]> git.proxmox.com Git - efi-boot-shim.git/commitdiff
Import Upstream version 0.9+1474479173.6c180c6
authorMathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Fri, 4 Aug 2017 16:10:50 +0000 (12:10 -0400)
committerMathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Fri, 4 Aug 2017 16:10:50 +0000 (12:10 -0400)
682 files changed:
.gitignore [new file with mode: 0644]
COPYRIGHT [new file with mode: 0644]
Cryptlib/Base.h [new file with mode: 0644]
Cryptlib/Cipher/CryptAes.c [new file with mode: 0644]
Cryptlib/Cipher/CryptArc4.c [new file with mode: 0644]
Cryptlib/Cipher/CryptTdes.c [new file with mode: 0644]
Cryptlib/Cryptlib.diff [new file with mode: 0644]
Cryptlib/Hash/CryptMd4.c [new file with mode: 0644]
Cryptlib/Hash/CryptMd5.c [new file with mode: 0644]
Cryptlib/Hash/CryptSha1.c [new file with mode: 0644]
Cryptlib/Hash/CryptSha256.c [new file with mode: 0644]
Cryptlib/Hash/CryptSha512.c [new file with mode: 0644]
Cryptlib/Hmac/CryptHmacMd5.c [new file with mode: 0644]
Cryptlib/Hmac/CryptHmacSha1.c [new file with mode: 0644]
Cryptlib/Include/OpenSslSupport.h [new file with mode: 0644]
Cryptlib/Include/Protocol/RuntimeCrypt.h [new file with mode: 0644]
Cryptlib/Include/arpa/inet.h [new file with mode: 0644]
Cryptlib/Include/assert.h [new file with mode: 0644]
Cryptlib/Include/ctype.h [new file with mode: 0644]
Cryptlib/Include/dirent.h [new file with mode: 0644]
Cryptlib/Include/errno.h [new file with mode: 0644]
Cryptlib/Include/limits.h [new file with mode: 0644]
Cryptlib/Include/malloc.h [new file with mode: 0644]
Cryptlib/Include/math.h [new file with mode: 0644]
Cryptlib/Include/memory.h [new file with mode: 0644]
Cryptlib/Include/netdb.h [new file with mode: 0644]
Cryptlib/Include/netinet/in.h [new file with mode: 0644]
Cryptlib/Include/openssl/README [new file with mode: 0644]
Cryptlib/Include/openssl/aes.h [new file with mode: 0644]
Cryptlib/Include/openssl/asn1.h [new file with mode: 0644]
Cryptlib/Include/openssl/asn1_mac.h [new file with mode: 0644]
Cryptlib/Include/openssl/asn1t.h [new file with mode: 0644]
Cryptlib/Include/openssl/bio.h [new file with mode: 0644]
Cryptlib/Include/openssl/blowfish.h [new file with mode: 0644]
Cryptlib/Include/openssl/bn.h [new file with mode: 0644]
Cryptlib/Include/openssl/buffer.h [new file with mode: 0644]
Cryptlib/Include/openssl/camellia.h [new file with mode: 0644]
Cryptlib/Include/openssl/cast.h [new file with mode: 0644]
Cryptlib/Include/openssl/cmac.h [new file with mode: 0644]
Cryptlib/Include/openssl/cms.h [new file with mode: 0644]
Cryptlib/Include/openssl/comp.h [new file with mode: 0644]
Cryptlib/Include/openssl/conf.h [new file with mode: 0644]
Cryptlib/Include/openssl/conf_api.h [new file with mode: 0644]
Cryptlib/Include/openssl/crypto.h [new file with mode: 0644]
Cryptlib/Include/openssl/des.h [new file with mode: 0644]
Cryptlib/Include/openssl/des_old.h [new file with mode: 0644]
Cryptlib/Include/openssl/dh.h [new file with mode: 0644]
Cryptlib/Include/openssl/dsa.h [new file with mode: 0644]
Cryptlib/Include/openssl/dso.h [new file with mode: 0644]
Cryptlib/Include/openssl/dtls1.h [new file with mode: 0644]
Cryptlib/Include/openssl/e_os2.h [new file with mode: 0644]
Cryptlib/Include/openssl/ebcdic.h [new file with mode: 0644]
Cryptlib/Include/openssl/ec.h [new file with mode: 0644]
Cryptlib/Include/openssl/ecdh.h [new file with mode: 0644]
Cryptlib/Include/openssl/ecdsa.h [new file with mode: 0644]
Cryptlib/Include/openssl/engine.h [new file with mode: 0644]
Cryptlib/Include/openssl/err.h [new file with mode: 0644]
Cryptlib/Include/openssl/evp.h [new file with mode: 0644]
Cryptlib/Include/openssl/hmac.h [new file with mode: 0644]
Cryptlib/Include/openssl/idea.h [new file with mode: 0644]
Cryptlib/Include/openssl/krb5_asn.h [new file with mode: 0644]
Cryptlib/Include/openssl/kssl.h [new file with mode: 0644]
Cryptlib/Include/openssl/lhash.h [new file with mode: 0644]
Cryptlib/Include/openssl/md4.h [new file with mode: 0644]
Cryptlib/Include/openssl/md5.h [new file with mode: 0644]
Cryptlib/Include/openssl/mdc2.h [new file with mode: 0644]
Cryptlib/Include/openssl/modes.h [new file with mode: 0644]
Cryptlib/Include/openssl/obj_mac.h [new file with mode: 0644]
Cryptlib/Include/openssl/objects.h [new file with mode: 0644]
Cryptlib/Include/openssl/ocsp.h [new file with mode: 0644]
Cryptlib/Include/openssl/opensslconf.h [new file with mode: 0644]
Cryptlib/Include/openssl/opensslv.h [new file with mode: 0644]
Cryptlib/Include/openssl/ossl_typ.h [new file with mode: 0644]
Cryptlib/Include/openssl/pem.h [new file with mode: 0644]
Cryptlib/Include/openssl/pem2.h [new file with mode: 0644]
Cryptlib/Include/openssl/pkcs12.h [new file with mode: 0644]
Cryptlib/Include/openssl/pkcs7.h [new file with mode: 0644]
Cryptlib/Include/openssl/pqueue.h [new file with mode: 0644]
Cryptlib/Include/openssl/rand.h [new file with mode: 0644]
Cryptlib/Include/openssl/rc2.h [new file with mode: 0644]
Cryptlib/Include/openssl/rc4.h [new file with mode: 0644]
Cryptlib/Include/openssl/ripemd.h [new file with mode: 0644]
Cryptlib/Include/openssl/rsa.h [new file with mode: 0644]
Cryptlib/Include/openssl/safestack.h [new file with mode: 0644]
Cryptlib/Include/openssl/seed.h [new file with mode: 0644]
Cryptlib/Include/openssl/sha.h [new file with mode: 0644]
Cryptlib/Include/openssl/srp.h [new file with mode: 0644]
Cryptlib/Include/openssl/srtp.h [new file with mode: 0644]
Cryptlib/Include/openssl/ssl.h [new file with mode: 0644]
Cryptlib/Include/openssl/ssl2.h [new file with mode: 0644]
Cryptlib/Include/openssl/ssl23.h [new file with mode: 0644]
Cryptlib/Include/openssl/ssl3.h [new file with mode: 0644]
Cryptlib/Include/openssl/stack.h [new file with mode: 0644]
Cryptlib/Include/openssl/symhacks.h [new file with mode: 0644]
Cryptlib/Include/openssl/tls1.h [new file with mode: 0644]
Cryptlib/Include/openssl/ts.h [new file with mode: 0644]
Cryptlib/Include/openssl/txt_db.h [new file with mode: 0644]
Cryptlib/Include/openssl/ui.h [new file with mode: 0644]
Cryptlib/Include/openssl/ui_compat.h [new file with mode: 0644]
Cryptlib/Include/openssl/whrlpool.h [new file with mode: 0644]
Cryptlib/Include/openssl/x509.h [new file with mode: 0644]
Cryptlib/Include/openssl/x509_vfy.h [new file with mode: 0644]
Cryptlib/Include/openssl/x509v3.h [new file with mode: 0644]
Cryptlib/Include/sgtty.h [new file with mode: 0644]
Cryptlib/Include/signal.h [new file with mode: 0644]
Cryptlib/Include/stdarg.h [new file with mode: 0644]
Cryptlib/Include/stddef.h [new file with mode: 0644]
Cryptlib/Include/stdio.h [new file with mode: 0644]
Cryptlib/Include/stdlib.h [new file with mode: 0644]
Cryptlib/Include/string.h [new file with mode: 0644]
Cryptlib/Include/strings.h [new file with mode: 0644]
Cryptlib/Include/sys/ioctl.h [new file with mode: 0644]
Cryptlib/Include/sys/param.h [new file with mode: 0644]
Cryptlib/Include/sys/socket.h [new file with mode: 0644]
Cryptlib/Include/sys/stat.h [new file with mode: 0644]
Cryptlib/Include/sys/time.h [new file with mode: 0644]
Cryptlib/Include/sys/times.h [new file with mode: 0644]
Cryptlib/Include/sys/types.h [new file with mode: 0644]
Cryptlib/Include/sys/un.h [new file with mode: 0644]
Cryptlib/Include/syslog.h [new file with mode: 0644]
Cryptlib/Include/time.h [new file with mode: 0644]
Cryptlib/Include/unistd.h [new file with mode: 0644]
Cryptlib/InternalCryptLib.h [new file with mode: 0644]
Cryptlib/Library/BaseCryptLib.h [new file with mode: 0644]
Cryptlib/Library/BaseLib.h [new file with mode: 0644]
Cryptlib/Library/BaseMemoryLib.h [new file with mode: 0644]
Cryptlib/Library/DebugLib.h [new file with mode: 0644]
Cryptlib/Library/MemoryAllocationLib.h [new file with mode: 0644]
Cryptlib/Makefile [new file with mode: 0644]
Cryptlib/OpenSSL/Makefile [new file with mode: 0644]
Cryptlib/OpenSSL/buildinf.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/LPdir_nyi.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_cbc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_cfb.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_core.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_ctr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_ecb.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_ige.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_misc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_ofb.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/aes/aes_wrap.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_bitstr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_bool.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_bytes.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_d2i_fp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_digest.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_dup.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_enum.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_gentm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_i2d_fp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_int.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_mbstr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_object.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_octet.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_print.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_set.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_sign.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_strex.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_strnid.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_time.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_type.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_utctm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_utf8.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/a_verify.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn1_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn1_gen.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn1_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn1_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn1_par.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn_mime.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn_moid.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/asn_pack.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/bio_asn1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/bio_ndef.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/charmap.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/d2i_pr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/d2i_pu.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/evp_asn1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/f_enum.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/f_int.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/f_string.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/i2d_pr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/i2d_pu.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/n_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/nsseq.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/p5_pbe.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/p8_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_bitst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_crl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_req.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_spki.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_x509.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/t_x509a.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_fre.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_new.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_typ.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/tasn_utl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_algor.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_attrib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_bignum.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_crl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_exten.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_info.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_long.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_name.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_nx509.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_pubkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_req.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_sig.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_spki.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_val.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_x509.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/asn1/x_x509a.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/b_dump.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/b_print.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/b_sock.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bf_buff.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bf_nbio.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bf_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bio_cb.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bio_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bio_lcl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bio_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_acpt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_bio.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_conn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_dgram.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_fd.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_file.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_log.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_mem.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bio/bss_sock.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_add.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_asm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_blind.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_const.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_ctx.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_depr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_div.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_exp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_exp2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_gcd.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_gf2m.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_kron.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_lcl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_mod.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_mont.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_mpi.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_mul.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_nist.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_prime.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_prime.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_print.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_rand.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_recp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_shift.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_sqr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_word.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/bn_x931p.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/bn/rsaz_exp.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/buffer/buf_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/buffer/buf_str.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/buffer/buffer.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cmac/cm_ameth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cmac/cm_pmeth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cmac/cmac.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/comp/c_rle.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/comp/c_zlib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/comp/comp_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/comp/comp_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_api.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_def.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_def.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_mall.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_mod.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/conf/conf_sap.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/constant_time_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cpt_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cryptlib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cryptlib.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/cversion.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/cbc_cksm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/cbc_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/cfb64ede.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/cfb64enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/cfb_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/des_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/des_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/des_old.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/des_old2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/des_ver.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ecb3_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ecb_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ede_cbcm_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/enc_read.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/enc_writ.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/fcrypt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/fcrypt_b.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ncbc_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ofb64ede.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ofb64enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/ofb_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/pcbc_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/qud_cksm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/rand_key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/read2pwd.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/rpc_des.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/rpc_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/set_key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/spr.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/str2key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/des/xcbc_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_ameth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_asn1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_check.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_depr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_gen.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_pmeth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dh/dh_rfc5114.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_beos.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_dl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_dlfcn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_openssl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_vms.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/dso/dso_win32.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ebcdic.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/err/err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/err/err_all.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/err/err_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/bio_b64.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/bio_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/bio_md.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/bio_ok.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/c_all.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/c_allc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/c_alld.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/digest.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_aes.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_bf.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_camellia.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_cast.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_des.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_des3.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_idea.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_old.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_rc2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_rc4.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_rc5.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_seed.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/encode.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_acnf.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_cnf.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_pbe.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/evp_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_dss.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_dss1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_md2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_md4.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_md5.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_mdc2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_ripemd.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_sha.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_sha1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_sigver.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/m_wp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/names.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p5_crpt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_dec.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_open.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_seal.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_sign.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/p_verify.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ex_data.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/fips_ers.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/hmac/hm_ameth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/hmac/hm_pmeth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/hmac/hmac.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/krb5/krb5_asn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/lhash/lh_stats.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/lhash/lhash.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md32_common.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md4/md4_dgst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md4/md4_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md4/md4_one.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md5/md5_dgst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md5/md5_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/md5/md5_one.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/mem.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/mem_clr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/mem_dbg.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/cbc128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/ccm128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/cfb128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/ctr128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/cts128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/gcm128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/modes_lcl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/ofb128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/wrap128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/modes/xts128.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_dir.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_dir.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_fips.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_init.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_str.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_str.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_time.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/o_time.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/o_names.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_dat.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_dat.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_xref.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/objects/obj_xref.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_asn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_cl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_ext.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_ht.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_srv.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ocsp/ocsp_vfy.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_all.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_info.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_oth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_pk8.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_pkey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_seal.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_sign.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_x509.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pem_xaux.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pem/pvkfmt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_add.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_asn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_attr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_crpt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_crt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_decr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_init.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_key.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_kiss.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_mutl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_npas.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_p8d.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_p8e.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/p12_utl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs12/pk12err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/bio_pk7.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_asn1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_attr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_mime.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pk7_smime.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/pkcs7/pkcs7err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/md_rand.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/rand_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/rand_lcl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/rand_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/rand_unix.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rand/randfile.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rc4/rc4_enc.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rc4/rc4_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rc4/rc4_skey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rc4/rc4_utl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_ameth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_asn1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_chk.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_crpt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_depr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_eay.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_none.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_null.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_oaep.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_pk1.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_pss.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_saos.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_sign.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_ssl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/rsa/rsa_x931.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha1_one.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha1dgst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha256.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha512.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha_dgst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/sha/sha_one.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/stack/stack.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/txt_db/txt_db.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ui/ui_compat.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ui/ui_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ui/ui_locl.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/ui/ui_util.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/uid.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/vpm_int.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_att.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_cmp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_d2.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_def.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_err.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_ext.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_lu.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_obj.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_r2x.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_req.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_set.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_trs.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_txt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_v3.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_vfy.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509_vpm.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509cset.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509name.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509rset.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509spki.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x509type.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509/x_all.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/ext_dat.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_cache.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_data.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_int.h [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_map.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_node.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/pcy_tree.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_akey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_akeya.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_alt.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_asid.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_bcons.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_bitst.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_conf.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_cpols.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_crld.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_enum.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_extku.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_ia5.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_info.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_int.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_lib.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_ncons.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_ocsp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_pci.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_pcia.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_pcons.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_pku.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_pmaps.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_prn.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_purp.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_skey.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_sxnet.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3_utl.c [new file with mode: 0644]
Cryptlib/OpenSSL/crypto/x509v3/v3err.c [new file with mode: 0644]
Cryptlib/OpenSSL/e_os.h [new file with mode: 0644]
Cryptlib/OpenSSL/openssl-bio-b_print-disable-sse.patch [new file with mode: 0644]
Cryptlib/OpenSSL/update.sh [new file with mode: 0755]
Cryptlib/Pem/CryptPem.c [new file with mode: 0644]
Cryptlib/Pk/CryptAuthenticode.c [new file with mode: 0644]
Cryptlib/Pk/CryptDhNull.c [new file with mode: 0644]
Cryptlib/Pk/CryptPkcs7SignNull.c [new file with mode: 0644]
Cryptlib/Pk/CryptPkcs7Verify.c [new file with mode: 0644]
Cryptlib/Pk/CryptRsaBasic.c [new file with mode: 0644]
Cryptlib/Pk/CryptRsaExtNull.c [new file with mode: 0644]
Cryptlib/Pk/CryptTs.c [new file with mode: 0644]
Cryptlib/Pk/CryptX509.c [new file with mode: 0644]
Cryptlib/Rand/CryptRand.c [new file with mode: 0644]
Cryptlib/SysCall/BaseMemAllocation.c [new file with mode: 0644]
Cryptlib/SysCall/BaseStrings.c [new file with mode: 0644]
Cryptlib/SysCall/CrtWrapper.c [new file with mode: 0644]
Cryptlib/SysCall/TimerWrapper.c [new file with mode: 0644]
Cryptlib/update.sh [new file with mode: 0755]
Makefile [new file with mode: 0644]
MokManager.c [new file with mode: 0644]
MokVars.txt [new file with mode: 0644]
PasswordCrypt.c [new file with mode: 0644]
PasswordCrypt.h [new file with mode: 0644]
README [new file with mode: 0644]
README.fallback [new file with mode: 0644]
TODO [new file with mode: 0644]
cert.S [new file with mode: 0644]
crypt_blowfish.c [new file with mode: 0644]
crypt_blowfish.h [new file with mode: 0644]
elf_aarch64_efi.lds [new file with mode: 0644]
elf_arm_efi.lds [new file with mode: 0644]
elf_ia32_efi.lds [new file with mode: 0644]
elf_ia64_efi.lds [new file with mode: 0644]
elf_x86_64_efi.lds [new file with mode: 0644]
fallback.c [new file with mode: 0644]
hexdump.h [new file with mode: 0644]
httpboot.c [new file with mode: 0644]
httpboot.h [new file with mode: 0644]
include/Http.h [new file with mode: 0644]
include/Ip4Config2.h [new file with mode: 0644]
include/Ip6Config.h [new file with mode: 0644]
include/PeImage.h [new file with mode: 0644]
include/configtable.h [new file with mode: 0644]
include/console.h [new file with mode: 0644]
include/efiauthenticated.h [new file with mode: 0644]
include/errors.h [new file with mode: 0644]
include/execute.h [new file with mode: 0644]
include/guid.h [new file with mode: 0644]
include/security_policy.h [new file with mode: 0644]
include/shell.h [new file with mode: 0644]
include/simple_file.h [new file with mode: 0644]
include/str.h [new file with mode: 0644]
include/variables.h [new file with mode: 0644]
include/version.h [new file with mode: 0644]
include/wincert.h [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/configtable.c [new file with mode: 0644]
lib/console.c [new file with mode: 0644]
lib/execute.c [new file with mode: 0644]
lib/guid.c [new file with mode: 0644]
lib/security_policy.c [new file with mode: 0644]
lib/shell.c [new file with mode: 0644]
lib/simple_file.c [new file with mode: 0644]
lib/variables.c [new file with mode: 0644]
make-certs [new file with mode: 0755]
netboot.c [new file with mode: 0644]
netboot.h [new file with mode: 0644]
replacements.c [new file with mode: 0644]
replacements.h [new file with mode: 0644]
shim.c [new file with mode: 0644]
shim.h [new file with mode: 0644]
testplan.txt [new file with mode: 0644]
tpm.c [new file with mode: 0644]
tpm.h [new file with mode: 0644]
ucs2.h [new file with mode: 0644]
version.c.in [new file with mode: 0644]
version.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..586bc24
--- /dev/null
@@ -0,0 +1,26 @@
+.*.sw?
+certdb
+shim_cert.h
+*.a
+*.cer
+*.crl
+*.crt
+*.csr
+*.db
+*.db.attr
+*.db.attr.old
+*.db.old
+*.domain.txt
+*.efi
+*.efi.debug
+*.efi.signed
+*.key
+*.key
+*.o
+*.pem
+*.p12
+*.so
+*.srl
+*.srl.old
+*.tar.*
+version.c
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644 (file)
index 0000000..3b5a464
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,30 @@
+Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+
+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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Significant portions of this code are derived from Tianocore
+(http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+Corporation.
diff --git a/Cryptlib/Base.h b/Cryptlib/Base.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Cryptlib/Cipher/CryptAes.c b/Cryptlib/Cipher/CryptAes.c
new file mode 100644 (file)
index 0000000..753d798
--- /dev/null
@@ -0,0 +1,323 @@
+/** @file\r
+  AES Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/aes.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for AES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for AES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AesGetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // AES uses different key contexts for encryption and decryption, so here memory\r
+  // for 2 copies of AES_KEY is allocated.\r
+  //\r
+  return (UINTN) (2 * sizeof (AES_KEY));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as AES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by AesContext as AES context.\r
+  In addition, it sets up all AES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeyLength is not valid, then return FALSE.\r
+\r
+  @param[out]  AesContext  Pointer to AES context being initialized.\r
+  @param[in]   Key         Pointer to the user-supplied AES key.\r
+  @param[in]   KeyLength   Length of AES key in bits.\r
+\r
+  @retval TRUE   AES context initialization succeeded.\r
+  @retval FALSE  AES context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesInit (\r
+  OUT  VOID         *AesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (AesContext == NULL || Key == NULL || (KeyLength != 128 && KeyLength != 192 && KeyLength != 256)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Initialize AES encryption & decryption key schedule.\r
+  //\r
+  AesKey = (AES_KEY *) AesContext;\r
+  if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {\r
+    return FALSE;\r
+  }\r
+  if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 0) {\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {\r
+    return FALSE;\r
+  }\r
+  \r
+  AesKey = (AES_KEY *) AesContext;\r
+\r
+  //\r
+  // Perform AES data encryption with ECB mode (block-by-block)\r
+  //\r
+  while (InputSize > 0) {\r
+    AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);\r
+    Input     += AES_BLOCK_SIZE;\r
+    Output    += AES_BLOCK_SIZE;\r
+    InputSize -= AES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+\r
+  //\r
+  // Perform AES data decryption with ECB mode (block-by-block)\r
+  //\r
+  while (InputSize > 0) {\r
+    AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);\r
+    Input     += AES_BLOCK_SIZE;\r
+    Output    += AES_BLOCK_SIZE;\r
+    InputSize -= AES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  UINT8    IvecBuffer[AES_BLOCK_SIZE];\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
+\r
+  //\r
+  // Perform AES data encryption with CBC mode\r
+  //\r
+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  UINT8    IvecBuffer[AES_BLOCK_SIZE];\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
+\r
+  //\r
+  // Perform AES data decryption with CBC mode\r
+  //\r
+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/Cipher/CryptArc4.c b/Cryptlib/Cipher/CryptArc4.c
new file mode 100644 (file)
index 0000000..f3c4d31
--- /dev/null
@@ -0,0 +1,211 @@
+/** @file\r
+  ARC4 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/rc4.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Arc4GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Memory for 2 copies of RC4_KEY is allocated, one for working copy, and the other\r
+  // for backup copy. When Arc4Reset() is called, we can use the backup copy to restore\r
+  // the working copy to the initial state.\r
+  //\r
+  return (UINTN) (2 * sizeof (RC4_KEY));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as ARC4 context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.\r
+  In addition, it sets up all ARC4 key materials for subsequent encryption and decryption\r
+  operations.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeySize does not in the range of [5, 256] bytes, then return FALSE.\r
+\r
+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied ARC4 key.\r
+  @param[in]   KeySize      Size of ARC4 key in bytes.\r
+\r
+  @retval TRUE   ARC4 context initialization succeeded.\r
+  @retval FALSE  ARC4 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Init (\r
+  OUT  VOID         *Arc4Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //  \r
+  if (Arc4Context == NULL || Key == NULL || (KeySize < 5 || KeySize > 256)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4_set_key (Rc4Key, (UINT32) KeySize, Key);\r
+\r
+  CopyMem (Rc4Key +  1, Rc4Key, sizeof (RC4_KEY));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs ARC4 encryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 encryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]       Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]       InputSize    Size of the Input buffer in bytes.\r
+  @param[out]      Output       Pointer to a buffer that receives the ARC4 encryption output.\r
+\r
+  @retval TRUE   ARC4 encryption succeeded.\r
+  @retval FALSE  ARC4 encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Encrypt (\r
+  IN OUT  VOID         *Arc4Context,\r
+  IN      CONST UINT8  *Input,\r
+  IN      UINTN        InputSize,\r
+  OUT     UINT8        *Output\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs ARC4 decryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 decryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]       Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]       InputSize    Size of the Input buffer in bytes.\r
+  @param[out]      Output       Pointer to a buffer that receives the ARC4 decryption output.\r
+\r
+  @retval TRUE   ARC4 decryption succeeded.\r
+  @retval FALSE  ARC4 decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Decrypt (\r
+  IN OUT  VOID   *Arc4Context,\r
+  IN      UINT8  *Input,\r
+  IN      UINTN  InputSize,\r
+  OUT     UINT8  *Output\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Arc4Context == NULL || Input == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Resets the ARC4 context to the initial state.\r
+\r
+  The function resets the ARC4 context to the state it had immediately after the\r
+  ARC4Init() function call.\r
+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context\r
+  should be already correctly initialized by ARC4Init().\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+\r
+  @retval TRUE   ARC4 reset succeeded.\r
+  @retval FALSE  ARC4 reset failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Reset (\r
+  IN OUT  VOID  *Arc4Context\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Arc4Context == NULL) {\r
+    return FALSE;\r
+  }\r
+  \r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  CopyMem (Rc4Key, Rc4Key + 1, sizeof (RC4_KEY));\r
+\r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/Cipher/CryptTdes.c b/Cryptlib/Cipher/CryptTdes.c
new file mode 100644 (file)
index 0000000..8025a49
--- /dev/null
@@ -0,0 +1,370 @@
+/** @file\r
+  TDES Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/des.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for TDES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+TdesGetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.\r
+  //\r
+  return (UINTN) (3 * sizeof (DES_key_schedule));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as TDES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
+  In addition, it sets up all TDES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 key options as follows:\r
+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeyLength is not valid, then return FALSE.\r
+\r
+  @param[out]  TdesContext  Pointer to TDES context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied TDES key.\r
+  @param[in]   KeyLength    Length of TDES key in bits.\r
+\r
+  @retval TRUE   TDES context initialization succeeded.\r
+  @retval FALSE  TDES context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesInit (\r
+  OUT  VOID         *TdesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (TdesContext == NULL || Key == NULL || (KeyLength != 64 && KeyLength != 128 && KeyLength != 192)) {\r
+    return FALSE;\r
+  }\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  //\r
+  // If input Key is a weak key, return error.\r
+  //\r
+  if (DES_is_weak_key ((const_DES_cblock *) Key) == 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);\r
+\r
+  if (KeyLength == 64) {\r
+    CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));\r
+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
+    return TRUE;\r
+  }\r
+\r
+  if (DES_is_weak_key ((const_DES_cblock *) (Key + 8)) == 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);\r
+\r
+  if (KeyLength == 128) {\r
+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
+    return TRUE;\r
+  }\r
+\r
+  if (DES_is_weak_key ((const_DES_cblock *) (Key + 16)) == 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  while (InputSize > 0) {\r
+    DES_ecb3_encrypt (\r
+      (const_DES_cblock *) Input,\r
+      (DES_cblock *) Output,\r
+      KeySchedule,\r
+      KeySchedule + 1,\r
+      KeySchedule + 2,\r
+      DES_ENCRYPT\r
+      );\r
+    Input     += TDES_BLOCK_SIZE;\r
+    Output    += TDES_BLOCK_SIZE;\r
+    InputSize -= TDES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  while (InputSize > 0) {\r
+    DES_ecb3_encrypt (\r
+      (const_DES_cblock *) Input,\r
+      (DES_cblock *) Output,\r
+      KeySchedule,\r
+      KeySchedule + 1,\r
+      KeySchedule + 2,\r
+      DES_DECRYPT\r
+      );\r
+    Input     += TDES_BLOCK_SIZE;\r
+    Output    += TDES_BLOCK_SIZE;\r
+    InputSize -= TDES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
+\r
+  DES_ede3_cbc_encrypt (\r
+    Input,\r
+    Output,\r
+    (UINT32) InputSize,\r
+    KeySchedule,\r
+    KeySchedule + 1,\r
+    KeySchedule + 2,\r
+    (DES_cblock *) IvecBuffer,\r
+    DES_ENCRYPT\r
+    );\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
+\r
+  DES_ede3_cbc_encrypt (\r
+    Input,\r
+    Output,\r
+    (UINT32) InputSize,\r
+    KeySchedule,\r
+    KeySchedule + 1,\r
+    KeySchedule + 2,\r
+    (DES_cblock *) IvecBuffer,\r
+    DES_DECRYPT\r
+    );\r
+\r
+  return TRUE;\r
+}\r
+\r
diff --git a/Cryptlib/Cryptlib.diff b/Cryptlib/Cryptlib.diff
new file mode 100644 (file)
index 0000000..a2f49d6
--- /dev/null
@@ -0,0 +1,57 @@
+diff --git a/Cryptlib/SysCall/BaseMemAllocation.c b/Cryptlib/SysCall/BaseMemAllocation.c
+index 68bc25a..1abe78e 100644
+--- a/Cryptlib/SysCall/BaseMemAllocation.c
++++ b/Cryptlib/SysCall/BaseMemAllocation.c
+@@ -32,7 +32,7 @@ void *realloc (void *ptr, size_t size)
+   // BUG: hardcode OldSize == size! We have no any knowledge about\r
+   // memory size of original pointer ptr.\r
+   //\r
+-  return ReallocatePool ((UINTN) size, (UINTN) size, ptr);\r
++  return ReallocatePool (ptr, (UINTN) size, (UINTN) size);\r
+ }\r
\r
+ /* De-allocates or frees a memory block */\r
+diff --git a/Cryptlib/SysCall/TimerWrapper.c b/Cryptlib/SysCall/TimerWrapper.c
+index 805e6b4..bb7bcba 100644
+--- a/Cryptlib/SysCall/TimerWrapper.c
++++ b/Cryptlib/SysCall/TimerWrapper.c
+@@ -13,9 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
+ **/\r
\r
+-#include <Uefi.h>\r
+ #include <OpenSslSupport.h>\r
+-#include <Library/UefiRuntimeServicesTableLib.h>\r
\r
+ //\r
+ // -- Time Management Routines --\r
+@@ -78,7 +76,7 @@ time_t time (time_t *timer)
+   //\r
+   // Get the current time and date information\r
+   //\r
+-  gRT->GetTime (&Time, NULL);\r
++  uefi_call_wrapper(RT->GetTime, 2, &Time, NULL);\r
\r
+   //\r
+   // Years Handling\r
+diff --git a/Cryptlib/SysCall/CrtWrapper.c b/Cryptlib/SysCall/CrtWrapper.c
+index fb446b6..5a8322d 100644
+--- a/Cryptlib/SysCall/CrtWrapper.c
++++ b/Cryptlib/SysCall/CrtWrapper.c
+@@ -293,16 +293,6 @@ size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream)
+ //  -- Dummy OpenSSL Support Routines --\r
+ //\r
\r
+-int BIO_printf (void *bio, const char *format, ...)\r
+-{\r
+-  return 0;\r
+-}\r
+-\r
+-int BIO_snprintf(char *buf, size_t n, const char *format, ...)\r
+-{\r
+-  return 0;\r
+-}\r
+-\r
+ void *UI_OpenSSL(void)\r
+ {\r
+   return NULL;\r
diff --git a/Cryptlib/Hash/CryptMd4.c b/Cryptlib/Hash/CryptMd4.c
new file mode 100644 (file)
index 0000000..633d343
--- /dev/null
@@ -0,0 +1,183 @@
+/** @file\r
+  MD4 Digest Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/md4.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for MD4 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for MD4 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Md4GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL MD4 Context Size\r
+  //\r
+  return (UINTN) (sizeof (MD4_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Md4Context as MD4 hash context for\r
+  subsequent use.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Md4Context  Pointer to MD4 context being initialized.\r
+\r
+  @retval TRUE   MD4 context initialization succeeded.\r
+  @retval FALSE  MD4 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Init (\r
+  OUT  VOID  *Md4Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md4Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD4 Context Initialization\r
+  //\r
+  return (BOOLEAN) (MD4_Init ((MD4_CTX *) Md4Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing MD4 context.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If NewMd4Context is NULL, then return FALSE.\r
+\r
+  @param[in]  Md4Context     Pointer to MD4 context being copied.\r
+  @param[out] NewMd4Context  Pointer to new MD4 context.\r
+\r
+  @retval TRUE   MD4 context copy succeeded.\r
+  @retval FALSE  MD4 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Duplicate (\r
+  IN   CONST VOID  *Md4Context,\r
+  OUT  VOID        *NewMd4Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md4Context == NULL || NewMd4Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewMd4Context, Md4Context, sizeof (MD4_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates MD4 context.\r
+\r
+  This function performs MD4 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD4 context should be already correctly intialized by Md4Init(), and should not be finalized\r
+  by Md4Final(). Behavior with invalid context is undefined.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Md4Context  Pointer to the MD4 context.\r
+  @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   MD4 data digest succeeded.\r
+  @retval FALSE  MD4 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Update (\r
+  IN OUT  VOID        *Md4Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md4Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD4 Hash Update\r
+  //\r
+  return (BOOLEAN) (MD4_Update ((MD4_CTX *) Md4Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the MD4 digest value.\r
+\r
+  This function completes MD4 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD4 context cannot\r
+  be used again.\r
+  MD4 context should be already correctly intialized by Md4Init(), and should not be\r
+  finalized by Md4Final(). Behavior with invalid MD4 context is undefined.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Md4Context  Pointer to the MD4 context.\r
+  @param[out]      HashValue   Pointer to a buffer that receives the MD4 digest\r
+                               value (16 bytes).\r
+\r
+  @retval TRUE   MD4 digest computation succeeded.\r
+  @retval FALSE  MD4 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Final (\r
+  IN OUT  VOID   *Md4Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md4Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD4 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (MD4_Final (HashValue, (MD4_CTX *) Md4Context));\r
+}\r
diff --git a/Cryptlib/Hash/CryptMd5.c b/Cryptlib/Hash/CryptMd5.c
new file mode 100644 (file)
index 0000000..e1c10e3
--- /dev/null
@@ -0,0 +1,185 @@
+/** @file\r
+  MD5 Digest Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/md5.h>\r
+\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for MD5 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for MD5 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Md5GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL MD5 Context Size\r
+  //\r
+  return (UINTN) (sizeof (MD5_CTX));\r
+}\r
+\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Md5Context as MD5 hash context for\r
+  subsequent use.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Md5Context  Pointer to MD5 context being initialized.\r
+\r
+  @retval TRUE   MD5 context initialization succeeded.\r
+  @retval FALSE  MD5 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Init (\r
+  OUT  VOID  *Md5Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md5Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD5 Context Initialization\r
+  //\r
+  return (BOOLEAN) (MD5_Init ((MD5_CTX *) Md5Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing MD5 context.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If NewMd5Context is NULL, then return FALSE.\r
+\r
+  @param[in]  Md5Context     Pointer to MD5 context being copied.\r
+  @param[out] NewMd5Context  Pointer to new MD5 context.\r
+\r
+  @retval TRUE   MD5 context copy succeeded.\r
+  @retval FALSE  MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Duplicate (\r
+  IN   CONST VOID  *Md5Context,\r
+  OUT  VOID        *NewMd5Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md5Context == NULL || NewMd5Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewMd5Context, Md5Context, sizeof (MD5_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates MD5 context.\r
+\r
+  This function performs MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized\r
+  by Md5Final(). Behavior with invalid context is undefined.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
+  @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   MD5 data digest succeeded.\r
+  @retval FALSE  MD5 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Update (\r
+  IN OUT  VOID        *Md5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md5Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && (DataSize != 0)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD5 Hash Update\r
+  //\r
+  return (BOOLEAN) (MD5_Update ((MD5_CTX *) Md5Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the MD5 digest value.\r
+\r
+  This function completes MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD5 context cannot\r
+  be used again.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be\r
+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
+  @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest\r
+                               value (16 bytes).\r
+\r
+  @retval TRUE   MD5 digest computation succeeded.\r
+  @retval FALSE  MD5 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Final (\r
+  IN OUT  VOID   *Md5Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Md5Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL MD5 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (MD5_Final (HashValue, (MD5_CTX *) Md5Context));\r
+}\r
diff --git a/Cryptlib/Hash/CryptSha1.c b/Cryptlib/Hash/CryptSha1.c
new file mode 100644 (file)
index 0000000..78c29c1
--- /dev/null
@@ -0,0 +1,184 @@
+/** @file\r
+  SHA-1 Digest Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/sha.h>\r
+\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-1 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha1GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves OpenSSL SHA Context Size\r
+  //\r
+  return (UINTN) (sizeof (SHA_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for\r
+  subsequent use.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.\r
+\r
+  @retval TRUE   SHA-1 context initialization succeeded.\r
+  @retval FALSE  SHA-1 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Init (\r
+  OUT  VOID  *Sha1Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha1Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-1 Context Initialization\r
+  //\r
+  return (BOOLEAN) (SHA1_Init ((SHA_CTX *) Sha1Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing SHA-1 context.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If NewSha1Context is NULL, then return FALSE.\r
+\r
+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.\r
+  @param[out] NewSha1Context  Pointer to new SHA-1 context.\r
+\r
+  @retval TRUE   SHA-1 context copy succeeded.\r
+  @retval FALSE  SHA-1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Duplicate (\r
+  IN   CONST VOID  *Sha1Context,\r
+  OUT  VOID        *NewSha1Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha1Context == NULL || NewSha1Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewSha1Context, Sha1Context, sizeof (SHA_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates SHA-1 context.\r
+\r
+  This function performs SHA-1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized\r
+  by Sha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize     Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-1 data digest succeeded.\r
+  @retval FALSE  SHA-1 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Update (\r
+  IN OUT  VOID        *Sha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha1Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-1 Hash Update\r
+  //\r
+  return (BOOLEAN) (SHA1_Update ((SHA_CTX *) Sha1Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the SHA-1 digest value.\r
+\r
+  This function completes SHA-1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-1 context cannot\r
+  be used again.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be\r
+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
+  @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest\r
+                                value (20 bytes).\r
+\r
+  @retval TRUE   SHA-1 digest computation succeeded.\r
+  @retval FALSE  SHA-1 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Final (\r
+  IN OUT  VOID   *Sha1Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha1Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-1 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (SHA1_Final (HashValue, (SHA_CTX *) Sha1Context));\r
+}\r
diff --git a/Cryptlib/Hash/CryptSha256.c b/Cryptlib/Hash/CryptSha256.c
new file mode 100644 (file)
index 0000000..56894ac
--- /dev/null
@@ -0,0 +1,183 @@
+/** @file\r
+  SHA-256 Digest Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/sha.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha256GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves OpenSSL SHA-256 Context Size\r
+  //\r
+  return (UINTN) (sizeof (SHA256_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
+  subsequent use.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.\r
+\r
+  @retval TRUE   SHA-256 context initialization succeeded.\r
+  @retval FALSE  SHA-256 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Init (\r
+  OUT  VOID  *Sha256Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha256Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-256 Context Initialization\r
+  //\r
+  return (BOOLEAN) (SHA256_Init ((SHA256_CTX *) Sha256Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing SHA-256 context.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+  If NewSha256Context is NULL, then return FALSE.\r
+\r
+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.\r
+  @param[out] NewSha256Context  Pointer to new SHA-256 context.\r
+\r
+  @retval TRUE   SHA-256 context copy succeeded.\r
+  @retval FALSE  SHA-256 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Duplicate (\r
+  IN   CONST VOID  *Sha256Context,\r
+  OUT  VOID        *NewSha256Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha256Context == NULL || NewSha256Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewSha256Context, Sha256Context, sizeof (SHA256_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates SHA-256 context.\r
+\r
+  This function performs SHA-256 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized\r
+  by Sha256Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-256 data digest succeeded.\r
+  @retval FALSE  SHA-256 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Update (\r
+  IN OUT  VOID        *Sha256Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha256Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-256 Hash Update\r
+  //\r
+  return (BOOLEAN) (SHA256_Update ((SHA256_CTX *) Sha256Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the SHA-256 digest value.\r
+\r
+  This function completes SHA-256 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-256 context cannot\r
+  be used again.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be\r
+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest\r
+                                  value (32 bytes).\r
+\r
+  @retval TRUE   SHA-256 digest computation succeeded.\r
+  @retval FALSE  SHA-256 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Final (\r
+  IN OUT  VOID   *Sha256Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha256Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-256 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (SHA256_Final (HashValue, (SHA256_CTX *) Sha256Context));\r
+}\r
diff --git a/Cryptlib/Hash/CryptSha512.c b/Cryptlib/Hash/CryptSha512.c
new file mode 100644 (file)
index 0000000..491f45d
--- /dev/null
@@ -0,0 +1,354 @@
+/** @file\r
+  SHA-384 and SHA-512 Digest Wrapper Implementations over OpenSSL.\r
+\r
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/sha.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-384 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha384GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves OpenSSL SHA-384 Context Size\r
+  //\r
+  return (UINTN) (sizeof (SHA512_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for\r
+  subsequent use.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha384Context  Pointer to SHA-384 context being initialized.\r
+\r
+  @retval TRUE   SHA-384 context initialization succeeded.\r
+  @retval FALSE  SHA-384 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Init (\r
+  OUT  VOID  *Sha384Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha384Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-384 Context Initialization\r
+  //\r
+  return (BOOLEAN) (SHA384_Init ((SHA512_CTX *) Sha384Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing SHA-384 context.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+  If NewSha384Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha384Context     Pointer to SHA-384 context being copied.\r
+  @param[out] NewSha384Context  Pointer to new SHA-384 context.\r
+\r
+  @retval TRUE   SHA-384 context copy succeeded.\r
+  @retval FALSE  SHA-384 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Duplicate (\r
+  IN   CONST VOID  *Sha384Context,\r
+  OUT  VOID        *NewSha384Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha384Context == NULL || NewSha384Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewSha384Context, Sha384Context, sizeof (SHA512_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates SHA-384 context.\r
+\r
+  This function performs SHA-384 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-384 context should be already correctly intialized by Sha384Init(), and should not be finalized\r
+  by Sha384Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha384Context  Pointer to the SHA-384 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-384 data digest succeeded.\r
+  @retval FALSE  SHA-384 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Update (\r
+  IN OUT  VOID        *Sha384Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha384Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-384 Hash Update\r
+  //\r
+  return (BOOLEAN) (SHA384_Update ((SHA512_CTX *) Sha384Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the SHA-384 digest value.\r
+\r
+  This function completes SHA-384 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-384 context cannot\r
+  be used again.\r
+  SHA-384 context should be already correctly intialized by Sha384Init(), and should not be\r
+  finalized by Sha384Final(). Behavior with invalid SHA-384 context is undefined.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha384Context  Pointer to the SHA-384 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-384 digest\r
+                                  value (48 bytes).\r
+\r
+  @retval TRUE   SHA-384 digest computation succeeded.\r
+  @retval FALSE  SHA-384 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Final (\r
+  IN OUT  VOID   *Sha384Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha384Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-384 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha384Context));\r
+}\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-512 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha512GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves OpenSSL SHA-512 Context Size\r
+  //\r
+  return (UINTN) (sizeof (SHA512_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for\r
+  subsequent use.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha512Context  Pointer to SHA-512 context being initialized.\r
+\r
+  @retval TRUE   SHA-512 context initialization succeeded.\r
+  @retval FALSE  SHA-512 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Init (\r
+  OUT  VOID  *Sha512Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha512Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-512 Context Initialization\r
+  //\r
+  return (BOOLEAN) (SHA512_Init ((SHA512_CTX *) Sha512Context));\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing SHA-512 context.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+  If NewSha512Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha512Context     Pointer to SHA-512 context being copied.\r
+  @param[out] NewSha512Context  Pointer to new SHA-512 context.\r
+\r
+  @retval TRUE   SHA-512 context copy succeeded.\r
+  @retval FALSE  SHA-512 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Duplicate (\r
+  IN   CONST VOID  *Sha512Context,\r
+  OUT  VOID        *NewSha512Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha512Context == NULL || NewSha512Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewSha512Context, Sha512Context, sizeof (SHA512_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates SHA-512 context.\r
+\r
+  This function performs SHA-512 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-512 context should be already correctly intialized by Sha512Init(), and should not be finalized\r
+  by Sha512Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha512Context  Pointer to the SHA-512 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-512 data digest succeeded.\r
+  @retval FALSE  SHA-512 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Update (\r
+  IN OUT  VOID        *Sha512Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha512Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-512 Hash Update\r
+  //\r
+  return (BOOLEAN) (SHA512_Update ((SHA512_CTX *) Sha512Context, Data, DataSize));\r
+}\r
+\r
+/**\r
+  Completes computation of the SHA-512 digest value.\r
+\r
+  This function completes SHA-512 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-512 context cannot\r
+  be used again.\r
+  SHA-512 context should be already correctly intialized by Sha512Init(), and should not be\r
+  finalized by Sha512Final(). Behavior with invalid SHA-512 context is undefined.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha512Context  Pointer to the SHA-512 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-512 digest\r
+                                  value (64 bytes).\r
+\r
+  @retval TRUE   SHA-512 digest computation succeeded.\r
+  @retval FALSE  SHA-512 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Final (\r
+  IN OUT  VOID   *Sha512Context,\r
+  OUT     UINT8  *HashValue\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Sha512Context == NULL || HashValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL SHA-512 Hash Finalization\r
+  //\r
+  return (BOOLEAN) (SHA384_Final (HashValue, (SHA512_CTX *) Sha512Context));\r
+}\r
diff --git a/Cryptlib/Hmac/CryptHmacMd5.c b/Cryptlib/Hmac/CryptHmacMd5.c
new file mode 100644 (file)
index 0000000..693cd32
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  HMAC-MD5 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/hmac.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacMd5GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL HMAC-MD5 Context Size\r
+  //\r
+  return (UINTN) (sizeof (HMAC_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for\r
+  subsequent use.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+\r
+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.\r
+  @param[in]   Key             Pointer to the user-supplied key.\r
+  @param[in]   KeySize         Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 context initialization succeeded.\r
+  @retval FALSE  HMAC-MD5 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Init (\r
+  OUT  VOID         *HmacMd5Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacMd5Context == NULL || KeySize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 Context Initialization\r
+  //\r
+  HMAC_CTX_init (HmacMd5Context);\r
+  HMAC_Init_ex (HmacMd5Context, Key, (UINT32) KeySize, EVP_md5(), NULL);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-MD5 context.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If NewHmacMd5Context is NULL, then return FALSE.\r
+\r
+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.\r
+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.\r
+\r
+  @retval TRUE   HMAC-MD5 context copy succeeded.\r
+  @retval FALSE  HMAC-MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Duplicate (\r
+  IN   CONST VOID  *HmacMd5Context,\r
+  OUT  VOID        *NewHmacMd5Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacMd5Context == NULL || NewHmacMd5Context == NULL) {\r
+    return FALSE;\r
+  }\r
+  \r
+  CopyMem (NewHmacMd5Context, HmacMd5Context, sizeof (HMAC_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates HMAC-MD5 context.\r
+\r
+  This function performs HMAC-MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 data digest succeeded.\r
+  @retval FALSE  HMAC-MD5 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Update (\r
+  IN OUT  VOID        *HmacMd5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacMd5Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 digest update\r
+  //\r
+  HMAC_Update (HmacMd5Context, Data, DataSize);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Completes computation of the HMAC-MD5 digest value.\r
+\r
+  This function completes HMAC-MD5 digest computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-MD5 context cannot\r
+  be used again.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If HmacValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[out]      HmacValue       Pointer to a buffer that receives the HMAC-MD5 digest\r
+                                   value (16 bytes).\r
+\r
+  @retval TRUE   HMAC-MD5 digest computation succeeded.\r
+  @retval FALSE  HMAC-MD5 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Final (\r
+  IN OUT  VOID   *HmacMd5Context,\r
+  OUT     UINT8  *HmacValue\r
+  )\r
+{\r
+  UINT32  Length;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacMd5Context == NULL || HmacValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 digest finalization\r
+  //\r
+  HMAC_Final (HmacMd5Context, HmacValue, &Length);\r
+  HMAC_CTX_cleanup (HmacMd5Context);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/Hmac/CryptHmacSha1.c b/Cryptlib/Hmac/CryptHmacSha1.c
new file mode 100644 (file)
index 0000000..881d26c
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  HMAC-SHA1 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/hmac.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacSha1GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL HMAC-SHA1 Context Size\r
+  //\r
+  return (UINTN) (sizeof (HMAC_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for\r
+  subsequent use.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+\r
+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.\r
+  @param[in]   Key              Pointer to the user-supplied key.\r
+  @param[in]   KeySize          Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 context initialization succeeded.\r
+  @retval FALSE  HMAC-SHA1 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Init (\r
+  OUT  VOID         *HmacSha1Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacSha1Context == NULL || KeySize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 Context Initialization\r
+  //\r
+  HMAC_CTX_init (HmacSha1Context);\r
+  HMAC_Init_ex (HmacSha1Context, Key, (UINT32) KeySize, EVP_sha1(), NULL);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-SHA1 context.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If NewHmacSha1Context is NULL, then return FALSE.\r
+\r
+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.\r
+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.\r
+\r
+  @retval TRUE   HMAC-SHA1 context copy succeeded.\r
+  @retval FALSE  HMAC-SHA1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Duplicate (\r
+  IN   CONST VOID  *HmacSha1Context,\r
+  OUT  VOID        *NewHmacSha1Context\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacSha1Context == NULL || NewHmacSha1Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (NewHmacSha1Context, HmacSha1Context, sizeof (HMAC_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates HMAC-SHA1 context.\r
+\r
+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not\r
+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 data digest succeeded.\r
+  @retval FALSE  HMAC-SHA1 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Update (\r
+  IN OUT  VOID        *HmacSha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacSha1Context == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL && DataSize != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 digest update\r
+  //\r
+  HMAC_Update (HmacSha1Context, Data, DataSize);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Completes computation of the HMAC-SHA1 digest value.\r
+\r
+  This function completes HMAC-SHA1 digest computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot\r
+  be used again.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should\r
+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If HmacValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.\r
+  @param[out]      HmacValue        Pointer to a buffer that receives the HMAC-SHA1 digest\r
+                                    value (20 bytes).\r
+\r
+  @retval TRUE   HMAC-SHA1 digest computation succeeded.\r
+  @retval FALSE  HMAC-SHA1 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Final (\r
+  IN OUT  VOID   *HmacSha1Context,\r
+  OUT     UINT8  *HmacValue\r
+  )\r
+{\r
+  UINT32  Length;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (HmacSha1Context == NULL || HmacValue == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 digest finalization\r
+  //\r
+  HMAC_Final (HmacSha1Context, HmacValue, &Length);\r
+  HMAC_CTX_cleanup (HmacSha1Context);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h
new file mode 100644 (file)
index 0000000..f73bbc9
--- /dev/null
@@ -0,0 +1,377 @@
+/** @file\r
+  Root include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __OPEN_SSL_SUPPORT_H__\r
+#define __OPEN_SSL_SUPPORT_H__\r
+\r
+#include <efi.h>\r
+#include <efilib.h>\r
+#include <Base.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#define CONST const\r
+\r
+//\r
+// OpenSSL relies on explicit configuration for word size in crypto/bn,\r
+// but we want it to be automatically inferred from the target. So we\r
+// bypass what's in <openssl/opensslconf.h> for OPENSSL_SYS_UEFI, and\r
+// define our own here.\r
+//\r
+#ifdef CONFIG_HEADER_BN_H\r
+#error CONFIG_HEADER_BN_H already defined\r
+#endif\r
+\r
+#define CONFIG_HEADER_BN_H\r
+\r
+#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64)\r
+//\r
+// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs\r
+// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is\r
+// 64-bit. Since using 'long long' works fine on GCC too, just do that.\r
+//\r
+#define SIXTY_FOUR_BIT\r
+#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)\r
+#define THIRTY_TWO_BIT\r
+#else\r
+#error Unknown target architecture\r
+#endif\r
+\r
+//\r
+// File operations are not required for building Open SSL, \r
+// so FILE is mapped to VOID * to pass build\r
+//\r
+typedef VOID  *FILE;\r
+\r
+//\r
+// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h\r
+//\r
+#if !defined(__CC_ARM) || defined(_STDARG_H) // if va_list is not already defined\r
+/*\r
+ * These are now unconditionally #defined by GNU_EFI's efistdarg.h,\r
+ * so we should #undef them here before providing a new definition.\r
+ */\r
+#undef va_arg\r
+#undef va_start\r
+#undef va_end\r
+\r
+#define va_list   VA_LIST\r
+#define va_arg    VA_ARG\r
+#define va_start  VA_START\r
+#define va_end    VA_END\r
+\r
+# if !defined(NO_BUILTIN_VA_FUNCS)\r
+\r
+typedef __builtin_va_list VA_LIST;\r
+\r
+#define VA_START(Marker, Parameter)  __builtin_va_start (Marker, Parameter)\r
+\r
+#define VA_ARG(Marker, TYPE)         ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))\r
+\r
+#define VA_END(Marker)               __builtin_va_end (Marker)\r
+\r
+#define VA_COPY(Dest, Start)         __builtin_va_copy (Dest, Start)\r
+\r
+# else\r
+\r
+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))\r
+///\r
+/// Variable used to traverse the list of arguments. This type can vary by\r
+/// implementation and could be an array or structure.\r
+///\r
+typedef CHAR8 *VA_LIST;\r
+\r
+/**\r
+  Retrieves a pointer to the beginning of a variable argument list, based on\r
+  the name of the parameter that immediately precedes the variable argument list.\r
+\r
+  This function initializes Marker to point to the beginning of the variable\r
+  argument list that immediately follows Parameter.  The method for computing the\r
+  pointer to the next argument in the argument list is CPU-specific following the\r
+  EFIAPI ABI.\r
+\r
+  @param   Marker       The VA_LIST used to traverse the list of arguments.\r
+  @param   Parameter    The name of the parameter that immediately precedes\r
+                        the variable argument list.\r
+\r
+  @return  A pointer to the beginning of a variable argument list.\r
+\r
+**/\r
+#define VA_START(Marker, Parameter) (Marker = (VA_LIST) ((UINTN) & (Parameter) + _INT_SIZE_OF (Parameter)))\r
+\r
+/**\r
+  Returns an argument of a specified type from a variable argument list and updates\r
+  the pointer to the variable argument list to point to the next argument.\r
+\r
+  This function returns an argument of the type specified by TYPE from the beginning\r
+  of the variable argument list specified by Marker.  Marker is then updated to point\r
+  to the next argument in the variable argument list.  The method for computing the\r
+  pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI.\r
+\r
+  @param   Marker   VA_LIST used to traverse the list of arguments.\r
+  @param   TYPE     The type of argument to retrieve from the beginning\r
+                    of the variable argument list.\r
+\r
+  @return  An argument of the type specified by TYPE.\r
+\r
+**/\r
+#define VA_ARG(Marker, TYPE)   (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE)))\r
+\r
+/**\r
+  Terminates the use of a variable argument list.\r
+\r
+  This function initializes Marker so it can no longer be used with VA_ARG().\r
+  After this macro is used, the only way to access the variable argument list is\r
+  by using VA_START() again.\r
+\r
+  @param   Marker   VA_LIST used to traverse the list of arguments.\r
+\r
+**/\r
+#define VA_END(Marker)      (Marker = (VA_LIST) 0)\r
+\r
+/**\r
+  Initializes a VA_LIST as a copy of an existing VA_LIST.\r
+\r
+  This macro initializes Dest as a copy of Start, as if the VA_START macro had been applied to Dest\r
+  followed by the same sequence of uses of the VA_ARG macro as had previously been used to reach\r
+  the present state of Start.\r
+\r
+  @param   Dest   VA_LIST used to traverse the list of arguments.\r
+  @param   Start  VA_LIST used to traverse the list of arguments.\r
+\r
+**/\r
+#define VA_COPY(Dest, Start)  ((void)((Dest) = (Start)))\r
+\r
+# endif\r
+\r
+#else // __CC_ARM\r
+#define va_start(Marker, Parameter)   __va_start(Marker, Parameter)\r
+#define va_arg(Marker, TYPE)          __va_arg(Marker, TYPE)\r
+#define va_end(Marker)                ((void)0)\r
+#endif\r
+\r
+//\r
+// #defines from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+#define ENOMEM       12               /* Cannot allocate memory */\r
+#define EINVAL       22               /* Invalid argument */\r
+#define BUFSIZ       1024             /* size of buffer used by setbuf */\r
+#define INT_MAX      2147483647       /* max value for an int */\r
+#define INT_MIN      (-2147483647-1)  /* min value for an int */\r
+#define LONG_MAX     2147483647L      /* max value for a long */\r
+#define LONG_MIN     (-2147483647-1)  /* min value for a long */\r
+#define ULONG_MAX    0xffffffff       /* max value for an unsigned long */\r
+#define LOG_DAEMON   (3<<3)           /* system daemons */\r
+#define LOG_EMERG    0                /* system is unusable */\r
+#define LOG_ALERT    1                /* action must be taken immediately */\r
+#define LOG_CRIT     2                /* critical conditions */\r
+#define LOG_ERR      3                /* error conditions */\r
+#define LOG_WARNING  4                /* warning conditions */\r
+#define LOG_NOTICE   5                /* normal but significant condition */\r
+#define LOG_INFO     6                /* informational */\r
+#define LOG_DEBUG    7                /* debug-level messages */\r
+#define LOG_PID      0x01             /* log the pid with each message */\r
+#define LOG_CONS     0x02             /* log on the console if errors in sending */\r
+\r
+//\r
+// Macros from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+/* The offsetof() macro calculates the offset of a structure member\r
+   in its structure.  Unfortunately this cannot be written down\r
+   portably, hence it is provided by a Standard C header file.\r
+   For pre-Standard C compilers, here is a version that usually works\r
+   (but watch out!): */\r
+#ifndef offsetof\r
+#define offsetof(type, member) ( (int) & ((type*)0) -> member )\r
+#endif\r
+\r
+//\r
+// Basic types from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+typedef UINTN          size_t;\r
+typedef INTN           ssize_t;\r
+typedef INT64          off_t;\r
+typedef UINT16         mode_t;\r
+typedef long           time_t;\r
+typedef unsigned long  clock_t;\r
+typedef UINT32         uid_t;\r
+typedef UINT32         gid_t;\r
+typedef UINT32         ino_t;\r
+typedef UINT32         dev_t;\r
+typedef UINT16         nlink_t;\r
+typedef int            pid_t;\r
+typedef void           *DIR;\r
+typedef void           __sighandler_t (int);\r
+\r
+//\r
+// Structures from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+struct tm {\r
+  int   tm_sec;     /* seconds after the minute [0-60] */\r
+  int   tm_min;     /* minutes after the hour [0-59] */\r
+  int   tm_hour;    /* hours since midnight [0-23] */\r
+  int   tm_mday;    /* day of the month [1-31] */\r
+  int   tm_mon;     /* months since January [0-11] */\r
+  int   tm_year;    /* years since 1900 */\r
+  int   tm_wday;    /* days since Sunday [0-6] */\r
+  int   tm_yday;    /* days since January 1 [0-365] */\r
+  int   tm_isdst;   /* Daylight Savings Time flag */\r
+  long  tm_gmtoff;  /* offset from CUT in seconds */\r
+  char  *tm_zone;   /* timezone abbreviation */\r
+};\r
+\r
+struct timeval {\r
+  long tv_sec;      /* time value, in seconds */\r
+  long tv_usec;     /* time value, in microseconds */\r
+};\r
+\r
+struct dirent {\r
+  UINT32  d_fileno;         /* file number of entry */\r
+  UINT16  d_reclen;         /* length of this record */\r
+  UINT8   d_type;           /* file type, see below */\r
+  UINT8   d_namlen;         /* length of string in d_name */\r
+  char    d_name[255 + 1];  /* name must be no longer than this */\r
+};\r
+\r
+struct stat {\r
+  dev_t    st_dev;          /* inode's device */\r
+  ino_t    st_ino;          /* inode's number */\r
+  mode_t   st_mode;         /* inode protection mode */\r
+  nlink_t  st_nlink;        /* number of hard links */\r
+  uid_t    st_uid;          /* user ID of the file's owner */\r
+  gid_t    st_gid;          /* group ID of the file's group */\r
+  dev_t    st_rdev;         /* device type */\r
+  time_t   st_atime;        /* time of last access */\r
+  long     st_atimensec;    /* nsec of last access */\r
+  time_t   st_mtime;        /* time of last data modification */\r
+  long     st_mtimensec;    /* nsec of last data modification */\r
+  time_t   st_ctime;        /* time of last file status change */\r
+  long     st_ctimensec;    /* nsec of last file status change */\r
+  off_t    st_size;         /* file size, in bytes */\r
+  INT64    st_blocks;       /* blocks allocated for file */\r
+  UINT32   st_blksize;      /* optimal blocksize for I/O */\r
+  UINT32   st_flags;        /* user defined flags for file */\r
+  UINT32   st_gen;          /* file generation number */\r
+  INT32    st_lspare;\r
+  INT64    st_qspare[2];\r
+};\r
+\r
+//\r
+// Externs from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+extern int errno;\r
+\r
+//\r
+// Function prototypes from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+void           *malloc     (size_t);\r
+void           *realloc    (void *, size_t);\r
+void           free        (void *);\r
+int            isdigit     (int);\r
+int            isspace     (int);\r
+int            tolower     (int);\r
+int            isupper     (int);\r
+int            isxdigit    (int);\r
+int            isalnum     (int);\r
+void           *memcpy     (void *, const void *, size_t);\r
+void           *memset     (void *, int, size_t);\r
+void           *memchr     (const void *, int, size_t);\r
+int            memcmp      (const void *, const void *, size_t);\r
+void           *memmove    (void *, const void *, size_t);\r
+int            strcmp      (const char *, const char *);\r
+int            strncmp     (const char *, const char *, size_t);\r
+char           *strcpy     (char *, const char *);\r
+char           *strncpy    (char *, const char *, size_t);\r
+size_t         strlen      (const char *);\r
+char           *strcat     (char *, const char *);\r
+char           *strchr     (const char *, int);\r
+int            strcasecmp  (const char *, const char *);\r
+int            strncasecmp (const char *, const char *, size_t);\r
+char           *strncpy    (char *, const char *, size_t);\r
+int            strncmp     (const char *, const char *, size_t);\r
+char           *strrchr    (const char *, int);\r
+unsigned long  strtoul     (const char *, char **, int);\r
+long           strtol      (const char *, char **, int);\r
+int            printf      (const char *, ...);\r
+int            sscanf      (const char *, const char *, ...);\r
+int            open        (const char *, int, ...);\r
+int            chmod       (const char *, mode_t);\r
+int            stat        (const char *, struct stat *);\r
+off_t          lseek       (int, off_t, int);\r
+ssize_t        read        (int, void *, size_t);\r
+ssize_t        write       (int, const void *, size_t);\r
+int            close       (int);\r
+FILE           *fopen      (const char *, const char *);\r
+size_t         fread       (void *, size_t, size_t, FILE *);\r
+size_t         fwrite      (const void *, size_t, size_t, FILE *);\r
+char           *fgets      (char *, int, FILE *);\r
+int            fputs       (const char *, FILE *);\r
+int            fprintf     (FILE *, const char *, ...);\r
+int            vfprintf    (FILE *, const char *, VA_LIST);\r
+int            fflush      (FILE *);\r
+int            fclose      (FILE *);\r
+DIR            *opendir    (const char *);\r
+struct dirent  *readdir    (DIR *);\r
+int            closedir    (DIR *);\r
+void           openlog     (const char *, int, int);\r
+void           closelog    (void);\r
+void           syslog      (int, const char *, ...);\r
+time_t         time        (time_t *);\r
+struct tm      *localtime  (const time_t *);\r
+struct tm      *gmtime     (const time_t *);\r
+struct tm      *gmtime_r   (const time_t *, struct tm *);\r
+uid_t          getuid      (void);\r
+uid_t          geteuid     (void);\r
+gid_t          getgid      (void);\r
+gid_t          getegid     (void);\r
+void           qsort       (void *, size_t, size_t, int (*)(const void *, const void *));\r
+char           *getenv     (const char *);\r
+void           exit        (int);\r
+void           abort       (void);\r
+__sighandler_t *signal     (int, __sighandler_t *);\r
+\r
+//\r
+// Global variables from EFI Application Toolkit required to buiild Open SSL\r
+//\r
+extern FILE  *stderr;\r
+extern FILE  *stdin;\r
+extern FILE  *stdout;\r
+\r
+#define AsciiStrLen(x) strlena(x)\r
+#define AsciiStrnCmp(s1, s2, len) strncmpa(s1, s2, len)\r
+\r
+//\r
+// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions\r
+//\r
+#define memcpy(dest,source,count)         ( {CopyMem(dest,source,(UINTN)(count)); dest; })\r
+#define memset(dest,ch,count)             SetMem(dest,(UINTN)(count),(UINT8)(ch))\r
+#define memchr(buf,ch,count)              ScanMem8(buf,(UINTN)(count),(UINT8)ch)\r
+#define memcmp(buf1,buf2,count)           (int)(CompareMem(buf1,buf2,(UINTN)(count)))\r
+#define memmove(dest,source,count)        CopyMem(dest,source,(UINTN)(count))\r
+#define strcmp                            strcmpa\r
+#define strncmp(string1,string2,count)    (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))\r
+#define strcpy(strDest,strSource)         AsciiStrCpy(strDest,strSource)\r
+#define strncpy(strDest,strSource,count)  AsciiStrnCpy(strDest,strSource,(UINTN)count)\r
+#define strlen(str)                       (size_t)(AsciiStrLen(str))\r
+#define strcat(strDest,strSource)         AsciiStrCat(strDest,strSource)\r
+#define strchr(str,ch)                    ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)\r
+#define abort()                           ASSERT (FALSE)\r
+#define assert(expression)\r
+#define localtime(timer)                  NULL\r
+#define gmtime_r(timer,result)            (result = NULL)\r
+#define atoi(nptr)                        Atoi(nptr)\r
+\r
+#endif\r
diff --git a/Cryptlib/Include/Protocol/RuntimeCrypt.h b/Cryptlib/Include/Protocol/RuntimeCrypt.h
new file mode 100644 (file)
index 0000000..bb03a62
--- /dev/null
@@ -0,0 +1,204 @@
+/** @file\r
+  The runtime cryptographic protocol.\r
+  Only limited crypto primitives (SHA-256 and RSA) are provided for runtime\r
+  authenticated variable service.\r
+\r
+Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __EFI_RUNTIME_CRYPT_PROTOCOL_H__\r
+#define __EFI_RUNTIME_CRYPT_PROTOCOL_H__\r
+\r
+#include <Library/BaseCryptLib.h>\r
+\r
+///\r
+/// Runtime Cryptographic Protocol GUID.\r
+///\r
+#define EFI_RUNTIME_CRYPT_PROTOCOL_GUID \\r
+  { \\r
+    0xe1475e0c, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } \\r
+  }\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-256 operations.\r
+\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_SHA256_GET_CONTEXT_SIZE) (\r
+  VOID\r
+  );\r
+\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
+  subsequent use.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to SHA-256 Context being initialized.\r
+\r
+  @retval TRUE   SHA-256 context initialization succeeded.\r
+  @retval FALSE  SHA-256 context initialization failed.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_SHA256_INIT) (\r
+  IN OUT  VOID  *Sha256Context\r
+  );\r
+\r
+\r
+/**\r
+  Performs SHA-256 digest on a data buffer of the specified length. This function can\r
+  be called multiple times to compute the digest of long or discontinuous data streams.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataLength     Length of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-256 data digest succeeded.\r
+  @retval FALSE  Invalid SHA-256 context. After Sha256Final function has been called, the\r
+                 SHA-256 context cannot be reused.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_SHA256_UPDATE) (\r
+  IN OUT  VOID        *Sha256Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataLength\r
+  );\r
+\r
+\r
+/**\r
+  Completes SHA-256 hash computation and retrieves the digest value into the specified\r
+  memory. After this function has been called, the SHA-256 context cannot be used again.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to SHA-256 context\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest\r
+                                  value (32 bytes).\r
+\r
+  @retval TRUE   SHA-256 digest computation succeeded.\r
+  @retval FALSE  SHA-256 digest computation failed.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_SHA256_FINAL) (\r
+  IN OUT  VOID   *Sha256Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+\r
+/**\r
+  Allocates and Initializes one RSA Context for subsequent use.\r
+\r
+  @return  Pointer to the RSA Context that has been initialized.\r
+           If the allocations fails, RsaNew() returns NULL.\r
+\r
+**/\r
+typedef\r
+VOID *\r
+(EFIAPI *EFI_RUNTIME_CRYPT_RSA_NEW) (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release the specified RSA Context.\r
+\r
+  @param[in]  RsaContext  Pointer to the RSA context to be released.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *EFI_RUNTIME_CRYPT_RSA_FREE) (\r
+  IN  VOID  *RsaContext\r
+  );\r
+\r
+/**\r
+  Sets the tag-designated RSA key component into the established RSA context from\r
+  the user-specified nonnegative integer (octet string format represented in RSA\r
+  PKCS#1).\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[in]       BigNumber   Pointer to octet integer buffer.\r
+  @param[in]       BnLength    Length of big number buffer in bytes.\r
+\r
+  @return  TRUE   RSA key component was set successfully.\r
+  @return  FALSE  Invalid RSA key component tag.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_RSA_SET_KEY) (\r
+  IN OUT VOID         *RsaContext,\r
+  IN     RSA_KEY_TAG  KeyTag,\r
+  IN     CONST UINT8  *BigNumber,\r
+  IN     UINTN        BnLength\r
+  );\r
+\r
+/**\r
+  Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If MessageHash is NULL, then return FALSE.\r
+  If Signature is NULL, then return FALSE.\r
+  If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.\r
+\r
+  @param[in]  RsaContext   Pointer to RSA context for signature verification.\r
+  @param[in]  MessageHash  Pointer to octet message hash to be checked.\r
+  @param[in]  HashLength   Length of the message hash in bytes.\r
+  @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.\r
+  @param[in]  SigLength    Length of signature in bytes.\r
+\r
+  @return  TRUE   Valid signature encoded in PKCS1-v1_5.\r
+  @return  FALSE  Invalid signature or invalid RSA context.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_RUNTIME_CRYPT_RSA_PKCS1_VERIFY) (\r
+  IN  VOID         *RsaContext,\r
+  IN  CONST UINT8  *MessageHash,\r
+  IN  UINTN        HashLength,\r
+  IN  UINT8        *Signature,\r
+  IN  UINTN        SigLength\r
+  );\r
+\r
+///\r
+/// Runtime Cryptographic Protocol Structure.\r
+///\r
+typedef struct {\r
+  EFI_RUNTIME_CRYPT_SHA256_GET_CONTEXT_SIZE  Sha256GetContextSize;\r
+  EFI_RUNTIME_CRYPT_SHA256_INIT              Sha256Init;\r
+  EFI_RUNTIME_CRYPT_SHA256_UPDATE            Sha256Update;\r
+  EFI_RUNTIME_CRYPT_SHA256_FINAL             Sha256Final;\r
+  EFI_RUNTIME_CRYPT_RSA_NEW                  RsaNew;\r
+  EFI_RUNTIME_CRYPT_RSA_FREE                 RsaFree;\r
+  EFI_RUNTIME_CRYPT_RSA_SET_KEY              RsaSetKey;\r
+  EFI_RUNTIME_CRYPT_RSA_PKCS1_VERIFY         RsaPkcs1Verify;\r
+} EFI_RUNTIME_CRYPT_PROTOCOL;\r
+\r
+extern EFI_GUID gEfiRuntimeCryptProtocolGuid;\r
+\r
+#endif\r
diff --git a/Cryptlib/Include/arpa/inet.h b/Cryptlib/Include/arpa/inet.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/assert.h b/Cryptlib/Include/assert.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/ctype.h b/Cryptlib/Include/ctype.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/dirent.h b/Cryptlib/Include/dirent.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/errno.h b/Cryptlib/Include/errno.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/limits.h b/Cryptlib/Include/limits.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/malloc.h b/Cryptlib/Include/malloc.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/math.h b/Cryptlib/Include/math.h
new file mode 100644 (file)
index 0000000..a21f554
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OPEN SSL \r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/memory.h b/Cryptlib/Include/memory.h
new file mode 100644 (file)
index 0000000..092b3cd
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/netdb.h b/Cryptlib/Include/netdb.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/netinet/in.h b/Cryptlib/Include/netinet/in.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/openssl/README b/Cryptlib/Include/openssl/README
new file mode 100644 (file)
index 0000000..1594010
--- /dev/null
@@ -0,0 +1 @@
+This directory contains all the public include files from the OpenSSL project.\r
diff --git a/Cryptlib/Include/openssl/aes.h b/Cryptlib/Include/openssl/aes.h
new file mode 100644 (file)
index 0000000..faa66c4
--- /dev/null
@@ -0,0 +1,149 @@
+/* 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_H
+# define HEADER_AES_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_AES
+#  error AES is disabled.
+# endif
+
+# include <stddef.h>
+
+# define AES_ENCRYPT     1
+# define AES_DECRYPT     0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+# define AES_MAXNR 14
+# define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+# ifdef AES_LONG
+    unsigned long rd_key[4 * (AES_MAXNR + 1)];
+# else
+    unsigned int rd_key[4 * (AES_MAXNR + 1)];
+# endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+
+int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                                AES_KEY *key);
+int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                                AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+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);
+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);
+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);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num);
+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);
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        const AES_KEY *key2, const unsigned char *ivec,
+                        const int enc);
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+                 unsigned char *out,
+                 const unsigned char *in, unsigned int inlen);
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+                   unsigned char *out,
+                   const unsigned char *in, unsigned int inlen);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif                          /* !HEADER_AES_H */
diff --git a/Cryptlib/Include/openssl/asn1.h b/Cryptlib/Include/openssl/asn1.h
new file mode 100644 (file)
index 0000000..68e791f
--- /dev/null
@@ -0,0 +1,1419 @@
+/* crypto/asn1/asn1.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_ASN1_H
+# define HEADER_ASN1_H
+
+# include <time.h>
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+
+# include <openssl/symhacks.h>
+
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define V_ASN1_UNIVERSAL                0x00
+# define V_ASN1_APPLICATION              0x40
+# define V_ASN1_CONTEXT_SPECIFIC         0x80
+# define V_ASN1_PRIVATE                  0xc0
+
+# define V_ASN1_CONSTRUCTED              0x20
+# define V_ASN1_PRIMITIVE_TAG            0x1f
+# define V_ASN1_PRIMATIVE_TAG            0x1f
+
+# define V_ASN1_APP_CHOOSE               -2/* let the recipient choose */
+# define V_ASN1_OTHER                    -3/* used in ASN1_TYPE */
+# define V_ASN1_ANY                      -4/* used in ASN1 template code */
+
+# define V_ASN1_NEG                      0x100/* negative flag */
+
+# define V_ASN1_UNDEF                    -1
+# define V_ASN1_EOC                      0
+# define V_ASN1_BOOLEAN                  1 /**/
+# define V_ASN1_INTEGER                  2
+# define V_ASN1_NEG_INTEGER              (2 | V_ASN1_NEG)
+# define V_ASN1_BIT_STRING               3
+# define V_ASN1_OCTET_STRING             4
+# define V_ASN1_NULL                     5
+# define V_ASN1_OBJECT                   6
+# define V_ASN1_OBJECT_DESCRIPTOR        7
+# define V_ASN1_EXTERNAL                 8
+# define V_ASN1_REAL                     9
+# define V_ASN1_ENUMERATED               10
+# define V_ASN1_NEG_ENUMERATED           (10 | V_ASN1_NEG)
+# define V_ASN1_UTF8STRING               12
+# define V_ASN1_SEQUENCE                 16
+# define V_ASN1_SET                      17
+# define V_ASN1_NUMERICSTRING            18 /**/
+# define V_ASN1_PRINTABLESTRING          19
+# define V_ASN1_T61STRING                20
+# define V_ASN1_TELETEXSTRING            20/* alias */
+# define V_ASN1_VIDEOTEXSTRING           21 /**/
+# define V_ASN1_IA5STRING                22
+# define V_ASN1_UTCTIME                  23
+# define V_ASN1_GENERALIZEDTIME          24 /**/
+# define V_ASN1_GRAPHICSTRING            25 /**/
+# define V_ASN1_ISO64STRING              26 /**/
+# define V_ASN1_VISIBLESTRING            26/* alias */
+# define V_ASN1_GENERALSTRING            27 /**/
+# define V_ASN1_UNIVERSALSTRING          28 /**/
+# define V_ASN1_BMPSTRING                30
+/* For use with d2i_ASN1_type_bytes() */
+# define B_ASN1_NUMERICSTRING    0x0001
+# define B_ASN1_PRINTABLESTRING  0x0002
+# define B_ASN1_T61STRING        0x0004
+# define B_ASN1_TELETEXSTRING    0x0004
+# define B_ASN1_VIDEOTEXSTRING   0x0008
+# define B_ASN1_IA5STRING        0x0010
+# define B_ASN1_GRAPHICSTRING    0x0020
+# define B_ASN1_ISO64STRING      0x0040
+# define B_ASN1_VISIBLESTRING    0x0040
+# define B_ASN1_GENERALSTRING    0x0080
+# define B_ASN1_UNIVERSALSTRING  0x0100
+# define B_ASN1_OCTET_STRING     0x0200
+# define B_ASN1_BIT_STRING       0x0400
+# define B_ASN1_BMPSTRING        0x0800
+# define B_ASN1_UNKNOWN          0x1000
+# define B_ASN1_UTF8STRING       0x2000
+# define B_ASN1_UTCTIME          0x4000
+# define B_ASN1_GENERALIZEDTIME  0x8000
+# define B_ASN1_SEQUENCE         0x10000
+/* For use with ASN1_mbstring_copy() */
+# define MBSTRING_FLAG           0x1000
+# define MBSTRING_UTF8           (MBSTRING_FLAG)
+# define MBSTRING_ASC            (MBSTRING_FLAG|1)
+# define MBSTRING_BMP            (MBSTRING_FLAG|2)
+# define MBSTRING_UNIV           (MBSTRING_FLAG|4)
+# define SMIME_OLDMIME           0x400
+# define SMIME_CRLFEOL           0x800
+# define SMIME_STREAM            0x1000
+    struct X509_algor_st;
+DECLARE_STACK_OF(X509_ALGOR)
+
+# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */
+# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */
+
+/*
+ * We MUST make sure that, except for constness, asn1_ctx_st and
+ * asn1_const_ctx are exactly the same.  Fortunately, as soon as the old ASN1
+ * parsing macros are gone, we can throw this away as well...
+ */
+typedef struct asn1_ctx_st {
+    unsigned char *p;           /* work char pointer */
+    int eos;                    /* end of sequence read for indefinite
+                                 * encoding */
+    int error;                  /* error code to use when returning an error */
+    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
+    int tag;                    /* tag from last 'get object' */
+    int xclass;                 /* class from last 'get object' */
+    long slen;                  /* length of last 'get object' */
+    unsigned char *max;         /* largest value of p allowed */
+    unsigned char *q;           /* temporary variable */
+    unsigned char **pp;         /* variable */
+    int line;                   /* used in error processing */
+} ASN1_CTX;
+
+typedef struct asn1_const_ctx_st {
+    const unsigned char *p;     /* work char pointer */
+    int eos;                    /* end of sequence read for indefinite
+                                 * encoding */
+    int error;                  /* error code to use when returning an error */
+    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
+    int tag;                    /* tag from last 'get object' */
+    int xclass;                 /* class from last 'get object' */
+    long slen;                  /* length of last 'get object' */
+    const unsigned char *max;   /* largest value of p allowed */
+    const unsigned char *q;     /* temporary variable */
+    const unsigned char **pp;   /* variable */
+    int line;                   /* used in error processing */
+} ASN1_const_CTX;
+
+/*
+ * These are used internally in the ASN1_OBJECT to keep track of whether the
+ * names and data need to be free()ed
+ */
+# define ASN1_OBJECT_FLAG_DYNAMIC         0x01/* internal use */
+# define ASN1_OBJECT_FLAG_CRITICAL        0x02/* critical x509v3 object id */
+# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
+# define ASN1_OBJECT_FLAG_DYNAMIC_DATA    0x08/* internal use */
+struct asn1_object_st {
+    const char *sn, *ln;
+    int nid;
+    int length;
+    const unsigned char *data;  /* data remains const after init */
+    int flags;                  /* Should we free this one */
+};
+
+# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
+/*
+ * This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should be
+ * inserted in the memory buffer
+ */
+# define ASN1_STRING_FLAG_NDEF 0x010
+
+/*
+ * This flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been accessed.
+ * The flag will be reset when content has been written to it.
+ */
+
+# define ASN1_STRING_FLAG_CONT 0x020
+/*
+ * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+# define ASN1_STRING_FLAG_MSTRING 0x040
+/* This is the base type that holds just about everything :-) */
+struct asn1_string_st {
+    int length;
+    int type;
+    unsigned char *data;
+    /*
+     * The value of the following field depends on the type being held.  It
+     * is mostly being used for BIT_STRING so if the input data has a
+     * non-zero 'unused bits' value, it will be handled correctly
+     */
+    long flags;
+};
+
+/*
+ * ASN1_ENCODING structure: this is used to save the received encoding of an
+ * ASN1 type. This is useful to get round problems with invalid encodings
+ * which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st {
+    unsigned char *enc;         /* DER encoding */
+    long len;                   /* Length of encoding */
+    int modified;               /* set to 1 if 'enc' is invalid */
+} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+# define ASN1_LONG_UNDEF 0x7fffffffL
+
+# define STABLE_FLAGS_MALLOC     0x01
+# define STABLE_NO_MASK          0x02
+# define DIRSTRING_TYPE  \
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+    int nid;
+    long minsize;
+    long maxsize;
+    unsigned long mask;
+    unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+# 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
+
+/*
+ * Declarations for template structures: for full definitions see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(itname)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(const type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(name)
+
+# define DECLARE_ASN1_NDEF_FUNCTION(name) \
+        int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+# define DECLARE_ASN1_FUNCTIONS_const(name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        type *name##_new(void); \
+        void name##_free(type *a);
+
+# define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+        DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                         const ASN1_PCTX *pctx);
+
+# define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+# define I2D_OF(type) int (*)(type *,unsigned char **)
+# define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+# define CHECKED_D2I_OF(type, d2i) \
+    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+# define CHECKED_I2D_OF(type, i2d) \
+    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+# define CHECKED_NEW_OF(type, xnew) \
+    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+# define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+# define CHECKED_PPTR_OF(type, p) \
+    ((void**) (1 ? p : (type**)0))
+
+# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/*-
+ * The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING;
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#  define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#  define DECLARE_ASN1_ITEM(name) \
+        OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+# else
+
+/*
+ * Platforms that can't easily handle shared global variables are declared as
+ * functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM *ASN1_ITEM_EXP (void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#  define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#  define DECLARE_ASN1_ITEM(name) \
+        const ASN1_ITEM * name##_it(void);
+
+# endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/*
+ * These determine which characters to escape: RFC2253 special characters,
+ * control characters and MSB set characters
+ */
+
+# define ASN1_STRFLGS_ESC_2253           1
+# define ASN1_STRFLGS_ESC_CTRL           2
+# define ASN1_STRFLGS_ESC_MSB            4
+
+/*
+ * This flag determines how we do escaping: normally RC2253 backslash only,
+ * set this to use backslash and quote.
+ */
+
+# define ASN1_STRFLGS_ESC_QUOTE          8
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+# define CHARTYPE_PRINTABLESTRING        0x10
+/* Character needs escaping if it is the first character */
+# define CHARTYPE_FIRST_ESC_2253         0x20
+/* Character needs escaping if it is the last character */
+# define CHARTYPE_LAST_ESC_2253          0x40
+
+/*
+ * NB the internal flags are safely reused below by flags handled at the top
+ * level.
+ */
+
+/*
+ * If this is set we convert all character strings to UTF8 first
+ */
+
+# define ASN1_STRFLGS_UTF8_CONVERT       0x10
+
+/*
+ * If this is set we don't attempt to interpret content: just assume all
+ * strings are 1 byte per character. This will produce some pretty odd
+ * looking output!
+ */
+
+# define ASN1_STRFLGS_IGNORE_TYPE        0x20
+
+/* If this is set we include the string type in the output */
+# define ASN1_STRFLGS_SHOW_TYPE          0x40
+
+/*
+ * This determines which strings to display and which to 'dump' (hex dump of
+ * content octets or DER encoding). We can only dump non character strings or
+ * everything. If we don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to the usual escaping
+ * options.
+ */
+
+# define ASN1_STRFLGS_DUMP_ALL           0x80
+# define ASN1_STRFLGS_DUMP_UNKNOWN       0x100
+
+/*
+ * These determine what 'dumping' does, we can dump the content octets or the
+ * DER encoding: both use the RFC2253 #XXXXX notation.
+ */
+
+# define ASN1_STRFLGS_DUMP_DER           0x200
+
+/*
+ * All the string flags consistent with RFC2253, escaping control characters
+ * isn't essential in RFC2253 but it is advisable anyway.
+ */
+
+# define ASN1_STRFLGS_RFC2253    (ASN1_STRFLGS_ESC_2253 | \
+                                ASN1_STRFLGS_ESC_CTRL | \
+                                ASN1_STRFLGS_ESC_MSB | \
+                                ASN1_STRFLGS_UTF8_CONVERT | \
+                                ASN1_STRFLGS_DUMP_UNKNOWN | \
+                                ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st {
+    int type;
+    union {
+        char *ptr;
+        ASN1_BOOLEAN boolean;
+        ASN1_STRING *asn1_string;
+        ASN1_OBJECT *object;
+        ASN1_INTEGER *integer;
+        ASN1_ENUMERATED *enumerated;
+        ASN1_BIT_STRING *bit_string;
+        ASN1_OCTET_STRING *octet_string;
+        ASN1_PRINTABLESTRING *printablestring;
+        ASN1_T61STRING *t61string;
+        ASN1_IA5STRING *ia5string;
+        ASN1_GENERALSTRING *generalstring;
+        ASN1_BMPSTRING *bmpstring;
+        ASN1_UNIVERSALSTRING *universalstring;
+        ASN1_UTCTIME *utctime;
+        ASN1_GENERALIZEDTIME *generalizedtime;
+        ASN1_VISIBLESTRING *visiblestring;
+        ASN1_UTF8STRING *utf8string;
+        /*
+         * set and sequence are left complete and still contain the set or
+         * sequence bytes
+         */
+        ASN1_STRING *set;
+        ASN1_STRING *sequence;
+        ASN1_VALUE *asn1_value;
+    } value;
+} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st {
+    ASN1_OCTET_STRING *header;
+    X509 *cert;
+} NETSCAPE_X509;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+    int bitnum;
+    const char *lname;
+    const char *sname;
+} BIT_STRING_BITNAME;
+
+# define M_ASN1_STRING_length(x) ((x)->length)
+# define M_ASN1_STRING_length_set(x, n)  ((x)->length = (n))
+# define M_ASN1_STRING_type(x)   ((x)->type)
+# define M_ASN1_STRING_data(x)   ((x)->data)
+
+/* Macros for string operations */
+# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\
+                ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+# define M_ASN1_BIT_STRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+                ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+# define M_ASN1_INTEGER_new()    (ASN1_INTEGER *)\
+                ASN1_STRING_type_new(V_ASN1_INTEGER)
+# define M_ASN1_INTEGER_free(a)          ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+                ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
+                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
+                ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+# define M_ASN1_ENUMERATED_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+                ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_ENUMERATED_cmp(a,b)      ASN1_STRING_cmp(\
+                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+# define M_ASN1_OCTET_STRING_new()       (ASN1_OCTET_STRING *)\
+                ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+# define M_ASN1_OCTET_STRING_free(a)     ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+                ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+# define M_ASN1_OCTET_STRING_set(a,b,c)  ASN1_STRING_set((ASN1_STRING *)a,b,c)
+# define M_ASN1_OCTET_STRING_print(a,b)  ASN1_STRING_print(a,(ASN1_STRING *)b)
+# define M_i2d_ASN1_OCTET_STRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+                V_ASN1_UNIVERSAL)
+
+# define B_ASN1_TIME \
+                        B_ASN1_UTCTIME | \
+                        B_ASN1_GENERALIZEDTIME
+
+# define B_ASN1_PRINTABLE \
+                        B_ASN1_NUMERICSTRING| \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_T61STRING| \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_BIT_STRING| \
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING|\
+                        B_ASN1_SEQUENCE|\
+                        B_ASN1_UNKNOWN
+
+# define B_ASN1_DIRECTORYSTRING \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_TELETEXSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_UTF8STRING
+
+# define B_ASN1_DISPLAYTEXT \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_VISIBLESTRING| \
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING
+
+# define M_ASN1_PRINTABLE_new()  ASN1_STRING_type_new(V_ASN1_T61STRING)
+# define M_ASN1_PRINTABLE_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+                pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+                        B_ASN1_PRINTABLE)
+
+# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+# define M_DIRECTORYSTRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+                                                pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_DIRECTORYSTRING(a,pp,l) \
+                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+                        B_ASN1_DIRECTORYSTRING)
+
+# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+                                                pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_DISPLAYTEXT(a,pp,l) \
+                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+                        B_ASN1_DISPLAYTEXT)
+
+# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+                ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+# define M_ASN1_PRINTABLESTRING_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+                V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+                (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+# define M_ASN1_T61STRING_new()  (ASN1_T61STRING *)\
+                ASN1_STRING_type_new(V_ASN1_T61STRING)
+# define M_ASN1_T61STRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_T61STRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+                V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_T61STRING(a,pp,l) \
+                (ASN1_T61STRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+# define M_ASN1_IA5STRING_new()  (ASN1_IA5STRING *)\
+                ASN1_STRING_type_new(V_ASN1_IA5STRING)
+# define M_ASN1_IA5STRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_IA5STRING_dup(a) \
+                (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_i2d_ASN1_IA5STRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_IA5STRING(a,pp,l) \
+                (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+                        B_ASN1_IA5STRING)
+
+# define M_ASN1_UTCTIME_new()    (ASN1_UTCTIME *)\
+                ASN1_STRING_type_new(V_ASN1_UTCTIME)
+# define M_ASN1_UTCTIME_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+                ASN1_STRING_dup((const ASN1_STRING *)a)
+
+# define M_ASN1_GENERALIZEDTIME_new()    (ASN1_GENERALIZEDTIME *)\
+                ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+# define M_ASN1_GENERALIZEDTIME_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+        (const ASN1_STRING *)a)
+
+# define M_ASN1_TIME_new()       (ASN1_TIME *)\
+                ASN1_STRING_type_new(V_ASN1_UTCTIME)
+# define M_ASN1_TIME_free(a)     ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+        ASN1_STRING_dup((const ASN1_STRING *)a)
+
+# define M_ASN1_GENERALSTRING_new()      (ASN1_GENERALSTRING *)\
+                ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+# define M_ASN1_GENERALSTRING_free(a)    ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_GENERALSTRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+                (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+# define M_ASN1_UNIVERSALSTRING_new()    (ASN1_UNIVERSALSTRING *)\
+                ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+# define M_ASN1_UNIVERSALSTRING_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+                (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+# define M_ASN1_BMPSTRING_new()  (ASN1_BMPSTRING *)\
+                ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+# define M_ASN1_BMPSTRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_BMPSTRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+                (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+# define M_ASN1_VISIBLESTRING_new()      (ASN1_VISIBLESTRING *)\
+                ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+# define M_ASN1_VISIBLESTRING_free(a)    ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+                (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
+                ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+# define M_ASN1_UTF8STRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_UTF8STRING(a,pp) \
+                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+                        V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+                (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+                ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+  /* for the is_set parameter to i2d_ASN1_SET */
+# define IS_SEQUENCE     0
+# define IS_SET          1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ASN1_OBJECT *ASN1_OBJECT_new(void);
+void ASN1_OBJECT_free(ASN1_OBJECT *a);
+int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp);
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *ASN1_STRING_new(void);
+void ASN1_STRING_free(ASN1_STRING *a);
+void ASN1_STRING_clear_free(ASN1_STRING *a);
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING *ASN1_STRING_type_new(int type);
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+  /*
+   * Since this is used to store all sorts of things, via macros, for now,
+   * make its data void *
+   */
+int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char *ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+                                     const unsigned char **pp, long length);
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+                          unsigned char *flags, int flags_len);
+
+# ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent);
+# endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+                            BIT_STRING_BITNAME *tbl);
+
+int i2d_ASN1_BOOLEAN(int a, unsigned char **pp);
+int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                               long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                                long length);
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+                               int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+# if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+# endif
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+                                               time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+                                               time_t t, int offset_day,
+                                               long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
+                          int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+                         int offset_day, long offset_sec);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME
+                                                   **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+                 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+                                      const unsigned char **pp,
+                                      long length, d2i_of_void *d2i,
+                                      void (*free_func) (OPENSSL_BLOCK),
+                                      int ex_tag, int ex_class);
+
+# ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size);
+int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+# endif
+int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+                                const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+                            long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
+                                 long length, int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+                    int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p, long len);
+int ASN1_const_check_infinite_end(const unsigned char **p, long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+                     int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+# define ASN1_dup_of(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(type, x)))
+
+# define ASN1_dup_of_const(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+# define M_ASN1_free_of(x, type) \
+                ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+# ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);
+
+#  define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+                        CHECKED_D2I_OF(type, d2i), \
+                        in, \
+                        CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);
+
+#  define ASN1_i2d_fp_of(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+# endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+# ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);
+
+#  define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+                          CHECKED_D2I_OF(type, d2i), \
+                          in, \
+                          CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);
+
+#  define ASN1_i2d_bio_of(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                  unsigned char *buf, int off);
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump);
+# endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+                                  unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
+                                  unsigned char *data, int max_len);
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+                                         d2i_of_void *d2i,
+                                         void (*free_func) (OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+                             unsigned char **buf, int *len);
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+                              ASN1_OCTET_STRING **oct);
+
+# define ASN1_pack_string_of(type,obj,i2d,oct) \
+    (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
+                      CHECKED_I2D_OF(type, i2d), \
+                      oct))
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it,
+                            ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+                       int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in,
+                          long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+                       const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+# define ASN1_PCTX_FLAGS_SHOW_ABSENT             0x001
+/* Mark start and end of SEQUENCE */
+# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE           0x002
+/* Mark start and end of SEQUENCE/SET OF */
+# define ASN1_PCTX_FLAGS_SHOW_SSOF               0x004
+/* Show the ASN1 type of primitives */
+# define ASN1_PCTX_FLAGS_SHOW_TYPE               0x008
+/* Don't show ASN1 type of ANY */
+# define ASN1_PCTX_FLAGS_NO_ANY_TYPE             0x010
+/* Don't show ASN1 type of MSTRINGs */
+# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE         0x020
+/* Don't show field names in SEQUENCE */
+# define ASN1_PCTX_FLAGS_NO_FIELD_NAME           0x040
+/* Show structure names of each SEQUENCE field */
+# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME  0x080
+/* Don't show structure name even at top level */
+# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME          0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                        const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                              const char *hdr, const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+                     int ctype_nid, int econt_nid,
+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+# define ASN1_F_A2D_ASN1_OBJECT                           100
+# define ASN1_F_A2I_ASN1_ENUMERATED                       101
+# define ASN1_F_A2I_ASN1_INTEGER                          102
+# define ASN1_F_A2I_ASN1_STRING                           103
+# define ASN1_F_APPEND_EXP                                176
+# define ASN1_F_ASN1_BIT_STRING_SET_BIT                   183
+# define ASN1_F_ASN1_CB                                   177
+# define ASN1_F_ASN1_CHECK_TLEN                           104
+# define ASN1_F_ASN1_COLLATE_PRIMITIVE                    105
+# define ASN1_F_ASN1_COLLECT                              106
+# define ASN1_F_ASN1_D2I_EX_PRIMITIVE                     108
+# define ASN1_F_ASN1_D2I_FP                               109
+# define ASN1_F_ASN1_D2I_READ_BIO                         107
+# define ASN1_F_ASN1_DIGEST                               184
+# define ASN1_F_ASN1_DO_ADB                               110
+# define ASN1_F_ASN1_DUP                                  111
+# define ASN1_F_ASN1_ENUMERATED_SET                       112
+# define ASN1_F_ASN1_ENUMERATED_TO_BN                     113
+# define ASN1_F_ASN1_EX_C2I                               204
+# define ASN1_F_ASN1_FIND_END                             190
+# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ                  216
+# define ASN1_F_ASN1_GENERALIZEDTIME_SET                  185
+# define ASN1_F_ASN1_GENERATE_V3                          178
+# define ASN1_F_ASN1_GET_OBJECT                           114
+# define ASN1_F_ASN1_HEADER_NEW                           115
+# define ASN1_F_ASN1_I2D_BIO                              116
+# define ASN1_F_ASN1_I2D_FP                               117
+# define ASN1_F_ASN1_INTEGER_SET                          118
+# define ASN1_F_ASN1_INTEGER_TO_BN                        119
+# define ASN1_F_ASN1_ITEM_D2I_FP                          206
+# define ASN1_F_ASN1_ITEM_DUP                             191
+# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW                  121
+# define ASN1_F_ASN1_ITEM_EX_D2I                          120
+# define ASN1_F_ASN1_ITEM_I2D_BIO                         192
+# define ASN1_F_ASN1_ITEM_I2D_FP                          193
+# define ASN1_F_ASN1_ITEM_PACK                            198
+# define ASN1_F_ASN1_ITEM_SIGN                            195
+# define ASN1_F_ASN1_ITEM_SIGN_CTX                        220
+# define ASN1_F_ASN1_ITEM_UNPACK                          199
+# define ASN1_F_ASN1_ITEM_VERIFY                          197
+# define ASN1_F_ASN1_MBSTRING_NCOPY                       122
+# define ASN1_F_ASN1_OBJECT_NEW                           123
+# define ASN1_F_ASN1_OUTPUT_DATA                          214
+# define ASN1_F_ASN1_PACK_STRING                          124
+# define ASN1_F_ASN1_PCTX_NEW                             205
+# define ASN1_F_ASN1_PKCS5_PBE_SET                        125
+# define ASN1_F_ASN1_SEQ_PACK                             126
+# define ASN1_F_ASN1_SEQ_UNPACK                           127
+# define ASN1_F_ASN1_SIGN                                 128
+# define ASN1_F_ASN1_STR2TYPE                             179
+# define ASN1_F_ASN1_STRING_SET                           186
+# define ASN1_F_ASN1_STRING_TABLE_ADD                     129
+# define ASN1_F_ASN1_STRING_TYPE_NEW                      130
+# define ASN1_F_ASN1_TEMPLATE_EX_D2I                      132
+# define ASN1_F_ASN1_TEMPLATE_NEW                         133
+# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I                   131
+# define ASN1_F_ASN1_TIME_ADJ                             217
+# define ASN1_F_ASN1_TIME_SET                             175
+# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING             134
+# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING                 135
+# define ASN1_F_ASN1_UNPACK_STRING                        136
+# define ASN1_F_ASN1_UTCTIME_ADJ                          218
+# define ASN1_F_ASN1_UTCTIME_SET                          187
+# define ASN1_F_ASN1_VERIFY                               137
+# define ASN1_F_B64_READ_ASN1                             209
+# define ASN1_F_B64_WRITE_ASN1                            210
+# define ASN1_F_BIO_NEW_NDEF                              208
+# define ASN1_F_BITSTR_CB                                 180
+# define ASN1_F_BN_TO_ASN1_ENUMERATED                     138
+# define ASN1_F_BN_TO_ASN1_INTEGER                        139
+# define ASN1_F_C2I_ASN1_BIT_STRING                       189
+# define ASN1_F_C2I_ASN1_INTEGER                          194
+# define ASN1_F_C2I_ASN1_OBJECT                           196
+# define ASN1_F_COLLECT_DATA                              140
+# define ASN1_F_D2I_ASN1_BIT_STRING                       141
+# define ASN1_F_D2I_ASN1_BOOLEAN                          142
+# define ASN1_F_D2I_ASN1_BYTES                            143
+# define ASN1_F_D2I_ASN1_GENERALIZEDTIME                  144
+# define ASN1_F_D2I_ASN1_HEADER                           145
+# define ASN1_F_D2I_ASN1_INTEGER                          146
+# define ASN1_F_D2I_ASN1_OBJECT                           147
+# define ASN1_F_D2I_ASN1_SET                              148
+# define ASN1_F_D2I_ASN1_TYPE_BYTES                       149
+# define ASN1_F_D2I_ASN1_UINTEGER                         150
+# define ASN1_F_D2I_ASN1_UTCTIME                          151
+# define ASN1_F_D2I_AUTOPRIVATEKEY                        207
+# define ASN1_F_D2I_NETSCAPE_RSA                          152
+# define ASN1_F_D2I_NETSCAPE_RSA_2                        153
+# define ASN1_F_D2I_PRIVATEKEY                            154
+# define ASN1_F_D2I_PUBLICKEY                             155
+# define ASN1_F_D2I_RSA_NET                               200
+# define ASN1_F_D2I_RSA_NET_2                             201
+# define ASN1_F_D2I_X509                                  156
+# define ASN1_F_D2I_X509_CINF                             157
+# define ASN1_F_D2I_X509_PKEY                             159
+# define ASN1_F_I2D_ASN1_BIO_STREAM                       211
+# define ASN1_F_I2D_ASN1_SET                              188
+# define ASN1_F_I2D_ASN1_TIME                             160
+# define ASN1_F_I2D_DSA_PUBKEY                            161
+# define ASN1_F_I2D_EC_PUBKEY                             181
+# define ASN1_F_I2D_PRIVATEKEY                            163
+# define ASN1_F_I2D_PUBLICKEY                             164
+# define ASN1_F_I2D_RSA_NET                               162
+# define ASN1_F_I2D_RSA_PUBKEY                            165
+# define ASN1_F_LONG_C2I                                  166
+# define ASN1_F_OID_MODULE_INIT                           174
+# define ASN1_F_PARSE_TAGGING                             182
+# define ASN1_F_PKCS5_PBE2_SET_IV                         167
+# define ASN1_F_PKCS5_PBE_SET                             202
+# define ASN1_F_PKCS5_PBE_SET0_ALGOR                      215
+# define ASN1_F_PKCS5_PBKDF2_SET                          219
+# define ASN1_F_SMIME_READ_ASN1                           212
+# define ASN1_F_SMIME_TEXT                                213
+# define ASN1_F_X509_CINF_NEW                             168
+# define ASN1_F_X509_CRL_ADD0_REVOKED                     169
+# define ASN1_F_X509_INFO_NEW                             170
+# define ASN1_F_X509_NAME_ENCODE                          203
+# define ASN1_F_X509_NAME_EX_D2I                          158
+# define ASN1_F_X509_NAME_EX_NEW                          171
+# define ASN1_F_X509_NEW                                  172
+# define ASN1_F_X509_PKEY_NEW                             173
+
+/* Reason codes. */
+# define ASN1_R_ADDING_OBJECT                             171
+# define ASN1_R_ASN1_PARSE_ERROR                          203
+# define ASN1_R_ASN1_SIG_PARSE_ERROR                      204
+# define ASN1_R_AUX_ERROR                                 100
+# define ASN1_R_BAD_CLASS                                 101
+# define ASN1_R_BAD_OBJECT_HEADER                         102
+# define ASN1_R_BAD_PASSWORD_READ                         103
+# define ASN1_R_BAD_TAG                                   104
+# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH                 214
+# define ASN1_R_BN_LIB                                    105
+# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                   106
+# define ASN1_R_BUFFER_TOO_SMALL                          107
+# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER           108
+# define ASN1_R_CONTEXT_NOT_INITIALISED                   217
+# define ASN1_R_DATA_IS_WRONG                             109
+# define ASN1_R_DECODE_ERROR                              110
+# define ASN1_R_DECODING_ERROR                            111
+# define ASN1_R_DEPTH_EXCEEDED                            174
+# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED         198
+# define ASN1_R_ENCODE_ERROR                              112
+# define ASN1_R_ERROR_GETTING_TIME                        173
+# define ASN1_R_ERROR_LOADING_SECTION                     172
+# define ASN1_R_ERROR_PARSING_SET_ELEMENT                 113
+# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS               114
+# define ASN1_R_EXPECTING_AN_INTEGER                      115
+# define ASN1_R_EXPECTING_AN_OBJECT                       116
+# define ASN1_R_EXPECTING_A_BOOLEAN                       117
+# define ASN1_R_EXPECTING_A_TIME                          118
+# define ASN1_R_EXPLICIT_LENGTH_MISMATCH                  119
+# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED              120
+# define ASN1_R_FIELD_MISSING                             121
+# define ASN1_R_FIRST_NUM_TOO_LARGE                       122
+# define ASN1_R_HEADER_TOO_LONG                           123
+# define ASN1_R_ILLEGAL_BITSTRING_FORMAT                  175
+# define ASN1_R_ILLEGAL_BOOLEAN                           176
+# define ASN1_R_ILLEGAL_CHARACTERS                        124
+# define ASN1_R_ILLEGAL_FORMAT                            177
+# define ASN1_R_ILLEGAL_HEX                               178
+# define ASN1_R_ILLEGAL_IMPLICIT_TAG                      179
+# define ASN1_R_ILLEGAL_INTEGER                           180
+# define ASN1_R_ILLEGAL_NESTED_TAGGING                    181
+# define ASN1_R_ILLEGAL_NULL                              125
+# define ASN1_R_ILLEGAL_NULL_VALUE                        182
+# define ASN1_R_ILLEGAL_OBJECT                            183
+# define ASN1_R_ILLEGAL_OPTIONAL_ANY                      126
+# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE          170
+# define ASN1_R_ILLEGAL_TAGGED_ANY                        127
+# define ASN1_R_ILLEGAL_TIME_VALUE                        184
+# define ASN1_R_INTEGER_NOT_ASCII_FORMAT                  185
+# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG                128
+# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT              220
+# define ASN1_R_INVALID_BMPSTRING_LENGTH                  129
+# define ASN1_R_INVALID_DIGIT                             130
+# define ASN1_R_INVALID_MIME_TYPE                         205
+# define ASN1_R_INVALID_MODIFIER                          186
+# define ASN1_R_INVALID_NUMBER                            187
+# define ASN1_R_INVALID_OBJECT_ENCODING                   216
+# define ASN1_R_INVALID_SEPARATOR                         131
+# define ASN1_R_INVALID_TIME_FORMAT                       132
+# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH            133
+# define ASN1_R_INVALID_UTF8STRING                        134
+# define ASN1_R_IV_TOO_LARGE                              135
+# define ASN1_R_LENGTH_ERROR                              136
+# define ASN1_R_LIST_ERROR                                188
+# define ASN1_R_MIME_NO_CONTENT_TYPE                      206
+# define ASN1_R_MIME_PARSE_ERROR                          207
+# define ASN1_R_MIME_SIG_PARSE_ERROR                      208
+# define ASN1_R_MISSING_EOC                               137
+# define ASN1_R_MISSING_SECOND_NUMBER                     138
+# define ASN1_R_MISSING_VALUE                             189
+# define ASN1_R_MSTRING_NOT_UNIVERSAL                     139
+# define ASN1_R_MSTRING_WRONG_TAG                         140
+# define ASN1_R_NESTED_ASN1_STRING                        197
+# define ASN1_R_NON_HEX_CHARACTERS                        141
+# define ASN1_R_NOT_ASCII_FORMAT                          190
+# define ASN1_R_NOT_ENOUGH_DATA                           142
+# define ASN1_R_NO_CONTENT_TYPE                           209
+# define ASN1_R_NO_DEFAULT_DIGEST                         201
+# define ASN1_R_NO_MATCHING_CHOICE_TYPE                   143
+# define ASN1_R_NO_MULTIPART_BODY_FAILURE                 210
+# define ASN1_R_NO_MULTIPART_BOUNDARY                     211
+# define ASN1_R_NO_SIG_CONTENT_TYPE                       212
+# define ASN1_R_NULL_IS_WRONG_LENGTH                      144
+# define ASN1_R_OBJECT_NOT_ASCII_FORMAT                   191
+# define ASN1_R_ODD_NUMBER_OF_CHARS                       145
+# define ASN1_R_PRIVATE_KEY_HEADER_MISSING                146
+# define ASN1_R_SECOND_NUMBER_TOO_LARGE                   147
+# define ASN1_R_SEQUENCE_LENGTH_MISMATCH                  148
+# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED                  149
+# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG              192
+# define ASN1_R_SHORT_LINE                                150
+# define ASN1_R_SIG_INVALID_MIME_TYPE                     213
+# define ASN1_R_STREAMING_NOT_SUPPORTED                   202
+# define ASN1_R_STRING_TOO_LONG                           151
+# define ASN1_R_STRING_TOO_SHORT                          152
+# define ASN1_R_TAG_VALUE_TOO_HIGH                        153
+# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+# define ASN1_R_TIME_NOT_ASCII_FORMAT                     193
+# define ASN1_R_TOO_LONG                                  155
+# define ASN1_R_TYPE_NOT_CONSTRUCTED                      156
+# define ASN1_R_TYPE_NOT_PRIMITIVE                        218
+# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY                  157
+# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY          158
+# define ASN1_R_UNEXPECTED_EOC                            159
+# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH           215
+# define ASN1_R_UNKNOWN_FORMAT                            160
+# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM          161
+# define ASN1_R_UNKNOWN_OBJECT_TYPE                       162
+# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE                   163
+# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM               199
+# define ASN1_R_UNKNOWN_TAG                               194
+# define ASN1_R_UNKOWN_FORMAT                             195
+# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE           164
+# define ASN1_R_UNSUPPORTED_CIPHER                        165
+# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM          166
+# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE               167
+# define ASN1_R_UNSUPPORTED_TYPE                          196
+# define ASN1_R_WRONG_PUBLIC_KEY_TYPE                     200
+# define ASN1_R_WRONG_TAG                                 168
+# define ASN1_R_WRONG_TYPE                                169
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/asn1_mac.h b/Cryptlib/Include/openssl/asn1_mac.h
new file mode 100644 (file)
index 0000000..3a672e9
--- /dev/null
@@ -0,0 +1,579 @@
+/* crypto/asn1/asn1_mac.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_ASN1_MAC_H
+# define HEADER_ASN1_MAC_H
+
+# include <openssl/asn1.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef ASN1_MAC_ERR_LIB
+#  define ASN1_MAC_ERR_LIB        ERR_LIB_ASN1
+# endif
+
+# define ASN1_MAC_H_err(f,r,line) \
+        ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),OPENSSL_FILE,(line))
+
+# define M_ASN1_D2I_vars(a,type,func) \
+        ASN1_const_CTX c; \
+        type ret=NULL; \
+        \
+        c.pp=(const unsigned char **)pp; \
+        c.q= *(const unsigned char **)pp; \
+        c.error=ERR_R_NESTED_ASN1_ERROR; \
+        if ((a == NULL) || ((*a) == NULL)) \
+                { if ((ret=(type)func()) == NULL) \
+                        { c.line=OPENSSL_LINE; goto err; } } \
+        else    ret=(*a);
+
+# define M_ASN1_D2I_Init() \
+        c.p= *(const unsigned char **)pp; \
+        c.max=(length == 0)?0:(c.p+length);
+
+# define M_ASN1_D2I_Finish_2(a) \
+        if (!asn1_const_Finish(&c)) \
+                { c.line=OPENSSL_LINE; goto err; } \
+        *(const unsigned char **)pp=c.p; \
+        if (a != NULL) (*a)=ret; \
+        return(ret);
+
+# define M_ASN1_D2I_Finish(a,func,e) \
+        M_ASN1_D2I_Finish_2(a); \
+err:\
+        ASN1_MAC_H_err((e),c.error,c.line); \
+        asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
+        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+        return(NULL)
+
+# define M_ASN1_D2I_start_sequence() \
+        if (!asn1_GetSequence(&c,&length)) \
+                { c.line=OPENSSL_LINE; goto err; }
+/* Begin reading ASN1 without a surrounding sequence */
+# define M_ASN1_D2I_begin() \
+        c.slen = length;
+
+/* End reading ASN1 with no check on length */
+# define M_ASN1_D2I_Finish_nolen(a, func, e) \
+        *pp=c.p; \
+        if (a != NULL) (*a)=ret; \
+        return(ret); \
+err:\
+        ASN1_MAC_H_err((e),c.error,c.line); \
+        asn1_add_error(*pp,(int)(c.q- *pp)); \
+        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+        return(NULL)
+
+# define M_ASN1_D2I_end_sequence() \
+        (((c.inf&1) == 0)?(c.slen <= 0): \
+                (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+# define M_ASN1_D2I_get(b, func) \
+        c.q=c.p; \
+        if (func(&(b),&c.p,c.slen) == NULL) \
+                {c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+# define M_ASN1_D2I_get_x(type,b,func) \
+        c.q=c.p; \
+        if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
+                {c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+/* use this instead () */
+# define M_ASN1_D2I_get_int(b,func) \
+        c.q=c.p; \
+        if (func(&(b),&c.p,c.slen) < 0) \
+                {c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+# define M_ASN1_D2I_get_opt(b,func,type) \
+        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+                == (V_ASN1_UNIVERSAL|(type)))) \
+                { \
+                M_ASN1_D2I_get(b,func); \
+                }
+
+# define M_ASN1_D2I_get_int_opt(b,func,type) \
+        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+                == (V_ASN1_UNIVERSAL|(type)))) \
+                { \
+                M_ASN1_D2I_get_int(b,func); \
+                }
+
+# define M_ASN1_D2I_get_imp(b,func, type) \
+        M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
+        c.q=c.p; \
+        if (func(&(b),&c.p,c.slen) == NULL) \
+                {c.line=OPENSSL_LINE; M_ASN1_next_prev = _tmp; goto err; } \
+        c.slen-=(c.p-c.q);\
+        M_ASN1_next_prev=_tmp;
+
+# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
+        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
+                (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
+                { \
+                unsigned char _tmp = M_ASN1_next; \
+                M_ASN1_D2I_get_imp(b,func, type);\
+                }
+
+# define M_ASN1_D2I_get_set(r,func,free_func) \
+                M_ASN1_D2I_get_imp_set(r,func,free_func, \
+                        V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
+                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
+                        V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+# define M_ASN1_D2I_get_set_opt(r,func,free_func) \
+        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+                { M_ASN1_D2I_get_set(r,func,free_func); }
+
+# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
+        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+                { M_ASN1_D2I_get_set_type(type,r,func,free_func); }
+
+# define M_ASN1_I2D_len_SET_opt(a,f) \
+        if ((a != NULL) && (sk_num(a) != 0)) \
+                M_ASN1_I2D_len_SET(a,f);
+
+# define M_ASN1_I2D_put_SET_opt(a,f) \
+        if ((a != NULL) && (sk_num(a) != 0)) \
+                M_ASN1_I2D_put_SET(a,f);
+
+# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+        if ((a != NULL) && (sk_num(a) != 0)) \
+                M_ASN1_I2D_put_SEQUENCE(a,f);
+
+# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
+        if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
+
+# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
+        if ((c.slen != 0) && \
+                (M_ASN1_next == \
+                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+                { \
+                M_ASN1_D2I_get_imp_set(b,func,free_func,\
+                        tag,V_ASN1_CONTEXT_SPECIFIC); \
+                }
+
+# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
+        if ((c.slen != 0) && \
+                (M_ASN1_next == \
+                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+                { \
+                M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
+                        tag,V_ASN1_CONTEXT_SPECIFIC); \
+                }
+
+# define M_ASN1_D2I_get_seq(r,func,free_func) \
+                M_ASN1_D2I_get_imp_set(r,func,free_func,\
+                        V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+
+# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
+                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+                                            V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
+        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+                { M_ASN1_D2I_get_seq(r,func,free_func); }
+
+# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
+        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+                { M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
+
+# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
+                M_ASN1_D2I_get_imp_set(r,func,free_func,\
+                        x,V_ASN1_CONTEXT_SPECIFIC);
+
+# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
+                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+                        x,V_ASN1_CONTEXT_SPECIFIC);
+
+# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
+        c.q=c.p; \
+        if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
+                (void (*)())free_func,a,b) == NULL) \
+                { c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
+        c.q=c.p; \
+        if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
+                                   free_func,a,b) == NULL) \
+                { c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+# define M_ASN1_D2I_get_set_strings(r,func,a,b) \
+        c.q=c.p; \
+        if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
+                { c.line=OPENSSL_LINE; goto err; } \
+        c.slen-=(c.p-c.q);
+
+# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
+        if ((c.slen != 0L) && (M_ASN1_next == \
+                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+                { \
+                int Tinf,Ttag,Tclass; \
+                long Tlen; \
+                \
+                c.q=c.p; \
+                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+                if (Tinf & 0x80) \
+                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+                        c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+                                        Tlen = c.slen - (c.p - c.q) - 2; \
+                if (func(&(r),&c.p,Tlen) == NULL) \
+                        { c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+                        Tlen = c.slen - (c.p - c.q); \
+                        if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
+                                { c.error=ERR_R_MISSING_ASN1_EOS; \
+                                c.line=OPENSSL_LINE; goto err; } \
+                }\
+                c.slen-=(c.p-c.q); \
+                }
+
+# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
+        if ((c.slen != 0) && (M_ASN1_next == \
+                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+                { \
+                int Tinf,Ttag,Tclass; \
+                long Tlen; \
+                \
+                c.q=c.p; \
+                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+                if (Tinf & 0x80) \
+                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+                        c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+                                        Tlen = c.slen - (c.p - c.q) - 2; \
+                if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
+                        (void (*)())free_func, \
+                        b,V_ASN1_UNIVERSAL) == NULL) \
+                        { c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+                        Tlen = c.slen - (c.p - c.q); \
+                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+                                { c.error=ERR_R_MISSING_ASN1_EOS; \
+                                c.line=OPENSSL_LINE; goto err; } \
+                }\
+                c.slen-=(c.p-c.q); \
+                }
+
+# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
+        if ((c.slen != 0) && (M_ASN1_next == \
+                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+                { \
+                int Tinf,Ttag,Tclass; \
+                long Tlen; \
+                \
+                c.q=c.p; \
+                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+                if (Tinf & 0x80) \
+                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+                        c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+                                        Tlen = c.slen - (c.p - c.q) - 2; \
+                if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
+                        free_func,b,V_ASN1_UNIVERSAL) == NULL) \
+                        { c.line=OPENSSL_LINE; goto err; } \
+                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+                        Tlen = c.slen - (c.p - c.q); \
+                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+                                { c.error=ERR_R_MISSING_ASN1_EOS; \
+                                c.line=OPENSSL_LINE; goto err; } \
+                }\
+                c.slen-=(c.p-c.q); \
+                }
+
+/* New macros */
+# define M_ASN1_New_Malloc(ret,type) \
+        if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
+                { c.line=OPENSSL_LINE; goto err2; }
+
+# define M_ASN1_New(arg,func) \
+        if (((arg)=func()) == NULL) return(NULL)
+
+# define M_ASN1_New_Error(a) \
+/*-     err:    ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
+                return(NULL);*/ \
+        err2:   ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
+                return(NULL)
+
+/*
+ * BIG UGLY WARNING! This is so damn ugly I wanna puke.  Unfortunately, some
+ * macros that use ASN1_const_CTX still insist on writing in the input
+ * stream.  ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? --
+ * Richard Levitte
+ */
+# define M_ASN1_next             (*((unsigned char *)(c.p)))
+# define M_ASN1_next_prev        (*((unsigned char *)(c.q)))
+
+/*************************************************/
+
+# define M_ASN1_I2D_vars(a)      int r=0,ret=0; \
+                                unsigned char *p; \
+                                if (a == NULL) return(0)
+
+/* Length Macros */
+# define M_ASN1_I2D_len(a,f)     ret+=f(a,NULL)
+# define M_ASN1_I2D_len_IMP_opt(a,f)     if (a != NULL) M_ASN1_I2D_len(a,f)
+
+# define M_ASN1_I2D_len_SET(a,f) \
+                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
+
+# define M_ASN1_I2D_len_SET_type(type,a,f) \
+                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
+                                            V_ASN1_UNIVERSAL,IS_SET);
+
+# define M_ASN1_I2D_len_SEQUENCE(a,f) \
+                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+                                  IS_SEQUENCE);
+
+# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
+                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
+                                            V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        M_ASN1_I2D_len_SEQUENCE(a,f);
+
+# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
+
+# define M_ASN1_I2D_len_IMP_SET(a,f,x) \
+                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
+                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+                                            V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+                                          IS_SET);
+
+# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+                                               V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
+                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+                                  IS_SEQUENCE);
+
+# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+                                          IS_SEQUENCE);
+
+# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+                                                    V_ASN1_CONTEXT_SPECIFIC, \
+                                                    IS_SEQUENCE);
+
+# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
+                if (a != NULL)\
+                        { \
+                        v=f(a,NULL); \
+                        ret+=ASN1_object_size(1,v,mtag); \
+                        }
+
+# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_num(a) != 0))\
+                        { \
+                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+                        ret+=ASN1_object_size(1,v,mtag); \
+                        }
+
+# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_num(a) != 0))\
+                        { \
+                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
+                                       IS_SEQUENCE); \
+                        ret+=ASN1_object_size(1,v,mtag); \
+                        }
+
+# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0))\
+                        { \
+                        v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
+                                                 V_ASN1_UNIVERSAL, \
+                                                 IS_SEQUENCE); \
+                        ret+=ASN1_object_size(1,v,mtag); \
+                        }
+
+/* Put Macros */
+# define M_ASN1_I2D_put(a,f)     f(a,&p)
+
+# define M_ASN1_I2D_put_IMP_opt(a,f,t)   \
+                if (a != NULL) \
+                        { \
+                        unsigned char *q=p; \
+                        f(a,&p); \
+                        *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
+                        }
+
+# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
+                        V_ASN1_UNIVERSAL,IS_SET)
+# define M_ASN1_I2D_put_SET_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
+# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+                        V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+                        V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
+
+# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
+                                             V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+                            IS_SEQUENCE)
+
+# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        M_ASN1_I2D_put_SEQUENCE(a,f);
+
+# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+                                       IS_SET); }
+
+# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+                                                 V_ASN1_CONTEXT_SPECIFIC, \
+                                                 IS_SET); }
+
+# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+                                       IS_SEQUENCE); }
+
+# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+                                                 V_ASN1_CONTEXT_SPECIFIC, \
+                                                 IS_SEQUENCE); }
+
+# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
+                if (a != NULL) \
+                        { \
+                        ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
+                        f(a,&p); \
+                        }
+
+# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        { \
+                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+                        }
+
+# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_num(a) != 0)) \
+                        { \
+                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
+                        }
+
+# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+                        { \
+                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+                        i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
+                                               IS_SEQUENCE); \
+                        }
+
+# define M_ASN1_I2D_seq_total() \
+                r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
+                if (pp == NULL) return(r); \
+                p= *pp; \
+                ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+# define M_ASN1_I2D_INF_seq_start(tag,ctx) \
+                *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
+                *(p++)=0x80
+
+# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
+
+# define M_ASN1_I2D_finish()     *pp=p; \
+                                return(r);
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length);
+void asn1_add_error(const unsigned char *address, int offset);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/asn1t.h b/Cryptlib/Include/openssl/asn1t.h
new file mode 100644 (file)
index 0000000..99bc0ee
--- /dev/null
@@ -0,0 +1,973 @@
+/* asn1t.h */
+/*
+ * 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).
+ *
+ */
+#ifndef HEADER_ASN1T_H
+# define HEADER_ASN1T_H
+
+# include <stddef.h>
+# include <openssl/e_os2.h>
+# include <openssl/asn1.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+#  define ASN1_ITEM_end(itname) \
+                };
+
+# else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        const ASN1_ITEM * itname##_it(void) \
+        { \
+                static const ASN1_ITEM local_it = {
+
+#  define ASN1_ITEM_end(itname) \
+                }; \
+        return &local_it; \
+        }
+
+# endif
+
+/* Macros to aid ASN1 template writing */
+
+# define ASN1_ITEM_TEMPLATE(tname) \
+        static const ASN1_TEMPLATE tname##_item_tt
+
+# define ASN1_ITEM_TEMPLATE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_PRIMITIVE,\
+                -1,\
+                &tname##_item_tt,\
+                0,\
+                NULL,\
+                0,\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+/* This is a ASN1 type which just embeds a template */
+
+/*-
+ * This pair helps declare a SEQUENCE. We can do:
+ *
+ *      ASN1_SEQUENCE(stname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END(stname)
+ *
+ *      This will produce an ASN1_ITEM called stname_it
+ *      for a structure called stname.
+ *
+ *      If you want the same structure but a different
+ *      name then use:
+ *
+ *      ASN1_SEQUENCE(itname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *      This will create an item called itname_it using
+ *      a structure called stname.
+ */
+
+# define ASN1_SEQUENCE(tname) \
+        static const ASN1_TEMPLATE tname##_seq_tt[]
+
+# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+# define ASN1_SEQUENCE_END_name(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE(tname) \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
+        ASN1_SEQUENCE_cb(tname, cb)
+
+# define ASN1_SEQUENCE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_BROKEN_SEQUENCE(tname) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_ref(tname, cb, lck) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_enc(tname, enc, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(tname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+
+# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_ref(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/*-
+ * This pair helps declare a CHOICE type. We can do:
+ *
+ *      ASN1_CHOICE(chname) = {
+ *              ... CHOICE options ...
+ *      ASN1_CHOICE_END(chname)
+ *
+ *      This will produce an ASN1_ITEM called chname_it
+ *      for a structure called chname. The structure
+ *      definition must look like this:
+ *      typedef struct {
+ *              int type;
+ *              union {
+ *                      ASN1_SOMETHING *opt1;
+ *                      ASN1_SOMEOTHER *opt2;
+ *              } value;
+ *      } chname;
+ *
+ *      the name of the selector must be 'type'.
+ *      to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+# define ASN1_CHOICE(tname) \
+        static const ASN1_TEMPLATE tname##_ch_tt[]
+
+# define ASN1_CHOICE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_CHOICE(tname)
+
+# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define ASN1_CHOICE_END_selector(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_CHOICE_END_cb(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+        (flags), (tag), 0,\
+        #name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+        (flags), (tag), offsetof(stname, field),\
+        #field, ASN1_ITEM_ref(type) }
+
+/* used when the structure is combined with the parent */
+
+# define ASN1_EX_COMBINE(flags, tag, type) { \
+        (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+# define ASN1_IMP_EX(stname, field, type, tag, ex) \
+                ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+# define ASN1_EXP_EX(stname, field, type, tag, ex) \
+                ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+# else
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+# endif
+/* Plain simple type */
+# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+# define ASN1_SEQUENCE_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+# define ASN1_SET_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+# define ASN1_SET_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+# define ASN1_IMP_SET_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_EXP_SET_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT using indefinite length constructed form */
+# define ASN1_NDEF_EXP(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+# define ASN1_ADB(name) \
+        static const ASN1_ADB_TABLE name##_adbtbl[]
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+        ;\
+        static const ASN1_ADB name##_adb = {\
+                flags,\
+                offsetof(name, field),\
+                app_table,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+        }
+
+# else
+
+#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+        ;\
+        static const ASN1_ITEM *name##_adb(void) \
+        { \
+        static const ASN1_ADB internal_adb = \
+                {\
+                flags,\
+                offsetof(name, field),\
+                app_table,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+                }; \
+                return (const ASN1_ITEM *) &internal_adb; \
+        } \
+        void dummy_function(void)
+
+# endif
+
+# define ADB_ENTRY(val, template) {val, template}
+
+# define ASN1_ADB_TEMPLATE(name) \
+        static const ASN1_TEMPLATE name##_tt
+
+/*
+ * This is the ASN1 template structure that defines a wrapper round the
+ * actual type. It determines the actual position of the field in the value
+ * structure, various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+    unsigned long flags;        /* Various flags */
+    long tag;                   /* tag, not used if no tagging */
+    unsigned long offset;       /* Offset of this field in structure */
+# ifndef NO_ASN1_FIELD_NAMES
+    const char *field_name;     /* Field name */
+# endif
+    ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+# define ASN1_TEMPLATE_item(t) (t->item_ptr)
+# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+    unsigned long flags;        /* Various flags */
+    unsigned long offset;       /* Offset of selector field */
+    STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+    const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
+    long tblcount;              /* Number of entries in tbl */
+    const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
+    const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+    long value;                 /* NID for an object or value for an int */
+    const ASN1_TEMPLATE tt;     /* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+# define ASN1_TFLG_OPTIONAL      (0x1)
+
+/* Field is a SET OF */
+# define ASN1_TFLG_SET_OF        (0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+# define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)
+
+/*
+ * Special case: this refers to a SET OF that will be sorted into DER order
+ * when encoded *and* the corresponding STACK will be modified to match the
+ * new order.
+ */
+# define ASN1_TFLG_SET_ORDER     (0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+# define ASN1_TFLG_SK_MASK       (0x3 << 1)
+
+/*
+ * These flags mean the tag should be taken from the tag field. If EXPLICIT
+ * then the underlying type is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+# define ASN1_TFLG_IMPTAG        (0x1 << 3)
+
+/* EXPLICIT tagging, inner tag from underlying type */
+# define ASN1_TFLG_EXPTAG        (0x2 << 3)
+
+# define ASN1_TFLG_TAG_MASK      (0x3 << 3)
+
+/* context specific IMPLICIT */
+# define ASN1_TFLG_IMPLICIT      ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+# define ASN1_TFLG_EXPLICIT      ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/*
+ * If tagging is in force these determine the type of tag to use. Otherwise
+ * the tag is determined by the underlying type. These values reflect the
+ * actual octet format.
+ */
+
+/* Universal tag */
+# define ASN1_TFLG_UNIVERSAL     (0x0<<6)
+/* Application tag */
+# define ASN1_TFLG_APPLICATION   (0x1<<6)
+/* Context specific tag */
+# define ASN1_TFLG_CONTEXT       (0x2<<6)
+/* Private tag */
+# define ASN1_TFLG_PRIVATE       (0x3<<6)
+
+# define ASN1_TFLG_TAG_CLASS     (0x3<<6)
+
+/*
+ * These are for ANY DEFINED BY type. In this case the 'item' field points to
+ * an ASN1_ADB structure which contains a table of values to decode the
+ * relevant type
+ */
+
+# define ASN1_TFLG_ADB_MASK      (0x3<<8)
+
+# define ASN1_TFLG_ADB_OID       (0x1<<8)
+
+# define ASN1_TFLG_ADB_INT       (0x1<<9)
+
+/*
+ * This flag means a parent structure is passed instead of the field: this is
+ * useful is a SEQUENCE is being combined with a CHOICE for example. Since
+ * this means the structure and item name will differ we need to use the
+ * ASN1_CHOICE_END_name() macro for example.
+ */
+
+# define ASN1_TFLG_COMBINE       (0x1<<10)
+
+/*
+ * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
+ * indefinite length constructed encoding to be used if required.
+ */
+
+# define ASN1_TFLG_NDEF          (0x1<<11)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+    char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
+                                 * or extern */
+    long utype;                 /* underlying type */
+    const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
+                                     * the contents */
+    long tcount;                /* Number of templates if SEQUENCE or CHOICE */
+    const void *funcs;          /* functions that handle this type */
+    long size;                  /* Structure size (usually) */
+# ifndef NO_ASN1_FIELD_NAMES
+    const char *sname;          /* Structure name */
+# endif
+};
+
+/*-
+ * These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions.
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+# define ASN1_ITYPE_PRIMITIVE            0x0
+
+# define ASN1_ITYPE_SEQUENCE             0x1
+
+# define ASN1_ITYPE_CHOICE               0x2
+
+# define ASN1_ITYPE_COMPAT               0x3
+
+# define ASN1_ITYPE_EXTERN               0x4
+
+# define ASN1_ITYPE_MSTRING              0x5
+
+# define ASN1_ITYPE_NDEF_SEQUENCE        0x6
+
+/*
+ * Cache for ASN1 tag and length, so we don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st {
+    char valid;                 /* Values below are valid */
+    int ret;                    /* return value */
+    long plen;                  /* length */
+    int ptag;                   /* class value */
+    int pclass;                 /* class value */
+    int hdrlen;                 /* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+
+typedef ASN1_VALUE *ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in,
+                                  long length);
+typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                        const ASN1_ITEM *it, int tag, int aclass, char opt,
+                        ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                        const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
+                               int indent, const char *fname,
+                               const ASN1_PCTX *pctx);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
+                               int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
+                               int len, int utype, char *free_cont,
+                               const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
+                                 const ASN1_ITEM *it, int indent,
+                                 const ASN1_PCTX *pctx);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+    ASN1_new_func *asn1_new;
+    ASN1_free_func *asn1_free;
+    ASN1_d2i_func *asn1_d2i;
+    ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+    void *app_data;
+    ASN1_ex_new_func *asn1_ex_new;
+    ASN1_ex_free_func *asn1_ex_free;
+    ASN1_ex_free_func *asn1_ex_clear;
+    ASN1_ex_d2i *asn1_ex_d2i;
+    ASN1_ex_i2d *asn1_ex_i2d;
+    ASN1_ex_print_func *asn1_ex_print;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+    void *app_data;
+    unsigned long flags;
+    ASN1_ex_new_func *prim_new;
+    ASN1_ex_free_func *prim_free;
+    ASN1_ex_free_func *prim_clear;
+    ASN1_primitive_c2i *prim_c2i;
+    ASN1_primitive_i2c *prim_i2c;
+    ASN1_primitive_print *prim_print;
+} ASN1_PRIMITIVE_FUNCS;
+
+/*
+ * This is the ASN1_AUX structure: it handles various miscellaneous
+ * requirements. For example the use of reference counts and an informational
+ * callback. The "informational callback" is called at various points during
+ * the ASN1 encoding and decoding. It can be used to provide minor
+ * customisation of the structures used. This is most useful where the
+ * supplied routines *almost* do the right thing but need some extra help at
+ * a few points. If the callback returns zero then it is assumed a fatal
+ * error has occurred and the main operation should be abandoned. If major
+ * changes in the default behaviour are required then an external type is
+ * more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+                        void *exarg);
+
+typedef struct ASN1_AUX_st {
+    void *app_data;
+    int flags;
+    int ref_offset;             /* Offset of reference value */
+    int ref_lock;               /* Lock type to use */
+    ASN1_aux_cb *asn1_cb;
+    int enc_offset;             /* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+    BIO *out;
+    int indent;
+    const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+    /* BIO to stream through */
+    BIO *out;
+    /* BIO with filters appended */
+    BIO *ndef_bio;
+    /* Streaming I/O boundary */
+    unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+# define ASN1_AFLG_REFCOUNT      1
+/* Save the encoding of structure (useful for signatures) */
+# define ASN1_AFLG_ENCODING      2
+/* The Sequence length is invalid */
+# define ASN1_AFLG_BROKEN        4
+
+/* operation values for asn1_cb */
+
+# define ASN1_OP_NEW_PRE         0
+# define ASN1_OP_NEW_POST        1
+# define ASN1_OP_FREE_PRE        2
+# define ASN1_OP_FREE_POST       3
+# define ASN1_OP_D2I_PRE         4
+# define ASN1_OP_D2I_POST        5
+# define ASN1_OP_I2D_PRE         6
+# define ASN1_OP_I2D_POST        7
+# define ASN1_OP_PRINT_PRE       8
+# define ASN1_OP_PRINT_POST      9
+# define ASN1_OP_STREAM_PRE      10
+# define ASN1_OP_STREAM_POST     11
+# define ASN1_OP_DETACHED_PRE    12
+# define ASN1_OP_DETACHED_POST   13
+
+/* Macro to implement a primitive type */
+# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+                                ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+                                ASN1_ITEM_end(itname)
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
+        static const ASN1_COMPAT_FUNCS sname##_ff = { \
+                (ASN1_new_func *)sname##_new, \
+                (ASN1_free_func *)sname##_free, \
+                (ASN1_d2i_func *)d2i_##sname, \
+                (ASN1_i2d_func *)i2d_##sname, \
+        }; \
+        ASN1_ITEM_start(sname) \
+                ASN1_ITYPE_COMPAT, \
+                tag, \
+                NULL, \
+                0, \
+                &sname##_ff, \
+                0, \
+                #sname \
+        ASN1_ITEM_end(sname)
+
+# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+        ASN1_ITEM_start(sname) \
+                ASN1_ITYPE_EXTERN, \
+                tag, \
+                NULL, \
+                0, \
+                &fptrs, \
+                0, \
+                #sname \
+        ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+                        IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+        pre stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        pre void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+        stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+        }
+
+/*
+ * This includes evil casts to remove const: they will go away when full ASN1
+ * constification is done.
+ */
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(const stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+        stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+        IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                                const ASN1_PCTX *pctx) \
+        { \
+                return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+                        ASN1_ITEM_rptr(itname), pctx); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DECLARE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                      const ASN1_TEMPLATE *tt);
+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);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                     const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
+                      const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                const ASN1_ITEM *it);
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                int utype, char *free_cont, const ASN1_ITEM *it);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+                             const ASN1_ITEM *it);
+
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                                 int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+                     const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+                  const ASN1_ITEM *it);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/bio.h b/Cryptlib/Include/openssl/bio.h
new file mode 100644 (file)
index 0000000..6790aed
--- /dev/null
@@ -0,0 +1,883 @@
+/* crypto/bio/bio.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_BIO_H
+# define HEADER_BIO_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+
+# include <openssl/crypto.h>
+
+# ifndef OPENSSL_NO_SCTP
+#  ifndef OPENSSL_SYS_VMS
+#   include <stdint.h>
+#  else
+#   include <inttypes.h>
+#  endif
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These are the 'types' of BIOs */
+# define BIO_TYPE_NONE           0
+# define BIO_TYPE_MEM            (1|0x0400)
+# define BIO_TYPE_FILE           (2|0x0400)
+
+# define BIO_TYPE_FD             (4|0x0400|0x0100)
+# define BIO_TYPE_SOCKET         (5|0x0400|0x0100)
+# define BIO_TYPE_NULL           (6|0x0400)
+# define BIO_TYPE_SSL            (7|0x0200)
+# define BIO_TYPE_MD             (8|0x0200)/* passive filter */
+# define BIO_TYPE_BUFFER         (9|0x0200)/* filter */
+# define BIO_TYPE_CIPHER         (10|0x0200)/* filter */
+# define BIO_TYPE_BASE64         (11|0x0200)/* filter */
+# define BIO_TYPE_CONNECT        (12|0x0400|0x0100)/* socket - connect */
+# define BIO_TYPE_ACCEPT         (13|0x0400|0x0100)/* socket for accept */
+# define BIO_TYPE_PROXY_CLIENT   (14|0x0200)/* client proxy BIO */
+# define BIO_TYPE_PROXY_SERVER   (15|0x0200)/* server proxy BIO */
+# define BIO_TYPE_NBIO_TEST      (16|0x0200)/* server proxy BIO */
+# define BIO_TYPE_NULL_FILTER    (17|0x0200)
+# define BIO_TYPE_BER            (18|0x0200)/* BER -> bin filter */
+# define BIO_TYPE_BIO            (19|0x0400)/* (half a) BIO pair */
+# define BIO_TYPE_LINEBUFFER     (20|0x0200)/* filter */
+# define BIO_TYPE_DGRAM          (21|0x0400|0x0100)
+# ifndef OPENSSL_NO_SCTP
+#  define BIO_TYPE_DGRAM_SCTP     (24|0x0400|0x0100)
+# endif
+# define BIO_TYPE_ASN1           (22|0x0200)/* filter */
+# define BIO_TYPE_COMP           (23|0x0200)/* filter */
+
+# define BIO_TYPE_DESCRIPTOR     0x0100/* socket, fd, connect or accept */
+# define BIO_TYPE_FILTER         0x0200
+# define BIO_TYPE_SOURCE_SINK    0x0400
+
+/*
+ * BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ */
+# define BIO_NOCLOSE             0x00
+# define BIO_CLOSE               0x01
+
+/*
+ * These are used in the following macros and are passed to BIO_ctrl()
+ */
+# define BIO_CTRL_RESET          1/* opt - rewind/zero etc */
+# define BIO_CTRL_EOF            2/* opt - are we at the eof */
+# define BIO_CTRL_INFO           3/* opt - extra tit-bits */
+# define BIO_CTRL_SET            4/* man - set the 'IO' type */
+# define BIO_CTRL_GET            5/* man - get the 'IO' type */
+# define BIO_CTRL_PUSH           6/* opt - internal, used to signify change */
+# define BIO_CTRL_POP            7/* opt - internal, used to signify change */
+# define BIO_CTRL_GET_CLOSE      8/* man - set the 'close' on free */
+# define BIO_CTRL_SET_CLOSE      9/* man - set the 'close' on free */
+# define BIO_CTRL_PENDING        10/* opt - is their more data buffered */
+# define BIO_CTRL_FLUSH          11/* opt - 'flush' buffered output */
+# define BIO_CTRL_DUP            12/* man - extra stuff for 'duped' BIO */
+# define BIO_CTRL_WPENDING       13/* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+# define BIO_CTRL_SET_CALLBACK   14/* opt - set callback function */
+# define BIO_CTRL_GET_CALLBACK   15/* opt - set callback function */
+
+# define BIO_CTRL_SET_FILENAME   30/* BIO_s_file special */
+
+/* dgram BIO stuff */
+# define BIO_CTRL_DGRAM_CONNECT       31/* BIO dgram special */
+# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected
+                                         * socket to be passed in */
+# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */
+# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */
+
+# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */
+
+/* #ifdef IP_MTU_DISCOVER */
+# define BIO_CTRL_DGRAM_MTU_DISCOVER       39/* set DF bit on egress packets */
+/* #endif */
+
+# define BIO_CTRL_DGRAM_QUERY_MTU          40/* as kernel for current MTU */
+# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
+# define BIO_CTRL_DGRAM_GET_MTU            41/* get cached value for MTU */
+# define BIO_CTRL_DGRAM_SET_MTU            42/* set cached value for MTU.
+                                              * want to use this if asking
+                                              * the kernel fails */
+
+# define BIO_CTRL_DGRAM_MTU_EXCEEDED       43/* check whether the MTU was
+                                              * exceed in the previous write
+                                              * operation */
+
+# define BIO_CTRL_DGRAM_GET_PEER           46
+# define BIO_CTRL_DGRAM_SET_PEER           44/* Destination for the data */
+
+# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45/* Next DTLS handshake timeout
+                                              * to adjust socket timeouts */
+# define BIO_CTRL_DGRAM_SET_DONT_FRAG      48
+
+# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP stuff */
+#  define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE    50
+#  define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY                51
+#  define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY               52
+#  define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD               53
+#  define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO         60
+#  define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO         61
+#  define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO         62
+#  define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO         63
+#  define BIO_CTRL_DGRAM_SCTP_GET_PRINFO                  64
+#  define BIO_CTRL_DGRAM_SCTP_SET_PRINFO                  65
+#  define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN               70
+# endif
+
+/* modifiers */
+# define BIO_FP_READ             0x02
+# define BIO_FP_WRITE            0x04
+# define BIO_FP_APPEND           0x08
+# define BIO_FP_TEXT             0x10
+
+# define BIO_FLAGS_READ          0x01
+# define BIO_FLAGS_WRITE         0x02
+# define BIO_FLAGS_IO_SPECIAL    0x04
+# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+# define BIO_FLAGS_SHOULD_RETRY  0x08
+# ifndef BIO_FLAGS_UPLINK
+/*
+ * "UPLINK" flag denotes file descriptors provided by application. It
+ * defaults to 0, as most platforms don't require UPLINK interface.
+ */
+#  define BIO_FLAGS_UPLINK        0
+# endif
+
+/* Used in BIO_gethostbyname() */
+# define BIO_GHBN_CTRL_HITS              1
+# define BIO_GHBN_CTRL_MISSES            2
+# define BIO_GHBN_CTRL_CACHE_SIZE        3
+# define BIO_GHBN_CTRL_GET_ENTRY         4
+# define BIO_GHBN_CTRL_FLUSH             5
+
+/* Mostly used in the SSL BIO */
+/*-
+ * Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP   0x40
+ */
+
+# define BIO_FLAGS_BASE64_NO_NL  0x100
+
+/*
+ * This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+# define BIO_FLAGS_MEM_RDONLY    0x200
+
+typedef struct bio_st BIO;
+
+void BIO_set_flags(BIO *b, int flags);
+int BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+# define BIO_set_retry_special(b) \
+                BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_read(b) \
+                BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_write(b) \
+                BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+# define BIO_clear_retry_flags(b) \
+                BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_get_retry_flags(b) \
+                BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+# define BIO_should_read(a)              BIO_test_flags(a, BIO_FLAGS_READ)
+# define BIO_should_write(a)             BIO_test_flags(a, BIO_FLAGS_WRITE)
+# define BIO_should_io_special(a)        BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+# define BIO_retry_type(a)               BIO_test_flags(a, BIO_FLAGS_RWS)
+# define BIO_should_retry(a)             BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/*
+ * The next three are used in conjunction with the BIO_should_io_special()
+ * condition.  After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int
+ * *reason); will walk the BIO stack and return the 'reason' for the special
+ * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return
+ * the code.
+ */
+/*
+ * Returned from the SSL bio when the certificate retrieval code had an error
+ */
+# define BIO_RR_SSL_X509_LOOKUP          0x01
+/* Returned from the connect BIO when a connect would have blocked */
+# define BIO_RR_CONNECT                  0x02
+/* Returned from the accept BIO when an accept would have blocked */
+# define BIO_RR_ACCEPT                   0x03
+
+/* These are passed by the BIO callback */
+# define BIO_CB_FREE     0x01
+# define BIO_CB_READ     0x02
+# define BIO_CB_WRITE    0x03
+# define BIO_CB_PUTS     0x04
+# define BIO_CB_GETS     0x05
+# define BIO_CB_CTRL     0x06
+
+/*
+ * The callback is called before and after the underling operation, The
+ * BIO_CB_RETURN flag indicates if it is after the call
+ */
+# define BIO_CB_RETURN   0x80
+# define BIO_CB_return(a) ((a)|BIO_CB_RETURN)
+# define BIO_cb_pre(a)   (!((a)&BIO_CB_RETURN))
+# define BIO_cb_post(a)  ((a)&BIO_CB_RETURN)
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
+                                        int, long, long);
+void BIO_set_callback(BIO *b,
+                      long (*callback) (struct bio_st *, int, const char *,
+                                        int, long, long));
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+const char *BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef void bio_info_cb (struct bio_st *, int, const char *, int, long,
+                          long);
+
+typedef struct bio_method_st {
+    int type;
+    const char *name;
+    int (*bwrite) (BIO *, const char *, int);
+    int (*bread) (BIO *, char *, int);
+    int (*bputs) (BIO *, const char *);
+    int (*bgets) (BIO *, char *, int);
+    long (*ctrl) (BIO *, int, long, void *);
+    int (*create) (BIO *);
+    int (*destroy) (BIO *);
+    long (*callback_ctrl) (BIO *, int, bio_info_cb *);
+} BIO_METHOD;
+
+struct bio_st {
+    BIO_METHOD *method;
+    /* bio, mode, argp, argi, argl, ret */
+    long (*callback) (struct bio_st *, int, const char *, int, long, long);
+    char *cb_arg;               /* first argument for the callback */
+    int init;
+    int shutdown;
+    int flags;                  /* extra storage */
+    int retry_reason;
+    int num;
+    void *ptr;
+    struct bio_st *next_bio;    /* used by filter BIOs */
+    struct bio_st *prev_bio;    /* used by filter BIOs */
+    int references;
+    unsigned long num_read;
+    unsigned long num_write;
+    CRYPTO_EX_DATA ex_data;
+};
+
+DECLARE_STACK_OF(BIO)
+
+typedef struct bio_f_buffer_ctx_struct {
+    /*-
+     * Buffers are setup like this:
+     *
+     * <---------------------- size ----------------------->
+     * +---------------------------------------------------+
+     * | consumed | remaining          | free space        |
+     * +---------------------------------------------------+
+     * <-- off --><------- len ------->
+     */
+    /*- BIO *bio; *//*
+     * this is now in the BIO struct
+     */
+    int ibuf_size;              /* how big is the input buffer */
+    int obuf_size;              /* how big is the output buffer */
+    char *ibuf;                 /* the char array */
+    int ibuf_len;               /* how many bytes are in it */
+    int ibuf_off;               /* write/read offset */
+    char *obuf;                 /* the char array */
+    int obuf_len;               /* how many bytes are in it */
+    int obuf_off;               /* write/read offset */
+} BIO_F_BUFFER_CTX;
+
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen,
+                          void *parg);
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP parameter structs */
+struct bio_dgram_sctp_sndinfo {
+    uint16_t snd_sid;
+    uint16_t snd_flags;
+    uint32_t snd_ppid;
+    uint32_t snd_context;
+};
+
+struct bio_dgram_sctp_rcvinfo {
+    uint16_t rcv_sid;
+    uint16_t rcv_ssn;
+    uint16_t rcv_flags;
+    uint32_t rcv_ppid;
+    uint32_t rcv_tsn;
+    uint32_t rcv_cumtsn;
+    uint32_t rcv_context;
+};
+
+struct bio_dgram_sctp_prinfo {
+    uint16_t pr_policy;
+    uint32_t pr_value;
+};
+# endif
+
+/* connect BIO stuff */
+# define BIO_CONN_S_BEFORE               1
+# define BIO_CONN_S_GET_IP               2
+# define BIO_CONN_S_GET_PORT             3
+# define BIO_CONN_S_CREATE_SOCKET        4
+# define BIO_CONN_S_CONNECT              5
+# define BIO_CONN_S_OK                   6
+# define BIO_CONN_S_BLOCKED_CONNECT      7
+# define BIO_CONN_S_NBIO                 8
+/*
+ * #define BIO_CONN_get_param_hostname BIO_ctrl
+ */
+
+# define BIO_C_SET_CONNECT                       100
+# define BIO_C_DO_STATE_MACHINE                  101
+# define BIO_C_SET_NBIO                          102
+# define BIO_C_SET_PROXY_PARAM                   103
+# define BIO_C_SET_FD                            104
+# define BIO_C_GET_FD                            105
+# define BIO_C_SET_FILE_PTR                      106
+# define BIO_C_GET_FILE_PTR                      107
+# define BIO_C_SET_FILENAME                      108
+# define BIO_C_SET_SSL                           109
+# define BIO_C_GET_SSL                           110
+# define BIO_C_SET_MD                            111
+# define BIO_C_GET_MD                            112
+# define BIO_C_GET_CIPHER_STATUS                 113
+# define BIO_C_SET_BUF_MEM                       114
+# define BIO_C_GET_BUF_MEM_PTR                   115
+# define BIO_C_GET_BUFF_NUM_LINES                116
+# define BIO_C_SET_BUFF_SIZE                     117
+# define BIO_C_SET_ACCEPT                        118
+# define BIO_C_SSL_MODE                          119
+# define BIO_C_GET_MD_CTX                        120
+# define BIO_C_GET_PROXY_PARAM                   121
+# define BIO_C_SET_BUFF_READ_DATA                122/* data to read first */
+# define BIO_C_GET_CONNECT                       123
+# define BIO_C_GET_ACCEPT                        124
+# define BIO_C_SET_SSL_RENEGOTIATE_BYTES         125
+# define BIO_C_GET_SSL_NUM_RENEGOTIATES          126
+# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT       127
+# define BIO_C_FILE_SEEK                         128
+# define BIO_C_GET_CIPHER_CTX                    129
+# define BIO_C_SET_BUF_MEM_EOF_RETURN            130/* return end of input
+                                                     * value */
+# define BIO_C_SET_BIND_MODE                     131
+# define BIO_C_GET_BIND_MODE                     132
+# define BIO_C_FILE_TELL                         133
+# define BIO_C_GET_SOCKS                         134
+# define BIO_C_SET_SOCKS                         135
+
+# define BIO_C_SET_WRITE_BUF_SIZE                136/* for BIO_s_bio */
+# define BIO_C_GET_WRITE_BUF_SIZE                137
+# define BIO_C_MAKE_BIO_PAIR                     138
+# define BIO_C_DESTROY_BIO_PAIR                  139
+# define BIO_C_GET_WRITE_GUARANTEE               140
+# define BIO_C_GET_READ_REQUEST                  141
+# define BIO_C_SHUTDOWN_WR                       142
+# define BIO_C_NREAD0                            143
+# define BIO_C_NREAD                             144
+# define BIO_C_NWRITE0                           145
+# define BIO_C_NWRITE                            146
+# define BIO_C_RESET_READ_REQUEST                147
+# define BIO_C_SET_MD_CTX                        148
+
+# define BIO_C_SET_PREFIX                        149
+# define BIO_C_GET_PREFIX                        150
+# define BIO_C_SET_SUFFIX                        151
+# define BIO_C_GET_SUFFIX                        152
+
+# define BIO_C_SET_EX_ARG                        153
+# define BIO_C_GET_EX_ARG                        154
+
+# define BIO_set_app_data(s,arg)         BIO_set_ex_data(s,0,arg)
+# define BIO_get_app_data(s)             BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+# define BIO_set_conn_ip(b,ip)     BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+# define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+# define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+# define BIO_get_conn_ip(b)               BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
+# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
+
+# define BIO_set_nbio(b,n)       BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept() */
+# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+# define BIO_get_accept_port(b)  BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n)    BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
+# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+# define BIO_BIND_NORMAL                 0
+# define BIO_BIND_REUSEADDR_IF_UNUSED    1
+# define BIO_BIND_REUSEADDR              2
+# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+/* BIO_s_accept() and BIO_s_connect() */
+# define BIO_do_connect(b)       BIO_do_handshake(b)
+# define BIO_do_accept(b)        BIO_do_handshake(b)
+# define BIO_do_handshake(b)     BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+# define BIO_set_url(b,url)      BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+# define BIO_set_proxies(b,p)    BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+# define BIO_get_url(b,url)      BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+# define BIO_get_no_connect_return(b)    BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */
+# define BIO_set_fd(b,fd,c)      BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+# define BIO_get_fd(b,c)         BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+/* BIO_s_file() */
+# define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+# define BIO_get_fp(b,fpp)       BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+/* BIO_s_fd() and BIO_s_file() */
+# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+# define BIO_tell(b)     (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/*
+ * name is cast to lose const, but might be better to route through a
+ * function so we can do it safely
+ */
+# ifdef CONST_STRICT
+/*
+ * If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b, const char *name);
+# else
+#  define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ,(char *)name)
+# endif
+# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_WRITE,name)
+# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_APPEND,name)
+# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/*
+ * WARNING WARNING, this ups the reference count on the read bio of the SSL
+ * structure.  This is because the ssl read BIO is now pointed to by the
+ * next_bio field in the bio.  So when you free the BIO, make sure you are
+ * doing a BIO_free_all() to catch the underlying BIO.
+ */
+# define BIO_set_ssl(b,ssl,c)    BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+# define BIO_get_ssl(b,sslp)     BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+# define BIO_set_ssl_mode(b,client)      BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+# define BIO_set_ssl_renegotiate_bytes(b,num) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+# define BIO_get_num_renegotiates(b) \
+        BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)     BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+# define BIO_get_mem_data(b,pp)  BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+# define BIO_get_mem_ptr(b,pp)   BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+# define BIO_set_mem_eof_return(b,v) \
+                                BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+# define BIO_get_buffer_num_lines(b)     BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+# define BIO_set_buffer_size(b,size)     BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+# define BIO_dup_state(b,ret)    BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+# define BIO_reset(b)            (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+# define BIO_eof(b)              (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+# define BIO_set_close(b,c)      (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+# define BIO_get_close(b)        (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+# define BIO_pending(b)          (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+# define BIO_wpending(b)         (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+# define BIO_flush(b)            (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+                                                   cbp)
+# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+# define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+# define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+# define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+# define BIO_ctrl_set_connected(b, state, peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
+# define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+# define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+# define BIO_dgram_get_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
+# define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+# define BIO_dgram_get_mtu_overhead(b) \
+         (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio, int idx, void *data);
+void *BIO_get_ex_data(BIO *bio, int idx);
+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);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free);
+
+# ifndef OPENSSL_NO_FP_API
+BIO_METHOD *BIO_s_file(void);
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+#  define BIO_s_file_internal    BIO_s_file
+# endif
+BIO *BIO_new(BIO_METHOD *type);
+int BIO_set(BIO *a, BIO_METHOD *type);
+int BIO_free(BIO *a);
+void BIO_vfree(BIO *a);
+int BIO_read(BIO *b, void *data, int len);
+int BIO_gets(BIO *bp, char *buf, int size);
+int BIO_write(BIO *b, const void *data, int len);
+int BIO_puts(BIO *bp, const char *buf);
+int BIO_indent(BIO *b, int indent, int max);
+long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd,
+                       void (*fp) (struct bio_st *, int, const char *, int,
+                                   long, long));
+char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
+long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
+BIO *BIO_push(BIO *b, BIO *append);
+BIO *BIO_pop(BIO *b);
+void BIO_free_all(BIO *a);
+BIO *BIO_find_type(BIO *b, int bio_type);
+BIO *BIO_next(BIO *b);
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
+int BIO_get_retry_reason(BIO *bio);
+BIO *BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
+                        long argl, long ret);
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(const void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+# ifndef OPENSSL_SYS_OS2
+BIO_METHOD *BIO_s_log(void);
+# endif
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+# ifdef OPENSSL_SYS_VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+# endif
+BIO_METHOD *BIO_f_nbio_test(void);
+# ifndef OPENSSL_NO_DGRAM
+BIO_METHOD *BIO_s_datagram(void);
+#  ifndef OPENSSL_NO_SCTP
+BIO_METHOD *BIO_s_datagram_sctp(void);
+#  endif
+# endif
+
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_dgram_non_fatal_error(int error);
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+                void *u, const char *s, int len);
+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 BIO_dump(BIO *b, const char *bytes, int len);
+int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
+# ifndef OPENSSL_NO_FP_API
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+# endif
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen);
+
+struct hostent *BIO_gethostbyname(const char *name);
+/*-
+ * We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ *     struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd, int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port, int mode);
+int BIO_accept(int sock, char **ip_port);
+int BIO_sock_init(void);
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock, int turn_on);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_dgram(int fd, int close_flag);
+# ifndef OPENSSL_NO_SCTP
+BIO *BIO_new_dgram_sctp(int fd, int close_flag);
+int BIO_dgram_is_sctp(BIO *bio);
+int BIO_dgram_sctp_notification_cb(BIO *b,
+                                   void (*handle_notifications) (BIO *bio,
+                                                                 void
+                                                                 *context,
+                                                                 void *buf),
+                                   void *context);
+int BIO_dgram_sctp_wait_for_dry(BIO *b);
+int BIO_dgram_sctp_msg_waiting(BIO *b);
+# endif
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(const char *host_port);
+BIO *BIO_new_accept(const char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+                     BIO **bio2, size_t writebuf2);
+/*
+ * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default
+ * value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*
+ * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+ */
+
+# ifdef __GNUC__
+#  define __bio_h__attr__ __attribute__
+# else
+#  define __bio_h__attr__(x)
+# endif
+int BIO_printf(BIO *bio, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 2, 3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 2, 0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 3, 4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 3, 0)));
+# undef __bio_h__attr__
+
+/* 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_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+# define BIO_F_ACPT_STATE                                 100
+# define BIO_F_BIO_ACCEPT                                 101
+# define BIO_F_BIO_BER_GET_HEADER                         102
+# define BIO_F_BIO_CALLBACK_CTRL                          131
+# define BIO_F_BIO_CTRL                                   103
+# define BIO_F_BIO_GETHOSTBYNAME                          120
+# define BIO_F_BIO_GETS                                   104
+# define BIO_F_BIO_GET_ACCEPT_SOCKET                      105
+# define BIO_F_BIO_GET_HOST_IP                            106
+# define BIO_F_BIO_GET_PORT                               107
+# define BIO_F_BIO_MAKE_PAIR                              121
+# define BIO_F_BIO_NEW                                    108
+# define BIO_F_BIO_NEW_FILE                               109
+# define BIO_F_BIO_NEW_MEM_BUF                            126
+# define BIO_F_BIO_NREAD                                  123
+# define BIO_F_BIO_NREAD0                                 124
+# define BIO_F_BIO_NWRITE                                 125
+# define BIO_F_BIO_NWRITE0                                122
+# define BIO_F_BIO_PUTS                                   110
+# define BIO_F_BIO_READ                                   111
+# define BIO_F_BIO_SOCK_INIT                              112
+# define BIO_F_BIO_WRITE                                  113
+# define BIO_F_BUFFER_CTRL                                114
+# define BIO_F_CONN_CTRL                                  127
+# define BIO_F_CONN_STATE                                 115
+# define BIO_F_DGRAM_SCTP_READ                            132
+# define BIO_F_DGRAM_SCTP_WRITE                           133
+# define BIO_F_FILE_CTRL                                  116
+# define BIO_F_FILE_READ                                  130
+# define BIO_F_LINEBUFFER_CTRL                            129
+# define BIO_F_MEM_READ                                   128
+# define BIO_F_MEM_WRITE                                  117
+# define BIO_F_SSL_NEW                                    118
+# define BIO_F_WSASTARTUP                                 119
+
+/* Reason codes. */
+# define BIO_R_ACCEPT_ERROR                               100
+# define BIO_R_BAD_FOPEN_MODE                             101
+# define BIO_R_BAD_HOSTNAME_LOOKUP                        102
+# define BIO_R_BROKEN_PIPE                                124
+# define BIO_R_CONNECT_ERROR                              103
+# define BIO_R_EOF_ON_MEMORY_BIO                          127
+# define BIO_R_ERROR_SETTING_NBIO                         104
+# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET      105
+# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET        106
+# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET          107
+# define BIO_R_INVALID_ARGUMENT                           125
+# define BIO_R_INVALID_IP_ADDRESS                         108
+# define BIO_R_IN_USE                                     123
+# define BIO_R_KEEPALIVE                                  109
+# define BIO_R_NBIO_CONNECT_ERROR                         110
+# define BIO_R_NO_ACCEPT_PORT_SPECIFIED                   111
+# define BIO_R_NO_HOSTNAME_SPECIFIED                      112
+# define BIO_R_NO_PORT_DEFINED                            113
+# define BIO_R_NO_PORT_SPECIFIED                          114
+# define BIO_R_NO_SUCH_FILE                               128
+# define BIO_R_NULL_PARAMETER                             115
+# define BIO_R_TAG_MISMATCH                               116
+# define BIO_R_UNABLE_TO_BIND_SOCKET                      117
+# define BIO_R_UNABLE_TO_CREATE_SOCKET                    118
+# define BIO_R_UNABLE_TO_LISTEN_SOCKET                    119
+# define BIO_R_UNINITIALIZED                              120
+# define BIO_R_UNSUPPORTED_METHOD                         121
+# define BIO_R_WRITE_TO_READ_ONLY_BIO                     126
+# define BIO_R_WSASTARTUP                                 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/blowfish.h b/Cryptlib/Include/openssl/blowfish.h
new file mode 100644 (file)
index 0000000..8329302
--- /dev/null
@@ -0,0 +1,130 @@
+/* crypto/bf/blowfish.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_BLOWFISH_H
+# define HEADER_BLOWFISH_H
+
+# include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_NO_BF
+#  error BF is disabled.
+# endif
+
+# define BF_ENCRYPT      1
+# define BF_DECRYPT      0
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! BF_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+# if defined(__LP32__)
+#  define BF_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#  define BF_LONG unsigned long
+#  define BF_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *                                      <appro@fy.chalmers.se>
+ */
+# else
+#  define BF_LONG unsigned int
+# endif
+
+# define BF_ROUNDS       16
+# define BF_BLOCK        8
+
+typedef struct bf_key_st {
+    BF_LONG P[BF_ROUNDS + 2];
+    BF_LONG S[4 * 256];
+} BF_KEY;
+
+# ifdef OPENSSL_FIPS
+void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+# endif
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key);
+void BF_decrypt(BF_LONG *data, const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                    const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/bn.h b/Cryptlib/Include/openssl/bn.h
new file mode 100644 (file)
index 0000000..86264ae
--- /dev/null
@@ -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/Include/openssl/buffer.h b/Cryptlib/Include/openssl/buffer.h
new file mode 100644 (file)
index 0000000..efd240a
--- /dev/null
@@ -0,0 +1,125 @@
+/* crypto/buffer/buffer.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_BUFFER_H
+# define HEADER_BUFFER_H
+
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <stddef.h>
+
+# if !defined(NO_SYS_TYPES_H)
+#  include <sys/types.h>
+# endif
+
+/* Already declared in ossl_typ.h */
+/* typedef struct buf_mem_st BUF_MEM; */
+
+struct buf_mem_st {
+    size_t length;              /* current number of bytes */
+    char *data;
+    size_t max;                 /* size of buffer */
+};
+
+BUF_MEM *BUF_MEM_new(void);
+void BUF_MEM_free(BUF_MEM *a);
+int BUF_MEM_grow(BUF_MEM *str, size_t len);
+int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+size_t BUF_strnlen(const char *str, size_t maxlen);
+char *BUF_strdup(const char *str);
+
+/*
+ * Like strndup, but in addition, explicitly guarantees to never read past the
+ * first |siz| bytes of |str|.
+ */
+char *BUF_strndup(const char *str, size_t siz);
+
+void *BUF_memdup(const void *data, size_t siz);
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);
+
+/* safe string functions */
+size_t BUF_strlcpy(char *dst, const char *src, size_t siz);
+size_t BUF_strlcat(char *dst, const char *src, size_t siz);
+
+/* 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_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+# define BUF_F_BUF_MEMDUP                                 103
+# define BUF_F_BUF_MEM_GROW                               100
+# define BUF_F_BUF_MEM_GROW_CLEAN                         105
+# define BUF_F_BUF_MEM_NEW                                101
+# define BUF_F_BUF_STRDUP                                 102
+# define BUF_F_BUF_STRNDUP                                104
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/camellia.h b/Cryptlib/Include/openssl/camellia.h
new file mode 100644 (file)
index 0000000..45e8d25
--- /dev/null
@@ -0,0 +1,132 @@
+/* crypto/camellia/camellia.h */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_CAMELLIA_H
+# define HEADER_CAMELLIA_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_CAMELLIA
+#  error CAMELLIA is disabled.
+# endif
+
+# include <stddef.h>
+
+# define CAMELLIA_ENCRYPT        1
+# define CAMELLIA_DECRYPT        0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+
+# define CAMELLIA_BLOCK_SIZE 16
+# define CAMELLIA_TABLE_BYTE_LEN 272
+# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match
+                                                               * with WORD */
+
+struct camellia_key_st {
+    union {
+        double d;               /* ensures 64-bit align */
+        KEY_TABLE_TYPE rd_key;
+    } u;
+    int grand_rounds;
+};
+typedef struct camellia_key_st CAMELLIA_KEY;
+
+# ifdef OPENSSL_FIPS
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
+                             CAMELLIA_KEY *key);
+# endif
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+                     CAMELLIA_KEY *key);
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                          const CAMELLIA_KEY *key, const int enc);
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                          size_t length, const CAMELLIA_KEY *key,
+                          unsigned char *ivec, const int enc);
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num);
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+                             unsigned int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif                          /* !HEADER_Camellia_H */
diff --git a/Cryptlib/Include/openssl/cast.h b/Cryptlib/Include/openssl/cast.h
new file mode 100644 (file)
index 0000000..0003ec9
--- /dev/null
@@ -0,0 +1,107 @@
+/* crypto/cast/cast.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_CAST_H
+# define HEADER_CAST_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_CAST
+#  error CAST is disabled.
+# endif
+
+# define CAST_ENCRYPT    1
+# define CAST_DECRYPT    0
+
+# define CAST_LONG unsigned int
+
+# define CAST_BLOCK      8
+# define CAST_KEY_LENGTH 16
+
+typedef struct cast_key_st {
+    CAST_LONG data[32];
+    int short_key;              /* Use reduced rounds for short key */
+} CAST_KEY;
+
+# ifdef OPENSSL_FIPS
+void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+# endif
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAST_KEY *key, int enc);
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const CAST_KEY *ks, unsigned char *iv,
+                      int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/cmac.h b/Cryptlib/Include/openssl/cmac.h
new file mode 100644 (file)
index 0000000..175be83
--- /dev/null
@@ -0,0 +1,82 @@
+/* crypto/cmac/cmac.h */
+/*
+ * 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.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMAC_H
+# define HEADER_CMAC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/evp.h>
+
+/* Opaque */
+typedef struct CMAC_CTX_st CMAC_CTX;
+
+CMAC_CTX *CMAC_CTX_new(void);
+void CMAC_CTX_cleanup(CMAC_CTX *ctx);
+void CMAC_CTX_free(CMAC_CTX *ctx);
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+              const EVP_CIPHER *cipher, ENGINE *impl);
+int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
+int CMAC_resume(CMAC_CTX *ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/cms.h b/Cryptlib/Include/openssl/cms.h
new file mode 100644 (file)
index 0000000..e6c7f96
--- /dev/null
@@ -0,0 +1,555 @@
+/* crypto/cms/cms.h */
+/*
+ * 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.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMS_H
+# define HEADER_CMS_H
+
+# include <openssl/x509.h>
+
+# ifdef OPENSSL_NO_CMS
+#  error CMS is disabled.
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+
+DECLARE_STACK_OF(CMS_SignerInfo)
+DECLARE_STACK_OF(GENERAL_NAMES)
+DECLARE_STACK_OF(CMS_RecipientEncryptedKey)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_NONE              -1
+# define CMS_RECIPINFO_TRANS             0
+# define CMS_RECIPINFO_AGREE             1
+# define CMS_RECIPINFO_KEK               2
+# define CMS_RECIPINFO_PASS              3
+# define CMS_RECIPINFO_OTHER             4
+
+/* S/MIME related flags */
+
+# define CMS_TEXT                        0x1
+# define CMS_NOCERTS                     0x2
+# define CMS_NO_CONTENT_VERIFY           0x4
+# define CMS_NO_ATTR_VERIFY              0x8
+# define CMS_NOSIGS                      \
+                        (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+# define CMS_NOINTERN                    0x10
+# define CMS_NO_SIGNER_CERT_VERIFY       0x20
+# define CMS_NOVERIFY                    0x20
+# define CMS_DETACHED                    0x40
+# define CMS_BINARY                      0x80
+# define CMS_NOATTR                      0x100
+# define CMS_NOSMIMECAP                  0x200
+# define CMS_NOOLDMIMETYPE               0x400
+# define CMS_CRLFEOL                     0x800
+# define CMS_STREAM                      0x1000
+# define CMS_NOCRL                       0x2000
+# define CMS_PARTIAL                     0x4000
+# define CMS_REUSE_DIGEST                0x8000
+# define CMS_USE_KEYID                   0x10000
+# define CMS_DEBUG_DECRYPT               0x20000
+# define CMS_KEY_PARAM                   0x40000
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+# ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+# endif
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
+              unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+                               const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+                             const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+                                    unsigned char *pass,
+                                    ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+                                               int iter, int wrap_nid,
+                                               int pbe_nid,
+                                               unsigned char *pass,
+                                               ossl_ssize_t passlen,
+                                               const EVP_CIPHER *kekciph);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags);
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+                           unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig);
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                               int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                               int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                  int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                                 int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type);
+
+# ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+                                               int allorfirst,
+                                               STACK_OF(GENERAL_NAMES)
+                                               *receiptList, STACK_OF(GENERAL_NAMES)
+                                               *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+                                    ASN1_STRING **pcid,
+                                    int *pallorfirst,
+                                    STACK_OF(GENERAL_NAMES) **plist,
+                                    STACK_OF(GENERAL_NAMES) **prto);
+# endif
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm);
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert);
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert);
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk);
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek);
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen);
+
+/* 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_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+# define CMS_F_CHECK_CONTENT                              99
+# define CMS_F_CMS_ADD0_CERT                              164
+# define CMS_F_CMS_ADD0_RECIPIENT_KEY                     100
+# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD                165
+# define CMS_F_CMS_ADD1_RECEIPTREQUEST                    158
+# define CMS_F_CMS_ADD1_RECIPIENT_CERT                    101
+# define CMS_F_CMS_ADD1_SIGNER                            102
+# define CMS_F_CMS_ADD1_SIGNINGTIME                       103
+# define CMS_F_CMS_COMPRESS                               104
+# define CMS_F_CMS_COMPRESSEDDATA_CREATE                  105
+# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO                106
+# define CMS_F_CMS_COPY_CONTENT                           107
+# define CMS_F_CMS_COPY_MESSAGEDIGEST                     108
+# define CMS_F_CMS_DATA                                   109
+# define CMS_F_CMS_DATAFINAL                              110
+# define CMS_F_CMS_DATAINIT                               111
+# define CMS_F_CMS_DECRYPT                                112
+# define CMS_F_CMS_DECRYPT_SET1_KEY                       113
+# define CMS_F_CMS_DECRYPT_SET1_PASSWORD                  166
+# define CMS_F_CMS_DECRYPT_SET1_PKEY                      114
+# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX               115
+# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO               116
+# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL                  117
+# define CMS_F_CMS_DIGEST_VERIFY                          118
+# define CMS_F_CMS_ENCODE_RECEIPT                         161
+# define CMS_F_CMS_ENCRYPT                                119
+# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO              120
+# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT                  121
+# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT                  122
+# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY                 123
+# define CMS_F_CMS_ENVELOPEDDATA_CREATE                   124
+# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO                 125
+# define CMS_F_CMS_ENVELOPED_DATA_INIT                    126
+# define CMS_F_CMS_ENV_ASN1_CTRL                          171
+# define CMS_F_CMS_FINAL                                  127
+# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES               128
+# define CMS_F_CMS_GET0_CONTENT                           129
+# define CMS_F_CMS_GET0_ECONTENT_TYPE                     130
+# define CMS_F_CMS_GET0_ENVELOPED                         131
+# define CMS_F_CMS_GET0_REVOCATION_CHOICES                132
+# define CMS_F_CMS_GET0_SIGNED                            133
+# define CMS_F_CMS_MSGSIGDIGEST_ADD1                      162
+# define CMS_F_CMS_RECEIPTREQUEST_CREATE0                 159
+# define CMS_F_CMS_RECEIPT_VERIFY                         160
+# define CMS_F_CMS_RECIPIENTINFO_DECRYPT                  134
+# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                  169
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT             178
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG            175
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID        173
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS           172
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP         174
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT            135
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT            136
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID            137
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP             138
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP            139
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT             140
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT             141
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS           142
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID      143
+# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT               167
+# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY                 144
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD            168
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY                145
+# define CMS_F_CMS_SD_ASN1_CTRL                           170
+# define CMS_F_CMS_SET1_IAS                               176
+# define CMS_F_CMS_SET1_KEYID                             177
+# define CMS_F_CMS_SET1_SIGNERIDENTIFIER                  146
+# define CMS_F_CMS_SET_DETACHED                           147
+# define CMS_F_CMS_SIGN                                   148
+# define CMS_F_CMS_SIGNED_DATA_INIT                       149
+# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN                150
+# define CMS_F_CMS_SIGNERINFO_SIGN                        151
+# define CMS_F_CMS_SIGNERINFO_VERIFY                      152
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
+# define CMS_F_CMS_SIGN_RECEIPT                           163
+# define CMS_F_CMS_STREAM                                 155
+# define CMS_F_CMS_UNCOMPRESS                             156
+# define CMS_F_CMS_VERIFY                                 157
+
+/* Reason codes. */
+# define CMS_R_ADD_SIGNER_ERROR                           99
+# define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
+# define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
+# define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
+# define CMS_R_CIPHER_INITIALISATION_ERROR                101
+# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR      102
+# define CMS_R_CMS_DATAFINAL_ERROR                        103
+# define CMS_R_CMS_LIB                                    104
+# define CMS_R_CONTENTIDENTIFIER_MISMATCH                 170
+# define CMS_R_CONTENT_NOT_FOUND                          105
+# define CMS_R_CONTENT_TYPE_MISMATCH                      171
+# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA           106
+# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA            107
+# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA               108
+# define CMS_R_CONTENT_VERIFY_ERROR                       109
+# define CMS_R_CTRL_ERROR                                 110
+# define CMS_R_CTRL_FAILURE                               111
+# define CMS_R_DECRYPT_ERROR                              112
+# define CMS_R_DIGEST_ERROR                               161
+# define CMS_R_ERROR_GETTING_PUBLIC_KEY                   113
+# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
+# define CMS_R_ERROR_SETTING_KEY                          115
+# define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
+# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
+# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
+# define CMS_R_INVALID_KEY_LENGTH                         118
+# define CMS_R_MD_BIO_INIT_ERROR                          119
+# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH       120
+# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH                 121
+# define CMS_R_MSGSIGDIGEST_ERROR                         172
+# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE          162
+# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH                  163
+# define CMS_R_NEED_ONE_SIGNER                            164
+# define CMS_R_NOT_A_SIGNED_RECEIPT                       165
+# define CMS_R_NOT_ENCRYPTED_DATA                         122
+# define CMS_R_NOT_KEK                                    123
+# define CMS_R_NOT_KEY_AGREEMENT                          181
+# define CMS_R_NOT_KEY_TRANSPORT                          124
+# define CMS_R_NOT_PWRI                                   177
+# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE            125
+# define CMS_R_NO_CIPHER                                  126
+# define CMS_R_NO_CONTENT                                 127
+# define CMS_R_NO_CONTENT_TYPE                            173
+# define CMS_R_NO_DEFAULT_DIGEST                          128
+# define CMS_R_NO_DIGEST_SET                              129
+# define CMS_R_NO_KEY                                     130
+# define CMS_R_NO_KEY_OR_CERT                             174
+# define CMS_R_NO_MATCHING_DIGEST                         131
+# define CMS_R_NO_MATCHING_RECIPIENT                      132
+# define CMS_R_NO_MATCHING_SIGNATURE                      166
+# define CMS_R_NO_MSGSIGDIGEST                            167
+# define CMS_R_NO_PASSWORD                                178
+# define CMS_R_NO_PRIVATE_KEY                             133
+# define CMS_R_NO_PUBLIC_KEY                              134
+# define CMS_R_NO_RECEIPT_REQUEST                         168
+# define CMS_R_NO_SIGNERS                                 135
+# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE     136
+# define CMS_R_RECEIPT_DECODE_ERROR                       169
+# define CMS_R_RECIPIENT_ERROR                            137
+# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND               138
+# define CMS_R_SIGNFINAL_ERROR                            139
+# define CMS_R_SMIME_TEXT_ERROR                           140
+# define CMS_R_STORE_INIT_ERROR                           141
+# define CMS_R_TYPE_NOT_COMPRESSED_DATA                   142
+# define CMS_R_TYPE_NOT_DATA                              143
+# define CMS_R_TYPE_NOT_DIGESTED_DATA                     144
+# define CMS_R_TYPE_NOT_ENCRYPTED_DATA                    145
+# define CMS_R_TYPE_NOT_ENVELOPED_DATA                    146
+# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                 147
+# define CMS_R_UNKNOWN_CIPHER                             148
+# define CMS_R_UNKNOWN_DIGEST_ALGORIHM                    149
+# define CMS_R_UNKNOWN_ID                                 150
+# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM          151
+# define CMS_R_UNSUPPORTED_CONTENT_TYPE                   152
+# define CMS_R_UNSUPPORTED_KEK_ALGORITHM                  153
+# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM       179
+# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE                 154
+# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE              155
+# define CMS_R_UNSUPPORTED_TYPE                           156
+# define CMS_R_UNWRAP_ERROR                               157
+# define CMS_R_UNWRAP_FAILURE                             180
+# define CMS_R_VERIFICATION_FAILURE                       158
+# define CMS_R_WRAP_ERROR                                 159
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/comp.h b/Cryptlib/Include/openssl/comp.h
new file mode 100644 (file)
index 0000000..60a0734
--- /dev/null
@@ -0,0 +1,83 @@
+
+#ifndef HEADER_COMP_H
+# define HEADER_COMP_H
+
+# include <openssl/crypto.h>
+
+# ifdef OPENSSL_NO_COMP
+#  error COMP is disabled.
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct comp_ctx_st COMP_CTX;
+
+typedef struct comp_method_st {
+    int type;                   /* NID for compression library */
+    const char *name;           /* A text string to identify the library */
+    int (*init) (COMP_CTX *ctx);
+    void (*finish) (COMP_CTX *ctx);
+    int (*compress) (COMP_CTX *ctx,
+                     unsigned char *out, unsigned int olen,
+                     unsigned char *in, unsigned int ilen);
+    int (*expand) (COMP_CTX *ctx,
+                   unsigned char *out, unsigned int olen,
+                   unsigned char *in, unsigned int ilen);
+    /*
+     * The following two do NOTHING, but are kept for backward compatibility
+     */
+    long (*ctrl) (void);
+    long (*callback_ctrl) (void);
+} COMP_METHOD;
+
+struct comp_ctx_st {
+    COMP_METHOD *meth;
+    unsigned long compress_in;
+    unsigned long compress_out;
+    unsigned long expand_in;
+    unsigned long expand_out;
+    CRYPTO_EX_DATA ex_data;
+};
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                        unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                      unsigned char *in, int ilen);
+COMP_METHOD *COMP_rle(void);
+COMP_METHOD *COMP_zlib(void);
+void COMP_zlib_cleanup(void);
+
+# ifdef HEADER_BIO_H
+#  ifdef ZLIB
+BIO_METHOD *BIO_f_zlib(void);
+#  endif
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_COMP_strings(void);
+
+/* Error codes for the COMP functions. */
+
+/* Function codes. */
+# define COMP_F_BIO_ZLIB_FLUSH                            99
+# define COMP_F_BIO_ZLIB_NEW                              100
+# define COMP_F_BIO_ZLIB_READ                             101
+# define COMP_F_BIO_ZLIB_WRITE                            102
+
+/* Reason codes. */
+# define COMP_R_ZLIB_DEFLATE_ERROR                        99
+# define COMP_R_ZLIB_INFLATE_ERROR                        100
+# define COMP_R_ZLIB_NOT_SUPPORTED                        101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/conf.h b/Cryptlib/Include/openssl/conf.h
new file mode 100644 (file)
index 0000000..c29e97d
--- /dev/null
@@ -0,0 +1,277 @@
+/* crypto/conf/conf.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_CONF_H
+# define HEADER_CONF_H
+
+# include <openssl/bio.h>
+# include <openssl/lhash.h>
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+# include <openssl/e_os2.h>
+
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    char *section;
+    char *name;
+    char *value;
+} CONF_VALUE;
+
+DECLARE_STACK_OF(CONF_VALUE)
+DECLARE_LHASH_OF(CONF_VALUE);
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st {
+    const char *name;
+    CONF *(*create) (CONF_METHOD *meth);
+    int (*init) (CONF *conf);
+    int (*destroy) (CONF *conf);
+    int (*destroy_data) (CONF *conf);
+    int (*load_bio) (CONF *conf, BIO *bp, long *eline);
+    int (*dump) (const CONF *conf, BIO *bp);
+    int (*is_number) (const CONF *conf, char c);
+    int (*to_int) (const CONF *conf, char c);
+    int (*load) (CONF *conf, const char *name, long *eline);
+};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
+/* DSO module function typedefs */
+typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func (CONF_IMODULE *md);
+
+# define CONF_MFLAGS_IGNORE_ERRORS       0x1
+# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2
+# define CONF_MFLAGS_SILENT              0x4
+# define CONF_MFLAGS_NO_DSO              0x8
+# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+# define CONF_MFLAGS_DEFAULT_SECTION     0x20
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash);
+# ifndef OPENSSL_NO_STDIO
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+                                long *eline);
+# endif
+# ifndef OPENSSL_NO_FP_API
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+                                   long *eline);
+# endif
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+                                    long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+                                       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+# ifndef OPENSSL_NO_FP_API
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+# endif
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
+
+void OPENSSL_config(const char *config_name);
+void OPENSSL_no_config(void);
+
+/*
+ * New conf code.  The semantics are different from the functions above. If
+ * that wasn't the case, the above functions would have been replaced
+ */
+
+struct conf_st {
+    CONF_METHOD *meth;
+    void *meth_data;
+    LHASH_OF(CONF_VALUE) *data;
+};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+# if 0                          /* Just to give you an idea of what I have in
+                                 * mind */
+CONF_METHOD *NCONF_XML(void);
+# endif
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+# ifndef OPENSSL_NO_STDIO
+int NCONF_load(CONF *conf, const char *file, long *eline);
+# endif
+# ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline);
+# endif
+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
+                                        const char *section);
+char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+                       long *result);
+# ifndef OPENSSL_NO_FP_API
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+# endif
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+# if 0                          /* The following function has no error
+                                 * checking, and should therefore be avoided */
+long NCONF_get_number(CONF *conf, char *group, char *name);
+# else
+#  define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+# endif
+
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+                      unsigned long flags);
+# ifndef OPENSSL_NO_STDIO
+int CONF_modules_load_file(const char *filename, const char *appname,
+                           unsigned long flags);
+# endif
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+void CONF_modules_free(void);
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+                    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+                    int (*list_cb) (const char *elem, int len, void *usr),
+                    void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CONF_strings(void);
+
+/* Error codes for the CONF functions. */
+
+/* Function codes. */
+# define CONF_F_CONF_DUMP_FP                              104
+# define CONF_F_CONF_LOAD                                 100
+# define CONF_F_CONF_LOAD_BIO                             102
+# define CONF_F_CONF_LOAD_FP                              103
+# define CONF_F_CONF_MODULES_LOAD                         116
+# define CONF_F_CONF_PARSE_LIST                           119
+# define CONF_F_DEF_LOAD                                  120
+# define CONF_F_DEF_LOAD_BIO                              121
+# define CONF_F_MODULE_INIT                               115
+# define CONF_F_MODULE_LOAD_DSO                           117
+# define CONF_F_MODULE_RUN                                118
+# define CONF_F_NCONF_DUMP_BIO                            105
+# define CONF_F_NCONF_DUMP_FP                             106
+# define CONF_F_NCONF_GET_NUMBER                          107
+# define CONF_F_NCONF_GET_NUMBER_E                        112
+# define CONF_F_NCONF_GET_SECTION                         108
+# define CONF_F_NCONF_GET_STRING                          109
+# define CONF_F_NCONF_LOAD                                113
+# define CONF_F_NCONF_LOAD_BIO                            110
+# define CONF_F_NCONF_LOAD_FP                             114
+# define CONF_F_NCONF_NEW                                 111
+# define CONF_F_STR_COPY                                  101
+
+/* Reason codes. */
+# define CONF_R_ERROR_LOADING_DSO                         110
+# define CONF_R_LIST_CANNOT_BE_NULL                       115
+# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET              100
+# define CONF_R_MISSING_EQUAL_SIGN                        101
+# define CONF_R_MISSING_FINISH_FUNCTION                   111
+# define CONF_R_MISSING_INIT_FUNCTION                     112
+# define CONF_R_MODULE_INITIALIZATION_ERROR               109
+# define CONF_R_NO_CLOSE_BRACE                            102
+# define CONF_R_NO_CONF                                   105
+# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE           106
+# define CONF_R_NO_SECTION                                107
+# define CONF_R_NO_SUCH_FILE                              114
+# define CONF_R_NO_VALUE                                  108
+# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION              103
+# define CONF_R_UNKNOWN_MODULE_NAME                       113
+# define CONF_R_VARIABLE_HAS_NO_VALUE                     104
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/conf_api.h b/Cryptlib/Include/openssl/conf_api.h
new file mode 100644 (file)
index 0000000..e478f7d
--- /dev/null
@@ -0,0 +1,89 @@
+/* conf_api.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_CONF_API_H
+# define HEADER_CONF_API_H
+
+# include <openssl/lhash.h>
+# include <openssl/conf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* 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);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+                       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section,
+                      const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/crypto.h b/Cryptlib/Include/openssl/crypto.h
new file mode 100644 (file)
index 0000000..bea4ca1
--- /dev/null
@@ -0,0 +1,661 @@
+/* crypto/crypto.h */
+/* ====================================================================
+ * 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.
+ */
+
+#ifndef HEADER_CRYPTO_H
+# define HEADER_CRYPTO_H
+
+# include <stdlib.h>
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+#  include <stdio.h>
+# endif
+
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+# include <openssl/opensslv.h>
+# include <openssl/ossl_typ.h>
+
+# ifdef CHARSET_EBCDIC
+#  include <openssl/ebcdic.h>
+# endif
+
+/*
+ * Resolve problems on some operating systems with symbol names that clash
+ * one way or another
+ */
+# include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Backward compatibility to SSLeay */
+/*
+ * This is more to be used to check the correct DLL is being used in the MS
+ * world.
+ */
+# define SSLEAY_VERSION_NUMBER   OPENSSL_VERSION_NUMBER
+# define SSLEAY_VERSION          0
+/* #define SSLEAY_OPTIONS       1 no longer supported */
+# define SSLEAY_CFLAGS           2
+# define SSLEAY_BUILT_ON         3
+# define SSLEAY_PLATFORM         4
+# define SSLEAY_DIR              5
+
+/* Already declared in ossl_typ.h */
+# if 0
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                           int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                             int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+                           void *from_d, int idx, long argl, void *argp);
+# endif
+
+/* A generic structure to pass assorted data in a expandable way */
+typedef struct openssl_item_st {
+    int code;
+    void *value;                /* Not used for flag attributes */
+    size_t value_size;          /* Max size of value for output, length for
+                                 * input */
+    size_t *value_length;       /* Returned length of value for output */
+} OPENSSL_ITEM;
+
+/*
+ * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+# define CRYPTO_LOCK_ERR                 1
+# define CRYPTO_LOCK_EX_DATA             2
+# define CRYPTO_LOCK_X509                3
+# define CRYPTO_LOCK_X509_INFO           4
+# define CRYPTO_LOCK_X509_PKEY           5
+# define CRYPTO_LOCK_X509_CRL            6
+# define CRYPTO_LOCK_X509_REQ            7
+# define CRYPTO_LOCK_DSA                 8
+# define CRYPTO_LOCK_RSA                 9
+# define CRYPTO_LOCK_EVP_PKEY            10
+# define CRYPTO_LOCK_X509_STORE          11
+# define CRYPTO_LOCK_SSL_CTX             12
+# define CRYPTO_LOCK_SSL_CERT            13
+# define CRYPTO_LOCK_SSL_SESSION         14
+# define CRYPTO_LOCK_SSL_SESS_CERT       15
+# define CRYPTO_LOCK_SSL                 16
+# define CRYPTO_LOCK_SSL_METHOD          17
+# define CRYPTO_LOCK_RAND                18
+# define CRYPTO_LOCK_RAND2               19
+# define CRYPTO_LOCK_MALLOC              20
+# define CRYPTO_LOCK_BIO                 21
+# define CRYPTO_LOCK_GETHOSTBYNAME       22
+# define CRYPTO_LOCK_GETSERVBYNAME       23
+# define CRYPTO_LOCK_READDIR             24
+# define CRYPTO_LOCK_RSA_BLINDING        25
+# define CRYPTO_LOCK_DH                  26
+# define CRYPTO_LOCK_MALLOC2             27
+# define CRYPTO_LOCK_DSO                 28
+# define CRYPTO_LOCK_DYNLOCK             29
+# define CRYPTO_LOCK_ENGINE              30
+# define CRYPTO_LOCK_UI                  31
+# define CRYPTO_LOCK_ECDSA               32
+# define CRYPTO_LOCK_EC                  33
+# define CRYPTO_LOCK_ECDH                34
+# define CRYPTO_LOCK_BN                  35
+# define CRYPTO_LOCK_EC_PRE_COMP         36
+# define CRYPTO_LOCK_STORE               37
+# define CRYPTO_LOCK_COMP                38
+# define CRYPTO_LOCK_FIPS                39
+# define CRYPTO_LOCK_FIPS2               40
+# define CRYPTO_NUM_LOCKS                41
+
+# define CRYPTO_LOCK             1
+# define CRYPTO_UNLOCK           2
+# define CRYPTO_READ             4
+# define CRYPTO_WRITE            8
+
+# ifndef OPENSSL_NO_LOCKING
+#  ifndef CRYPTO_w_lock
+#   define CRYPTO_w_lock(type)     \
+        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE)
+#   define CRYPTO_w_unlock(type)   \
+        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE)
+#   define CRYPTO_r_lock(type)     \
+        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE)
+#   define CRYPTO_r_unlock(type)   \
+        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE)
+#   define CRYPTO_add(addr,amount,type)    \
+        CRYPTO_add_lock(addr,amount,type,OPENSSL_FILE,OPENSSL_LINE)
+#  endif
+# else
+#  define CRYPTO_w_lock(a)
+#  define CRYPTO_w_unlock(a)
+#  define CRYPTO_r_lock(a)
+#  define CRYPTO_r_unlock(a)
+#  define CRYPTO_add(a,b,c)       ((*(a))+=(b))
+# endif
+
+/*
+ * Some applications as well as some parts of OpenSSL need to allocate and
+ * deallocate locks in a dynamic fashion.  The following typedef makes this
+ * possible in a type-safe manner.
+ */
+/* struct CRYPTO_dynlock_value has to be defined by the application. */
+typedef struct {
+    int references;
+    struct CRYPTO_dynlock_value *data;
+} CRYPTO_dynlock;
+
+/*
+ * The following can be used to detect memory leaks in the SSLeay library. It
+ * used, it turns on malloc checking
+ */
+
+# define CRYPTO_MEM_CHECK_OFF    0x0/* an enume */
+# define CRYPTO_MEM_CHECK_ON     0x1/* a bit */
+# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */
+# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */
+
+/*
+ * The following are bit values to turn on or off options connected to the
+ * malloc checking functionality
+ */
+
+/* Adds time to the memory checking information */
+# define V_CRYPTO_MDEBUG_TIME    0x1/* a bit */
+/* Adds thread number to the memory checking information */
+# define V_CRYPTO_MDEBUG_THREAD  0x2/* a bit */
+
+# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+struct crypto_ex_data_st {
+    STACK_OF(void) *sk;
+    /* gcc is screwing up this data structure :-( */
+    int dummy;
+};
+DECLARE_STACK_OF(void)
+
+/*
+ * This stuff is basically class callback functions The current classes are
+ * SSL_CTX, SSL, SSL_SESSION, and a few more
+ */
+
+typedef struct crypto_ex_data_func_st {
+    long argl;                  /* Arbitary long */
+    void *argp;                 /* Arbitary void * */
+    CRYPTO_EX_new *new_func;
+    CRYPTO_EX_free *free_func;
+    CRYPTO_EX_dup *dup_func;
+} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/*
+ * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+# define CRYPTO_EX_INDEX_BIO             0
+# define CRYPTO_EX_INDEX_SSL             1
+# define CRYPTO_EX_INDEX_SSL_CTX         2
+# define CRYPTO_EX_INDEX_SSL_SESSION     3
+# define CRYPTO_EX_INDEX_X509_STORE      4
+# define CRYPTO_EX_INDEX_X509_STORE_CTX  5
+# define CRYPTO_EX_INDEX_RSA             6
+# define CRYPTO_EX_INDEX_DSA             7
+# define CRYPTO_EX_INDEX_DH              8
+# define CRYPTO_EX_INDEX_ENGINE          9
+# define CRYPTO_EX_INDEX_X509            10
+# define CRYPTO_EX_INDEX_UI              11
+# define CRYPTO_EX_INDEX_ECDSA           12
+# define CRYPTO_EX_INDEX_ECDH            13
+# define CRYPTO_EX_INDEX_COMP            14
+# define CRYPTO_EX_INDEX_STORE           15
+
+/*
+ * Dynamically assigned indexes start from this value (don't use directly,
+ * use via CRYPTO_ex_data_new_class).
+ */
+# define CRYPTO_EX_INDEX_USER            100
+
+/*
+ * This is the default callbacks, but we can have others as well: this is
+ * needed in Win32 where the application malloc and the library malloc may
+ * not be the same.
+ */
+# define CRYPTO_malloc_init()    CRYPTO_set_mem_functions(\
+        malloc, realloc, free)
+
+# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+#  ifndef CRYPTO_MDEBUG         /* avoid duplicate #define */
+#   define CRYPTO_MDEBUG
+#  endif
+# endif
+
+/*
+ * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG
+ * is defined)
+ */
+# define CRYPTO_malloc_debug_init()      do {\
+        CRYPTO_set_mem_debug_functions(\
+                CRYPTO_dbg_malloc,\
+                CRYPTO_dbg_realloc,\
+                CRYPTO_dbg_free,\
+                CRYPTO_dbg_set_options,\
+                CRYPTO_dbg_get_options);\
+        } while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+# define MemCheck_on()   CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+# define MemCheck_off()  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+# define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+# define OPENSSL_malloc(num)     CRYPTO_malloc((int)num,OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_strdup(str)     CRYPTO_strdup((str),OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_realloc(addr,num) \
+        CRYPTO_realloc((char *)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_realloc_clean(addr,old_num,num) \
+        CRYPTO_realloc_clean(addr,old_num,num,OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_remalloc(addr,num) \
+        CRYPTO_remalloc((char **)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_freeFunc        CRYPTO_free
+# define OPENSSL_free(addr)      CRYPTO_free(addr)
+
+# define OPENSSL_malloc_locked(num) \
+        CRYPTO_malloc_locked((int)num,OPENSSL_FILE,OPENSSL_LINE)
+# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int OPENSSL_issetugid(void);
+
+/* An opaque type representing an implementation of "ex_data" support */
+typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL;
+/* Return an opaque pointer to the current "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+/* Sets the "ex_data" implementation to be used (if it's not too late) */
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
+/* Get a new "ex_data" class, and return the corresponding "class_index" */
+int CRYPTO_ex_data_new_class(void);
+/* Within a given 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);
+/*
+ * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a
+ * given class (invokes whatever per-class callbacks are applicable)
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+                       CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/*
+ * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular
+ * index (relative to the class type involved)
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
+/*
+ * This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions.
+ */
+void CRYPTO_cleanup_all_ex_data(void);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void);     /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type, const char *file, int line);
+void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
+                                               const char *file, int line));
+void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
+                                           const char *file, int line);
+void CRYPTO_set_add_lock_callback(int (*func)
+                                   (int *num, int mount, int type,
+                                    const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
+                                           const char *file, int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st {
+    void *ptr;
+    unsigned long val;
+} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+# ifndef OPENSSL_NO_DEPRECATED
+void CRYPTO_set_id_callback(unsigned long (*func) (void));
+unsigned long (*CRYPTO_get_id_callback(void)) (void);
+unsigned long CRYPTO_thread_id(void);
+# endif
+
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+                    int line);
+
+int CRYPTO_get_new_dynlockid(void);
+void CRYPTO_destroy_dynlockid(int i);
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value
+                                        *(*dyn_create_function) (const char
+                                                                 *file,
+                                                                 int line));
+void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
+                                       (int mode,
+                                        struct CRYPTO_dynlock_value *l,
+                                        const char *file, int line));
+void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
+                                          (struct CRYPTO_dynlock_value *l,
+                                           const char *file, int line));
+struct CRYPTO_dynlock_value
+*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line);
+void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
+                                                struct CRYPTO_dynlock_value
+                                                *l, const char *file,
+                                                int line);
+void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value
+                                                   *l, const char *file,
+                                                   int line);
+
+/*
+ * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call
+ * the latter last if you need different functions
+ */
+int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
+                             void (*f) (void *));
+int CRYPTO_set_locked_mem_functions(void *(*m) (size_t),
+                                    void (*free_func) (void *));
+int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+                                void *(*r) (void *, size_t, const char *,
+                                            int), void (*f) (void *));
+int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
+                                       void (*free_func) (void *));
+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));
+void CRYPTO_get_mem_functions(void *(**m) (size_t),
+                              void *(**r) (void *, size_t),
+                              void (**f) (void *));
+void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
+                                     void (**f) (void *));
+void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
+                                 void *(**r) (void *, size_t, const char *,
+                                              int), void (**f) (void *));
+void CRYPTO_get_locked_mem_ex_functions(void
+                                        *(**m) (size_t, const char *, int),
+                                        void (**f) (void *));
+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));
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *ptr);
+void *CRYPTO_malloc(int num, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
+void CRYPTO_free(void *ptr);
+void *CRYPTO_realloc(void *addr, int num, const char *file, int line);
+void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file,
+                           int line);
+void *CRYPTO_remalloc(void *addr, int num, const char *file, int line);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+# define CRYPTO_push_info(info) \
+        CRYPTO_push_info_(info, OPENSSL_FILE, OPENSSL_LINE);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+/*
+ * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
+ * used as default in CRYPTO_MDEBUG compilations):
+ */
+/*-
+ * The last argument has the following significance:
+ *
+ * 0:   called before the actual memory allocation has taken place
+ * 1:   called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
+                       int before_p);
+void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file,
+                        int line, int before_p);
+void CRYPTO_dbg_free(void *addr, int before_p);
+/*-
+ * Tell the debugging code about options.  By default, the following values
+ * apply:
+ *
+ * 0:                           Clear all options.
+ * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
+ * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
+ * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+# ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+# endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int,
+                                  void *);
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
+
+/* die if we have to */
+void OpenSSLDie(const char *file, int line, const char *assertion);
+# define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, #e),1))
+
+unsigned long *OPENSSL_ia32cap_loc(void);
+# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+int OPENSSL_isservice(void);
+
+int FIPS_mode(void);
+int FIPS_mode_set(int r);
+
+void OPENSSL_init(void);
+
+# define fips_md_init(alg) fips_md_init_ctx(alg, alg)
+
+# ifdef OPENSSL_FIPS
+#  define fips_md_init_ctx(alg, cx) \
+        int alg##_Init(cx##_CTX *c) \
+        { \
+        if (FIPS_mode()) OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, \
+                "Low level API call to digest " #alg " forbidden in FIPS mode!"); \
+        return private_##alg##_Init(c); \
+        } \
+        int private_##alg##_Init(cx##_CTX *c)
+
+#  define fips_cipher_abort(alg) \
+        if (FIPS_mode()) OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, \
+                "Low level API call to cipher " #alg " forbidden in FIPS mode!")
+
+# else
+#  define fips_md_init_ctx(alg, cx) \
+        int alg##_Init(cx##_CTX *c)
+#  define fips_cipher_abort(alg) while(0)
+# endif
+
+/*
+ * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal.
+ * It takes an amount of time dependent on |len|, but independent of the
+ * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements
+ * into a defined order as the return value when a != b is undefined, other
+ * than to be non-zero.
+ */
+int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX                 100
+# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID                103
+# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID                   101
+# define CRYPTO_F_CRYPTO_SET_EX_DATA                      102
+# define CRYPTO_F_DEF_ADD_INDEX                           104
+# define CRYPTO_F_DEF_GET_CLASS                           105
+# define CRYPTO_F_FIPS_MODE_SET                           109
+# define CRYPTO_F_INT_DUP_EX_DATA                         106
+# define CRYPTO_F_INT_FREE_EX_DATA                        107
+# define CRYPTO_F_INT_NEW_EX_DATA                         108
+
+/* Reason codes. */
+# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                 101
+# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK              100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/des.h b/Cryptlib/Include/openssl/des.h
new file mode 100644 (file)
index 0000000..1b40144
--- /dev/null
@@ -0,0 +1,257 @@
+/* crypto/des/des.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_NEW_DES_H
+# define HEADER_NEW_DES_H
+
+# include <openssl/e_os2.h>     /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG
+                                 * (via openssl/opensslconf.h */
+
+# ifdef OPENSSL_NO_DES
+#  error DES is disabled.
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/*
+ * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and
+ * const_DES_cblock * are incompatible pointer types.
+ */
+
+typedef struct DES_ks {
+    union {
+        DES_cblock cblock;
+        /*
+         * make sure things are correct size on machines with 8 byte longs
+         */
+        DES_LONG deslong[2];
+    } ks[16];
+} DES_key_schedule;
+
+# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+#  ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#   define OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  endif
+# endif
+
+# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  include <openssl/des_old.h>
+# endif
+
+# define DES_KEY_SZ      (sizeof(DES_cblock))
+# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+# define DES_ENCRYPT     1
+# define DES_DECRYPT     0
+
+# define DES_CBC_MODE    0
+# define DES_PCBC_MODE   1
+
+# define DES_ecb2_encrypt(i,o,k1,k2,e) \
+        DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+        DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+        DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+        DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */
+# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */
+# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
+
+const char *DES_options(void);
+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);
+DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
+                       long length, DES_key_schedule *schedule,
+                       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, const_DES_cblock *inw,
+                      const_DES_cblock *outw, int enc);
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks, int enc);
+
+/*
+ * This is the DES encryption function that gets called by just about every
+ * other DES routine in the library.  You should not use this function except
+ * to implement 'modes' of DES.  I say this because the functions that call
+ * this routine do the conversion from 'char *' to long, and this needs to be
+ * done to make sure 'non-aligned' memory access do not occur.  The
+ * characters are loaded 'little endian'. Data is a pointer to 2 unsigned
+ * long's and ks is the DES_key_schedule to use.  enc, is non zero specifies
+ * encryption, zero if decryption.
+ */
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+/*
+ * This functions is the same as DES_encrypt1() except that the DES initial
+ * permutation (IP) and final permutation (FP) have been left out.  As for
+ * DES_encrypt1(), you should not use this function. It is used by the
+ * routines in the library that implement triple DES. IP() DES_encrypt2()
+ * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1()
+ * DES_encrypt1() DES_encrypt1() except faster :-).
+ */
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+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);
+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);
+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);
+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);
+void DES_ede3_ofb64_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);
+# if 0
+void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white,
+                       DES_cblock *out_white);
+# endif
+
+int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
+                 DES_cblock *iv);
+int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched,
+                  DES_cblock *iv);
+char *DES_fcrypt(const char *buf, const char *salt, char *ret);
+char *DES_crypt(const char *buf, const char *salt);
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+                        long length, int out_count, DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/*
+ * DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise.
+ */
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
+# ifdef OPENSSL_FIPS
+void private_DES_set_key_unchecked(const_DES_cblock *key,
+                                   DES_key_schedule *schedule);
+# endif
+void DES_string_to_key(const char *str, DES_cblock *key);
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num, int enc);
+void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num);
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify);
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2,
+                        const char *prompt, int verify);
+
+# define DES_fixup_key_parity DES_set_odd_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/des_old.h b/Cryptlib/Include/openssl/des_old.h
new file mode 100644 (file)
index 0000000..ee7607a
--- /dev/null
@@ -0,0 +1,497 @@
+/* crypto/des/des_old.h */
+
+/*-
+ * 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.6 and older as
+ * well as 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.
+ *
+ * This include files has two compatibility modes:
+ *
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
+ *     that is compatible with libdes and SSLeay.
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
+ *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
+ *
+ * Note that these modes break earlier snapshots of OpenSSL, where
+ * libdes compatibility was the only available mode or (later on) the
+ * prefered compatibility mode.  However, after much consideration
+ * (and more or less violent discussions with external parties), it
+ * was concluded that OpenSSL should be compatible with earlier versions
+ * of itself before anything else.  Also, in all honesty, libdes is
+ * an old beast that shouldn't really be used any more.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will disappear 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-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).
+ *
+ */
+
+#ifndef HEADER_DES_H
+# define HEADER_DES_H
+
+# include <openssl/e_os2.h>     /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */
+
+# ifdef OPENSSL_NO_DES
+#  error DES is disabled.
+# endif
+
+# ifndef HEADER_NEW_DES_H
+#  error You must include des.h, not des_old.h directly.
+# endif
+
+# ifdef _KERBEROS_DES_H
+#  error <openssl/des_old.h> replaces <kerberos/des.h>.
+# endif
+
+# include <openssl/symhacks.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef _
+#  undef _
+# endif
+
+typedef unsigned char _ossl_old_des_cblock[8];
+typedef struct _ossl_old_des_ks_struct {
+    union {
+        _ossl_old_des_cblock _;
+        /*
+         * make sure things are correct size on machines with 8 byte longs
+         */
+        DES_LONG pad[2];
+    } ks;
+} _ossl_old_des_key_schedule[16];
+
+# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
+#  define des_cblock DES_cblock
+#  define const_des_cblock const_DES_cblock
+#  define des_key_schedule DES_key_schedule
+#  define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+        DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
+#  define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+        DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
+#  define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
+        DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
+#  define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+        DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
+#  define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+        DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
+#  define des_options()\
+        DES_options()
+#  define des_cbc_cksum(i,o,l,k,iv)\
+        DES_cbc_cksum((i),(o),(l),&(k),(iv))
+#  define des_cbc_encrypt(i,o,l,k,iv,e)\
+        DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#  define des_ncbc_encrypt(i,o,l,k,iv,e)\
+        DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#  define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+        DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
+#  define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+        DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
+#  define des_ecb_encrypt(i,o,k,e)\
+        DES_ecb_encrypt((i),(o),&(k),(e))
+#  define des_encrypt1(d,k,e)\
+        DES_encrypt1((d),&(k),(e))
+#  define des_encrypt2(d,k,e)\
+        DES_encrypt2((d),&(k),(e))
+#  define des_encrypt3(d,k1,k2,k3)\
+        DES_encrypt3((d),&(k1),&(k2),&(k3))
+#  define des_decrypt3(d,k1,k2,k3)\
+        DES_decrypt3((d),&(k1),&(k2),&(k3))
+#  define des_xwhite_in2out(k,i,o)\
+        DES_xwhite_in2out((k),(i),(o))
+#  define des_enc_read(f,b,l,k,iv)\
+        DES_enc_read((f),(b),(l),&(k),(iv))
+#  define des_enc_write(f,b,l,k,iv)\
+        DES_enc_write((f),(b),(l),&(k),(iv))
+#  define des_fcrypt(b,s,r)\
+        DES_fcrypt((b),(s),(r))
+#  if 0
+#   define des_crypt(b,s)\
+        DES_crypt((b),(s))
+#   if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
+#    define crypt(b,s)\
+        DES_crypt((b),(s))
+#   endif
+#  endif
+#  define des_ofb_encrypt(i,o,n,l,k,iv)\
+        DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
+#  define des_pcbc_encrypt(i,o,l,k,iv,e)\
+        DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#  define des_quad_cksum(i,o,l,c,s)\
+        DES_quad_cksum((i),(o),(l),(c),(s))
+#  define des_random_seed(k)\
+        _ossl_096_des_random_seed((k))
+#  define des_random_key(r)\
+        DES_random_key((r))
+#  define des_read_password(k,p,v) \
+        DES_read_password((k),(p),(v))
+#  define des_read_2passwords(k1,k2,p,v) \
+        DES_read_2passwords((k1),(k2),(p),(v))
+#  define des_set_odd_parity(k)\
+        DES_set_odd_parity((k))
+#  define des_check_key_parity(k)\
+        DES_check_key_parity((k))
+#  define des_is_weak_key(k)\
+        DES_is_weak_key((k))
+#  define des_set_key(k,ks)\
+        DES_set_key((k),&(ks))
+#  define des_key_sched(k,ks)\
+        DES_key_sched((k),&(ks))
+#  define des_set_key_checked(k,ks)\
+        DES_set_key_checked((k),&(ks))
+#  define des_set_key_unchecked(k,ks)\
+        DES_set_key_unchecked((k),&(ks))
+#  define des_string_to_key(s,k)\
+        DES_string_to_key((s),(k))
+#  define des_string_to_2keys(s,k1,k2)\
+        DES_string_to_2keys((s),(k1),(k2))
+#  define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+        DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
+#  define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+        DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))
+
+#  define des_ecb2_encrypt(i,o,k1,k2,e) \
+        des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#  define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+        des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#  define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#  define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+        des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#  define des_check_key DES_check_key
+#  define des_rw_mode DES_rw_mode
+# else                          /* libdes compatibility */
+/*
+ * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with
+ * libdes
+ */
+#  define des_cblock _ossl_old_des_cblock
+#  define des_key_schedule _ossl_old_des_key_schedule
+#  define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+        _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
+#  define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+        _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
+#  define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+        _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
+#  define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+        _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
+#  define des_options()\
+        _ossl_old_des_options()
+#  define des_cbc_cksum(i,o,l,k,iv)\
+        _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
+#  define des_cbc_encrypt(i,o,l,k,iv,e)\
+        _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
+#  define des_ncbc_encrypt(i,o,l,k,iv,e)\
+        _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
+#  define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+        _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
+#  define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+        _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
+#  define des_ecb_encrypt(i,o,k,e)\
+        _ossl_old_des_ecb_encrypt((i),(o),(k),(e))
+#  define des_encrypt(d,k,e)\
+        _ossl_old_des_encrypt((d),(k),(e))
+#  define des_encrypt2(d,k,e)\
+        _ossl_old_des_encrypt2((d),(k),(e))
+#  define des_encrypt3(d,k1,k2,k3)\
+        _ossl_old_des_encrypt3((d),(k1),(k2),(k3))
+#  define des_decrypt3(d,k1,k2,k3)\
+        _ossl_old_des_decrypt3((d),(k1),(k2),(k3))
+#  define des_xwhite_in2out(k,i,o)\
+        _ossl_old_des_xwhite_in2out((k),(i),(o))
+#  define des_enc_read(f,b,l,k,iv)\
+        _ossl_old_des_enc_read((f),(b),(l),(k),(iv))
+#  define des_enc_write(f,b,l,k,iv)\
+        _ossl_old_des_enc_write((f),(b),(l),(k),(iv))
+#  define des_fcrypt(b,s,r)\
+        _ossl_old_des_fcrypt((b),(s),(r))
+#  define des_crypt(b,s)\
+        _ossl_old_des_crypt((b),(s))
+#  if 0
+#   define crypt(b,s)\
+        _ossl_old_crypt((b),(s))
+#  endif
+#  define des_ofb_encrypt(i,o,n,l,k,iv)\
+        _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
+#  define des_pcbc_encrypt(i,o,l,k,iv,e)\
+        _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
+#  define des_quad_cksum(i,o,l,c,s)\
+        _ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
+#  define des_random_seed(k)\
+        _ossl_old_des_random_seed((k))
+#  define des_random_key(r)\
+        _ossl_old_des_random_key((r))
+#  define des_read_password(k,p,v) \
+        _ossl_old_des_read_password((k),(p),(v))
+#  define des_read_2passwords(k1,k2,p,v) \
+        _ossl_old_des_read_2passwords((k1),(k2),(p),(v))
+#  define des_set_odd_parity(k)\
+        _ossl_old_des_set_odd_parity((k))
+#  define des_is_weak_key(k)\
+        _ossl_old_des_is_weak_key((k))
+#  define des_set_key(k,ks)\
+        _ossl_old_des_set_key((k),(ks))
+#  define des_key_sched(k,ks)\
+        _ossl_old_des_key_sched((k),(ks))
+#  define des_string_to_key(s,k)\
+        _ossl_old_des_string_to_key((s),(k))
+#  define des_string_to_2keys(s,k1,k2)\
+        _ossl_old_des_string_to_2keys((s),(k1),(k2))
+#  define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+        _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
+#  define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+        _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))
+
+#  define des_ecb2_encrypt(i,o,k1,k2,e) \
+        des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#  define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+        des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#  define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#  define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+        des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#  define des_check_key DES_check_key
+#  define des_rw_mode DES_rw_mode
+# endif
+
+const char *_ossl_old_des_options(void);
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,
+                                _ossl_old_des_cblock *output,
+                                _ossl_old_des_key_schedule ks1,
+                                _ossl_old_des_key_schedule ks2,
+                                _ossl_old_des_key_schedule ks3, int enc);
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,
+                                 _ossl_old_des_cblock *output, long length,
+                                 _ossl_old_des_key_schedule schedule,
+                                 _ossl_old_des_cblock *ivec);
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,
+                               _ossl_old_des_cblock *output, long length,
+                               _ossl_old_des_key_schedule schedule,
+                               _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,
+                                _ossl_old_des_cblock *output, long length,
+                                _ossl_old_des_key_schedule schedule,
+                                _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,
+                                _ossl_old_des_cblock *output, long length,
+                                _ossl_old_des_key_schedule schedule,
+                                _ossl_old_des_cblock *ivec,
+                                _ossl_old_des_cblock *inw,
+                                _ossl_old_des_cblock *outw, int enc);
+void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out,
+                               int numbits, long length,
+                               _ossl_old_des_key_schedule schedule,
+                               _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,
+                               _ossl_old_des_cblock *output,
+                               _ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks,
+                           int enc);
+void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks,
+                            int enc);
+void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+                            _ossl_old_des_key_schedule ks2,
+                            _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+                            _ossl_old_des_key_schedule ks2,
+                            _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input,
+                                    _ossl_old_des_cblock *output, long length,
+                                    _ossl_old_des_key_schedule ks1,
+                                    _ossl_old_des_key_schedule ks2,
+                                    _ossl_old_des_key_schedule ks3,
+                                    _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+                                      long length,
+                                      _ossl_old_des_key_schedule ks1,
+                                      _ossl_old_des_key_schedule ks2,
+                                      _ossl_old_des_key_schedule ks3,
+                                      _ossl_old_des_cblock *ivec, int *num,
+                                      int enc);
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+                                      long length,
+                                      _ossl_old_des_key_schedule ks1,
+                                      _ossl_old_des_key_schedule ks2,
+                                      _ossl_old_des_key_schedule ks3,
+                                      _ossl_old_des_cblock *ivec, int *num);
+# if 0
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key),
+                                 _ossl_old_des_cblock (*in_white),
+                                 _ossl_old_des_cblock (*out_white));
+# endif
+
+int _ossl_old_des_enc_read(int fd, char *buf, int len,
+                           _ossl_old_des_key_schedule sched,
+                           _ossl_old_des_cblock *iv);
+int _ossl_old_des_enc_write(int fd, char *buf, int len,
+                            _ossl_old_des_key_schedule sched,
+                            _ossl_old_des_cblock *iv);
+char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret);
+char *_ossl_old_des_crypt(const char *buf, const char *salt);
+# if !defined(PERL5) && !defined(NeXT)
+char *_ossl_old_crypt(const char *buf, const char *salt);
+# endif
+void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out,
+                               int numbits, long length,
+                               _ossl_old_des_key_schedule schedule,
+                               _ossl_old_des_cblock *ivec);
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,
+                                _ossl_old_des_cblock *output, long length,
+                                _ossl_old_des_key_schedule schedule,
+                                _ossl_old_des_cblock *ivec, int 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);
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt,
+                                int verify);
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,
+                                  _ossl_old_des_cblock *key2,
+                                  const char *prompt, int verify);
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,
+                          _ossl_old_des_key_schedule schedule);
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,
+                            _ossl_old_des_key_schedule schedule);
+void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key);
+void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1,
+                                   _ossl_old_des_cblock *key2);
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out,
+                                 long length,
+                                 _ossl_old_des_key_schedule schedule,
+                                 _ossl_old_des_cblock *ivec, int *num,
+                                 int enc);
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out,
+                                 long length,
+                                 _ossl_old_des_key_schedule schedule,
+                                 _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_096_des_random_seed(des_cblock *key);
+
+/*
+ * The following definitions provide compatibility with the MIT Kerberos
+ * library. The _ossl_old_des_key_schedule structure is not binary
+ * compatible.
+ */
+
+# define _KERBEROS_DES_H
+
+# define KRBDES_ENCRYPT DES_ENCRYPT
+# define KRBDES_DECRYPT DES_DECRYPT
+
+# ifdef KERBEROS
+#  define ENCRYPT DES_ENCRYPT
+#  define DECRYPT DES_DECRYPT
+# endif
+
+# ifndef NCOMPAT
+#  define C_Block des_cblock
+#  define Key_schedule des_key_schedule
+#  define KEY_SZ DES_KEY_SZ
+#  define string_to_key des_string_to_key
+#  define read_pw_string des_read_pw_string
+#  define random_key des_random_key
+#  define pcbc_encrypt des_pcbc_encrypt
+#  define set_key des_set_key
+#  define key_sched des_key_sched
+#  define ecb_encrypt des_ecb_encrypt
+#  define cbc_encrypt des_cbc_encrypt
+#  define ncbc_encrypt des_ncbc_encrypt
+#  define xcbc_encrypt des_xcbc_encrypt
+#  define cbc_cksum des_cbc_cksum
+#  define quad_cksum des_quad_cksum
+#  define check_parity des_check_key_parity
+# endif
+
+# define des_fixup_key_parity DES_fixup_key_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* for DES_read_pw_string et al */
+# include <openssl/ui_compat.h>
+
+#endif
diff --git a/Cryptlib/Include/openssl/dh.h b/Cryptlib/Include/openssl/dh.h
new file mode 100644 (file)
index 0000000..6488879
--- /dev/null
@@ -0,0 +1,397 @@
+/* crypto/dh/dh.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_DH_H
+# define HEADER_DH_H
+
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_DH
+#  error DH is disabled.
+# endif
+
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+# ifndef OPENSSL_DH_MAX_MODULUS_BITS
+#  define OPENSSL_DH_MAX_MODULUS_BITS    10000
+# endif
+
+# define DH_FLAG_CACHE_MONT_P     0x01
+
+/*
+ * new with 0.9.7h; the built-in DH
+ * implementation now uses constant time
+ * modular exponentiation for secret exponents
+ * by default. This flag causes the
+ * faster variable sliding window method to
+ * be used for all exponents.
+ */
+# define DH_FLAG_NO_EXP_CONSTTIME 0x02
+
+/*
+ * If this flag is set the DH method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its reposibility to ensure the
+ * result is compliant.
+ */
+
+# define DH_FLAG_FIPS_METHOD                     0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DH_FLAG_NON_FIPS_ALLOW                  0x0400
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+struct dh_method {
+    const char *name;
+    /* Methods here */
+    int (*generate_key) (DH *dh);
+    int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+    /* Can be null */
+    int (*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);
+    int (*init) (DH *dh);
+    int (*finish) (DH *dh);
+    int flags;
+    char *app_data;
+    /* If this is non-NULL, it will be used to generate parameters */
+    int (*generate_params) (DH *dh, int prime_len, int generator,
+                            BN_GENCB *cb);
+};
+
+struct dh_st {
+    /*
+     * This first argument is used to pick up errors when a DH is passed
+     * instead of a EVP_PKEY
+     */
+    int pad;
+    int version;
+    BIGNUM *p;
+    BIGNUM *g;
+    long length;                /* optional */
+    BIGNUM *pub_key;            /* g^x % p */
+    BIGNUM *priv_key;           /* x */
+    int flags;
+    BN_MONT_CTX *method_mont_p;
+    /* Place holders if we want to do X9.42 DH */
+    BIGNUM *q;
+    BIGNUM *j;
+    unsigned char *seed;
+    int seedlen;
+    BIGNUM *counter;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    const DH_METHOD *meth;
+    ENGINE *engine;
+};
+
+# define DH_GENERATOR_2          2
+/* #define DH_GENERATOR_3       3 */
+# define DH_GENERATOR_5          5
+
+/* DH_check error codes */
+# define DH_CHECK_P_NOT_PRIME            0x01
+# define DH_CHECK_P_NOT_SAFE_PRIME       0x02
+# define DH_UNABLE_TO_CHECK_GENERATOR    0x04
+# define DH_NOT_SUITABLE_GENERATOR       0x08
+# define DH_CHECK_Q_NOT_PRIME            0x10
+# define DH_CHECK_INVALID_Q_VALUE        0x20
+# define DH_CHECK_INVALID_J_VALUE        0x40
+
+/* DH_check_pub_key error codes */
+# define DH_CHECK_PUBKEY_TOO_SMALL       0x01
+# define DH_CHECK_PUBKEY_TOO_LARGE       0x02
+# define DH_CHECK_PUBKEY_INVALID         0x04
+
+/*
+ * primes p where (p-1)/2 is prime too are called "safe"; we define this for
+ * backward compatibility:
+ */
+# define DH_CHECK_P_NOT_STRONG_PRIME     DH_CHECK_P_NOT_SAFE_PRIME
+
+# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+                (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+                (unsigned char *)(x))
+# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+DH *DHparams_dup(DH *);
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *DH_new(void);
+void DH_free(DH *dh);
+int DH_up_ref(DH *dh);
+int DH_size(const DH *dh);
+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);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+# ifndef OPENSSL_NO_DEPRECATED
+DH *DH_generate_parameters(int prime_len, int generator,
+                           void (*callback) (int, int, void *), void *cb_arg);
+# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
+                              BN_GENCB *cb);
+
+int DH_check(const DH *dh, int *codes);
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
+int DH_generate_key(DH *dh);
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHparams(const DH *a, unsigned char **pp);
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHxparams(const DH *a, unsigned char **pp);
+# ifndef OPENSSL_NO_FP_API
+int DHparams_print_fp(FILE *fp, const DH *x);
+# endif
+# ifndef OPENSSL_NO_BIO
+int DHparams_print(BIO *bp, const DH *x);
+# else
+int DHparams_print(char *bp, const DH *x);
+# endif
+
+/* RFC 5114 parameters */
+DH *DH_get_1024_160(void);
+DH *DH_get_2048_224(void);
+DH *DH_get_2048_256(void);
+
+# ifndef OPENSSL_NO_CMS
+/* RFC2631 KDF */
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md);
+# endif
+
+# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid)
+
+# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p)
+
+# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN     (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR     (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DH_RFC5114                (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN  (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE          (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_DH_KDF_TYPE               (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_DH_KDF_MD                 (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_DH_KDF_MD             (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_DH_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN         (EVP_PKEY_ALG_CTRL + 10)
+# define EVP_PKEY_CTRL_DH_KDF_UKM                (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_DH_KDF_UKM            (EVP_PKEY_ALG_CTRL + 12)
+# define EVP_PKEY_CTRL_DH_KDF_OID                (EVP_PKEY_ALG_CTRL + 13)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OID            (EVP_PKEY_ALG_CTRL + 14)
+
+/* KDF types */
+# define EVP_PKEY_DH_KDF_NONE                            1
+# ifndef OPENSSL_NO_CMS
+# define EVP_PKEY_DH_KDF_X9_42                           2
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+# define DH_F_COMPUTE_KEY                                 102
+# define DH_F_DHPARAMS_PRINT_FP                           101
+# define DH_F_DH_BUILTIN_GENPARAMS                        106
+# define DH_F_DH_CMS_DECRYPT                              117
+# define DH_F_DH_CMS_SET_PEERKEY                          118
+# define DH_F_DH_CMS_SET_SHARED_INFO                      119
+# define DH_F_DH_COMPUTE_KEY                              114
+# define DH_F_DH_GENERATE_KEY                             115
+# define DH_F_DH_GENERATE_PARAMETERS_EX                   116
+# define DH_F_DH_NEW_METHOD                               105
+# define DH_F_DH_PARAM_DECODE                             107
+# define DH_F_DH_PRIV_DECODE                              110
+# define DH_F_DH_PRIV_ENCODE                              111
+# define DH_F_DH_PUB_DECODE                               108
+# define DH_F_DH_PUB_ENCODE                               109
+# define DH_F_DO_DH_PRINT                                 100
+# define DH_F_GENERATE_KEY                                103
+# define DH_F_GENERATE_PARAMETERS                         104
+# define DH_F_PKEY_DH_DERIVE                              112
+# define DH_F_PKEY_DH_KEYGEN                              113
+
+/* Reason codes. */
+# define DH_R_BAD_GENERATOR                               101
+# define DH_R_BN_DECODE_ERROR                             109
+# define DH_R_BN_ERROR                                    106
+# define DH_R_DECODE_ERROR                                104
+# define DH_R_INVALID_PUBKEY                              102
+# define DH_R_KDF_PARAMETER_ERROR                         112
+# define DH_R_KEYS_NOT_SET                                108
+# define DH_R_KEY_SIZE_TOO_SMALL                          110
+# define DH_R_MODULUS_TOO_LARGE                           103
+# define DH_R_NON_FIPS_METHOD                             111
+# define DH_R_NO_PARAMETERS_SET                           107
+# define DH_R_NO_PRIVATE_VALUE                            100
+# define DH_R_PARAMETER_ENCODING_ERROR                    105
+# define DH_R_PEER_KEY_ERROR                              113
+# define DH_R_SHARED_INFO_ERROR                           114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/dsa.h b/Cryptlib/Include/openssl/dsa.h
new file mode 100644 (file)
index 0000000..545358f
--- /dev/null
@@ -0,0 +1,332 @@
+/* crypto/dsa/dsa.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.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+# define HEADER_DSA_H
+
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_DSA
+#  error DSA is disabled.
+# endif
+
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/crypto.h>
+# include <openssl/ossl_typ.h>
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+#  ifndef OPENSSL_NO_DH
+#   include <openssl/dh.h>
+#  endif
+# endif
+
+# ifndef OPENSSL_DSA_MAX_MODULUS_BITS
+#  define OPENSSL_DSA_MAX_MODULUS_BITS   10000
+# endif
+
+# define DSA_FLAG_CACHE_MONT_P   0x01
+/*
+ * new with 0.9.7h; the built-in DSA implementation now uses constant time
+ * modular exponentiation for secret exponents by default. This flag causes
+ * the faster variable sliding window method to be used for all exponents.
+ */
+# define DSA_FLAG_NO_EXP_CONSTTIME       0x02
+
+/*
+ * If this flag is set the DSA method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its reposibility to ensure the
+ * result is compliant.
+ */
+
+# define DSA_FLAG_FIPS_METHOD                    0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DSA_FLAG_NON_FIPS_ALLOW                 0x0400
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dsa_st DSA; */
+/* typedef struct dsa_method DSA_METHOD; */
+
+typedef struct DSA_SIG_st {
+    BIGNUM *r;
+    BIGNUM *s;
+} DSA_SIG;
+
+struct dsa_method {
+    const char *name;
+    DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa);
+    int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                           BIGNUM **rp);
+    int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len,
+                          DSA_SIG *sig, DSA *dsa);
+    int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+                        BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+                        BN_MONT_CTX *in_mont);
+    /* Can be null */
+    int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+    int (*init) (DSA *dsa);
+    int (*finish) (DSA *dsa);
+    int flags;
+    char *app_data;
+    /* If this is non-NULL, it is used to generate DSA parameters */
+    int (*dsa_paramgen) (DSA *dsa, int bits,
+                         const unsigned char *seed, int seed_len,
+                         int *counter_ret, unsigned long *h_ret,
+                         BN_GENCB *cb);
+    /* If this is non-NULL, it is used to generate DSA keys */
+    int (*dsa_keygen) (DSA *dsa);
+};
+
+struct dsa_st {
+    /*
+     * This first variable is used to pick up errors where a DSA is passed
+     * instead of of a EVP_PKEY
+     */
+    int pad;
+    long version;
+    int write_params;
+    BIGNUM *p;
+    BIGNUM *q;                  /* == 20 */
+    BIGNUM *g;
+    BIGNUM *pub_key;            /* y public key */
+    BIGNUM *priv_key;           /* x private key */
+    BIGNUM *kinv;               /* Signing pre-calc */
+    BIGNUM *r;                  /* Signing pre-calc */
+    int flags;
+    /* Normally used to cache montgomery values */
+    BN_MONT_CTX *method_mont_p;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    const DSA_METHOD *meth;
+    /* functional reference if 'meth' is ENGINE-provided */
+    ENGINE *engine;
+};
+
+# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+                (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+                (unsigned char *)(x))
+# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
+# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+
+DSA *DSAparams_dup(DSA *x);
+DSA_SIG *DSA_SIG_new(void);
+void DSA_SIG_free(DSA_SIG *a);
+int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+
+DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+int DSA_do_verify(const unsigned char *dgst, int dgst_len,
+                  DSA_SIG *sig, DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+int DSA_set_method(DSA *dsa, const DSA_METHOD *);
+
+DSA *DSA_new(void);
+DSA *DSA_new_method(ENGINE *engine);
+void DSA_free(DSA *r);
+/* "up" the DSA object's reference count */
+int DSA_up_ref(DSA *r);
+int DSA_size(const DSA *);
+        /* next 4 return -1 on error */
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+int DSA_sign(int type, const unsigned char *dgst, int dlen,
+             unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+               const unsigned char *sigbuf, int siglen, DSA *dsa);
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+/* Deprecated version */
+# ifndef OPENSSL_NO_DEPRECATED
+DSA *DSA_generate_parameters(int bits,
+                             unsigned char *seed, int seed_len,
+                             int *counter_ret, unsigned long *h_ret, void
+                              (*callback) (int, int, void *), void *cb_arg);
+# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int DSA_generate_parameters_ex(DSA *dsa, int bits,
+                               const unsigned char *seed, int seed_len,
+                               int *counter_ret, unsigned long *h_ret,
+                               BN_GENCB *cb);
+
+int DSA_generate_key(DSA *a);
+int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int i2d_DSAparams(const DSA *a, unsigned char **pp);
+
+# ifndef OPENSSL_NO_BIO
+int DSAparams_print(BIO *bp, const DSA *x);
+int DSA_print(BIO *bp, const DSA *x, int off);
+# endif
+# ifndef OPENSSL_NO_FP_API
+int DSAparams_print_fp(FILE *fp, const DSA *x);
+int DSA_print_fp(FILE *bp, const DSA *x, int off);
+# endif
+
+# define DSS_prime_checks 50
+/*
+ * Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
+ * Rabin-Miller
+ */
+# define DSA_is_prime(n, callback, cb_arg) \
+        BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+# ifndef OPENSSL_NO_DH
+/*
+ * Convert DSA structure (key or just parameters) into DH structure (be
+ * careful to avoid small subgroup attacks when using this!)
+ */
+DH *DSA_dup_DH(const DSA *r);
+# endif
+
+# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
+                                EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
+
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS         (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS       (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD           (EVP_PKEY_ALG_CTRL + 3)
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSA_strings(void);
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+# define DSA_F_D2I_DSA_SIG                                110
+# define DSA_F_DO_DSA_PRINT                               104
+# define DSA_F_DSAPARAMS_PRINT                            100
+# define DSA_F_DSAPARAMS_PRINT_FP                         101
+# define DSA_F_DSA_BUILTIN_PARAMGEN2                      126
+# define DSA_F_DSA_DO_SIGN                                112
+# define DSA_F_DSA_DO_VERIFY                              113
+# define DSA_F_DSA_GENERATE_KEY                           124
+# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 123
+# define DSA_F_DSA_NEW_METHOD                             103
+# define DSA_F_DSA_PARAM_DECODE                           119
+# define DSA_F_DSA_PRINT_FP                               105
+# define DSA_F_DSA_PRIV_DECODE                            115
+# define DSA_F_DSA_PRIV_ENCODE                            116
+# define DSA_F_DSA_PUB_DECODE                             117
+# define DSA_F_DSA_PUB_ENCODE                             118
+# define DSA_F_DSA_SIGN                                   106
+# define DSA_F_DSA_SIGN_SETUP                             107
+# define DSA_F_DSA_SIG_NEW                                109
+# define DSA_F_DSA_SIG_PRINT                              125
+# define DSA_F_DSA_VERIFY                                 108
+# define DSA_F_I2D_DSA_SIG                                111
+# define DSA_F_OLD_DSA_PRIV_DECODE                        122
+# define DSA_F_PKEY_DSA_CTRL                              120
+# define DSA_F_PKEY_DSA_KEYGEN                            121
+# define DSA_F_SIG_CB                                     114
+
+/* Reason codes. */
+# define DSA_R_BAD_Q_VALUE                                102
+# define DSA_R_BN_DECODE_ERROR                            108
+# define DSA_R_BN_ERROR                                   109
+# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                100
+# define DSA_R_DECODE_ERROR                               104
+# define DSA_R_INVALID_DIGEST_TYPE                        106
+# define DSA_R_INVALID_PARAMETERS                         112
+# define DSA_R_MISSING_PARAMETERS                         101
+# define DSA_R_MODULUS_TOO_LARGE                          103
+# define DSA_R_NEED_NEW_SETUP_VALUES                      110
+# define DSA_R_NON_FIPS_DSA_METHOD                        111
+# define DSA_R_NO_PARAMETERS_SET                          107
+# define DSA_R_PARAMETER_ENCODING_ERROR                   105
+# define DSA_R_Q_NOT_PRIME                                113
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/dso.h b/Cryptlib/Include/openssl/dso.h
new file mode 100644 (file)
index 0000000..c9013f5
--- /dev/null
@@ -0,0 +1,451 @@
+/* dso.h */
+/*
+ * 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).
+ *
+ */
+
+#ifndef HEADER_DSO_H
+# define HEADER_DSO_H
+
+# include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These values are used as commands to DSO_ctrl() */
+# define DSO_CTRL_GET_FLAGS      1
+# define DSO_CTRL_SET_FLAGS      2
+# define DSO_CTRL_OR_FLAGS       3
+
+/*
+ * By default, DSO_load() will translate the provided filename into a form
+ * typical for the platform (more specifically the DSO_METHOD) using the
+ * dso_name_converter function of the method. Eg. win32 will transform "blah"
+ * into "blah.dll", and dlfcn will transform it into "libblah.so". The
+ * behaviour can be overriden by setting the name_converter callback in the
+ * DSO object (using DSO_set_name_converter()). This callback could even
+ * utilise the DSO_METHOD's converter too if it only wants to override
+ * behaviour for one or two possible DSO methods. However, the following flag
+ * can be set in a DSO to prevent *any* native name-translation at all - eg.
+ * if the caller has prompted the user for a path to a driver library so the
+ * filename should be interpreted as-is.
+ */
+# define DSO_FLAG_NO_NAME_TRANSLATION            0x01
+/*
+ * An extra flag to give if only the extension should be added as
+ * translation.  This is obviously only of importance on Unix and other
+ * operating systems where the translation also may prefix the name with
+ * something, like 'lib', and ignored everywhere else. This flag is also
+ * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time.
+ */
+# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY      0x02
+
+/*
+ * The following flag controls the translation of symbol names to upper case.
+ * This is currently only being implemented for OpenVMS.
+ */
+# define DSO_FLAG_UPCASE_SYMBOL                  0x10
+
+/*
+ * This flag loads the library with public symbols. Meaning: The exported
+ * symbols of this library are public to all libraries loaded after this
+ * library. At the moment only implemented in unix.
+ */
+# define DSO_FLAG_GLOBAL_SYMBOLS                 0x20
+
+typedef void (*DSO_FUNC_TYPE) (void);
+
+typedef struct dso_st DSO;
+
+/*
+ * The function prototype used for method functions (or caller-provided
+ * callbacks) that transform filenames. They are passed a DSO structure
+ * pointer (or NULL if they are to be used independantly of a DSO object) and
+ * a filename to transform. They should either return NULL (if there is an
+ * error condition) or a newly allocated string containing the transformed
+ * form that the caller will need to free with OPENSSL_free() when done.
+ */
+typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
+/*
+ * The function prototype used for method functions (or caller-provided
+ * callbacks) that merge two file specifications. They are passed a DSO
+ * structure pointer (or NULL if they are to be used independantly of a DSO
+ * object) and two file specifications to merge. They should either return
+ * NULL (if there is an error condition) or a newly allocated string
+ * containing the result of merging that the caller will need to free with
+ * OPENSSL_free() when done. Here, merging means that bits and pieces are
+ * taken from each of the file specifications and added together in whatever
+ * fashion that is sensible for the DSO method in question.  The only rule
+ * that really applies is that if the two specification contain pieces of the
+ * same type, the copy from the first string takes priority.  One could see
+ * it as the first specification is the one given by the user and the second
+ * being a bunch of defaults to add on if they're missing in the first.
+ */
+typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
+
+typedef struct dso_meth_st {
+    const char *name;
+    /*
+     * Loads a shared library, NB: new DSO_METHODs must ensure that a
+     * successful load populates the loaded_filename field, and likewise a
+     * successful unload OPENSSL_frees and NULLs it out.
+     */
+    int (*dso_load) (DSO *dso);
+    /* Unloads a shared library */
+    int (*dso_unload) (DSO *dso);
+    /* Binds a variable */
+    void *(*dso_bind_var) (DSO *dso, const char *symname);
+    /*
+     * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should
+     * be cast to the real function prototype by the caller. Platforms that
+     * don't have compatible representations for different prototypes (this
+     * is possible within ANSI C) are highly unlikely to have shared
+     * libraries at all, let alone a DSO_METHOD implemented for them.
+     */
+    DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname);
+/* I don't think this would actually be used in any circumstances. */
+# if 0
+    /* Unbinds a variable */
+    int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr);
+    /* Unbinds a function */
+    int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+# endif
+    /*
+     * The generic (yuck) "ctrl()" function. NB: Negative return values
+     * (rather than zero) indicate errors.
+     */
+    long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg);
+    /*
+     * The default DSO_METHOD-specific function for converting filenames to a
+     * canonical native form.
+     */
+    DSO_NAME_CONVERTER_FUNC dso_name_converter;
+    /*
+     * The default DSO_METHOD-specific function for converting filenames to a
+     * canonical native form.
+     */
+    DSO_MERGER_FUNC dso_merger;
+    /* [De]Initialisation handlers. */
+    int (*init) (DSO *dso);
+    int (*finish) (DSO *dso);
+    /* Return pathname of the module containing location */
+    int (*pathbyaddr) (void *addr, char *path, int sz);
+    /* Perform global symbol lookup, i.e. among *all* modules */
+    void *(*globallookup) (const char *symname);
+} DSO_METHOD;
+
+/**********************************************************************/
+/* The low-level handle type used to refer to a loaded shared library */
+
+struct dso_st {
+    DSO_METHOD *meth;
+    /*
+     * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use
+     * anything but will need to cache the filename for use in the dso_bind
+     * handler. All in all, let each method control its own destiny.
+     * "Handles" and such go in a STACK.
+     */
+    STACK_OF(void) *meth_data;
+    int references;
+    int flags;
+    /*
+     * For use by applications etc ... use this for your bits'n'pieces, don't
+     * touch meth_data!
+     */
+    CRYPTO_EX_DATA ex_data;
+    /*
+     * If this callback function pointer is set to non-NULL, then it will be
+     * used in DSO_load() in place of meth->dso_name_converter. NB: This
+     * should normally set using DSO_set_name_converter().
+     */
+    DSO_NAME_CONVERTER_FUNC name_converter;
+    /*
+     * If this callback function pointer is set to non-NULL, then it will be
+     * used in DSO_load() in place of meth->dso_merger. NB: This should
+     * normally set using DSO_set_merger().
+     */
+    DSO_MERGER_FUNC merger;
+    /*
+     * This is populated with (a copy of) the platform-independant filename
+     * used for this DSO.
+     */
+    char *filename;
+    /*
+     * This is populated with (a copy of) the translated filename by which
+     * the DSO was actually loaded. It is NULL iff the DSO is not currently
+     * loaded. NB: This is here because the filename translation process may
+     * involve a callback being invoked more than once not only to convert to
+     * a platform-specific form, but also to try different filenames in the
+     * process of trying to perform a load. As such, this variable can be
+     * used to indicate (a) whether this DSO structure corresponds to a
+     * loaded library or not, and (b) the filename with which it was actually
+     * loaded.
+     */
+    char *loaded_filename;
+};
+
+DSO *DSO_new(void);
+DSO *DSO_new_method(DSO_METHOD *method);
+int DSO_free(DSO *dso);
+int DSO_flags(DSO *dso);
+int DSO_up_ref(DSO *dso);
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
+
+/*
+ * This function sets the DSO's name_converter callback. If it is non-NULL,
+ * then it will be used instead of the associated DSO_METHOD's function. If
+ * oldcb is non-NULL then it is set to the function pointer value being
+ * replaced. Return value is non-zero for success.
+ */
+int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+                           DSO_NAME_CONVERTER_FUNC *oldcb);
+/*
+ * These functions can be used to get/set the platform-independant filename
+ * used for a DSO. NB: set will fail if the DSO is already loaded.
+ */
+const char *DSO_get_filename(DSO *dso);
+int DSO_set_filename(DSO *dso, const char *filename);
+/*
+ * This function will invoke the DSO's name_converter callback to translate a
+ * filename, or if the callback isn't set it will instead use the DSO_METHOD's
+ * converter. If "filename" is NULL, the "filename" in the DSO itself will be
+ * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
+ * simply duplicated. NB: This function is usually called from within a
+ * DSO_METHOD during the processing of a DSO_load() call, and is exposed so
+ * that caller-created DSO_METHODs can do the same thing. A non-NULL return
+ * value will need to be OPENSSL_free()'d.
+ */
+char *DSO_convert_filename(DSO *dso, const char *filename);
+/*
+ * This function will invoke the DSO's merger callback to merge two file
+ * specifications, or if the callback isn't set it will instead use the
+ * DSO_METHOD's merger.  A non-NULL return value will need to be
+ * OPENSSL_free()'d.
+ */
+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
+/*
+ * If the DSO is currently loaded, this returns the filename that it was
+ * loaded under, otherwise it returns NULL. So it is also useful as a test as
+ * to whether the DSO is currently loaded. NB: This will not necessarily
+ * return the same value as DSO_convert_filename(dso, dso->filename), because
+ * the DSO_METHOD's load function may have tried a variety of filenames (with
+ * and/or without the aid of the converters) before settling on the one it
+ * actually loaded.
+ */
+const char *DSO_get_loaded_filename(DSO *dso);
+
+void DSO_set_default_method(DSO_METHOD *meth);
+DSO_METHOD *DSO_get_default_method(void);
+DSO_METHOD *DSO_get_method(DSO *dso);
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
+
+/*
+ * The all-singing all-dancing load function, you normally pass NULL for the
+ * first and third parameters. Use DSO_up and DSO_free for subsequent
+ * reference count handling. Any flags passed in will be set in the
+ * constructed DSO after its init() function but before the load operation.
+ * If 'dso' is non-NULL, 'flags' is ignored.
+ */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
+
+/* This function binds to a variable inside a shared library. */
+void *DSO_bind_var(DSO *dso, const char *symname);
+
+/* This function binds to a function inside a shared library. */
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
+
+/*
+ * This method is the default, but will beg, borrow, or steal whatever method
+ * should be the default on any particular platform (including
+ * DSO_METH_null() if necessary).
+ */
+DSO_METHOD *DSO_METHOD_openssl(void);
+
+/*
+ * This method is defined for all platforms - if a platform has no DSO
+ * support then this will be the only method!
+ */
+DSO_METHOD *DSO_METHOD_null(void);
+
+/*
+ * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen,
+ * dlclose, dlsym, etc) will be used and incorporated into this method. If
+ * not, this method will return NULL.
+ */
+DSO_METHOD *DSO_METHOD_dlfcn(void);
+
+/*
+ * If DSO_DL is defined, the standard dl.h-style functions (shl_load,
+ * shl_unload, shl_findsym, etc) will be used and incorporated into this
+ * method. If not, this method will return NULL.
+ */
+DSO_METHOD *DSO_METHOD_dl(void);
+
+/* If WIN32 is defined, use DLLs. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_win32(void);
+
+/* If VMS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_vms(void);
+
+/*
+ * This function writes null-terminated pathname of DSO module containing
+ * 'addr' into 'sz' large caller-provided 'path' and returns the number of
+ * characters [including trailing zero] written to it. If 'sz' is 0 or
+ * negative, 'path' is ignored and required amount of charachers [including
+ * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero return value
+ * denotes error.
+ */
+int DSO_pathbyaddr(void *addr, char *path, int sz);
+
+/*
+ * This function should be used with caution! It looks up symbols in *all*
+ * loaded modules and if module gets unloaded by somebody else attempt to
+ * dereference the pointer is doomed to have fatal consequences. Primary
+ * usage for this function is to probe *core* system functionality, e.g.
+ * check if getnameinfo(3) is available at run-time without bothering about
+ * OS-specific details such as libc.so.versioning or where does it actually
+ * reside: in libc itself or libsocket.
+ */
+void *DSO_global_lookup(const char *name);
+
+/* If BeOS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_beos(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSO_strings(void);
+
+/* Error codes for the DSO functions. */
+
+/* Function codes. */
+# define DSO_F_BEOS_BIND_FUNC                             144
+# define DSO_F_BEOS_BIND_VAR                              145
+# define DSO_F_BEOS_LOAD                                  146
+# define DSO_F_BEOS_NAME_CONVERTER                        147
+# define DSO_F_BEOS_UNLOAD                                148
+# define DSO_F_DLFCN_BIND_FUNC                            100
+# define DSO_F_DLFCN_BIND_VAR                             101
+# define DSO_F_DLFCN_LOAD                                 102
+# define DSO_F_DLFCN_MERGER                               130
+# define DSO_F_DLFCN_NAME_CONVERTER                       123
+# define DSO_F_DLFCN_UNLOAD                               103
+# define DSO_F_DL_BIND_FUNC                               104
+# define DSO_F_DL_BIND_VAR                                105
+# define DSO_F_DL_LOAD                                    106
+# define DSO_F_DL_MERGER                                  131
+# define DSO_F_DL_NAME_CONVERTER                          124
+# define DSO_F_DL_UNLOAD                                  107
+# define DSO_F_DSO_BIND_FUNC                              108
+# define DSO_F_DSO_BIND_VAR                               109
+# define DSO_F_DSO_CONVERT_FILENAME                       126
+# define DSO_F_DSO_CTRL                                   110
+# define DSO_F_DSO_FREE                                   111
+# define DSO_F_DSO_GET_FILENAME                           127
+# define DSO_F_DSO_GET_LOADED_FILENAME                    128
+# define DSO_F_DSO_GLOBAL_LOOKUP                          139
+# define DSO_F_DSO_LOAD                                   112
+# define DSO_F_DSO_MERGE                                  132
+# define DSO_F_DSO_NEW_METHOD                             113
+# define DSO_F_DSO_PATHBYADDR                             140
+# define DSO_F_DSO_SET_FILENAME                           129
+# define DSO_F_DSO_SET_NAME_CONVERTER                     122
+# define DSO_F_DSO_UP_REF                                 114
+# define DSO_F_GLOBAL_LOOKUP_FUNC                         138
+# define DSO_F_PATHBYADDR                                 137
+# define DSO_F_VMS_BIND_SYM                               115
+# define DSO_F_VMS_LOAD                                   116
+# define DSO_F_VMS_MERGER                                 133
+# define DSO_F_VMS_UNLOAD                                 117
+# define DSO_F_WIN32_BIND_FUNC                            118
+# define DSO_F_WIN32_BIND_VAR                             119
+# define DSO_F_WIN32_GLOBALLOOKUP                         142
+# define DSO_F_WIN32_GLOBALLOOKUP_FUNC                    143
+# define DSO_F_WIN32_JOINER                               135
+# define DSO_F_WIN32_LOAD                                 120
+# define DSO_F_WIN32_MERGER                               134
+# define DSO_F_WIN32_NAME_CONVERTER                       125
+# define DSO_F_WIN32_PATHBYADDR                           141
+# define DSO_F_WIN32_SPLITTER                             136
+# define DSO_F_WIN32_UNLOAD                               121
+
+/* Reason codes. */
+# define DSO_R_CTRL_FAILED                                100
+# define DSO_R_DSO_ALREADY_LOADED                         110
+# define DSO_R_EMPTY_FILE_STRUCTURE                       113
+# define DSO_R_FAILURE                                    114
+# define DSO_R_FILENAME_TOO_BIG                           101
+# define DSO_R_FINISH_FAILED                              102
+# define DSO_R_INCORRECT_FILE_SYNTAX                      115
+# define DSO_R_LOAD_FAILED                                103
+# define DSO_R_NAME_TRANSLATION_FAILED                    109
+# define DSO_R_NO_FILENAME                                111
+# define DSO_R_NO_FILE_SPECIFICATION                      116
+# define DSO_R_NULL_HANDLE                                104
+# define DSO_R_SET_FILENAME_FAILED                        112
+# define DSO_R_STACK_ERROR                                105
+# define DSO_R_SYM_FAILURE                                106
+# define DSO_R_UNLOAD_FAILED                              107
+# define DSO_R_UNSUPPORTED                                108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/dtls1.h b/Cryptlib/Include/openssl/dtls1.h
new file mode 100644 (file)
index 0000000..30bbcf2
--- /dev/null
@@ -0,0 +1,272 @@
+/* ssl/dtls1.h */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DTLS1_H
+# define HEADER_DTLS1_H
+
+# include <openssl/buffer.h>
+# include <openssl/pqueue.h>
+# ifdef OPENSSL_SYS_VMS
+#  include <resource.h>
+#  include <sys/timeb.h>
+# endif
+# ifdef OPENSSL_SYS_WIN32
+/* Needed for struct timeval */
+#  include <winsock.h>
+# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
+#  include <sys/timeval.h>
+# else
+#  if defined(OPENSSL_SYS_VXWORKS)
+#   include <sys/times.h>
+#  else
+#   include <sys/time.h>
+#  endif
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define DTLS1_VERSION                   0xFEFF
+# define DTLS1_2_VERSION                 0xFEFD
+# define DTLS_MAX_VERSION                DTLS1_2_VERSION
+# define DTLS1_VERSION_MAJOR             0xFE
+
+# define DTLS1_BAD_VER                   0x0100
+
+/* Special value for method supporting multiple versions */
+# define DTLS_ANY_VERSION                0x1FFFF
+
+# if 0
+/* this alert description is not specified anywhere... */
+#  define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+# endif
+
+/* lengths of messages */
+# define DTLS1_COOKIE_LENGTH                     256
+
+# define DTLS1_RT_HEADER_LENGTH                  13
+
+# define DTLS1_HM_HEADER_LENGTH                  12
+
+# define DTLS1_HM_BAD_FRAGMENT                   -2
+# define DTLS1_HM_FRAGMENT_RETRY                 -3
+
+# define DTLS1_CCS_HEADER_LENGTH                  1
+
+# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#  define DTLS1_AL_HEADER_LENGTH                   7
+# else
+#  define DTLS1_AL_HEADER_LENGTH                   2
+# endif
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+#  ifndef OPENSSL_NO_SCTP
+#   define DTLS1_SCTP_AUTH_LABEL   "EXPORTER_DTLS_OVER_SCTP"
+#  endif
+
+/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
+#  define DTLS1_MAX_MTU_OVERHEAD                   48
+
+typedef struct dtls1_bitmap_st {
+    unsigned long map;          /* track 32 packets on 32-bit systems and 64
+                                 * - on 64-bit systems */
+    unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit
+                                   * value in big-endian encoding */
+} DTLS1_BITMAP;
+
+struct dtls1_retransmit_state {
+    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+    EVP_MD_CTX *write_hash;     /* used for mac generation */
+#  ifndef OPENSSL_NO_COMP
+    COMP_CTX *compress;         /* compression */
+#  else
+    char *compress;
+#  endif
+    SSL_SESSION *session;
+    unsigned short epoch;
+};
+
+struct hm_header_st {
+    unsigned char type;
+    unsigned long msg_len;
+    unsigned short seq;
+    unsigned long frag_off;
+    unsigned long frag_len;
+    unsigned int is_ccs;
+    struct dtls1_retransmit_state saved_retransmit_state;
+};
+
+struct ccs_header_st {
+    unsigned char type;
+    unsigned short seq;
+};
+
+struct dtls1_timeout_st {
+    /* Number of read timeouts so far */
+    unsigned int read_timeouts;
+    /* Number of write timeouts so far */
+    unsigned int write_timeouts;
+    /* Number of alerts received so far */
+    unsigned int num_alerts;
+};
+
+typedef struct record_pqueue_st {
+    unsigned short epoch;
+    pqueue q;
+} record_pqueue;
+
+typedef struct hm_fragment_st {
+    struct hm_header_st msg_header;
+    unsigned char *fragment;
+    unsigned char *reassembly;
+} hm_fragment;
+
+typedef struct dtls1_state_st {
+    unsigned int send_cookie;
+    unsigned char cookie[DTLS1_COOKIE_LENGTH];
+    unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
+    unsigned int cookie_len;
+    /*
+     * The current data and handshake epoch.  This is initially
+     * undefined, and starts at zero once the initial handshake is
+     * completed
+     */
+    unsigned short r_epoch;
+    unsigned short w_epoch;
+    /* records being received in the current epoch */
+    DTLS1_BITMAP bitmap;
+    /* renegotiation starts a new set of sequence numbers */
+    DTLS1_BITMAP next_bitmap;
+    /* handshake message numbers */
+    unsigned short handshake_write_seq;
+    unsigned short next_handshake_write_seq;
+    unsigned short handshake_read_seq;
+    /* save last sequence number for retransmissions */
+    unsigned char last_write_sequence[8];
+    /* Received handshake records (processed and unprocessed) */
+    record_pqueue unprocessed_rcds;
+    record_pqueue processed_rcds;
+    /* Buffered handshake messages */
+    pqueue buffered_messages;
+    /* Buffered (sent) handshake records */
+    pqueue sent_messages;
+    /*
+     * Buffered application records. Only for records between CCS and
+     * Finished to prevent either protocol violation or unnecessary message
+     * loss.
+     */
+    record_pqueue buffered_app_data;
+    /* Is set when listening for new connections with dtls1_listen() */
+    unsigned int listen;
+    unsigned int link_mtu;      /* max on-the-wire DTLS packet size */
+    unsigned int mtu;           /* max DTLS packet size */
+    struct hm_header_st w_msg_hdr;
+    struct hm_header_st r_msg_hdr;
+    struct dtls1_timeout_st timeout;
+    /*
+     * Indicates when the last handshake msg or heartbeat sent will timeout
+     */
+    struct timeval next_timeout;
+    /* Timeout duration */
+    unsigned short timeout_duration;
+    /*
+     * storage for Alert/Handshake protocol data received but not yet
+     * processed by ssl3_read_bytes:
+     */
+    unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+    unsigned int alert_fragment_len;
+    unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+    unsigned int handshake_fragment_len;
+    unsigned int retransmitting;
+    /*
+     * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+     * Cleared after the message has been processed.
+     */
+    unsigned int change_cipher_spec_ok;
+#  ifndef OPENSSL_NO_SCTP
+    /* used when SSL_ST_XX_FLUSH is entered */
+    int next_state;
+    int shutdown_received;
+#  endif
+} DTLS1_STATE;
+
+typedef struct dtls1_record_data_st {
+    unsigned char *packet;
+    unsigned int packet_length;
+    SSL3_BUFFER rbuf;
+    SSL3_RECORD rrec;
+#  ifndef OPENSSL_NO_SCTP
+    struct bio_dgram_sctp_rcvinfo recordinfo;
+#  endif
+} DTLS1_RECORD_DATA;
+
+# endif
+
+/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
+# define DTLS1_TMO_READ_COUNT                      2
+# define DTLS1_TMO_WRITE_COUNT                     2
+
+# define DTLS1_TMO_ALERT_COUNT                     12
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/e_os2.h b/Cryptlib/Include/openssl/e_os2.h
new file mode 100644 (file)
index 0000000..909e22f
--- /dev/null
@@ -0,0 +1,335 @@
+/* e_os2.h */
+/* ====================================================================
+ * 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/opensslconf.h>
+
+#ifndef HEADER_E_OS2_H
+# define HEADER_E_OS2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems.  This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+# define OPENSSL_SYS_UNIX
+
+/* ---------------------- Macintosh, before MacOS X ----------------------- */
+# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_MACINTOSH_CLASSIC
+# endif
+
+/* ---------------------- NetWare ----------------------------------------- */
+# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_NETWARE
+# endif
+
+/* --------------------- Microsoft operating systems ---------------------- */
+
+/*
+ * Note that MSDOS actually denotes 32-bit environments running on top of
+ * MS-DOS, such as DJGPP one.
+ */
+# if defined(OPENSSL_SYSNAME_MSDOS)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_MSDOS
+# endif
+
+/*
+ * For 32 bit environment, there seems to be the CygWin environment and then
+ * all the others that try to do the same thing Microsoft does...
+ */
+/*
+ * UEFI lives here because it might be built with a Microsoft toolchain and
+ * we need to avoid the false positive match on Windows.
+ */
+# if defined(OPENSSL_SYSNAME_UEFI)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_UEFI
+# elif defined(OPENSSL_SYSNAME_UWIN)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WIN32_UWIN
+# else
+#  if defined(__CYGWIN__) || defined(OPENSSL_SYSNAME_CYGWIN)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WIN32_CYGWIN
+#  else
+#   if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
+#    undef OPENSSL_SYS_UNIX
+#    define OPENSSL_SYS_WIN32
+#   endif
+#   if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64)
+#    undef OPENSSL_SYS_UNIX
+#    if !defined(OPENSSL_SYS_WIN64)
+#     define OPENSSL_SYS_WIN64
+#    endif
+#   endif
+#   if defined(OPENSSL_SYSNAME_WINNT)
+#    undef OPENSSL_SYS_UNIX
+#    define OPENSSL_SYS_WINNT
+#   endif
+#   if defined(OPENSSL_SYSNAME_WINCE)
+#    undef OPENSSL_SYS_UNIX
+#    define OPENSSL_SYS_WINCE
+#   endif
+#  endif
+# endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WINDOWS
+#  ifndef OPENSSL_SYS_MSDOS
+#   define OPENSSL_SYS_MSDOS
+#  endif
+# endif
+
+/*
+ * DLL settings.  This part is a bit tough, because it's up to the
+ * application implementor how he or she will link the application, so it
+ * requires some macro to be used.
+ */
+# ifdef OPENSSL_SYS_WINDOWS
+#  ifndef OPENSSL_OPT_WINDLL
+#   if defined(_WINDLL)         /* This is used when building OpenSSL to
+                                 * indicate that DLL linkage should be used */
+#    define OPENSSL_OPT_WINDLL
+#   endif
+#  endif
+# endif
+
+/* ------------------------------- OpenVMS -------------------------------- */
+# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_VMS
+#  if defined(__DECC)
+#   define OPENSSL_SYS_VMS_DECC
+#  elif defined(__DECCXX)
+#   define OPENSSL_SYS_VMS_DECC
+#   define OPENSSL_SYS_VMS_DECCXX
+#  else
+#   define OPENSSL_SYS_VMS_NODECC
+#  endif
+# endif
+
+/* -------------------------------- OS/2 ---------------------------------- */
+# if defined(__EMX__) || defined(__OS2__)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_OS2
+# endif
+
+/* -------------------------------- Unix ---------------------------------- */
+# ifdef OPENSSL_SYS_UNIX
+#  if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
+#   define OPENSSL_SYS_LINUX
+#  endif
+#  ifdef OPENSSL_SYSNAME_MPE
+#   define OPENSSL_SYS_MPE
+#  endif
+#  ifdef OPENSSL_SYSNAME_SNI
+#   define OPENSSL_SYS_SNI
+#  endif
+#  ifdef OPENSSL_SYSNAME_ULTRASPARC
+#   define OPENSSL_SYS_ULTRASPARC
+#  endif
+#  ifdef OPENSSL_SYSNAME_NEWS4
+#   define OPENSSL_SYS_NEWS4
+#  endif
+#  ifdef OPENSSL_SYSNAME_MACOSX
+#   define OPENSSL_SYS_MACOSX
+#  endif
+#  ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
+#   define OPENSSL_SYS_MACOSX_RHAPSODY
+#   define OPENSSL_SYS_MACOSX
+#  endif
+#  ifdef OPENSSL_SYSNAME_SUNOS
+#   define OPENSSL_SYS_SUNOS
+#  endif
+#  if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
+#   define OPENSSL_SYS_CRAY
+#  endif
+#  if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
+#   define OPENSSL_SYS_AIX
+#  endif
+# endif
+
+/* -------------------------------- VOS ----------------------------------- */
+# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
+#  define OPENSSL_SYS_VOS
+#  ifdef __HPPA__
+#   define OPENSSL_SYS_VOS_HPPA
+#  endif
+#  ifdef __IA32__
+#   define OPENSSL_SYS_VOS_IA32
+#  endif
+# endif
+
+/* ------------------------------ VxWorks --------------------------------- */
+# ifdef OPENSSL_SYSNAME_VXWORKS
+#  define OPENSSL_SYS_VXWORKS
+# endif
+
+/* -------------------------------- BeOS ---------------------------------- */
+# if defined(__BEOS__)
+#  define OPENSSL_SYS_BEOS
+#  include <sys/socket.h>
+#  if defined(BONE_VERSION)
+#   define OPENSSL_SYS_BEOS_BONE
+#  else
+#   define OPENSSL_SYS_BEOS_R5
+#  endif
+# endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+/* Specials for I/O an exit */
+# ifdef OPENSSL_SYS_MSDOS
+#  define OPENSSL_UNISTD_IO <io.h>
+#  define OPENSSL_DECLARE_EXIT extern void exit(int);
+# else
+#  define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+#  define OPENSSL_DECLARE_EXIT  /* declared in unistd.h */
+# endif
+
+/*-
+ * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+ * certain global symbols that, with some compilers under VMS, have to be
+ * defined and declared explicitely with globaldef and globalref.
+ * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+ * DLL exports and imports for compilers under Win32.  These are a little
+ * more complicated to use.  Basically, for any library that exports some
+ * global variables, the following code must be present in the header file
+ * that declares them, before OPENSSL_EXTERN is used:
+ *
+ * #ifdef SOME_BUILD_FLAG_MACRO
+ * # undef OPENSSL_EXTERN
+ * # define OPENSSL_EXTERN OPENSSL_EXPORT
+ * #endif
+ *
+ * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
+ * have some generally sensible values, and for OPENSSL_EXTERN to have the
+ * value OPENSSL_IMPORT.
+ */
+
+# if defined(OPENSSL_SYS_VMS_NODECC)
+#  define OPENSSL_EXPORT globalref
+#  define OPENSSL_IMPORT globalref
+#  define OPENSSL_GLOBAL globaldef
+# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+#  define OPENSSL_EXPORT extern __declspec(dllexport)
+#  define OPENSSL_IMPORT extern __declspec(dllimport)
+#  define OPENSSL_GLOBAL
+# else
+#  define OPENSSL_EXPORT extern
+#  define OPENSSL_IMPORT extern
+#  define OPENSSL_GLOBAL
+# endif
+# define OPENSSL_EXTERN OPENSSL_IMPORT
+
+/*-
+ * Macros to allow global variables to be reached through function calls when
+ * required (if a shared library version requires it, for example.
+ * The way it's done allows definitions like this:
+ *
+ *      // in foobar.c
+ *      OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
+ *      // in foobar.h
+ *      OPENSSL_DECLARE_GLOBAL(int,foobar);
+ *      #define foobar OPENSSL_GLOBAL_REF(foobar)
+ */
+# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)                      \
+        type *_shadow_##name(void)                                      \
+        { static type _hide_##name=value; return &_hide_##name; }
+#  define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+#  define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+# else
+#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
+#  define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+#  define OPENSSL_GLOBAL_REF(name) _shadow_##name
+# endif
+
+# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE)
+#  define ossl_ssize_t long
+# endif
+
+# ifdef OPENSSL_SYS_MSDOS
+#  define ossl_ssize_t long
+# endif
+
+# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
+#  define ssize_t int
+# endif
+
+# if defined(__ultrix) && !defined(ssize_t)
+#  define ossl_ssize_t int
+# endif
+
+# ifndef ossl_ssize_t
+#  define ossl_ssize_t ssize_t
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ebcdic.h b/Cryptlib/Include/openssl/ebcdic.h
new file mode 100644 (file)
index 0000000..4cbdfeb
--- /dev/null
@@ -0,0 +1,26 @@
+/* crypto/ebcdic.h */
+
+#ifndef HEADER_EBCDIC_H
+# define HEADER_EBCDIC_H
+
+# include <sys/types.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Avoid name clashes with other applications */
+# define os_toascii   _openssl_os_toascii
+# define os_toebcdic  _openssl_os_toebcdic
+# define ebcdic2ascii _openssl_ebcdic2ascii
+# define ascii2ebcdic _openssl_ascii2ebcdic
+
+extern const unsigned char os_toascii[256];
+extern const unsigned char os_toebcdic[256];
+void *ebcdic2ascii(void *dest, const void *srce, size_t count);
+void *ascii2ebcdic(void *dest, const void *srce, size_t count);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ec.h b/Cryptlib/Include/openssl/ec.h
new file mode 100644 (file)
index 0000000..81e6faf
--- /dev/null
@@ -0,0 +1,1282 @@
+/* crypto/ec/ec.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/**
+ * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
+ * \author Originally written by Bodo Moeller for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions 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 OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_EC_H
+# define HEADER_EC_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_EC
+#  error EC is disabled.
+# endif
+
+# include <openssl/asn1.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C" {
+# elif defined(__SUNPRO_C)
+#  if __SUNPRO_C >= 0x520
+#   pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#  endif
+# endif
+
+# ifndef OPENSSL_ECC_MAX_FIELD_BITS
+#  define OPENSSL_ECC_MAX_FIELD_BITS 661
+# endif
+
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ *  for the encoding of a elliptic curve point (x,y) */
+typedef enum {
+        /** the point is encoded as z||x, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
+    POINT_CONVERSION_COMPRESSED = 2,
+        /** the point is encoded as z||x||y, where z is the octet 0x04  */
+    POINT_CONVERSION_UNCOMPRESSED = 4,
+        /** the point is encoded as z||x||y, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
+    POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+typedef struct ec_method_st EC_METHOD;
+
+typedef struct ec_group_st
+    /*-
+     EC_METHOD *meth;
+     -- field definition
+     -- curve coefficients
+     -- optional generator with associated information (order, cofactor)
+     -- optional extra data (precomputed table for fast computation of multiples of generator)
+     -- ASN1 stuff
+    */
+    EC_GROUP;
+
+typedef struct ec_point_st EC_POINT;
+
+/********************************************************************/
+/*               EC_METHODs for curves over GF(p)                   */
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ *  optimized methods.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nist_method(void);
+
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/** Returns 64-bit optimized methods for nistp224
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp224_method(void);
+
+/** Returns 64-bit optimized methods for nistp256
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp256_method(void);
+
+/** Returns 64-bit optimized methods for nistp521
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp521_method(void);
+# endif
+
+# ifndef OPENSSL_NO_EC2M
+/********************************************************************/
+/*           EC_METHOD for curves over GF(2^m)                      */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+# endif
+
+/********************************************************************/
+/*                   EC_GROUP functions                             */
+/********************************************************************/
+
+/** Creates a new EC_GROUP object
+ *  \param   meth  EC_METHOD to use
+ *  \return  newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
+
+/** Frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
+
+/** Clears and frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
+
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ *  \param  dst  destination EC_GROUP object
+ *  \param  src  source EC_GROUP object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ *  form src to the newly created EC_KEY object
+ *  \param  src  source EC_GROUP object
+ *  \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ *  \param  meth  EC_METHOD object
+ *  \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ *  \param  group      EC_GROUP object
+ *  \param  generator  EC_POINT object with the generator.
+ *  \param  order      the order of the group generated by the generator.
+ *  \param  cofactor   the index of the sub-group generated by the generator
+ *                     in the group of all points on the elliptic curve.
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+                           const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Returns the montgomery data for order(Generator)
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+*/
+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \param  order  BIGNUM to which the order is copied
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the cofactor of a EC_GROUP
+ *  \param  group     EC_GROUP object
+ *  \param  cofactor  BIGNUM to which the cofactor is copied
+ *  \param  ctx       BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+                          BN_CTX *ctx);
+
+/** Sets the name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \param  nid    NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+                                        point_conversion_form_t form);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the prime number
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                           const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the prime number
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                           BIGNUM *b, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the polynomial defining the underlying field
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the polynomial defining the underlying field
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                            BIGNUM *b, BN_CTX *ctx);
+# endif
+/** Returns the number of bits needed to represent a field element
+ *  \param  group  EC_GROUP object
+ *  \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if group is a valid ec group and 0 otherwise
+ */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ *  \param  a    first EC_GROUP object
+ *  \param  b    second EC_GROUP object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 0 if both groups are equal and 1 otherwise
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
+
+/*
+ * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after
+ * choosing an appropriate EC_METHOD
+ */
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ *  \param  p    BIGNUM with the prime number
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+                                 const BIGNUM *b, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ *  \param  p    BIGNUM with the polynomial defining the underlying field
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
+                                  const BIGNUM *b, BN_CTX *ctx);
+# endif
+/** Creates a EC_GROUP object with a curve specified by a NID
+ *  \param  nid  NID of the OID of the curve name
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+
+/********************************************************************/
+/*               handling of internal curves                        */
+/********************************************************************/
+
+typedef struct {
+    int nid;
+    const char *comment;
+} EC_builtin_curve;
+
+/*
+ * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all
+ * available curves or zero if a error occurred. In case r ist not zero
+ * nitems EC_builtin_curve structures are filled with the data of the first
+ * nitems internal groups
+ */
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
+
+const char *EC_curve_nid2nist(int nid);
+int EC_curve_nist2nid(const char *name);
+
+/********************************************************************/
+/*                    EC_POINT functions                            */
+/********************************************************************/
+
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ *  \param  group  EC_GROUP the underlying EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ *  \param  point  EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ *  \param  point  EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ *  \param  dst  destination EC_POINT object
+ *  \param  src  source EC_POINT object
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ *  EC_POINT
+ *  \param  src    source EC_POINT object
+ *  \param  group  underlying the EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
+
+/** Returns the EC_METHOD used in EC_POINT object
+ *  \param  point  EC_POINT object
+ *  \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
+
+/** Sets a point to infinity (neutral element)
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT to set to infinity
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
+
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  z      BIGNUM with the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             EC_POINT *p, const BIGNUM *x,
+                                             const BIGNUM *y, const BIGNUM *z,
+                                             BN_CTX *ctx);
+
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  z      BIGNUM for the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             const EC_POINT *p, BIGNUM *x,
+                                             BIGNUM *y, BIGNUM *z,
+                                             BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+                                        const BIGNUM *x, const BIGNUM *y,
+                                        BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+                                        const EC_POINT *p, BIGNUM *x,
+                                        BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+                                            EC_POINT *p, const BIGNUM *x,
+                                            int y_bit, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+                                         const BIGNUM *x, const BIGNUM *y,
+                                         BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+                                         const EC_POINT *p, BIGNUM *x,
+                                         BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
+                                             EC_POINT *p, const BIGNUM *x,
+                                             int y_bit, BN_CTX *ctx);
+# endif
+/** Encodes a EC_POINT object to a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+                          point_conversion_form_t form,
+                          unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+                       const unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/* other interfaces to point2oct/oct2point: */
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
+                          point_conversion_form_t form, BIGNUM *, BN_CTX *);
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
+                            EC_POINT *, BN_CTX *);
+char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
+                         point_conversion_form_t form, BN_CTX *);
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
+                             EC_POINT *, BN_CTX *);
+
+/********************************************************************/
+/*         functions for doing EC_POINT arithmetic                  */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = a + b)
+ *  \param  a      EC_POINT object with the first summand
+ *  \param  b      EC_POINT object with the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = 2 * a)
+ *  \param  a      EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ *  \param  group  the underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object to check
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if point if on the curve and 0 otherwise
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+                         BN_CTX *ctx);
+
+/** Compares two EC_POINTs
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      first EC_POINT object
+ *  \param  b      second EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 0 if both points are equal and a value != 0 otherwise
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+                 BN_CTX *ctx);
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+                          EC_POINT *points[], BN_CTX *ctx);
+
+/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  num    number futher summands
+ *  \param  p      array of size num of EC_POINT objects
+ *  \param  m      array of size num of BIGNUM objects
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
+                  BN_CTX *ctx);
+
+/** Computes r = generator * n + q * m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  q      EC_POINT object with the first factor of the second summand
+ *  \param  m      BIGNUM with the second factor of the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+                 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
+
+/** Stores multiples of generator for faster point multiplication
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ *  \param  group  EC_GROUP object
+ *  \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
+
+/********************************************************************/
+/*                       ASN1 stuff                                 */
+/********************************************************************/
+
+/*
+ * EC_GROUP_get_basis_type() returns the NID of the basis type used to
+ * represent the field elements
+ */
+int EC_GROUP_get_basis_type(const EC_GROUP *);
+# ifndef OPENSSL_NO_EC2M
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
+                                   unsigned int *k2, unsigned int *k3);
+# endif
+
+# define OPENSSL_EC_NAMED_CURVE  0x001
+
+typedef struct ecpk_parameters_st ECPKPARAMETERS;
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
+int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
+
+# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
+                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
+# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
+                (unsigned char *)(x))
+
+# ifndef OPENSSL_NO_BIO
+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
+# endif
+# ifndef OPENSSL_NO_FP_API
+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
+# endif
+
+/********************************************************************/
+/*                      EC_KEY functions                            */
+/********************************************************************/
+
+typedef struct ec_key_st EC_KEY;
+
+/* some values for the encoding_flag */
+# define EC_PKEY_NO_PARAMETERS   0x001
+# define EC_PKEY_NO_PUBKEY       0x002
+
+/* some values for the flags field */
+# define EC_FLAG_NON_FIPS_ALLOW  0x1
+# define EC_FLAG_FIPS_CHECKED    0x2
+
+/** Creates a new EC_KEY object.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new(void);
+
+int EC_KEY_get_flags(const EC_KEY *key);
+
+void EC_KEY_set_flags(EC_KEY *key, int flags);
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ *  EC_GROUP object.
+ *  \param  nid  NID of the named curve.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+
+/** Frees a EC_KEY object.
+ *  \param  key  EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
+
+/** Copies a EC_KEY object.
+ *  \param  dst  destination EC_KEY object
+ *  \param  src  src EC_KEY object
+ *  \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ *  \param  src  the source EC_KEY object
+ *  \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ *  \param  key  EC_KEY object
+ *  \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ *  \param  key    EC_KEY object
+ *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ *                 object will use an own copy of the EC_GROUP).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
+ *               will use an own copy of the BIGNUM).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ *  \param  key  the EC_KEY object
+ *  \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
+ *               will use an own copy of the EC_POINT object).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
+/* functions to set/get method specific data  */
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+                                 void *(*dup_func) (void *),
+                                 void (*free_func) (void *),
+                                 void (*clear_free_func) (void *));
+/** Sets the key method data of an EC_KEY object, if none has yet been set.
+ *  \param  key              EC_KEY object
+ *  \param  data             opaque data to install.
+ *  \param  dup_func         a function that duplicates |data|.
+ *  \param  free_func        a function that frees |data|.
+ *  \param  clear_free_func  a function that wipes and frees |data|.
+ *  \return the previously set data pointer, or NULL if |data| was inserted.
+ */
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+                                    void *(*dup_func) (void *),
+                                    void (*free_func) (void *),
+                                    void (*clear_free_func) (void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
+
+/** Creates a table of pre-computed multiples of the generator to
+ *  accelerate further EC_KEY operations.
+ *  \param  key  EC_KEY object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+
+/** Creates a new ec private (and optional a new public) key.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ *  \param  key  the EC_KEY object
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+/** Sets a public key from affine coordindates performing
+ *  neccessary NIST PKV tests.
+ *  \param  key  the EC_KEY object
+ *  \param  x    public key x coordinate
+ *  \param  y    public key y coordinate
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
+                                             BIGNUM *y);
+
+/********************************************************************/
+/*        de- and encoding functions for SEC1 ECPrivateKey          */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded private key
+ *  \param  len  length of the DER encoded private key
+ *  \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ *  \param  key  the EC_KEY object to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/*        de- and encoding functions for EC parameters              */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded ec parameters
+ *  \param  len  length of the DER encoded ec parameters
+ *  \return a EC_KEY object with the decoded parameters or NULL if an error
+ *          occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ *  \param  key  the EC_KEY object with ec paramters to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/*         de- and encoding functions for EC public key             */
+/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ *  \param  key  a pointer to a EC_KEY object which should be used
+ *  \param  in   memory buffer with the encoded public key
+ *  \param  len  length of the encoded public key
+ *  \return EC_KEY object with decoded public key or NULL if an error
+ *          occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ *  \param  key  the EC_KEY object with the public key
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
+
+# ifndef OPENSSL_NO_BIO
+/** Prints out the ec parameters on human readable form.
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
+# endif
+# ifndef OPENSSL_NO_FP_API
+/** Prints out the ec parameters on human readable form.
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
+# endif
+
+# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+# ifndef __cplusplus
+#  if defined(__SUNPRO_C)
+#   if __SUNPRO_C >= 0x520
+#    pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#   endif
+#  endif
+# endif
+
+# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen)
+
+# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p)
+
+# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p)
+
+# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID             (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_EC_PARAM_ENC                      (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR                  (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_EC_KDF_TYPE                       (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_EC_KDF_MD                         (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_GET_EC_KDF_MD                     (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_EC_KDF_OUTLEN                     (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN                 (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_EC_KDF_UKM                        (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 10)
+/* KDF types */
+# define EVP_PKEY_ECDH_KDF_NONE                          1
+# define EVP_PKEY_ECDH_KDF_X9_62                         2
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+# define EC_F_BN_TO_FELEM                                 224
+# define EC_F_COMPUTE_WNAF                                143
+# define EC_F_D2I_ECPARAMETERS                            144
+# define EC_F_D2I_ECPKPARAMETERS                          145
+# define EC_F_D2I_ECPRIVATEKEY                            146
+# define EC_F_DO_EC_KEY_PRINT                             221
+# define EC_F_ECDH_CMS_DECRYPT                            238
+# define EC_F_ECDH_CMS_SET_SHARED_INFO                    239
+# define EC_F_ECKEY_PARAM2TYPE                            223
+# define EC_F_ECKEY_PARAM_DECODE                          212
+# define EC_F_ECKEY_PRIV_DECODE                           213
+# define EC_F_ECKEY_PRIV_ENCODE                           214
+# define EC_F_ECKEY_PUB_DECODE                            215
+# define EC_F_ECKEY_PUB_ENCODE                            216
+# define EC_F_ECKEY_TYPE2PARAM                            220
+# define EC_F_ECPARAMETERS_PRINT                          147
+# define EC_F_ECPARAMETERS_PRINT_FP                       148
+# define EC_F_ECPKPARAMETERS_PRINT                        149
+# define EC_F_ECPKPARAMETERS_PRINT_FP                     150
+# define EC_F_ECP_NISTZ256_GET_AFFINE                     240
+# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE                243
+# define EC_F_ECP_NISTZ256_POINTS_MUL                     241
+# define EC_F_ECP_NISTZ256_PRE_COMP_NEW                   244
+# define EC_F_ECP_NISTZ256_SET_WORDS                      245
+# define EC_F_ECP_NISTZ256_WINDOWED_MUL                   242
+# define EC_F_ECP_NIST_MOD_192                            203
+# define EC_F_ECP_NIST_MOD_224                            204
+# define EC_F_ECP_NIST_MOD_256                            205
+# define EC_F_ECP_NIST_MOD_521                            206
+# define EC_F_EC_ASN1_GROUP2CURVE                         153
+# define EC_F_EC_ASN1_GROUP2FIELDID                       154
+# define EC_F_EC_ASN1_GROUP2PARAMETERS                    155
+# define EC_F_EC_ASN1_GROUP2PKPARAMETERS                  156
+# define EC_F_EC_ASN1_PARAMETERS2GROUP                    157
+# define EC_F_EC_ASN1_PKPARAMETERS2GROUP                  158
+# define EC_F_EC_EX_DATA_SET_DATA                         211
+# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY           208
+# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT     159
+# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE              195
+# define EC_F_EC_GF2M_SIMPLE_OCT2POINT                    160
+# define EC_F_EC_GF2M_SIMPLE_POINT2OCT                    161
+# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
+# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
+# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES   164
+# define EC_F_EC_GFP_MONT_FIELD_DECODE                    133
+# define EC_F_EC_GFP_MONT_FIELD_ENCODE                    134
+# define EC_F_EC_GFP_MONT_FIELD_MUL                       131
+# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE                209
+# define EC_F_EC_GFP_MONT_FIELD_SQR                       132
+# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE                 189
+# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP             135
+# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE             225
+# define EC_F_EC_GFP_NISTP224_POINTS_MUL                  228
+# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
+# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE             230
+# define EC_F_EC_GFP_NISTP256_POINTS_MUL                  231
+# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
+# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE             233
+# define EC_F_EC_GFP_NISTP521_POINTS_MUL                  234
+# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
+# define EC_F_EC_GFP_NIST_FIELD_MUL                       200
+# define EC_F_EC_GFP_NIST_FIELD_SQR                       201
+# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE                 202
+# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT      165
+# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE               166
+# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP           100
+# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR           101
+# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                   102
+# define EC_F_EC_GFP_SIMPLE_OCT2POINT                     103
+# define EC_F_EC_GFP_SIMPLE_POINT2OCT                     104
+# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE            137
+# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES  167
+# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
+# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES  168
+# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
+# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES    169
+# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+# define EC_F_EC_GROUP_CHECK                              170
+# define EC_F_EC_GROUP_CHECK_DISCRIMINANT                 171
+# define EC_F_EC_GROUP_COPY                               106
+# define EC_F_EC_GROUP_GET0_GENERATOR                     139
+# define EC_F_EC_GROUP_GET_COFACTOR                       140
+# define EC_F_EC_GROUP_GET_CURVE_GF2M                     172
+# define EC_F_EC_GROUP_GET_CURVE_GFP                      130
+# define EC_F_EC_GROUP_GET_DEGREE                         173
+# define EC_F_EC_GROUP_GET_ORDER                          141
+# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS              193
+# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS                194
+# define EC_F_EC_GROUP_NEW                                108
+# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME                  174
+# define EC_F_EC_GROUP_NEW_FROM_DATA                      175
+# define EC_F_EC_GROUP_PRECOMPUTE_MULT                    142
+# define EC_F_EC_GROUP_SET_CURVE_GF2M                     176
+# define EC_F_EC_GROUP_SET_CURVE_GFP                      109
+# define EC_F_EC_GROUP_SET_EXTRA_DATA                     110
+# define EC_F_EC_GROUP_SET_GENERATOR                      111
+# define EC_F_EC_KEY_CHECK_KEY                            177
+# define EC_F_EC_KEY_COPY                                 178
+# define EC_F_EC_KEY_GENERATE_KEY                         179
+# define EC_F_EC_KEY_NEW                                  182
+# define EC_F_EC_KEY_PRINT                                180
+# define EC_F_EC_KEY_PRINT_FP                             181
+# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES    229
+# define EC_F_EC_POINTS_MAKE_AFFINE                       136
+# define EC_F_EC_POINT_ADD                                112
+# define EC_F_EC_POINT_CMP                                113
+# define EC_F_EC_POINT_COPY                               114
+# define EC_F_EC_POINT_DBL                                115
+# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M        183
+# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP         116
+# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP    117
+# define EC_F_EC_POINT_INVERT                             210
+# define EC_F_EC_POINT_IS_AT_INFINITY                     118
+# define EC_F_EC_POINT_IS_ON_CURVE                        119
+# define EC_F_EC_POINT_MAKE_AFFINE                        120
+# define EC_F_EC_POINT_MUL                                184
+# define EC_F_EC_POINT_NEW                                121
+# define EC_F_EC_POINT_OCT2POINT                          122
+# define EC_F_EC_POINT_POINT2OCT                          123
+# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M        185
+# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP         124
+# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M    186
+# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP     125
+# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP    126
+# define EC_F_EC_POINT_SET_TO_INFINITY                    127
+# define EC_F_EC_PRE_COMP_DUP                             207
+# define EC_F_EC_PRE_COMP_NEW                             196
+# define EC_F_EC_WNAF_MUL                                 187
+# define EC_F_EC_WNAF_PRECOMPUTE_MULT                     188
+# define EC_F_I2D_ECPARAMETERS                            190
+# define EC_F_I2D_ECPKPARAMETERS                          191
+# define EC_F_I2D_ECPRIVATEKEY                            192
+# define EC_F_I2O_ECPUBLICKEY                             151
+# define EC_F_NISTP224_PRE_COMP_NEW                       227
+# define EC_F_NISTP256_PRE_COMP_NEW                       236
+# define EC_F_NISTP521_PRE_COMP_NEW                       237
+# define EC_F_O2I_ECPUBLICKEY                             152
+# define EC_F_OLD_EC_PRIV_DECODE                          222
+# define EC_F_PKEY_EC_CTRL                                197
+# define EC_F_PKEY_EC_CTRL_STR                            198
+# define EC_F_PKEY_EC_DERIVE                              217
+# define EC_F_PKEY_EC_KEYGEN                              199
+# define EC_F_PKEY_EC_PARAMGEN                            219
+# define EC_F_PKEY_EC_SIGN                                218
+
+/* Reason codes. */
+# define EC_R_ASN1_ERROR                                  115
+# define EC_R_ASN1_UNKNOWN_FIELD                          116
+# define EC_R_BIGNUM_OUT_OF_RANGE                         144
+# define EC_R_BUFFER_TOO_SMALL                            100
+# define EC_R_COORDINATES_OUT_OF_RANGE                    146
+# define EC_R_D2I_ECPKPARAMETERS_FAILURE                  117
+# define EC_R_DECODE_ERROR                                142
+# define EC_R_DISCRIMINANT_IS_ZERO                        118
+# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE                119
+# define EC_R_FIELD_TOO_LARGE                             143
+# define EC_R_GF2M_NOT_SUPPORTED                          147
+# define EC_R_GROUP2PKPARAMETERS_FAILURE                  120
+# define EC_R_I2D_ECPKPARAMETERS_FAILURE                  121
+# define EC_R_INCOMPATIBLE_OBJECTS                        101
+# define EC_R_INVALID_ARGUMENT                            112
+# define EC_R_INVALID_COMPRESSED_POINT                    110
+# define EC_R_INVALID_COMPRESSION_BIT                     109
+# define EC_R_INVALID_CURVE                               141
+# define EC_R_INVALID_DIGEST                              151
+# define EC_R_INVALID_DIGEST_TYPE                         138
+# define EC_R_INVALID_ENCODING                            102
+# define EC_R_INVALID_FIELD                               103
+# define EC_R_INVALID_FORM                                104
+# define EC_R_INVALID_GROUP_ORDER                         122
+# define EC_R_INVALID_PENTANOMIAL_BASIS                   132
+# define EC_R_INVALID_PRIVATE_KEY                         123
+# define EC_R_INVALID_TRINOMIAL_BASIS                     137
+# define EC_R_KDF_PARAMETER_ERROR                         148
+# define EC_R_KEYS_NOT_SET                                140
+# define EC_R_MISSING_PARAMETERS                          124
+# define EC_R_MISSING_PRIVATE_KEY                         125
+# define EC_R_NOT_A_NIST_PRIME                            135
+# define EC_R_NOT_A_SUPPORTED_NIST_PRIME                  136
+# define EC_R_NOT_IMPLEMENTED                             126
+# define EC_R_NOT_INITIALIZED                             111
+# define EC_R_NO_FIELD_MOD                                133
+# define EC_R_NO_PARAMETERS_SET                           139
+# define EC_R_PASSED_NULL_PARAMETER                       134
+# define EC_R_PEER_KEY_ERROR                              149
+# define EC_R_PKPARAMETERS2GROUP_FAILURE                  127
+# define EC_R_POINT_AT_INFINITY                           106
+# define EC_R_POINT_IS_NOT_ON_CURVE                       107
+# define EC_R_SHARED_INFO_ERROR                           150
+# define EC_R_SLOT_FULL                                   108
+# define EC_R_UNDEFINED_GENERATOR                         113
+# define EC_R_UNDEFINED_ORDER                             128
+# define EC_R_UNKNOWN_GROUP                               129
+# define EC_R_UNKNOWN_ORDER                               114
+# define EC_R_UNSUPPORTED_FIELD                           131
+# define EC_R_WRONG_CURVE_PARAMETERS                      145
+# define EC_R_WRONG_ORDER                                 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ecdh.h b/Cryptlib/Include/openssl/ecdh.h
new file mode 100644 (file)
index 0000000..25348b3
--- /dev/null
@@ -0,0 +1,134 @@
+/* crypto/ecdh/ecdh.h */
+/* ====================================================================
+ * 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.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-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).
+ *
+ */
+#ifndef HEADER_ECDH_H
+# define HEADER_ECDH_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_ECDH
+#  error ECDH is disabled.
+# endif
+
+# include <openssl/ec.h>
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define EC_FLAG_COFACTOR_ECDH   0x1000
+
+const ECDH_METHOD *ECDH_OpenSSL(void);
+
+void ECDH_set_default_method(const ECDH_METHOD *);
+const ECDH_METHOD *ECDH_get_default_method(void);
+int ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+                     EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen,
+                                                 void *out, size_t *outlen));
+
+int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
+                          *new_func, CRYPTO_EX_dup *dup_func,
+                          CRYPTO_EX_free *free_func);
+int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
+void *ECDH_get_ex_data(EC_KEY *d, int idx);
+
+int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
+                   const unsigned char *Z, size_t Zlen,
+                   const unsigned char *sinfo, size_t sinfolen,
+                   const EVP_MD *md);
+
+/* 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_ECDH_strings(void);
+
+/* Error codes for the ECDH functions. */
+
+/* Function codes. */
+# define ECDH_F_ECDH_CHECK                                102
+# define ECDH_F_ECDH_COMPUTE_KEY                          100
+# define ECDH_F_ECDH_DATA_NEW_METHOD                      101
+
+/* Reason codes. */
+# define ECDH_R_KDF_FAILED                                102
+# define ECDH_R_NON_FIPS_METHOD                           103
+# define ECDH_R_NO_PRIVATE_VALUE                          100
+# define ECDH_R_POINT_ARITHMETIC_FAILURE                  101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ecdsa.h b/Cryptlib/Include/openssl/ecdsa.h
new file mode 100644 (file)
index 0000000..a6f0930
--- /dev/null
@@ -0,0 +1,335 @@
+/* crypto/ecdsa/ecdsa.h */
+/**
+ * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
+ * \author Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+#ifndef HEADER_ECDSA_H
+# define HEADER_ECDSA_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_ECDSA
+#  error ECDSA is disabled.
+# endif
+
+# include <openssl/ec.h>
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ECDSA_SIG_st {
+    BIGNUM *r;
+    BIGNUM *s;
+} ECDSA_SIG;
+
+/** Allocates and initialize a ECDSA_SIG structure
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** frees a ECDSA_SIG structure
+ *  \param  sig  pointer to the ECDSA_SIG structure
+ */
+void ECDSA_SIG_free(ECDSA_SIG *sig);
+
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ *  (*pp += length of the DER encoded signature)).
+ *  \param  sig  pointer to the ECDSA_SIG object
+ *  \param  pp   pointer to a unsigned char pointer for the output or NULL
+ *  \return the length of the DER encoded ECDSA_SIG object or 0
+ */
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ *  (*pp += len)).
+ *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
+ *  \param  pp   memory buffer with the DER encoded signature
+ *  \param  len  length of the buffer
+ *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
+
+/** Computes the ECDSA signature of the given hash value using
+ *  the supplied private key and returns the created signature.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  eckey     EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
+                         EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl),
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
+                            const BIGNUM *kinv, const BIGNUM *rp,
+                            EC_KEY *eckey);
+
+/** Verifies that the supplied signature is a valid ECDSA
+ *  signature of the supplied hash value using the supplied public key.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  sig       ECDSA_SIG structure
+ *  \param  eckey     EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+                    const ECDSA_SIG *sig, EC_KEY *eckey);
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void);
+
+/** Sets the default ECDSA method
+ *  \param  meth  new default ECDSA_METHOD
+ */
+void ECDSA_set_default_method(const ECDSA_METHOD *meth);
+
+/** Returns the default ECDSA method
+ *  \return pointer to ECDSA_METHOD structure containing the default method
+ */
+const ECDSA_METHOD *ECDSA_get_default_method(void);
+
+/** Sets method to be used for the ECDSA operations
+ *  \param  eckey  EC_KEY object
+ *  \param  meth   new method
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
+
+/** Returns the maximum length of the DER encoded signature
+ *  \param  eckey  EC_KEY object
+ *  \return numbers of bytes required for the DER encoded signature
+ */
+int ECDSA_size(const EC_KEY *eckey);
+
+/** Precompute parts of the signing operation
+ *  \param  eckey  EC_KEY object containing a private EC key
+ *  \param  ctx    BN_CTX object (optional)
+ *  \param  kinv   BIGNUM pointer for the inverse of k
+ *  \param  rp     BIGNUM pointer for x coordinate of k * generator
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      memory for the DER encoded created signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
+               unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      buffer to hold the DER encoded signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optioanl),
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
+                  unsigned char *sig, unsigned int *siglen,
+                  const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** Verifies that the given signature is valid ECDSA signature
+ *  of the supplied hash value using the specified public key.
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      pointer to the DER encoded signature
+ *  \param  siglen   length of the DER encoded signature
+ *  \param  eckey    EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
+                 const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/* the standard ex_data functions */
+int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
+                           *new_func, CRYPTO_EX_dup *dup_func,
+                           CRYPTO_EX_free *free_func);
+int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+void *ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+/** Allocates and initialize a ECDSA_METHOD structure
+ *  \param ecdsa_method pointer to ECDSA_METHOD to copy.  (May be NULL)
+ *  \return pointer to a ECDSA_METHOD structure or NULL if an error occurred
+ */
+
+ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method);
+
+/** frees a ECDSA_METHOD structure
+ *  \param  ecdsa_method  pointer to the ECDSA_METHOD structure
+ */
+void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method);
+
+/**  Sets application specific data in the ECDSA_METHOD
+ *   \param  ecdsa_method pointer to existing ECDSA_METHOD
+ *   \param  app application specific data to set
+ */
+
+void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app);
+
+/** Returns application specific data from a ECDSA_METHOD structure
+ *  \param ecdsa_method pointer to ECDSA_METHOD structure
+ *  \return pointer to application specific data.
+ */
+
+void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method);
+
+/**  Set the ECDSA_do_sign function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_do_sign a funtion of type ECDSA_do_sign
+ */
+
+void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method,
+                           ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char
+                                                        *dgst, int dgst_len,
+                                                        const BIGNUM *inv,
+                                                        const BIGNUM *rp,
+                                                        EC_KEY *eckey));
+
+/**  Set the  ECDSA_sign_setup function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_sign_setup a funtion of type ECDSA_sign_setup
+ */
+
+void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
+                                 int (*ecdsa_sign_setup) (EC_KEY *eckey,
+                                                          BN_CTX *ctx,
+                                                          BIGNUM **kinv,
+                                                          BIGNUM **r));
+
+/**  Set the ECDSA_do_verify function in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  ecdsa_do_verify a funtion of type ECDSA_do_verify
+ */
+
+void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
+                             int (*ecdsa_do_verify) (const unsigned char
+                                                     *dgst, int dgst_len,
+                                                     const ECDSA_SIG *sig,
+                                                     EC_KEY *eckey));
+
+void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags);
+
+/**  Set the flags field in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  flags flags value to set
+ */
+
+void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name);
+
+/**  Set the name field in the ECDSA_METHOD
+ *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
+ *   \param  name name to set
+ */
+
+/* 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_ECDSA_strings(void);
+
+/* Error codes for the ECDSA functions. */
+
+/* Function codes. */
+# define ECDSA_F_ECDSA_CHECK                              104
+# define ECDSA_F_ECDSA_DATA_NEW_METHOD                    100
+# define ECDSA_F_ECDSA_DO_SIGN                            101
+# define ECDSA_F_ECDSA_DO_VERIFY                          102
+# define ECDSA_F_ECDSA_METHOD_NEW                         105
+# define ECDSA_F_ECDSA_SIGN_SETUP                         103
+
+/* Reason codes. */
+# define ECDSA_R_BAD_SIGNATURE                            100
+# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE              101
+# define ECDSA_R_ERR_EC_LIB                               102
+# define ECDSA_R_MISSING_PARAMETERS                       103
+# define ECDSA_R_NEED_NEW_SETUP_VALUES                    106
+# define ECDSA_R_NON_FIPS_METHOD                          107
+# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED          104
+# define ECDSA_R_SIGNATURE_MALLOC_FAILED                  105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/engine.h b/Cryptlib/Include/openssl/engine.h
new file mode 100644 (file)
index 0000000..bd7b591
--- /dev/null
@@ -0,0 +1,960 @@
+/* openssl/engine.h */
+/*
+ * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+# define HEADER_ENGINE_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_ENGINE
+#  error ENGINE is disabled.
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  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_DH
+#   include <openssl/dh.h>
+#  endif
+#  ifndef OPENSSL_NO_ECDH
+#   include <openssl/ecdh.h>
+#  endif
+#  ifndef OPENSSL_NO_ECDSA
+#   include <openssl/ecdsa.h>
+#  endif
+#  include <openssl/rand.h>
+#  include <openssl/ui.h>
+#  include <openssl/err.h>
+# endif
+
+# include <openssl/ossl_typ.h>
+# include <openssl/symhacks.h>
+
+# include <openssl/x509.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These flags are used to control combinations of algorithm (methods) by
+ * bitwise "OR"ing.
+ */
+# define ENGINE_METHOD_RSA               (unsigned int)0x0001
+# define ENGINE_METHOD_DSA               (unsigned int)0x0002
+# define ENGINE_METHOD_DH                (unsigned int)0x0004
+# define ENGINE_METHOD_RAND              (unsigned int)0x0008
+# define ENGINE_METHOD_ECDH              (unsigned int)0x0010
+# define ENGINE_METHOD_ECDSA             (unsigned int)0x0020
+# define ENGINE_METHOD_CIPHERS           (unsigned int)0x0040
+# define ENGINE_METHOD_DIGESTS           (unsigned int)0x0080
+# define ENGINE_METHOD_STORE             (unsigned int)0x0100
+# define ENGINE_METHOD_PKEY_METHS        (unsigned int)0x0200
+# define ENGINE_METHOD_PKEY_ASN1_METHS   (unsigned int)0x0400
+/* Obvious all-or-nothing cases. */
+# define ENGINE_METHOD_ALL               (unsigned int)0xFFFF
+# define ENGINE_METHOD_NONE              (unsigned int)0x0000
+
+/*
+ * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be
+ * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised.
+ */
+# define ENGINE_TABLE_FLAG_NOINIT        (unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* Not used */
+/* #define ENGINE_FLAGS_MALLOCED        0x0001 */
+
+/*
+ * This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles
+ * these control commands on behalf of the ENGINE using their "cmd_defns"
+ * data.
+ */
+# define ENGINE_FLAGS_MANUAL_CMD_CTRL    (int)0x0002
+
+/*
+ * This flag is for ENGINEs who return new duplicate structures when found
+ * via "ENGINE_by_id()". When an ENGINE must store state (eg. if
+ * ENGINE_ctrl() commands are called in sequence as part of some stateful
+ * process like key-generation setup and execution), it can set this flag -
+ * then each attempt to obtain the ENGINE will result in it being copied into
+ * a new structure. Normally, ENGINEs don't declare this flag so
+ * ENGINE_by_id() just increments the existing ENGINE's structural reference
+ * count.
+ */
+# define ENGINE_FLAGS_BY_ID_COPY         (int)0x0004
+
+/*
+ * This flag if for an ENGINE that does not want its methods registered as
+ * part of ENGINE_register_all_complete() for example if the methods are not
+ * usable as default methods.
+ */
+
+# define ENGINE_FLAGS_NO_REGISTER_ALL    (int)0x0008
+
+/*
+ * ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input
+ * each command expects. Currently only numeric and string input is
+ * supported. If a control command supports none of the _NUMERIC, _STRING, or
+ * _NO_INPUT options, then it is regarded as an "internal" control command -
+ * and not for use in config setting situations. As such, they're not
+ * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl()
+ * access. Changes to this list of 'command types' should be reflected
+ * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string().
+ */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+# define ENGINE_CMD_FLAG_NUMERIC         (unsigned int)0x0001
+/*
+ * accepts string input (cast from 'void*' to 'const char *', 4th parameter
+ * to ENGINE_ctrl)
+ */
+# define ENGINE_CMD_FLAG_STRING          (unsigned int)0x0002
+/*
+ * Indicates that the control command takes *no* input. Ie. the control
+ * command is unparameterised.
+ */
+# define ENGINE_CMD_FLAG_NO_INPUT        (unsigned int)0x0004
+/*
+ * Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function.
+ */
+# define ENGINE_CMD_FLAG_INTERNAL        (unsigned int)0x0008
+
+/*
+ * NB: These 3 control commands are deprecated and should not be used.
+ * ENGINEs relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate
+ * the same functionality to their own ENGINE-specific control functions that
+ * can be "discovered" by calling applications. The fact these control
+ * commands wouldn't be "executable" (ie. usable by text-based config)
+ * doesn't change the fact that application code can find and use them
+ * without requiring per-ENGINE hacking.
+ */
+
+/*
+ * These flags are used to tell the ctrl function what should be done. All
+ * command numbers are shared between all engines, even if some don't make
+ * sense to some engines.  In such a case, they do nothing but return the
+ * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED.
+ */
+# define ENGINE_CTRL_SET_LOGSTREAM               1
+# define ENGINE_CTRL_SET_PASSWORD_CALLBACK       2
+# define ENGINE_CTRL_HUP                         3/* Close and reinitialise
+                                                   * any handles/connections
+                                                   * etc. */
+# define ENGINE_CTRL_SET_USER_INTERFACE          4/* Alternative to callback */
+# define ENGINE_CTRL_SET_CALLBACK_DATA           5/* User-specific data, used
+                                                   * when calling the password
+                                                   * callback and the user
+                                                   * interface */
+# define ENGINE_CTRL_LOAD_CONFIGURATION          6/* Load a configuration,
+                                                   * given a string that
+                                                   * represents a file name
+                                                   * or so */
+# define ENGINE_CTRL_LOAD_SECTION                7/* Load data from a given
+                                                   * section in the already
+                                                   * loaded configuration */
+
+/*
+ * These control commands allow an application to deal with an arbitrary
+ * engine in a dynamic way. Warn: Negative return values indicate errors FOR
+ * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other
+ * commands, including ENGINE-specific command types, return zero for an
+ * error. An ENGINE can choose to implement these ctrl functions, and can
+ * internally manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise
+ * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the
+ * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's
+ * ctrl() handler need only implement its own commands - the above "meta"
+ * commands will be taken care of.
+ */
+
+/*
+ * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not",
+ * then all the remaining control commands will return failure, so it is
+ * worth checking this first if the caller is trying to "discover" the
+ * engine's capabilities and doesn't want errors generated unnecessarily.
+ */
+# define ENGINE_CTRL_HAS_CTRL_FUNCTION           10
+/*
+ * Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported.
+ */
+# define ENGINE_CTRL_GET_FIRST_CMD_TYPE          11
+/*
+ * The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more.
+ */
+# define ENGINE_CTRL_GET_NEXT_CMD_TYPE           12
+/*
+ * The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it.
+ */
+# define ENGINE_CTRL_GET_CMD_FROM_NAME           13
+/*
+ * The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the
+ * NAME_LEN case, the return value is the length of the command name (not
+ * counting a trailing EOL). In the NAME case, the 'void*' argument must be a
+ * string buffer large enough, and it will be populated with the name of the
+ * command (WITH a trailing EOL).
+ */
+# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD       14
+# define ENGINE_CTRL_GET_NAME_FROM_CMD           15
+/* The next two are similar but give a "short description" of a command. */
+# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD       16
+# define ENGINE_CTRL_GET_DESC_FROM_CMD           17
+/*
+ * With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects.
+ */
+# define ENGINE_CTRL_GET_CMD_FLAGS               18
+
+/*
+ * ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc).
+ */
+# define ENGINE_CMD_BASE                         200
+
+/*
+ * NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before
+ * these are removed.
+ */
+
+/* Flags specific to the nCipher "chil" engine */
+# define ENGINE_CTRL_CHIL_SET_FORKCHECK          100
+        /*
+         * Depending on the value of the (long)i argument, this sets or
+         * unsets the SimpleForkCheck flag in the CHIL API to enable or
+         * disable checking and workarounds for applications that fork().
+         */
+# define ENGINE_CTRL_CHIL_NO_LOCKING             101
+        /*
+         * This prevents the initialisation function from providing mutex
+         * callbacks to the nCipher library.
+         */
+
+/*
+ * If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on
+ * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN
+ * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl()
+ * handler that supports the stated commands (ie. the "cmd_num" entries as
+ * described by the array). NB: The array must be ordered in increasing order
+ * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element
+ * has cmd_num set to zero and/or cmd_name set to NULL.
+ */
+typedef struct ENGINE_CMD_DEFN_st {
+    unsigned int cmd_num;       /* The command number */
+    const char *cmd_name;       /* The command name itself */
+    const char *cmd_desc;       /* A short description of the command */
+    unsigned int cmd_flags;     /* The input the command expects */
+} ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR) (void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *,
+                                     void (*f) (void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+                                         UI_METHOD *ui_method,
+                                         void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl,
+                                           STACK_OF(X509_NAME) *ca_dn,
+                                           X509 **pcert, EVP_PKEY **pkey,
+                                           STACK_OF(X509) **pother,
+                                           UI_METHOD *ui_method,
+                                           void *callback_data);
+/*-
+ * These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/*
+ * Returns to a pointer to the array of supported cipher 'nid's. If the
+ * second parameter is non-NULL it is set to the size of the returned array.
+ */
+typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **,
+                                   const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **,
+                                   int);
+typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **,
+                                      const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **,
+                                           const int **, int);
+/*
+ * STRUCTURE functions ... all of these functions deal with pointers to
+ * ENGINE structures where the pointers have a "structural reference". This
+ * means that their reference is to allowed access to the structure but it
+ * does not imply that the structure is functional. To simply increment or
+ * decrement the structural reference count, use ENGINE_by_id and
+ * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next
+ * as it will automatically decrement the structural reference count of the
+ * "current" ENGINE and increment the structural reference count of the
+ * ENGINE it returns (unless it is NULL).
+ */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+/* Add all the built-in engines. */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+# ifndef OPENSSL_NO_STATIC_ENGINE
+void ENGINE_load_4758cca(void);
+void ENGINE_load_aep(void);
+void ENGINE_load_atalla(void);
+void ENGINE_load_chil(void);
+void ENGINE_load_cswift(void);
+void ENGINE_load_nuron(void);
+void ENGINE_load_sureware(void);
+void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#  ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#  endif
+#  ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#  endif
+# endif
+void ENGINE_load_cryptodev(void);
+void ENGINE_load_rdrand(void);
+void ENGINE_load_builtin_engines(void);
+
+/*
+ * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling.
+ */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/*- Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required, so
+ * ENGINE_cleanup() will reverse any "register" operations.
+ */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_ECDH(ENGINE *e);
+void ENGINE_unregister_ECDH(ENGINE *e);
+void ENGINE_register_all_ECDH(void);
+
+int ENGINE_register_ECDSA(ENGINE *e);
+void ENGINE_unregister_ECDSA(ENGINE *e);
+void ENGINE_register_all_ECDSA(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_STORE(ENGINE *e);
+void ENGINE_unregister_STORE(ENGINE *e);
+void ENGINE_register_all_STORE(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
+/*
+ * These functions register all support from the above categories. Note, use
+ * of these functions can result in static linkage of code your application
+ * may not need. If you only need a subset of functionality, consider using
+ * more selective initialisation.
+ */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/*
+ * Send parametrised control commands to the engine. The possibilities to
+ * send down an integer, a pointer to data or a function pointer are
+ * provided. Any of the parameters may or may not be NULL, depending on the
+ * command number. In actuality, this function only requires a structural
+ * (rather than functional) reference to an engine, but many control commands
+ * may require the engine be functional. The caller should be aware of trying
+ * commands that require an operational ENGINE, and only use functional
+ * references in such situations.
+ */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void));
+
+/*
+ * This function tests if an ENGINE-specific command is usable as a
+ * "setting". Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl().
+ */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/*
+ * This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional
+ * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation
+ * on how to use the cmd_name and cmd_optional.
+ */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+                    long i, void *p, void (*f) (void), int cmd_optional);
+
+/*
+ * This function passes a command-name and argument to an ENGINE. The
+ * cmd_name is converted to a command number and the control command is
+ * called using 'arg' as an argument (unless the ENGINE doesn't support such
+ * a command, in which case no control command is called). The command is
+ * checked for input flags, and if necessary the argument will be converted
+ * to a numeric value. If cmd_optional is non-zero, then if the ENGINE
+ * doesn't support the given cmd_name the return value will be success
+ * anyway. This function is intended for applications to use so that users
+ * (or config files) can supply engine-specific config data to the ENGINE at
+ * run-time to control behaviour of specific engines. As such, it shouldn't
+ * be used for calling ENGINE_ctrl() functions that return data, deal with
+ * binary data, or that are otherwise supposed to be used directly through
+ * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl()
+ * operation in this function will be lost - the return value is interpreted
+ * as failure if the return value is zero, success otherwise, and this
+ * function returns a boolean value as a result. In other words, vendors of
+ * 'ENGINE'-enabled devices should write ENGINE implementations with
+ * parameterisations that work in this scheme, so that compliant ENGINE-based
+ * applications can work consistently with the same configuration for the
+ * same ENGINE-enabled devices, across applications.
+ */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+                           int cmd_optional);
+
+/*
+ * These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an
+ * ENGINE structure with personalised implementations of things prior to
+ * using it directly or adding it to the builtin ENGINE list in OpenSSL.
+ * These are also here so that the ENGINE structure doesn't have to be
+ * exposed and break binary compatibility!
+ */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e,
+                                     ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+                                             ENGINE_SSL_CLIENT_CERT_PTR
+                                             loadssl_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                            CRYPTO_EX_dup *dup_func,
+                            CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+/*
+ * This function cleans up anything that needs it. Eg. the ENGINE_add()
+ * function automatically ensures the list cleanup function is registered to
+ * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_***
+ * functions ensure ENGINE_cleanup() will clean up after them.
+ */
+void ENGINE_cleanup(void);
+
+/*
+ * These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic!
+ */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
+                                                               *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+                                                          const char *str,
+                                                          int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+                                                      const char *str,
+                                                      int len);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/*
+ * FUNCTIONAL functions. These functions deal with ENGINE structures that
+ * have (or will) be initialised for use. Broadly speaking, the structural
+ * functions are useful for iterating the list of available engine types,
+ * creating new engine types, and other "list" operations. These functions
+ * actually deal with ENGINEs that are to be used. As such these functions
+ * can fail (if applicable) when particular engines are unavailable - eg. if
+ * a hardware accelerator is not attached or not functioning correctly. Each
+ * ENGINE has 2 reference counts; structural and functional. Every time a
+ * functional reference is obtained or released, a corresponding structural
+ * reference is automatically obtained or released too.
+ */
+
+/*
+ * Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently operational
+ * and cannot initialise.
+ */
+int ENGINE_init(ENGINE *e);
+/*
+ * Free a functional reference to a engine type. This does not require a
+ * corresponding call to ENGINE_free as it also releases a structural
+ * reference.
+ */
+int ENGINE_finish(ENGINE *e);
+
+/*
+ * The following functions handle keys that are stored in some secondary
+ * location, handled by the engine.  The storage may be on a card or
+ * whatever.
+ */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+                                  UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+                                 UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+                                STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
+                                EVP_PKEY **ppkey, STACK_OF(X509) **pother,
+                                UI_METHOD *ui_method, void *callback_data);
+
+/*
+ * This returns a pointer for the current ENGINE structure that is (by
+ * default) performing any RSA operations. The value returned is an
+ * incremented reference, so it should be free'd (ENGINE_finish) before it is
+ * discarded.
+ */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_ECDH(void);
+ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/*
+ * These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid".
+ */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
+
+/*
+ * This sets a new default ENGINE structure for performing RSA operations. If
+ * the result is non-zero (success) then the ENGINE structure will have had
+ * its reference count up'd so the caller should still free their own
+ * reference 'e'.
+ */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_ECDH(ENGINE *e);
+int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
+
+/*
+ * The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions.
+ */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+# define OSSL_DYNAMIC_VERSION            (unsigned long)0x00020000
+/*
+ * Binary versions older than this are too old for us (whether we're a loader
+ * or a loadee)
+ */
+# define OSSL_DYNAMIC_OLDEST             (unsigned long)0x00020000
+
+/*
+ * When compiling an ENGINE entirely as an external shared library, loadable
+ * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns'
+ * structure type provides the calling application's (or library's) error
+ * functionality and memory management function pointers to the loaded
+ * library. These should be used/set in the loaded library code so that the
+ * loading application's 'state' will be used/changed in all operations. The
+ * 'static_state' pointer allows the loaded library to know if it shares the
+ * same static data as the calling application (or library), and thus whether
+ * these callbacks need to be set or not.
+ */
+typedef void *(*dyn_MEM_malloc_cb) (size_t);
+typedef void *(*dyn_MEM_realloc_cb) (void *, size_t);
+typedef void (*dyn_MEM_free_cb) (void *);
+typedef struct st_dynamic_MEM_fns {
+    dyn_MEM_malloc_cb malloc_cb;
+    dyn_MEM_realloc_cb realloc_cb;
+    dyn_MEM_free_cb free_cb;
+} dynamic_MEM_fns;
+/*
+ * FIXME: Perhaps the memory and locking code (crypto.h) should declare and
+ * use these types so we (and any other dependant code) can simplify a bit??
+ */
+typedef void (*dyn_lock_locking_cb) (int, int, const char *, int);
+typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int);
+typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *,
+                                                               int);
+typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *,
+                                     const char *, int);
+typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *,
+                                        const char *, int);
+typedef struct st_dynamic_LOCK_fns {
+    dyn_lock_locking_cb lock_locking_cb;
+    dyn_lock_add_lock_cb lock_add_lock_cb;
+    dyn_dynlock_create_cb dynlock_create_cb;
+    dyn_dynlock_lock_cb dynlock_lock_cb;
+    dyn_dynlock_destroy_cb dynlock_destroy_cb;
+} dynamic_LOCK_fns;
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+    void *static_state;
+    const ERR_FNS *err_fns;
+    const CRYPTO_EX_DATA_IMPL *ex_data_fns;
+    dynamic_MEM_fns mem_fns;
+    dynamic_LOCK_fns lock_fns;
+} dynamic_fns;
+
+/*
+ * The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading
+ * code. If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's
+ * version is unsatisfactory and could veto the load. The function is
+ * expected to be implemented with the symbol name "v_check", and a default
+ * implementation can be fully instantiated with
+ * IMPLEMENT_DYNAMIC_CHECK_FN().
+ */
+typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version);
+# define IMPLEMENT_DYNAMIC_CHECK_FN() \
+        OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
+        OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
+                if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+                return 0; }
+
+/*
+ * This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load
+ * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto
+ * the structure, and (c) the shared library will be unloaded. So
+ * implementations should do their own internal cleanup in failure
+ * circumstances otherwise they could leak. The 'id' parameter, if non-NULL,
+ * represents the ENGINE id that the loader is looking for. If this is NULL,
+ * the shared library can choose to return failure or to initialise a
+ * 'default' ENGINE. If non-NULL, the shared library must initialise only an
+ * ENGINE matching the passed 'id'. The function is expected to be
+ * implemented with the symbol name "bind_engine". A standard implementation
+ * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter
+ * 'fn' is a callback function that populates the ENGINE structure and
+ * returns an int value (zero for failure). 'fn' should have prototype;
+ * [static] int fn(ENGINE *e, const char *id);
+ */
+typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id,
+                                    const dynamic_fns *fns);
+# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+        OPENSSL_EXPORT \
+        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
+        OPENSSL_EXPORT \
+        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+                if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+                if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+                        fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+                        return 0; \
+                CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+                CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+                CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+                CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+                CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+                if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+                        return 0; \
+                if(!ERR_set_implementation(fns->err_fns)) return 0; \
+        skip_cbs: \
+                if(!fn(e,id)) return 0; \
+                return 1; }
+
+/*
+ * If the loading application (or library) and the loaded ENGINE library
+ * share the same static data (eg. they're both dynamically linked to the
+ * same libcrypto.so) we need a way to avoid trying to set system callbacks -
+ * this would fail, and for the same reason that it's unnecessary to try. If
+ * the loaded ENGINE has (or gets from through the loader) its own copy of
+ * the libcrypto static data, we will need to set the callbacks. The easiest
+ * way to detect this is to have a function that returns a pointer to some
+ * static data and let the loading application and loaded ENGINE compare
+ * their respective values.
+ */
+void *ENGINE_get_static_state(void);
+
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+void ENGINE_setup_bsd_cryptodev(void);
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+# define ENGINE_F_DYNAMIC_CTRL                            180
+# define ENGINE_F_DYNAMIC_GET_DATA_CTX                    181
+# define ENGINE_F_DYNAMIC_LOAD                            182
+# define ENGINE_F_DYNAMIC_SET_DATA_CTX                    183
+# define ENGINE_F_ENGINE_ADD                              105
+# define ENGINE_F_ENGINE_BY_ID                            106
+# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE                170
+# define ENGINE_F_ENGINE_CTRL                             142
+# define ENGINE_F_ENGINE_CTRL_CMD                         178
+# define ENGINE_F_ENGINE_CTRL_CMD_STRING                  171
+# define ENGINE_F_ENGINE_FINISH                           107
+# define ENGINE_F_ENGINE_FREE_UTIL                        108
+# define ENGINE_F_ENGINE_GET_CIPHER                       185
+# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE                 177
+# define ENGINE_F_ENGINE_GET_DIGEST                       186
+# define ENGINE_F_ENGINE_GET_NEXT                         115
+# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH               193
+# define ENGINE_F_ENGINE_GET_PKEY_METH                    192
+# define ENGINE_F_ENGINE_GET_PREV                         116
+# define ENGINE_F_ENGINE_INIT                             119
+# define ENGINE_F_ENGINE_LIST_ADD                         120
+# define ENGINE_F_ENGINE_LIST_REMOVE                      121
+# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY                 150
+# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY                  151
+# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT             194
+# define ENGINE_F_ENGINE_NEW                              122
+# define ENGINE_F_ENGINE_REMOVE                           123
+# define ENGINE_F_ENGINE_SET_DEFAULT_STRING               189
+# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE                 126
+# define ENGINE_F_ENGINE_SET_ID                           129
+# define ENGINE_F_ENGINE_SET_NAME                         130
+# define ENGINE_F_ENGINE_TABLE_REGISTER                   184
+# define ENGINE_F_ENGINE_UNLOAD_KEY                       152
+# define ENGINE_F_ENGINE_UNLOCKED_FINISH                  191
+# define ENGINE_F_ENGINE_UP_REF                           190
+# define ENGINE_F_INT_CTRL_HELPER                         172
+# define ENGINE_F_INT_ENGINE_CONFIGURE                    188
+# define ENGINE_F_INT_ENGINE_MODULE_INIT                  187
+# define ENGINE_F_LOG_MESSAGE                             141
+
+/* Reason codes. */
+# define ENGINE_R_ALREADY_LOADED                          100
+# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER                133
+# define ENGINE_R_CMD_NOT_EXECUTABLE                      134
+# define ENGINE_R_COMMAND_TAKES_INPUT                     135
+# define ENGINE_R_COMMAND_TAKES_NO_INPUT                  136
+# define ENGINE_R_CONFLICTING_ENGINE_ID                   103
+# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED            119
+# define ENGINE_R_DH_NOT_IMPLEMENTED                      139
+# define ENGINE_R_DSA_NOT_IMPLEMENTED                     140
+# define ENGINE_R_DSO_FAILURE                             104
+# define ENGINE_R_DSO_NOT_FOUND                           132
+# define ENGINE_R_ENGINES_SECTION_ERROR                   148
+# define ENGINE_R_ENGINE_CONFIGURATION_ERROR              102
+# define ENGINE_R_ENGINE_IS_NOT_IN_LIST                   105
+# define ENGINE_R_ENGINE_SECTION_ERROR                    149
+# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY              128
+# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY               129
+# define ENGINE_R_FINISH_FAILED                           106
+# define ENGINE_R_GET_HANDLE_FAILED                       107
+# define ENGINE_R_ID_OR_NAME_MISSING                      108
+# define ENGINE_R_INIT_FAILED                             109
+# define ENGINE_R_INTERNAL_LIST_ERROR                     110
+# define ENGINE_R_INVALID_ARGUMENT                        143
+# define ENGINE_R_INVALID_CMD_NAME                        137
+# define ENGINE_R_INVALID_CMD_NUMBER                      138
+# define ENGINE_R_INVALID_INIT_VALUE                      151
+# define ENGINE_R_INVALID_STRING                          150
+# define ENGINE_R_NOT_INITIALISED                         117
+# define ENGINE_R_NOT_LOADED                              112
+# define ENGINE_R_NO_CONTROL_FUNCTION                     120
+# define ENGINE_R_NO_INDEX                                144
+# define ENGINE_R_NO_LOAD_FUNCTION                        125
+# define ENGINE_R_NO_REFERENCE                            130
+# define ENGINE_R_NO_SUCH_ENGINE                          116
+# define ENGINE_R_NO_UNLOAD_FUNCTION                      126
+# define ENGINE_R_PROVIDE_PARAMETERS                      113
+# define ENGINE_R_RSA_NOT_IMPLEMENTED                     141
+# define ENGINE_R_UNIMPLEMENTED_CIPHER                    146
+# define ENGINE_R_UNIMPLEMENTED_DIGEST                    147
+# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD         101
+# define ENGINE_R_VERSION_INCOMPATIBILITY                 145
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/err.h b/Cryptlib/Include/openssl/err.h
new file mode 100644 (file)
index 0000000..04c6cfc
--- /dev/null
@@ -0,0 +1,389 @@
+/* crypto/err/err.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-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_ERR_H
+# define HEADER_ERR_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+#  include <stdio.h>
+#  include <stdlib.h>
+# endif
+
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# ifndef OPENSSL_NO_LHASH
+#  include <openssl/lhash.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_NO_ERR
+#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,d,e)
+# else
+#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,NULL,0)
+# endif
+
+# include <errno.h>
+
+# define ERR_TXT_MALLOCED        0x01
+# define ERR_TXT_STRING          0x02
+
+# define ERR_FLAG_MARK           0x01
+
+# define ERR_NUM_ERRORS  16
+typedef struct err_state_st {
+    CRYPTO_THREADID tid;
+    int err_flags[ERR_NUM_ERRORS];
+    unsigned long err_buffer[ERR_NUM_ERRORS];
+    char *err_data[ERR_NUM_ERRORS];
+    int err_data_flags[ERR_NUM_ERRORS];
+    const char *err_file[ERR_NUM_ERRORS];
+    int err_line[ERR_NUM_ERRORS];
+    int top, bottom;
+} ERR_STATE;
+
+/* library */
+# define ERR_LIB_NONE            1
+# define ERR_LIB_SYS             2
+# define ERR_LIB_BN              3
+# define ERR_LIB_RSA             4
+# define ERR_LIB_DH              5
+# define ERR_LIB_EVP             6
+# define ERR_LIB_BUF             7
+# define ERR_LIB_OBJ             8
+# define ERR_LIB_PEM             9
+# define ERR_LIB_DSA             10
+# define ERR_LIB_X509            11
+/* #define ERR_LIB_METH         12 */
+# define ERR_LIB_ASN1            13
+# define ERR_LIB_CONF            14
+# define ERR_LIB_CRYPTO          15
+# define ERR_LIB_EC              16
+# define ERR_LIB_SSL             20
+/* #define ERR_LIB_SSL23        21 */
+/* #define ERR_LIB_SSL2         22 */
+/* #define ERR_LIB_SSL3         23 */
+/* #define ERR_LIB_RSAREF       30 */
+/* #define ERR_LIB_PROXY        31 */
+# define ERR_LIB_BIO             32
+# define ERR_LIB_PKCS7           33
+# define ERR_LIB_X509V3          34
+# define ERR_LIB_PKCS12          35
+# define ERR_LIB_RAND            36
+# define ERR_LIB_DSO             37
+# define ERR_LIB_ENGINE          38
+# define ERR_LIB_OCSP            39
+# define ERR_LIB_UI              40
+# define ERR_LIB_COMP            41
+# define ERR_LIB_ECDSA           42
+# define ERR_LIB_ECDH            43
+# define ERR_LIB_STORE           44
+# define ERR_LIB_FIPS            45
+# define ERR_LIB_CMS             46
+# define ERR_LIB_TS              47
+# define ERR_LIB_HMAC            48
+# define ERR_LIB_JPAKE           49
+
+# define ERR_LIB_USER            128
+
+# define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+/*
+ * Borland C seems too stupid to be able to shift and do longs in the
+ * pre-processor :-(
+ */
+# define ERR_PACK(l,f,r)         (((((unsigned long)l)&0xffL)*0x1000000)| \
+                                ((((unsigned long)f)&0xfffL)*0x1000)| \
+                                ((((unsigned long)r)&0xfffL)))
+# define ERR_GET_LIB(l)          (int)((((unsigned long)l)>>24L)&0xffL)
+# define ERR_GET_FUNC(l)         (int)((((unsigned long)l)>>12L)&0xfffL)
+# define ERR_GET_REASON(l)       (int)((l)&0xfffL)
+# define ERR_FATAL_ERROR(l)      (int)((l)&ERR_R_FATAL)
+
+/* OS functions */
+# define SYS_F_FOPEN             1
+# define SYS_F_CONNECT           2
+# define SYS_F_GETSERVBYNAME     3
+# define SYS_F_SOCKET            4
+# define SYS_F_IOCTLSOCKET       5
+# define SYS_F_BIND              6
+# define SYS_F_LISTEN            7
+# define SYS_F_ACCEPT            8
+# define SYS_F_WSASTARTUP        9/* Winsock stuff */
+# define SYS_F_OPENDIR           10
+# define SYS_F_FREAD             11
+
+/* reasons */
+# define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */
+# define ERR_R_BN_LIB    ERR_LIB_BN/* 3 */
+# define ERR_R_RSA_LIB   ERR_LIB_RSA/* 4 */
+# define ERR_R_DH_LIB    ERR_LIB_DH/* 5 */
+# define ERR_R_EVP_LIB   ERR_LIB_EVP/* 6 */
+# define ERR_R_BUF_LIB   ERR_LIB_BUF/* 7 */
+# define ERR_R_OBJ_LIB   ERR_LIB_OBJ/* 8 */
+# define ERR_R_PEM_LIB   ERR_LIB_PEM/* 9 */
+# define ERR_R_DSA_LIB   ERR_LIB_DSA/* 10 */
+# define ERR_R_X509_LIB  ERR_LIB_X509/* 11 */
+# define ERR_R_ASN1_LIB  ERR_LIB_ASN1/* 13 */
+# define ERR_R_CONF_LIB  ERR_LIB_CONF/* 14 */
+# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */
+# define ERR_R_EC_LIB    ERR_LIB_EC/* 16 */
+# define ERR_R_SSL_LIB   ERR_LIB_SSL/* 20 */
+# define ERR_R_BIO_LIB   ERR_LIB_BIO/* 32 */
+# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */
+# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */
+# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */
+# define ERR_R_RAND_LIB  ERR_LIB_RAND/* 36 */
+# define ERR_R_DSO_LIB   ERR_LIB_DSO/* 37 */
+# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */
+# define ERR_R_OCSP_LIB  ERR_LIB_OCSP/* 39 */
+# define ERR_R_UI_LIB    ERR_LIB_UI/* 40 */
+# define ERR_R_COMP_LIB  ERR_LIB_COMP/* 41 */
+# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */
+# define ERR_R_ECDH_LIB  ERR_LIB_ECDH/* 43 */
+# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */
+# define ERR_R_TS_LIB    ERR_LIB_TS/* 45 */
+
+# define ERR_R_NESTED_ASN1_ERROR                 58
+# define ERR_R_BAD_ASN1_OBJECT_HEADER            59
+# define ERR_R_BAD_GET_ASN1_OBJECT_CALL          60
+# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE        61
+# define ERR_R_ASN1_LENGTH_MISMATCH              62
+# define ERR_R_MISSING_ASN1_EOS                  63
+
+/* fatal error */
+# define ERR_R_FATAL                             64
+# define ERR_R_MALLOC_FAILURE                    (1|ERR_R_FATAL)
+# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED       (2|ERR_R_FATAL)
+# define ERR_R_PASSED_NULL_PARAMETER             (3|ERR_R_FATAL)
+# define ERR_R_INTERNAL_ERROR                    (4|ERR_R_FATAL)
+# define ERR_R_DISABLED                          (5|ERR_R_FATAL)
+
+/*
+ * 99 is the maximum possible ERR_R_... code, higher values are reserved for
+ * the individual libraries
+ */
+
+typedef struct ERR_string_data_st {
+    unsigned long error;
+    const char *string;
+} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func, int reason, const char *file, int line);
+void ERR_set_error_data(char *data, int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file, int *line);
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+                                      const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file, int *line);
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+                                       const char **data, int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file, int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+                                            const char **data, int *flags);
+void ERR_clear_error(void);
+char *ERR_error_string(unsigned long e, char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
+                         void *u);
+# ifndef OPENSSL_NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+# endif
+# ifndef OPENSSL_NO_BIO
+void ERR_print_errors(BIO *bp);
+# endif
+void ERR_add_error_data(int num, ...);
+void ERR_add_error_vdata(int num, va_list args);
+void ERR_load_strings(int lib, ERR_STRING_DATA str[]);
+void ERR_unload_strings(int lib, ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+# ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+# endif
+ERR_STATE *ERR_get_state(void);
+
+# ifndef OPENSSL_NO_LHASH
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
+# endif
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+/* Already defined in ossl_typ.h */
+/* typedef struct st_ERR_FNS ERR_FNS; */
+/*
+ * An application can use this function and provide the return value to
+ * loaded modules that should use the application's ERR state/functionality
+ */
+const ERR_FNS *ERR_get_implementation(void);
+/*
+ * A loaded module should call this function prior to any ERR operations
+ * using the application's "ERR_FNS".
+ */
+int ERR_set_implementation(const ERR_FNS *fns);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/evp.h b/Cryptlib/Include/openssl/evp.h
new file mode 100644 (file)
index 0000000..ad1e350
--- /dev/null
@@ -0,0 +1,1536 @@
+/* crypto/evp/evp.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_ENVELOPE_H
+# define HEADER_ENVELOPE_H
+
+# ifdef OPENSSL_ALGORITHM_DEFINES
+#  include <openssl/opensslconf.h>
+# else
+#  define OPENSSL_ALGORITHM_DEFINES
+#  include <openssl/opensslconf.h>
+#  undef OPENSSL_ALGORITHM_DEFINES
+# endif
+
+# include <openssl/ossl_typ.h>
+
+# include <openssl/symhacks.h>
+
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+
+/*-
+#define EVP_RC2_KEY_SIZE                16
+#define EVP_RC4_KEY_SIZE                16
+#define EVP_BLOWFISH_KEY_SIZE           16
+#define EVP_CAST5_KEY_SIZE              16
+#define EVP_RC5_32_12_16_KEY_SIZE       16
+*/
+# define EVP_MAX_MD_SIZE                 64/* longest known is SHA512 */
+# define EVP_MAX_KEY_LENGTH              64
+# define EVP_MAX_IV_LENGTH               16
+# define EVP_MAX_BLOCK_LENGTH            32
+
+# define PKCS5_SALT_LEN                  8
+/* Default PKCS#5 iteration count */
+# define PKCS5_DEFAULT_ITER              2048
+
+# include <openssl/objects.h>
+
+# define EVP_PK_RSA      0x0001
+# define EVP_PK_DSA      0x0002
+# define EVP_PK_DH       0x0004
+# define EVP_PK_EC       0x0008
+# define EVP_PKT_SIGN    0x0010
+# define EVP_PKT_ENC     0x0020
+# define EVP_PKT_EXCH    0x0040
+# define EVP_PKS_RSA     0x0100
+# define EVP_PKS_DSA     0x0200
+# define EVP_PKS_EC      0x0400
+
+# define EVP_PKEY_NONE   NID_undef
+# define EVP_PKEY_RSA    NID_rsaEncryption
+# define EVP_PKEY_RSA2   NID_rsa
+# define EVP_PKEY_DSA    NID_dsa
+# define EVP_PKEY_DSA1   NID_dsa_2
+# define EVP_PKEY_DSA2   NID_dsaWithSHA
+# define EVP_PKEY_DSA3   NID_dsaWithSHA1
+# define EVP_PKEY_DSA4   NID_dsaWithSHA1_2
+# define EVP_PKEY_DH     NID_dhKeyAgreement
+# define EVP_PKEY_DHX    NID_dhpublicnumber
+# define EVP_PKEY_EC     NID_X9_62_id_ecPublicKey
+# define EVP_PKEY_HMAC   NID_hmac
+# define EVP_PKEY_CMAC   NID_cmac
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type needs to be a bit field Sub-type needs to be for variations on the
+ * method, as in, can it do arbitrary encryption....
+ */
+struct evp_pkey_st {
+    int type;
+    int save_type;
+    int references;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *engine;
+    union {
+        char *ptr;
+# ifndef OPENSSL_NO_RSA
+        struct rsa_st *rsa;     /* RSA */
+# endif
+# ifndef OPENSSL_NO_DSA
+        struct dsa_st *dsa;     /* DSA */
+# endif
+# ifndef OPENSSL_NO_DH
+        struct dh_st *dh;       /* DH */
+# endif
+# ifndef OPENSSL_NO_EC
+        struct ec_key_st *ec;   /* ECC */
+# endif
+    } pkey;
+    int save_parameters;
+    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+} /* EVP_PKEY */ ;
+
+# define EVP_PKEY_MO_SIGN        0x0001
+# define EVP_PKEY_MO_VERIFY      0x0002
+# define EVP_PKEY_MO_ENCRYPT     0x0004
+# define EVP_PKEY_MO_DECRYPT     0x0008
+
+# ifndef EVP_MD
+struct env_md_st {
+    int type;
+    int pkey_type;
+    int md_size;
+    unsigned long flags;
+    int (*init) (EVP_MD_CTX *ctx);
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
+    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
+    int (*cleanup) (EVP_MD_CTX *ctx);
+    /* FIXME: prototype these some day */
+    int (*sign) (int type, const unsigned char *m, unsigned int m_length,
+                 unsigned char *sigret, unsigned int *siglen, void *key);
+    int (*verify) (int type, const unsigned char *m, unsigned int m_length,
+                   const unsigned char *sigbuf, unsigned int siglen,
+                   void *key);
+    int required_pkey_type[5];  /* EVP_PKEY_xxx */
+    int block_size;
+    int ctx_size;               /* how big does the ctx->md_data need to be */
+    /* control function */
+    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+} /* EVP_MD */ ;
+
+typedef int evp_sign_method(int type, const unsigned char *m,
+                            unsigned int m_length, unsigned char *sigret,
+                            unsigned int *siglen, void *key);
+typedef int evp_verify_method(int type, const unsigned char *m,
+                              unsigned int m_length,
+                              const unsigned char *sigbuf,
+                              unsigned int siglen, void *key);
+
+/* digest can only handle a single block */
+#  define EVP_MD_FLAG_ONESHOT     0x0001
+
+/*
+ * digest is a "clone" digest used
+ * which is a copy of an existing
+ * one for a specific public key type.
+ * EVP_dss1() etc
+ */
+#  define EVP_MD_FLAG_PKEY_DIGEST 0x0002
+
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+#  define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE       0x0004
+
+/* DigestAlgorithmIdentifier flags... */
+
+#  define EVP_MD_FLAG_DIGALGID_MASK               0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+#  define EVP_MD_FLAG_DIGALGID_NULL               0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+#  define EVP_MD_FLAG_DIGALGID_ABSENT             0x0008
+
+/* Custom handling via ctrl */
+
+#  define EVP_MD_FLAG_DIGALGID_CUSTOM             0x0018
+
+/* Note if suitable for use in FIPS mode */
+#  define EVP_MD_FLAG_FIPS        0x0400
+
+/* Digest ctrls */
+
+#  define EVP_MD_CTRL_DIGALGID                    0x1
+#  define EVP_MD_CTRL_MICALG                      0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+#  define EVP_MD_CTRL_ALG_CTRL                    0x1000
+
+#  define EVP_PKEY_NULL_method    NULL,NULL,{0,0,0,0}
+
+#  ifndef OPENSSL_NO_DSA
+#   define EVP_PKEY_DSA_method     (evp_sign_method *)DSA_sign, \
+                                (evp_verify_method *)DSA_verify, \
+                                {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+                                        EVP_PKEY_DSA4,0}
+#  else
+#   define EVP_PKEY_DSA_method     EVP_PKEY_NULL_method
+#  endif
+
+#  ifndef OPENSSL_NO_ECDSA
+#   define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
+                                (evp_verify_method *)ECDSA_verify, \
+                                 {EVP_PKEY_EC,0,0,0}
+#  else
+#   define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
+#  endif
+
+#  ifndef OPENSSL_NO_RSA
+#   define EVP_PKEY_RSA_method     (evp_sign_method *)RSA_sign, \
+                                (evp_verify_method *)RSA_verify, \
+                                {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#   define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+                                (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
+                                (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
+                                {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#  else
+#   define EVP_PKEY_RSA_method     EVP_PKEY_NULL_method
+#   define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#  endif
+
+# endif                         /* !EVP_MD */
+
+struct env_md_ctx_st {
+    const EVP_MD *digest;
+    ENGINE *engine;             /* functional reference if 'digest' is
+                                 * ENGINE-provided */
+    unsigned long flags;
+    void *md_data;
+    /* Public key context for sign/verify */
+    EVP_PKEY_CTX *pctx;
+    /* Update function: usually copied from EVP_MD */
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+} /* EVP_MD_CTX */ ;
+
+/* values for EVP_MD_CTX flags */
+
+# define EVP_MD_CTX_FLAG_ONESHOT         0x0001/* digest update will be
+                                                * called once only */
+# define EVP_MD_CTX_FLAG_CLEANED         0x0002/* context has already been
+                                                * cleaned */
+# define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
+                                                * in EVP_MD_CTX_cleanup */
+/*
+ * FIPS and pad options are ignored in 1.0.0, definitions are here so we
+ * don't accidentally reuse the values for other purposes.
+ */
+
+# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008/* Allow use of non FIPS
+                                                * digest in FIPS mode */
+
+/*
+ * The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
+# define EVP_MD_CTX_FLAG_PAD_MASK        0xF0/* RSA mode to use */
+# define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
+# define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
+# define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */
+
+# define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */
+
+struct evp_cipher_st {
+    int nid;
+    int block_size;
+    /* Default value for variable length ciphers */
+    int key_len;
+    int iv_len;
+    /* Various flags */
+    unsigned long flags;
+    /* init key */
+    int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                 const unsigned char *iv, int enc);
+    /* encrypt/decrypt data */
+    int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
+                      const unsigned char *in, size_t inl);
+    /* cleanup ctx */
+    int (*cleanup) (EVP_CIPHER_CTX *);
+    /* how big ctx->cipher_data needs to be */
+    int ctx_size;
+    /* Populate a ASN1_TYPE with parameters */
+    int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+    /* Get parameters from a ASN1_TYPE */
+    int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+    /* Miscellaneous operations */
+    int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
+    /* Application data */
+    void *app_data;
+} /* EVP_CIPHER */ ;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+# define         EVP_CIPH_STREAM_CIPHER          0x0
+# define         EVP_CIPH_ECB_MODE               0x1
+# define         EVP_CIPH_CBC_MODE               0x2
+# define         EVP_CIPH_CFB_MODE               0x3
+# define         EVP_CIPH_OFB_MODE               0x4
+# define         EVP_CIPH_CTR_MODE               0x5
+# define         EVP_CIPH_GCM_MODE               0x6
+# define         EVP_CIPH_CCM_MODE               0x7
+# define         EVP_CIPH_XTS_MODE               0x10001
+# define         EVP_CIPH_WRAP_MODE              0x10002
+# define         EVP_CIPH_MODE                   0xF0007
+/* Set if variable length cipher */
+# define         EVP_CIPH_VARIABLE_LENGTH        0x8
+/* Set if the iv handling should be done by the cipher itself */
+# define         EVP_CIPH_CUSTOM_IV              0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+# define         EVP_CIPH_ALWAYS_CALL_INIT       0x20
+/* Call ctrl() to init cipher parameters */
+# define         EVP_CIPH_CTRL_INIT              0x40
+/* Don't use standard key length function */
+# define         EVP_CIPH_CUSTOM_KEY_LENGTH      0x80
+/* Don't use standard block padding */
+# define         EVP_CIPH_NO_PADDING             0x100
+/* cipher handles random key generation */
+# define         EVP_CIPH_RAND_KEY               0x200
+/* cipher has its own additional copying logic */
+# define         EVP_CIPH_CUSTOM_COPY            0x400
+/* Allow use default ASN1 get/set iv */
+# define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
+/* Buffer length in bits not bytes: CFB1 mode only */
+# define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
+/* Note if suitable for use in FIPS mode */
+# define         EVP_CIPH_FLAG_FIPS              0x4000
+/* Allow non FIPS cipher in FIPS mode */
+# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x8000
+/*
+ * Cipher handles any and all padding logic as well as finalisation.
+ */
+# define         EVP_CIPH_FLAG_CUSTOM_CIPHER     0x100000
+# define         EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
+# define         EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000
+
+/*
+ * Cipher context flag to indicate we can handle wrap mode: if allowed in
+ * older applications it could overflow buffers.
+ */
+
+# define         EVP_CIPHER_CTX_FLAG_WRAP_ALLOW  0x1
+
+/* ctrl() values */
+
+# define         EVP_CTRL_INIT                   0x0
+# define         EVP_CTRL_SET_KEY_LENGTH         0x1
+# define         EVP_CTRL_GET_RC2_KEY_BITS       0x2
+# define         EVP_CTRL_SET_RC2_KEY_BITS       0x3
+# define         EVP_CTRL_GET_RC5_ROUNDS         0x4
+# define         EVP_CTRL_SET_RC5_ROUNDS         0x5
+# define         EVP_CTRL_RAND_KEY               0x6
+# define         EVP_CTRL_PBE_PRF_NID            0x7
+# define         EVP_CTRL_COPY                   0x8
+# define         EVP_CTRL_GCM_SET_IVLEN          0x9
+# define         EVP_CTRL_GCM_GET_TAG            0x10
+# define         EVP_CTRL_GCM_SET_TAG            0x11
+# define         EVP_CTRL_GCM_SET_IV_FIXED       0x12
+# define         EVP_CTRL_GCM_IV_GEN             0x13
+# define         EVP_CTRL_CCM_SET_IVLEN          EVP_CTRL_GCM_SET_IVLEN
+# define         EVP_CTRL_CCM_GET_TAG            EVP_CTRL_GCM_GET_TAG
+# define         EVP_CTRL_CCM_SET_TAG            EVP_CTRL_GCM_SET_TAG
+# define         EVP_CTRL_CCM_SET_L              0x14
+# define         EVP_CTRL_CCM_SET_MSGLEN         0x15
+/*
+ * AEAD cipher deduces payload length and returns number of bytes required to
+ * store MAC and eventual padding. Subsequent call to EVP_Cipher even
+ * appends/verifies MAC.
+ */
+# define         EVP_CTRL_AEAD_TLS1_AAD          0x16
+/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
+# define         EVP_CTRL_AEAD_SET_MAC_KEY       0x17
+/* Set the GCM invocation field, decrypt only */
+# define         EVP_CTRL_GCM_SET_IV_INV         0x18
+
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_AAD  0x19
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT      0x1a
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT      0x1b
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE  0x1c
+
+/* RFC 5246 defines additional data to be 13 bytes in length */
+# define         EVP_AEAD_TLS1_AAD_LEN           13
+
+typedef struct {
+    unsigned char *out;
+    const unsigned char *inp;
+    size_t len;
+    unsigned int interleave;
+} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM;
+
+/* GCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+# define EVP_GCM_TLS_FIXED_IV_LEN                        4
+/* Length of explicit part of IV part of TLS records */
+# define EVP_GCM_TLS_EXPLICIT_IV_LEN                     8
+/* Length of tag for TLS */
+# define EVP_GCM_TLS_TAG_LEN                             16
+
+typedef struct evp_cipher_info_st {
+    const EVP_CIPHER *cipher;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+} EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st {
+    const EVP_CIPHER *cipher;
+    ENGINE *engine;             /* functional reference if 'cipher' is
+                                 * ENGINE-provided */
+    int encrypt;                /* encrypt or decrypt */
+    int buf_len;                /* number we have left */
+    unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
+    unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
+    unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
+    int num;                    /* used by cfb/ofb/ctr mode */
+    void *app_data;             /* application stuff */
+    int key_len;                /* May change for variable length cipher */
+    unsigned long flags;        /* Various flags */
+    void *cipher_data;          /* per EVP data */
+    int final_used;
+    int block_mask;
+    unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
+} /* EVP_CIPHER_CTX */ ;
+
+typedef struct evp_Encode_Ctx_st {
+    /* number saved in a partial encode/decode */
+    int num;
+    /*
+     * The length is either the output line length (in input bytes) or the
+     * shortest input line length that is ok.  Once decoding begins, the
+     * length is adjusted up each time a longer line is decoded
+     */
+    int length;
+    /* data to encode */
+    unsigned char enc_data[80];
+    /* number read on current line */
+    int line_num;
+    int expect_nl;
+} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
+                              int passlen, ASN1_TYPE *param,
+                              const EVP_CIPHER *cipher, const EVP_MD *md,
+                              int en_de);
+
+# ifndef OPENSSL_NO_RSA
+#  define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+                                        (char *)(rsa))
+# endif
+
+# ifndef OPENSSL_NO_DSA
+#  define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+                                        (char *)(dsa))
+# endif
+
+# ifndef OPENSSL_NO_DH
+#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+                                        (char *)(dh))
+# endif
+
+# ifndef OPENSSL_NO_EC
+#  define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                        (char *)(eckey))
+# endif
+
+/* Add some extra combinations */
+# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+int EVP_MD_type(const EVP_MD *md);
+# define EVP_MD_nid(e)                   EVP_MD_type(e)
+# define EVP_MD_name(e)                  OBJ_nid2sn(EVP_MD_nid(e))
+int EVP_MD_pkey_type(const EVP_MD *md);
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+# define EVP_MD_CTX_size(e)              EVP_MD_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_block_size(e)        EVP_MD_block_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_type(e)              EVP_MD_type(EVP_MD_CTX_md(e))
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_name(e)              OBJ_nid2sn(EVP_CIPHER_nid(e))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_mode(e)              (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+# define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+# define EVP_CIPHER_CTX_mode(e)          (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
+
+# define EVP_ENCODE_LENGTH(l)    (((l+2)/3*4)+(l/48+1)*2+80)
+# define EVP_DECODE_LENGTH(l)    ((l+3)/4*3+80)
+
+# define EVP_SignInit_ex(a,b,c)          EVP_DigestInit_ex(a,b,c)
+# define EVP_SignInit(a,b)               EVP_DigestInit(a,b)
+# define EVP_SignUpdate(a,b,c)           EVP_DigestUpdate(a,b,c)
+# define EVP_VerifyInit_ex(a,b,c)        EVP_DigestInit_ex(a,b,c)
+# define EVP_VerifyInit(a,b)             EVP_DigestInit(a,b)
+# define EVP_VerifyUpdate(a,b,c)         EVP_DigestUpdate(a,b,c)
+# define EVP_OpenUpdate(a,b,c,d,e)       EVP_DecryptUpdate(a,b,c,d,e)
+# define EVP_SealUpdate(a,b,c,d,e)       EVP_EncryptUpdate(a,b,c,d,e)
+# define EVP_DigestSignUpdate(a,b,c)     EVP_DigestUpdate(a,b,c)
+# define EVP_DigestVerifyUpdate(a,b,c)   EVP_DigestUpdate(a,b,c)
+
+# ifdef CONST_STRICT
+void BIO_set_md(BIO *, const EVP_MD *md);
+# else
+#  define BIO_set_md(b,md)               BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+# endif
+# define BIO_get_md(b,mdp)               BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
+# define BIO_get_cipher_status(b)        BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+# define BIO_get_cipher_ctx(b,c_pp)      BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+int EVP_Cipher(EVP_CIPHER_CTX *c,
+               unsigned char *out, const unsigned char *in, unsigned int inl);
+
+# define EVP_add_cipher_alias(n,alias) \
+        OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_add_digest_alias(n,alias) \
+        OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_delete_cipher_alias(alias) \
+        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+# define EVP_delete_digest_alias(alias) \
+        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
+int EVP_Digest(const void *data, size_t count,
+               unsigned char *md, unsigned int *size, const EVP_MD *type,
+               ENGINE *impl);
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
+
+#ifndef OPENSSL_NO_UI
+int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify);
+int EVP_read_pw_string_min(char *buf, int minlen, int maxlen,
+                           const char *prompt, int verify);
+void EVP_set_pw_prompt(const char *prompt);
+char *EVP_get_pw_prompt(void);
+#endif
+
+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);
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                    const unsigned char *key, const unsigned char *iv);
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                       ENGINE *impl, const unsigned char *key,
+                       const unsigned char *iv);
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl);
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                    const unsigned char *key, const unsigned char *iv);
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                       ENGINE *impl, const unsigned char *key,
+                       const unsigned char *iv);
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl);
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                   const unsigned char *key, const unsigned char *iv,
+                   int 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);
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl);
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
+                  EVP_PKEY *pkey);
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+                    unsigned int siglen, EVP_PKEY *pkey);
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                       const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
+                        unsigned char *sigret, size_t *siglen);
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
+                          const unsigned char *sig, size_t siglen);
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                 const unsigned char *ek, int ekl, const unsigned char *iv,
+                 EVP_PKEY *priv);
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                 unsigned char **ek, int *ekl, unsigned char *iv,
+                 EVP_PKEY **pubk, int npubk);
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl);
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl);
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+                    char *out, int *outl);
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+# ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+                    const unsigned char *i, int enc);
+# endif
+
+const EVP_MD *EVP_md_null(void);
+# ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+# endif
+# ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+# endif
+# ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+# endif
+# ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_dss(void);
+const EVP_MD *EVP_dss1(void);
+const EVP_MD *EVP_ecdsa(void);
+# endif
+# ifndef OPENSSL_NO_SHA256
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+# endif
+# ifndef OPENSSL_NO_SHA512
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+# endif
+# ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+# endif
+# ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void);
+# endif
+# ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+# endif
+const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
+# ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+#  define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+#  define EVP_des_ede_cfb EVP_des_ede_cfb64
+#  if 0
+const EVP_CIPHER *EVP_des_ede_cfb1(void);
+const EVP_CIPHER *EVP_des_ede_cfb8(void);
+#  endif
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+#  define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_wrap(void);
+/*
+ * This should now be supported through the dev_crypto ENGINE. But also, why
+ * are rc4 and md5 declarations made here inside a "NO_DES" precompiler
+ * branch?
+ */
+#  if 0
+#   ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_dev_crypto_rc4(void);
+const EVP_MD *EVP_dev_crypto_md5(void);
+#   endif
+#  endif
+# endif
+# ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+#  ifndef OPENSSL_NO_MD5
+const EVP_CIPHER *EVP_rc4_hmac_md5(void);
+#  endif
+# endif
+# ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+#  define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+# endif
+# ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+#  define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+# endif
+# ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+#  define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+# endif
+# ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+#  define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+# endif
+# ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+#  define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+# endif
+# ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+#  define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
+const EVP_CIPHER *EVP_aes_128_wrap(void);
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+#  define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
+const EVP_CIPHER *EVP_aes_192_wrap(void);
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+#  define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
+const EVP_CIPHER *EVP_aes_256_wrap(void);
+#  if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
+#  endif
+#  ifndef OPENSSL_NO_SHA256
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);
+#  endif
+# endif
+# ifndef OPENSSL_NO_CAMELLIA
+const EVP_CIPHER *EVP_camellia_128_ecb(void);
+const EVP_CIPHER *EVP_camellia_128_cbc(void);
+const EVP_CIPHER *EVP_camellia_128_cfb1(void);
+const EVP_CIPHER *EVP_camellia_128_cfb8(void);
+const EVP_CIPHER *EVP_camellia_128_cfb128(void);
+#  define EVP_camellia_128_cfb EVP_camellia_128_cfb128
+const EVP_CIPHER *EVP_camellia_128_ofb(void);
+const EVP_CIPHER *EVP_camellia_192_ecb(void);
+const EVP_CIPHER *EVP_camellia_192_cbc(void);
+const EVP_CIPHER *EVP_camellia_192_cfb1(void);
+const EVP_CIPHER *EVP_camellia_192_cfb8(void);
+const EVP_CIPHER *EVP_camellia_192_cfb128(void);
+#  define EVP_camellia_192_cfb EVP_camellia_192_cfb128
+const EVP_CIPHER *EVP_camellia_192_ofb(void);
+const EVP_CIPHER *EVP_camellia_256_ecb(void);
+const EVP_CIPHER *EVP_camellia_256_cbc(void);
+const EVP_CIPHER *EVP_camellia_256_cfb1(void);
+const EVP_CIPHER *EVP_camellia_256_cfb8(void);
+const EVP_CIPHER *EVP_camellia_256_cfb128(void);
+#  define EVP_camellia_256_cfb EVP_camellia_256_cfb128
+const EVP_CIPHER *EVP_camellia_256_ofb(void);
+# endif
+
+# ifndef OPENSSL_NO_SEED
+const EVP_CIPHER *EVP_seed_ecb(void);
+const EVP_CIPHER *EVP_seed_cbc(void);
+const EVP_CIPHER *EVP_seed_cfb128(void);
+#  define EVP_seed_cfb EVP_seed_cfb128
+const EVP_CIPHER *EVP_seed_ofb(void);
+# endif
+
+void OPENSSL_add_all_algorithms_noconf(void);
+void OPENSSL_add_all_algorithms_conf(void);
+
+# ifdef OPENSSL_LOAD_CONF
+#  define OpenSSL_add_all_algorithms() \
+                OPENSSL_add_all_algorithms_conf()
+# else
+#  define OpenSSL_add_all_algorithms() \
+                OPENSSL_add_all_algorithms_noconf()
+# endif
+
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+# define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
+                                   const char *from, const char *to, void *x),
+                       void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)
+                               (const EVP_CIPHER *ciph, const char *from,
+                                const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph,
+                               const char *from, const char *to, void *x),
+                   void *arg);
+void EVP_MD_do_all_sorted(void (*fn)
+                           (const EVP_MD *ciph, const char *from,
+                            const char *to, void *x), void *arg);
+
+int EVP_PKEY_decrypt_old(unsigned char *dec_key,
+                         const unsigned char *enc_key, int enc_key_len,
+                         EVP_PKEY *private_key);
+int EVP_PKEY_encrypt_old(unsigned char *enc_key,
+                         const unsigned char *key, int key_len,
+                         EVP_PKEY *pub_key);
+int EVP_PKEY_type(int type);
+int EVP_PKEY_id(const EVP_PKEY *pkey);
+int EVP_PKEY_base_id(const EVP_PKEY *pkey);
+int EVP_PKEY_bits(EVP_PKEY *pkey);
+int EVP_PKEY_size(EVP_PKEY *pkey);
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
+void *EVP_PKEY_get0(EVP_PKEY *pkey);
+
+# ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+# endif
+
+EVP_PKEY *EVP_PKEY_new(void);
+void EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                        long length);
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                         long length);
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+                             long length);
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+                           int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_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);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+                           const unsigned char *salt, int saltlen, int iter,
+                           int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+                      const unsigned char *salt, int saltlen, int iter,
+                      const EVP_MD *digest, int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                          const EVP_MD *md, int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+# define EVP_PBE_TYPE_OUTER      0x0
+/* Is an PRF type OID */
+# define EVP_PBE_TYPE_PRF        0x1
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
+                         int md_nid, EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+                    EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
+                 EVP_PBE_KEYGEN **pkeygen);
+void EVP_PBE_cleanup(void);
+
+# define ASN1_PKEY_ALIAS         0x1
+# define ASN1_PKEY_DYNAMIC       0x2
+# define ASN1_PKEY_SIGPARAM_NULL 0x4
+
+# define ASN1_PKEY_CTRL_PKCS7_SIGN       0x1
+# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT    0x2
+# define ASN1_PKEY_CTRL_DEFAULT_MD_NID   0x3
+# define ASN1_PKEY_CTRL_CMS_SIGN         0x5
+# define ASN1_PKEY_CTRL_CMS_ENVELOPE     0x7
+# define ASN1_PKEY_CTRL_CMS_RI_TYPE      0x8
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+                                                   const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id,
+                            int *ppkey_flags, const char **pinfo,
+                            const char **ppem_str,
+                            const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+                                        const char *pem_str,
+                                        const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+                        const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+                              int (*pub_decode) (EVP_PKEY *pk,
+                                                 X509_PUBKEY *pub),
+                              int (*pub_encode) (X509_PUBKEY *pub,
+                                                 const EVP_PKEY *pk),
+                              int (*pub_cmp) (const EVP_PKEY *a,
+                                              const EVP_PKEY *b),
+                              int (*pub_print) (BIO *out,
+                                                const EVP_PKEY *pkey,
+                                                int indent, ASN1_PCTX *pctx),
+                              int (*pkey_size) (const EVP_PKEY *pk),
+                              int (*pkey_bits) (const EVP_PKEY *pk));
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+                               int (*priv_decode) (EVP_PKEY *pk,
+                                                   PKCS8_PRIV_KEY_INFO
+                                                   *p8inf),
+                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+                                                   const EVP_PKEY *pk),
+                               int (*priv_print) (BIO *out,
+                                                  const EVP_PKEY *pkey,
+                                                  int indent,
+                                                  ASN1_PCTX *pctx));
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+                             int (*param_decode) (EVP_PKEY *pkey,
+                                                  const unsigned char **pder,
+                                                  int derlen),
+                             int (*param_encode) (const EVP_PKEY *pkey,
+                                                  unsigned char **pder),
+                             int (*param_missing) (const EVP_PKEY *pk),
+                             int (*param_copy) (EVP_PKEY *to,
+                                                const EVP_PKEY *from),
+                             int (*param_cmp) (const EVP_PKEY *a,
+                                               const EVP_PKEY *b),
+                             int (*param_print) (BIO *out,
+                                                 const EVP_PKEY *pkey,
+                                                 int indent,
+                                                 ASN1_PCTX *pctx));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+                            void (*pkey_free) (EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+                                              long arg1, void *arg2));
+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));
+
+# define EVP_PKEY_OP_UNDEFINED           0
+# define EVP_PKEY_OP_PARAMGEN            (1<<1)
+# define EVP_PKEY_OP_KEYGEN              (1<<2)
+# define EVP_PKEY_OP_SIGN                (1<<3)
+# define EVP_PKEY_OP_VERIFY              (1<<4)
+# define EVP_PKEY_OP_VERIFYRECOVER       (1<<5)
+# define EVP_PKEY_OP_SIGNCTX             (1<<6)
+# define EVP_PKEY_OP_VERIFYCTX           (1<<7)
+# define EVP_PKEY_OP_ENCRYPT             (1<<8)
+# define EVP_PKEY_OP_DECRYPT             (1<<9)
+# define EVP_PKEY_OP_DERIVE              (1<<10)
+
+# define EVP_PKEY_OP_TYPE_SIG    \
+        (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+                | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+# define EVP_PKEY_OP_TYPE_CRYPT \
+        (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+# define EVP_PKEY_OP_TYPE_NOGEN \
+        (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
+
+# define EVP_PKEY_OP_TYPE_GEN \
+                (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+# define  EVP_PKEY_CTX_set_signature_md(ctx, md) \
+                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+                                        EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_get_signature_md(ctx, pmd)        \
+                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+                                        EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTRL_MD                1
+# define EVP_PKEY_CTRL_PEER_KEY          2
+
+# define EVP_PKEY_CTRL_PKCS7_ENCRYPT     3
+# define EVP_PKEY_CTRL_PKCS7_DECRYPT     4
+
+# define EVP_PKEY_CTRL_PKCS7_SIGN        5
+
+# define EVP_PKEY_CTRL_SET_MAC_KEY       6
+
+# define EVP_PKEY_CTRL_DIGESTINIT        7
+
+/* Used by GOST key encryption in TLS */
+# define EVP_PKEY_CTRL_SET_IV            8
+
+# define EVP_PKEY_CTRL_CMS_ENCRYPT       9
+# define EVP_PKEY_CTRL_CMS_DECRYPT       10
+# define EVP_PKEY_CTRL_CMS_SIGN          11
+
+# define EVP_PKEY_CTRL_CIPHER            12
+
+# define EVP_PKEY_CTRL_GET_MD            13
+
+# define EVP_PKEY_ALG_CTRL               0x1000
+
+# define EVP_PKEY_FLAG_AUTOARGLEN        2
+/*
+ * Method handles all operations: don't assume any digest related defaults.
+ */
+# define EVP_PKEY_FLAG_SIGCTX_CUSTOM     4
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+                             const EVP_PKEY_METHOD *meth);
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+                      int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+                          const char *value);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+                               const unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+                  unsigned char *sig, size_t *siglen,
+                  const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+                    const unsigned char *sig, size_t siglen,
+                    const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+                            unsigned char *rout, size_t *routlen,
+                            const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+                            int (*init) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+                            int (*copy) (EVP_PKEY_CTX *dst,
+                                         EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+                               void (*cleanup) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+                                int (*paramgen) (EVP_PKEY_CTX *ctx,
+                                                 EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
+                              int (*keygen) (EVP_PKEY_CTX *ctx,
+                                             EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+                            int (*sign_init) (EVP_PKEY_CTX *ctx),
+                            int (*sign) (EVP_PKEY_CTX *ctx,
+                                         unsigned char *sig, size_t *siglen,
+                                         const unsigned char *tbs,
+                                         size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+                              int (*verify_init) (EVP_PKEY_CTX *ctx),
+                              int (*verify) (EVP_PKEY_CTX *ctx,
+                                             const unsigned char *sig,
+                                             size_t siglen,
+                                             const unsigned char *tbs,
+                                             size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+                                      int (*verify_recover_init) (EVP_PKEY_CTX
+                                                                  *ctx),
+                                      int (*verify_recover) (EVP_PKEY_CTX
+                                                             *ctx,
+                                                             unsigned char
+                                                             *sig,
+                                                             size_t *siglen,
+                                                             const unsigned
+                                                             char *tbs,
+                                                             size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
+                                                    EVP_MD_CTX *mctx),
+                               int (*signctx) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *sig,
+                                               size_t *siglen,
+                                               EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+                                                        EVP_MD_CTX *mctx),
+                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
+                                                   const unsigned char *sig,
+                                                   int siglen,
+                                                   EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *out,
+                                                 size_t *outlen,
+                                                 const unsigned char *in,
+                                                 size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*decrypt) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *out,
+                                               size_t *outlen,
+                                               const unsigned char *in,
+                                               size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+                              int (*derive_init) (EVP_PKEY_CTX *ctx),
+                              int (*derive) (EVP_PKEY_CTX *ctx,
+                                             unsigned char *key,
+                                             size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+                                         void *p2),
+                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+                                             const char *type,
+                                             const char *value));
+
+void EVP_add_alg_module(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+# define EVP_F_AESNI_INIT_KEY                             165
+# define EVP_F_AESNI_XTS_CIPHER                           176
+# define EVP_F_AES_INIT_KEY                               133
+# define EVP_F_AES_T4_INIT_KEY                            178
+# define EVP_F_AES_XTS                                    172
+# define EVP_F_AES_XTS_CIPHER                             175
+# define EVP_F_ALG_MODULE_INIT                            177
+# define EVP_F_CAMELLIA_INIT_KEY                          159
+# define EVP_F_CMAC_INIT                                  173
+# define EVP_F_CMLL_T4_INIT_KEY                           179
+# define EVP_F_D2I_PKEY                                   100
+# define EVP_F_DO_SIGVER_INIT                             161
+# define EVP_F_DSAPKEY2PKCS8                              134
+# define EVP_F_DSA_PKEY2PKCS8                             135
+# define EVP_F_ECDSA_PKEY2PKCS8                           129
+# define EVP_F_ECKEY_PKEY2PKCS8                           132
+# define EVP_F_EVP_CIPHERINIT_EX                          123
+# define EVP_F_EVP_CIPHER_CTX_COPY                        163
+# define EVP_F_EVP_CIPHER_CTX_CTRL                        124
+# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH              122
+# define EVP_F_EVP_DECRYPTFINAL_EX                        101
+# define EVP_F_EVP_DIGESTINIT_EX                          128
+# define EVP_F_EVP_ENCRYPTFINAL_EX                        127
+# define EVP_F_EVP_MD_CTX_COPY_EX                         110
+# define EVP_F_EVP_MD_SIZE                                162
+# define EVP_F_EVP_OPENINIT                               102
+# define EVP_F_EVP_PBE_ALG_ADD                            115
+# define EVP_F_EVP_PBE_ALG_ADD_TYPE                       160
+# define EVP_F_EVP_PBE_CIPHERINIT                         116
+# define EVP_F_EVP_PKCS82PKEY                             111
+# define EVP_F_EVP_PKCS82PKEY_BROKEN                      136
+# define EVP_F_EVP_PKEY2PKCS8_BROKEN                      113
+# define EVP_F_EVP_PKEY_COPY_PARAMETERS                   103
+# define EVP_F_EVP_PKEY_CTX_CTRL                          137
+# define EVP_F_EVP_PKEY_CTX_CTRL_STR                      150
+# define EVP_F_EVP_PKEY_CTX_DUP                           156
+# define EVP_F_EVP_PKEY_DECRYPT                           104
+# define EVP_F_EVP_PKEY_DECRYPT_INIT                      138
+# define EVP_F_EVP_PKEY_DECRYPT_OLD                       151
+# define EVP_F_EVP_PKEY_DERIVE                            153
+# define EVP_F_EVP_PKEY_DERIVE_INIT                       154
+# define EVP_F_EVP_PKEY_DERIVE_SET_PEER                   155
+# define EVP_F_EVP_PKEY_ENCRYPT                           105
+# define EVP_F_EVP_PKEY_ENCRYPT_INIT                      139
+# define EVP_F_EVP_PKEY_ENCRYPT_OLD                       152
+# define EVP_F_EVP_PKEY_GET1_DH                           119
+# define EVP_F_EVP_PKEY_GET1_DSA                          120
+# define EVP_F_EVP_PKEY_GET1_ECDSA                        130
+# define EVP_F_EVP_PKEY_GET1_EC_KEY                       131
+# define EVP_F_EVP_PKEY_GET1_RSA                          121
+# define EVP_F_EVP_PKEY_KEYGEN                            146
+# define EVP_F_EVP_PKEY_KEYGEN_INIT                       147
+# define EVP_F_EVP_PKEY_NEW                               106
+# define EVP_F_EVP_PKEY_PARAMGEN                          148
+# define EVP_F_EVP_PKEY_PARAMGEN_INIT                     149
+# define EVP_F_EVP_PKEY_SIGN                              140
+# define EVP_F_EVP_PKEY_SIGN_INIT                         141
+# define EVP_F_EVP_PKEY_VERIFY                            142
+# define EVP_F_EVP_PKEY_VERIFY_INIT                       143
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER                    144
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT               145
+# define EVP_F_EVP_RIJNDAEL                               126
+# define EVP_F_EVP_SIGNFINAL                              107
+# define EVP_F_EVP_VERIFYFINAL                            108
+# define EVP_F_FIPS_CIPHERINIT                            166
+# define EVP_F_FIPS_CIPHER_CTX_COPY                       170
+# define EVP_F_FIPS_CIPHER_CTX_CTRL                       167
+# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH             171
+# define EVP_F_FIPS_DIGESTINIT                            168
+# define EVP_F_FIPS_MD_CTX_COPY                           169
+# define EVP_F_HMAC_INIT_EX                               174
+# define EVP_F_INT_CTX_NEW                                157
+# define EVP_F_PKCS5_PBE_KEYIVGEN                         117
+# define EVP_F_PKCS5_V2_PBE_KEYIVGEN                      118
+# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN                   164
+# define EVP_F_PKCS8_SET_BROKEN                           112
+# define EVP_F_PKEY_SET_TYPE                              158
+# define EVP_F_RC2_MAGIC_TO_METH                          109
+# define EVP_F_RC5_CTRL                                   125
+
+/* Reason codes. */
+# define EVP_R_AES_IV_SETUP_FAILED                        162
+# define EVP_R_AES_KEY_SETUP_FAILED                       143
+# define EVP_R_ASN1_LIB                                   140
+# define EVP_R_BAD_BLOCK_LENGTH                           136
+# define EVP_R_BAD_DECRYPT                                100
+# define EVP_R_BAD_KEY_LENGTH                             137
+# define EVP_R_BN_DECODE_ERROR                            112
+# define EVP_R_BN_PUBKEY_ERROR                            113
+# define EVP_R_BUFFER_TOO_SMALL                           155
+# define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
+# define EVP_R_CIPHER_PARAMETER_ERROR                     122
+# define EVP_R_COMMAND_NOT_SUPPORTED                      147
+# define EVP_R_CTRL_NOT_IMPLEMENTED                       132
+# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED             133
+# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH          138
+# define EVP_R_DECODE_ERROR                               114
+# define EVP_R_DIFFERENT_KEY_TYPES                        101
+# define EVP_R_DIFFERENT_PARAMETERS                       153
+# define EVP_R_DISABLED_FOR_FIPS                          163
+# define EVP_R_ENCODE_ERROR                               115
+# define EVP_R_ERROR_LOADING_SECTION                      165
+# define EVP_R_ERROR_SETTING_FIPS_MODE                    166
+# define EVP_R_EVP_PBE_CIPHERINIT_ERROR                   119
+# define EVP_R_EXPECTING_AN_RSA_KEY                       127
+# define EVP_R_EXPECTING_A_DH_KEY                         128
+# define EVP_R_EXPECTING_A_DSA_KEY                        129
+# define EVP_R_EXPECTING_A_ECDSA_KEY                      141
+# define EVP_R_EXPECTING_A_EC_KEY                         142
+# define EVP_R_FIPS_MODE_NOT_SUPPORTED                    167
+# define EVP_R_INITIALIZATION_ERROR                       134
+# define EVP_R_INPUT_NOT_INITIALIZED                      111
+# define EVP_R_INVALID_DIGEST                             152
+# define EVP_R_INVALID_FIPS_MODE                          168
+# define EVP_R_INVALID_KEY_LENGTH                         130
+# define EVP_R_INVALID_OPERATION                          148
+# define EVP_R_IV_TOO_LARGE                               102
+# define EVP_R_KEYGEN_FAILURE                             120
+# define EVP_R_MESSAGE_DIGEST_IS_NULL                     159
+# define EVP_R_METHOD_NOT_SUPPORTED                       144
+# define EVP_R_MISSING_PARAMETERS                         103
+# define EVP_R_NO_CIPHER_SET                              131
+# define EVP_R_NO_DEFAULT_DIGEST                          158
+# define EVP_R_NO_DIGEST_SET                              139
+# define EVP_R_NO_DSA_PARAMETERS                          116
+# define EVP_R_NO_KEY_SET                                 154
+# define EVP_R_NO_OPERATION_SET                           149
+# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED                104
+# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED              105
+# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   150
+# define EVP_R_OPERATON_NOT_INITIALIZED                   151
+# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                  117
+# define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
+# define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
+# define EVP_R_PUBLIC_KEY_NOT_RSA                         106
+# define EVP_R_TOO_LARGE                                  164
+# define EVP_R_UNKNOWN_CIPHER                             160
+# define EVP_R_UNKNOWN_DIGEST                             161
+# define EVP_R_UNKNOWN_OPTION                             169
+# define EVP_R_UNKNOWN_PBE_ALGORITHM                      121
+# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS                135
+# define EVP_R_UNSUPPORTED_ALGORITHM                      156
+# define EVP_R_UNSUPPORTED_CIPHER                         107
+# define EVP_R_UNSUPPORTED_KEYLENGTH                      123
+# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION        124
+# define EVP_R_UNSUPPORTED_KEY_SIZE                       108
+# define EVP_R_UNSUPPORTED_PRF                            125
+# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM          118
+# define EVP_R_UNSUPPORTED_SALT_TYPE                      126
+# define EVP_R_WRAP_MODE_NOT_ALLOWED                      170
+# define EVP_R_WRONG_FINAL_BLOCK_LENGTH                   109
+# define EVP_R_WRONG_PUBLIC_KEY_TYPE                      110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/hmac.h b/Cryptlib/Include/openssl/hmac.h
new file mode 100644 (file)
index 0000000..b8b55cd
--- /dev/null
@@ -0,0 +1,109 @@
+/* crypto/hmac/hmac.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_HMAC_H
+# define HEADER_HMAC_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_HMAC
+#  error HMAC is disabled.
+# endif
+
+# include <openssl/evp.h>
+
+# define HMAC_MAX_MD_CBLOCK      128/* largest known is SHA512 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct hmac_ctx_st {
+    const EVP_MD *md;
+    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX i_ctx;
+    EVP_MD_CTX o_ctx;
+    unsigned int key_length;
+    unsigned char key[HMAC_MAX_MD_CBLOCK];
+} HMAC_CTX;
+
+# define HMAC_size(e)    (EVP_MD_size((e)->md))
+
+void HMAC_CTX_init(HMAC_CTX *ctx);
+void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+/* deprecated */
+# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx)
+
+/* deprecated */
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md);
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+                 const EVP_MD *md, ENGINE *impl);
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                    const unsigned char *d, size_t n, unsigned char *md,
+                    unsigned int *md_len);
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/idea.h b/Cryptlib/Include/openssl/idea.h
new file mode 100644 (file)
index 0000000..6075984
--- /dev/null
@@ -0,0 +1,105 @@
+/* crypto/idea/idea.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_IDEA_H
+# define HEADER_IDEA_H
+
+# include <openssl/opensslconf.h>/* IDEA_INT, OPENSSL_NO_IDEA */
+
+# ifdef OPENSSL_NO_IDEA
+#  error IDEA is disabled.
+# endif
+
+# define IDEA_ENCRYPT    1
+# define IDEA_DECRYPT    0
+
+# define IDEA_BLOCK      8
+# define IDEA_KEY_LENGTH 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct idea_key_st {
+    IDEA_INT data[9][6];
+} IDEA_KEY_SCHEDULE;
+
+const char *idea_options(void);
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      IDEA_KEY_SCHEDULE *ks);
+# ifdef OPENSSL_FIPS
+void private_idea_set_encrypt_key(const unsigned char *key,
+                                  IDEA_KEY_SCHEDULE *ks);
+# endif
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                      int enc);
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                        int *num, int enc);
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                        int *num);
+void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/krb5_asn.h b/Cryptlib/Include/openssl/krb5_asn.h
new file mode 100644 (file)
index 0000000..9cf5a26
--- /dev/null
@@ -0,0 +1,240 @@
+/* krb5_asn.h */
+/*
+ * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project, **
+ * using ocsp/{*.h,*asn*.c} as a starting point
+ */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_KRB5_ASN_H
+# define HEADER_KRB5_ASN_H
+
+/*
+ * #include <krb5.h>
+ */
+# include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ASN.1 from Kerberos RFC 1510
+ */
+
+/*-     EncryptedData ::=   SEQUENCE {
+ *              etype[0]                      INTEGER, -- EncryptionType
+ *              kvno[1]                       INTEGER OPTIONAL,
+ *              cipher[2]                     OCTET STRING -- ciphertext
+ *      }
+ */
+typedef struct krb5_encdata_st {
+    ASN1_INTEGER *etype;
+    ASN1_INTEGER *kvno;
+    ASN1_OCTET_STRING *cipher;
+} KRB5_ENCDATA;
+
+DECLARE_STACK_OF(KRB5_ENCDATA)
+
+/*-     PrincipalName ::=   SEQUENCE {
+ *              name-type[0]                  INTEGER,
+ *              name-string[1]                SEQUENCE OF GeneralString
+ *      }
+ */
+typedef struct krb5_princname_st {
+    ASN1_INTEGER *nametype;
+    STACK_OF(ASN1_GENERALSTRING) *namestring;
+} KRB5_PRINCNAME;
+
+DECLARE_STACK_OF(KRB5_PRINCNAME)
+
+/*-     Ticket ::=      [APPLICATION 1] SEQUENCE {
+ *              tkt-vno[0]                    INTEGER,
+ *              realm[1]                      Realm,
+ *              sname[2]                      PrincipalName,
+ *              enc-part[3]                   EncryptedData
+ *      }
+ */
+typedef struct krb5_tktbody_st {
+    ASN1_INTEGER *tktvno;
+    ASN1_GENERALSTRING *realm;
+    KRB5_PRINCNAME *sname;
+    KRB5_ENCDATA *encdata;
+} KRB5_TKTBODY;
+
+typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
+DECLARE_STACK_OF(KRB5_TKTBODY)
+
+/*-     AP-REQ ::=      [APPLICATION 14] SEQUENCE {
+ *              pvno[0]                       INTEGER,
+ *              msg-type[1]                   INTEGER,
+ *              ap-options[2]                 APOptions,
+ *              ticket[3]                     Ticket,
+ *              authenticator[4]              EncryptedData
+ *      }
+ *
+ *      APOptions ::=   BIT STRING {
+ *              reserved(0), use-session-key(1), mutual-required(2) }
+ */
+typedef struct krb5_ap_req_st {
+    ASN1_INTEGER *pvno;
+    ASN1_INTEGER *msgtype;
+    ASN1_BIT_STRING *apoptions;
+    KRB5_TICKET *ticket;
+    KRB5_ENCDATA *authenticator;
+} KRB5_APREQBODY;
+
+typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
+DECLARE_STACK_OF(KRB5_APREQBODY)
+
+/*      Authenticator Stuff     */
+
+/*-     Checksum ::=   SEQUENCE {
+ *              cksumtype[0]                  INTEGER,
+ *              checksum[1]                   OCTET STRING
+ *      }
+ */
+typedef struct krb5_checksum_st {
+    ASN1_INTEGER *ctype;
+    ASN1_OCTET_STRING *checksum;
+} KRB5_CHECKSUM;
+
+DECLARE_STACK_OF(KRB5_CHECKSUM)
+
+/*-     EncryptionKey ::=   SEQUENCE {
+ *              keytype[0]                    INTEGER,
+ *              keyvalue[1]                   OCTET STRING
+ *      }
+ */
+typedef struct krb5_encryptionkey_st {
+    ASN1_INTEGER *ktype;
+    ASN1_OCTET_STRING *keyvalue;
+} KRB5_ENCKEY;
+
+DECLARE_STACK_OF(KRB5_ENCKEY)
+
+/*-     AuthorizationData ::=   SEQUENCE OF SEQUENCE {
+ *              ad-type[0]                    INTEGER,
+ *              ad-data[1]                    OCTET STRING
+ *      }
+ */
+typedef struct krb5_authorization_st {
+    ASN1_INTEGER *adtype;
+    ASN1_OCTET_STRING *addata;
+} KRB5_AUTHDATA;
+
+DECLARE_STACK_OF(KRB5_AUTHDATA)
+
+/*-     -- Unencrypted authenticator
+ *      Authenticator ::=    [APPLICATION 2] SEQUENCE    {
+ *              authenticator-vno[0]          INTEGER,
+ *              crealm[1]                     Realm,
+ *              cname[2]                      PrincipalName,
+ *              cksum[3]                      Checksum OPTIONAL,
+ *              cusec[4]                      INTEGER,
+ *              ctime[5]                      KerberosTime,
+ *              subkey[6]                     EncryptionKey OPTIONAL,
+ *              seq-number[7]                 INTEGER OPTIONAL,
+ *              authorization-data[8]         AuthorizationData OPTIONAL
+ *      }
+ */
+typedef struct krb5_authenticator_st {
+    ASN1_INTEGER *avno;
+    ASN1_GENERALSTRING *crealm;
+    KRB5_PRINCNAME *cname;
+    KRB5_CHECKSUM *cksum;
+    ASN1_INTEGER *cusec;
+    ASN1_GENERALIZEDTIME *ctime;
+    KRB5_ENCKEY *subkey;
+    ASN1_INTEGER *seqnum;
+    KRB5_AUTHDATA *authorization;
+} KRB5_AUTHENTBODY;
+
+typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
+DECLARE_STACK_OF(KRB5_AUTHENTBODY)
+
+/*-  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
+ *      type *name##_new(void);
+ *      void name##_free(type *a);
+ *      DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
+ *       DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
+ *        type *d2i_##name(type **a, const unsigned char **in, long len);
+ *        int i2d_##name(type *a, unsigned char **out);
+ *        DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
+ */
+
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
+DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
+
+DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/kssl.h b/Cryptlib/Include/openssl/kssl.h
new file mode 100644 (file)
index 0000000..ae8a51f
--- /dev/null
@@ -0,0 +1,197 @@
+/* ssl/kssl.h */
+/*
+ * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project
+ * 2000. 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).
+ *
+ */
+
+/*
+ **      19990701        VRS     Started.
+ */
+
+#ifndef KSSL_H
+# define KSSL_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_KRB5
+
+#  include <stdio.h>
+#  include <ctype.h>
+#  include <krb5.h>
+#  ifdef OPENSSL_SYS_WIN32
+/*
+ * These can sometimes get redefined indirectly by krb5 header files after
+ * they get undefed in ossl_typ.h
+ */
+#   undef X509_NAME
+#   undef X509_EXTENSIONS
+#   undef OCSP_REQUEST
+#   undef OCSP_RESPONSE
+#  endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ *      Depending on which KRB5 implementation used, some types from
+ *      the other may be missing.  Resolve that here and now
+ */
+#  ifdef KRB5_HEIMDAL
+typedef unsigned char krb5_octet;
+#   define FAR
+#  else
+
+#   ifndef FAR
+#    define FAR
+#   endif
+
+#  endif
+
+/*-
+ *      Uncomment this to debug kssl problems or
+ *      to trace usage of the Kerberos session key
+ *
+ *      #define         KSSL_DEBUG
+ */
+
+#  ifndef KRB5SVC
+#   define KRB5SVC "host"
+#  endif
+
+#  ifndef KRB5KEYTAB
+#   define KRB5KEYTAB      "/etc/krb5.keytab"
+#  endif
+
+#  ifndef KRB5SENDAUTH
+#   define KRB5SENDAUTH    1
+#  endif
+
+#  ifndef KRB5CHECKAUTH
+#   define KRB5CHECKAUTH   1
+#  endif
+
+#  ifndef KSSL_CLOCKSKEW
+#   define KSSL_CLOCKSKEW  300;
+#  endif
+
+#  define KSSL_ERR_MAX    255
+typedef struct kssl_err_st {
+    int reason;
+    char text[KSSL_ERR_MAX + 1];
+} KSSL_ERR;
+
+/*-     Context for passing
+ *              (1) Kerberos session key to SSL, and
+ *              (2)     Config data between application and SSL lib
+ */
+typedef struct kssl_ctx_st {
+    /*      used by:    disposition:            */
+    char *service_name;         /* C,S default ok (kssl) */
+    char *service_host;         /* C input, REQUIRED */
+    char *client_princ;         /* S output from krb5 ticket */
+    char *keytab_file;          /* S NULL (/etc/krb5.keytab) */
+    char *cred_cache;           /* C NULL (default) */
+    krb5_enctype enctype;
+    int length;
+    krb5_octet FAR *key;
+} KSSL_CTX;
+
+#  define KSSL_CLIENT     1
+#  define KSSL_SERVER     2
+#  define KSSL_SERVICE    3
+#  define KSSL_KEYTAB     4
+
+#  define KSSL_CTX_OK     0
+#  define KSSL_CTX_ERR    1
+#  define KSSL_NOMEM      2
+
+/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
+krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+KSSL_CTX *kssl_ctx_new(void);
+KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
+void kssl_ctx_show(KSSL_CTX *kssl_ctx);
+krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+                                  krb5_data *realm, krb5_data *entity,
+                                  int nentities);
+krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp,
+                              krb5_data *authenp, KSSL_ERR *kssl_err);
+krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata,
+                              krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
+krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
+krb5_error_code kssl_build_principal_2(krb5_context context,
+                                       krb5_principal *princ, int rlen,
+                                       const char *realm, int slen,
+                                       const char *svc, int hlen,
+                                       const char *host);
+krb5_error_code kssl_validate_times(krb5_timestamp atime,
+                                    krb5_ticket_times *ttimes);
+krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
+                                   krb5_timestamp *atimep,
+                                   KSSL_ERR *kssl_err);
+unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
+
+void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx);
+KSSL_CTX *SSL_get0_kssl_ctx(SSL *s);
+char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx);
+
+#ifdef  __cplusplus
+}
+#endif
+# endif                         /* OPENSSL_NO_KRB5 */
+#endif                          /* KSSL_H */
diff --git a/Cryptlib/Include/openssl/lhash.h b/Cryptlib/Include/openssl/lhash.h
new file mode 100644 (file)
index 0000000..b6c328b
--- /dev/null
@@ -0,0 +1,240 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Header for dynamic hash table routines Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+# define HEADER_LHASH_H
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+#  include <stdio.h>
+# endif
+
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st {
+    void *data;
+    struct lhash_node_st *next;
+# ifndef OPENSSL_NO_HASH_COMP
+    unsigned long hash;
+# endif
+} LHASH_NODE;
+
+typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *);
+typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *);
+typedef void (*LHASH_DOALL_FN_TYPE) (void *);
+typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);
+
+/*
+ * Macros for declaring and implementing type-safe wrappers for LHASH
+ * callbacks. This way, callbacks can be provided to LHASH structures without
+ * function pointer casting and the macro-defined callbacks provide
+ * per-variable casting before deferring to the underlying type-specific
+ * callbacks. NB: It is possible to place a "static" in front of both the
+ * DECLARE and IMPLEMENT macros if the functions are strictly internal.
+ */
+
+/* First: "hash" functions */
+# define DECLARE_LHASH_HASH_FN(name, o_type) \
+        unsigned long name##_LHASH_HASH(const void *);
+# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+        unsigned long name##_LHASH_HASH(const void *arg) { \
+                const o_type *a = arg; \
+                return name##_hash(a); }
+# define LHASH_HASH_FN(name) name##_LHASH_HASH
+
+/* Second: "compare" functions */
+# define DECLARE_LHASH_COMP_FN(name, o_type) \
+        int name##_LHASH_COMP(const void *, const void *);
+# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+        int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+                const o_type *a = arg1;             \
+                const o_type *b = arg2; \
+                return name##_cmp(a,b); }
+# define LHASH_COMP_FN(name) name##_LHASH_COMP
+
+/* Third: "doall" functions */
+# define DECLARE_LHASH_DOALL_FN(name, o_type) \
+        void name##_LHASH_DOALL(void *);
+# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+        void name##_LHASH_DOALL(void *arg) { \
+                o_type *a = arg; \
+                name##_doall(a); }
+# define LHASH_DOALL_FN(name) name##_LHASH_DOALL
+
+/* Fourth: "doall_arg" functions */
+# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+        void name##_LHASH_DOALL_ARG(void *, void *);
+# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+        void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+                o_type *a = arg1; \
+                a_type *b = arg2; \
+                name##_doall_arg(a, b); }
+# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
+
+typedef struct lhash_st {
+    LHASH_NODE **b;
+    LHASH_COMP_FN_TYPE comp;
+    LHASH_HASH_FN_TYPE hash;
+    unsigned int num_nodes;
+    unsigned int num_alloc_nodes;
+    unsigned int p;
+    unsigned int pmax;
+    unsigned long up_load;      /* load times 256 */
+    unsigned long down_load;    /* load times 256 */
+    unsigned long num_items;
+    unsigned long num_expands;
+    unsigned long num_expand_reallocs;
+    unsigned long num_contracts;
+    unsigned long num_contract_reallocs;
+    unsigned long num_hash_calls;
+    unsigned long num_comp_calls;
+    unsigned long num_insert;
+    unsigned long num_replace;
+    unsigned long num_delete;
+    unsigned long num_no_delete;
+    unsigned long num_retrieve;
+    unsigned long num_retrieve_miss;
+    unsigned long num_hash_comps;
+    int error;
+} _LHASH;                       /* Do not use _LHASH directly, use LHASH_OF
+                                 * and friends */
+
+# define LH_LOAD_MULT    256
+
+/*
+ * Indicates a malloc() error in the last call, this is only bad in
+ * lh_insert().
+ */
+# define lh_error(lh)    ((lh)->error)
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(_LHASH *lh);
+void *lh_insert(_LHASH *lh, void *data);
+void *lh_delete(_LHASH *lh, const void *data);
+void *lh_retrieve(_LHASH *lh, const void *data);
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(const _LHASH *lh);
+
+# ifndef OPENSSL_NO_FP_API
+void lh_stats(const _LHASH *lh, FILE *out);
+void lh_node_stats(const _LHASH *lh, FILE *out);
+void lh_node_usage_stats(const _LHASH *lh, FILE *out);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+void lh_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
+# endif
+
+/* Type checking... */
+
+# define LHASH_OF(type) struct lhash_st_##type
+
+# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
+
+# define CHECKED_LHASH_OF(type,lh) \
+  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
+
+/* Define wrapper functions. */
+# define LHM_lh_new(type, name) \
+  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
+# define LHM_lh_error(type, lh) \
+  lh_error(CHECKED_LHASH_OF(type,lh))
+# define LHM_lh_insert(type, lh, inst) \
+  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
+                     CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_retrieve(type, lh, inst) \
+  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
+                       CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_delete(type, lh, inst) \
+  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),                        \
+                     CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
+# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
+  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
+# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
+# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
+# define LHM_lh_node_stats_bio(type, lh, out) \
+  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_node_usage_stats_bio(type, lh, out) \
+  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_stats_bio(type, lh, out) \
+  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
+
+DECLARE_LHASH_OF(OPENSSL_STRING);
+DECLARE_LHASH_OF(OPENSSL_CSTRING);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/md4.h b/Cryptlib/Include/openssl/md4.h
new file mode 100644 (file)
index 0000000..11fd712
--- /dev/null
@@ -0,0 +1,119 @@
+/* crypto/md4/md4.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_MD4_H
+# define HEADER_MD4_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_NO_MD4
+#  error MD4 is disabled.
+# endif
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD4_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+# if defined(__LP32__)
+#  define MD4_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#  define MD4_LONG unsigned long
+#  define MD4_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *                                      <appro@fy.chalmers.se>
+ */
+# else
+#  define MD4_LONG unsigned int
+# endif
+
+# define MD4_CBLOCK      64
+# define MD4_LBLOCK      (MD4_CBLOCK/4)
+# define MD4_DIGEST_LENGTH 16
+
+typedef struct MD4state_st {
+    MD4_LONG A, B, C, D;
+    MD4_LONG Nl, Nh;
+    MD4_LONG data[MD4_LBLOCK];
+    unsigned int num;
+} MD4_CTX;
+
+# ifdef OPENSSL_FIPS
+int private_MD4_Init(MD4_CTX *c);
+# endif
+int MD4_Init(MD4_CTX *c);
+int MD4_Update(MD4_CTX *c, const void *data, size_t len);
+int MD4_Final(unsigned char *md, MD4_CTX *c);
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
+void MD4_Transform(MD4_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/md5.h b/Cryptlib/Include/openssl/md5.h
new file mode 100644 (file)
index 0000000..2659038
--- /dev/null
@@ -0,0 +1,119 @@
+/* crypto/md5/md5.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_MD5_H
+# define HEADER_MD5_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_NO_MD5
+#  error MD5 is disabled.
+# endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD5_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+# if defined(__LP32__)
+#  define MD5_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#  define MD5_LONG unsigned long
+#  define MD5_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *                                      <appro@fy.chalmers.se>
+ */
+# else
+#  define MD5_LONG unsigned int
+# endif
+
+# define MD5_CBLOCK      64
+# define MD5_LBLOCK      (MD5_CBLOCK/4)
+# define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st {
+    MD5_LONG A, B, C, D;
+    MD5_LONG Nl, Nh;
+    MD5_LONG data[MD5_LBLOCK];
+    unsigned int num;
+} MD5_CTX;
+
+# ifdef OPENSSL_FIPS
+int private_MD5_Init(MD5_CTX *c);
+# endif
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/mdc2.h b/Cryptlib/Include/openssl/mdc2.h
new file mode 100644 (file)
index 0000000..7efe53b
--- /dev/null
@@ -0,0 +1,94 @@
+/* crypto/mdc2/mdc2.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_MDC2_H
+# define HEADER_MDC2_H
+
+# include <openssl/des.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_NO_MDC2
+#  error MDC2 is disabled.
+# endif
+
+# define MDC2_BLOCK              8
+# define MDC2_DIGEST_LENGTH      16
+
+typedef struct mdc2_ctx_st {
+    unsigned int num;
+    unsigned char data[MDC2_BLOCK];
+    DES_cblock h, hh;
+    int pad_type;               /* either 1 or 2, default 1 */
+} MDC2_CTX;
+
+# ifdef OPENSSL_FIPS
+int private_MDC2_Init(MDC2_CTX *c);
+# endif
+int MDC2_Init(MDC2_CTX *c);
+int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
+int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/modes.h b/Cryptlib/Include/openssl/modes.h
new file mode 100644 (file)
index 0000000..fd48849
--- /dev/null
@@ -0,0 +1,163 @@
+/* ====================================================================
+ * 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 <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+typedef void (*block128_f) (const unsigned char in[16],
+                            unsigned char out[16], const void *key);
+
+typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out,
+                          size_t len, const void *key,
+                          unsigned char ivec[16], int enc);
+
+typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out,
+                          size_t blocks, const void *key,
+                          const unsigned char ivec[16]);
+
+typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out,
+                          size_t blocks, const void *key,
+                          const unsigned char ivec[16],
+                          unsigned char cmac[16]);
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block);
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block);
+
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16],
+                           unsigned char ecount_buf[16], unsigned int *num,
+                           block128_f block);
+
+void CRYPTO_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 ctr);
+
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num,
+                           block128_f block);
+
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num,
+                           int enc, block128_f block);
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block);
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t bits, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block);
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block);
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc);
+
+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 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 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 CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16], cbc128_f cbc);
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block);
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+                         size_t len);
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+                      size_t len);
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len);
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len);
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream);
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream);
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
+                         size_t len);
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+typedef struct ccm128_context CCM128_CONTEXT;
+
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+                        unsigned int M, unsigned int L, void *key,
+                        block128_f block);
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce,
+                        size_t nlen, size_t mlen);
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad,
+                       size_t alen);
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                          unsigned char *out, size_t len);
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                          unsigned char *out, size_t len);
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                                unsigned char *out, size_t len,
+                                ccm128_f stream);
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                                unsigned char *out, size_t len,
+                                ccm128_f stream);
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+
+typedef struct xts128_context XTS128_CONTEXT;
+
+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);
+
+size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
+                       unsigned char *out,
+                       const unsigned char *in, size_t inlen,
+                       block128_f block);
+
+size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
+                         unsigned char *out,
+                         const unsigned char *in, size_t inlen,
+                         block128_f block);
+
+#ifdef  __cplusplus
+}
+#endif
diff --git a/Cryptlib/Include/openssl/obj_mac.h b/Cryptlib/Include/openssl/obj_mac.h
new file mode 100644 (file)
index 0000000..779c309
--- /dev/null
@@ -0,0 +1,4194 @@
+/* crypto/objects/obj_mac.h */
+
+/*
+ * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following
+ * command: perl objects.pl objects.txt obj_mac.num obj_mac.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 SN_undef                        "UNDEF"
+#define LN_undef                        "undefined"
+#define NID_undef                       0
+#define OBJ_undef                       0L
+
+#define SN_itu_t                "ITU-T"
+#define LN_itu_t                "itu-t"
+#define NID_itu_t               645
+#define OBJ_itu_t               0L
+
+#define NID_ccitt               404
+#define OBJ_ccitt               OBJ_itu_t
+
+#define SN_iso          "ISO"
+#define LN_iso          "iso"
+#define NID_iso         181
+#define OBJ_iso         1L
+
+#define SN_joint_iso_itu_t              "JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t              "joint-iso-itu-t"
+#define NID_joint_iso_itu_t             646
+#define OBJ_joint_iso_itu_t             2L
+
+#define NID_joint_iso_ccitt             393
+#define OBJ_joint_iso_ccitt             OBJ_joint_iso_itu_t
+
+#define SN_member_body          "member-body"
+#define LN_member_body          "ISO Member Body"
+#define NID_member_body         182
+#define OBJ_member_body         OBJ_iso,2L
+
+#define SN_identified_organization              "identified-organization"
+#define NID_identified_organization             676
+#define OBJ_identified_organization             OBJ_iso,3L
+
+#define SN_hmac_md5             "HMAC-MD5"
+#define LN_hmac_md5             "hmac-md5"
+#define NID_hmac_md5            780
+#define OBJ_hmac_md5            OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1            "HMAC-SHA1"
+#define LN_hmac_sha1            "hmac-sha1"
+#define NID_hmac_sha1           781
+#define OBJ_hmac_sha1           OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc         "certicom-arc"
+#define NID_certicom_arc                677
+#define OBJ_certicom_arc                OBJ_identified_organization,132L
+
+#define SN_international_organizations          "international-organizations"
+#define LN_international_organizations          "International Organizations"
+#define NID_international_organizations         647
+#define OBJ_international_organizations         OBJ_joint_iso_itu_t,23L
+
+#define SN_wap          "wap"
+#define NID_wap         678
+#define OBJ_wap         OBJ_international_organizations,43L
+
+#define SN_wap_wsg              "wap-wsg"
+#define NID_wap_wsg             679
+#define OBJ_wap_wsg             OBJ_wap,1L
+
+#define SN_selected_attribute_types             "selected-attribute-types"
+#define LN_selected_attribute_types             "Selected Attribute Types"
+#define NID_selected_attribute_types            394
+#define OBJ_selected_attribute_types            OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance            "clearance"
+#define NID_clearance           395
+#define OBJ_clearance           OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US               "ISO-US"
+#define LN_ISO_US               "ISO US Member Body"
+#define NID_ISO_US              183
+#define OBJ_ISO_US              OBJ_member_body,840L
+
+#define SN_X9_57                "X9-57"
+#define LN_X9_57                "X9.57"
+#define NID_X9_57               184
+#define OBJ_X9_57               OBJ_ISO_US,10040L
+
+#define SN_X9cm         "X9cm"
+#define LN_X9cm         "X9.57 CM ?"
+#define NID_X9cm                185
+#define OBJ_X9cm                OBJ_X9_57,4L
+
+#define SN_dsa          "DSA"
+#define LN_dsa          "dsaEncryption"
+#define NID_dsa         116
+#define OBJ_dsa         OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1          "DSA-SHA1"
+#define LN_dsaWithSHA1          "dsaWithSHA1"
+#define NID_dsaWithSHA1         113
+#define OBJ_dsaWithSHA1         OBJ_X9cm,3L
+
+#define SN_ansi_X9_62           "ansi-X9-62"
+#define LN_ansi_X9_62           "ANSI X9.62"
+#define NID_ansi_X9_62          405
+#define OBJ_ansi_X9_62          OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType          OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field            "prime-field"
+#define NID_X9_62_prime_field           406
+#define OBJ_X9_62_prime_field           OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field               "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field              407
+#define OBJ_X9_62_characteristic_two_field              OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis            "id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis           680
+#define OBJ_X9_62_id_characteristic_two_basis           OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis                "onBasis"
+#define NID_X9_62_onBasis               681
+#define OBJ_X9_62_onBasis               OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis                "tpBasis"
+#define NID_X9_62_tpBasis               682
+#define OBJ_X9_62_tpBasis               OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis                "ppBasis"
+#define NID_X9_62_ppBasis               683
+#define OBJ_X9_62_ppBasis               OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType              OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey         "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey                408
+#define OBJ_X9_62_id_ecPublicKey                OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve         OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve            OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1             "c2pnb163v1"
+#define NID_X9_62_c2pnb163v1            684
+#define OBJ_X9_62_c2pnb163v1            OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2             "c2pnb163v2"
+#define NID_X9_62_c2pnb163v2            685
+#define OBJ_X9_62_c2pnb163v2            OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3             "c2pnb163v3"
+#define NID_X9_62_c2pnb163v3            686
+#define OBJ_X9_62_c2pnb163v3            OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1             "c2pnb176v1"
+#define NID_X9_62_c2pnb176v1            687
+#define OBJ_X9_62_c2pnb176v1            OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1             "c2tnb191v1"
+#define NID_X9_62_c2tnb191v1            688
+#define OBJ_X9_62_c2tnb191v1            OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2             "c2tnb191v2"
+#define NID_X9_62_c2tnb191v2            689
+#define OBJ_X9_62_c2tnb191v2            OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3             "c2tnb191v3"
+#define NID_X9_62_c2tnb191v3            690
+#define OBJ_X9_62_c2tnb191v3            OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4             "c2onb191v4"
+#define NID_X9_62_c2onb191v4            691
+#define OBJ_X9_62_c2onb191v4            OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5             "c2onb191v5"
+#define NID_X9_62_c2onb191v5            692
+#define OBJ_X9_62_c2onb191v5            OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1             "c2pnb208w1"
+#define NID_X9_62_c2pnb208w1            693
+#define OBJ_X9_62_c2pnb208w1            OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1             "c2tnb239v1"
+#define NID_X9_62_c2tnb239v1            694
+#define OBJ_X9_62_c2tnb239v1            OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2             "c2tnb239v2"
+#define NID_X9_62_c2tnb239v2            695
+#define OBJ_X9_62_c2tnb239v2            OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3             "c2tnb239v3"
+#define NID_X9_62_c2tnb239v3            696
+#define OBJ_X9_62_c2tnb239v3            OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4             "c2onb239v4"
+#define NID_X9_62_c2onb239v4            697
+#define OBJ_X9_62_c2onb239v4            OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5             "c2onb239v5"
+#define NID_X9_62_c2onb239v5            698
+#define OBJ_X9_62_c2onb239v5            OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1             "c2pnb272w1"
+#define NID_X9_62_c2pnb272w1            699
+#define OBJ_X9_62_c2pnb272w1            OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1             "c2pnb304w1"
+#define NID_X9_62_c2pnb304w1            700
+#define OBJ_X9_62_c2pnb304w1            OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1             "c2tnb359v1"
+#define NID_X9_62_c2tnb359v1            701
+#define OBJ_X9_62_c2tnb359v1            OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1             "c2pnb368w1"
+#define NID_X9_62_c2pnb368w1            702
+#define OBJ_X9_62_c2pnb368w1            OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1             "c2tnb431r1"
+#define NID_X9_62_c2tnb431r1            703
+#define OBJ_X9_62_c2tnb431r1            OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve            OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1             "prime192v1"
+#define NID_X9_62_prime192v1            409
+#define OBJ_X9_62_prime192v1            OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2             "prime192v2"
+#define NID_X9_62_prime192v2            410
+#define OBJ_X9_62_prime192v2            OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3             "prime192v3"
+#define NID_X9_62_prime192v3            411
+#define OBJ_X9_62_prime192v3            OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1             "prime239v1"
+#define NID_X9_62_prime239v1            412
+#define OBJ_X9_62_prime239v1            OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2             "prime239v2"
+#define NID_X9_62_prime239v2            413
+#define OBJ_X9_62_prime239v2            OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3             "prime239v3"
+#define NID_X9_62_prime239v3            414
+#define OBJ_X9_62_prime239v3            OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1             "prime256v1"
+#define NID_X9_62_prime256v1            415
+#define OBJ_X9_62_prime256v1            OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType          OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1              "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1             416
+#define OBJ_ecdsa_with_SHA1             OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended               "ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended              791
+#define OBJ_ecdsa_with_Recommended              OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified         "ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified                792
+#define OBJ_ecdsa_with_Specified                OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224            "ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224           793
+#define OBJ_ecdsa_with_SHA224           OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256            "ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256           794
+#define OBJ_ecdsa_with_SHA256           OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384            "ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384           795
+#define OBJ_ecdsa_with_SHA384           OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512            "ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512           796
+#define OBJ_ecdsa_with_SHA512           OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve          OBJ_certicom_arc,0L
+
+#define SN_secp112r1            "secp112r1"
+#define NID_secp112r1           704
+#define OBJ_secp112r1           OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2            "secp112r2"
+#define NID_secp112r2           705
+#define OBJ_secp112r2           OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1            "secp128r1"
+#define NID_secp128r1           706
+#define OBJ_secp128r1           OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2            "secp128r2"
+#define NID_secp128r2           707
+#define OBJ_secp128r2           OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1            "secp160k1"
+#define NID_secp160k1           708
+#define OBJ_secp160k1           OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1            "secp160r1"
+#define NID_secp160r1           709
+#define OBJ_secp160r1           OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2            "secp160r2"
+#define NID_secp160r2           710
+#define OBJ_secp160r2           OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1            "secp192k1"
+#define NID_secp192k1           711
+#define OBJ_secp192k1           OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1            "secp224k1"
+#define NID_secp224k1           712
+#define OBJ_secp224k1           OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1            "secp224r1"
+#define NID_secp224r1           713
+#define OBJ_secp224r1           OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1            "secp256k1"
+#define NID_secp256k1           714
+#define OBJ_secp256k1           OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1            "secp384r1"
+#define NID_secp384r1           715
+#define OBJ_secp384r1           OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1            "secp521r1"
+#define NID_secp521r1           716
+#define OBJ_secp521r1           OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1            "sect113r1"
+#define NID_sect113r1           717
+#define OBJ_sect113r1           OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2            "sect113r2"
+#define NID_sect113r2           718
+#define OBJ_sect113r2           OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1            "sect131r1"
+#define NID_sect131r1           719
+#define OBJ_sect131r1           OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2            "sect131r2"
+#define NID_sect131r2           720
+#define OBJ_sect131r2           OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1            "sect163k1"
+#define NID_sect163k1           721
+#define OBJ_sect163k1           OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1            "sect163r1"
+#define NID_sect163r1           722
+#define OBJ_sect163r1           OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2            "sect163r2"
+#define NID_sect163r2           723
+#define OBJ_sect163r2           OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1            "sect193r1"
+#define NID_sect193r1           724
+#define OBJ_sect193r1           OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2            "sect193r2"
+#define NID_sect193r2           725
+#define OBJ_sect193r2           OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1            "sect233k1"
+#define NID_sect233k1           726
+#define OBJ_sect233k1           OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1            "sect233r1"
+#define NID_sect233r1           727
+#define OBJ_sect233r1           OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1            "sect239k1"
+#define NID_sect239k1           728
+#define OBJ_sect239k1           OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1            "sect283k1"
+#define NID_sect283k1           729
+#define OBJ_sect283k1           OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1            "sect283r1"
+#define NID_sect283r1           730
+#define OBJ_sect283r1           OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1            "sect409k1"
+#define NID_sect409k1           731
+#define OBJ_sect409k1           OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1            "sect409r1"
+#define NID_sect409r1           732
+#define OBJ_sect409r1           OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1            "sect571k1"
+#define NID_sect571k1           733
+#define OBJ_sect571k1           OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1            "sect571r1"
+#define NID_sect571r1           734
+#define OBJ_sect571r1           OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid            OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1               "wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1              735
+#define OBJ_wap_wsg_idm_ecid_wtls1              OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3               "wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3              736
+#define OBJ_wap_wsg_idm_ecid_wtls3              OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4               "wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4              737
+#define OBJ_wap_wsg_idm_ecid_wtls4              OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5               "wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5              738
+#define OBJ_wap_wsg_idm_ecid_wtls5              OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6               "wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6              739
+#define OBJ_wap_wsg_idm_ecid_wtls6              OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7               "wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7              740
+#define OBJ_wap_wsg_idm_ecid_wtls7              OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8               "wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8              741
+#define OBJ_wap_wsg_idm_ecid_wtls8              OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9               "wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9              742
+#define OBJ_wap_wsg_idm_ecid_wtls9              OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10              "wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10             743
+#define OBJ_wap_wsg_idm_ecid_wtls10             OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11              "wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11             744
+#define OBJ_wap_wsg_idm_ecid_wtls11             OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12              "wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12             745
+#define OBJ_wap_wsg_idm_ecid_wtls12             OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc            "CAST5-CBC"
+#define LN_cast5_cbc            "cast5-cbc"
+#define NID_cast5_cbc           108
+#define OBJ_cast5_cbc           OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb            "CAST5-ECB"
+#define LN_cast5_ecb            "cast5-ecb"
+#define NID_cast5_ecb           109
+
+#define SN_cast5_cfb64          "CAST5-CFB"
+#define LN_cast5_cfb64          "cast5-cfb"
+#define NID_cast5_cfb64         110
+
+#define SN_cast5_ofb64          "CAST5-OFB"
+#define LN_cast5_ofb64          "cast5-ofb"
+#define NID_cast5_ofb64         111
+
+#define LN_pbeWithMD5AndCast5_CBC               "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC              112
+#define OBJ_pbeWithMD5AndCast5_CBC              OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC          "id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC          "password based MAC"
+#define NID_id_PasswordBasedMAC         782
+#define OBJ_id_PasswordBasedMAC         OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac                "id-DHBasedMac"
+#define LN_id_DHBasedMac                "Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac               783
+#define OBJ_id_DHBasedMac               OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi               "rsadsi"
+#define LN_rsadsi               "RSA Data Security, Inc."
+#define NID_rsadsi              1
+#define OBJ_rsadsi              OBJ_ISO_US,113549L
+
+#define SN_pkcs         "pkcs"
+#define LN_pkcs         "RSA Data Security, Inc. PKCS"
+#define NID_pkcs                2
+#define OBJ_pkcs                OBJ_rsadsi,1L
+
+#define SN_pkcs1                "pkcs1"
+#define NID_pkcs1               186
+#define OBJ_pkcs1               OBJ_pkcs,1L
+
+#define LN_rsaEncryption                "rsaEncryption"
+#define NID_rsaEncryption               6
+#define OBJ_rsaEncryption               OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption         "RSA-MD2"
+#define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption                7
+#define OBJ_md2WithRSAEncryption                OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption         "RSA-MD4"
+#define LN_md4WithRSAEncryption         "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption                396
+#define OBJ_md4WithRSAEncryption                OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption         "RSA-MD5"
+#define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption                8
+#define OBJ_md5WithRSAEncryption                OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption                "RSA-SHA1"
+#define LN_sha1WithRSAEncryption                "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption               65
+#define OBJ_sha1WithRSAEncryption               OBJ_pkcs1,5L
+
+#define SN_rsaesOaep            "RSAES-OAEP"
+#define LN_rsaesOaep            "rsaesOaep"
+#define NID_rsaesOaep           919
+#define OBJ_rsaesOaep           OBJ_pkcs1,7L
+
+#define SN_mgf1         "MGF1"
+#define LN_mgf1         "mgf1"
+#define NID_mgf1                911
+#define OBJ_mgf1                OBJ_pkcs1,8L
+
+#define SN_pSpecified           "PSPECIFIED"
+#define LN_pSpecified           "pSpecified"
+#define NID_pSpecified          935
+#define OBJ_pSpecified          OBJ_pkcs1,9L
+
+#define SN_rsassaPss            "RSASSA-PSS"
+#define LN_rsassaPss            "rsassaPss"
+#define NID_rsassaPss           912
+#define OBJ_rsassaPss           OBJ_pkcs1,10L
+
+#define SN_sha256WithRSAEncryption              "RSA-SHA256"
+#define LN_sha256WithRSAEncryption              "sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption             668
+#define OBJ_sha256WithRSAEncryption             OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption              "RSA-SHA384"
+#define LN_sha384WithRSAEncryption              "sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption             669
+#define OBJ_sha384WithRSAEncryption             OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption              "RSA-SHA512"
+#define LN_sha512WithRSAEncryption              "sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption             670
+#define OBJ_sha512WithRSAEncryption             OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption              "RSA-SHA224"
+#define LN_sha224WithRSAEncryption              "sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption             671
+#define OBJ_sha224WithRSAEncryption             OBJ_pkcs1,14L
+
+#define SN_pkcs3                "pkcs3"
+#define NID_pkcs3               27
+#define OBJ_pkcs3               OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement               "dhKeyAgreement"
+#define NID_dhKeyAgreement              28
+#define OBJ_dhKeyAgreement              OBJ_pkcs3,1L
+
+#define SN_pkcs5                "pkcs5"
+#define NID_pkcs5               187
+#define OBJ_pkcs5               OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC                9
+#define OBJ_pbeWithMD2AndDES_CBC                OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC                10
+#define OBJ_pbeWithMD5AndDES_CBC                OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC                168
+#define OBJ_pbeWithMD2AndRC2_CBC                OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC                169
+#define OBJ_pbeWithMD5AndRC2_CBC                OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC                "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC                "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC               170
+#define OBJ_pbeWithSHA1AndDES_CBC               OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC                "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC                "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC               68
+#define OBJ_pbeWithSHA1AndRC2_CBC               OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2            "PBKDF2"
+#define NID_id_pbkdf2           69
+#define OBJ_id_pbkdf2           OBJ_pkcs5,12L
+
+#define LN_pbes2                "PBES2"
+#define NID_pbes2               161
+#define OBJ_pbes2               OBJ_pkcs5,13L
+
+#define LN_pbmac1               "PBMAC1"
+#define NID_pbmac1              162
+#define OBJ_pbmac1              OBJ_pkcs5,14L
+
+#define SN_pkcs7                "pkcs7"
+#define NID_pkcs7               20
+#define OBJ_pkcs7               OBJ_pkcs,7L
+
+#define LN_pkcs7_data           "pkcs7-data"
+#define NID_pkcs7_data          21
+#define OBJ_pkcs7_data          OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed         "pkcs7-signedData"
+#define NID_pkcs7_signed                22
+#define OBJ_pkcs7_signed                OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped              "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped             23
+#define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped             "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped            24
+#define OBJ_pkcs7_signedAndEnveloped            OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest         "pkcs7-digestData"
+#define NID_pkcs7_digest                25
+#define OBJ_pkcs7_digest                OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted              "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted             26
+#define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L
+
+#define SN_pkcs9                "pkcs9"
+#define NID_pkcs9               47
+#define OBJ_pkcs9               OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress           "emailAddress"
+#define NID_pkcs9_emailAddress          48
+#define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName               "unstructuredName"
+#define NID_pkcs9_unstructuredName              49
+#define OBJ_pkcs9_unstructuredName              OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType            "contentType"
+#define NID_pkcs9_contentType           50
+#define OBJ_pkcs9_contentType           OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest          "messageDigest"
+#define NID_pkcs9_messageDigest         51
+#define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime            "signingTime"
+#define NID_pkcs9_signingTime           52
+#define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature               "countersignature"
+#define NID_pkcs9_countersignature              53
+#define OBJ_pkcs9_countersignature              OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword              "challengePassword"
+#define NID_pkcs9_challengePassword             54
+#define OBJ_pkcs9_challengePassword             OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress            "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress           55
+#define OBJ_pkcs9_unstructuredAddress           OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes              "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes             56
+#define OBJ_pkcs9_extCertAttributes             OBJ_pkcs9,9L
+
+#define SN_ext_req              "extReq"
+#define LN_ext_req              "Extension Request"
+#define NID_ext_req             172
+#define OBJ_ext_req             OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities            "SMIME-CAPS"
+#define LN_SMIMECapabilities            "S/MIME Capabilities"
+#define NID_SMIMECapabilities           167
+#define OBJ_SMIMECapabilities           OBJ_pkcs9,15L
+
+#define SN_SMIME                "SMIME"
+#define LN_SMIME                "S/MIME"
+#define NID_SMIME               188
+#define OBJ_SMIME               OBJ_pkcs9,16L
+
+#define SN_id_smime_mod         "id-smime-mod"
+#define NID_id_smime_mod                189
+#define OBJ_id_smime_mod                OBJ_SMIME,0L
+
+#define SN_id_smime_ct          "id-smime-ct"
+#define NID_id_smime_ct         190
+#define OBJ_id_smime_ct         OBJ_SMIME,1L
+
+#define SN_id_smime_aa          "id-smime-aa"
+#define NID_id_smime_aa         191
+#define OBJ_id_smime_aa         OBJ_SMIME,2L
+
+#define SN_id_smime_alg         "id-smime-alg"
+#define NID_id_smime_alg                192
+#define OBJ_id_smime_alg                OBJ_SMIME,3L
+
+#define SN_id_smime_cd          "id-smime-cd"
+#define NID_id_smime_cd         193
+#define OBJ_id_smime_cd         OBJ_SMIME,4L
+
+#define SN_id_smime_spq         "id-smime-spq"
+#define NID_id_smime_spq                194
+#define OBJ_id_smime_spq                OBJ_SMIME,5L
+
+#define SN_id_smime_cti         "id-smime-cti"
+#define NID_id_smime_cti                195
+#define OBJ_id_smime_cti                OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms             "id-smime-mod-cms"
+#define NID_id_smime_mod_cms            196
+#define OBJ_id_smime_mod_cms            OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess             "id-smime-mod-ess"
+#define NID_id_smime_mod_ess            197
+#define OBJ_id_smime_mod_ess            OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid             "id-smime-mod-oid"
+#define NID_id_smime_mod_oid            198
+#define OBJ_id_smime_mod_oid            OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3          "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3         199
+#define OBJ_id_smime_mod_msg_v3         OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88               "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88              200
+#define OBJ_id_smime_mod_ets_eSignature_88              OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97               "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97              201
+#define OBJ_id_smime_mod_ets_eSignature_97              OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88               "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88              202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88              OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97               "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97              203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97              OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt          "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt         204
+#define OBJ_id_smime_ct_receipt         OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData         "id-smime-ct-authData"
+#define NID_id_smime_ct_authData                205
+#define OBJ_id_smime_ct_authData                OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert              "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert             206
+#define OBJ_id_smime_ct_publishCert             OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo          "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo         207
+#define OBJ_id_smime_ct_TSTInfo         OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo          "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo         208
+#define OBJ_id_smime_ct_TDTInfo         OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo              "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo             209
+#define OBJ_id_smime_ct_contentInfo             OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData          "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData         210
+#define OBJ_id_smime_ct_DVCSRequestData         OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData         "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData                211
+#define OBJ_id_smime_ct_DVCSResponseData                OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData           "id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData          786
+#define OBJ_id_smime_ct_compressedData          OBJ_id_smime_ct,9L
+
+#define SN_id_ct_asciiTextWithCRLF              "id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF             787
+#define OBJ_id_ct_asciiTextWithCRLF             OBJ_id_smime_ct,27L
+
+#define SN_id_smime_aa_receiptRequest           "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest          212
+#define OBJ_id_smime_aa_receiptRequest          OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel            "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel           213
+#define OBJ_id_smime_aa_securityLabel           OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory          "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory         214
+#define OBJ_id_smime_aa_mlExpandHistory         OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint              "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint             215
+#define OBJ_id_smime_aa_contentHint             OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest             "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest            216
+#define OBJ_id_smime_aa_msgSigDigest            OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType         "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType                217
+#define OBJ_id_smime_aa_encapContentType                OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier                "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier               218
+#define OBJ_id_smime_aa_contentIdentifier               OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue         "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue                219
+#define OBJ_id_smime_aa_macValue                OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels         "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels                220
+#define OBJ_id_smime_aa_equivalentLabels                OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference         "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference                221
+#define OBJ_id_smime_aa_contentReference                OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref            "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref           222
+#define OBJ_id_smime_aa_encrypKeyPref           OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate               "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate              223
+#define OBJ_id_smime_aa_signingCertificate              OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts                "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts               224
+#define OBJ_id_smime_aa_smimeEncryptCerts               OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken           "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken          225
+#define OBJ_id_smime_aa_timeStampToken          OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId          "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId         226
+#define OBJ_id_smime_aa_ets_sigPolicyId         OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType               "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType              227
+#define OBJ_id_smime_aa_ets_commitmentType              OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation               "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation              228
+#define OBJ_id_smime_aa_ets_signerLocation              OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr           "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr          229
+#define OBJ_id_smime_aa_ets_signerAttr          OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert         "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert                230
+#define OBJ_id_smime_aa_ets_otherSigCert                OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp             "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp            231
+#define OBJ_id_smime_aa_ets_contentTimestamp            OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs              "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs             232
+#define OBJ_id_smime_aa_ets_CertificateRefs             OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs               "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs              233
+#define OBJ_id_smime_aa_ets_RevocationRefs              OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues           "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues          234
+#define OBJ_id_smime_aa_ets_certValues          OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues             "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues            235
+#define OBJ_id_smime_aa_ets_revocationValues            OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp         "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp                236
+#define OBJ_id_smime_aa_ets_escTimeStamp                OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp             "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp            237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp            OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp             "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp            238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp            OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType            "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType           239
+#define OBJ_id_smime_aa_signatureType           OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc         "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc                240
+#define OBJ_id_smime_aa_dvcs_dvc                OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES            "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES           241
+#define OBJ_id_smime_alg_ESDHwith3DES           OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2             "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2            242
+#define OBJ_id_smime_alg_ESDHwithRC2            OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap                "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap               243
+#define OBJ_id_smime_alg_3DESwrap               OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap         "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap                244
+#define OBJ_id_smime_alg_RC2wrap                OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH            "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH           245
+#define OBJ_id_smime_alg_ESDH           OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap             "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap            246
+#define OBJ_id_smime_alg_CMS3DESwrap            OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap              "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap             247
+#define OBJ_id_smime_alg_CMSRC2wrap             OBJ_id_smime_alg,7L
+
+#define SN_id_alg_PWRI_KEK              "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK             893
+#define OBJ_id_alg_PWRI_KEK             OBJ_id_smime_alg,9L
+
+#define SN_id_smime_cd_ldap             "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap            248
+#define OBJ_id_smime_cd_ldap            OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri             "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri            249
+#define OBJ_id_smime_spq_ets_sqt_uri            OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice         "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice                250
+#define OBJ_id_smime_spq_ets_sqt_unotice                OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin               "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin              251
+#define OBJ_id_smime_cti_ets_proofOfOrigin              OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt              "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt             252
+#define OBJ_id_smime_cti_ets_proofOfReceipt             OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery             "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery            253
+#define OBJ_id_smime_cti_ets_proofOfDelivery            OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender               "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender              254
+#define OBJ_id_smime_cti_ets_proofOfSender              OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval             "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval            255
+#define OBJ_id_smime_cti_ets_proofOfApproval            OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation             "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation            256
+#define OBJ_id_smime_cti_ets_proofOfCreation            OBJ_id_smime_cti,6L
+
+#define LN_friendlyName         "friendlyName"
+#define NID_friendlyName                156
+#define OBJ_friendlyName                OBJ_pkcs9,20L
+
+#define LN_localKeyID           "localKeyID"
+#define NID_localKeyID          157
+#define OBJ_localKeyID          OBJ_pkcs9,21L
+
+#define SN_ms_csp_name          "CSPName"
+#define LN_ms_csp_name          "Microsoft CSP Name"
+#define NID_ms_csp_name         417
+#define OBJ_ms_csp_name         1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet          "LocalKeySet"
+#define LN_LocalKeySet          "Microsoft Local Key set"
+#define NID_LocalKeySet         856
+#define OBJ_LocalKeySet         1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes           OBJ_pkcs9,22L
+
+#define LN_x509Certificate              "x509Certificate"
+#define NID_x509Certificate             158
+#define OBJ_x509Certificate             OBJ_certTypes,1L
+
+#define LN_sdsiCertificate              "sdsiCertificate"
+#define NID_sdsiCertificate             159
+#define OBJ_sdsiCertificate             OBJ_certTypes,2L
+
+#define OBJ_crlTypes            OBJ_pkcs9,23L
+
+#define LN_x509Crl              "x509Crl"
+#define NID_x509Crl             160
+#define OBJ_x509Crl             OBJ_crlTypes,1L
+
+#define OBJ_pkcs12              OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids               OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4             "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4             "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4            144
+#define OBJ_pbe_WithSHA1And128BitRC4            OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4              "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4              "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4             145
+#define OBJ_pbe_WithSHA1And40BitRC4             OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC           "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC           "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC          146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC           "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC           "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC          147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC                148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC                OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC          "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC          "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC         149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC         OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1             OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds               OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag               "keyBag"
+#define NID_keyBag              150
+#define OBJ_keyBag              OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag          "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag         151
+#define OBJ_pkcs8ShroudedKeyBag         OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag              "certBag"
+#define NID_certBag             152
+#define OBJ_certBag             OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag               "crlBag"
+#define NID_crlBag              153
+#define OBJ_crlBag              OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag            "secretBag"
+#define NID_secretBag           154
+#define OBJ_secretBag           OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag              "safeContentsBag"
+#define NID_safeContentsBag             155
+#define OBJ_safeContentsBag             OBJ_pkcs12_BagIds,6L
+
+#define SN_md2          "MD2"
+#define LN_md2          "md2"
+#define NID_md2         3
+#define OBJ_md2         OBJ_rsadsi,2L,2L
+
+#define SN_md4          "MD4"
+#define LN_md4          "md4"
+#define NID_md4         257
+#define OBJ_md4         OBJ_rsadsi,2L,4L
+
+#define SN_md5          "MD5"
+#define LN_md5          "md5"
+#define NID_md5         4
+#define OBJ_md5         OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1             "MD5-SHA1"
+#define LN_md5_sha1             "md5-sha1"
+#define NID_md5_sha1            114
+
+#define LN_hmacWithMD5          "hmacWithMD5"
+#define NID_hmacWithMD5         797
+#define OBJ_hmacWithMD5         OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1         "hmacWithSHA1"
+#define NID_hmacWithSHA1                163
+#define OBJ_hmacWithSHA1                OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224               "hmacWithSHA224"
+#define NID_hmacWithSHA224              798
+#define OBJ_hmacWithSHA224              OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256               "hmacWithSHA256"
+#define NID_hmacWithSHA256              799
+#define OBJ_hmacWithSHA256              OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384               "hmacWithSHA384"
+#define NID_hmacWithSHA384              800
+#define OBJ_hmacWithSHA384              OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512               "hmacWithSHA512"
+#define NID_hmacWithSHA512              801
+#define OBJ_hmacWithSHA512              OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc              "RC2-CBC"
+#define LN_rc2_cbc              "rc2-cbc"
+#define NID_rc2_cbc             37
+#define OBJ_rc2_cbc             OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb              "RC2-ECB"
+#define LN_rc2_ecb              "rc2-ecb"
+#define NID_rc2_ecb             38
+
+#define SN_rc2_cfb64            "RC2-CFB"
+#define LN_rc2_cfb64            "rc2-cfb"
+#define NID_rc2_cfb64           39
+
+#define SN_rc2_ofb64            "RC2-OFB"
+#define LN_rc2_ofb64            "rc2-ofb"
+#define NID_rc2_ofb64           40
+
+#define SN_rc2_40_cbc           "RC2-40-CBC"
+#define LN_rc2_40_cbc           "rc2-40-cbc"
+#define NID_rc2_40_cbc          98
+
+#define SN_rc2_64_cbc           "RC2-64-CBC"
+#define LN_rc2_64_cbc           "rc2-64-cbc"
+#define NID_rc2_64_cbc          166
+
+#define SN_rc4          "RC4"
+#define LN_rc4          "rc4"
+#define NID_rc4         5
+#define OBJ_rc4         OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40               "RC4-40"
+#define LN_rc4_40               "rc4-40"
+#define NID_rc4_40              97
+
+#define SN_des_ede3_cbc         "DES-EDE3-CBC"
+#define LN_des_ede3_cbc         "des-ede3-cbc"
+#define NID_des_ede3_cbc                44
+#define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc              "RC5-CBC"
+#define LN_rc5_cbc              "rc5-cbc"
+#define NID_rc5_cbc             120
+#define OBJ_rc5_cbc             OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb              "RC5-ECB"
+#define LN_rc5_ecb              "rc5-ecb"
+#define NID_rc5_ecb             121
+
+#define SN_rc5_cfb64            "RC5-CFB"
+#define LN_rc5_cfb64            "rc5-cfb"
+#define NID_rc5_cfb64           122
+
+#define SN_rc5_ofb64            "RC5-OFB"
+#define LN_rc5_ofb64            "rc5-ofb"
+#define NID_rc5_ofb64           123
+
+#define SN_ms_ext_req           "msExtReq"
+#define LN_ms_ext_req           "Microsoft Extension Request"
+#define NID_ms_ext_req          171
+#define OBJ_ms_ext_req          1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind          "msCodeInd"
+#define LN_ms_code_ind          "Microsoft Individual Code Signing"
+#define NID_ms_code_ind         134
+#define OBJ_ms_code_ind         1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com          "msCodeCom"
+#define LN_ms_code_com          "Microsoft Commercial Code Signing"
+#define NID_ms_code_com         135
+#define OBJ_ms_code_com         1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign          "msCTLSign"
+#define LN_ms_ctl_sign          "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign         136
+#define OBJ_ms_ctl_sign         1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc               "msSGC"
+#define LN_ms_sgc               "Microsoft Server Gated Crypto"
+#define NID_ms_sgc              137
+#define OBJ_ms_sgc              1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs               "msEFS"
+#define LN_ms_efs               "Microsoft Encrypted File System"
+#define NID_ms_efs              138
+#define OBJ_ms_efs              1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login           "msSmartcardLogin"
+#define LN_ms_smartcard_login           "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login          648
+#define OBJ_ms_smartcard_login          1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn               "msUPN"
+#define LN_ms_upn               "Microsoft Universal Principal Name"
+#define NID_ms_upn              649
+#define OBJ_ms_upn              1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc             "IDEA-CBC"
+#define LN_idea_cbc             "idea-cbc"
+#define NID_idea_cbc            34
+#define OBJ_idea_cbc            1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb             "IDEA-ECB"
+#define LN_idea_ecb             "idea-ecb"
+#define NID_idea_ecb            36
+
+#define SN_idea_cfb64           "IDEA-CFB"
+#define LN_idea_cfb64           "idea-cfb"
+#define NID_idea_cfb64          35
+
+#define SN_idea_ofb64           "IDEA-OFB"
+#define LN_idea_ofb64           "idea-ofb"
+#define NID_idea_ofb64          46
+
+#define SN_bf_cbc               "BF-CBC"
+#define LN_bf_cbc               "bf-cbc"
+#define NID_bf_cbc              91
+#define OBJ_bf_cbc              1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb               "BF-ECB"
+#define LN_bf_ecb               "bf-ecb"
+#define NID_bf_ecb              92
+
+#define SN_bf_cfb64             "BF-CFB"
+#define LN_bf_cfb64             "bf-cfb"
+#define NID_bf_cfb64            93
+
+#define SN_bf_ofb64             "BF-OFB"
+#define LN_bf_ofb64             "bf-ofb"
+#define NID_bf_ofb64            94
+
+#define SN_id_pkix              "PKIX"
+#define NID_id_pkix             127
+#define OBJ_id_pkix             1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod          "id-pkix-mod"
+#define NID_id_pkix_mod         258
+#define OBJ_id_pkix_mod         OBJ_id_pkix,0L
+
+#define SN_id_pe                "id-pe"
+#define NID_id_pe               175
+#define OBJ_id_pe               OBJ_id_pkix,1L
+
+#define SN_id_qt                "id-qt"
+#define NID_id_qt               259
+#define OBJ_id_qt               OBJ_id_pkix,2L
+
+#define SN_id_kp                "id-kp"
+#define NID_id_kp               128
+#define OBJ_id_kp               OBJ_id_pkix,3L
+
+#define SN_id_it                "id-it"
+#define NID_id_it               260
+#define OBJ_id_it               OBJ_id_pkix,4L
+
+#define SN_id_pkip              "id-pkip"
+#define NID_id_pkip             261
+#define OBJ_id_pkip             OBJ_id_pkix,5L
+
+#define SN_id_alg               "id-alg"
+#define NID_id_alg              262
+#define OBJ_id_alg              OBJ_id_pkix,6L
+
+#define SN_id_cmc               "id-cmc"
+#define NID_id_cmc              263
+#define OBJ_id_cmc              OBJ_id_pkix,7L
+
+#define SN_id_on                "id-on"
+#define NID_id_on               264
+#define OBJ_id_on               OBJ_id_pkix,8L
+
+#define SN_id_pda               "id-pda"
+#define NID_id_pda              265
+#define OBJ_id_pda              OBJ_id_pkix,9L
+
+#define SN_id_aca               "id-aca"
+#define NID_id_aca              266
+#define OBJ_id_aca              OBJ_id_pkix,10L
+
+#define SN_id_qcs               "id-qcs"
+#define NID_id_qcs              267
+#define OBJ_id_qcs              OBJ_id_pkix,11L
+
+#define SN_id_cct               "id-cct"
+#define NID_id_cct              268
+#define OBJ_id_cct              OBJ_id_pkix,12L
+
+#define SN_id_ppl               "id-ppl"
+#define NID_id_ppl              662
+#define OBJ_id_ppl              OBJ_id_pkix,21L
+
+#define SN_id_ad                "id-ad"
+#define NID_id_ad               176
+#define OBJ_id_ad               OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88         "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88                269
+#define OBJ_id_pkix1_explicit_88                OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88         "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88                270
+#define OBJ_id_pkix1_implicit_88                OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93         "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93                271
+#define OBJ_id_pkix1_explicit_93                OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93         "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93                272
+#define OBJ_id_pkix1_implicit_93                OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf          "id-mod-crmf"
+#define NID_id_mod_crmf         273
+#define OBJ_id_mod_crmf         OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc           "id-mod-cmc"
+#define NID_id_mod_cmc          274
+#define OBJ_id_mod_cmc          OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88                "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88               275
+#define OBJ_id_mod_kea_profile_88               OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93                "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93               276
+#define OBJ_id_mod_kea_profile_93               OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp           "id-mod-cmp"
+#define NID_id_mod_cmp          277
+#define OBJ_id_mod_cmp          OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88             "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88            278
+#define OBJ_id_mod_qualified_cert_88            OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93             "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93            279
+#define OBJ_id_mod_qualified_cert_93            OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert                "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert               280
+#define OBJ_id_mod_attribute_cert               OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol            "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol           281
+#define OBJ_id_mod_timestamp_protocol           OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp          "id-mod-ocsp"
+#define NID_id_mod_ocsp         282
+#define OBJ_id_mod_ocsp         OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs          "id-mod-dvcs"
+#define NID_id_mod_dvcs         283
+#define OBJ_id_mod_dvcs         OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000               "id-mod-cmp2000"
+#define NID_id_mod_cmp2000              284
+#define OBJ_id_mod_cmp2000              OBJ_id_pkix_mod,16L
+
+#define SN_info_access          "authorityInfoAccess"
+#define LN_info_access          "Authority Information Access"
+#define NID_info_access         177
+#define OBJ_info_access         OBJ_id_pe,1L
+
+#define SN_biometricInfo                "biometricInfo"
+#define LN_biometricInfo                "Biometric Info"
+#define NID_biometricInfo               285
+#define OBJ_biometricInfo               OBJ_id_pe,2L
+
+#define SN_qcStatements         "qcStatements"
+#define NID_qcStatements                286
+#define OBJ_qcStatements                OBJ_id_pe,3L
+
+#define SN_ac_auditEntity               "ac-auditEntity"
+#define NID_ac_auditEntity              287
+#define OBJ_ac_auditEntity              OBJ_id_pe,4L
+
+#define SN_ac_targeting         "ac-targeting"
+#define NID_ac_targeting                288
+#define OBJ_ac_targeting                OBJ_id_pe,5L
+
+#define SN_aaControls           "aaControls"
+#define NID_aaControls          289
+#define OBJ_aaControls          OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock             "sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock            290
+#define OBJ_sbgp_ipAddrBlock            OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum                "sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum               291
+#define OBJ_sbgp_autonomousSysNum               OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier                "sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier               292
+#define OBJ_sbgp_routerIdentifier               OBJ_id_pe,9L
+
+#define SN_ac_proxying          "ac-proxying"
+#define NID_ac_proxying         397
+#define OBJ_ac_proxying         OBJ_id_pe,10L
+
+#define SN_sinfo_access         "subjectInfoAccess"
+#define LN_sinfo_access         "Subject Information Access"
+#define NID_sinfo_access                398
+#define OBJ_sinfo_access                OBJ_id_pe,11L
+
+#define SN_proxyCertInfo                "proxyCertInfo"
+#define LN_proxyCertInfo                "Proxy Certificate Information"
+#define NID_proxyCertInfo               663
+#define OBJ_proxyCertInfo               OBJ_id_pe,14L
+
+#define SN_id_qt_cps            "id-qt-cps"
+#define LN_id_qt_cps            "Policy Qualifier CPS"
+#define NID_id_qt_cps           164
+#define OBJ_id_qt_cps           OBJ_id_qt,1L
+
+#define SN_id_qt_unotice                "id-qt-unotice"
+#define LN_id_qt_unotice                "Policy Qualifier User Notice"
+#define NID_id_qt_unotice               165
+#define OBJ_id_qt_unotice               OBJ_id_qt,2L
+
+#define SN_textNotice           "textNotice"
+#define NID_textNotice          293
+#define OBJ_textNotice          OBJ_id_qt,3L
+
+#define SN_server_auth          "serverAuth"
+#define LN_server_auth          "TLS Web Server Authentication"
+#define NID_server_auth         129
+#define OBJ_server_auth         OBJ_id_kp,1L
+
+#define SN_client_auth          "clientAuth"
+#define LN_client_auth          "TLS Web Client Authentication"
+#define NID_client_auth         130
+#define OBJ_client_auth         OBJ_id_kp,2L
+
+#define SN_code_sign            "codeSigning"
+#define LN_code_sign            "Code Signing"
+#define NID_code_sign           131
+#define OBJ_code_sign           OBJ_id_kp,3L
+
+#define SN_email_protect                "emailProtection"
+#define LN_email_protect                "E-mail Protection"
+#define NID_email_protect               132
+#define OBJ_email_protect               OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem               "ipsecEndSystem"
+#define LN_ipsecEndSystem               "IPSec End System"
+#define NID_ipsecEndSystem              294
+#define OBJ_ipsecEndSystem              OBJ_id_kp,5L
+
+#define SN_ipsecTunnel          "ipsecTunnel"
+#define LN_ipsecTunnel          "IPSec Tunnel"
+#define NID_ipsecTunnel         295
+#define OBJ_ipsecTunnel         OBJ_id_kp,6L
+
+#define SN_ipsecUser            "ipsecUser"
+#define LN_ipsecUser            "IPSec User"
+#define NID_ipsecUser           296
+#define OBJ_ipsecUser           OBJ_id_kp,7L
+
+#define SN_time_stamp           "timeStamping"
+#define LN_time_stamp           "Time Stamping"
+#define NID_time_stamp          133
+#define OBJ_time_stamp          OBJ_id_kp,8L
+
+#define SN_OCSP_sign            "OCSPSigning"
+#define LN_OCSP_sign            "OCSP Signing"
+#define NID_OCSP_sign           180
+#define OBJ_OCSP_sign           OBJ_id_kp,9L
+
+#define SN_dvcs         "DVCS"
+#define LN_dvcs         "dvcs"
+#define NID_dvcs                297
+#define OBJ_dvcs                OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert          "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert         298
+#define OBJ_id_it_caProtEncCert         OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes               "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes              299
+#define OBJ_id_it_signKeyPairTypes              OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes                "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes               300
+#define OBJ_id_it_encKeyPairTypes               OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg               "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg              301
+#define OBJ_id_it_preferredSymmAlg              OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo                "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo               302
+#define OBJ_id_it_caKeyUpdateInfo               OBJ_id_it,5L
+
+#define SN_id_it_currentCRL             "id-it-currentCRL"
+#define NID_id_it_currentCRL            303
+#define OBJ_id_it_currentCRL            OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs                "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs               304
+#define OBJ_id_it_unsupportedOIDs               OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest            "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest           305
+#define OBJ_id_it_subscriptionRequest           OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse           "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse          306
+#define OBJ_id_it_subscriptionResponse          OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq                "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq               307
+#define OBJ_id_it_keyPairParamReq               OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep                "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep               308
+#define OBJ_id_it_keyPairParamRep               OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase          "id-it-revPassphrase"
+#define NID_id_it_revPassphrase         309
+#define OBJ_id_it_revPassphrase         OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm                "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm               310
+#define OBJ_id_it_implicitConfirm               OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime                "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime               311
+#define OBJ_id_it_confirmWaitTime               OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage         "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage                312
+#define OBJ_id_it_origPKIMessage                OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags           "id-it-suppLangTags"
+#define NID_id_it_suppLangTags          784
+#define OBJ_id_it_suppLangTags          OBJ_id_it,16L
+
+#define SN_id_regCtrl           "id-regCtrl"
+#define NID_id_regCtrl          313
+#define OBJ_id_regCtrl          OBJ_id_pkip,1L
+
+#define SN_id_regInfo           "id-regInfo"
+#define NID_id_regInfo          314
+#define OBJ_id_regInfo          OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken          "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken         315
+#define OBJ_id_regCtrl_regToken         OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator             "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator            316
+#define OBJ_id_regCtrl_authenticator            OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo                "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo               317
+#define OBJ_id_regCtrl_pkiPublicationInfo               OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions         "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions                318
+#define OBJ_id_regCtrl_pkiArchiveOptions                OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID         "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID                319
+#define OBJ_id_regCtrl_oldCertID                OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey           "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey          320
+#define OBJ_id_regCtrl_protocolEncrKey          OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs         "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs                321
+#define OBJ_id_regInfo_utf8Pairs                OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq           "id-regInfo-certReq"
+#define NID_id_regInfo_certReq          322
+#define OBJ_id_regInfo_certReq          OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40         "id-alg-des40"
+#define NID_id_alg_des40                323
+#define OBJ_id_alg_des40                OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature           "id-alg-noSignature"
+#define NID_id_alg_noSignature          324
+#define OBJ_id_alg_noSignature          OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1              "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1             325
+#define OBJ_id_alg_dh_sig_hmac_sha1             OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop                "id-alg-dh-pop"
+#define NID_id_alg_dh_pop               326
+#define OBJ_id_alg_dh_pop               OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo            "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo           327
+#define OBJ_id_cmc_statusInfo           OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification                "id-cmc-identification"
+#define NID_id_cmc_identification               328
+#define OBJ_id_cmc_identification               OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof         "id-cmc-identityProof"
+#define NID_id_cmc_identityProof                329
+#define OBJ_id_cmc_identityProof                OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn            "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn           330
+#define OBJ_id_cmc_dataReturn           OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId         "id-cmc-transactionId"
+#define NID_id_cmc_transactionId                331
+#define OBJ_id_cmc_transactionId                OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce           "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce          332
+#define OBJ_id_cmc_senderNonce          OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce                "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce               333
+#define OBJ_id_cmc_recipientNonce               OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions         "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions                334
+#define OBJ_id_cmc_addExtensions                OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP          "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP         335
+#define OBJ_id_cmc_encryptedPOP         OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP          "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP         336
+#define OBJ_id_cmc_decryptedPOP         OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness         "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness                337
+#define OBJ_id_cmc_lraPOPWitness                OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert               "id-cmc-getCert"
+#define NID_id_cmc_getCert              338
+#define OBJ_id_cmc_getCert              OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL                "id-cmc-getCRL"
+#define NID_id_cmc_getCRL               339
+#define OBJ_id_cmc_getCRL               OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest         "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest                340
+#define OBJ_id_cmc_revokeRequest                OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo               "id-cmc-regInfo"
+#define NID_id_cmc_regInfo              341
+#define OBJ_id_cmc_regInfo              OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo          "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo         342
+#define OBJ_id_cmc_responseInfo         OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending          "id-cmc-queryPending"
+#define NID_id_cmc_queryPending         343
+#define OBJ_id_cmc_queryPending         OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom         "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom                344
+#define OBJ_id_cmc_popLinkRandom                OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness                "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness               345
+#define OBJ_id_cmc_popLinkWitness               OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance         "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance                346
+#define OBJ_id_cmc_confirmCertAcceptance                OBJ_id_cmc,24L
+
+#define SN_id_on_personalData           "id-on-personalData"
+#define NID_id_on_personalData          347
+#define OBJ_id_on_personalData          OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier            "id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier            "Permanent Identifier"
+#define NID_id_on_permanentIdentifier           858
+#define OBJ_id_on_permanentIdentifier           OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth           "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth          348
+#define OBJ_id_pda_dateOfBirth          OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth          "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth         349
+#define OBJ_id_pda_placeOfBirth         OBJ_id_pda,2L
+
+#define SN_id_pda_gender                "id-pda-gender"
+#define NID_id_pda_gender               351
+#define OBJ_id_pda_gender               OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship          "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship         352
+#define OBJ_id_pda_countryOfCitizenship         OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence            "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence           353
+#define OBJ_id_pda_countryOfResidence           OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo            "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo           354
+#define OBJ_id_aca_authenticationInfo           OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity                "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity               355
+#define OBJ_id_aca_accessIdentity               OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity              "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity             356
+#define OBJ_id_aca_chargingIdentity             OBJ_id_aca,3L
+
+#define SN_id_aca_group         "id-aca-group"
+#define NID_id_aca_group                357
+#define OBJ_id_aca_group                OBJ_id_aca,4L
+
+#define SN_id_aca_role          "id-aca-role"
+#define NID_id_aca_role         358
+#define OBJ_id_aca_role         OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs              "id-aca-encAttrs"
+#define NID_id_aca_encAttrs             399
+#define OBJ_id_aca_encAttrs             OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1               "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1              359
+#define OBJ_id_qcs_pkixQCSyntax_v1              OBJ_id_qcs,1L
+
+#define SN_id_cct_crs           "id-cct-crs"
+#define NID_id_cct_crs          360
+#define OBJ_id_cct_crs          OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData               "id-cct-PKIData"
+#define NID_id_cct_PKIData              361
+#define OBJ_id_cct_PKIData              OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse           "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse          362
+#define OBJ_id_cct_PKIResponse          OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage           "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage           "Any language"
+#define NID_id_ppl_anyLanguage          664
+#define OBJ_id_ppl_anyLanguage          OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll            "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll            "Inherit all"
+#define NID_id_ppl_inheritAll           665
+#define OBJ_id_ppl_inheritAll           OBJ_id_ppl,1L
+
+#define SN_Independent          "id-ppl-independent"
+#define LN_Independent          "Independent"
+#define NID_Independent         667
+#define OBJ_Independent         OBJ_id_ppl,2L
+
+#define SN_ad_OCSP              "OCSP"
+#define LN_ad_OCSP              "OCSP"
+#define NID_ad_OCSP             178
+#define OBJ_ad_OCSP             OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers                "caIssuers"
+#define LN_ad_ca_issuers                "CA Issuers"
+#define NID_ad_ca_issuers               179
+#define OBJ_ad_ca_issuers               OBJ_id_ad,2L
+
+#define SN_ad_timeStamping              "ad_timestamping"
+#define LN_ad_timeStamping              "AD Time Stamping"
+#define NID_ad_timeStamping             363
+#define OBJ_ad_timeStamping             OBJ_id_ad,3L
+
+#define SN_ad_dvcs              "AD_DVCS"
+#define LN_ad_dvcs              "ad dvcs"
+#define NID_ad_dvcs             364
+#define OBJ_ad_dvcs             OBJ_id_ad,4L
+
+#define SN_caRepository         "caRepository"
+#define LN_caRepository         "CA Repository"
+#define NID_caRepository                785
+#define OBJ_caRepository                OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP                OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic           "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic           "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic          365
+#define OBJ_id_pkix_OCSP_basic          OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce           "Nonce"
+#define LN_id_pkix_OCSP_Nonce           "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce          366
+#define OBJ_id_pkix_OCSP_Nonce          OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID           "CrlID"
+#define LN_id_pkix_OCSP_CrlID           "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID          367
+#define OBJ_id_pkix_OCSP_CrlID          OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses             "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses             "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses            368
+#define OBJ_id_pkix_OCSP_acceptableResponses            OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck         "noCheck"
+#define LN_id_pkix_OCSP_noCheck         "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck                369
+#define OBJ_id_pkix_OCSP_noCheck                OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff           "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff           "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff          370
+#define OBJ_id_pkix_OCSP_archiveCutoff          OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator          "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator          "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator         371
+#define OBJ_id_pkix_OCSP_serviceLocator         OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus          "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus          "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus         372
+#define OBJ_id_pkix_OCSP_extendedStatus         OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid           "valid"
+#define NID_id_pkix_OCSP_valid          373
+#define OBJ_id_pkix_OCSP_valid          OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path            "path"
+#define NID_id_pkix_OCSP_path           374
+#define OBJ_id_pkix_OCSP_path           OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot               "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot               "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot              375
+#define OBJ_id_pkix_OCSP_trustRoot              OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm            "algorithm"
+#define LN_algorithm            "algorithm"
+#define NID_algorithm           376
+#define OBJ_algorithm           1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA           "RSA-NP-MD5"
+#define LN_md5WithRSA           "md5WithRSA"
+#define NID_md5WithRSA          104
+#define OBJ_md5WithRSA          OBJ_algorithm,3L
+
+#define SN_des_ecb              "DES-ECB"
+#define LN_des_ecb              "des-ecb"
+#define NID_des_ecb             29
+#define OBJ_des_ecb             OBJ_algorithm,6L
+
+#define SN_des_cbc              "DES-CBC"
+#define LN_des_cbc              "des-cbc"
+#define NID_des_cbc             31
+#define OBJ_des_cbc             OBJ_algorithm,7L
+
+#define SN_des_ofb64            "DES-OFB"
+#define LN_des_ofb64            "des-ofb"
+#define NID_des_ofb64           45
+#define OBJ_des_ofb64           OBJ_algorithm,8L
+
+#define SN_des_cfb64            "DES-CFB"
+#define LN_des_cfb64            "des-cfb"
+#define NID_des_cfb64           30
+#define OBJ_des_cfb64           OBJ_algorithm,9L
+
+#define SN_rsaSignature         "rsaSignature"
+#define NID_rsaSignature                377
+#define OBJ_rsaSignature                OBJ_algorithm,11L
+
+#define SN_dsa_2                "DSA-old"
+#define LN_dsa_2                "dsaEncryption-old"
+#define NID_dsa_2               67
+#define OBJ_dsa_2               OBJ_algorithm,12L
+
+#define SN_dsaWithSHA           "DSA-SHA"
+#define LN_dsaWithSHA           "dsaWithSHA"
+#define NID_dsaWithSHA          66
+#define OBJ_dsaWithSHA          OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption         "RSA-SHA"
+#define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption                42
+#define OBJ_shaWithRSAEncryption                OBJ_algorithm,15L
+
+#define SN_des_ede_ecb          "DES-EDE"
+#define LN_des_ede_ecb          "des-ede"
+#define NID_des_ede_ecb         32
+#define OBJ_des_ede_ecb         OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb         "DES-EDE3"
+#define LN_des_ede3_ecb         "des-ede3"
+#define NID_des_ede3_ecb                33
+
+#define SN_des_ede_cbc          "DES-EDE-CBC"
+#define LN_des_ede_cbc          "des-ede-cbc"
+#define NID_des_ede_cbc         43
+
+#define SN_des_ede_cfb64                "DES-EDE-CFB"
+#define LN_des_ede_cfb64                "des-ede-cfb"
+#define NID_des_ede_cfb64               60
+
+#define SN_des_ede3_cfb64               "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64               "des-ede3-cfb"
+#define NID_des_ede3_cfb64              61
+
+#define SN_des_ede_ofb64                "DES-EDE-OFB"
+#define LN_des_ede_ofb64                "des-ede-ofb"
+#define NID_des_ede_ofb64               62
+
+#define SN_des_ede3_ofb64               "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64               "des-ede3-ofb"
+#define NID_des_ede3_ofb64              63
+
+#define SN_desx_cbc             "DESX-CBC"
+#define LN_desx_cbc             "desx-cbc"
+#define NID_desx_cbc            80
+
+#define SN_sha          "SHA"
+#define LN_sha          "sha"
+#define NID_sha         41
+#define OBJ_sha         OBJ_algorithm,18L
+
+#define SN_sha1         "SHA1"
+#define LN_sha1         "sha1"
+#define NID_sha1                64
+#define OBJ_sha1                OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2                "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2               70
+#define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L
+
+#define SN_sha1WithRSA          "RSA-SHA1-2"
+#define LN_sha1WithRSA          "sha1WithRSA"
+#define NID_sha1WithRSA         115
+#define OBJ_sha1WithRSA         OBJ_algorithm,29L
+
+#define SN_ripemd160            "RIPEMD160"
+#define LN_ripemd160            "ripemd160"
+#define NID_ripemd160           117
+#define OBJ_ripemd160           1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA             "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA             "ripemd160WithRSA"
+#define NID_ripemd160WithRSA            119
+#define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet                "SXNetID"
+#define LN_sxnet                "Strong Extranet ID"
+#define NID_sxnet               143
+#define OBJ_sxnet               1L,3L,101L,1L,4L,1L
+
+#define SN_X500         "X500"
+#define LN_X500         "directory services (X.500)"
+#define NID_X500                11
+#define OBJ_X500                2L,5L
+
+#define SN_X509         "X509"
+#define NID_X509                12
+#define OBJ_X509                OBJ_X500,4L
+
+#define SN_commonName           "CN"
+#define LN_commonName           "commonName"
+#define NID_commonName          13
+#define OBJ_commonName          OBJ_X509,3L
+
+#define SN_surname              "SN"
+#define LN_surname              "surname"
+#define NID_surname             100
+#define OBJ_surname             OBJ_X509,4L
+
+#define LN_serialNumber         "serialNumber"
+#define NID_serialNumber                105
+#define OBJ_serialNumber                OBJ_X509,5L
+
+#define SN_countryName          "C"
+#define LN_countryName          "countryName"
+#define NID_countryName         14
+#define OBJ_countryName         OBJ_X509,6L
+
+#define SN_localityName         "L"
+#define LN_localityName         "localityName"
+#define NID_localityName                15
+#define OBJ_localityName                OBJ_X509,7L
+
+#define SN_stateOrProvinceName          "ST"
+#define LN_stateOrProvinceName          "stateOrProvinceName"
+#define NID_stateOrProvinceName         16
+#define OBJ_stateOrProvinceName         OBJ_X509,8L
+
+#define SN_streetAddress                "street"
+#define LN_streetAddress                "streetAddress"
+#define NID_streetAddress               660
+#define OBJ_streetAddress               OBJ_X509,9L
+
+#define SN_organizationName             "O"
+#define LN_organizationName             "organizationName"
+#define NID_organizationName            17
+#define OBJ_organizationName            OBJ_X509,10L
+
+#define SN_organizationalUnitName               "OU"
+#define LN_organizationalUnitName               "organizationalUnitName"
+#define NID_organizationalUnitName              18
+#define OBJ_organizationalUnitName              OBJ_X509,11L
+
+#define SN_title                "title"
+#define LN_title                "title"
+#define NID_title               106
+#define OBJ_title               OBJ_X509,12L
+
+#define LN_description          "description"
+#define NID_description         107
+#define OBJ_description         OBJ_X509,13L
+
+#define LN_searchGuide          "searchGuide"
+#define NID_searchGuide         859
+#define OBJ_searchGuide         OBJ_X509,14L
+
+#define LN_businessCategory             "businessCategory"
+#define NID_businessCategory            860
+#define OBJ_businessCategory            OBJ_X509,15L
+
+#define LN_postalAddress                "postalAddress"
+#define NID_postalAddress               861
+#define OBJ_postalAddress               OBJ_X509,16L
+
+#define LN_postalCode           "postalCode"
+#define NID_postalCode          661
+#define OBJ_postalCode          OBJ_X509,17L
+
+#define LN_postOfficeBox                "postOfficeBox"
+#define NID_postOfficeBox               862
+#define OBJ_postOfficeBox               OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName           "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName          863
+#define OBJ_physicalDeliveryOfficeName          OBJ_X509,19L
+
+#define LN_telephoneNumber              "telephoneNumber"
+#define NID_telephoneNumber             864
+#define OBJ_telephoneNumber             OBJ_X509,20L
+
+#define LN_telexNumber          "telexNumber"
+#define NID_telexNumber         865
+#define OBJ_telexNumber         OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier            "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier           866
+#define OBJ_teletexTerminalIdentifier           OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber             "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber            867
+#define OBJ_facsimileTelephoneNumber            OBJ_X509,23L
+
+#define LN_x121Address          "x121Address"
+#define NID_x121Address         868
+#define OBJ_x121Address         OBJ_X509,24L
+
+#define LN_internationaliSDNNumber              "internationaliSDNNumber"
+#define NID_internationaliSDNNumber             869
+#define OBJ_internationaliSDNNumber             OBJ_X509,25L
+
+#define LN_registeredAddress            "registeredAddress"
+#define NID_registeredAddress           870
+#define OBJ_registeredAddress           OBJ_X509,26L
+
+#define LN_destinationIndicator         "destinationIndicator"
+#define NID_destinationIndicator                871
+#define OBJ_destinationIndicator                OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod              "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod             872
+#define OBJ_preferredDeliveryMethod             OBJ_X509,28L
+
+#define LN_presentationAddress          "presentationAddress"
+#define NID_presentationAddress         873
+#define OBJ_presentationAddress         OBJ_X509,29L
+
+#define LN_supportedApplicationContext          "supportedApplicationContext"
+#define NID_supportedApplicationContext         874
+#define OBJ_supportedApplicationContext         OBJ_X509,30L
+
+#define SN_member               "member"
+#define NID_member              875
+#define OBJ_member              OBJ_X509,31L
+
+#define SN_owner                "owner"
+#define NID_owner               876
+#define OBJ_owner               OBJ_X509,32L
+
+#define LN_roleOccupant         "roleOccupant"
+#define NID_roleOccupant                877
+#define OBJ_roleOccupant                OBJ_X509,33L
+
+#define SN_seeAlso              "seeAlso"
+#define NID_seeAlso             878
+#define OBJ_seeAlso             OBJ_X509,34L
+
+#define LN_userPassword         "userPassword"
+#define NID_userPassword                879
+#define OBJ_userPassword                OBJ_X509,35L
+
+#define LN_userCertificate              "userCertificate"
+#define NID_userCertificate             880
+#define OBJ_userCertificate             OBJ_X509,36L
+
+#define LN_cACertificate                "cACertificate"
+#define NID_cACertificate               881
+#define OBJ_cACertificate               OBJ_X509,37L
+
+#define LN_authorityRevocationList              "authorityRevocationList"
+#define NID_authorityRevocationList             882
+#define OBJ_authorityRevocationList             OBJ_X509,38L
+
+#define LN_certificateRevocationList            "certificateRevocationList"
+#define NID_certificateRevocationList           883
+#define OBJ_certificateRevocationList           OBJ_X509,39L
+
+#define LN_crossCertificatePair         "crossCertificatePair"
+#define NID_crossCertificatePair                884
+#define OBJ_crossCertificatePair                OBJ_X509,40L
+
+#define SN_name         "name"
+#define LN_name         "name"
+#define NID_name                173
+#define OBJ_name                OBJ_X509,41L
+
+#define SN_givenName            "GN"
+#define LN_givenName            "givenName"
+#define NID_givenName           99
+#define OBJ_givenName           OBJ_X509,42L
+
+#define SN_initials             "initials"
+#define LN_initials             "initials"
+#define NID_initials            101
+#define OBJ_initials            OBJ_X509,43L
+
+#define LN_generationQualifier          "generationQualifier"
+#define NID_generationQualifier         509
+#define OBJ_generationQualifier         OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier         "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier                503
+#define OBJ_x500UniqueIdentifier                OBJ_X509,45L
+
+#define SN_dnQualifier          "dnQualifier"
+#define LN_dnQualifier          "dnQualifier"
+#define NID_dnQualifier         174
+#define OBJ_dnQualifier         OBJ_X509,46L
+
+#define LN_enhancedSearchGuide          "enhancedSearchGuide"
+#define NID_enhancedSearchGuide         885
+#define OBJ_enhancedSearchGuide         OBJ_X509,47L
+
+#define LN_protocolInformation          "protocolInformation"
+#define NID_protocolInformation         886
+#define OBJ_protocolInformation         OBJ_X509,48L
+
+#define LN_distinguishedName            "distinguishedName"
+#define NID_distinguishedName           887
+#define OBJ_distinguishedName           OBJ_X509,49L
+
+#define LN_uniqueMember         "uniqueMember"
+#define NID_uniqueMember                888
+#define OBJ_uniqueMember                OBJ_X509,50L
+
+#define LN_houseIdentifier              "houseIdentifier"
+#define NID_houseIdentifier             889
+#define OBJ_houseIdentifier             OBJ_X509,51L
+
+#define LN_supportedAlgorithms          "supportedAlgorithms"
+#define NID_supportedAlgorithms         890
+#define OBJ_supportedAlgorithms         OBJ_X509,52L
+
+#define LN_deltaRevocationList          "deltaRevocationList"
+#define NID_deltaRevocationList         891
+#define OBJ_deltaRevocationList         OBJ_X509,53L
+
+#define SN_dmdName              "dmdName"
+#define NID_dmdName             892
+#define OBJ_dmdName             OBJ_X509,54L
+
+#define LN_pseudonym            "pseudonym"
+#define NID_pseudonym           510
+#define OBJ_pseudonym           OBJ_X509,65L
+
+#define SN_role         "role"
+#define LN_role         "role"
+#define NID_role                400
+#define OBJ_role                OBJ_X509,72L
+
+#define SN_X500algorithms               "X500algorithms"
+#define LN_X500algorithms               "directory services - algorithms"
+#define NID_X500algorithms              378
+#define OBJ_X500algorithms              OBJ_X500,8L
+
+#define SN_rsa          "RSA"
+#define LN_rsa          "rsa"
+#define NID_rsa         19
+#define OBJ_rsa         OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA          "RSA-MDC2"
+#define LN_mdc2WithRSA          "mdc2WithRSA"
+#define NID_mdc2WithRSA         96
+#define OBJ_mdc2WithRSA         OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2         "MDC2"
+#define LN_mdc2         "mdc2"
+#define NID_mdc2                95
+#define OBJ_mdc2                OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce                "id-ce"
+#define NID_id_ce               81
+#define OBJ_id_ce               OBJ_X500,29L
+
+#define SN_subject_directory_attributes         "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes         "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes                769
+#define OBJ_subject_directory_attributes                OBJ_id_ce,9L
+
+#define SN_subject_key_identifier               "subjectKeyIdentifier"
+#define LN_subject_key_identifier               "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier              82
+#define OBJ_subject_key_identifier              OBJ_id_ce,14L
+
+#define SN_key_usage            "keyUsage"
+#define LN_key_usage            "X509v3 Key Usage"
+#define NID_key_usage           83
+#define OBJ_key_usage           OBJ_id_ce,15L
+
+#define SN_private_key_usage_period             "privateKeyUsagePeriod"
+#define LN_private_key_usage_period             "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period            84
+#define OBJ_private_key_usage_period            OBJ_id_ce,16L
+
+#define SN_subject_alt_name             "subjectAltName"
+#define LN_subject_alt_name             "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name            85
+#define OBJ_subject_alt_name            OBJ_id_ce,17L
+
+#define SN_issuer_alt_name              "issuerAltName"
+#define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name             86
+#define OBJ_issuer_alt_name             OBJ_id_ce,18L
+
+#define SN_basic_constraints            "basicConstraints"
+#define LN_basic_constraints            "X509v3 Basic Constraints"
+#define NID_basic_constraints           87
+#define OBJ_basic_constraints           OBJ_id_ce,19L
+
+#define SN_crl_number           "crlNumber"
+#define LN_crl_number           "X509v3 CRL Number"
+#define NID_crl_number          88
+#define OBJ_crl_number          OBJ_id_ce,20L
+
+#define SN_crl_reason           "CRLReason"
+#define LN_crl_reason           "X509v3 CRL Reason Code"
+#define NID_crl_reason          141
+#define OBJ_crl_reason          OBJ_id_ce,21L
+
+#define SN_invalidity_date              "invalidityDate"
+#define LN_invalidity_date              "Invalidity Date"
+#define NID_invalidity_date             142
+#define OBJ_invalidity_date             OBJ_id_ce,24L
+
+#define SN_delta_crl            "deltaCRL"
+#define LN_delta_crl            "X509v3 Delta CRL Indicator"
+#define NID_delta_crl           140
+#define OBJ_delta_crl           OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point           "issuingDistributionPoint"
+#define LN_issuing_distribution_point           "X509v3 Issuing Distrubution Point"
+#define NID_issuing_distribution_point          770
+#define OBJ_issuing_distribution_point          OBJ_id_ce,28L
+
+#define SN_certificate_issuer           "certificateIssuer"
+#define LN_certificate_issuer           "X509v3 Certificate Issuer"
+#define NID_certificate_issuer          771
+#define OBJ_certificate_issuer          OBJ_id_ce,29L
+
+#define SN_name_constraints             "nameConstraints"
+#define LN_name_constraints             "X509v3 Name Constraints"
+#define NID_name_constraints            666
+#define OBJ_name_constraints            OBJ_id_ce,30L
+
+#define SN_crl_distribution_points              "crlDistributionPoints"
+#define LN_crl_distribution_points              "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points             103
+#define OBJ_crl_distribution_points             OBJ_id_ce,31L
+
+#define SN_certificate_policies         "certificatePolicies"
+#define LN_certificate_policies         "X509v3 Certificate Policies"
+#define NID_certificate_policies                89
+#define OBJ_certificate_policies                OBJ_id_ce,32L
+
+#define SN_any_policy           "anyPolicy"
+#define LN_any_policy           "X509v3 Any Policy"
+#define NID_any_policy          746
+#define OBJ_any_policy          OBJ_certificate_policies,0L
+
+#define SN_policy_mappings              "policyMappings"
+#define LN_policy_mappings              "X509v3 Policy Mappings"
+#define NID_policy_mappings             747
+#define OBJ_policy_mappings             OBJ_id_ce,33L
+
+#define SN_authority_key_identifier             "authorityKeyIdentifier"
+#define LN_authority_key_identifier             "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier            90
+#define OBJ_authority_key_identifier            OBJ_id_ce,35L
+
+#define SN_policy_constraints           "policyConstraints"
+#define LN_policy_constraints           "X509v3 Policy Constraints"
+#define NID_policy_constraints          401
+#define OBJ_policy_constraints          OBJ_id_ce,36L
+
+#define SN_ext_key_usage                "extendedKeyUsage"
+#define LN_ext_key_usage                "X509v3 Extended Key Usage"
+#define NID_ext_key_usage               126
+#define OBJ_ext_key_usage               OBJ_id_ce,37L
+
+#define SN_freshest_crl         "freshestCRL"
+#define LN_freshest_crl         "X509v3 Freshest CRL"
+#define NID_freshest_crl                857
+#define OBJ_freshest_crl                OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy           "inhibitAnyPolicy"
+#define LN_inhibit_any_policy           "X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy          748
+#define OBJ_inhibit_any_policy          OBJ_id_ce,54L
+
+#define SN_target_information           "targetInformation"
+#define LN_target_information           "X509v3 AC Targeting"
+#define NID_target_information          402
+#define OBJ_target_information          OBJ_id_ce,55L
+
+#define SN_no_rev_avail         "noRevAvail"
+#define LN_no_rev_avail         "X509v3 No Revocation Available"
+#define NID_no_rev_avail                403
+#define OBJ_no_rev_avail                OBJ_id_ce,56L
+
+#define SN_anyExtendedKeyUsage          "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage          "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage         910
+#define OBJ_anyExtendedKeyUsage         OBJ_ext_key_usage,0L
+
+#define SN_netscape             "Netscape"
+#define LN_netscape             "Netscape Communications Corp."
+#define NID_netscape            57
+#define OBJ_netscape            2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension              "nsCertExt"
+#define LN_netscape_cert_extension              "Netscape Certificate Extension"
+#define NID_netscape_cert_extension             58
+#define OBJ_netscape_cert_extension             OBJ_netscape,1L
+
+#define SN_netscape_data_type           "nsDataType"
+#define LN_netscape_data_type           "Netscape Data Type"
+#define NID_netscape_data_type          59
+#define OBJ_netscape_data_type          OBJ_netscape,2L
+
+#define SN_netscape_cert_type           "nsCertType"
+#define LN_netscape_cert_type           "Netscape Cert Type"
+#define NID_netscape_cert_type          71
+#define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url            "nsBaseUrl"
+#define LN_netscape_base_url            "Netscape Base Url"
+#define NID_netscape_base_url           72
+#define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url              "nsRevocationUrl"
+#define LN_netscape_revocation_url              "Netscape Revocation Url"
+#define NID_netscape_revocation_url             73
+#define OBJ_netscape_revocation_url             OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url           "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url           "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url          74
+#define OBJ_netscape_ca_revocation_url          OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url         "nsRenewalUrl"
+#define LN_netscape_renewal_url         "Netscape Renewal Url"
+#define NID_netscape_renewal_url                75
+#define OBJ_netscape_renewal_url                OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url               "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url               "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url              76
+#define OBJ_netscape_ca_policy_url              OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name             "nsSslServerName"
+#define LN_netscape_ssl_server_name             "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name            77
+#define OBJ_netscape_ssl_server_name            OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment             "nsComment"
+#define LN_netscape_comment             "Netscape Comment"
+#define NID_netscape_comment            78
+#define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence               "nsCertSequence"
+#define LN_netscape_cert_sequence               "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence              79
+#define OBJ_netscape_cert_sequence              OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc               "nsSGC"
+#define LN_ns_sgc               "Netscape Server Gated Crypto"
+#define NID_ns_sgc              139
+#define OBJ_ns_sgc              OBJ_netscape,4L,1L
+
+#define SN_org          "ORG"
+#define LN_org          "org"
+#define NID_org         379
+#define OBJ_org         OBJ_iso,3L
+
+#define SN_dod          "DOD"
+#define LN_dod          "dod"
+#define NID_dod         380
+#define OBJ_dod         OBJ_org,6L
+
+#define SN_iana         "IANA"
+#define LN_iana         "iana"
+#define NID_iana                381
+#define OBJ_iana                OBJ_dod,1L
+
+#define OBJ_internet            OBJ_iana
+
+#define SN_Directory            "directory"
+#define LN_Directory            "Directory"
+#define NID_Directory           382
+#define OBJ_Directory           OBJ_internet,1L
+
+#define SN_Management           "mgmt"
+#define LN_Management           "Management"
+#define NID_Management          383
+#define OBJ_Management          OBJ_internet,2L
+
+#define SN_Experimental         "experimental"
+#define LN_Experimental         "Experimental"
+#define NID_Experimental                384
+#define OBJ_Experimental                OBJ_internet,3L
+
+#define SN_Private              "private"
+#define LN_Private              "Private"
+#define NID_Private             385
+#define OBJ_Private             OBJ_internet,4L
+
+#define SN_Security             "security"
+#define LN_Security             "Security"
+#define NID_Security            386
+#define OBJ_Security            OBJ_internet,5L
+
+#define SN_SNMPv2               "snmpv2"
+#define LN_SNMPv2               "SNMPv2"
+#define NID_SNMPv2              387
+#define OBJ_SNMPv2              OBJ_internet,6L
+
+#define LN_Mail         "Mail"
+#define NID_Mail                388
+#define OBJ_Mail                OBJ_internet,7L
+
+#define SN_Enterprises          "enterprises"
+#define LN_Enterprises          "Enterprises"
+#define NID_Enterprises         389
+#define OBJ_Enterprises         OBJ_Private,1L
+
+#define SN_dcObject             "dcobject"
+#define LN_dcObject             "dcObject"
+#define NID_dcObject            390
+#define OBJ_dcObject            OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs             "mime-mhs"
+#define LN_mime_mhs             "MIME MHS"
+#define NID_mime_mhs            504
+#define OBJ_mime_mhs            OBJ_Mail,1L
+
+#define SN_mime_mhs_headings            "mime-mhs-headings"
+#define LN_mime_mhs_headings            "mime-mhs-headings"
+#define NID_mime_mhs_headings           505
+#define OBJ_mime_mhs_headings           OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies              "mime-mhs-bodies"
+#define LN_mime_mhs_bodies              "mime-mhs-bodies"
+#define NID_mime_mhs_bodies             506
+#define OBJ_mime_mhs_bodies             OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message               "id-hex-partial-message"
+#define LN_id_hex_partial_message               "id-hex-partial-message"
+#define NID_id_hex_partial_message              507
+#define OBJ_id_hex_partial_message              OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message             "id-hex-multipart-message"
+#define LN_id_hex_multipart_message             "id-hex-multipart-message"
+#define NID_id_hex_multipart_message            508
+#define OBJ_id_hex_multipart_message            OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression              "RLE"
+#define LN_rle_compression              "run length compression"
+#define NID_rle_compression             124
+#define OBJ_rle_compression             1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression             "ZLIB"
+#define LN_zlib_compression             "zlib compression"
+#define NID_zlib_compression            125
+#define OBJ_zlib_compression            OBJ_id_smime_alg,8L
+
+#define OBJ_csor                2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms              OBJ_csor,4L
+
+#define OBJ_aes         OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb          "AES-128-ECB"
+#define LN_aes_128_ecb          "aes-128-ecb"
+#define NID_aes_128_ecb         418
+#define OBJ_aes_128_ecb         OBJ_aes,1L
+
+#define SN_aes_128_cbc          "AES-128-CBC"
+#define LN_aes_128_cbc          "aes-128-cbc"
+#define NID_aes_128_cbc         419
+#define OBJ_aes_128_cbc         OBJ_aes,2L
+
+#define SN_aes_128_ofb128               "AES-128-OFB"
+#define LN_aes_128_ofb128               "aes-128-ofb"
+#define NID_aes_128_ofb128              420
+#define OBJ_aes_128_ofb128              OBJ_aes,3L
+
+#define SN_aes_128_cfb128               "AES-128-CFB"
+#define LN_aes_128_cfb128               "aes-128-cfb"
+#define NID_aes_128_cfb128              421
+#define OBJ_aes_128_cfb128              OBJ_aes,4L
+
+#define SN_id_aes128_wrap               "id-aes128-wrap"
+#define NID_id_aes128_wrap              788
+#define OBJ_id_aes128_wrap              OBJ_aes,5L
+
+#define SN_aes_128_gcm          "id-aes128-GCM"
+#define LN_aes_128_gcm          "aes-128-gcm"
+#define NID_aes_128_gcm         895
+#define OBJ_aes_128_gcm         OBJ_aes,6L
+
+#define SN_aes_128_ccm          "id-aes128-CCM"
+#define LN_aes_128_ccm          "aes-128-ccm"
+#define NID_aes_128_ccm         896
+#define OBJ_aes_128_ccm         OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad           "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad          897
+#define OBJ_id_aes128_wrap_pad          OBJ_aes,8L
+
+#define SN_aes_192_ecb          "AES-192-ECB"
+#define LN_aes_192_ecb          "aes-192-ecb"
+#define NID_aes_192_ecb         422
+#define OBJ_aes_192_ecb         OBJ_aes,21L
+
+#define SN_aes_192_cbc          "AES-192-CBC"
+#define LN_aes_192_cbc          "aes-192-cbc"
+#define NID_aes_192_cbc         423
+#define OBJ_aes_192_cbc         OBJ_aes,22L
+
+#define SN_aes_192_ofb128               "AES-192-OFB"
+#define LN_aes_192_ofb128               "aes-192-ofb"
+#define NID_aes_192_ofb128              424
+#define OBJ_aes_192_ofb128              OBJ_aes,23L
+
+#define SN_aes_192_cfb128               "AES-192-CFB"
+#define LN_aes_192_cfb128               "aes-192-cfb"
+#define NID_aes_192_cfb128              425
+#define OBJ_aes_192_cfb128              OBJ_aes,24L
+
+#define SN_id_aes192_wrap               "id-aes192-wrap"
+#define NID_id_aes192_wrap              789
+#define OBJ_id_aes192_wrap              OBJ_aes,25L
+
+#define SN_aes_192_gcm          "id-aes192-GCM"
+#define LN_aes_192_gcm          "aes-192-gcm"
+#define NID_aes_192_gcm         898
+#define OBJ_aes_192_gcm         OBJ_aes,26L
+
+#define SN_aes_192_ccm          "id-aes192-CCM"
+#define LN_aes_192_ccm          "aes-192-ccm"
+#define NID_aes_192_ccm         899
+#define OBJ_aes_192_ccm         OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad           "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad          900
+#define OBJ_id_aes192_wrap_pad          OBJ_aes,28L
+
+#define SN_aes_256_ecb          "AES-256-ECB"
+#define LN_aes_256_ecb          "aes-256-ecb"
+#define NID_aes_256_ecb         426
+#define OBJ_aes_256_ecb         OBJ_aes,41L
+
+#define SN_aes_256_cbc          "AES-256-CBC"
+#define LN_aes_256_cbc          "aes-256-cbc"
+#define NID_aes_256_cbc         427
+#define OBJ_aes_256_cbc         OBJ_aes,42L
+
+#define SN_aes_256_ofb128               "AES-256-OFB"
+#define LN_aes_256_ofb128               "aes-256-ofb"
+#define NID_aes_256_ofb128              428
+#define OBJ_aes_256_ofb128              OBJ_aes,43L
+
+#define SN_aes_256_cfb128               "AES-256-CFB"
+#define LN_aes_256_cfb128               "aes-256-cfb"
+#define NID_aes_256_cfb128              429
+#define OBJ_aes_256_cfb128              OBJ_aes,44L
+
+#define SN_id_aes256_wrap               "id-aes256-wrap"
+#define NID_id_aes256_wrap              790
+#define OBJ_id_aes256_wrap              OBJ_aes,45L
+
+#define SN_aes_256_gcm          "id-aes256-GCM"
+#define LN_aes_256_gcm          "aes-256-gcm"
+#define NID_aes_256_gcm         901
+#define OBJ_aes_256_gcm         OBJ_aes,46L
+
+#define SN_aes_256_ccm          "id-aes256-CCM"
+#define LN_aes_256_ccm          "aes-256-ccm"
+#define NID_aes_256_ccm         902
+#define OBJ_aes_256_ccm         OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad           "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad          903
+#define OBJ_id_aes256_wrap_pad          OBJ_aes,48L
+
+#define SN_aes_128_cfb1         "AES-128-CFB1"
+#define LN_aes_128_cfb1         "aes-128-cfb1"
+#define NID_aes_128_cfb1                650
+
+#define SN_aes_192_cfb1         "AES-192-CFB1"
+#define LN_aes_192_cfb1         "aes-192-cfb1"
+#define NID_aes_192_cfb1                651
+
+#define SN_aes_256_cfb1         "AES-256-CFB1"
+#define LN_aes_256_cfb1         "aes-256-cfb1"
+#define NID_aes_256_cfb1                652
+
+#define SN_aes_128_cfb8         "AES-128-CFB8"
+#define LN_aes_128_cfb8         "aes-128-cfb8"
+#define NID_aes_128_cfb8                653
+
+#define SN_aes_192_cfb8         "AES-192-CFB8"
+#define LN_aes_192_cfb8         "aes-192-cfb8"
+#define NID_aes_192_cfb8                654
+
+#define SN_aes_256_cfb8         "AES-256-CFB8"
+#define LN_aes_256_cfb8         "aes-256-cfb8"
+#define NID_aes_256_cfb8                655
+
+#define SN_aes_128_ctr          "AES-128-CTR"
+#define LN_aes_128_ctr          "aes-128-ctr"
+#define NID_aes_128_ctr         904
+
+#define SN_aes_192_ctr          "AES-192-CTR"
+#define LN_aes_192_ctr          "aes-192-ctr"
+#define NID_aes_192_ctr         905
+
+#define SN_aes_256_ctr          "AES-256-CTR"
+#define LN_aes_256_ctr          "aes-256-ctr"
+#define NID_aes_256_ctr         906
+
+#define SN_aes_128_xts          "AES-128-XTS"
+#define LN_aes_128_xts          "aes-128-xts"
+#define NID_aes_128_xts         913
+
+#define SN_aes_256_xts          "AES-256-XTS"
+#define LN_aes_256_xts          "aes-256-xts"
+#define NID_aes_256_xts         914
+
+#define SN_des_cfb1             "DES-CFB1"
+#define LN_des_cfb1             "des-cfb1"
+#define NID_des_cfb1            656
+
+#define SN_des_cfb8             "DES-CFB8"
+#define LN_des_cfb8             "des-cfb8"
+#define NID_des_cfb8            657
+
+#define SN_des_ede3_cfb1                "DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1                "des-ede3-cfb1"
+#define NID_des_ede3_cfb1               658
+
+#define SN_des_ede3_cfb8                "DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8                "des-ede3-cfb8"
+#define NID_des_ede3_cfb8               659
+
+#define OBJ_nist_hashalgs               OBJ_nistAlgorithms,2L
+
+#define SN_sha256               "SHA256"
+#define LN_sha256               "sha256"
+#define NID_sha256              672
+#define OBJ_sha256              OBJ_nist_hashalgs,1L
+
+#define SN_sha384               "SHA384"
+#define LN_sha384               "sha384"
+#define NID_sha384              673
+#define OBJ_sha384              OBJ_nist_hashalgs,2L
+
+#define SN_sha512               "SHA512"
+#define LN_sha512               "sha512"
+#define NID_sha512              674
+#define OBJ_sha512              OBJ_nist_hashalgs,3L
+
+#define SN_sha224               "SHA224"
+#define LN_sha224               "sha224"
+#define NID_sha224              675
+#define OBJ_sha224              OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2               OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224              "dsa_with_SHA224"
+#define NID_dsa_with_SHA224             802
+#define OBJ_dsa_with_SHA224             OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256              "dsa_with_SHA256"
+#define NID_dsa_with_SHA256             803
+#define OBJ_dsa_with_SHA256             OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code                "holdInstructionCode"
+#define LN_hold_instruction_code                "Hold Instruction Code"
+#define NID_hold_instruction_code               430
+#define OBJ_hold_instruction_code               OBJ_id_ce,23L
+
+#define OBJ_holdInstruction             OBJ_X9_57,2L
+
+#define SN_hold_instruction_none                "holdInstructionNone"
+#define LN_hold_instruction_none                "Hold Instruction None"
+#define NID_hold_instruction_none               431
+#define OBJ_hold_instruction_none               OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer         "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer         "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer                432
+#define OBJ_hold_instruction_call_issuer                OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject              "holdInstructionReject"
+#define LN_hold_instruction_reject              "Hold Instruction Reject"
+#define NID_hold_instruction_reject             433
+#define OBJ_hold_instruction_reject             OBJ_holdInstruction,3L
+
+#define SN_data         "data"
+#define NID_data                434
+#define OBJ_data                OBJ_itu_t,9L
+
+#define SN_pss          "pss"
+#define NID_pss         435
+#define OBJ_pss         OBJ_data,2342L
+
+#define SN_ucl          "ucl"
+#define NID_ucl         436
+#define OBJ_ucl         OBJ_pss,19200300L
+
+#define SN_pilot                "pilot"
+#define NID_pilot               437
+#define OBJ_pilot               OBJ_ucl,100L
+
+#define LN_pilotAttributeType           "pilotAttributeType"
+#define NID_pilotAttributeType          438
+#define OBJ_pilotAttributeType          OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax         "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax                439
+#define OBJ_pilotAttributeSyntax                OBJ_pilot,3L
+
+#define LN_pilotObjectClass             "pilotObjectClass"
+#define NID_pilotObjectClass            440
+#define OBJ_pilotObjectClass            OBJ_pilot,4L
+
+#define LN_pilotGroups          "pilotGroups"
+#define NID_pilotGroups         441
+#define OBJ_pilotGroups         OBJ_pilot,10L
+
+#define LN_iA5StringSyntax              "iA5StringSyntax"
+#define NID_iA5StringSyntax             442
+#define OBJ_iA5StringSyntax             OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax            "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax           443
+#define OBJ_caseIgnoreIA5StringSyntax           OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject          "pilotObject"
+#define NID_pilotObject         444
+#define OBJ_pilotObject         OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson          "pilotPerson"
+#define NID_pilotPerson         445
+#define OBJ_pilotPerson         OBJ_pilotObjectClass,4L
+
+#define SN_account              "account"
+#define NID_account             446
+#define OBJ_account             OBJ_pilotObjectClass,5L
+
+#define SN_document             "document"
+#define NID_document            447
+#define OBJ_document            OBJ_pilotObjectClass,6L
+
+#define SN_room         "room"
+#define NID_room                448
+#define OBJ_room                OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries               "documentSeries"
+#define NID_documentSeries              449
+#define OBJ_documentSeries              OBJ_pilotObjectClass,9L
+
+#define SN_Domain               "domain"
+#define LN_Domain               "Domain"
+#define NID_Domain              392
+#define OBJ_Domain              OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart              "rFC822localPart"
+#define NID_rFC822localPart             450
+#define OBJ_rFC822localPart             OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain            "dNSDomain"
+#define NID_dNSDomain           451
+#define OBJ_dNSDomain           OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject          "domainRelatedObject"
+#define NID_domainRelatedObject         452
+#define OBJ_domainRelatedObject         OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry              "friendlyCountry"
+#define NID_friendlyCountry             453
+#define OBJ_friendlyCountry             OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject         "simpleSecurityObject"
+#define NID_simpleSecurityObject                454
+#define OBJ_simpleSecurityObject                OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization            "pilotOrganization"
+#define NID_pilotOrganization           455
+#define OBJ_pilotOrganization           OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA             "pilotDSA"
+#define NID_pilotDSA            456
+#define OBJ_pilotDSA            OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData          "qualityLabelledData"
+#define NID_qualityLabelledData         457
+#define OBJ_qualityLabelledData         OBJ_pilotObjectClass,22L
+
+#define SN_userId               "UID"
+#define LN_userId               "userId"
+#define NID_userId              458
+#define OBJ_userId              OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress         "textEncodedORAddress"
+#define NID_textEncodedORAddress                459
+#define OBJ_textEncodedORAddress                OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox                "mail"
+#define LN_rfc822Mailbox                "rfc822Mailbox"
+#define NID_rfc822Mailbox               460
+#define OBJ_rfc822Mailbox               OBJ_pilotAttributeType,3L
+
+#define SN_info         "info"
+#define NID_info                461
+#define OBJ_info                OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink               "favouriteDrink"
+#define NID_favouriteDrink              462
+#define OBJ_favouriteDrink              OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber           "roomNumber"
+#define NID_roomNumber          463
+#define OBJ_roomNumber          OBJ_pilotAttributeType,6L
+
+#define SN_photo                "photo"
+#define NID_photo               464
+#define OBJ_photo               OBJ_pilotAttributeType,7L
+
+#define LN_userClass            "userClass"
+#define NID_userClass           465
+#define OBJ_userClass           OBJ_pilotAttributeType,8L
+
+#define SN_host         "host"
+#define NID_host                466
+#define OBJ_host                OBJ_pilotAttributeType,9L
+
+#define SN_manager              "manager"
+#define NID_manager             467
+#define OBJ_manager             OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier           "documentIdentifier"
+#define NID_documentIdentifier          468
+#define OBJ_documentIdentifier          OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle                "documentTitle"
+#define NID_documentTitle               469
+#define OBJ_documentTitle               OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion              "documentVersion"
+#define NID_documentVersion             470
+#define OBJ_documentVersion             OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor               "documentAuthor"
+#define NID_documentAuthor              471
+#define OBJ_documentAuthor              OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation             "documentLocation"
+#define NID_documentLocation            472
+#define OBJ_documentLocation            OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber          "homeTelephoneNumber"
+#define NID_homeTelephoneNumber         473
+#define OBJ_homeTelephoneNumber         OBJ_pilotAttributeType,20L
+
+#define SN_secretary            "secretary"
+#define NID_secretary           474
+#define OBJ_secretary           OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox         "otherMailbox"
+#define NID_otherMailbox                475
+#define OBJ_otherMailbox                OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime             "lastModifiedTime"
+#define NID_lastModifiedTime            476
+#define OBJ_lastModifiedTime            OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy               "lastModifiedBy"
+#define NID_lastModifiedBy              477
+#define OBJ_lastModifiedBy              OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent              "DC"
+#define LN_domainComponent              "domainComponent"
+#define NID_domainComponent             391
+#define OBJ_domainComponent             OBJ_pilotAttributeType,25L
+
+#define LN_aRecord              "aRecord"
+#define NID_aRecord             478
+#define OBJ_aRecord             OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27         "pilotAttributeType27"
+#define NID_pilotAttributeType27                479
+#define OBJ_pilotAttributeType27                OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord             "mXRecord"
+#define NID_mXRecord            480
+#define OBJ_mXRecord            OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord             "nSRecord"
+#define NID_nSRecord            481
+#define OBJ_nSRecord            OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord            "sOARecord"
+#define NID_sOARecord           482
+#define OBJ_sOARecord           OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord          "cNAMERecord"
+#define NID_cNAMERecord         483
+#define OBJ_cNAMERecord         OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain             "associatedDomain"
+#define NID_associatedDomain            484
+#define OBJ_associatedDomain            OBJ_pilotAttributeType,37L
+
+#define LN_associatedName               "associatedName"
+#define NID_associatedName              485
+#define OBJ_associatedName              OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress            "homePostalAddress"
+#define NID_homePostalAddress           486
+#define OBJ_homePostalAddress           OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle                "personalTitle"
+#define NID_personalTitle               487
+#define OBJ_personalTitle               OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber                "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber               488
+#define OBJ_mobileTelephoneNumber               OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber         "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber                489
+#define OBJ_pagerTelephoneNumber                OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName          "friendlyCountryName"
+#define NID_friendlyCountryName         490
+#define OBJ_friendlyCountryName         OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus         "organizationalStatus"
+#define NID_organizationalStatus                491
+#define OBJ_organizationalStatus                OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox         "janetMailbox"
+#define NID_janetMailbox                492
+#define OBJ_janetMailbox                OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption         "mailPreferenceOption"
+#define NID_mailPreferenceOption                493
+#define OBJ_mailPreferenceOption                OBJ_pilotAttributeType,47L
+
+#define LN_buildingName         "buildingName"
+#define NID_buildingName                494
+#define OBJ_buildingName                OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality           "dSAQuality"
+#define NID_dSAQuality          495
+#define OBJ_dSAQuality          OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality           "singleLevelQuality"
+#define NID_singleLevelQuality          496
+#define OBJ_singleLevelQuality          OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality                "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality               497
+#define OBJ_subtreeMinimumQuality               OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality                "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality               498
+#define OBJ_subtreeMaximumQuality               OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature            "personalSignature"
+#define NID_personalSignature           499
+#define OBJ_personalSignature           OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect          "dITRedirect"
+#define NID_dITRedirect         500
+#define OBJ_dITRedirect         OBJ_pilotAttributeType,54L
+
+#define SN_audio                "audio"
+#define NID_audio               501
+#define OBJ_audio               OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher            "documentPublisher"
+#define NID_documentPublisher           502
+#define OBJ_documentPublisher           OBJ_pilotAttributeType,56L
+
+#define SN_id_set               "id-set"
+#define LN_id_set               "Secure Electronic Transactions"
+#define NID_id_set              512
+#define OBJ_id_set              OBJ_international_organizations,42L
+
+#define SN_set_ctype            "set-ctype"
+#define LN_set_ctype            "content types"
+#define NID_set_ctype           513
+#define OBJ_set_ctype           OBJ_id_set,0L
+
+#define SN_set_msgExt           "set-msgExt"
+#define LN_set_msgExt           "message extensions"
+#define NID_set_msgExt          514
+#define OBJ_set_msgExt          OBJ_id_set,1L
+
+#define SN_set_attr             "set-attr"
+#define NID_set_attr            515
+#define OBJ_set_attr            OBJ_id_set,3L
+
+#define SN_set_policy           "set-policy"
+#define NID_set_policy          516
+#define OBJ_set_policy          OBJ_id_set,5L
+
+#define SN_set_certExt          "set-certExt"
+#define LN_set_certExt          "certificate extensions"
+#define NID_set_certExt         517
+#define OBJ_set_certExt         OBJ_id_set,7L
+
+#define SN_set_brand            "set-brand"
+#define NID_set_brand           518
+#define OBJ_set_brand           OBJ_id_set,8L
+
+#define SN_setct_PANData                "setct-PANData"
+#define NID_setct_PANData               519
+#define OBJ_setct_PANData               OBJ_set_ctype,0L
+
+#define SN_setct_PANToken               "setct-PANToken"
+#define NID_setct_PANToken              520
+#define OBJ_setct_PANToken              OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly                "setct-PANOnly"
+#define NID_setct_PANOnly               521
+#define OBJ_setct_PANOnly               OBJ_set_ctype,2L
+
+#define SN_setct_OIData         "setct-OIData"
+#define NID_setct_OIData                522
+#define OBJ_setct_OIData                OBJ_set_ctype,3L
+
+#define SN_setct_PI             "setct-PI"
+#define NID_setct_PI            523
+#define OBJ_setct_PI            OBJ_set_ctype,4L
+
+#define SN_setct_PIData         "setct-PIData"
+#define NID_setct_PIData                524
+#define OBJ_setct_PIData                OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned         "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned                525
+#define OBJ_setct_PIDataUnsigned                OBJ_set_ctype,6L
+
+#define SN_setct_HODInput               "setct-HODInput"
+#define NID_setct_HODInput              526
+#define OBJ_setct_HODInput              OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage         "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage                527
+#define OBJ_setct_AuthResBaggage                OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage              "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage             528
+#define OBJ_setct_AuthRevReqBaggage             OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage              "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage             529
+#define OBJ_setct_AuthRevResBaggage             OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq            "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq           530
+#define OBJ_setct_CapTokenSeq           OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData           "setct-PInitResData"
+#define NID_setct_PInitResData          531
+#define OBJ_setct_PInitResData          OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS         "setct-PI-TBS"
+#define NID_setct_PI_TBS                532
+#define OBJ_setct_PI_TBS                OBJ_set_ctype,13L
+
+#define SN_setct_PResData               "setct-PResData"
+#define NID_setct_PResData              533
+#define OBJ_setct_PResData              OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS             "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS            534
+#define OBJ_setct_AuthReqTBS            OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS             "setct-AuthResTBS"
+#define NID_setct_AuthResTBS            535
+#define OBJ_setct_AuthResTBS            OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX            "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX           536
+#define OBJ_setct_AuthResTBSX           OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS           "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS          537
+#define OBJ_setct_AuthTokenTBS          OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData           "setct-CapTokenData"
+#define NID_setct_CapTokenData          538
+#define OBJ_setct_CapTokenData          OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS            "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS           539
+#define OBJ_setct_CapTokenTBS           OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg         "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg                540
+#define OBJ_setct_AcqCardCodeMsg                OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS          "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS         541
+#define OBJ_setct_AuthRevReqTBS         OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData         "setct-AuthRevResData"
+#define NID_setct_AuthRevResData                542
+#define OBJ_setct_AuthRevResData                OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS          "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS         543
+#define OBJ_setct_AuthRevResTBS         OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS              "setct-CapReqTBS"
+#define NID_setct_CapReqTBS             544
+#define OBJ_setct_CapReqTBS             OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX             "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX            545
+#define OBJ_setct_CapReqTBSX            OBJ_set_ctype,27L
+
+#define SN_setct_CapResData             "setct-CapResData"
+#define NID_setct_CapResData            546
+#define OBJ_setct_CapResData            OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS           "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS          547
+#define OBJ_setct_CapRevReqTBS          OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX          "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX         548
+#define OBJ_setct_CapRevReqTBSX         OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData          "setct-CapRevResData"
+#define NID_setct_CapRevResData         549
+#define OBJ_setct_CapRevResData         OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS             "setct-CredReqTBS"
+#define NID_setct_CredReqTBS            550
+#define OBJ_setct_CredReqTBS            OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX            "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX           551
+#define OBJ_setct_CredReqTBSX           OBJ_set_ctype,33L
+
+#define SN_setct_CredResData            "setct-CredResData"
+#define NID_setct_CredResData           552
+#define OBJ_setct_CredResData           OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS          "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS         553
+#define OBJ_setct_CredRevReqTBS         OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX         "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX                554
+#define OBJ_setct_CredRevReqTBSX                OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData         "setct-CredRevResData"
+#define NID_setct_CredRevResData                555
+#define OBJ_setct_CredRevResData                OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData           "setct-PCertReqData"
+#define NID_setct_PCertReqData          556
+#define OBJ_setct_PCertReqData          OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS            "setct-PCertResTBS"
+#define NID_setct_PCertResTBS           557
+#define OBJ_setct_PCertResTBS           OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData              "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData             558
+#define OBJ_setct_BatchAdminReqData             OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData              "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData             559
+#define OBJ_setct_BatchAdminResData             OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS                "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS               560
+#define OBJ_setct_CardCInitResTBS               OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS                "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS               561
+#define OBJ_setct_MeAqCInitResTBS               OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS          "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS         562
+#define OBJ_setct_RegFormResTBS         OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData            "setct-CertReqData"
+#define NID_setct_CertReqData           563
+#define OBJ_setct_CertReqData           OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS             "setct-CertReqTBS"
+#define NID_setct_CertReqTBS            564
+#define OBJ_setct_CertReqTBS            OBJ_set_ctype,46L
+
+#define SN_setct_CertResData            "setct-CertResData"
+#define NID_setct_CertResData           565
+#define OBJ_setct_CertResData           OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS          "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS         566
+#define OBJ_setct_CertInqReqTBS         OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS               "setct-ErrorTBS"
+#define NID_setct_ErrorTBS              567
+#define OBJ_setct_ErrorTBS              OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE                "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE               568
+#define OBJ_setct_PIDualSignedTBE               OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE          "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE         569
+#define OBJ_setct_PIUnsignedTBE         OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE             "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE            570
+#define OBJ_setct_AuthReqTBE            OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE             "setct-AuthResTBE"
+#define NID_setct_AuthResTBE            571
+#define OBJ_setct_AuthResTBE            OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX            "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX           572
+#define OBJ_setct_AuthResTBEX           OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE           "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE          573
+#define OBJ_setct_AuthTokenTBE          OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE            "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE           574
+#define OBJ_setct_CapTokenTBE           OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX           "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX          575
+#define OBJ_setct_CapTokenTBEX          OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE              "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE             576
+#define OBJ_setct_AcqCardCodeMsgTBE             OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE          "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE         577
+#define OBJ_setct_AuthRevReqTBE         OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE          "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE         578
+#define OBJ_setct_AuthRevResTBE         OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB         "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB                579
+#define OBJ_setct_AuthRevResTBEB                OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE              "setct-CapReqTBE"
+#define NID_setct_CapReqTBE             580
+#define OBJ_setct_CapReqTBE             OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX             "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX            581
+#define OBJ_setct_CapReqTBEX            OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE              "setct-CapResTBE"
+#define NID_setct_CapResTBE             582
+#define OBJ_setct_CapResTBE             OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE           "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE          583
+#define OBJ_setct_CapRevReqTBE          OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX          "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX         584
+#define OBJ_setct_CapRevReqTBEX         OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE           "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE          585
+#define OBJ_setct_CapRevResTBE          OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE             "setct-CredReqTBE"
+#define NID_setct_CredReqTBE            586
+#define OBJ_setct_CredReqTBE            OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX            "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX           587
+#define OBJ_setct_CredReqTBEX           OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE             "setct-CredResTBE"
+#define NID_setct_CredResTBE            588
+#define OBJ_setct_CredResTBE            OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE          "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE         589
+#define OBJ_setct_CredRevReqTBE         OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX         "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX                590
+#define OBJ_setct_CredRevReqTBEX                OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE          "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE         591
+#define OBJ_setct_CredRevResTBE         OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE               "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE              592
+#define OBJ_setct_BatchAdminReqTBE              OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE               "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE              593
+#define OBJ_setct_BatchAdminResTBE              OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE          "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE         594
+#define OBJ_setct_RegFormReqTBE         OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE             "setct-CertReqTBE"
+#define NID_setct_CertReqTBE            595
+#define OBJ_setct_CertReqTBE            OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX            "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX           596
+#define OBJ_setct_CertReqTBEX           OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE             "setct-CertResTBE"
+#define NID_setct_CertResTBE            597
+#define OBJ_setct_CertResTBE            OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS             "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS            598
+#define OBJ_setct_CRLNotificationTBS            OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS          "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS         599
+#define OBJ_setct_CRLNotificationResTBS         OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS             "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS            600
+#define OBJ_setct_BCIDistributionTBS            OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt              "setext-genCrypt"
+#define LN_setext_genCrypt              "generic cryptogram"
+#define NID_setext_genCrypt             601
+#define OBJ_setext_genCrypt             OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth                "setext-miAuth"
+#define LN_setext_miAuth                "merchant initiated auth"
+#define NID_setext_miAuth               602
+#define OBJ_setext_miAuth               OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure             "setext-pinSecure"
+#define NID_setext_pinSecure            603
+#define OBJ_setext_pinSecure            OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny                "setext-pinAny"
+#define NID_setext_pinAny               604
+#define OBJ_setext_pinAny               OBJ_set_msgExt,5L
+
+#define SN_setext_track2                "setext-track2"
+#define NID_setext_track2               605
+#define OBJ_setext_track2               OBJ_set_msgExt,7L
+
+#define SN_setext_cv            "setext-cv"
+#define LN_setext_cv            "additional verification"
+#define NID_setext_cv           606
+#define OBJ_setext_cv           OBJ_set_msgExt,8L
+
+#define SN_set_policy_root              "set-policy-root"
+#define NID_set_policy_root             607
+#define OBJ_set_policy_root             OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot           "setCext-hashedRoot"
+#define NID_setCext_hashedRoot          608
+#define OBJ_setCext_hashedRoot          OBJ_set_certExt,0L
+
+#define SN_setCext_certType             "setCext-certType"
+#define NID_setCext_certType            609
+#define OBJ_setCext_certType            OBJ_set_certExt,1L
+
+#define SN_setCext_merchData            "setCext-merchData"
+#define NID_setCext_merchData           610
+#define OBJ_setCext_merchData           OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired                "setCext-cCertRequired"
+#define NID_setCext_cCertRequired               611
+#define OBJ_setCext_cCertRequired               OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling            "setCext-tunneling"
+#define NID_setCext_tunneling           612
+#define OBJ_setCext_tunneling           OBJ_set_certExt,4L
+
+#define SN_setCext_setExt               "setCext-setExt"
+#define NID_setCext_setExt              613
+#define OBJ_setCext_setExt              OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf             "setCext-setQualf"
+#define NID_setCext_setQualf            614
+#define OBJ_setCext_setQualf            OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities             "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities            615
+#define OBJ_setCext_PGWYcapabilities            OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier              "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier             616
+#define OBJ_setCext_TokenIdentifier             OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data           "setCext-Track2Data"
+#define NID_setCext_Track2Data          617
+#define OBJ_setCext_Track2Data          OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType            "setCext-TokenType"
+#define NID_setCext_TokenType           618
+#define OBJ_setCext_TokenType           OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities           "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities          619
+#define OBJ_setCext_IssuerCapabilities          OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert         "setAttr-Cert"
+#define NID_setAttr_Cert                620
+#define OBJ_setAttr_Cert                OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap              "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap              "payment gateway capabilities"
+#define NID_setAttr_PGWYcap             621
+#define OBJ_setAttr_PGWYcap             OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType            "setAttr-TokenType"
+#define NID_setAttr_TokenType           622
+#define OBJ_setAttr_TokenType           OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap               "setAttr-IssCap"
+#define LN_setAttr_IssCap               "issuer capabilities"
+#define NID_setAttr_IssCap              623
+#define OBJ_setAttr_IssCap              OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb             "set-rootKeyThumb"
+#define NID_set_rootKeyThumb            624
+#define OBJ_set_rootKeyThumb            OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy                "set-addPolicy"
+#define NID_set_addPolicy               625
+#define OBJ_set_addPolicy               OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV            "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV           626
+#define OBJ_setAttr_Token_EMV           OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime                "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime               627
+#define OBJ_setAttr_Token_B0Prime               OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM           "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM          628
+#define OBJ_setAttr_IssCap_CVM          OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2            "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2           629
+#define OBJ_setAttr_IssCap_T2           OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig           "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig          630
+#define OBJ_setAttr_IssCap_Sig          OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm          "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm          "generate cryptogram"
+#define NID_setAttr_GenCryptgrm         631
+#define OBJ_setAttr_GenCryptgrm         OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc                "setAttr-T2Enc"
+#define LN_setAttr_T2Enc                "encrypted track 2"
+#define NID_setAttr_T2Enc               632
+#define OBJ_setAttr_T2Enc               OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt           "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt           "cleartext track 2"
+#define NID_setAttr_T2cleartxt          633
+#define OBJ_setAttr_T2cleartxt          OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig            "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig            "ICC or token signature"
+#define NID_setAttr_TokICCsig           634
+#define OBJ_setAttr_TokICCsig           OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig            "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig            "secure device signature"
+#define NID_setAttr_SecDevSig           635
+#define OBJ_setAttr_SecDevSig           OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA           "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA          636
+#define OBJ_set_brand_IATA_ATA          OBJ_set_brand,1L
+
+#define SN_set_brand_Diners             "set-brand-Diners"
+#define NID_set_brand_Diners            637
+#define OBJ_set_brand_Diners            OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress            "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress           638
+#define OBJ_set_brand_AmericanExpress           OBJ_set_brand,34L
+
+#define SN_set_brand_JCB                "set-brand-JCB"
+#define NID_set_brand_JCB               639
+#define OBJ_set_brand_JCB               OBJ_set_brand,35L
+
+#define SN_set_brand_Visa               "set-brand-Visa"
+#define NID_set_brand_Visa              640
+#define OBJ_set_brand_Visa              OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard         "set-brand-MasterCard"
+#define NID_set_brand_MasterCard                641
+#define OBJ_set_brand_MasterCard                OBJ_set_brand,5L
+
+#define SN_set_brand_Novus              "set-brand-Novus"
+#define NID_set_brand_Novus             642
+#define OBJ_set_brand_Novus             OBJ_set_brand,6011L
+
+#define SN_des_cdmf             "DES-CDMF"
+#define LN_des_cdmf             "des-cdmf"
+#define NID_des_cdmf            643
+#define OBJ_des_cdmf            OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET         "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET                644
+#define OBJ_rsaOAEPEncryptionSET                OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3               "Oakley-EC2N-3"
+#define LN_ipsec3               "ipsec3"
+#define NID_ipsec3              749
+
+#define SN_ipsec4               "Oakley-EC2N-4"
+#define LN_ipsec4               "ipsec4"
+#define NID_ipsec4              750
+
+#define SN_whirlpool            "whirlpool"
+#define NID_whirlpool           804
+#define OBJ_whirlpool           OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro            "cryptopro"
+#define NID_cryptopro           805
+#define OBJ_cryptopro           OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom            "cryptocom"
+#define NID_cryptocom           806
+#define OBJ_cryptocom           OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001          "id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001          "GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001         807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001         OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94            "id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94            "GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94           808
+#define OBJ_id_GostR3411_94_with_GostR3410_94           OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94              "md_gost94"
+#define LN_id_GostR3411_94              "GOST R 34.11-94"
+#define NID_id_GostR3411_94             809
+#define OBJ_id_GostR3411_94             OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94          "id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94          "HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94         810
+#define OBJ_id_HMACGostR3411_94         OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001            "gost2001"
+#define LN_id_GostR3410_2001            "GOST R 34.10-2001"
+#define NID_id_GostR3410_2001           811
+#define OBJ_id_GostR3410_2001           OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94              "gost94"
+#define LN_id_GostR3410_94              "GOST R 34.10-94"
+#define NID_id_GostR3410_94             812
+#define OBJ_id_GostR3410_94             OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89              "gost89"
+#define LN_id_Gost28147_89              "GOST 28147-89"
+#define NID_id_Gost28147_89             813
+#define OBJ_id_Gost28147_89             OBJ_cryptopro,21L
+
+#define SN_gost89_cnt           "gost89-cnt"
+#define NID_gost89_cnt          814
+
+#define SN_id_Gost28147_89_MAC          "gost-mac"
+#define LN_id_Gost28147_89_MAC          "GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC         815
+#define OBJ_id_Gost28147_89_MAC         OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf          "prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf          "GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf         816
+#define OBJ_id_GostR3411_94_prf         OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH          "id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH          "GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH         817
+#define OBJ_id_GostR3410_2001DH         OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH            "id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH            "GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH           818
+#define OBJ_id_GostR3410_94DH           OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing         "id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing                819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing                OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing              "id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing             820
+#define OBJ_id_Gost28147_89_None_KeyMeshing             OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet         "id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet                821
+#define OBJ_id_GostR3411_94_TestParamSet                OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet            "id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet           822
+#define OBJ_id_GostR3411_94_CryptoProParamSet           OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet         "id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet                823
+#define OBJ_id_Gost28147_89_TestParamSet                OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet         "id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet                824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet                OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet         "id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet                825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet                OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet         "id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet                826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet                OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet         "id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet                827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet                OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet             "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet         "id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet                831
+#define OBJ_id_GostR3410_94_TestParamSet                OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet         "id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet                832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet                OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet         "id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet                833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet                OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet         "id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet                834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet                OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet         "id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet                835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet                OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet              "id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet             836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet             OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet              "id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet             837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet             OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet              "id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet             838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet             OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet               "id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet              839
+#define OBJ_id_GostR3410_2001_TestParamSet              OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet               "id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet              840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet              OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet               "id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet              841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet              OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet               "id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet              842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet              OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet            "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet           843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet           OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet            "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet           844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet           OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a            "id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a           845
+#define OBJ_id_GostR3410_94_a           OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis         "id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis                846
+#define OBJ_id_GostR3410_94_aBis                OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b            "id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b           847
+#define OBJ_id_GostR3410_94_b           OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis         "id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis                848
+#define OBJ_id_GostR3410_94_bBis                OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc           "id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc           "GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc          849
+#define OBJ_id_Gost28147_89_cc          OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc           "gost94cc"
+#define LN_id_GostR3410_94_cc           "GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc          850
+#define OBJ_id_GostR3410_94_cc          OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc         "gost2001cc"
+#define LN_id_GostR3410_2001_cc         "GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc                851
+#define OBJ_id_GostR3410_2001_cc                OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc         "id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc         "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc                852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc                OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc               "id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc               "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc              853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc              OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc                "id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc                "GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc               854
+#define OBJ_id_GostR3410_2001_ParamSet_cc               OBJ_cryptocom,1L,8L,1L
+
+#define SN_camellia_128_cbc             "CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc             "camellia-128-cbc"
+#define NID_camellia_128_cbc            751
+#define OBJ_camellia_128_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc             "CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc             "camellia-192-cbc"
+#define NID_camellia_192_cbc            752
+#define OBJ_camellia_192_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc             "CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc             "camellia-256-cbc"
+#define NID_camellia_256_cbc            753
+#define OBJ_camellia_256_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define SN_id_camellia128_wrap          "id-camellia128-wrap"
+#define NID_id_camellia128_wrap         907
+#define OBJ_id_camellia128_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap          "id-camellia192-wrap"
+#define NID_id_camellia192_wrap         908
+#define OBJ_id_camellia192_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap          "id-camellia256-wrap"
+#define NID_id_camellia256_wrap         909
+#define OBJ_id_camellia256_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
+#define OBJ_ntt_ds              0L,3L,4401L,5L
+
+#define OBJ_camellia            OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb             "CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb             "camellia-128-ecb"
+#define NID_camellia_128_ecb            754
+#define OBJ_camellia_128_ecb            OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128          "CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128          "camellia-128-ofb"
+#define NID_camellia_128_ofb128         766
+#define OBJ_camellia_128_ofb128         OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128          "CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128          "camellia-128-cfb"
+#define NID_camellia_128_cfb128         757
+#define OBJ_camellia_128_cfb128         OBJ_camellia,4L
+
+#define SN_camellia_192_ecb             "CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb             "camellia-192-ecb"
+#define NID_camellia_192_ecb            755
+#define OBJ_camellia_192_ecb            OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128          "CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128          "camellia-192-ofb"
+#define NID_camellia_192_ofb128         767
+#define OBJ_camellia_192_ofb128         OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128          "CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128          "camellia-192-cfb"
+#define NID_camellia_192_cfb128         758
+#define OBJ_camellia_192_cfb128         OBJ_camellia,24L
+
+#define SN_camellia_256_ecb             "CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb             "camellia-256-ecb"
+#define NID_camellia_256_ecb            756
+#define OBJ_camellia_256_ecb            OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128          "CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128          "camellia-256-ofb"
+#define NID_camellia_256_ofb128         768
+#define OBJ_camellia_256_ofb128         OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128          "CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128          "camellia-256-cfb"
+#define NID_camellia_256_cfb128         759
+#define OBJ_camellia_256_cfb128         OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1            "CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1            "camellia-128-cfb1"
+#define NID_camellia_128_cfb1           760
+
+#define SN_camellia_192_cfb1            "CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1            "camellia-192-cfb1"
+#define NID_camellia_192_cfb1           761
+
+#define SN_camellia_256_cfb1            "CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1            "camellia-256-cfb1"
+#define NID_camellia_256_cfb1           762
+
+#define SN_camellia_128_cfb8            "CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8            "camellia-128-cfb8"
+#define NID_camellia_128_cfb8           763
+
+#define SN_camellia_192_cfb8            "CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8            "camellia-192-cfb8"
+#define NID_camellia_192_cfb8           764
+
+#define SN_camellia_256_cfb8            "CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8            "camellia-256-cfb8"
+#define NID_camellia_256_cfb8           765
+
+#define SN_kisa         "KISA"
+#define LN_kisa         "kisa"
+#define NID_kisa                773
+#define OBJ_kisa                OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb             "SEED-ECB"
+#define LN_seed_ecb             "seed-ecb"
+#define NID_seed_ecb            776
+#define OBJ_seed_ecb            OBJ_kisa,1L,3L
+
+#define SN_seed_cbc             "SEED-CBC"
+#define LN_seed_cbc             "seed-cbc"
+#define NID_seed_cbc            777
+#define OBJ_seed_cbc            OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128          "SEED-CFB"
+#define LN_seed_cfb128          "seed-cfb"
+#define NID_seed_cfb128         779
+#define OBJ_seed_cfb128         OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128          "SEED-OFB"
+#define LN_seed_ofb128          "seed-ofb"
+#define NID_seed_ofb128         778
+#define OBJ_seed_ofb128         OBJ_kisa,1L,6L
+
+#define SN_hmac         "HMAC"
+#define LN_hmac         "hmac"
+#define NID_hmac                855
+
+#define SN_cmac         "CMAC"
+#define LN_cmac         "cmac"
+#define NID_cmac                894
+
+#define SN_rc4_hmac_md5         "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5         "rc4-hmac-md5"
+#define NID_rc4_hmac_md5                915
+
+#define SN_aes_128_cbc_hmac_sha1                "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1                "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1               916
+
+#define SN_aes_192_cbc_hmac_sha1                "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1                "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1               917
+
+#define SN_aes_256_cbc_hmac_sha1                "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1                "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1               918
+
+#define SN_aes_128_cbc_hmac_sha256              "AES-128-CBC-HMAC-SHA256"
+#define LN_aes_128_cbc_hmac_sha256              "aes-128-cbc-hmac-sha256"
+#define NID_aes_128_cbc_hmac_sha256             948
+
+#define SN_aes_192_cbc_hmac_sha256              "AES-192-CBC-HMAC-SHA256"
+#define LN_aes_192_cbc_hmac_sha256              "aes-192-cbc-hmac-sha256"
+#define NID_aes_192_cbc_hmac_sha256             949
+
+#define SN_aes_256_cbc_hmac_sha256              "AES-256-CBC-HMAC-SHA256"
+#define LN_aes_256_cbc_hmac_sha256              "aes-256-cbc-hmac-sha256"
+#define NID_aes_256_cbc_hmac_sha256             950
+
+#define SN_dhpublicnumber               "dhpublicnumber"
+#define LN_dhpublicnumber               "X9.42 DH"
+#define NID_dhpublicnumber              920
+#define OBJ_dhpublicnumber              OBJ_ISO_US,10046L,2L,1L
+
+#define SN_brainpoolP160r1              "brainpoolP160r1"
+#define NID_brainpoolP160r1             921
+#define OBJ_brainpoolP160r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
+
+#define SN_brainpoolP160t1              "brainpoolP160t1"
+#define NID_brainpoolP160t1             922
+#define OBJ_brainpoolP160t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
+
+#define SN_brainpoolP192r1              "brainpoolP192r1"
+#define NID_brainpoolP192r1             923
+#define OBJ_brainpoolP192r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
+
+#define SN_brainpoolP192t1              "brainpoolP192t1"
+#define NID_brainpoolP192t1             924
+#define OBJ_brainpoolP192t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
+
+#define SN_brainpoolP224r1              "brainpoolP224r1"
+#define NID_brainpoolP224r1             925
+#define OBJ_brainpoolP224r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
+
+#define SN_brainpoolP224t1              "brainpoolP224t1"
+#define NID_brainpoolP224t1             926
+#define OBJ_brainpoolP224t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
+
+#define SN_brainpoolP256r1              "brainpoolP256r1"
+#define NID_brainpoolP256r1             927
+#define OBJ_brainpoolP256r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
+
+#define SN_brainpoolP256t1              "brainpoolP256t1"
+#define NID_brainpoolP256t1             928
+#define OBJ_brainpoolP256t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
+
+#define SN_brainpoolP320r1              "brainpoolP320r1"
+#define NID_brainpoolP320r1             929
+#define OBJ_brainpoolP320r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
+
+#define SN_brainpoolP320t1              "brainpoolP320t1"
+#define NID_brainpoolP320t1             930
+#define OBJ_brainpoolP320t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
+
+#define SN_brainpoolP384r1              "brainpoolP384r1"
+#define NID_brainpoolP384r1             931
+#define OBJ_brainpoolP384r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
+
+#define SN_brainpoolP384t1              "brainpoolP384t1"
+#define NID_brainpoolP384t1             932
+#define OBJ_brainpoolP384t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
+
+#define SN_brainpoolP512r1              "brainpoolP512r1"
+#define NID_brainpoolP512r1             933
+#define OBJ_brainpoolP512r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
+
+#define SN_brainpoolP512t1              "brainpoolP512t1"
+#define NID_brainpoolP512t1             934
+#define OBJ_brainpoolP512t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
+
+#define OBJ_x9_63_scheme                1L,3L,133L,16L,840L,63L,0L
+
+#define OBJ_secg_scheme         OBJ_certicom_arc,1L
+
+#define SN_dhSinglePass_stdDH_sha1kdf_scheme            "dhSinglePass-stdDH-sha1kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha1kdf_scheme           936
+#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme           OBJ_x9_63_scheme,2L
+
+#define SN_dhSinglePass_stdDH_sha224kdf_scheme          "dhSinglePass-stdDH-sha224kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha224kdf_scheme         937
+#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme         OBJ_secg_scheme,11L,0L
+
+#define SN_dhSinglePass_stdDH_sha256kdf_scheme          "dhSinglePass-stdDH-sha256kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha256kdf_scheme         938
+#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme         OBJ_secg_scheme,11L,1L
+
+#define SN_dhSinglePass_stdDH_sha384kdf_scheme          "dhSinglePass-stdDH-sha384kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha384kdf_scheme         939
+#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme         OBJ_secg_scheme,11L,2L
+
+#define SN_dhSinglePass_stdDH_sha512kdf_scheme          "dhSinglePass-stdDH-sha512kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha512kdf_scheme         940
+#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme         OBJ_secg_scheme,11L,3L
+
+#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme               "dhSinglePass-cofactorDH-sha1kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme              941
+#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme              OBJ_x9_63_scheme,3L
+
+#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme             "dhSinglePass-cofactorDH-sha224kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme            942
+#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme            OBJ_secg_scheme,14L,0L
+
+#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme             "dhSinglePass-cofactorDH-sha256kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme            943
+#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme            OBJ_secg_scheme,14L,1L
+
+#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme             "dhSinglePass-cofactorDH-sha384kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme            944
+#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme            OBJ_secg_scheme,14L,2L
+
+#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme             "dhSinglePass-cofactorDH-sha512kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme            945
+#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme            OBJ_secg_scheme,14L,3L
+
+#define SN_dh_std_kdf           "dh-std-kdf"
+#define NID_dh_std_kdf          946
+
+#define SN_dh_cofactor_kdf              "dh-cofactor-kdf"
+#define NID_dh_cofactor_kdf             947
+
+#define SN_ct_precert_scts              "ct_precert_scts"
+#define LN_ct_precert_scts              "CT Precertificate SCTs"
+#define NID_ct_precert_scts             951
+#define OBJ_ct_precert_scts             1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L
+
+#define SN_ct_precert_poison            "ct_precert_poison"
+#define LN_ct_precert_poison            "CT Precertificate Poison"
+#define NID_ct_precert_poison           952
+#define OBJ_ct_precert_poison           1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L
+
+#define SN_ct_precert_signer            "ct_precert_signer"
+#define LN_ct_precert_signer            "CT Precertificate Signer"
+#define NID_ct_precert_signer           953
+#define OBJ_ct_precert_signer           1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L
+
+#define SN_ct_cert_scts         "ct_cert_scts"
+#define LN_ct_cert_scts         "CT Certificate SCTs"
+#define NID_ct_cert_scts                954
+#define OBJ_ct_cert_scts                1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L
+
+#define SN_jurisdictionLocalityName             "jurisdictionL"
+#define LN_jurisdictionLocalityName             "jurisdictionLocalityName"
+#define NID_jurisdictionLocalityName            955
+#define OBJ_jurisdictionLocalityName            1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L
+
+#define SN_jurisdictionStateOrProvinceName              "jurisdictionST"
+#define LN_jurisdictionStateOrProvinceName              "jurisdictionStateOrProvinceName"
+#define NID_jurisdictionStateOrProvinceName             956
+#define OBJ_jurisdictionStateOrProvinceName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L
+
+#define SN_jurisdictionCountryName              "jurisdictionC"
+#define LN_jurisdictionCountryName              "jurisdictionCountryName"
+#define NID_jurisdictionCountryName             957
+#define OBJ_jurisdictionCountryName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L
diff --git a/Cryptlib/Include/openssl/objects.h b/Cryptlib/Include/openssl/objects.h
new file mode 100644 (file)
index 0000000..b8dafa8
--- /dev/null
@@ -0,0 +1,1143 @@
+/* crypto/objects/objects.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_OBJECTS_H
+# define HEADER_OBJECTS_H
+
+# define USE_OBJ_MAC
+
+# ifdef USE_OBJ_MAC
+#  include <openssl/obj_mac.h>
+# else
+#  define SN_undef                        "UNDEF"
+#  define LN_undef                        "undefined"
+#  define NID_undef                       0
+#  define OBJ_undef                       0L
+
+#  define SN_Algorithm                    "Algorithm"
+#  define LN_algorithm                    "algorithm"
+#  define NID_algorithm                   38
+#  define OBJ_algorithm                   1L,3L,14L,3L,2L
+
+#  define LN_rsadsi                       "rsadsi"
+#  define NID_rsadsi                      1
+#  define OBJ_rsadsi                      1L,2L,840L,113549L
+
+#  define LN_pkcs                         "pkcs"
+#  define NID_pkcs                        2
+#  define OBJ_pkcs                        OBJ_rsadsi,1L
+
+#  define SN_md2                          "MD2"
+#  define LN_md2                          "md2"
+#  define NID_md2                         3
+#  define OBJ_md2                         OBJ_rsadsi,2L,2L
+
+#  define SN_md5                          "MD5"
+#  define LN_md5                          "md5"
+#  define NID_md5                         4
+#  define OBJ_md5                         OBJ_rsadsi,2L,5L
+
+#  define SN_rc4                          "RC4"
+#  define LN_rc4                          "rc4"
+#  define NID_rc4                         5
+#  define OBJ_rc4                         OBJ_rsadsi,3L,4L
+
+#  define LN_rsaEncryption                "rsaEncryption"
+#  define NID_rsaEncryption               6
+#  define OBJ_rsaEncryption               OBJ_pkcs,1L,1L
+
+#  define SN_md2WithRSAEncryption         "RSA-MD2"
+#  define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
+#  define NID_md2WithRSAEncryption        7
+#  define OBJ_md2WithRSAEncryption        OBJ_pkcs,1L,2L
+
+#  define SN_md5WithRSAEncryption         "RSA-MD5"
+#  define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
+#  define NID_md5WithRSAEncryption        8
+#  define OBJ_md5WithRSAEncryption        OBJ_pkcs,1L,4L
+
+#  define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
+#  define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
+#  define NID_pbeWithMD2AndDES_CBC        9
+#  define OBJ_pbeWithMD2AndDES_CBC        OBJ_pkcs,5L,1L
+
+#  define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
+#  define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
+#  define NID_pbeWithMD5AndDES_CBC        10
+#  define OBJ_pbeWithMD5AndDES_CBC        OBJ_pkcs,5L,3L
+
+#  define LN_X500                         "X500"
+#  define NID_X500                        11
+#  define OBJ_X500                        2L,5L
+
+#  define LN_X509                         "X509"
+#  define NID_X509                        12
+#  define OBJ_X509                        OBJ_X500,4L
+
+#  define SN_commonName                   "CN"
+#  define LN_commonName                   "commonName"
+#  define NID_commonName                  13
+#  define OBJ_commonName                  OBJ_X509,3L
+
+#  define SN_countryName                  "C"
+#  define LN_countryName                  "countryName"
+#  define NID_countryName                 14
+#  define OBJ_countryName                 OBJ_X509,6L
+
+#  define SN_localityName                 "L"
+#  define LN_localityName                 "localityName"
+#  define NID_localityName                15
+#  define OBJ_localityName                OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#  define SN_stateOrProvinceName          "ST"
+#  define LN_stateOrProvinceName          "stateOrProvinceName"
+#  define NID_stateOrProvinceName         16
+#  define OBJ_stateOrProvinceName         OBJ_X509,8L
+
+#  define SN_organizationName             "O"
+#  define LN_organizationName             "organizationName"
+#  define NID_organizationName            17
+#  define OBJ_organizationName            OBJ_X509,10L
+
+#  define SN_organizationalUnitName       "OU"
+#  define LN_organizationalUnitName       "organizationalUnitName"
+#  define NID_organizationalUnitName      18
+#  define OBJ_organizationalUnitName      OBJ_X509,11L
+
+#  define SN_rsa                          "RSA"
+#  define LN_rsa                          "rsa"
+#  define NID_rsa                         19
+#  define OBJ_rsa                         OBJ_X500,8L,1L,1L
+
+#  define LN_pkcs7                        "pkcs7"
+#  define NID_pkcs7                       20
+#  define OBJ_pkcs7                       OBJ_pkcs,7L
+
+#  define LN_pkcs7_data                   "pkcs7-data"
+#  define NID_pkcs7_data                  21
+#  define OBJ_pkcs7_data                  OBJ_pkcs7,1L
+
+#  define LN_pkcs7_signed                 "pkcs7-signedData"
+#  define NID_pkcs7_signed                22
+#  define OBJ_pkcs7_signed                OBJ_pkcs7,2L
+
+#  define LN_pkcs7_enveloped              "pkcs7-envelopedData"
+#  define NID_pkcs7_enveloped             23
+#  define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L
+
+#  define LN_pkcs7_signedAndEnveloped     "pkcs7-signedAndEnvelopedData"
+#  define NID_pkcs7_signedAndEnveloped    24
+#  define OBJ_pkcs7_signedAndEnveloped    OBJ_pkcs7,4L
+
+#  define LN_pkcs7_digest                 "pkcs7-digestData"
+#  define NID_pkcs7_digest                25
+#  define OBJ_pkcs7_digest                OBJ_pkcs7,5L
+
+#  define LN_pkcs7_encrypted              "pkcs7-encryptedData"
+#  define NID_pkcs7_encrypted             26
+#  define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L
+
+#  define LN_pkcs3                        "pkcs3"
+#  define NID_pkcs3                       27
+#  define OBJ_pkcs3                       OBJ_pkcs,3L
+
+#  define LN_dhKeyAgreement               "dhKeyAgreement"
+#  define NID_dhKeyAgreement              28
+#  define OBJ_dhKeyAgreement              OBJ_pkcs3,1L
+
+#  define SN_des_ecb                      "DES-ECB"
+#  define LN_des_ecb                      "des-ecb"
+#  define NID_des_ecb                     29
+#  define OBJ_des_ecb                     OBJ_algorithm,6L
+
+#  define SN_des_cfb64                    "DES-CFB"
+#  define LN_des_cfb64                    "des-cfb"
+#  define NID_des_cfb64                   30
+/* IV + num */
+#  define OBJ_des_cfb64                   OBJ_algorithm,9L
+
+#  define SN_des_cbc                      "DES-CBC"
+#  define LN_des_cbc                      "des-cbc"
+#  define NID_des_cbc                     31
+/* IV */
+#  define OBJ_des_cbc                     OBJ_algorithm,7L
+
+#  define SN_des_ede                      "DES-EDE"
+#  define LN_des_ede                      "des-ede"
+#  define NID_des_ede                     32
+/* ?? */
+#  define OBJ_des_ede                     OBJ_algorithm,17L
+
+#  define SN_des_ede3                     "DES-EDE3"
+#  define LN_des_ede3                     "des-ede3"
+#  define NID_des_ede3                    33
+
+#  define SN_idea_cbc                     "IDEA-CBC"
+#  define LN_idea_cbc                     "idea-cbc"
+#  define NID_idea_cbc                    34
+#  define OBJ_idea_cbc                    1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#  define SN_idea_cfb64                   "IDEA-CFB"
+#  define LN_idea_cfb64                   "idea-cfb"
+#  define NID_idea_cfb64                  35
+
+#  define SN_idea_ecb                     "IDEA-ECB"
+#  define LN_idea_ecb                     "idea-ecb"
+#  define NID_idea_ecb                    36
+
+#  define SN_rc2_cbc                      "RC2-CBC"
+#  define LN_rc2_cbc                      "rc2-cbc"
+#  define NID_rc2_cbc                     37
+#  define OBJ_rc2_cbc                     OBJ_rsadsi,3L,2L
+
+#  define SN_rc2_ecb                      "RC2-ECB"
+#  define LN_rc2_ecb                      "rc2-ecb"
+#  define NID_rc2_ecb                     38
+
+#  define SN_rc2_cfb64                    "RC2-CFB"
+#  define LN_rc2_cfb64                    "rc2-cfb"
+#  define NID_rc2_cfb64                   39
+
+#  define SN_rc2_ofb64                    "RC2-OFB"
+#  define LN_rc2_ofb64                    "rc2-ofb"
+#  define NID_rc2_ofb64                   40
+
+#  define SN_sha                          "SHA"
+#  define LN_sha                          "sha"
+#  define NID_sha                         41
+#  define OBJ_sha                         OBJ_algorithm,18L
+
+#  define SN_shaWithRSAEncryption         "RSA-SHA"
+#  define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
+#  define NID_shaWithRSAEncryption        42
+#  define OBJ_shaWithRSAEncryption        OBJ_algorithm,15L
+
+#  define SN_des_ede_cbc                  "DES-EDE-CBC"
+#  define LN_des_ede_cbc                  "des-ede-cbc"
+#  define NID_des_ede_cbc                 43
+
+#  define SN_des_ede3_cbc                 "DES-EDE3-CBC"
+#  define LN_des_ede3_cbc                 "des-ede3-cbc"
+#  define NID_des_ede3_cbc                44
+#  define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L
+
+#  define SN_des_ofb64                    "DES-OFB"
+#  define LN_des_ofb64                    "des-ofb"
+#  define NID_des_ofb64                   45
+#  define OBJ_des_ofb64                   OBJ_algorithm,8L
+
+#  define SN_idea_ofb64                   "IDEA-OFB"
+#  define LN_idea_ofb64                   "idea-ofb"
+#  define NID_idea_ofb64                  46
+
+#  define LN_pkcs9                        "pkcs9"
+#  define NID_pkcs9                       47
+#  define OBJ_pkcs9                       OBJ_pkcs,9L
+
+#  define SN_pkcs9_emailAddress           "Email"
+#  define LN_pkcs9_emailAddress           "emailAddress"
+#  define NID_pkcs9_emailAddress          48
+#  define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L
+
+#  define LN_pkcs9_unstructuredName       "unstructuredName"
+#  define NID_pkcs9_unstructuredName      49
+#  define OBJ_pkcs9_unstructuredName      OBJ_pkcs9,2L
+
+#  define LN_pkcs9_contentType            "contentType"
+#  define NID_pkcs9_contentType           50
+#  define OBJ_pkcs9_contentType           OBJ_pkcs9,3L
+
+#  define LN_pkcs9_messageDigest          "messageDigest"
+#  define NID_pkcs9_messageDigest         51
+#  define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L
+
+#  define LN_pkcs9_signingTime            "signingTime"
+#  define NID_pkcs9_signingTime           52
+#  define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L
+
+#  define LN_pkcs9_countersignature       "countersignature"
+#  define NID_pkcs9_countersignature      53
+#  define OBJ_pkcs9_countersignature      OBJ_pkcs9,6L
+
+#  define LN_pkcs9_challengePassword      "challengePassword"
+#  define NID_pkcs9_challengePassword     54
+#  define OBJ_pkcs9_challengePassword     OBJ_pkcs9,7L
+
+#  define LN_pkcs9_unstructuredAddress    "unstructuredAddress"
+#  define NID_pkcs9_unstructuredAddress   55
+#  define OBJ_pkcs9_unstructuredAddress   OBJ_pkcs9,8L
+
+#  define LN_pkcs9_extCertAttributes      "extendedCertificateAttributes"
+#  define NID_pkcs9_extCertAttributes     56
+#  define OBJ_pkcs9_extCertAttributes     OBJ_pkcs9,9L
+
+#  define SN_netscape                     "Netscape"
+#  define LN_netscape                     "Netscape Communications Corp."
+#  define NID_netscape                    57
+#  define OBJ_netscape                    2L,16L,840L,1L,113730L
+
+#  define SN_netscape_cert_extension      "nsCertExt"
+#  define LN_netscape_cert_extension      "Netscape Certificate Extension"
+#  define NID_netscape_cert_extension     58
+#  define OBJ_netscape_cert_extension     OBJ_netscape,1L
+
+#  define SN_netscape_data_type           "nsDataType"
+#  define LN_netscape_data_type           "Netscape Data Type"
+#  define NID_netscape_data_type          59
+#  define OBJ_netscape_data_type          OBJ_netscape,2L
+
+#  define SN_des_ede_cfb64                "DES-EDE-CFB"
+#  define LN_des_ede_cfb64                "des-ede-cfb"
+#  define NID_des_ede_cfb64               60
+
+#  define SN_des_ede3_cfb64               "DES-EDE3-CFB"
+#  define LN_des_ede3_cfb64               "des-ede3-cfb"
+#  define NID_des_ede3_cfb64              61
+
+#  define SN_des_ede_ofb64                "DES-EDE-OFB"
+#  define LN_des_ede_ofb64                "des-ede-ofb"
+#  define NID_des_ede_ofb64               62
+
+#  define SN_des_ede3_ofb64               "DES-EDE3-OFB"
+#  define LN_des_ede3_ofb64               "des-ede3-ofb"
+#  define NID_des_ede3_ofb64              63
+
+/* I'm not sure about the object ID */
+#  define SN_sha1                         "SHA1"
+#  define LN_sha1                         "sha1"
+#  define NID_sha1                        64
+#  define OBJ_sha1                        OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1                     1L,3L,14L,2L,26L,05L <- wrong */
+
+#  define SN_sha1WithRSAEncryption        "RSA-SHA1"
+#  define LN_sha1WithRSAEncryption        "sha1WithRSAEncryption"
+#  define NID_sha1WithRSAEncryption       65
+#  define OBJ_sha1WithRSAEncryption       OBJ_pkcs,1L,5L
+
+#  define SN_dsaWithSHA                   "DSA-SHA"
+#  define LN_dsaWithSHA                   "dsaWithSHA"
+#  define NID_dsaWithSHA                  66
+#  define OBJ_dsaWithSHA                  OBJ_algorithm,13L
+
+#  define SN_dsa_2                        "DSA-old"
+#  define LN_dsa_2                        "dsaEncryption-old"
+#  define NID_dsa_2                       67
+#  define OBJ_dsa_2                       OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#  define SN_pbeWithSHA1AndRC2_CBC        "PBE-SHA1-RC2-64"
+#  define LN_pbeWithSHA1AndRC2_CBC        "pbeWithSHA1AndRC2-CBC"
+#  define NID_pbeWithSHA1AndRC2_CBC       68
+#  define OBJ_pbeWithSHA1AndRC2_CBC       OBJ_pkcs,5L,11L
+
+/*
+ * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined
+ * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely
+ * different.
+ */
+#  define LN_id_pbkdf2                    "PBKDF2"
+#  define NID_id_pbkdf2                   69
+#  define OBJ_id_pbkdf2                   OBJ_pkcs,5L,12L
+
+#  define SN_dsaWithSHA1_2                "DSA-SHA1-old"
+#  define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
+#  define NID_dsaWithSHA1_2               70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#  define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L
+
+#  define SN_netscape_cert_type           "nsCertType"
+#  define LN_netscape_cert_type           "Netscape Cert Type"
+#  define NID_netscape_cert_type          71
+#  define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L
+
+#  define SN_netscape_base_url            "nsBaseUrl"
+#  define LN_netscape_base_url            "Netscape Base Url"
+#  define NID_netscape_base_url           72
+#  define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L
+
+#  define SN_netscape_revocation_url      "nsRevocationUrl"
+#  define LN_netscape_revocation_url      "Netscape Revocation Url"
+#  define NID_netscape_revocation_url     73
+#  define OBJ_netscape_revocation_url     OBJ_netscape_cert_extension,3L
+
+#  define SN_netscape_ca_revocation_url   "nsCaRevocationUrl"
+#  define LN_netscape_ca_revocation_url   "Netscape CA Revocation Url"
+#  define NID_netscape_ca_revocation_url  74
+#  define OBJ_netscape_ca_revocation_url  OBJ_netscape_cert_extension,4L
+
+#  define SN_netscape_renewal_url         "nsRenewalUrl"
+#  define LN_netscape_renewal_url         "Netscape Renewal Url"
+#  define NID_netscape_renewal_url        75
+#  define OBJ_netscape_renewal_url        OBJ_netscape_cert_extension,7L
+
+#  define SN_netscape_ca_policy_url       "nsCaPolicyUrl"
+#  define LN_netscape_ca_policy_url       "Netscape CA Policy Url"
+#  define NID_netscape_ca_policy_url      76
+#  define OBJ_netscape_ca_policy_url      OBJ_netscape_cert_extension,8L
+
+#  define SN_netscape_ssl_server_name     "nsSslServerName"
+#  define LN_netscape_ssl_server_name     "Netscape SSL Server Name"
+#  define NID_netscape_ssl_server_name    77
+#  define OBJ_netscape_ssl_server_name    OBJ_netscape_cert_extension,12L
+
+#  define SN_netscape_comment             "nsComment"
+#  define LN_netscape_comment             "Netscape Comment"
+#  define NID_netscape_comment            78
+#  define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L
+
+#  define SN_netscape_cert_sequence       "nsCertSequence"
+#  define LN_netscape_cert_sequence       "Netscape Certificate Sequence"
+#  define NID_netscape_cert_sequence      79
+#  define OBJ_netscape_cert_sequence      OBJ_netscape_data_type,5L
+
+#  define SN_desx_cbc                     "DESX-CBC"
+#  define LN_desx_cbc                     "desx-cbc"
+#  define NID_desx_cbc                    80
+
+#  define SN_id_ce                        "id-ce"
+#  define NID_id_ce                       81
+#  define OBJ_id_ce                       2L,5L,29L
+
+#  define SN_subject_key_identifier       "subjectKeyIdentifier"
+#  define LN_subject_key_identifier       "X509v3 Subject Key Identifier"
+#  define NID_subject_key_identifier      82
+#  define OBJ_subject_key_identifier      OBJ_id_ce,14L
+
+#  define SN_key_usage                    "keyUsage"
+#  define LN_key_usage                    "X509v3 Key Usage"
+#  define NID_key_usage                   83
+#  define OBJ_key_usage                   OBJ_id_ce,15L
+
+#  define SN_private_key_usage_period     "privateKeyUsagePeriod"
+#  define LN_private_key_usage_period     "X509v3 Private Key Usage Period"
+#  define NID_private_key_usage_period    84
+#  define OBJ_private_key_usage_period    OBJ_id_ce,16L
+
+#  define SN_subject_alt_name             "subjectAltName"
+#  define LN_subject_alt_name             "X509v3 Subject Alternative Name"
+#  define NID_subject_alt_name            85
+#  define OBJ_subject_alt_name            OBJ_id_ce,17L
+
+#  define SN_issuer_alt_name              "issuerAltName"
+#  define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
+#  define NID_issuer_alt_name             86
+#  define OBJ_issuer_alt_name             OBJ_id_ce,18L
+
+#  define SN_basic_constraints            "basicConstraints"
+#  define LN_basic_constraints            "X509v3 Basic Constraints"
+#  define NID_basic_constraints           87
+#  define OBJ_basic_constraints           OBJ_id_ce,19L
+
+#  define SN_crl_number                   "crlNumber"
+#  define LN_crl_number                   "X509v3 CRL Number"
+#  define NID_crl_number                  88
+#  define OBJ_crl_number                  OBJ_id_ce,20L
+
+#  define SN_certificate_policies         "certificatePolicies"
+#  define LN_certificate_policies         "X509v3 Certificate Policies"
+#  define NID_certificate_policies        89
+#  define OBJ_certificate_policies        OBJ_id_ce,32L
+
+#  define SN_authority_key_identifier     "authorityKeyIdentifier"
+#  define LN_authority_key_identifier     "X509v3 Authority Key Identifier"
+#  define NID_authority_key_identifier    90
+#  define OBJ_authority_key_identifier    OBJ_id_ce,35L
+
+#  define SN_bf_cbc                       "BF-CBC"
+#  define LN_bf_cbc                       "bf-cbc"
+#  define NID_bf_cbc                      91
+#  define OBJ_bf_cbc                      1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#  define SN_bf_ecb                       "BF-ECB"
+#  define LN_bf_ecb                       "bf-ecb"
+#  define NID_bf_ecb                      92
+
+#  define SN_bf_cfb64                     "BF-CFB"
+#  define LN_bf_cfb64                     "bf-cfb"
+#  define NID_bf_cfb64                    93
+
+#  define SN_bf_ofb64                     "BF-OFB"
+#  define LN_bf_ofb64                     "bf-ofb"
+#  define NID_bf_ofb64                    94
+
+#  define SN_mdc2                         "MDC2"
+#  define LN_mdc2                         "mdc2"
+#  define NID_mdc2                        95
+#  define OBJ_mdc2                        2L,5L,8L,3L,101L
+/* An alternative?                      1L,3L,14L,3L,2L,19L */
+
+#  define SN_mdc2WithRSA                  "RSA-MDC2"
+#  define LN_mdc2WithRSA                  "mdc2withRSA"
+#  define NID_mdc2WithRSA                 96
+#  define OBJ_mdc2WithRSA                 2L,5L,8L,3L,100L
+
+#  define SN_rc4_40                       "RC4-40"
+#  define LN_rc4_40                       "rc4-40"
+#  define NID_rc4_40                      97
+
+#  define SN_rc2_40_cbc                   "RC2-40-CBC"
+#  define LN_rc2_40_cbc                   "rc2-40-cbc"
+#  define NID_rc2_40_cbc                  98
+
+#  define SN_givenName                    "G"
+#  define LN_givenName                    "givenName"
+#  define NID_givenName                   99
+#  define OBJ_givenName                   OBJ_X509,42L
+
+#  define SN_surname                      "S"
+#  define LN_surname                      "surname"
+#  define NID_surname                     100
+#  define OBJ_surname                     OBJ_X509,4L
+
+#  define SN_initials                     "I"
+#  define LN_initials                     "initials"
+#  define NID_initials                    101
+#  define OBJ_initials                    OBJ_X509,43L
+
+#  define SN_uniqueIdentifier             "UID"
+#  define LN_uniqueIdentifier             "uniqueIdentifier"
+#  define NID_uniqueIdentifier            102
+#  define OBJ_uniqueIdentifier            OBJ_X509,45L
+
+#  define SN_crl_distribution_points      "crlDistributionPoints"
+#  define LN_crl_distribution_points      "X509v3 CRL Distribution Points"
+#  define NID_crl_distribution_points     103
+#  define OBJ_crl_distribution_points     OBJ_id_ce,31L
+
+#  define SN_md5WithRSA                   "RSA-NP-MD5"
+#  define LN_md5WithRSA                   "md5WithRSA"
+#  define NID_md5WithRSA                  104
+#  define OBJ_md5WithRSA                  OBJ_algorithm,3L
+
+#  define SN_serialNumber                 "SN"
+#  define LN_serialNumber                 "serialNumber"
+#  define NID_serialNumber                105
+#  define OBJ_serialNumber                OBJ_X509,5L
+
+#  define SN_title                        "T"
+#  define LN_title                        "title"
+#  define NID_title                       106
+#  define OBJ_title                       OBJ_X509,12L
+
+#  define SN_description                  "D"
+#  define LN_description                  "description"
+#  define NID_description                 107
+#  define OBJ_description                 OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#  define SN_cast5_cbc                    "CAST5-CBC"
+#  define LN_cast5_cbc                    "cast5-cbc"
+#  define NID_cast5_cbc                   108
+#  define OBJ_cast5_cbc                   1L,2L,840L,113533L,7L,66L,10L
+
+#  define SN_cast5_ecb                    "CAST5-ECB"
+#  define LN_cast5_ecb                    "cast5-ecb"
+#  define NID_cast5_ecb                   109
+
+#  define SN_cast5_cfb64                  "CAST5-CFB"
+#  define LN_cast5_cfb64                  "cast5-cfb"
+#  define NID_cast5_cfb64                 110
+
+#  define SN_cast5_ofb64                  "CAST5-OFB"
+#  define LN_cast5_ofb64                  "cast5-ofb"
+#  define NID_cast5_ofb64                 111
+
+#  define LN_pbeWithMD5AndCast5_CBC       "pbeWithMD5AndCast5CBC"
+#  define NID_pbeWithMD5AndCast5_CBC      112
+#  define OBJ_pbeWithMD5AndCast5_CBC      1L,2L,840L,113533L,7L,66L,12L
+
+/*-
+ * This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#  define SN_dsaWithSHA1                  "DSA-SHA1"
+#  define LN_dsaWithSHA1                  "dsaWithSHA1"
+#  define NID_dsaWithSHA1                 113
+#  define OBJ_dsaWithSHA1                 1L,2L,840L,10040L,4L,3L
+
+#  define NID_md5_sha1                    114
+#  define SN_md5_sha1                     "MD5-SHA1"
+#  define LN_md5_sha1                     "md5-sha1"
+
+#  define SN_sha1WithRSA                  "RSA-SHA1-2"
+#  define LN_sha1WithRSA                  "sha1WithRSA"
+#  define NID_sha1WithRSA                 115
+#  define OBJ_sha1WithRSA                 OBJ_algorithm,29L
+
+#  define SN_dsa                          "DSA"
+#  define LN_dsa                          "dsaEncryption"
+#  define NID_dsa                         116
+#  define OBJ_dsa                         1L,2L,840L,10040L,4L,1L
+
+#  define SN_ripemd160                    "RIPEMD160"
+#  define LN_ripemd160                    "ripemd160"
+#  define NID_ripemd160                   117
+#  define OBJ_ripemd160                   1L,3L,36L,3L,2L,1L
+
+/*
+ * The name should actually be rsaSignatureWithripemd160, but I'm going to
+ * continue using the convention I'm using with the other ciphers
+ */
+#  define SN_ripemd160WithRSA             "RSA-RIPEMD160"
+#  define LN_ripemd160WithRSA             "ripemd160WithRSA"
+#  define NID_ripemd160WithRSA            119
+#  define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L
+
+/*-
+ * Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *      version           INTEGER (v1_0(16)),
+ *      rounds            INTEGER (8..127),
+ *      blockSizeInBits   INTEGER (64, 128),
+ *      iv                OCTET STRING OPTIONAL
+ *      }
+ */
+#  define SN_rc5_cbc                      "RC5-CBC"
+#  define LN_rc5_cbc                      "rc5-cbc"
+#  define NID_rc5_cbc                     120
+#  define OBJ_rc5_cbc                     OBJ_rsadsi,3L,8L
+
+#  define SN_rc5_ecb                      "RC5-ECB"
+#  define LN_rc5_ecb                      "rc5-ecb"
+#  define NID_rc5_ecb                     121
+
+#  define SN_rc5_cfb64                    "RC5-CFB"
+#  define LN_rc5_cfb64                    "rc5-cfb"
+#  define NID_rc5_cfb64                   122
+
+#  define SN_rc5_ofb64                    "RC5-OFB"
+#  define LN_rc5_ofb64                    "rc5-ofb"
+#  define NID_rc5_ofb64                   123
+
+#  define SN_rle_compression              "RLE"
+#  define LN_rle_compression              "run length compression"
+#  define NID_rle_compression             124
+#  define OBJ_rle_compression             1L,1L,1L,1L,666L,1L
+
+#  define SN_zlib_compression             "ZLIB"
+#  define LN_zlib_compression             "zlib compression"
+#  define NID_zlib_compression            125
+#  define OBJ_zlib_compression            1L,1L,1L,1L,666L,2L
+
+#  define SN_ext_key_usage                "extendedKeyUsage"
+#  define LN_ext_key_usage                "X509v3 Extended Key Usage"
+#  define NID_ext_key_usage               126
+#  define OBJ_ext_key_usage               OBJ_id_ce,37
+
+#  define SN_id_pkix                      "PKIX"
+#  define NID_id_pkix                     127
+#  define OBJ_id_pkix                     1L,3L,6L,1L,5L,5L,7L
+
+#  define SN_id_kp                        "id-kp"
+#  define NID_id_kp                       128
+#  define OBJ_id_kp                       OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#  define SN_server_auth                  "serverAuth"
+#  define LN_server_auth                  "TLS Web Server Authentication"
+#  define NID_server_auth                 129
+#  define OBJ_server_auth                 OBJ_id_kp,1L
+
+#  define SN_client_auth                  "clientAuth"
+#  define LN_client_auth                  "TLS Web Client Authentication"
+#  define NID_client_auth                 130
+#  define OBJ_client_auth                 OBJ_id_kp,2L
+
+#  define SN_code_sign                    "codeSigning"
+#  define LN_code_sign                    "Code Signing"
+#  define NID_code_sign                   131
+#  define OBJ_code_sign                   OBJ_id_kp,3L
+
+#  define SN_email_protect                "emailProtection"
+#  define LN_email_protect                "E-mail Protection"
+#  define NID_email_protect               132
+#  define OBJ_email_protect               OBJ_id_kp,4L
+
+#  define SN_time_stamp                   "timeStamping"
+#  define LN_time_stamp                   "Time Stamping"
+#  define NID_time_stamp                  133
+#  define OBJ_time_stamp                  OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#  define SN_ms_code_ind                  "msCodeInd"
+#  define LN_ms_code_ind                  "Microsoft Individual Code Signing"
+#  define NID_ms_code_ind                 134
+#  define OBJ_ms_code_ind                 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#  define SN_ms_code_com                  "msCodeCom"
+#  define LN_ms_code_com                  "Microsoft Commercial Code Signing"
+#  define NID_ms_code_com                 135
+#  define OBJ_ms_code_com                 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#  define SN_ms_ctl_sign                  "msCTLSign"
+#  define LN_ms_ctl_sign                  "Microsoft Trust List Signing"
+#  define NID_ms_ctl_sign                 136
+#  define OBJ_ms_ctl_sign                 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#  define SN_ms_sgc                       "msSGC"
+#  define LN_ms_sgc                       "Microsoft Server Gated Crypto"
+#  define NID_ms_sgc                      137
+#  define OBJ_ms_sgc                      1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#  define SN_ms_efs                       "msEFS"
+#  define LN_ms_efs                       "Microsoft Encrypted File System"
+#  define NID_ms_efs                      138
+#  define OBJ_ms_efs                      1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#  define SN_ns_sgc                       "nsSGC"
+#  define LN_ns_sgc                       "Netscape Server Gated Crypto"
+#  define NID_ns_sgc                      139
+#  define OBJ_ns_sgc                      OBJ_netscape,4L,1L
+
+#  define SN_delta_crl                    "deltaCRL"
+#  define LN_delta_crl                    "X509v3 Delta CRL Indicator"
+#  define NID_delta_crl                   140
+#  define OBJ_delta_crl                   OBJ_id_ce,27L
+
+#  define SN_crl_reason                   "CRLReason"
+#  define LN_crl_reason                   "CRL Reason Code"
+#  define NID_crl_reason                  141
+#  define OBJ_crl_reason                  OBJ_id_ce,21L
+
+#  define SN_invalidity_date              "invalidityDate"
+#  define LN_invalidity_date              "Invalidity Date"
+#  define NID_invalidity_date             142
+#  define OBJ_invalidity_date             OBJ_id_ce,24L
+
+#  define SN_sxnet                        "SXNetID"
+#  define LN_sxnet                        "Strong Extranet ID"
+#  define NID_sxnet                       143
+#  define OBJ_sxnet                       1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#  define OBJ_pkcs12                      OBJ_pkcs,12L
+#  define OBJ_pkcs12_pbeids               OBJ_pkcs12, 1
+
+#  define SN_pbe_WithSHA1And128BitRC4     "PBE-SHA1-RC4-128"
+#  define LN_pbe_WithSHA1And128BitRC4     "pbeWithSHA1And128BitRC4"
+#  define NID_pbe_WithSHA1And128BitRC4    144
+#  define OBJ_pbe_WithSHA1And128BitRC4    OBJ_pkcs12_pbeids, 1L
+
+#  define SN_pbe_WithSHA1And40BitRC4      "PBE-SHA1-RC4-40"
+#  define LN_pbe_WithSHA1And40BitRC4      "pbeWithSHA1And40BitRC4"
+#  define NID_pbe_WithSHA1And40BitRC4     145
+#  define OBJ_pbe_WithSHA1And40BitRC4     OBJ_pkcs12_pbeids, 2L
+
+#  define SN_pbe_WithSHA1And3_Key_TripleDES_CBC   "PBE-SHA1-3DES"
+#  define LN_pbe_WithSHA1And3_Key_TripleDES_CBC   "pbeWithSHA1And3-KeyTripleDES-CBC"
+#  define NID_pbe_WithSHA1And3_Key_TripleDES_CBC  146
+#  define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 3L
+
+#  define SN_pbe_WithSHA1And2_Key_TripleDES_CBC   "PBE-SHA1-2DES"
+#  define LN_pbe_WithSHA1And2_Key_TripleDES_CBC   "pbeWithSHA1And2-KeyTripleDES-CBC"
+#  define NID_pbe_WithSHA1And2_Key_TripleDES_CBC  147
+#  define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 4L
+
+#  define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
+#  define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
+#  define NID_pbe_WithSHA1And128BitRC2_CBC        148
+#  define OBJ_pbe_WithSHA1And128BitRC2_CBC        OBJ_pkcs12_pbeids, 5L
+
+#  define SN_pbe_WithSHA1And40BitRC2_CBC  "PBE-SHA1-RC2-40"
+#  define LN_pbe_WithSHA1And40BitRC2_CBC  "pbeWithSHA1And40BitRC2-CBC"
+#  define NID_pbe_WithSHA1And40BitRC2_CBC 149
+#  define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L
+
+#  define OBJ_pkcs12_Version1     OBJ_pkcs12, 10L
+
+#  define OBJ_pkcs12_BagIds       OBJ_pkcs12_Version1, 1L
+
+#  define LN_keyBag               "keyBag"
+#  define NID_keyBag              150
+#  define OBJ_keyBag              OBJ_pkcs12_BagIds, 1L
+
+#  define LN_pkcs8ShroudedKeyBag  "pkcs8ShroudedKeyBag"
+#  define NID_pkcs8ShroudedKeyBag 151
+#  define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L
+
+#  define LN_certBag              "certBag"
+#  define NID_certBag             152
+#  define OBJ_certBag             OBJ_pkcs12_BagIds, 3L
+
+#  define LN_crlBag               "crlBag"
+#  define NID_crlBag              153
+#  define OBJ_crlBag              OBJ_pkcs12_BagIds, 4L
+
+#  define LN_secretBag            "secretBag"
+#  define NID_secretBag           154
+#  define OBJ_secretBag           OBJ_pkcs12_BagIds, 5L
+
+#  define LN_safeContentsBag      "safeContentsBag"
+#  define NID_safeContentsBag     155
+#  define OBJ_safeContentsBag     OBJ_pkcs12_BagIds, 6L
+
+#  define LN_friendlyName         "friendlyName"
+#  define NID_friendlyName        156
+#  define OBJ_friendlyName        OBJ_pkcs9, 20L
+
+#  define LN_localKeyID           "localKeyID"
+#  define NID_localKeyID          157
+#  define OBJ_localKeyID          OBJ_pkcs9, 21L
+
+#  define OBJ_certTypes           OBJ_pkcs9, 22L
+
+#  define LN_x509Certificate      "x509Certificate"
+#  define NID_x509Certificate     158
+#  define OBJ_x509Certificate     OBJ_certTypes, 1L
+
+#  define LN_sdsiCertificate      "sdsiCertificate"
+#  define NID_sdsiCertificate     159
+#  define OBJ_sdsiCertificate     OBJ_certTypes, 2L
+
+#  define OBJ_crlTypes            OBJ_pkcs9, 23L
+
+#  define LN_x509Crl              "x509Crl"
+#  define NID_x509Crl             160
+#  define OBJ_x509Crl             OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#  define LN_pbes2                "PBES2"
+#  define NID_pbes2               161
+#  define OBJ_pbes2               OBJ_pkcs,5L,13L
+
+#  define LN_pbmac1               "PBMAC1"
+#  define NID_pbmac1              162
+#  define OBJ_pbmac1              OBJ_pkcs,5L,14L
+
+#  define LN_hmacWithSHA1         "hmacWithSHA1"
+#  define NID_hmacWithSHA1        163
+#  define OBJ_hmacWithSHA1        OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#  define LN_id_qt_cps            "Policy Qualifier CPS"
+#  define SN_id_qt_cps            "id-qt-cps"
+#  define NID_id_qt_cps           164
+#  define OBJ_id_qt_cps           OBJ_id_pkix,2L,1L
+
+#  define LN_id_qt_unotice        "Policy Qualifier User Notice"
+#  define SN_id_qt_unotice        "id-qt-unotice"
+#  define NID_id_qt_unotice       165
+#  define OBJ_id_qt_unotice       OBJ_id_pkix,2L,2L
+
+#  define SN_rc2_64_cbc                   "RC2-64-CBC"
+#  define LN_rc2_64_cbc                   "rc2-64-cbc"
+#  define NID_rc2_64_cbc                  166
+
+#  define SN_SMIMECapabilities            "SMIME-CAPS"
+#  define LN_SMIMECapabilities            "S/MIME Capabilities"
+#  define NID_SMIMECapabilities           167
+#  define OBJ_SMIMECapabilities           OBJ_pkcs9,15L
+
+#  define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
+#  define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
+#  define NID_pbeWithMD2AndRC2_CBC        168
+#  define OBJ_pbeWithMD2AndRC2_CBC        OBJ_pkcs,5L,4L
+
+#  define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
+#  define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
+#  define NID_pbeWithMD5AndRC2_CBC        169
+#  define OBJ_pbeWithMD5AndRC2_CBC        OBJ_pkcs,5L,6L
+
+#  define SN_pbeWithSHA1AndDES_CBC        "PBE-SHA1-DES"
+#  define LN_pbeWithSHA1AndDES_CBC        "pbeWithSHA1AndDES-CBC"
+#  define NID_pbeWithSHA1AndDES_CBC       170
+#  define OBJ_pbeWithSHA1AndDES_CBC       OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#  define LN_ms_ext_req                   "Microsoft Extension Request"
+#  define SN_ms_ext_req                   "msExtReq"
+#  define NID_ms_ext_req                  171
+#  define OBJ_ms_ext_req                  1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#  define LN_ext_req                      "Extension Request"
+#  define SN_ext_req                      "extReq"
+#  define NID_ext_req                     172
+#  define OBJ_ext_req                     OBJ_pkcs9,14L
+
+#  define SN_name                         "name"
+#  define LN_name                         "name"
+#  define NID_name                        173
+#  define OBJ_name                        OBJ_X509,41L
+
+#  define SN_dnQualifier                  "dnQualifier"
+#  define LN_dnQualifier                  "dnQualifier"
+#  define NID_dnQualifier                 174
+#  define OBJ_dnQualifier                 OBJ_X509,46L
+
+#  define SN_id_pe                        "id-pe"
+#  define NID_id_pe                       175
+#  define OBJ_id_pe                       OBJ_id_pkix,1L
+
+#  define SN_id_ad                        "id-ad"
+#  define NID_id_ad                       176
+#  define OBJ_id_ad                       OBJ_id_pkix,48L
+
+#  define SN_info_access                  "authorityInfoAccess"
+#  define LN_info_access                  "Authority Information Access"
+#  define NID_info_access                 177
+#  define OBJ_info_access                 OBJ_id_pe,1L
+
+#  define SN_ad_OCSP                      "OCSP"
+#  define LN_ad_OCSP                      "OCSP"
+#  define NID_ad_OCSP                     178
+#  define OBJ_ad_OCSP                     OBJ_id_ad,1L
+
+#  define SN_ad_ca_issuers                "caIssuers"
+#  define LN_ad_ca_issuers                "CA Issuers"
+#  define NID_ad_ca_issuers               179
+#  define OBJ_ad_ca_issuers               OBJ_id_ad,2L
+
+#  define SN_OCSP_sign                    "OCSPSigning"
+#  define LN_OCSP_sign                    "OCSP Signing"
+#  define NID_OCSP_sign                   180
+#  define OBJ_OCSP_sign                   OBJ_id_kp,9L
+# endif                         /* USE_OBJ_MAC */
+
+# include <openssl/bio.h>
+# include <openssl/asn1.h>
+
+# define OBJ_NAME_TYPE_UNDEF             0x00
+# define OBJ_NAME_TYPE_MD_METH           0x01
+# define OBJ_NAME_TYPE_CIPHER_METH       0x02
+# define OBJ_NAME_TYPE_PKEY_METH         0x03
+# define OBJ_NAME_TYPE_COMP_METH         0x04
+# define OBJ_NAME_TYPE_NUM               0x05
+
+# define OBJ_NAME_ALIAS                  0x8000
+
+# define OBJ_BSEARCH_VALUE_ON_NOMATCH            0x01
+# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH        0x02
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st {
+    int type;
+    int alias;
+    const char *name;
+    const char *data;
+} OBJ_NAME;
+
+# define         OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+int OBJ_NAME_init(void);
+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 *));
+const char *OBJ_NAME_get(const char *name, int type);
+int OBJ_NAME_add(const char *name, int type, const char *data);
+int OBJ_NAME_remove(const char *name, int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
+                     void *arg);
+void OBJ_NAME_do_all_sorted(int type,
+                            void (*fn) (const OBJ_NAME *, void *arg),
+                            void *arg);
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_nid2obj(int n);
+const char *OBJ_nid2ln(int n);
+const char *OBJ_nid2sn(int n);
+int OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name);
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int OBJ_txt2nid(const char *s);
+int OBJ_ln2nid(const char *s);
+int OBJ_sn2nid(const char *s);
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+                         int (*cmp) (const void *, const void *));
+const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
+                            int size,
+                            int (*cmp) (const void *, const void *),
+                            int flags);
+
+# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)    \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+  static int nm##_cmp(type1 const *, type2 const *); \
+  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)   \
+  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)     \
+  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*-
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)  \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+                                        nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)   \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+                                        nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+# define OBJ_bsearch(type1,key,type2,base,num,cmp)                              \
+  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+                         num,sizeof(type2),                             \
+                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
+                          (void)CHECKED_PTR_OF(type2,cmp##_type_2),     \
+                          cmp##_BSEARCH_CMP_FN)))
+
+# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)                      \
+  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+                         num,sizeof(type2),                             \
+                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
+                          (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+                          cmp##_BSEARCH_CMP_FN)),flags)
+
+int OBJ_new_nid(int num);
+int OBJ_add_object(const ASN1_OBJECT *obj);
+int OBJ_create(const char *oid, const char *sn, const char *ln);
+void OBJ_cleanup(void);
+int OBJ_create_objects(BIO *in);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+extern int obj_cleanup_defer;
+void check_defer(int nid);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+# define OBJ_F_OBJ_ADD_OBJECT                             105
+# define OBJ_F_OBJ_CREATE                                 100
+# define OBJ_F_OBJ_DUP                                    101
+# define OBJ_F_OBJ_NAME_NEW_INDEX                         106
+# define OBJ_F_OBJ_NID2LN                                 102
+# define OBJ_F_OBJ_NID2OBJ                                103
+# define OBJ_F_OBJ_NID2SN                                 104
+
+/* Reason codes. */
+# define OBJ_R_MALLOC_FAILURE                             100
+# define OBJ_R_UNKNOWN_NID                                101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ocsp.h b/Cryptlib/Include/openssl/ocsp.h
new file mode 100644 (file)
index 0000000..ca2ee76
--- /dev/null
@@ -0,0 +1,637 @@
+/* ocsp.h */
+/*
+ * 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).
+ *
+ */
+
+#ifndef HEADER_OCSP_H
+# define HEADER_OCSP_H
+
+# include <openssl/ossl_typ.h>
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+# include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Various flags and values */
+
+# define OCSP_DEFAULT_NONCE_LENGTH       16
+
+# define OCSP_NOCERTS                    0x1
+# define OCSP_NOINTERN                   0x2
+# define OCSP_NOSIGS                     0x4
+# define OCSP_NOCHAIN                    0x8
+# define OCSP_NOVERIFY                   0x10
+# define OCSP_NOEXPLICIT                 0x20
+# define OCSP_NOCASIGN                   0x40
+# define OCSP_NODELEGATED                0x80
+# define OCSP_NOCHECKS                   0x100
+# define OCSP_TRUSTOTHER                 0x200
+# define OCSP_RESPID_KEY                 0x400
+# define OCSP_NOTIME                     0x800
+
+/*-  CertID ::= SEQUENCE {
+ *       hashAlgorithm            AlgorithmIdentifier,
+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
+ *       serialNumber       CertificateSerialNumber }
+ */
+typedef struct ocsp_cert_id_st {
+    X509_ALGOR *hashAlgorithm;
+    ASN1_OCTET_STRING *issuerNameHash;
+    ASN1_OCTET_STRING *issuerKeyHash;
+    ASN1_INTEGER *serialNumber;
+} OCSP_CERTID;
+
+DECLARE_STACK_OF(OCSP_CERTID)
+
+/*-  Request ::=     SEQUENCE {
+ *       reqCert                    CertID,
+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_one_request_st {
+    OCSP_CERTID *reqCert;
+    STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+} OCSP_ONEREQ;
+
+DECLARE_STACK_OF(OCSP_ONEREQ)
+DECLARE_ASN1_SET_OF(OCSP_ONEREQ)
+
+/*-  TBSRequest      ::=     SEQUENCE {
+ *       version             [0] EXPLICIT Version DEFAULT v1,
+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+ *       requestList             SEQUENCE OF Request,
+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_req_info_st {
+    ASN1_INTEGER *version;
+    GENERAL_NAME *requestorName;
+    STACK_OF(OCSP_ONEREQ) *requestList;
+    STACK_OF(X509_EXTENSION) *requestExtensions;
+} OCSP_REQINFO;
+
+/*-  Signature       ::=     SEQUENCE {
+ *       signatureAlgorithm   AlgorithmIdentifier,
+ *       signature            BIT STRING,
+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+typedef struct ocsp_signature_st {
+    X509_ALGOR *signatureAlgorithm;
+    ASN1_BIT_STRING *signature;
+    STACK_OF(X509) *certs;
+} OCSP_SIGNATURE;
+
+/*-  OCSPRequest     ::=     SEQUENCE {
+ *       tbsRequest                  TBSRequest,
+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+ */
+typedef struct ocsp_request_st {
+    OCSP_REQINFO *tbsRequest;
+    OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
+} OCSP_REQUEST;
+
+/*-  OCSPResponseStatus ::= ENUMERATED {
+ *       successful            (0),      --Response has valid confirmations
+ *       malformedRequest      (1),      --Illegal confirmation request
+ *       internalError         (2),      --Internal error in issuer
+ *       tryLater              (3),      --Try again later
+ *                                       --(4) is not used
+ *       sigRequired           (5),      --Must sign the request
+ *       unauthorized          (6)       --Request unauthorized
+ *   }
+ */
+# define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
+# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
+# define OCSP_RESPONSE_STATUS_INTERNALERROR        2
+# define OCSP_RESPONSE_STATUS_TRYLATER             3
+# define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
+# define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
+
+/*-  ResponseBytes ::=       SEQUENCE {
+ *       responseType   OBJECT IDENTIFIER,
+ *       response       OCTET STRING }
+ */
+typedef struct ocsp_resp_bytes_st {
+    ASN1_OBJECT *responseType;
+    ASN1_OCTET_STRING *response;
+} OCSP_RESPBYTES;
+
+/*-  OCSPResponse ::= SEQUENCE {
+ *      responseStatus         OCSPResponseStatus,
+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+struct ocsp_response_st {
+    ASN1_ENUMERATED *responseStatus;
+    OCSP_RESPBYTES *responseBytes;
+};
+
+/*-  ResponderID ::= CHOICE {
+ *      byName   [1] Name,
+ *      byKey    [2] KeyHash }
+ */
+# define V_OCSP_RESPID_NAME 0
+# define V_OCSP_RESPID_KEY  1
+struct ocsp_responder_id_st {
+    int type;
+    union {
+        X509_NAME *byName;
+        ASN1_OCTET_STRING *byKey;
+    } value;
+};
+
+DECLARE_STACK_OF(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+
+/*-  KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ *                            --(excluding the tag and length fields)
+ */
+
+/*-  RevokedInfo ::= SEQUENCE {
+ *       revocationTime              GeneralizedTime,
+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ */
+typedef struct ocsp_revoked_info_st {
+    ASN1_GENERALIZEDTIME *revocationTime;
+    ASN1_ENUMERATED *revocationReason;
+} OCSP_REVOKEDINFO;
+
+/*-  CertStatus ::= CHOICE {
+ *       good                [0]     IMPLICIT NULL,
+ *       revoked             [1]     IMPLICIT RevokedInfo,
+ *       unknown             [2]     IMPLICIT UnknownInfo }
+ */
+# define V_OCSP_CERTSTATUS_GOOD    0
+# define V_OCSP_CERTSTATUS_REVOKED 1
+# define V_OCSP_CERTSTATUS_UNKNOWN 2
+typedef struct ocsp_cert_status_st {
+    int type;
+    union {
+        ASN1_NULL *good;
+        OCSP_REVOKEDINFO *revoked;
+        ASN1_NULL *unknown;
+    } value;
+} OCSP_CERTSTATUS;
+
+/*-  SingleResponse ::= SEQUENCE {
+ *      certID                       CertID,
+ *      certStatus                   CertStatus,
+ *      thisUpdate                   GeneralizedTime,
+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_single_response_st {
+    OCSP_CERTID *certId;
+    OCSP_CERTSTATUS *certStatus;
+    ASN1_GENERALIZEDTIME *thisUpdate;
+    ASN1_GENERALIZEDTIME *nextUpdate;
+    STACK_OF(X509_EXTENSION) *singleExtensions;
+} OCSP_SINGLERESP;
+
+DECLARE_STACK_OF(OCSP_SINGLERESP)
+DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)
+
+/*-  ResponseData ::= SEQUENCE {
+ *      version              [0] EXPLICIT Version DEFAULT v1,
+ *      responderID              ResponderID,
+ *      producedAt               GeneralizedTime,
+ *      responses                SEQUENCE OF SingleResponse,
+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_response_data_st {
+    ASN1_INTEGER *version;
+    OCSP_RESPID *responderId;
+    ASN1_GENERALIZEDTIME *producedAt;
+    STACK_OF(OCSP_SINGLERESP) *responses;
+    STACK_OF(X509_EXTENSION) *responseExtensions;
+} OCSP_RESPDATA;
+
+/*-  BasicOCSPResponse       ::= SEQUENCE {
+ *      tbsResponseData      ResponseData,
+ *      signatureAlgorithm   AlgorithmIdentifier,
+ *      signature            BIT STRING,
+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+  /*
+   * Note 1: The value for "signature" is specified in the OCSP rfc2560 as
+   * follows: "The value for the signature SHALL be computed on the hash of
+   * the DER encoding ResponseData." This means that you must hash the
+   * DER-encoded tbsResponseData, and then run it through a crypto-signing
+   * function, which will (at least w/RSA) do a hash-'n'-private-encrypt
+   * operation.  This seems a bit odd, but that's the spec.  Also note that
+   * the data structures do not leave anywhere to independently specify the
+   * algorithm used for the initial hash. So, we look at the
+   * signature-specification algorithm, and try to do something intelligent.
+   * -- Kathy Weinhold, CertCo
+   */
+  /*
+   * Note 2: It seems that the mentioned passage from RFC 2560 (section
+   * 4.2.1) is open for interpretation.  I've done tests against another
+   * responder, and found that it doesn't do the double hashing that the RFC
+   * seems to say one should.  Therefore, all relevant functions take a flag
+   * saying which variant should be used.  -- Richard Levitte, OpenSSL team
+   * and CeloCom
+   */
+typedef struct ocsp_basic_response_st {
+    OCSP_RESPDATA *tbsResponseData;
+    X509_ALGOR *signatureAlgorithm;
+    ASN1_BIT_STRING *signature;
+    STACK_OF(X509) *certs;
+} OCSP_BASICRESP;
+
+/*-
+ *   CRLReason ::= ENUMERATED {
+ *        unspecified             (0),
+ *        keyCompromise           (1),
+ *        cACompromise            (2),
+ *        affiliationChanged      (3),
+ *        superseded              (4),
+ *        cessationOfOperation    (5),
+ *        certificateHold         (6),
+ *        removeFromCRL           (8) }
+ */
+# define OCSP_REVOKED_STATUS_NOSTATUS               -1
+# define OCSP_REVOKED_STATUS_UNSPECIFIED             0
+# define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
+# define OCSP_REVOKED_STATUS_CACOMPROMISE            2
+# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
+# define OCSP_REVOKED_STATUS_SUPERSEDED              4
+# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
+# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
+# define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
+
+/*-
+ * CrlID ::= SEQUENCE {
+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+ */
+typedef struct ocsp_crl_id_st {
+    ASN1_IA5STRING *crlUrl;
+    ASN1_INTEGER *crlNum;
+    ASN1_GENERALIZEDTIME *crlTime;
+} OCSP_CRLID;
+
+/*-
+ * ServiceLocator ::= SEQUENCE {
+ *      issuer    Name,
+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
+ */
+typedef struct ocsp_service_locator_st {
+    X509_NAME *issuer;
+    STACK_OF(ACCESS_DESCRIPTION) *locator;
+} OCSP_SERVICELOC;
+
+# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST"
+# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
+
+# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
+
+# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
+
+# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
+     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
+
+# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
+     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
+
+# define PEM_write_bio_OCSP_REQUEST(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
+                        bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+# define PEM_write_bio_OCSP_RESPONSE(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
+                        bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
+
+# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
+
+# define OCSP_REQUEST_sign(o,pkey,md) \
+        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
+                o->optionalSignature->signatureAlgorithm,NULL,\
+                o->optionalSignature->signature,o->tbsRequest,pkey,md)
+
+# define OCSP_BASICRESP_sign(o,pkey,md,d) \
+        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
+                o->signature,o->tbsResponseData,pkey,md)
+
+# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
+        a->optionalSignature->signatureAlgorithm,\
+        a->optionalSignature->signature,a->tbsRequest,r)
+
+# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
+        a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
+
+# define ASN1_BIT_STRING_digest(data,type,md,len) \
+        ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
+
+# define OCSP_CERTSTATUS_dup(cs)\
+                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
+                (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
+
+OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req);
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
+                               int maxline);
+int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx);
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
+OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline);
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len);
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
+                     ASN1_VALUE *val);
+int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval,
+                          const ASN1_ITEM *it);
+BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
+                     ASN1_VALUE *val);
+int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+                             const char *name, const char *value);
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
+                              X509_NAME *issuerName,
+                              ASN1_BIT_STRING *issuerKey,
+                              ASN1_INTEGER *serialNumber);
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
+
+int OCSP_request_sign(OCSP_REQUEST *req,
+                      X509 *signer,
+                      EVP_PKEY *key,
+                      const EVP_MD *dgst,
+                      STACK_OF(X509) *certs, unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+
+int OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+                            ASN1_GENERALIZEDTIME **revtime,
+                            ASN1_GENERALIZEDTIME **thisupd,
+                            ASN1_GENERALIZEDTIME **nextupd);
+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 OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+                        ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec);
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
+                        X509_STORE *store, unsigned long flags);
+
+int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
+                   int *pssl);
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req);
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+                      ASN1_OCTET_STRING **pikeyHash,
+                      ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
+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);
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
+int OCSP_basic_sign(OCSP_BASICRESP *brsp,
+                    X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+                    STACK_OF(X509) *certs, unsigned long flags);
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
+
+X509_EXTENSION *OCSP_accept_responses_new(char **oids);
+
+X509_EXTENSION *OCSP_archive_cutoff_new(char *tim);
+
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls);
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj,
+                                int lastpos);
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit,
+                                int *idx);
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+                              unsigned long flags);
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+                             unsigned long flags);
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj,
+                                  int lastpos);
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
+                                       int lastpos);
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
+                                  int *idx);
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
+                                int crit, unsigned long flags);
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj,
+                                   int lastpos);
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
+                                        int lastpos);
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
+                                   int *idx);
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
+                                 int crit, unsigned long flags);
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
+
+DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
+DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
+DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
+
+const char *OCSP_response_status_str(long s);
+const char *OCSP_cert_status_str(long s);
+const char *OCSP_crl_reason_str(long s);
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags);
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags);
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+                      X509_STORE *st, unsigned long flags);
+
+/* 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_OCSP_strings(void);
+
+/* Error codes for the OCSP functions. */
+
+/* Function codes. */
+# define OCSP_F_ASN1_STRING_ENCODE                        100
+# define OCSP_F_D2I_OCSP_NONCE                            102
+# define OCSP_F_OCSP_BASIC_ADD1_STATUS                    103
+# define OCSP_F_OCSP_BASIC_SIGN                           104
+# define OCSP_F_OCSP_BASIC_VERIFY                         105
+# define OCSP_F_OCSP_CERT_ID_NEW                          101
+# define OCSP_F_OCSP_CHECK_DELEGATED                      106
+# define OCSP_F_OCSP_CHECK_IDS                            107
+# define OCSP_F_OCSP_CHECK_ISSUER                         108
+# define OCSP_F_OCSP_CHECK_VALIDITY                       115
+# define OCSP_F_OCSP_MATCH_ISSUERID                       109
+# define OCSP_F_OCSP_PARSE_URL                            114
+# define OCSP_F_OCSP_REQUEST_SIGN                         110
+# define OCSP_F_OCSP_REQUEST_VERIFY                       116
+# define OCSP_F_OCSP_RESPONSE_GET1_BASIC                  111
+# define OCSP_F_OCSP_SENDREQ_BIO                          112
+# define OCSP_F_OCSP_SENDREQ_NBIO                         117
+# define OCSP_F_PARSE_HTTP_LINE1                          118
+# define OCSP_F_REQUEST_VERIFY                            113
+
+/* Reason codes. */
+# define OCSP_R_BAD_DATA                                  100
+# define OCSP_R_CERTIFICATE_VERIFY_ERROR                  101
+# define OCSP_R_DIGEST_ERR                                102
+# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD                 122
+# define OCSP_R_ERROR_IN_THISUPDATE_FIELD                 123
+# define OCSP_R_ERROR_PARSING_URL                         121
+# define OCSP_R_MISSING_OCSPSIGNING_USAGE                 103
+# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE              124
+# define OCSP_R_NOT_BASIC_RESPONSE                        104
+# define OCSP_R_NO_CERTIFICATES_IN_CHAIN                  105
+# define OCSP_R_NO_CONTENT                                106
+# define OCSP_R_NO_PUBLIC_KEY                             107
+# define OCSP_R_NO_RESPONSE_DATA                          108
+# define OCSP_R_NO_REVOKED_TIME                           109
+# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE    110
+# define OCSP_R_REQUEST_NOT_SIGNED                        128
+# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA      111
+# define OCSP_R_ROOT_CA_NOT_TRUSTED                       112
+# define OCSP_R_SERVER_READ_ERROR                         113
+# define OCSP_R_SERVER_RESPONSE_ERROR                     114
+# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR               115
+# define OCSP_R_SERVER_WRITE_ERROR                        116
+# define OCSP_R_SIGNATURE_FAILURE                         117
+# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND              118
+# define OCSP_R_STATUS_EXPIRED                            125
+# define OCSP_R_STATUS_NOT_YET_VALID                      126
+# define OCSP_R_STATUS_TOO_OLD                            127
+# define OCSP_R_UNKNOWN_MESSAGE_DIGEST                    119
+# define OCSP_R_UNKNOWN_NID                               120
+# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE            129
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/opensslconf.h b/Cryptlib/Include/openssl/opensslconf.h
new file mode 100644 (file)
index 0000000..adcaa01
--- /dev/null
@@ -0,0 +1,503 @@
+/* opensslconf.h */\r
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\r
+\r
+#ifdef  __cplusplus\r
+extern "C" {\r
+#endif\r
+/* OpenSSL was configured with the following options: */\r
+#ifndef OPENSSL_SYSNAME_UEFI\r
+# define OPENSSL_SYSNAME_UEFI\r
+#endif\r
+#ifndef OPENSSL_DOING_MAKEDEPEND\r
+\r
+\r
+#ifndef OPENSSL_NO_BF\r
+# define OPENSSL_NO_BF\r
+#endif\r
+#ifndef OPENSSL_NO_CAMELLIA\r
+# define OPENSSL_NO_CAMELLIA\r
+#endif\r
+#ifndef OPENSSL_NO_CAPIENG\r
+# define OPENSSL_NO_CAPIENG\r
+#endif\r
+#ifndef OPENSSL_NO_CAST\r
+# define OPENSSL_NO_CAST\r
+#endif\r
+#ifndef OPENSSL_NO_CMS\r
+# define OPENSSL_NO_CMS\r
+#endif\r
+#ifndef OPENSSL_NO_DEPRECATED\r
+# define OPENSSL_NO_DEPRECATED\r
+#endif\r
+#ifndef OPENSSL_NO_DGRAM\r
+# define OPENSSL_NO_DGRAM\r
+#endif\r
+#ifndef OPENSSL_NO_DSA\r
+# define OPENSSL_NO_DSA\r
+#endif\r
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE\r
+# define OPENSSL_NO_DYNAMIC_ENGINE\r
+#endif\r
+#ifndef OPENSSL_NO_EC\r
+# define OPENSSL_NO_EC\r
+#endif\r
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128\r
+# define OPENSSL_NO_EC_NISTP_64_GCC_128\r
+#endif\r
+#ifndef OPENSSL_NO_ECDH\r
+# define OPENSSL_NO_ECDH\r
+#endif\r
+#ifndef OPENSSL_NO_ECDSA\r
+# define OPENSSL_NO_ECDSA\r
+#endif\r
+#ifndef OPENSSL_NO_ENGINE\r
+# define OPENSSL_NO_ENGINE\r
+#endif\r
+#ifndef OPENSSL_NO_ENGINES\r
+# define OPENSSL_NO_ENGINES\r
+#endif\r
+#ifndef OPENSSL_NO_FILENAMES\r
+# define OPENSSL_NO_FILENAMES\r
+#endif\r
+#ifndef OPENSSL_NO_FP_API\r
+# define OPENSSL_NO_FP_API\r
+#endif\r
+#ifndef OPENSSL_NO_GMP\r
+# define OPENSSL_NO_GMP\r
+#endif\r
+#ifndef OPENSSL_NO_GOST\r
+# define OPENSSL_NO_GOST\r
+#endif\r
+#ifndef OPENSSL_NO_IDEA\r
+# define OPENSSL_NO_IDEA\r
+#endif\r
+#ifndef OPENSSL_NO_JPAKE\r
+# define OPENSSL_NO_JPAKE\r
+#endif\r
+#ifndef OPENSSL_NO_KRB5\r
+# define OPENSSL_NO_KRB5\r
+#endif\r
+#ifndef OPENSSL_NO_LIBUNBOUND\r
+# define OPENSSL_NO_LIBUNBOUND\r
+#endif\r
+#ifndef OPENSSL_NO_LOCKING\r
+# define OPENSSL_NO_LOCKING\r
+#endif\r
+#ifndef OPENSSL_NO_MD2\r
+# define OPENSSL_NO_MD2\r
+#endif\r
+#ifndef OPENSSL_NO_MDC2\r
+# define OPENSSL_NO_MDC2\r
+#endif\r
+#ifndef OPENSSL_NO_POSIX_IO\r
+# define OPENSSL_NO_POSIX_IO\r
+#endif\r
+#ifndef OPENSSL_NO_PQUEUE\r
+# define OPENSSL_NO_PQUEUE\r
+#endif\r
+#ifndef OPENSSL_NO_RC2\r
+# define OPENSSL_NO_RC2\r
+#endif\r
+#ifndef OPENSSL_NO_RC5\r
+# define OPENSSL_NO_RC5\r
+#endif\r
+#ifndef OPENSSL_NO_RCS\r
+# define OPENSSL_NO_RCS\r
+#endif\r
+#ifndef OPENSSL_NO_RFC3779\r
+# define OPENSSL_NO_RFC3779\r
+#endif\r
+#ifndef OPENSSL_NO_RIPEMD\r
+# define OPENSSL_NO_RIPEMD\r
+#endif\r
+#ifndef OPENSSL_NO_SCRYPT\r
+# define OPENSSL_NO_SCRYPT\r
+#endif\r
+#ifndef OPENSSL_NO_SCT\r
+# define OPENSSL_NO_SCT\r
+#endif\r
+#ifndef OPENSSL_NO_SCTP\r
+# define OPENSSL_NO_SCTP\r
+#endif\r
+#ifndef OPENSSL_NO_SEED\r
+# define OPENSSL_NO_SEED\r
+#endif\r
+#ifndef OPENSSL_NO_SHA0\r
+# define OPENSSL_NO_SHA0\r
+#endif\r
+#ifndef OPENSSL_NO_SOCK\r
+# define OPENSSL_NO_SOCK\r
+#endif\r
+#ifndef OPENSSL_NO_SRP\r
+# define OPENSSL_NO_SRP\r
+#endif\r
+#ifndef OPENSSL_NO_SSL_TRACE\r
+# define OPENSSL_NO_SSL_TRACE\r
+#endif\r
+#ifndef OPENSSL_NO_SSL2\r
+# define OPENSSL_NO_SSL2\r
+#endif\r
+#ifndef OPENSSL_NO_SSL3\r
+# define OPENSSL_NO_SSL3\r
+#endif\r
+#ifndef OPENSSL_NO_STDIO\r
+# define OPENSSL_NO_STDIO\r
+#endif\r
+#ifndef OPENSSL_NO_STORE\r
+# define OPENSSL_NO_STORE\r
+#endif\r
+#ifndef OPENSSL_NO_TS\r
+# define OPENSSL_NO_TS\r
+#endif\r
+#ifndef OPENSSL_NO_UI\r
+# define OPENSSL_NO_UI\r
+#endif\r
+#ifndef OPENSSL_NO_UNIT_TEST\r
+# define OPENSSL_NO_UNIT_TEST\r
+#endif\r
+#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS\r
+# define OPENSSL_NO_WEAK_SSL_CIPHERS\r
+#endif\r
+#ifndef OPENSSL_NO_WHIRLPOOL\r
+# define OPENSSL_NO_WHIRLPOOL\r
+#endif\r
+\r
+#endif /* OPENSSL_DOING_MAKEDEPEND */\r
+\r
+#ifndef OPENSSL_NO_ASM\r
+# define OPENSSL_NO_ASM\r
+#endif\r
+#ifndef OPENSSL_NO_ERR\r
+# define OPENSSL_NO_ERR\r
+#endif\r
+#ifndef OPENSSL_NO_HW\r
+# define OPENSSL_NO_HW\r
+#endif\r
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE\r
+# define OPENSSL_NO_DYNAMIC_ENGINE\r
+#endif\r
+\r
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application\r
+   asks for it.  This is a transient feature that is provided for those\r
+   who haven't had the time to do the appropriate changes in their\r
+   applications.  */\r
+#ifdef OPENSSL_ALGORITHM_DEFINES\r
+# if defined(OPENSSL_NO_BF) && !defined(NO_BF)\r
+#  define NO_BF\r
+# endif\r
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)\r
+#  define NO_CAMELLIA\r
+# endif\r
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)\r
+#  define NO_CAPIENG\r
+# endif\r
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)\r
+#  define NO_CAST\r
+# endif\r
+# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)\r
+#  define NO_CMS\r
+# endif\r
+# if defined(OPENSSL_NO_DEPRECATED) && !defined(NO_DEPRECATED)\r
+#  define NO_DEPRECATED\r
+# endif\r
+# if defined(OPENSSL_NO_DGRAM) && !defined(NO_DGRAM)\r
+#  define NO_DGRAM\r
+# endif\r
+# if defined(OPENSSL_NO_DSA) && !defined(NO_DSA)\r
+#  define NO_DSA\r
+# endif\r
+# if defined(OPENSSL_NO_DYNAMIC_ENGINE) && !defined(NO_DYNAMIC_ENGINE)\r
+#  define NO_DYNAMIC_ENGINE\r
+# endif\r
+# if defined(OPENSSL_NO_EC) && !defined(NO_EC)\r
+#  define NO_EC\r
+# endif\r
+# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)\r
+#  define NO_EC_NISTP_64_GCC_128\r
+# endif\r
+# if defined(OPENSSL_NO_ECDH) && !defined(NO_ECDH)\r
+#  define NO_ECDH\r
+# endif\r
+# if defined(OPENSSL_NO_ECDSA) && !defined(NO_ECDSA)\r
+#  define NO_ECDSA\r
+# endif\r
+# if defined(OPENSSL_NO_ENGINE) && !defined(NO_ENGINE)\r
+#  define NO_ENGINE\r
+# endif\r
+# if defined(OPENSSL_NO_ENGINES) && !defined(NO_ENGINES)\r
+#  define NO_ENGINES\r
+# endif\r
+# if defined(OPENSSL_NO_FILENAMES) && !defined(NO_FILENAMES)\r
+#  define NO_FILENAMES\r
+# endif\r
+# if defined(OPENSSL_NO_FP_API) && !defined(NO_FP_API)\r
+#  define NO_FP_API\r
+# endif\r
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)\r
+#  define NO_GMP\r
+# endif\r
+# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)\r
+#  define NO_GOST\r
+# endif\r
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)\r
+#  define NO_IDEA\r
+# endif\r
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)\r
+#  define NO_JPAKE\r
+# endif\r
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)\r
+#  define NO_KRB5\r
+# endif\r
+# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND)\r
+#  define NO_LIBUNBOUND\r
+# endif\r
+# if defined(OPENSSL_NO_LOCKING) && !defined(NO_LOCKING)\r
+#  define NO_LOCKING\r
+# endif\r
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)\r
+#  define NO_MD2\r
+# endif\r
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)\r
+#  define NO_MDC2\r
+# endif\r
+# if defined(OPENSSL_NO_POSIX_IO) && !defined(NO_POSIX_IO)\r
+#  define NO_POSIX_IO\r
+# endif\r
+# if defined(OPENSSL_NO_PQUEUE) && !defined(NO_PQUEUE)\r
+#  define NO_PQUEUE\r
+# endif\r
+# if defined(OPENSSL_NO_RC2) && !defined(NO_RC2)\r
+#  define NO_RC2\r
+# endif\r
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)\r
+#  define NO_RC5\r
+# endif\r
+# if defined(OPENSSL_NO_RCS) && !defined(NO_RCS)\r
+#  define NO_RCS\r
+# endif\r
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)\r
+#  define NO_RFC3779\r
+# endif\r
+# if defined(OPENSSL_NO_RIPEMD) && !defined(NO_RIPEMD)\r
+#  define NO_RIPEMD\r
+# endif\r
+# if defined(OPENSSL_NO_SCRYPT) && !defined(NO_SCRYPT)\r
+#  define NO_SCRYPT\r
+# endif\r
+# if defined(OPENSSL_NO_SCT) && !defined(NO_SCT)\r
+#  define NO_SCT\r
+# endif\r
+# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)\r
+#  define NO_SCTP\r
+# endif\r
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)\r
+#  define NO_SEED\r
+# endif\r
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)\r
+#  define NO_SHA0\r
+# endif\r
+# if defined(OPENSSL_NO_SOCK) && !defined(NO_SOCK)\r
+#  define NO_SOCK\r
+# endif\r
+# if defined(OPENSSL_NO_SRP) && !defined(NO_SRP)\r
+#  define NO_SRP\r
+# endif\r
+# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE)\r
+#  define NO_SSL_TRACE\r
+# endif\r
+# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2)\r
+#  define NO_SSL2\r
+# endif\r
+# if defined(OPENSSL_NO_SSL3) && !defined(NO_SSL3)\r
+#  define NO_SSL3\r
+# endif\r
+# if defined(OPENSSL_NO_STDIO) && !defined(NO_STDIO)\r
+#  define NO_STDIO\r
+# endif\r
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)\r
+#  define NO_STORE\r
+# endif\r
+# if defined(OPENSSL_NO_TS) && !defined(NO_TS)\r
+#  define NO_TS\r
+# endif\r
+# if defined(OPENSSL_NO_UI) && !defined(NO_UI)\r
+#  define NO_UI\r
+# endif\r
+# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST)\r
+#  define NO_UNIT_TEST\r
+# endif\r
+# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS)\r
+#  define NO_WEAK_SSL_CIPHERS\r
+# endif\r
+# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)\r
+#  define NO_WHIRLPOOL\r
+# endif\r
+#endif\r
+\r
+/* crypto/opensslconf.h.in */\r
+\r
+#ifndef OPENSSL_FILE\r
+#ifdef OPENSSL_NO_FILENAMES\r
+#define OPENSSL_FILE ""\r
+#define OPENSSL_LINE 0\r
+#else\r
+#define OPENSSL_FILE __FILE__\r
+#define OPENSSL_LINE __LINE__\r
+#endif\r
+#endif\r
+\r
+/* Generate 80386 code? */\r
+#undef I386_ONLY\r
+\r
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */\r
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)\r
+#define ENGINESDIR "/usr/local/ssl/lib/engines"\r
+#define OPENSSLDIR "/usr/local/ssl"\r
+#endif\r
+#endif\r
+\r
+#undef OPENSSL_UNISTD\r
+#define OPENSSL_UNISTD <unistd.h>\r
+\r
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\r
+\r
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)\r
+#define IDEA_INT unsigned int\r
+#endif\r
+\r
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)\r
+#define MD2_INT unsigned int\r
+#endif\r
+\r
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)\r
+/* I need to put in a mod for the alpha - eay */\r
+#define RC2_INT unsigned int\r
+#endif\r
+\r
+#if defined(HEADER_RC4_H)\r
+#if !defined(RC4_INT)\r
+/* using int types make the structure larger but make the code faster\r
+ * on most boxes I have tested - up to %20 faster. */\r
+/*\r
+ * I don't know what does "most" mean, but declaring "int" is a must on:\r
+ * - Intel P6 because partial register stalls are very expensive;\r
+ * - elder Alpha because it lacks byte load/store instructions;\r
+ */\r
+#define RC4_INT unsigned int\r
+#endif\r
+#if !defined(RC4_CHUNK)\r
+/*\r
+ * This enables code handling data aligned at natural CPU word\r
+ * boundary. See crypto/rc4/rc4_enc.c for further details.\r
+ */\r
+#undef RC4_CHUNK\r
+#endif\r
+#endif\r
+\r
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)\r
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a\r
+ * %20 speed up (longs are 8 bytes, int's are 4). */\r
+#ifndef DES_LONG\r
+#define DES_LONG unsigned long\r
+#endif\r
+#endif\r
+\r
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) && !defined(OPENSSL_SYSNAME_UEFI)\r
+#define CONFIG_HEADER_BN_H\r
+#undef BN_LLONG\r
+\r
+/* Should we define BN_DIV2W here? */\r
+\r
+/* Only one for the following should be defined */\r
+#undef SIXTY_FOUR_BIT_LONG\r
+#undef SIXTY_FOUR_BIT\r
+#define THIRTY_TWO_BIT\r
+#endif\r
+\r
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)\r
+#define CONFIG_HEADER_RC4_LOCL_H\r
+/* if this is defined data[i] is used instead of *data, this is a %20\r
+ * speedup on x86 */\r
+#undef RC4_INDEX\r
+#endif\r
+\r
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)\r
+#define CONFIG_HEADER_BF_LOCL_H\r
+#undef BF_PTR\r
+#endif /* HEADER_BF_LOCL_H */\r
+\r
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)\r
+#define CONFIG_HEADER_DES_LOCL_H\r
+#ifndef DES_DEFAULT_OPTIONS\r
+/* the following is tweaked from a config script, that is why it is a\r
+ * protected undef/define */\r
+#ifndef DES_PTR\r
+#undef DES_PTR\r
+#endif\r
+\r
+/* This helps C compiler generate the correct code for multiple functional\r
+ * units.  It reduces register dependancies at the expense of 2 more\r
+ * registers */\r
+#ifndef DES_RISC1\r
+#undef DES_RISC1\r
+#endif\r
+\r
+#ifndef DES_RISC2\r
+#undef DES_RISC2\r
+#endif\r
+\r
+#if defined(DES_RISC1) && defined(DES_RISC2)\r
+#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!\r
+#endif\r
+\r
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.\r
+ * Very mucy CPU dependant */\r
+#ifndef DES_UNROLL\r
+#undef DES_UNROLL\r
+#endif\r
+\r
+/* These default values were supplied by\r
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>\r
+ * They are only used if nothing else has been defined */\r
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)\r
+/* Special defines which change the way the code is built depending on the\r
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find\r
+   even newer MIPS CPU's, but at the moment one size fits all for\r
+   optimization options.  Older Sparc's work better with only UNROLL, but\r
+   there's no way to tell at compile time what it is you're running on */\r
\r
+#if defined( __sun ) || defined ( sun )                /* Newer Sparc's */\r
+#  define DES_PTR\r
+#  define DES_RISC1\r
+#  define DES_UNROLL\r
+#elif defined( __ultrix )      /* Older MIPS */\r
+#  define DES_PTR\r
+#  define DES_RISC2\r
+#  define DES_UNROLL\r
+#elif defined( __osf1__ )      /* Alpha */\r
+#  define DES_PTR\r
+#  define DES_RISC2\r
+#elif defined ( _AIX )         /* RS6000 */\r
+  /* Unknown */\r
+#elif defined( __hpux )                /* HP-PA */\r
+  /* Unknown */\r
+#elif defined( __aux )         /* 68K */\r
+  /* Unknown */\r
+#elif defined( __dgux )                /* 88K (but P6 in latest boxes) */\r
+#  define DES_UNROLL\r
+#elif defined( __sgi )         /* Newer MIPS */\r
+#  define DES_PTR\r
+#  define DES_RISC2\r
+#  define DES_UNROLL\r
+#elif defined(i386) || defined(__i386__)       /* x86 boxes, should be gcc */\r
+#  define DES_PTR\r
+#  define DES_RISC1\r
+#  define DES_UNROLL\r
+#endif /* Systems-specific speed defines */\r
+#endif\r
+\r
+#endif /* DES_DEFAULT_OPTIONS */\r
+#endif /* HEADER_DES_LOCL_H */\r
+#ifdef  __cplusplus\r
+}\r
+#endif\r
diff --git a/Cryptlib/Include/openssl/opensslv.h b/Cryptlib/Include/openssl/opensslv.h
new file mode 100644 (file)
index 0000000..13fe440
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef HEADER_OPENSSLV_H
+# define HEADER_OPENSSLV_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev      0x00903000
+ * 0.9.3-beta1    0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3          0x0090300f
+ * 0.9.3a         0x0090301f
+ * 0.9.4          0x0090400f
+ * 1.2.3z         0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+# define OPENSSL_VERSION_NUMBER  0x1000208fL
+# ifdef OPENSSL_FIPS
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2h-fips  3 May 2016"
+# else
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2h  3 May 2016"
+# endif
+# define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
+
+/*-
+ * The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *      libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ *      libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons.  The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time.  When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *      3.0
+ *      3.0:3.1
+ *      3.0:3.1:3.2
+ *      4.0
+ *      4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+# define SHLIB_VERSION_HISTORY ""
+# define SHLIB_VERSION_NUMBER "1.0.0"
+
+
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* HEADER_OPENSSLV_H */
diff --git a/Cryptlib/Include/openssl/ossl_typ.h b/Cryptlib/Include/openssl/ossl_typ.h
new file mode 100644 (file)
index 0000000..9144ea2
--- /dev/null
@@ -0,0 +1,211 @@
+/* ====================================================================
+ * 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).
+ *
+ */
+
+#ifndef HEADER_OPENSSL_TYPES_H
+# define HEADER_OPENSSL_TYPES_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/e_os2.h>
+
+# ifdef NO_ASN1_TYPEDEFS
+#  define ASN1_INTEGER            ASN1_STRING
+#  define ASN1_ENUMERATED         ASN1_STRING
+#  define ASN1_BIT_STRING         ASN1_STRING
+#  define ASN1_OCTET_STRING       ASN1_STRING
+#  define ASN1_PRINTABLESTRING    ASN1_STRING
+#  define ASN1_T61STRING          ASN1_STRING
+#  define ASN1_IA5STRING          ASN1_STRING
+#  define ASN1_UTCTIME            ASN1_STRING
+#  define ASN1_GENERALIZEDTIME    ASN1_STRING
+#  define ASN1_TIME               ASN1_STRING
+#  define ASN1_GENERALSTRING      ASN1_STRING
+#  define ASN1_UNIVERSALSTRING    ASN1_STRING
+#  define ASN1_BMPSTRING          ASN1_STRING
+#  define ASN1_VISIBLESTRING      ASN1_STRING
+#  define ASN1_UTF8STRING         ASN1_STRING
+#  define ASN1_BOOLEAN            int
+#  define ASN1_NULL               int
+# else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+# endif
+
+typedef struct asn1_object_st ASN1_OBJECT;
+
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct asn1_pctx_st ASN1_PCTX;
+
+# ifdef OPENSSL_SYS_WIN32
+#  undef X509_NAME
+#  undef X509_EXTENSIONS
+#  undef X509_CERT_PAIR
+#  undef PKCS7_ISSUER_AND_SERIAL
+#  undef OCSP_REQUEST
+#  undef OCSP_RESPONSE
+# endif
+
+# ifdef BIGNUM
+#  undef BIGNUM
+# endif
+typedef struct bignum_st BIGNUM;
+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;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ecdh_method ECDH_METHOD;
+typedef struct ecdsa_method ECDSA_METHOD;
+
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+
+typedef struct store_st STORE;
+typedef struct store_method_st STORE_METHOD;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct st_ERR_FNS ERR_FNS;
+
+typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
+  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
+# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */
+# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Callback types for crypto.h */
+typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                           int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                             int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+                           void *from_d, int idx, long argl, void *argp);
+
+typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
+typedef struct ocsp_response_st OCSP_RESPONSE;
+typedef struct ocsp_responder_id_st OCSP_RESPID;
+
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* def HEADER_OPENSSL_TYPES_H */
diff --git a/Cryptlib/Include/openssl/pem.h b/Cryptlib/Include/openssl/pem.h
new file mode 100644 (file)
index 0000000..5df6ffd
--- /dev/null
@@ -0,0 +1,620 @@
+/* crypto/pem/pem.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_PEM_H
+# define HEADER_PEM_H
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# ifndef OPENSSL_NO_STACK
+#  include <openssl/stack.h>
+# endif
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define PEM_BUFSIZE             1024
+
+# define PEM_OBJ_UNDEF           0
+# define PEM_OBJ_X509            1
+# define PEM_OBJ_X509_REQ        2
+# define PEM_OBJ_CRL             3
+# define PEM_OBJ_SSL_SESSION     4
+# define PEM_OBJ_PRIV_KEY        10
+# define PEM_OBJ_PRIV_RSA        11
+# define PEM_OBJ_PRIV_DSA        12
+# define PEM_OBJ_PRIV_DH         13
+# define PEM_OBJ_PUB_RSA         14
+# define PEM_OBJ_PUB_DSA         15
+# define PEM_OBJ_PUB_DH          16
+# define PEM_OBJ_DHPARAMS        17
+# define PEM_OBJ_DSAPARAMS       18
+# define PEM_OBJ_PRIV_RSA_PUBLIC 19
+# define PEM_OBJ_PRIV_ECDSA      20
+# define PEM_OBJ_PUB_ECDSA       21
+# define PEM_OBJ_ECPARAMETERS    22
+
+# define PEM_ERROR               30
+# define PEM_DEK_DES_CBC         40
+# define PEM_DEK_IDEA_CBC        45
+# define PEM_DEK_DES_EDE         50
+# define PEM_DEK_DES_ECB         60
+# define PEM_DEK_RSA             70
+# define PEM_DEK_RSA_MD2         80
+# define PEM_DEK_RSA_MD5         90
+
+# define PEM_MD_MD2              NID_md2
+# define PEM_MD_MD5              NID_md5
+# define PEM_MD_SHA              NID_sha
+# define PEM_MD_MD2_RSA          NID_md2WithRSAEncryption
+# define PEM_MD_MD5_RSA          NID_md5WithRSAEncryption
+# define PEM_MD_SHA_RSA          NID_sha1WithRSAEncryption
+
+# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
+# define PEM_STRING_X509         "CERTIFICATE"
+# define PEM_STRING_X509_PAIR    "CERTIFICATE PAIR"
+# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
+# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
+# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
+# define PEM_STRING_X509_CRL     "X509 CRL"
+# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
+# define PEM_STRING_PUBLIC       "PUBLIC KEY"
+# define PEM_STRING_RSA          "RSA PRIVATE KEY"
+# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
+# define PEM_STRING_DSA          "DSA PRIVATE KEY"
+# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
+# define PEM_STRING_PKCS7        "PKCS7"
+# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
+# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
+# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
+# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
+# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
+# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
+# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
+# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
+# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
+# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
+# define PEM_STRING_PARAMETERS   "PARAMETERS"
+# define PEM_STRING_CMS          "CMS"
+
+  /*
+   * Note that this structure is initialised by PEM_SealInit and cleaned up
+   * by PEM_SealFinal (at least for now)
+   */
+typedef struct PEM_Encode_Seal_st {
+    EVP_ENCODE_CTX encode;
+    EVP_MD_CTX md;
+    EVP_CIPHER_CTX cipher;
+} PEM_ENCODE_SEAL_CTX;
+
+/* enc_type is one off */
+# define PEM_TYPE_ENCRYPTED      10
+# define PEM_TYPE_MIC_ONLY       20
+# define PEM_TYPE_MIC_CLEAR      30
+# define PEM_TYPE_CLEAR          40
+
+typedef struct pem_recip_st {
+    char *name;
+    X509_NAME *dn;
+    int cipher;
+    int key_enc;
+    /*      char iv[8]; unused and wrong size */
+} PEM_USER;
+
+typedef struct pem_ctx_st {
+    int type;                   /* what type of object */
+    struct {
+        int version;
+        int mode;
+    } proc_type;
+
+    char *domain;
+
+    struct {
+        int cipher;
+        /*-
+        unused, and wrong size
+        unsigned char iv[8]; */
+    } DEK_info;
+
+    PEM_USER *originator;
+
+    int num_recipient;
+    PEM_USER **recipient;
+/*-
+    XXX(ben): don#t think this is used!
+        STACK *x509_chain;      / * certificate chain */
+    EVP_MD *md;                 /* signature type */
+
+    int md_enc;                 /* is the md encrypted or not? */
+    int md_len;                 /* length of md_data */
+    char *md_data;              /* message digest, could be pkey encrypted */
+
+    EVP_CIPHER *dec;            /* date encryption cipher */
+    int key_len;                /* key length */
+    unsigned char *key;         /* key */
+  /*-
+    unused, and wrong size
+    unsigned char iv[8]; */
+
+    int data_enc;               /* is the data encrypted */
+    int data_len;
+    unsigned char *data;
+} PEM_CTX;
+
+/*
+ * These macros make the PEM_read/PEM_write functions easier to maintain and
+ * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or
+ * IMPLEMENT_PEM_rw_cb(...)
+ */
+
+# ifdef OPENSSL_NO_FP_API
+
+#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
+# else
+
+#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
+type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
+}
+
+#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, const type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, \
+                  void *u) \
+        { \
+        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+        }
+
+#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, \
+                  void *u) \
+        { \
+        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+        }
+
+# endif
+
+# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
+}
+
+# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, const type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+        { \
+        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
+        }
+
+# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+        { \
+        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
+        }
+
+# define IMPLEMENT_PEM_write(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_fp_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_read_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb(name, type, str, asn1)
+
+/* These are the same except they are for the declarations */
+
+# if defined(OPENSSL_NO_FP_API)
+
+#  define DECLARE_PEM_read_fp(name, type) /**/
+#  define DECLARE_PEM_write_fp(name, type) /**/
+#  define DECLARE_PEM_write_fp_const(name, type) /**/
+#  define DECLARE_PEM_write_cb_fp(name, type) /**/
+# else
+
+#  define DECLARE_PEM_read_fp(name, type) \
+        type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+
+#  define DECLARE_PEM_write_fp(name, type) \
+        int PEM_write_##name(FILE *fp, type *x);
+
+#  define DECLARE_PEM_write_fp_const(name, type) \
+        int PEM_write_##name(FILE *fp, const type *x);
+
+#  define DECLARE_PEM_write_cb_fp(name, type) \
+        int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+# endif
+
+# ifndef OPENSSL_NO_BIO
+#  define DECLARE_PEM_read_bio(name, type) \
+        type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+
+#  define DECLARE_PEM_write_bio(name, type) \
+        int PEM_write_bio_##name(BIO *bp, type *x);
+
+#  define DECLARE_PEM_write_bio_const(name, type) \
+        int PEM_write_bio_##name(BIO *bp, const type *x);
+
+#  define DECLARE_PEM_write_cb_bio(name, type) \
+        int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+# else
+
+#  define DECLARE_PEM_read_bio(name, type) /**/
+#  define DECLARE_PEM_write_bio(name, type) /**/
+#  define DECLARE_PEM_write_bio_const(name, type) /**/
+#  define DECLARE_PEM_write_cb_bio(name, type) /**/
+# endif
+# define DECLARE_PEM_write(name, type) \
+        DECLARE_PEM_write_bio(name, type) \
+        DECLARE_PEM_write_fp(name, type)
+# define DECLARE_PEM_write_const(name, type) \
+        DECLARE_PEM_write_bio_const(name, type) \
+        DECLARE_PEM_write_fp_const(name, type)
+# define DECLARE_PEM_write_cb(name, type) \
+        DECLARE_PEM_write_cb_bio(name, type) \
+        DECLARE_PEM_write_cb_fp(name, type)
+# define DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_read_bio(name, type) \
+        DECLARE_PEM_read_fp(name, type)
+# define DECLARE_PEM_rw(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write(name, type)
+# define DECLARE_PEM_rw_const(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write_const(name, type)
+# define DECLARE_PEM_rw_cb(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write_cb(name, type)
+# if 1
+/* "userdata": new with OpenSSL 0.9.4 */
+typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
+# else
+/* OpenSSL 0.9.3, 0.9.3a */
+typedef int pem_password_cb (char *buf, int size, int rwflag);
+# endif
+
+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len,
+                  pem_password_cb *callback, void *u);
+
+# ifndef OPENSSL_NO_BIO
+int PEM_read_bio(BIO *bp, char **name, char **header,
+                 unsigned char **data, long *len);
+int PEM_write_bio(BIO *bp, const char *name, const char *hdr,
+                  const unsigned char *data, long len);
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+                       const char *name, BIO *bp, pem_password_cb *cb,
+                       void *u);
+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+                        pem_password_cb *cb, void *u);
+int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
+                       const EVP_CIPHER *enc, unsigned char *kstr, int klen,
+                       pem_password_cb *cb, void *u);
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+                                            pem_password_cb *cb, void *u);
+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+                            unsigned char *kstr, int klen,
+                            pem_password_cb *cd, void *u);
+# endif
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_read(FILE *fp, char **name, char **header,
+             unsigned char **data, long *len);
+int PEM_write(FILE *fp, const char *name, const char *hdr,
+              const unsigned char *data, long len);
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+                    pem_password_cb *cb, void *u);
+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
+                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                   int klen, pem_password_cb *callback, void *u);
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+                                        pem_password_cb *cb, void *u);
+#endif
+
+int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
+                 EVP_MD *md_type, unsigned char **ek, int *ekl,
+                 unsigned char *iv, EVP_PKEY **pubk, int npubk);
+void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+                    unsigned char *in, int inl);
+int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
+                  unsigned char *out, int *outl, EVP_PKEY *priv);
+
+void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt);
+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                  unsigned int *siglen, EVP_PKEY *pkey);
+
+int PEM_def_callback(char *buf, int num, int w, void *key);
+void PEM_proc_type(char *buf, int type);
+void PEM_dek_info(char *buf, const char *type, int len, char *str);
+
+# include <openssl/symhacks.h>
+
+DECLARE_PEM_rw(X509, X509)
+DECLARE_PEM_rw(X509_AUX, X509)
+DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
+DECLARE_PEM_rw(X509_REQ, X509_REQ)
+DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
+DECLARE_PEM_rw(X509_CRL, X509_CRL)
+DECLARE_PEM_rw(PKCS7, PKCS7)
+DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+DECLARE_PEM_rw(PKCS8, X509_SIG)
+DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+# ifndef OPENSSL_NO_RSA
+DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
+DECLARE_PEM_rw_const(RSAPublicKey, RSA)
+DECLARE_PEM_rw(RSA_PUBKEY, RSA)
+# endif
+# ifndef OPENSSL_NO_DSA
+DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+DECLARE_PEM_rw(DSA_PUBKEY, DSA)
+DECLARE_PEM_rw_const(DSAparams, DSA)
+# endif
+# ifndef OPENSSL_NO_EC
+DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
+DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
+DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
+# endif
+# ifndef OPENSSL_NO_DH
+DECLARE_PEM_rw_const(DHparams, DH)
+DECLARE_PEM_write_const(DHxparams, DH)
+# endif
+DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
+DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+                                      char *kstr, int klen,
+                                      pem_password_cb *cb, void *u);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+                                  char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                            char *kstr, int klen,
+                            pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+                                char *kstr, int klen,
+                                pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u);
+
+#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);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+                               char *kstr, int klen,
+                               pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                                 void *u);
+
+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                              char *kstr, int klen, pem_password_cb *cd,
+                              void *u);
+#endif
+
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+# ifndef OPENSSL_NO_RC4
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+                pem_password_cb *cb, void *u);
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * 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_PEM_strings(void);
+
+/* Error codes for the PEM functions. */
+
+/* Function codes. */
+# define PEM_F_B2I_DSS                                    127
+# define PEM_F_B2I_PVK_BIO                                128
+# define PEM_F_B2I_RSA                                    129
+# define PEM_F_CHECK_BITLEN_DSA                           130
+# define PEM_F_CHECK_BITLEN_RSA                           131
+# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO                    120
+# define PEM_F_D2I_PKCS8PRIVATEKEY_FP                     121
+# define PEM_F_DO_B2I                                     132
+# define PEM_F_DO_B2I_BIO                                 133
+# define PEM_F_DO_BLOB_HEADER                             134
+# define PEM_F_DO_PK8PKEY                                 126
+# define PEM_F_DO_PK8PKEY_FP                              125
+# define PEM_F_DO_PVK_BODY                                135
+# define PEM_F_DO_PVK_HEADER                              136
+# define PEM_F_I2B_PVK                                    137
+# define PEM_F_I2B_PVK_BIO                                138
+# define PEM_F_LOAD_IV                                    101
+# define PEM_F_PEM_ASN1_READ                              102
+# define PEM_F_PEM_ASN1_READ_BIO                          103
+# define PEM_F_PEM_ASN1_WRITE                             104
+# define PEM_F_PEM_ASN1_WRITE_BIO                         105
+# define PEM_F_PEM_DEF_CALLBACK                           100
+# define PEM_F_PEM_DO_HEADER                              106
+# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY            118
+# define PEM_F_PEM_GET_EVP_CIPHER_INFO                    107
+# define PEM_F_PEM_PK8PKEY                                119
+# define PEM_F_PEM_READ                                   108
+# define PEM_F_PEM_READ_BIO                               109
+# define PEM_F_PEM_READ_BIO_DHPARAMS                      141
+# define PEM_F_PEM_READ_BIO_PARAMETERS                    140
+# define PEM_F_PEM_READ_BIO_PRIVATEKEY                    123
+# define PEM_F_PEM_READ_DHPARAMS                          142
+# define PEM_F_PEM_READ_PRIVATEKEY                        124
+# define PEM_F_PEM_SEALFINAL                              110
+# define PEM_F_PEM_SEALINIT                               111
+# define PEM_F_PEM_SIGNFINAL                              112
+# define PEM_F_PEM_WRITE                                  113
+# define PEM_F_PEM_WRITE_BIO                              114
+# define PEM_F_PEM_WRITE_PRIVATEKEY                       139
+# define PEM_F_PEM_X509_INFO_READ                         115
+# define PEM_F_PEM_X509_INFO_READ_BIO                     116
+# define PEM_F_PEM_X509_INFO_WRITE_BIO                    117
+
+/* Reason codes. */
+# define PEM_R_BAD_BASE64_DECODE                          100
+# define PEM_R_BAD_DECRYPT                                101
+# define PEM_R_BAD_END_LINE                               102
+# define PEM_R_BAD_IV_CHARS                               103
+# define PEM_R_BAD_MAGIC_NUMBER                           116
+# define PEM_R_BAD_PASSWORD_READ                          104
+# define PEM_R_BAD_VERSION_NUMBER                         117
+# define PEM_R_BIO_WRITE_FAILURE                          118
+# define PEM_R_CIPHER_IS_NULL                             127
+# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY               115
+# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB                 119
+# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB                  120
+# define PEM_R_INCONSISTENT_HEADER                        121
+# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR                 122
+# define PEM_R_KEYBLOB_TOO_SHORT                          123
+# define PEM_R_NOT_DEK_INFO                               105
+# define PEM_R_NOT_ENCRYPTED                              106
+# define PEM_R_NOT_PROC_TYPE                              107
+# define PEM_R_NO_START_LINE                              108
+# define PEM_R_PROBLEMS_GETTING_PASSWORD                  109
+# define PEM_R_PUBLIC_KEY_NO_RSA                          110
+# define PEM_R_PVK_DATA_TOO_SHORT                         124
+# define PEM_R_PVK_TOO_SHORT                              125
+# define PEM_R_READ_KEY                                   111
+# define PEM_R_SHORT_HEADER                               112
+# define PEM_R_UNSUPPORTED_CIPHER                         113
+# define PEM_R_UNSUPPORTED_ENCRYPTION                     114
+# define PEM_R_UNSUPPORTED_KEY_COMPONENTS                 126
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/pem2.h b/Cryptlib/Include/openssl/pem2.h
new file mode 100644 (file)
index 0000000..84897d5
--- /dev/null
@@ -0,0 +1,70 @@
+/* ====================================================================
+ * 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 header only exists to break a circular dependency between pem and err
+ * Ben 30 Jan 1999.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HEADER_PEM_H
+void ERR_load_PEM_strings(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Cryptlib/Include/openssl/pkcs12.h b/Cryptlib/Include/openssl/pkcs12.h
new file mode 100644 (file)
index 0000000..a39adf5
--- /dev/null
@@ -0,0 +1,342 @@
+/* pkcs12.h */
+/*
+ * 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 HEADER_PKCS12_H
+# define HEADER_PKCS12_H
+
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define PKCS12_KEY_ID   1
+# define PKCS12_IV_ID    2
+# define PKCS12_MAC_ID   3
+
+/* Default iteration count */
+# ifndef PKCS12_DEFAULT_ITER
+#  define PKCS12_DEFAULT_ITER     PKCS5_DEFAULT_ITER
+# endif
+
+# define PKCS12_MAC_KEY_LENGTH 20
+
+# define PKCS12_SALT_LEN 8
+
+/* Uncomment out next line for unicode password and names, otherwise ASCII */
+
+/*
+ * #define PBE_UNICODE
+ */
+
+# ifdef PBE_UNICODE
+#  define PKCS12_key_gen PKCS12_key_gen_uni
+#  define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
+# else
+#  define PKCS12_key_gen PKCS12_key_gen_asc
+#  define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
+# endif
+
+/* MS key usage constants */
+
+# define KEY_EX  0x10
+# define KEY_SIG 0x80
+
+typedef struct {
+    X509_SIG *dinfo;
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *iter;         /* defaults to 1 */
+} PKCS12_MAC_DATA;
+
+typedef struct {
+    ASN1_INTEGER *version;
+    PKCS12_MAC_DATA *mac;
+    PKCS7 *authsafes;
+} PKCS12;
+
+typedef struct {
+    ASN1_OBJECT *type;
+    union {
+        struct pkcs12_bag_st *bag; /* secret, crl and certbag */
+        struct pkcs8_priv_key_info_st *keybag; /* keybag */
+        X509_SIG *shkeybag;     /* shrouded key bag */
+        STACK_OF(PKCS12_SAFEBAG) *safes;
+        ASN1_TYPE *other;
+    } value;
+    STACK_OF(X509_ATTRIBUTE) *attrib;
+} PKCS12_SAFEBAG;
+
+DECLARE_STACK_OF(PKCS12_SAFEBAG)
+DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
+DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct pkcs12_bag_st {
+    ASN1_OBJECT *type;
+    union {
+        ASN1_OCTET_STRING *x509cert;
+        ASN1_OCTET_STRING *x509crl;
+        ASN1_OCTET_STRING *octet;
+        ASN1_IA5STRING *sdsicert;
+        ASN1_TYPE *other;       /* Secret or other bag */
+    } value;
+} PKCS12_BAGS;
+
+# define PKCS12_ERROR    0
+# define PKCS12_OK       1
+
+/* Compatibility macros */
+
+# define M_PKCS12_x5092certbag PKCS12_x5092certbag
+# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
+
+# define M_PKCS12_certbag2x509 PKCS12_certbag2x509
+# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl
+
+# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
+# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
+# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
+# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
+
+# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
+# define M_PKCS8_decrypt PKCS8_decrypt
+
+# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
+# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
+# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
+
+# define PKCS12_get_attr(bag, attr_nid) \
+                         PKCS12_get_attr_gen(bag->attrib, attr_nid)
+
+# define PKCS8_get_attr(p8, attr_nid) \
+                PKCS12_get_attr_gen(p8->attributes, attr_nid)
+
+# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
+                                         int nid1, int nid2);
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass,
+                                   int passlen);
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
+                                         const char *pass, int passlen);
+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 *p8);
+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);
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+                             unsigned char *salt, int saltlen, int iter,
+                             STACK_OF(PKCS12_SAFEBAG) *bags);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
+                                                  int passlen);
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
+                          int namelen);
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+                                int namelen);
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+                           int namelen);
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
+                                const unsigned char *name, int namelen);
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
+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);
+void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+                              const char *pass, int passlen,
+                              ASN1_OCTET_STRING *oct, int zbuf);
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
+                                           const ASN1_ITEM *it,
+                                           const char *pass, int passlen,
+                                           void *obj, int zbuf);
+PKCS12 *PKCS12_init(int mode);
+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 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);
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                        const EVP_MD *md_type, int en_de);
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *mac, unsigned int *maclen);
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *salt, int saltlen, int iter,
+                   const EVP_MD *md_type);
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
+                     int saltlen, const EVP_MD *md_type);
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
+                               unsigned char **uni, int *unilen);
+char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
+
+DECLARE_ASN1_FUNCTIONS(PKCS12)
+DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
+DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
+
+void PKCS12_PBE_add(void);
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+                 STACK_OF(X509) **ca);
+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_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
+                               EVP_PKEY *key, int key_usage, int iter,
+                               int key_nid, char *pass);
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+                    int safe_nid, int iter, char *pass);
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+
+/* 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_PKCS12_strings(void);
+
+/* Error codes for the PKCS12 functions. */
+
+/* Function codes. */
+# define PKCS12_F_PARSE_BAG                               129
+# define PKCS12_F_PARSE_BAGS                              103
+# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME                 100
+# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC             127
+# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI             102
+# define PKCS12_F_PKCS12_ADD_LOCALKEYID                   104
+# define PKCS12_F_PKCS12_CREATE                           105
+# define PKCS12_F_PKCS12_GEN_MAC                          107
+# define PKCS12_F_PKCS12_INIT                             109
+# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I                 106
+# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT                 108
+# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG                117
+# define PKCS12_F_PKCS12_KEY_GEN_ASC                      110
+# define PKCS12_F_PKCS12_KEY_GEN_UNI                      111
+# define PKCS12_F_PKCS12_MAKE_KEYBAG                      112
+# define PKCS12_F_PKCS12_MAKE_SHKEYBAG                    113
+# define PKCS12_F_PKCS12_NEWPASS                          128
+# define PKCS12_F_PKCS12_PACK_P7DATA                      114
+# define PKCS12_F_PKCS12_PACK_P7ENCDATA                   115
+# define PKCS12_F_PKCS12_PARSE                            118
+# define PKCS12_F_PKCS12_PBE_CRYPT                        119
+# define PKCS12_F_PKCS12_PBE_KEYIVGEN                     120
+# define PKCS12_F_PKCS12_SETUP_MAC                        122
+# define PKCS12_F_PKCS12_SET_MAC                          123
+# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES                 130
+# define PKCS12_F_PKCS12_UNPACK_P7DATA                    131
+# define PKCS12_F_PKCS12_VERIFY_MAC                       126
+# define PKCS12_F_PKCS8_ADD_KEYUSAGE                      124
+# define PKCS12_F_PKCS8_ENCRYPT                           125
+
+/* Reason codes. */
+# define PKCS12_R_CANT_PACK_STRUCTURE                     100
+# define PKCS12_R_CONTENT_TYPE_NOT_DATA                   121
+# define PKCS12_R_DECODE_ERROR                            101
+# define PKCS12_R_ENCODE_ERROR                            102
+# define PKCS12_R_ENCRYPT_ERROR                           103
+# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE       120
+# define PKCS12_R_INVALID_NULL_ARGUMENT                   104
+# define PKCS12_R_INVALID_NULL_PKCS12_POINTER             105
+# define PKCS12_R_IV_GEN_ERROR                            106
+# define PKCS12_R_KEY_GEN_ERROR                           107
+# define PKCS12_R_MAC_ABSENT                              108
+# define PKCS12_R_MAC_GENERATION_ERROR                    109
+# define PKCS12_R_MAC_SETUP_ERROR                         110
+# define PKCS12_R_MAC_STRING_SET_ERROR                    111
+# define PKCS12_R_MAC_VERIFY_ERROR                        112
+# define PKCS12_R_MAC_VERIFY_FAILURE                      113
+# define PKCS12_R_PARSE_ERROR                             114
+# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR           115
+# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR                116
+# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR                  117
+# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM                118
+# define PKCS12_R_UNSUPPORTED_PKCS12_MODE                 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/pkcs7.h b/Cryptlib/Include/openssl/pkcs7.h
new file mode 100644 (file)
index 0000000..b51b386
--- /dev/null
@@ -0,0 +1,481 @@
+/* crypto/pkcs7/pkcs7.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_PKCS7_H
+# define HEADER_PKCS7_H
+
+# include <openssl/asn1.h>
+# include <openssl/bio.h>
+# include <openssl/e_os2.h>
+
+# include <openssl/symhacks.h>
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+#  undef PKCS7_ISSUER_AND_SERIAL
+#  undef PKCS7_SIGNER_INFO
+# endif
+
+/*-
+Encryption_ID           DES-CBC
+Digest_ID               MD5
+Digest_Encryption_ID    rsaEncryption
+Key_Encryption_ID       rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st {
+    X509_NAME *issuer;
+    ASN1_INTEGER *serial;
+} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+    X509_ALGOR *digest_alg;
+    STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
+    X509_ALGOR *digest_enc_alg;
+    ASN1_OCTET_STRING *enc_digest;
+    STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
+    /* The private key to sign with */
+    EVP_PKEY *pkey;
+} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+    X509_ALGOR *key_enc_algor;
+    ASN1_OCTET_STRING *enc_key;
+    X509 *cert;                 /* get the pub-key from this */
+} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    STACK_OF(X509_ALGOR) *md_algs; /* md used */
+    STACK_OF(X509) *cert;       /* [ 0 ] */
+    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
+    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+    struct pkcs7_st *contents;
+} PKCS7_SIGNED;
+/*
+ * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about
+ * merging the two
+ */
+
+typedef struct pkcs7_enc_content_st {
+    ASN1_OBJECT *content_type;
+    X509_ALGOR *algorithm;
+    ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
+    const EVP_CIPHER *cipher;
+} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+    PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    STACK_OF(X509_ALGOR) *md_algs; /* md used */
+    STACK_OF(X509) *cert;       /* [ 0 ] */
+    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
+    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+    PKCS7_ENC_CONTENT *enc_data;
+    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    X509_ALGOR *md;             /* md used */
+    struct pkcs7_st *contents;
+    ASN1_OCTET_STRING *digest;
+} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st {
+    /*
+     * The following is non NULL if it contains ASN1 encoding of this
+     * structure
+     */
+    unsigned char *asn1;
+    long length;
+# define PKCS7_S_HEADER  0
+# define PKCS7_S_BODY    1
+# define PKCS7_S_TAIL    2
+    int state;                  /* used during processing */
+    int detached;
+    ASN1_OBJECT *type;
+    /* content as defined by the type */
+    /*
+     * all encryption/message digests are applied to the 'contents', leaving
+     * out the 'type' field.
+     */
+    union {
+        char *ptr;
+        /* NID_pkcs7_data */
+        ASN1_OCTET_STRING *data;
+        /* NID_pkcs7_signed */
+        PKCS7_SIGNED *sign;
+        /* NID_pkcs7_enveloped */
+        PKCS7_ENVELOPE *enveloped;
+        /* NID_pkcs7_signedAndEnveloped */
+        PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+        /* NID_pkcs7_digest */
+        PKCS7_DIGEST *digest;
+        /* NID_pkcs7_encrypted */
+        PKCS7_ENCRYPT *encrypted;
+        /* Anything else */
+        ASN1_TYPE *other;
+    } d;
+} PKCS7;
+
+DECLARE_STACK_OF(PKCS7)
+DECLARE_ASN1_SET_OF(PKCS7)
+DECLARE_PKCS12_STACK_OF(PKCS7)
+
+# define PKCS7_OP_SET_DETACHED_SIGNATURE 1
+# define PKCS7_OP_GET_DETACHED_SIGNATURE 2
+
+# define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
+# define PKCS7_get_attributes(si)        ((si)->unauth_attr)
+
+# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+# define PKCS7_type_is_signedAndEnveloped(a) \
+                (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+# define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+# define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+# define PKCS7_set_detached(p,v) \
+                PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+# define PKCS7_get_detached(p) \
+                PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+/* S/MIME related flags */
+
+# define PKCS7_TEXT              0x1
+# define PKCS7_NOCERTS           0x2
+# define PKCS7_NOSIGS            0x4
+# define PKCS7_NOCHAIN           0x8
+# define PKCS7_NOINTERN          0x10
+# define PKCS7_NOVERIFY          0x20
+# define PKCS7_DETACHED          0x40
+# define PKCS7_BINARY            0x80
+# define PKCS7_NOATTR            0x100
+# define PKCS7_NOSMIMECAP        0x200
+# define PKCS7_NOOLDMIMETYPE     0x400
+# define PKCS7_CRLFEOL           0x800
+# define PKCS7_STREAM            0x1000
+# define PKCS7_NOCRL             0x2000
+# define PKCS7_PARTIAL           0x4000
+# define PKCS7_REUSE_DIGEST      0x8000
+
+/* Flags: for compatibility with older code */
+
+# define SMIME_TEXT      PKCS7_TEXT
+# define SMIME_NOCERTS   PKCS7_NOCERTS
+# define SMIME_NOSIGS    PKCS7_NOSIGS
+# define SMIME_NOCHAIN   PKCS7_NOCHAIN
+# define SMIME_NOINTERN  PKCS7_NOINTERN
+# define SMIME_NOVERIFY  PKCS7_NOVERIFY
+# define SMIME_DETACHED  PKCS7_DETACHED
+# define SMIME_BINARY    PKCS7_BINARY
+# define SMIME_NOATTR    PKCS7_NOATTR
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
+                                   const EVP_MD *type, unsigned char *md,
+                                   unsigned int *len);
+# ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
+# endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+                          const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+                     BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+                          X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+                                       EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+                                 X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
+                               void *data);
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+                        void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+                                STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
+                         STACK_OF(X509_ATTRIBUTE) *sk);
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+                  BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+                                         X509 *signcert, EVP_PKEY *pkey,
+                                         const EVP_MD *md, int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+                 BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
+                                   int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+                     int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data,
+                  int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+                              STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+                             const unsigned char *md, int mdlen);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
+/* 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_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+# define PKCS7_F_B64_READ_PKCS7                           120
+# define PKCS7_F_B64_WRITE_PKCS7                          121
+# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB                   136
+# define PKCS7_F_I2D_PKCS7_BIO_STREAM                     140
+# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME           135
+# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP                118
+# define PKCS7_F_PKCS7_ADD_CERTIFICATE                    100
+# define PKCS7_F_PKCS7_ADD_CRL                            101
+# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO                 102
+# define PKCS7_F_PKCS7_ADD_SIGNATURE                      131
+# define PKCS7_F_PKCS7_ADD_SIGNER                         103
+# define PKCS7_F_PKCS7_BIO_ADD_DIGEST                     125
+# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST               138
+# define PKCS7_F_PKCS7_CTRL                               104
+# define PKCS7_F_PKCS7_DATADECODE                         112
+# define PKCS7_F_PKCS7_DATAFINAL                          128
+# define PKCS7_F_PKCS7_DATAINIT                           105
+# define PKCS7_F_PKCS7_DATASIGN                           106
+# define PKCS7_F_PKCS7_DATAVERIFY                         107
+# define PKCS7_F_PKCS7_DECRYPT                            114
+# define PKCS7_F_PKCS7_DECRYPT_RINFO                      133
+# define PKCS7_F_PKCS7_ENCODE_RINFO                       132
+# define PKCS7_F_PKCS7_ENCRYPT                            115
+# define PKCS7_F_PKCS7_FINAL                              134
+# define PKCS7_F_PKCS7_FIND_DIGEST                        127
+# define PKCS7_F_PKCS7_GET0_SIGNERS                       124
+# define PKCS7_F_PKCS7_RECIP_INFO_SET                     130
+# define PKCS7_F_PKCS7_SET_CIPHER                         108
+# define PKCS7_F_PKCS7_SET_CONTENT                        109
+# define PKCS7_F_PKCS7_SET_DIGEST                         126
+# define PKCS7_F_PKCS7_SET_TYPE                           110
+# define PKCS7_F_PKCS7_SIGN                               116
+# define PKCS7_F_PKCS7_SIGNATUREVERIFY                    113
+# define PKCS7_F_PKCS7_SIGNER_INFO_SET                    129
+# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN                   139
+# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER                    137
+# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP                    119
+# define PKCS7_F_PKCS7_VERIFY                             117
+# define PKCS7_F_SMIME_READ_PKCS7                         122
+# define PKCS7_F_SMIME_TEXT                               123
+
+/* Reason codes. */
+# define PKCS7_R_CERTIFICATE_VERIFY_ERROR                 117
+# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER          144
+# define PKCS7_R_CIPHER_NOT_INITIALIZED                   116
+# define PKCS7_R_CONTENT_AND_DATA_PRESENT                 118
+# define PKCS7_R_CTRL_ERROR                               152
+# define PKCS7_R_DECODE_ERROR                             130
+# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH            100
+# define PKCS7_R_DECRYPT_ERROR                            119
+# define PKCS7_R_DIGEST_FAILURE                           101
+# define PKCS7_R_ENCRYPTION_CTRL_FAILURE                  149
+# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
+# define PKCS7_R_ERROR_ADDING_RECIPIENT                   120
+# define PKCS7_R_ERROR_SETTING_CIPHER                     121
+# define PKCS7_R_INVALID_MIME_TYPE                        131
+# define PKCS7_R_INVALID_NULL_POINTER                     143
+# define PKCS7_R_INVALID_SIGNED_DATA_TYPE                 155
+# define PKCS7_R_MIME_NO_CONTENT_TYPE                     132
+# define PKCS7_R_MIME_PARSE_ERROR                         133
+# define PKCS7_R_MIME_SIG_PARSE_ERROR                     134
+# define PKCS7_R_MISSING_CERIPEND_INFO                    103
+# define PKCS7_R_NO_CONTENT                               122
+# define PKCS7_R_NO_CONTENT_TYPE                          135
+# define PKCS7_R_NO_DEFAULT_DIGEST                        151
+# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND            154
+# define PKCS7_R_NO_MULTIPART_BODY_FAILURE                136
+# define PKCS7_R_NO_MULTIPART_BOUNDARY                    137
+# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE         115
+# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY                 146
+# define PKCS7_R_NO_SIGNATURES_ON_DATA                    123
+# define PKCS7_R_NO_SIGNERS                               142
+# define PKCS7_R_NO_SIG_CONTENT_TYPE                      138
+# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE     104
+# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR                124
+# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR                   153
+# define PKCS7_R_PKCS7_DATAFINAL                          126
+# define PKCS7_R_PKCS7_DATAFINAL_ERROR                    125
+# define PKCS7_R_PKCS7_DATASIGN                           145
+# define PKCS7_R_PKCS7_PARSE_ERROR                        139
+# define PKCS7_R_PKCS7_SIG_PARSE_ERROR                    140
+# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE   127
+# define PKCS7_R_SIGNATURE_FAILURE                        105
+# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND             128
+# define PKCS7_R_SIGNING_CTRL_FAILURE                     147
+# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE  148
+# define PKCS7_R_SIG_INVALID_MIME_TYPE                    141
+# define PKCS7_R_SMIME_TEXT_ERROR                         129
+# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE               106
+# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO                   107
+# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST            108
+# define PKCS7_R_UNKNOWN_DIGEST_TYPE                      109
+# define PKCS7_R_UNKNOWN_OPERATION                        110
+# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE                  111
+# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE                 112
+# define PKCS7_R_WRONG_CONTENT_TYPE                       113
+# define PKCS7_R_WRONG_PKCS7_TYPE                         114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/pqueue.h b/Cryptlib/Include/openssl/pqueue.h
new file mode 100644 (file)
index 0000000..d40d9c7
--- /dev/null
@@ -0,0 +1,99 @@
+/* crypto/pqueue/pqueue.h */
+/*
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PQUEUE_H
+# define HEADER_PQUEUE_H
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+typedef struct _pqueue *pqueue;
+
+typedef struct _pitem {
+    unsigned char priority[8];  /* 64-bit value in big-endian encoding */
+    void *data;
+    struct _pitem *next;
+} pitem;
+
+typedef struct _pitem *piterator;
+
+pitem *pitem_new(unsigned char *prio64be, void *data);
+void pitem_free(pitem *item);
+
+pqueue pqueue_new(void);
+void pqueue_free(pqueue pq);
+
+pitem *pqueue_insert(pqueue pq, pitem *item);
+pitem *pqueue_peek(pqueue pq);
+pitem *pqueue_pop(pqueue pq);
+pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
+pitem *pqueue_iterator(pqueue pq);
+pitem *pqueue_next(piterator *iter);
+
+void pqueue_print(pqueue pq);
+int pqueue_size(pqueue pq);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* ! HEADER_PQUEUE_H */
diff --git a/Cryptlib/Include/openssl/rand.h b/Cryptlib/Include/openssl/rand.h
new file mode 100644 (file)
index 0000000..2553afd
--- /dev/null
@@ -0,0 +1,150 @@
+/* crypto/rand/rand.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_RAND_H
+# define HEADER_RAND_H
+
+# include <stdlib.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/e_os2.h>
+
+# if defined(OPENSSL_SYS_WINDOWS)
+#  include <windows.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if defined(OPENSSL_FIPS)
+#  define FIPS_RAND_SIZE_T size_t
+# endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st {
+    void (*seed) (const void *buf, int num);
+    int (*bytes) (unsigned char *buf, int num);
+    void (*cleanup) (void);
+    void (*add) (const void *buf, int num, double entropy);
+    int (*pseudorand) (unsigned char *buf, int num);
+    int (*status) (void);
+};
+
+# ifdef BN_DEBUG
+extern int rand_predictable;
+# endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+# ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+# endif
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void);
+int RAND_bytes(unsigned char *buf, int num);
+int RAND_pseudo_bytes(unsigned char *buf, int num);
+void RAND_seed(const void *buf, int num);
+void RAND_add(const void *buf, int num, double entropy);
+int RAND_load_file(const char *file, long max_bytes);
+int RAND_write_file(const char *file);
+const char *RAND_file_name(char *file, size_t num);
+int RAND_status(void);
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path, int bytes);
+int RAND_poll(void);
+
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+
+# endif
+
+# ifdef OPENSSL_FIPS
+void RAND_set_fips_drbg_type(int type, int flags);
+int RAND_init_fips(void);
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+# define RAND_F_RAND_GET_RAND_METHOD                      101
+# define RAND_F_RAND_INIT_FIPS                            102
+# define RAND_F_SSLEAY_RAND_BYTES                         100
+
+/* Reason codes. */
+# define RAND_R_DUAL_EC_DRBG_DISABLED                     104
+# define RAND_R_ERROR_INITIALISING_DRBG                   102
+# define RAND_R_ERROR_INSTANTIATING_DRBG                  103
+# define RAND_R_NO_FIPS_RANDOM_METHOD_SET                 101
+# define RAND_R_PRNG_NOT_SEEDED                           100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/rc2.h b/Cryptlib/Include/openssl/rc2.h
new file mode 100644 (file)
index 0000000..29d02d7
--- /dev/null
@@ -0,0 +1,103 @@
+/* crypto/rc2/rc2.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_RC2_H
+# define HEADER_RC2_H
+
+# include <openssl/opensslconf.h>/* OPENSSL_NO_RC2, RC2_INT */
+# ifdef OPENSSL_NO_RC2
+#  error RC2 is disabled.
+# endif
+
+# define RC2_ENCRYPT     1
+# define RC2_DECRYPT     0
+
+# define RC2_BLOCK       8
+# define RC2_KEY_LENGTH  16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc2_key_st {
+    RC2_INT data[64];
+} RC2_KEY;
+
+# ifdef OPENSSL_FIPS
+void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,
+                         int bits);
+# endif
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits);
+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     RC2_KEY *key, int enc);
+void RC2_encrypt(unsigned long *data, RC2_KEY *key);
+void RC2_decrypt(unsigned long *data, RC2_KEY *key);
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                     RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num, int enc);
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/rc4.h b/Cryptlib/Include/openssl/rc4.h
new file mode 100644 (file)
index 0000000..39162b1
--- /dev/null
@@ -0,0 +1,88 @@
+/* crypto/rc4/rc4.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_RC4_H
+# define HEADER_RC4_H
+
+# include <openssl/opensslconf.h>/* OPENSSL_NO_RC4, RC4_INT */
+# ifdef OPENSSL_NO_RC4
+#  error RC4 is disabled.
+# endif
+
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st {
+    RC4_INT x, y;
+    RC4_INT data[256];
+} RC4_KEY;
+
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+         unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/ripemd.h b/Cryptlib/Include/openssl/ripemd.h
new file mode 100644 (file)
index 0000000..b88ef25
--- /dev/null
@@ -0,0 +1,105 @@
+/* crypto/ripemd/ripemd.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_RIPEMD_H
+# define HEADER_RIPEMD_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_NO_RIPEMD
+#  error RIPEMD is disabled.
+# endif
+
+# if defined(__LP32__)
+#  define RIPEMD160_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#  define RIPEMD160_LONG unsigned long
+#  define RIPEMD160_LONG_LOG2 3
+# else
+#  define RIPEMD160_LONG unsigned int
+# endif
+
+# define RIPEMD160_CBLOCK        64
+# define RIPEMD160_LBLOCK        (RIPEMD160_CBLOCK/4)
+# define RIPEMD160_DIGEST_LENGTH 20
+
+typedef struct RIPEMD160state_st {
+    RIPEMD160_LONG A, B, C, D, E;
+    RIPEMD160_LONG Nl, Nh;
+    RIPEMD160_LONG data[RIPEMD160_LBLOCK];
+    unsigned int num;
+} RIPEMD160_CTX;
+
+# ifdef OPENSSL_FIPS
+int private_RIPEMD160_Init(RIPEMD160_CTX *c);
+# endif
+int RIPEMD160_Init(RIPEMD160_CTX *c);
+int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
+int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md);
+void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/rsa.h b/Cryptlib/Include/openssl/rsa.h
new file mode 100644 (file)
index 0000000..d2ee374
--- /dev/null
@@ -0,0 +1,664 @@
+/* crypto/rsa/rsa.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_RSA_H
+# define HEADER_RSA_H
+
+# include <openssl/asn1.h>
+
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/crypto.h>
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/bn.h>
+# endif
+
+# ifdef OPENSSL_NO_RSA
+#  error RSA is disabled.
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct rsa_st RSA; */
+/* typedef struct rsa_meth_st RSA_METHOD; */
+
+struct rsa_meth_st {
+    const char *name;
+    int (*rsa_pub_enc) (int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_pub_dec) (int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_priv_enc) (int flen, const unsigned char *from,
+                         unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_priv_dec) (int flen, const unsigned char *from,
+                         unsigned char *to, RSA *rsa, int padding);
+    /* Can be null */
+    int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+    /* Can be null */
+    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+    /* called at new */
+    int (*init) (RSA *rsa);
+    /* called at free */
+    int (*finish) (RSA *rsa);
+    /* RSA_METHOD_FLAG_* things */
+    int flags;
+    /* may be needed! */
+    char *app_data;
+    /*
+     * New sign and verify functions: some libraries don't allow arbitrary
+     * data to be signed/verified: this allows them to be used. Note: for
+     * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
+     * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note:
+     * for backwards compatibility this functionality is only enabled if the
+     * RSA_FLAG_SIGN_VER option is set in 'flags'.
+     */
+    int (*rsa_sign) (int type,
+                     const unsigned char *m, unsigned int m_length,
+                     unsigned char *sigret, unsigned int *siglen,
+                     const RSA *rsa);
+    int (*rsa_verify) (int dtype, const unsigned char *m,
+                       unsigned int m_length, const unsigned char *sigbuf,
+                       unsigned int siglen, const RSA *rsa);
+    /*
+     * If this callback is NULL, the builtin software RSA key-gen will be
+     * used. This is for behavioural compatibility whilst the code gets
+     * rewired, but one day it would be nice to assume there are no such
+     * things as "builtin software" implementations.
+     */
+    int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+};
+
+struct rsa_st {
+    /*
+     * The first parameter is used to pickup errors where this is passed
+     * instead of aEVP_PKEY, it is set to 0
+     */
+    int pad;
+    long version;
+    const RSA_METHOD *meth;
+    /* functional reference if 'meth' is ENGINE-provided */
+    ENGINE *engine;
+    BIGNUM *n;
+    BIGNUM *e;
+    BIGNUM *d;
+    BIGNUM *p;
+    BIGNUM *q;
+    BIGNUM *dmp1;
+    BIGNUM *dmq1;
+    BIGNUM *iqmp;
+    /* be careful using this if the RSA structure is shared */
+    CRYPTO_EX_DATA ex_data;
+    int references;
+    int flags;
+    /* Used to cache montgomery values */
+    BN_MONT_CTX *_method_mod_n;
+    BN_MONT_CTX *_method_mod_p;
+    BN_MONT_CTX *_method_mod_q;
+    /*
+     * all BIGNUM values are actually in the following data, if it is not
+     * NULL
+     */
+    char *bignum_data;
+    BN_BLINDING *blinding;
+    BN_BLINDING *mt_blinding;
+};
+
+# ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+#  define OPENSSL_RSA_MAX_MODULUS_BITS   16384
+# endif
+
+# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+#  define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
+# endif
+# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+
+/* exponent limit enforced for "large" modulus only */
+#  define OPENSSL_RSA_MAX_PUBEXP_BITS    64
+# endif
+
+# define RSA_3   0x3L
+# define RSA_F4  0x10001L
+
+# define RSA_METHOD_FLAG_NO_CHECK        0x0001/* don't check pub/private
+                                                * match */
+
+# define RSA_FLAG_CACHE_PUBLIC           0x0002
+# define RSA_FLAG_CACHE_PRIVATE          0x0004
+# define RSA_FLAG_BLINDING               0x0008
+# define RSA_FLAG_THREAD_SAFE            0x0010
+/*
+ * This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag
+ * bn_mod_exp gets called when private key components are absent.
+ */
+# define RSA_FLAG_EXT_PKEY               0x0020
+
+/*
+ * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify
+ * functions.
+ */
+# define RSA_FLAG_SIGN_VER               0x0040
+
+/*
+ * new with 0.9.6j and 0.9.7b; the built-in
+ * RSA implementation now uses blinding by
+ * default (ignoring RSA_FLAG_BLINDING),
+ * but other engines might not need it
+ */
+# define RSA_FLAG_NO_BLINDING            0x0080
+/*
+ * new with 0.9.8f; the built-in RSA
+ * implementation now uses constant time
+ * operations by default in private key operations,
+ * e.g., constant time modular exponentiation,
+ * modular inverse without leaking branches,
+ * division without leaking branches. This
+ * flag disables these constant time
+ * operations and results in faster RSA
+ * private key operations.
+ */
+# define RSA_FLAG_NO_CONSTTIME           0x0100
+# ifdef OPENSSL_USE_DEPRECATED
+/* deprecated name for the flag*/
+/*
+ * new with 0.9.7h; the built-in RSA
+ * implementation now uses constant time
+ * modular exponentiation for secret exponents
+ * by default. This flag causes the
+ * faster variable sliding window method to
+ * be used for all exponents.
+ */
+#  define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME
+# endif
+
+# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+                                pad, NULL)
+
+# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \
+                                EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)
+
+# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+                                EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+                                len, NULL)
+
+# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+                                EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \
+                                0, plen)
+
+# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+# define  EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)  \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
+                                EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md)  \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
+                                EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd)
+
+# define  EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd)
+
+# define  EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l)
+
+# define  EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l)       \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l)
+
+# define EVP_PKEY_CTRL_RSA_PADDING       (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN   (EVP_PKEY_ALG_CTRL + 2)
+
+# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS   (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_RSA_MGF1_MD       (EVP_PKEY_ALG_CTRL + 5)
+
+# define EVP_PKEY_CTRL_GET_RSA_PADDING           (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN       (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD           (EVP_PKEY_ALG_CTRL + 8)
+
+# define EVP_PKEY_CTRL_RSA_OAEP_MD       (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_RSA_OAEP_LABEL    (EVP_PKEY_ALG_CTRL + 10)
+
+# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD   (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)
+
+# define RSA_PKCS1_PADDING       1
+# define RSA_SSLV23_PADDING      2
+# define RSA_NO_PADDING          3
+# define RSA_PKCS1_OAEP_PADDING  4
+# define RSA_X931_PADDING        5
+/* EVP_PKEY_ only */
+# define RSA_PKCS1_PSS_PADDING   6
+
+# define RSA_PKCS1_PADDING_SIZE  11
+
+# define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+# define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *RSA_new(void);
+RSA *RSA_new_method(ENGINE *engine);
+int RSA_size(const RSA *rsa);
+
+/* Deprecated version */
+# ifndef OPENSSL_NO_DEPRECATED
+RSA *RSA_generate_key(int bits, unsigned long e, void
+                       (*callback) (int, int, void *), void *cb_arg);
+# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
+int RSA_check_key(const RSA *);
+        /* next 4 return -1 on error */
+int RSA_public_encrypt(int flen, const unsigned char *from,
+                       unsigned char *to, RSA *rsa, int padding);
+int RSA_private_encrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+int RSA_public_decrypt(int flen, const unsigned char *from,
+                       unsigned char *to, RSA *rsa, int padding);
+int RSA_private_decrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+void RSA_free(RSA *r);
+/* "up" the RSA object's reference count */
+int RSA_up_ref(RSA *r);
+
+int RSA_flags(const RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(const RSA *rsa);
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* This function needs the memory locking malloc callbacks to be installed */
+int RSA_memory_lock(RSA *r);
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+
+typedef struct rsa_pss_params_st {
+    X509_ALGOR *hashAlgorithm;
+    X509_ALGOR *maskGenAlgorithm;
+    ASN1_INTEGER *saltLength;
+    ASN1_INTEGER *trailerField;
+} RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
+typedef struct rsa_oaep_params_st {
+    X509_ALGOR *hashFunc;
+    X509_ALGOR *maskGenFunc;
+    X509_ALGOR *pSourceFunc;
+} RSA_OAEP_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
+
+# ifndef OPENSSL_NO_FP_API
+int RSA_print_fp(FILE *fp, const RSA *r, int offset);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+int RSA_print(BIO *bp, const RSA *r, int offset);
+# endif
+
+# ifndef OPENSSL_NO_RC4
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+                int (*cb) (char *buf, int len, const char *prompt,
+                           int verify), int sgckey);
+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);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+                     int (*cb) (char *buf, int len, const char *prompt,
+                                int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+                      int (*cb) (char *buf, int len, const char *prompt,
+                                 int verify));
+# endif
+
+/*
+ * The following 2 functions sign and verify a X509_SIG ASN1 object inside
+ * PKCS#1 padded RSA encryption
+ */
+int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
+             unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
+               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/*
+ * The following 2 function sign and verify a ASN1_OCTET_STRING object inside
+ * PKCS#1 padded RSA encryption
+ */
+int RSA_sign_ASN1_OCTET_STRING(int type,
+                               const unsigned char *m, unsigned int m_length,
+                               unsigned char *sigret, unsigned int *siglen,
+                               RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m,
+                                 unsigned int m_length, unsigned char *sigbuf,
+                                 unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+                                   const unsigned char *f, int fl,
+                                   int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+                                   const unsigned char *f, int fl,
+                                   int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed,
+               long seedlen, const EVP_MD *dgst);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+                               const unsigned char *f, int fl,
+                               const unsigned char *p, int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl, int rsa_len,
+                                 const unsigned char *p, int pl);
+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 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 RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl);
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+                             const unsigned char *f, int fl, int rsa_len);
+int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f,
+                         int fl);
+int RSA_padding_check_none(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl, int rsa_len);
+int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f,
+                         int fl);
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl, int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+                         const EVP_MD *Hash, const unsigned char *EM,
+                         int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+                              const unsigned char *mHash, const EVP_MD *Hash,
+                              int 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 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 RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int RSA_set_ex_data(RSA *r, int idx, void *arg);
+void *RSA_get_ex_data(const RSA *r, int idx);
+
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+
+/*
+ * If this flag is set the RSA method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define RSA_FLAG_FIPS_METHOD                    0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define RSA_FLAG_NON_FIPS_ALLOW                 0x0400
+/*
+ * Application has decided PRNG is good enough to generate a key: don't
+ * check.
+ */
+# define RSA_FLAG_CHECKED                        0x0800
+
+/* 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_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+# define RSA_F_CHECK_PADDING_MD                           140
+# define RSA_F_DO_RSA_PRINT                               146
+# define RSA_F_INT_RSA_VERIFY                             145
+# define RSA_F_MEMORY_LOCK                                100
+# define RSA_F_OLD_RSA_PRIV_DECODE                        147
+# define RSA_F_PKEY_RSA_CTRL                              143
+# define RSA_F_PKEY_RSA_CTRL_STR                          144
+# define RSA_F_PKEY_RSA_SIGN                              142
+# define RSA_F_PKEY_RSA_VERIFY                            154
+# define RSA_F_PKEY_RSA_VERIFYRECOVER                     141
+# define RSA_F_RSA_ALGOR_TO_MD                            157
+# define RSA_F_RSA_BUILTIN_KEYGEN                         129
+# define RSA_F_RSA_CHECK_KEY                              123
+# define RSA_F_RSA_CMS_DECRYPT                            158
+# define RSA_F_RSA_EAY_PRIVATE_DECRYPT                    101
+# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT                    102
+# define RSA_F_RSA_EAY_PUBLIC_DECRYPT                     103
+# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT                     104
+# define RSA_F_RSA_GENERATE_KEY                           105
+# define RSA_F_RSA_GENERATE_KEY_EX                        155
+# define RSA_F_RSA_ITEM_VERIFY                            156
+# define RSA_F_RSA_MEMORY_LOCK                            130
+# define RSA_F_RSA_MGF1_TO_MD                             159
+# define RSA_F_RSA_NEW_METHOD                             106
+# define RSA_F_RSA_NULL                                   124
+# define RSA_F_RSA_NULL_MOD_EXP                           131
+# define RSA_F_RSA_NULL_PRIVATE_DECRYPT                   132
+# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT                   133
+# define RSA_F_RSA_NULL_PUBLIC_DECRYPT                    134
+# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT                    135
+# define RSA_F_RSA_PADDING_ADD_NONE                       107
+# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP                 121
+# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1            160
+# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS                  125
+# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1             148
+# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1               108
+# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2               109
+# define RSA_F_RSA_PADDING_ADD_SSLV23                     110
+# define RSA_F_RSA_PADDING_ADD_X931                       127
+# define RSA_F_RSA_PADDING_CHECK_NONE                     111
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP               122
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1          161
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1             112
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2             113
+# define RSA_F_RSA_PADDING_CHECK_SSLV23                   114
+# define RSA_F_RSA_PADDING_CHECK_X931                     128
+# define RSA_F_RSA_PRINT                                  115
+# define RSA_F_RSA_PRINT_FP                               116
+# define RSA_F_RSA_PRIVATE_DECRYPT                        150
+# define RSA_F_RSA_PRIVATE_ENCRYPT                        151
+# define RSA_F_RSA_PRIV_DECODE                            137
+# define RSA_F_RSA_PRIV_ENCODE                            138
+# define RSA_F_RSA_PSS_TO_CTX                             162
+# define RSA_F_RSA_PUBLIC_DECRYPT                         152
+# define RSA_F_RSA_PUBLIC_ENCRYPT                         153
+# define RSA_F_RSA_PUB_DECODE                             139
+# define RSA_F_RSA_SETUP_BLINDING                         136
+# define RSA_F_RSA_SIGN                                   117
+# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                 118
+# define RSA_F_RSA_VERIFY                                 119
+# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING               120
+# define RSA_F_RSA_VERIFY_PKCS1_PSS                       126
+# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1                  149
+
+/* Reason codes. */
+# define RSA_R_ALGORITHM_MISMATCH                         100
+# define RSA_R_BAD_E_VALUE                                101
+# define RSA_R_BAD_FIXED_HEADER_DECRYPT                   102
+# define RSA_R_BAD_PAD_BYTE_COUNT                         103
+# define RSA_R_BAD_SIGNATURE                              104
+# define RSA_R_BLOCK_TYPE_IS_NOT_01                       106
+# define RSA_R_BLOCK_TYPE_IS_NOT_02                       107
+# define RSA_R_DATA_GREATER_THAN_MOD_LEN                  108
+# define RSA_R_DATA_TOO_LARGE                             109
+# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                110
+# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS                 132
+# define RSA_R_DATA_TOO_SMALL                             111
+# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE                122
+# define RSA_R_DIGEST_DOES_NOT_MATCH                      166
+# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY                 112
+# define RSA_R_DMP1_NOT_CONGRUENT_TO_D                    124
+# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D                    125
+# define RSA_R_D_E_NOT_CONGRUENT_TO_1                     123
+# define RSA_R_FIRST_OCTET_INVALID                        133
+# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE        144
+# define RSA_R_INVALID_DIGEST                             160
+# define RSA_R_INVALID_DIGEST_LENGTH                      143
+# define RSA_R_INVALID_HEADER                             137
+# define RSA_R_INVALID_KEYBITS                            145
+# define RSA_R_INVALID_LABEL                              161
+# define RSA_R_INVALID_MESSAGE_LENGTH                     131
+# define RSA_R_INVALID_MGF1_MD                            156
+# define RSA_R_INVALID_OAEP_PARAMETERS                    162
+# define RSA_R_INVALID_PADDING                            138
+# define RSA_R_INVALID_PADDING_MODE                       141
+# define RSA_R_INVALID_PSS_PARAMETERS                     149
+# define RSA_R_INVALID_PSS_SALTLEN                        146
+# define RSA_R_INVALID_SALT_LENGTH                        150
+# define RSA_R_INVALID_TRAILER                            139
+# define RSA_R_INVALID_X931_DIGEST                        142
+# define RSA_R_IQMP_NOT_INVERSE_OF_Q                      126
+# define RSA_R_KEY_SIZE_TOO_SMALL                         120
+# define RSA_R_LAST_OCTET_INVALID                         134
+# define RSA_R_MODULUS_TOO_LARGE                          105
+# define RSA_R_NON_FIPS_RSA_METHOD                        157
+# define RSA_R_NO_PUBLIC_EXPONENT                         140
+# define RSA_R_NULL_BEFORE_BLOCK_MISSING                  113
+# define RSA_R_N_DOES_NOT_EQUAL_P_Q                       127
+# define RSA_R_OAEP_DECODING_ERROR                        121
+# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE         158
+# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   148
+# define RSA_R_PADDING_CHECK_FAILED                       114
+# define RSA_R_PKCS_DECODING_ERROR                        159
+# define RSA_R_P_NOT_PRIME                                128
+# define RSA_R_Q_NOT_PRIME                                129
+# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED               130
+# define RSA_R_SLEN_CHECK_FAILED                          136
+# define RSA_R_SLEN_RECOVERY_FAILED                       135
+# define RSA_R_SSLV3_ROLLBACK_ATTACK                      115
+# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+# define RSA_R_UNKNOWN_ALGORITHM_TYPE                     117
+# define RSA_R_UNKNOWN_DIGEST                             163
+# define RSA_R_UNKNOWN_MASK_DIGEST                        151
+# define RSA_R_UNKNOWN_PADDING_TYPE                       118
+# define RSA_R_UNKNOWN_PSS_DIGEST                         152
+# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE                164
+# define RSA_R_UNSUPPORTED_LABEL_SOURCE                   165
+# define RSA_R_UNSUPPORTED_MASK_ALGORITHM                 153
+# define RSA_R_UNSUPPORTED_MASK_PARAMETER                 154
+# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE                 155
+# define RSA_R_VALUE_MISSING                              147
+# define RSA_R_WRONG_SIGNATURE_LENGTH                     119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/safestack.h b/Cryptlib/Include/openssl/safestack.h
new file mode 100644 (file)
index 0000000..1d4f87e
--- /dev/null
@@ -0,0 +1,2672 @@
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * 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_SAFESTACK_H
+# define HEADER_SAFESTACK_H
+
+# include <openssl/stack.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifndef CHECKED_PTR_OF
+#  define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+# endif
+
+/*
+ * In C++ we get problems because an explicit cast is needed from (void *) we
+ * use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below.
+ */
+
+# define CHECKED_STACK_OF(type, p) \
+    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
+# define CHECKED_SK_COPY_FUNC(type, p) \
+    ((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0)))
+
+# define CHECKED_SK_FREE_FUNC(type, p) \
+    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
+
+# define CHECKED_SK_CMP_FUNC(type, p) \
+    ((int (*)(const void *, const void *)) \
+        ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
+
+# define STACK_OF(type) struct stack_st_##type
+# define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+# define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
+    };
+# define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+    { \
+    _STACK stack; \
+    };
+
+/* nada (obsolete in new safestack approach)*/
+# define IMPLEMENT_STACK_OF(type)
+
+/*-
+ * Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+ * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/*
+ * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned
+ * above, instead of a single char each entry is a NUL-terminated array of
+ * chars. So, we have to implement STRING specially for STACK_OF. This is
+ * dealt with in the autogenerated macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/*
+ * Similarly, we sometimes use a block of characters, NOT nul-terminated.
+ * These should also be distinguished from "normal" stacks.
+ */
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
+/*
+ * SKM_sk_... stack macros are internal to safestack.h: never use them
+ * directly, use sk_<type>_... instead
+ */
+# define SKM_sk_new(type, cmp) \
+        ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
+# define SKM_sk_new_null(type) \
+        ((STACK_OF(type) *)sk_new_null())
+# define SKM_sk_free(type, st) \
+        sk_free(CHECKED_STACK_OF(type, st))
+# define SKM_sk_num(type, st) \
+        sk_num(CHECKED_STACK_OF(type, st))
+# define SKM_sk_value(type, st,i) \
+        ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
+# define SKM_sk_set(type, st,i,val) \
+        sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
+# define SKM_sk_zero(type, st) \
+        sk_zero(CHECKED_STACK_OF(type, st))
+# define SKM_sk_push(type, st, val) \
+        sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_unshift(type, st, val) \
+        sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_find(type, st, val) \
+        sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_find_ex(type, st, val) \
+        sk_find_ex(CHECKED_STACK_OF(type, st), \
+                   CHECKED_PTR_OF(type, val))
+# define SKM_sk_delete(type, st, i) \
+        (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+# define SKM_sk_delete_ptr(type, st, ptr) \
+        (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+# define SKM_sk_insert(type, st,val, i) \
+        sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+# define SKM_sk_set_cmp_func(type, st, cmp) \
+        ((int (*)(const type * const *,const type * const *)) \
+        sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
+# define SKM_sk_dup(type, st) \
+        (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+# define SKM_sk_pop_free(type, st, free_func) \
+        sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
+# define SKM_sk_deep_copy(type, st, copy_func, free_func) \
+        (STACK_OF(type) *)sk_deep_copy(CHECKED_STACK_OF(type, st), CHECKED_SK_COPY_FUNC(type, copy_func), CHECKED_SK_FREE_FUNC(type, free_func))
+# define SKM_sk_shift(type, st) \
+        (type *)sk_shift(CHECKED_STACK_OF(type, st))
+# define SKM_sk_pop(type, st) \
+        (type *)sk_pop(CHECKED_STACK_OF(type, st))
+# define SKM_sk_sort(type, st) \
+        sk_sort(CHECKED_STACK_OF(type, st))
+# define SKM_sk_is_sorted(type, st) \
+        sk_is_sorted(CHECKED_STACK_OF(type, st))
+# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+  (STACK_OF(type) *)d2i_ASN1_SET( \
+                                (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
+                                pp, length, \
+                                CHECKED_D2I_OF(type, d2i_func), \
+                                CHECKED_SK_FREE_FUNC(type, free_func), \
+                                ex_tag, ex_class)
+# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
+                                CHECKED_I2D_OF(type, i2d_func), \
+                                ex_tag, ex_class, is_set)
+# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+        ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
+                        CHECKED_I2D_OF(type, i2d_func), buf, len)
+# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+        (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
+# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+        (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
+                                CHECKED_D2I_OF(type, d2i_func), \
+                                CHECKED_SK_FREE_FUNC(type, free_func), \
+                                pass, passlen, oct, seq)
+/*
+ * This block of defines is updated by util/mkstack.pl, please do not touch!
+ */
+# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
+# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+# define sk_ACCESS_DESCRIPTION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ACCESS_DESCRIPTION, (st), (copy_func), (free_func))
+# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
+# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+# define sk_ASIdOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASIdOrRange, (st), (copy_func), (free_func))
+# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
+# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+# define sk_ASN1_GENERALSTRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_GENERALSTRING, (st), (copy_func), (free_func))
+# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
+# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+# define sk_ASN1_INTEGER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_INTEGER, (st), (copy_func), (free_func))
+# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
+# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+# define sk_ASN1_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_OBJECT, (st), (copy_func), (free_func))
+# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
+# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+# define sk_ASN1_STRING_TABLE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_STRING_TABLE, (st), (copy_func), (free_func))
+# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
+# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+# define sk_ASN1_TYPE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_TYPE, (st), (copy_func), (free_func))
+# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+# define sk_ASN1_UTF8STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_UTF8STRING, (st), (copy_func), (free_func))
+# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
+# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+# define sk_ASN1_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_VALUE, (st), (copy_func), (free_func))
+# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
+# define sk_BIO_new_null() SKM_sk_new_null(BIO)
+# define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+# define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+# define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+# define sk_BIO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BIO, (st), (copy_func), (free_func))
+# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+# define sk_BY_DIR_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_ENTRY, (st), (copy_func), (free_func))
+# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+# define sk_BY_DIR_HASH_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_HASH, (st), (copy_func), (free_func))
+# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
+# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
+# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
+# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
+# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
+# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
+# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
+# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
+# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
+# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
+# define sk_CMS_CertificateChoices_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_CertificateChoices, (st), (copy_func), (free_func))
+# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
+# define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp))
+# define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey)
+# define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i))
+# define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val))
+# define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val))
+# define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val))
+# define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val))
+# define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val))
+# define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i))
+# define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr))
+# define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i))
+# define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp))
+# define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st)
+# define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func))
+# define sk_CMS_RecipientEncryptedKey_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientEncryptedKey, (st), (copy_func), (free_func))
+# define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st))
+# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
+# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
+# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
+# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
+# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
+# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
+# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
+# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
+# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
+# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
+# define sk_CMS_RecipientInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientInfo, (st), (copy_func), (free_func))
+# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
+# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
+# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
+# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
+# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
+# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
+# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
+# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
+# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
+# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
+# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
+# define sk_CMS_RevocationInfoChoice_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RevocationInfoChoice, (st), (copy_func), (free_func))
+# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
+# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
+# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
+# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
+# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
+# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
+# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
+# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
+# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
+# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
+# define sk_CMS_SignerInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_SignerInfo, (st), (copy_func), (free_func))
+# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
+# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
+# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+# define sk_CONF_IMODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_IMODULE, (st), (copy_func), (free_func))
+# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
+# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+# define sk_CONF_MODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_MODULE, (st), (copy_func), (free_func))
+# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
+# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+# define sk_CONF_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_VALUE, (st), (copy_func), (free_func))
+# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
+# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+# define sk_CRYPTO_EX_DATA_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_EX_DATA_FUNCS, (st), (copy_func), (free_func))
+# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
+# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+# define sk_CRYPTO_dynlock_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_dynlock, (st), (copy_func), (free_func))
+# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
+# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+# define sk_DIST_POINT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(DIST_POINT, (st), (copy_func), (free_func))
+# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
+# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+# define sk_ENGINE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE, (st), (copy_func), (free_func))
+# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
+# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+# define sk_ENGINE_CLEANUP_ITEM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE_CLEANUP_ITEM, (st), (copy_func), (free_func))
+# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+# define sk_ESS_CERT_ID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ESS_CERT_ID, (st), (copy_func), (free_func))
+# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+# define sk_EVP_MD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_MD, (st), (copy_func), (free_func))
+# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+# define sk_EVP_PBE_CTL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PBE_CTL, (st), (copy_func), (free_func))
+# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+# define sk_EVP_PKEY_ASN1_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_ASN1_METHOD, (st), (copy_func), (free_func))
+# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+# define sk_EVP_PKEY_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_METHOD, (st), (copy_func), (free_func))
+# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
+# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+# define sk_GENERAL_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAME, (st), (copy_func), (free_func))
+# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
+# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
+# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
+# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
+# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
+# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
+# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
+# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
+# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
+# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
+# define sk_GENERAL_NAMES_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAMES, (st), (copy_func), (free_func))
+# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
+# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
+# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+# define sk_GENERAL_SUBTREE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_SUBTREE, (st), (copy_func), (free_func))
+# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
+# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+# define sk_IPAddressFamily_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressFamily, (st), (copy_func), (free_func))
+# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
+# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+# define sk_IPAddressOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressOrRange, (st), (copy_func), (free_func))
+# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
+# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+# define sk_KRB5_APREQBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_APREQBODY, (st), (copy_func), (free_func))
+# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
+# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+# define sk_KRB5_AUTHDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHDATA, (st), (copy_func), (free_func))
+# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
+# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+# define sk_KRB5_AUTHENTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHENTBODY, (st), (copy_func), (free_func))
+# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
+# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+# define sk_KRB5_CHECKSUM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_CHECKSUM, (st), (copy_func), (free_func))
+# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
+# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+# define sk_KRB5_ENCDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCDATA, (st), (copy_func), (free_func))
+# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
+# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+# define sk_KRB5_ENCKEY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCKEY, (st), (copy_func), (free_func))
+# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
+# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+# define sk_KRB5_PRINCNAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_PRINCNAME, (st), (copy_func), (free_func))
+# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
+# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+# define sk_KRB5_TKTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_TKTBODY, (st), (copy_func), (free_func))
+# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+# define sk_MEM_OBJECT_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEM_OBJECT_DATA, (st), (copy_func), (free_func))
+# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
+# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+# define sk_MIME_HEADER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_HEADER, (st), (copy_func), (free_func))
+# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
+# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+# define sk_MIME_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_PARAM, (st), (copy_func), (free_func))
+# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
+# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+# define sk_NAME_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(NAME_FUNCS, (st), (copy_func), (free_func))
+# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
+# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+# define sk_OCSP_CERTID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_CERTID, (st), (copy_func), (free_func))
+# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
+# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+# define sk_OCSP_ONEREQ_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_ONEREQ, (st), (copy_func), (free_func))
+# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
+# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
+# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
+# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
+# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
+# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
+# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
+# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
+# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
+# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
+# define sk_OCSP_RESPID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_RESPID, (st), (copy_func), (free_func))
+# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
+# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
+# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+# define sk_OCSP_SINGLERESP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_SINGLERESP, (st), (copy_func), (free_func))
+# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
+# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+# define sk_PKCS12_SAFEBAG_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS12_SAFEBAG, (st), (copy_func), (free_func))
+# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
+# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+# define sk_PKCS7_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7, (st), (copy_func), (free_func))
+# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
+# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+# define sk_PKCS7_RECIP_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_RECIP_INFO, (st), (copy_func), (free_func))
+# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
+# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+# define sk_PKCS7_SIGNER_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_SIGNER_INFO, (st), (copy_func), (free_func))
+# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
+# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+# define sk_POLICYINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYINFO, (st), (copy_func), (free_func))
+# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
+# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+# define sk_POLICYQUALINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYQUALINFO, (st), (copy_func), (free_func))
+# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
+# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+# define sk_POLICY_MAPPING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICY_MAPPING, (st), (copy_func), (free_func))
+# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+# define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp))
+# define sk_SCT_new_null() SKM_sk_new_null(SCT)
+# define sk_SCT_free(st) SKM_sk_free(SCT, (st))
+# define sk_SCT_num(st) SKM_sk_num(SCT, (st))
+# define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i))
+# define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val))
+# define sk_SCT_zero(st) SKM_sk_zero(SCT, (st))
+# define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val))
+# define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val))
+# define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val))
+# define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val))
+# define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i))
+# define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr))
+# define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i))
+# define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp))
+# define sk_SCT_dup(st) SKM_sk_dup(SCT, st)
+# define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func))
+# define sk_SCT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SCT, (st), (copy_func), (free_func))
+# define sk_SCT_shift(st) SKM_sk_shift(SCT, (st))
+# define sk_SCT_pop(st) SKM_sk_pop(SCT, (st))
+# define sk_SCT_sort(st) SKM_sk_sort(SCT, (st))
+# define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st))
+# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp))
+# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
+# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
+# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
+# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
+# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
+# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
+# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
+# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
+# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
+# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val))
+# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
+# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
+# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
+# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
+# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
+# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
+# define sk_SRP_gN_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN, (st), (copy_func), (free_func))
+# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
+# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
+# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
+# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st))
+# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp))
+# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
+# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
+# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
+# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
+# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
+# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
+# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
+# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
+# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
+# define sk_SRP_gN_cache_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN_cache, (st), (copy_func), (free_func))
+# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st))
+# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp))
+# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
+# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
+# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
+# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
+# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
+# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
+# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
+# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
+# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
+# define sk_SRP_user_pwd_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_user_pwd, (st), (copy_func), (free_func))
+# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
+# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
+# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
+# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
+# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
+# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
+# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
+# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
+# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
+# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
+# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
+# define sk_SRTP_PROTECTION_PROFILE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRTP_PROTECTION_PROFILE, (st), (copy_func), (free_func))
+# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
+# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+# define sk_SSL_CIPHER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_CIPHER, (st), (copy_func), (free_func))
+# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
+# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+# define sk_SSL_COMP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_COMP, (st), (copy_func), (free_func))
+# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+# define sk_STACK_OF_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STACK_OF_X509_NAME_ENTRY, (st), (copy_func), (free_func))
+# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+# define sk_STORE_ATTR_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_ATTR_INFO, (st), (copy_func), (free_func))
+# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
+# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+# define sk_STORE_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_OBJECT, (st), (copy_func), (free_func))
+# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
+# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+# define sk_SXNETID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SXNETID, (st), (copy_func), (free_func))
+# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
+# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+# define sk_UI_STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(UI_STRING, (st), (copy_func), (free_func))
+# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
+# define sk_X509_new_null() SKM_sk_new_null(X509)
+# define sk_X509_free(st) SKM_sk_free(X509, (st))
+# define sk_X509_num(st) SKM_sk_num(X509, (st))
+# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+# define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+# define sk_X509_dup(st) SKM_sk_dup(X509, st)
+# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+# define sk_X509_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509, (st), (copy_func), (free_func))
+# define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+# define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+# define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
+# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+# define sk_X509V3_EXT_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509V3_EXT_METHOD, (st), (copy_func), (free_func))
+# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
+# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+# define sk_X509_ALGOR_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ALGOR, (st), (copy_func), (free_func))
+# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
+# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+# define sk_X509_ATTRIBUTE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ATTRIBUTE, (st), (copy_func), (free_func))
+# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
+# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+# define sk_X509_CRL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_CRL, (st), (copy_func), (free_func))
+# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
+# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+# define sk_X509_EXTENSION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_EXTENSION, (st), (copy_func), (free_func))
+# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
+# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+# define sk_X509_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_INFO, (st), (copy_func), (free_func))
+# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
+# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+# define sk_X509_LOOKUP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_LOOKUP, (st), (copy_func), (free_func))
+# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
+# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+# define sk_X509_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME, (st), (copy_func), (free_func))
+# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
+# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+# define sk_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME_ENTRY, (st), (copy_func), (free_func))
+# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
+# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+# define sk_X509_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_OBJECT, (st), (copy_func), (free_func))
+# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
+# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+# define sk_X509_POLICY_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_DATA, (st), (copy_func), (free_func))
+# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
+# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+# define sk_X509_POLICY_NODE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_NODE, (st), (copy_func), (free_func))
+# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
+# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+# define sk_X509_PURPOSE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_PURPOSE, (st), (copy_func), (free_func))
+# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
+# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+# define sk_X509_REVOKED_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_REVOKED, (st), (copy_func), (free_func))
+# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
+# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+# define sk_X509_TRUST_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_TRUST, (st), (copy_func), (free_func))
+# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
+# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+# define sk_X509_VERIFY_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_VERIFY_PARAM, (st), (copy_func), (free_func))
+# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+# define sk_nid_triple_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(nid_triple, (st), (copy_func), (free_func))
+# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+# define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+# define sk_void_new_null() SKM_sk_new_null(void)
+# define sk_void_free(st) SKM_sk_free(void, (st))
+# define sk_void_num(st) SKM_sk_num(void, (st))
+# define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+# define sk_void_zero(st) SKM_sk_zero(void, (st))
+# define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+# define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+# define sk_void_dup(st) SKM_sk_dup(void, st)
+# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+# define sk_void_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(void, (st), (copy_func), (free_func))
+# define sk_void_shift(st) SKM_sk_shift(void, (st))
+# define sk_void_pop(st) SKM_sk_pop(void, (st))
+# define sk_void_sort(st) SKM_sk_sort(void, (st))
+# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
+# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC(char, free_func))
+# define sk_OPENSSL_STRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_STRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_COPY_FUNC(char, copy_func), CHECKED_SK_FREE_FUNC(char, free_func)))
+# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
+# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
+# define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
+        ((int (*)(const char * const *,const char * const *)) \
+        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
+# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
+# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
+# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC(void, free_func))
+# define sk_OPENSSL_BLOCK_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_COPY_FUNC(void, copy_func), CHECKED_SK_FREE_FUNC(void, free_func)))
+# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
+# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
+# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
+        ((int (*)(const void * const *,const void * const *)) \
+        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
+# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
+# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
+# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func))
+# define sk_OPENSSL_PSTRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_PSTRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_COPY_FUNC(OPENSSL_STRING, copy_func), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func)))
+# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
+        ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
+# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+        SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+        SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+        SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+        SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+        SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+        SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+# define lh_APP_INFO_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_stats_bio(lh,out) \
+  LHM_lh_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+# define lh_CONF_VALUE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+# define lh_ERR_STATE_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+# define lh_FUNCTION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+# define lh_MEM_new() LHM_lh_new(MEM,mem)
+# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+# define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+# define lh_MEM_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(MEM,lh,out)
+# define lh_MEM_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(MEM,lh,out)
+# define lh_MEM_stats_bio(lh,out) \
+  LHM_lh_stats_bio(MEM,lh,out)
+# define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+# define lh_OBJ_NAME_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_stats_bio(lh,out) \
+  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+# define lh_SSL_SESSION_node_stats_bio(lh,out) \
+  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_stats_bio(lh,out) \
+  LHM_lh_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* !defined HEADER_SAFESTACK_H */
diff --git a/Cryptlib/Include/openssl/seed.h b/Cryptlib/Include/openssl/seed.h
new file mode 100644 (file)
index 0000000..8cbf0d9
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-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).
+ *
+ */
+
+#ifndef HEADER_SEED_H
+# define HEADER_SEED_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/e_os2.h>
+# include <openssl/crypto.h>
+
+# ifdef OPENSSL_NO_SEED
+#  error SEED is disabled.
+# endif
+
+/* look whether we need 'long' to get 32 bits */
+# ifdef AES_LONG
+#  ifndef SEED_LONG
+#   define SEED_LONG 1
+#  endif
+# endif
+
+# if !defined(NO_SYS_TYPES_H)
+#  include <sys/types.h>
+# endif
+
+# define SEED_BLOCK_SIZE 16
+# define SEED_KEY_LENGTH 16
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct seed_key_st {
+# ifdef SEED_LONG
+    unsigned long data[32];
+# else
+    unsigned int data[32];
+# endif
+} SEED_KEY_SCHEDULE;
+
+# ifdef OPENSSL_FIPS
+void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
+                          SEED_KEY_SCHEDULE *ks);
+# endif
+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
+                  SEED_KEY_SCHEDULE *ks);
+
+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks);
+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks);
+
+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const SEED_KEY_SCHEDULE *ks, int enc);
+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+                      const SEED_KEY_SCHEDULE *ks,
+                      unsigned char ivec[SEED_BLOCK_SIZE], int enc);
+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num,
+                         int enc);
+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif                          /* HEADER_SEED_H */
diff --git a/Cryptlib/Include/openssl/sha.h b/Cryptlib/Include/openssl/sha.h
new file mode 100644 (file)
index 0000000..e5169e4
--- /dev/null
@@ -0,0 +1,214 @@
+/* crypto/sha/sha.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_SHA_H
+# define HEADER_SHA_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+#  error SHA is disabled.
+# endif
+
+# if defined(OPENSSL_FIPS)
+#  define FIPS_SHA_SIZE_T size_t
+# endif
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+# if defined(__LP32__)
+#  define SHA_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#  define SHA_LONG unsigned long
+#  define SHA_LONG_LOG2 3
+# else
+#  define SHA_LONG unsigned int
+# endif
+
+# define SHA_LBLOCK      16
+# define SHA_CBLOCK      (SHA_LBLOCK*4)/* SHA treats input data as a
+                                        * contiguous array of 32 bit wide
+                                        * big-endian values. */
+# define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+# define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st {
+    SHA_LONG h0, h1, h2, h3, h4;
+    SHA_LONG Nl, Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num;
+} SHA_CTX;
+
+# ifndef OPENSSL_NO_SHA0
+#  ifdef OPENSSL_FIPS
+int private_SHA_Init(SHA_CTX *c);
+#  endif
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+# endif
+# ifndef OPENSSL_NO_SHA1
+#  ifdef OPENSSL_FIPS
+int private_SHA1_Init(SHA_CTX *c);
+#  endif
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+# endif
+
+# define SHA256_CBLOCK   (SHA_LBLOCK*4)/* SHA-256 treats input data as a
+                                        * contiguous array of 32 bit wide
+                                        * big-endian values. */
+# define SHA224_DIGEST_LENGTH    28
+# define SHA256_DIGEST_LENGTH    32
+
+typedef struct SHA256state_st {
+    SHA_LONG h[8];
+    SHA_LONG Nl, Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num, md_len;
+} SHA256_CTX;
+
+# ifndef OPENSSL_NO_SHA256
+#  ifdef OPENSSL_FIPS
+int private_SHA224_Init(SHA256_CTX *c);
+int private_SHA256_Init(SHA256_CTX *c);
+#  endif
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+# endif
+
+# define SHA384_DIGEST_LENGTH    48
+# define SHA512_DIGEST_LENGTH    64
+
+# ifndef OPENSSL_NO_SHA512
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+/*
+ * SHA-512 treats input data as a
+ * contiguous array of 64 bit
+ * wide big-endian values.
+ */
+#  define SHA512_CBLOCK   (SHA_LBLOCK*8)
+#  if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#   define SHA_LONG64 unsigned __int64
+#   define U64(C)     C##UI64
+#  elif defined(__arch64__)
+#   define SHA_LONG64 unsigned long
+#   define U64(C)     C##UL
+#  else
+#   define SHA_LONG64 unsigned long long
+#   define U64(C)     C##ULL
+#  endif
+
+typedef struct SHA512state_st {
+    SHA_LONG64 h[8];
+    SHA_LONG64 Nl, Nh;
+    union {
+        SHA_LONG64 d[SHA_LBLOCK];
+        unsigned char p[SHA512_CBLOCK];
+    } u;
+    unsigned int num, md_len;
+} SHA512_CTX;
+# endif
+
+# ifndef OPENSSL_NO_SHA512
+#  ifdef OPENSSL_FIPS
+int private_SHA384_Init(SHA512_CTX *c);
+int private_SHA512_Init(SHA512_CTX *c);
+#  endif
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/srp.h b/Cryptlib/Include/openssl/srp.h
new file mode 100644 (file)
index 0000000..4ed4bfe
--- /dev/null
@@ -0,0 +1,181 @@
+/* crypto/srp/srp.h */
+/*
+ * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
+ * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
+ * EdelKey project and contributed to 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).
+ *
+ */
+#ifndef __SRP_H__
+# define __SRP_H__
+
+# ifndef OPENSSL_NO_SRP
+
+#  include <stdio.h>
+#  include <string.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#  include <openssl/safestack.h>
+#  include <openssl/bn.h>
+#  include <openssl/crypto.h>
+
+typedef struct SRP_gN_cache_st {
+    char *b64_bn;
+    BIGNUM *bn;
+} SRP_gN_cache;
+
+
+DECLARE_STACK_OF(SRP_gN_cache)
+
+typedef struct SRP_user_pwd_st {
+    /* Owned by us. */
+    char *id;
+    BIGNUM *s;
+    BIGNUM *v;
+    /* Not owned by us. */
+    const BIGNUM *g;
+    const BIGNUM *N;
+    /* Owned by us. */
+    char *info;
+} SRP_user_pwd;
+
+DECLARE_STACK_OF(SRP_user_pwd)
+
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd);
+
+typedef struct SRP_VBASE_st {
+    STACK_OF(SRP_user_pwd) *users_pwd;
+    STACK_OF(SRP_gN_cache) *gN_cache;
+/* to simulate a user */
+    char *seed_key;
+    BIGNUM *default_g;
+    BIGNUM *default_N;
+} SRP_VBASE;
+
+/*
+ * Structure interne pour retenir les couples N et g
+ */
+typedef struct SRP_gN_st {
+    char *id;
+    BIGNUM *g;
+    BIGNUM *N;
+} SRP_gN;
+
+DECLARE_STACK_OF(SRP_gN)
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key);
+int SRP_VBASE_free(SRP_VBASE *vb);
+#ifndef OPENSSL_NO_STDIO
+int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file);
+#endif
+
+/* This method ignores the configured seed and fails for an unknown user. */
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
+/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username);
+
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+                          char **verifier, const char *N, const char *g);
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
+                           BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
+
+#  define SRP_NO_ERROR 0
+#  define SRP_ERR_VBASE_INCOMPLETE_FILE 1
+#  define SRP_ERR_VBASE_BN_LIB 2
+#  define SRP_ERR_OPEN_FILE 3
+#  define SRP_ERR_MEMORY 4
+
+#  define DB_srptype      0
+#  define DB_srpverifier  1
+#  define DB_srpsalt      2
+#  define DB_srpid        3
+#  define DB_srpgN        4
+#  define DB_srpinfo      5
+#  undef  DB_NUMBER
+#  define DB_NUMBER       6
+
+#  define DB_SRP_INDEX    'I'
+#  define DB_SRP_VALID    'V'
+#  define DB_SRP_REVOKED  'R'
+#  define DB_SRP_MODIF    'v'
+
+/* see srp.c */
+char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N);
+SRP_gN *SRP_get_default_gN(const char *id);
+
+/* server side .... */
+BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
+                            BIGNUM *N);
+BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v);
+int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N);
+BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N);
+
+/* client side .... */
+BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass);
+BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g);
+BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
+                            BIGNUM *a, BIGNUM *u);
+int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N);
+
+#  define SRP_MINIMAL_N 1024
+
+#ifdef  __cplusplus
+}
+#endif
+
+# endif
+#endif
diff --git a/Cryptlib/Include/openssl/srtp.h b/Cryptlib/Include/openssl/srtp.h
new file mode 100644 (file)
index 0000000..2279c32
--- /dev/null
@@ -0,0 +1,147 @@
+/* ssl/srtp.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-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).
+ *
+ */
+/*
+ * DTLS code by Eric Rescorla <ekr@rtfm.com>
+ *
+ * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc.
+ */
+
+#ifndef HEADER_D1_SRTP_H
+# define HEADER_D1_SRTP_H
+
+# include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define SRTP_AES128_CM_SHA1_80 0x0001
+# define SRTP_AES128_CM_SHA1_32 0x0002
+# define SRTP_AES128_F8_SHA1_80 0x0003
+# define SRTP_AES128_F8_SHA1_32 0x0004
+# define SRTP_NULL_SHA1_80      0x0005
+# define SRTP_NULL_SHA1_32      0x0006
+
+# ifndef OPENSSL_NO_SRTP
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/ssl.h b/Cryptlib/Include/openssl/ssl.h
new file mode 100644 (file)
index 0000000..5ef56fa
--- /dev/null
@@ -0,0 +1,3169 @@
+/* ssl/ssl.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-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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_SSL_H
+# define HEADER_SSL_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_COMP
+#  include <openssl/comp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# ifndef OPENSSL_NO_DEPRECATED
+#  ifndef OPENSSL_NO_X509
+#   include <openssl/x509.h>
+#  endif
+#  include <openssl/crypto.h>
+#  include <openssl/lhash.h>
+#  include <openssl/buffer.h>
+# endif
+# include <openssl/pem.h>
+# include <openssl/hmac.h>
+
+# include <openssl/kssl.h>
+# include <openssl/safestack.h>
+# include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* SSLeay version number for ASN.1 encoding of the session information */
+/*-
+ * Version 0 - initial version
+ * Version 1 - added the optional peer certificate
+ */
+# define SSL_SESSION_ASN1_VERSION 0x0001
+
+/* text strings for the ciphers */
+# define SSL_TXT_NULL_WITH_MD5           SSL2_TXT_NULL_WITH_MD5
+# define SSL_TXT_RC4_128_WITH_MD5        SSL2_TXT_RC4_128_WITH_MD5
+# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5
+# define SSL_TXT_RC2_128_CBC_WITH_MD5    SSL2_TXT_RC2_128_CBC_WITH_MD5
+# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5
+# define SSL_TXT_IDEA_128_CBC_WITH_MD5   SSL2_TXT_IDEA_128_CBC_WITH_MD5
+# define SSL_TXT_DES_64_CBC_WITH_MD5     SSL2_TXT_DES_64_CBC_WITH_MD5
+# define SSL_TXT_DES_64_CBC_WITH_SHA     SSL2_TXT_DES_64_CBC_WITH_SHA
+# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5
+# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA
+
+/*
+ * VRS Additional Kerberos5 entries
+ */
+# define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+# define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
+# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
+# define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+# define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
+# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5
+
+# define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+# define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA
+# define SSL_TXT_KRB5_RC4_40_SHA       SSL3_TXT_KRB5_RC4_40_SHA
+# define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+# define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5
+# define SSL_TXT_KRB5_RC4_40_MD5       SSL3_TXT_KRB5_RC4_40_MD5
+
+# define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+# define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+# define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+# define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+# define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
+
+# define SSL_MAX_SSL_SESSION_ID_LENGTH           32
+# define SSL_MAX_SID_CTX_LENGTH                  32
+
+# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES     (512/8)
+# define SSL_MAX_KEY_ARG_LENGTH                  8
+# define SSL_MAX_MASTER_KEY_LENGTH               48
+
+/* These are used to specify which ciphers to use and not to use */
+
+# define SSL_TXT_EXP40           "EXPORT40"
+# define SSL_TXT_EXP56           "EXPORT56"
+# define SSL_TXT_LOW             "LOW"
+# define SSL_TXT_MEDIUM          "MEDIUM"
+# define SSL_TXT_HIGH            "HIGH"
+# define SSL_TXT_FIPS            "FIPS"
+
+# define SSL_TXT_kFZA            "kFZA"/* unused! */
+# define SSL_TXT_aFZA            "aFZA"/* unused! */
+# define SSL_TXT_eFZA            "eFZA"/* unused! */
+# define SSL_TXT_FZA             "FZA"/* unused! */
+
+# define SSL_TXT_aNULL           "aNULL"
+# define SSL_TXT_eNULL           "eNULL"
+# define SSL_TXT_NULL            "NULL"
+
+# define SSL_TXT_kRSA            "kRSA"
+# define SSL_TXT_kDHr            "kDHr"
+# define SSL_TXT_kDHd            "kDHd"
+# define SSL_TXT_kDH             "kDH"
+# define SSL_TXT_kEDH            "kEDH"
+# define SSL_TXT_kDHE            "kDHE"/* alias for kEDH */
+# define SSL_TXT_kKRB5           "kKRB5"
+# define SSL_TXT_kECDHr          "kECDHr"
+# define SSL_TXT_kECDHe          "kECDHe"
+# define SSL_TXT_kECDH           "kECDH"
+# define SSL_TXT_kEECDH          "kEECDH"
+# define SSL_TXT_kECDHE          "kECDHE"/* alias for kEECDH */
+# define SSL_TXT_kPSK            "kPSK"
+# define SSL_TXT_kGOST           "kGOST"
+# define SSL_TXT_kSRP            "kSRP"
+
+# define SSL_TXT_aRSA            "aRSA"
+# define SSL_TXT_aDSS            "aDSS"
+# define SSL_TXT_aDH             "aDH"
+# define SSL_TXT_aECDH           "aECDH"
+# define SSL_TXT_aKRB5           "aKRB5"
+# define SSL_TXT_aECDSA          "aECDSA"
+# define SSL_TXT_aPSK            "aPSK"
+# define SSL_TXT_aGOST94 "aGOST94"
+# define SSL_TXT_aGOST01 "aGOST01"
+# define SSL_TXT_aGOST  "aGOST"
+# define SSL_TXT_aSRP            "aSRP"
+
+# define SSL_TXT_DSS             "DSS"
+# define SSL_TXT_DH              "DH"
+# define SSL_TXT_EDH             "EDH"/* same as "kEDH:-ADH" */
+# define SSL_TXT_DHE             "DHE"/* alias for EDH */
+# define SSL_TXT_ADH             "ADH"
+# define SSL_TXT_RSA             "RSA"
+# define SSL_TXT_ECDH            "ECDH"
+# define SSL_TXT_EECDH           "EECDH"/* same as "kEECDH:-AECDH" */
+# define SSL_TXT_ECDHE           "ECDHE"/* alias for ECDHE" */
+# define SSL_TXT_AECDH           "AECDH"
+# define SSL_TXT_ECDSA           "ECDSA"
+# define SSL_TXT_KRB5            "KRB5"
+# define SSL_TXT_PSK             "PSK"
+# define SSL_TXT_SRP             "SRP"
+
+# define SSL_TXT_DES             "DES"
+# define SSL_TXT_3DES            "3DES"
+# define SSL_TXT_RC4             "RC4"
+# define SSL_TXT_RC2             "RC2"
+# define SSL_TXT_IDEA            "IDEA"
+# define SSL_TXT_SEED            "SEED"
+# define SSL_TXT_AES128          "AES128"
+# define SSL_TXT_AES256          "AES256"
+# define SSL_TXT_AES             "AES"
+# define SSL_TXT_AES_GCM         "AESGCM"
+# define SSL_TXT_CAMELLIA128     "CAMELLIA128"
+# define SSL_TXT_CAMELLIA256     "CAMELLIA256"
+# define SSL_TXT_CAMELLIA        "CAMELLIA"
+
+# define SSL_TXT_MD5             "MD5"
+# define SSL_TXT_SHA1            "SHA1"
+# define SSL_TXT_SHA             "SHA"/* same as "SHA1" */
+# define SSL_TXT_GOST94          "GOST94"
+# define SSL_TXT_GOST89MAC               "GOST89MAC"
+# define SSL_TXT_SHA256          "SHA256"
+# define SSL_TXT_SHA384          "SHA384"
+
+# define SSL_TXT_SSLV2           "SSLv2"
+# define SSL_TXT_SSLV3           "SSLv3"
+# define SSL_TXT_TLSV1           "TLSv1"
+# define SSL_TXT_TLSV1_1         "TLSv1.1"
+# define SSL_TXT_TLSV1_2         "TLSv1.2"
+
+# define SSL_TXT_EXP             "EXP"
+# define SSL_TXT_EXPORT          "EXPORT"
+
+# define SSL_TXT_ALL             "ALL"
+
+/*-
+ * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
+ * ciphers normally not being used.
+ * Example: "RC4" will activate all ciphers using RC4 including ciphers
+ * without authentication, which would normally disabled by DEFAULT (due
+ * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
+ * will make sure that it is also disabled in the specific selection.
+ * COMPLEMENTOF* identifiers are portable between version, as adjustments
+ * to the default cipher setup will also be included here.
+ *
+ * COMPLEMENTOFDEFAULT does not experience the same special treatment that
+ * DEFAULT gets, as only selection is being done and no sorting as needed
+ * for DEFAULT.
+ */
+# define SSL_TXT_CMPALL          "COMPLEMENTOFALL"
+# define SSL_TXT_CMPDEF          "COMPLEMENTOFDEFAULT"
+
+/*
+ * The following cipher list is used by default. It also is substituted when
+ * an application-defined cipher list string starts with 'DEFAULT'.
+ */
+# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2"
+/*
+ * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
+ * starts with a reasonable order, and all we have to do for DEFAULT is
+ * throwing out anonymous and unencrypted ciphersuites! (The latter are not
+ * actually enabled by ALL, but "ALL:RSA" would enable some of them.)
+ */
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+# define SSL_SENT_SHUTDOWN       1
+# define SSL_RECEIVED_SHUTDOWN   2
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
+#  define OPENSSL_NO_SSL2
+# endif
+
+# define SSL_FILETYPE_ASN1       X509_FILETYPE_ASN1
+# define SSL_FILETYPE_PEM        X509_FILETYPE_PEM
+
+/*
+ * This is needed to stop compilers complaining about the 'struct ssl_st *'
+ * function parameters used to prototype callbacks in SSL_CTX.
+ */
+typedef struct ssl_st *ssl_crock_st;
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_cipher_st SSL_CIPHER;
+typedef struct ssl_session_st SSL_SESSION;
+typedef struct tls_sigalgs_st TLS_SIGALGS;
+typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
+typedef struct srtp_protection_profile_st {
+    const char *name;
+    unsigned long id;
+} SRTP_PROTECTION_PROFILE;
+
+DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
+
+typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s,
+                                             const unsigned char *data,
+                                             int len, void *arg);
+typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret,
+                                         int *secret_len,
+                                         STACK_OF(SSL_CIPHER) *peer_ciphers,
+                                         SSL_CIPHER **cipher, void *arg);
+
+# ifndef OPENSSL_NO_TLSEXT
+
+/* Typedefs for handling custom extensions */
+
+typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type,
+                                  const unsigned char **out,
+                                  size_t *outlen, int *al, void *add_arg);
+
+typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type,
+                                    const unsigned char *out, void *add_arg);
+
+typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
+                                    const unsigned char *in,
+                                    size_t inlen, int *al, void *parse_arg);
+
+# endif
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+/* used to hold info on the particular ciphers used */
+struct ssl_cipher_st {
+    int valid;
+    const char *name;           /* text name */
+    unsigned long id;           /* id, 4 bytes, first is version */
+    /*
+     * changed in 0.9.9: these four used to be portions of a single value
+     * 'algorithms'
+     */
+    unsigned long algorithm_mkey; /* key exchange algorithm */
+    unsigned long algorithm_auth; /* server authentication */
+    unsigned long algorithm_enc; /* symmetric encryption */
+    unsigned long algorithm_mac; /* symmetric authentication */
+    unsigned long algorithm_ssl; /* (major) protocol version */
+    unsigned long algo_strength; /* strength and export flags */
+    unsigned long algorithm2;   /* Extra flags */
+    int strength_bits;          /* Number of bits really used */
+    int alg_bits;               /* Number of bits for algorithm */
+};
+
+/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
+struct ssl_method_st {
+    int version;
+    int (*ssl_new) (SSL *s);
+    void (*ssl_clear) (SSL *s);
+    void (*ssl_free) (SSL *s);
+    int (*ssl_accept) (SSL *s);
+    int (*ssl_connect) (SSL *s);
+    int (*ssl_read) (SSL *s, void *buf, int len);
+    int (*ssl_peek) (SSL *s, void *buf, int len);
+    int (*ssl_write) (SSL *s, const void *buf, int len);
+    int (*ssl_shutdown) (SSL *s);
+    int (*ssl_renegotiate) (SSL *s);
+    int (*ssl_renegotiate_check) (SSL *s);
+    long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long
+                             max, int *ok);
+    int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len,
+                           int peek);
+    int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len);
+    int (*ssl_dispatch_alert) (SSL *s);
+    long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg);
+    long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg);
+    const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr);
+    int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr);
+    int (*ssl_pending) (const SSL *s);
+    int (*num_ciphers) (void);
+    const SSL_CIPHER *(*get_cipher) (unsigned ncipher);
+    const struct ssl_method_st *(*get_ssl_method) (int version);
+    long (*get_timeout) (void);
+    struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
+    int (*ssl_version) (void);
+    long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void));
+    long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
+};
+
+/*-
+ * Lets make this into an ASN.1 type structure as follows
+ * SSL_SESSION_ID ::= SEQUENCE {
+ *      version                 INTEGER,        -- structure version number
+ *      SSLversion              INTEGER,        -- SSL version number
+ *      Cipher                  OCTET STRING,   -- the 3 byte cipher ID
+ *      Session_ID              OCTET STRING,   -- the Session ID
+ *      Master_key              OCTET STRING,   -- the master key
+ *      KRB5_principal          OCTET STRING    -- optional Kerberos principal
+ *      Key_Arg [ 0 ] IMPLICIT  OCTET STRING,   -- the optional Key argument
+ *      Time [ 1 ] EXPLICIT     INTEGER,        -- optional Start Time
+ *      Timeout [ 2 ] EXPLICIT  INTEGER,        -- optional Timeout ins seconds
+ *      Peer [ 3 ] EXPLICIT     X509,           -- optional Peer Certificate
+ *      Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
+ *      Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
+ *      HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension
+ *      PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ *      PSK_identity [ 8 ] EXPLICIT OCTET STRING,  -- optional PSK identity
+ *      Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
+ *      Ticket [10]             EXPLICIT OCTET STRING, -- session ticket (clients only)
+ *      Compression_meth [11]   EXPLICIT OCTET STRING, -- optional compression method
+ *      SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
+ *      }
+ * Look in ssl/ssl_asn1.c for more details
+ * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
+ */
+struct ssl_session_st {
+    int ssl_version;            /* what ssl version session info is being
+                                 * kept in here? */
+    /* only really used in SSLv2 */
+    unsigned int key_arg_length;
+    unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
+    int master_key_length;
+    unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+    /* session_id - valid? */
+    unsigned int session_id_length;
+    unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+    /*
+     * this is used to determine whether the session is being reused in the
+     * appropriate context. It is up to the application to set this, via
+     * SSL_new
+     */
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+#  ifndef OPENSSL_NO_KRB5
+    unsigned int krb5_client_princ_len;
+    unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
+#  endif                        /* OPENSSL_NO_KRB5 */
+#  ifndef OPENSSL_NO_PSK
+    char *psk_identity_hint;
+    char *psk_identity;
+#  endif
+    /*
+     * Used to indicate that session resumption is not allowed. Applications
+     * can also set this bit for a new session via not_resumable_session_cb
+     * to disable session caching and tickets.
+     */
+    int not_resumable;
+    /* The cert is the certificate used to establish this connection */
+    struct sess_cert_st /* SESS_CERT */ *sess_cert;
+    /*
+     * This is the cert for the other end. On clients, it will be the same as
+     * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is
+     * not retained in the external representation of sessions, see
+     * ssl_asn1.c).
+     */
+    X509 *peer;
+    /*
+     * when app_verify_callback accepts a session where the peer's
+     * certificate is not ok, we must remember the error for session reuse:
+     */
+    long verify_result;         /* only for servers */
+    int references;
+    long timeout;
+    long time;
+    unsigned int compress_meth; /* Need to lookup the method */
+    const SSL_CIPHER *cipher;
+    unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used
+                                 * to load the 'cipher' structure */
+    STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+    CRYPTO_EX_DATA ex_data;     /* application specific data */
+    /*
+     * These are used to make removal of session-ids more efficient and to
+     * implement a maximum cache size.
+     */
+    struct ssl_session_st *prev, *next;
+#  ifndef OPENSSL_NO_TLSEXT
+    char *tlsext_hostname;
+#   ifndef OPENSSL_NO_EC
+    size_t tlsext_ecpointformatlist_length;
+    unsigned char *tlsext_ecpointformatlist; /* peer's list */
+    size_t tlsext_ellipticcurvelist_length;
+    unsigned char *tlsext_ellipticcurvelist; /* peer's list */
+#   endif                       /* OPENSSL_NO_EC */
+    /* RFC4507 info */
+    unsigned char *tlsext_tick; /* Session ticket */
+    size_t tlsext_ticklen;      /* Session ticket length */
+    long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
+#  endif
+#  ifndef OPENSSL_NO_SRP
+    char *srp_username;
+#  endif
+};
+
+# endif
+
+# define SSL_OP_MICROSOFT_SESS_ID_BUG                    0x00000001L
+# define SSL_OP_NETSCAPE_CHALLENGE_BUG                   0x00000002L
+/* Allow initial connection to servers that don't support RI */
+# define SSL_OP_LEGACY_SERVER_CONNECT                    0x00000004L
+# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG         0x00000008L
+# define SSL_OP_TLSEXT_PADDING                           0x00000010L
+# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER               0x00000020L
+# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG                   0x00000040L
+# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG                 0x00000080L
+# define SSL_OP_TLS_D5_BUG                               0x00000100L
+# define SSL_OP_TLS_BLOCK_PADDING_BUG                    0x00000200L
+
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+# define SSL_OP_MSIE_SSLV2_RSA_PADDING                   0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG              0x0
+
+/*
+ * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in
+ * OpenSSL 0.9.6d.  Usually (depending on the application protocol) the
+ * workaround is not needed.  Unfortunately some broken SSL/TLS
+ * implementations cannot handle it at all, which is why we include it in
+ * SSL_OP_ALL.
+ */
+/* added in 0.9.6e */
+# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L
+
+/*
+ * SSL_OP_ALL: various bug workarounds that should be rather harmless.  This
+ * used to be 0x000FFFFFL before 0.9.7.
+ */
+# define SSL_OP_ALL                                      0x80000BFFL
+
+/* DTLS options */
+# define SSL_OP_NO_QUERY_MTU                 0x00001000L
+/* Turn on Cookie Exchange (on relevant for servers) */
+# define SSL_OP_COOKIE_EXCHANGE              0x00002000L
+/* Don't use RFC4507 ticket extension */
+# define SSL_OP_NO_TICKET                    0x00004000L
+/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client)  */
+# define SSL_OP_CISCO_ANYCONNECT             0x00008000L
+
+/* As server, disallow session resumption on renegotiation */
+# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION   0x00010000L
+/* Don't use compression even if supported */
+# define SSL_OP_NO_COMPRESSION                           0x00020000L
+/* Permit unsafe legacy renegotiation */
+# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION        0x00040000L
+/* If set, always create a new key when using tmp_ecdh parameters */
+# define SSL_OP_SINGLE_ECDH_USE                          0x00080000L
+/* Does nothing: retained for compatibility */
+# define SSL_OP_SINGLE_DH_USE                            0x00100000L
+/* Does nothing: retained for compatibiity */
+# define SSL_OP_EPHEMERAL_RSA                            0x0
+/*
+ * Set on servers to choose the cipher according to the server's preferences
+ */
+# define SSL_OP_CIPHER_SERVER_PREFERENCE                 0x00400000L
+/*
+ * If set, a server will allow a client to issue a SSLv3.0 version number as
+ * latest version supported in the premaster secret, even when TLSv1.0
+ * (version 3.1) was announced in the client hello. Normally this is
+ * forbidden to prevent version rollback attacks.
+ */
+# define SSL_OP_TLS_ROLLBACK_BUG                         0x00800000L
+
+# define SSL_OP_NO_SSLv2                                 0x01000000L
+# define SSL_OP_NO_SSLv3                                 0x02000000L
+# define SSL_OP_NO_TLSv1                                 0x04000000L
+# define SSL_OP_NO_TLSv1_2                               0x08000000L
+# define SSL_OP_NO_TLSv1_1                               0x10000000L
+
+# define SSL_OP_NO_DTLSv1                                0x04000000L
+# define SSL_OP_NO_DTLSv1_2                              0x08000000L
+
+# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\
+        SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)
+
+/*
+ * These next two were never actually used for anything since SSLeay zap so
+ * we have some more flags.
+ */
+/*
+ * The next flag deliberately changes the ciphertest, this is a check for the
+ * PKCS#1 attack
+ */
+# define SSL_OP_PKCS1_CHECK_1                            0x0
+# define SSL_OP_PKCS1_CHECK_2                            0x0
+
+# define SSL_OP_NETSCAPE_CA_DN_BUG                       0x20000000L
+# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG          0x40000000L
+/*
+ * Make server add server-hello extension from early version of cryptopro
+ * draft, when GOST ciphersuite is negotiated. Required for interoperability
+ * with CryptoPro CSP 3.x
+ */
+# define SSL_OP_CRYPTOPRO_TLSEXT_BUG                     0x80000000L
+
+/*
+ * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written):
+ */
+# define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
+/*
+ * Make it possible to retry SSL_write() with changed buffer location (buffer
+ * contents must stay the same!); this is not the default to avoid the
+ * misconception that non-blocking SSL_write() behaves like non-blocking
+ * write():
+ */
+# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+/*
+ * Never bother the application with retries if the transport is blocking:
+ */
+# define SSL_MODE_AUTO_RETRY 0x00000004L
+/* Don't attempt to automatically build certificate chain */
+# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/*
+ * Save RAM by releasing read and write buffers when they're empty. (SSL3 and
+ * TLS only.) "Released" buffers are put onto a free-list in the context or
+ * just freed (depending on the context's setting for freelist_max_len).
+ */
+# define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+/*
+ * Send the current time in the Random fields of the ClientHello and
+ * ServerHello records for compatibility with hypothetical implementations
+ * that require it.
+ */
+# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
+# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
+/*
+ * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications
+ * that reconnect with a downgraded protocol version; see
+ * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your
+ * application attempts a normal handshake. Only use this in explicit
+ * fallback retries, following the guidance in
+ * draft-ietf-tls-downgrade-scsv-00.
+ */
+# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
+
+/* Cert related flags */
+/*
+ * Many implementations ignore some aspects of the TLS standards such as
+ * enforcing certifcate chain algorithms. When this is set we enforce them.
+ */
+# define SSL_CERT_FLAG_TLS_STRICT                0x00000001L
+
+/* Suite B modes, takes same values as certificate verify flags */
+# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY       0x10000
+/* Suite B 192 bit only mode */
+# define SSL_CERT_FLAG_SUITEB_192_LOS            0x20000
+/* Suite B 128 bit mode allowing 192 bit algorithms */
+# define SSL_CERT_FLAG_SUITEB_128_LOS            0x30000
+
+/* Perform all sorts of protocol violations for testing purposes */
+# define SSL_CERT_FLAG_BROKEN_PROTOCOL           0x10000000
+
+/* Flags for building certificate chains */
+/* Treat any existing certificates as untrusted CAs */
+# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED          0x1
+/* Don't include root CA in chain */
+# define SSL_BUILD_CHAIN_FLAG_NO_ROOT            0x2
+/* Just check certificates already there */
+# define SSL_BUILD_CHAIN_FLAG_CHECK              0x4
+/* Ignore verification errors */
+# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR       0x8
+/* Clear verification errors from queue */
+# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR        0x10
+
+/* Flags returned by SSL_check_chain */
+/* Certificate can be used with this session */
+# define CERT_PKEY_VALID         0x1
+/* Certificate can also be used for signing */
+# define CERT_PKEY_SIGN          0x2
+/* EE certificate signing algorithm OK */
+# define CERT_PKEY_EE_SIGNATURE  0x10
+/* CA signature algorithms OK */
+# define CERT_PKEY_CA_SIGNATURE  0x20
+/* EE certificate parameters OK */
+# define CERT_PKEY_EE_PARAM      0x40
+/* CA certificate parameters OK */
+# define CERT_PKEY_CA_PARAM      0x80
+/* Signing explicitly allowed as opposed to SHA1 fallback */
+# define CERT_PKEY_EXPLICIT_SIGN 0x100
+/* Client CA issuer names match (always set for server cert) */
+# define CERT_PKEY_ISSUER_NAME   0x200
+/* Cert type matches client types (always set for server cert) */
+# define CERT_PKEY_CERT_TYPE     0x400
+/* Cert chain suitable to Suite B */
+# define CERT_PKEY_SUITEB        0x800
+
+# define SSL_CONF_FLAG_CMDLINE           0x1
+# define SSL_CONF_FLAG_FILE              0x2
+# define SSL_CONF_FLAG_CLIENT            0x4
+# define SSL_CONF_FLAG_SERVER            0x8
+# define SSL_CONF_FLAG_SHOW_ERRORS       0x10
+# define SSL_CONF_FLAG_CERTIFICATE       0x20
+/* Configuration value types */
+# define SSL_CONF_TYPE_UNKNOWN           0x0
+# define SSL_CONF_TYPE_STRING            0x1
+# define SSL_CONF_TYPE_FILE              0x2
+# define SSL_CONF_TYPE_DIR               0x3
+
+/*
+ * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they
+ * cannot be used to clear bits.
+ */
+
+# define SSL_CTX_set_options(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+# define SSL_CTX_clear_options(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
+# define SSL_CTX_get_options(ctx) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
+# define SSL_set_options(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+# define SSL_clear_options(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
+# define SSL_get_options(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
+
+# define SSL_CTX_set_mode(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+# define SSL_CTX_clear_mode(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
+# define SSL_CTX_get_mode(ctx) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+# define SSL_clear_mode(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
+# define SSL_set_mode(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
+# define SSL_get_mode(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
+# define SSL_set_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+# define DTLS_set_link_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
+# define DTLS_get_link_min_mtu(ssl) \
+        SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
+
+# define SSL_get_secure_renegotiation_support(ssl) \
+        SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
+
+# ifndef OPENSSL_NO_HEARTBEATS
+#  define SSL_heartbeat(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL)
+# endif
+
+# define SSL_CTX_set_cert_flags(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL)
+# define SSL_set_cert_flags(s,op) \
+        SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL)
+# define SSL_CTX_clear_cert_flags(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
+# define SSL_clear_cert_flags(s,op) \
+        SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
+                              void (*cb) (int write_p, int version,
+                                          int content_type, const void *buf,
+                                          size_t len, SSL *ssl, void *arg));
+void SSL_set_msg_callback(SSL *ssl,
+                          void (*cb) (int write_p, int version,
+                                      int content_type, const void *buf,
+                                      size_t len, SSL *ssl, void *arg));
+# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+
+# ifndef OPENSSL_NO_SRP
+
+#  ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct srp_ctx_st {
+    /* param for all the callbacks */
+    void *SRP_cb_arg;
+    /* set client Hello login callback */
+    int (*TLS_ext_srp_username_callback) (SSL *, int *, void *);
+    /* set SRP N/g param callback for verification */
+    int (*SRP_verify_param_callback) (SSL *, void *);
+    /* set SRP client passwd callback */
+    char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *);
+    char *login;
+    BIGNUM *N, *g, *s, *B, *A;
+    BIGNUM *a, *b, *v;
+    char *info;
+    int strength;
+    unsigned long srp_Mask;
+} SRP_CTX;
+
+#  endif
+
+/* see tls_srp.c */
+int SSL_SRP_CTX_init(SSL *s);
+int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
+int SSL_SRP_CTX_free(SSL *ctx);
+int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
+int SSL_srp_server_param_with_username(SSL *s, int *ad);
+int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key);
+int SRP_Calc_A_param(SSL *s);
+int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key);
+
+# endif
+
+# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
+#  define SSL_MAX_CERT_LIST_DEFAULT 1024*30
+                                          /* 30k max cert list :-) */
+# else
+#  define SSL_MAX_CERT_LIST_DEFAULT 1024*100
+                                           /* 100k max cert list :-) */
+# endif
+
+# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT      (1024*20)
+
+/*
+ * This callback type is used inside SSL_CTX, SSL, and in the functions that
+ * set them. It is used to override the generation of SSL/TLS session IDs in
+ * a server. Return value should be zero on an error, non-zero to proceed.
+ * Also, callbacks should themselves check if the id they generate is unique
+ * otherwise the SSL handshake will fail with an error - callbacks can do
+ * this using the 'ssl' value they're passed by;
+ * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in
+ * is set at the maximum size the session ID can be. In SSLv2 this is 16
+ * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this
+ * length to be less if desired, but under SSLv2 session IDs are supposed to
+ * be fixed at 16 bytes so the id will be padded after the callback returns
+ * in this case. It is also an error for the callback to set the size to
+ * zero.
+ */
+typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id,
+                               unsigned int *id_len);
+
+typedef struct ssl_comp_st SSL_COMP;
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+struct ssl_comp_st {
+    int id;
+    const char *name;
+#  ifndef OPENSSL_NO_COMP
+    COMP_METHOD *method;
+#  else
+    char *method;
+#  endif
+};
+
+DECLARE_STACK_OF(SSL_COMP)
+DECLARE_LHASH_OF(SSL_SESSION);
+
+struct ssl_ctx_st {
+    const SSL_METHOD *method;
+    STACK_OF(SSL_CIPHER) *cipher_list;
+    /* same as above but sorted for lookup */
+    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+    struct x509_store_st /* X509_STORE */ *cert_store;
+    LHASH_OF(SSL_SESSION) *sessions;
+    /*
+     * Most session-ids that will be cached, default is
+     * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
+     */
+    unsigned long session_cache_size;
+    struct ssl_session_st *session_cache_head;
+    struct ssl_session_st *session_cache_tail;
+    /*
+     * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT,
+     * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which
+     * means only SSL_accept which cache SSL_SESSIONS.
+     */
+    int session_cache_mode;
+    /*
+     * If timeout is not 0, it is the default timeout value set when
+     * SSL_new() is called.  This has been put in to make life easier to set
+     * things up
+     */
+    long session_timeout;
+    /*
+     * If this callback is not null, it will be called each time a session id
+     * is added to the cache.  If this function returns 1, it means that the
+     * callback will do a SSL_SESSION_free() when it has finished using it.
+     * Otherwise, on 0, it means the callback has finished with it. If
+     * remove_session_cb is not null, it will be called when a session-id is
+     * removed from the cache.  After the call, OpenSSL will
+     * SSL_SESSION_free() it.
+     */
+    int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess);
+    void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+    SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl,
+                                    unsigned char *data, int len, int *copy);
+    struct {
+        int sess_connect;       /* SSL new conn - started */
+        int sess_connect_renegotiate; /* SSL reneg - requested */
+        int sess_connect_good;  /* SSL new conne/reneg - finished */
+        int sess_accept;        /* SSL new accept - started */
+        int sess_accept_renegotiate; /* SSL reneg - requested */
+        int sess_accept_good;   /* SSL accept/reneg - finished */
+        int sess_miss;          /* session lookup misses */
+        int sess_timeout;       /* reuse attempt on timeouted session */
+        int sess_cache_full;    /* session removed due to full cache */
+        int sess_hit;           /* session reuse actually done */
+        int sess_cb_hit;        /* session-id that was not in the cache was
+                                 * passed back via the callback.  This
+                                 * indicates that the application is
+                                 * supplying session-id's from other
+                                 * processes - spooky :-) */
+    } stats;
+
+    int references;
+
+    /* if defined, these override the X509_verify_cert() calls */
+    int (*app_verify_callback) (X509_STORE_CTX *, void *);
+    void *app_verify_arg;
+    /*
+     * before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+     * ('app_verify_callback' was called with just one argument)
+     */
+
+    /* Default password callback. */
+    pem_password_cb *default_passwd_callback;
+
+    /* Default password callback user data. */
+    void *default_passwd_callback_userdata;
+
+    /* get client cert callback */
+    int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+    /* cookie generate callback */
+    int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie,
+                              unsigned int *cookie_len);
+
+    /* verify cookie callback */
+    int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie,
+                                 unsigned int cookie_len);
+
+    CRYPTO_EX_DATA ex_data;
+
+    const EVP_MD *rsa_md5;      /* For SSLv2 - name is 'ssl2-md5' */
+    const EVP_MD *md5;          /* For SSLv3/TLSv1 'ssl3-md5' */
+    const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3->sha1' */
+
+    STACK_OF(X509) *extra_certs;
+    STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
+
+    /* Default values used when no per-SSL value is defined follow */
+
+    /* used if SSL's info_callback is NULL */
+    void (*info_callback) (const SSL *ssl, int type, int val);
+
+    /* what we put in client cert requests */
+    STACK_OF(X509_NAME) *client_CA;
+
+    /*
+     * Default values to use in SSL structures follow (these are copied by
+     * SSL_new)
+     */
+
+    unsigned long options;
+    unsigned long mode;
+    long max_cert_list;
+
+    struct cert_st /* CERT */ *cert;
+    int read_ahead;
+
+    /* callback that allows applications to peek at protocol messages */
+    void (*msg_callback) (int write_p, int version, int content_type,
+                          const void *buf, size_t len, SSL *ssl, void *arg);
+    void *msg_callback_arg;
+
+    int verify_mode;
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+    /* called 'verify_callback' in the SSL */
+    int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
+
+    /* Default generate session ID callback. */
+    GEN_SESSION_CB generate_session_id;
+
+    X509_VERIFY_PARAM *param;
+
+#  if 0
+    int purpose;                /* Purpose setting */
+    int trust;                  /* Trust setting */
+#  endif
+
+    int quiet_shutdown;
+
+    /*
+     * Maximum amount of data to send in one fragment. actual record size can
+     * be more than this due to padding and MAC overheads.
+     */
+    unsigned int max_send_fragment;
+
+#  ifndef OPENSSL_NO_ENGINE
+    /*
+     * Engine to pass requests for client certs to
+     */
+    ENGINE *client_cert_engine;
+#  endif
+
+#  ifndef OPENSSL_NO_TLSEXT
+    /* TLS extensions servername callback */
+    int (*tlsext_servername_callback) (SSL *, int *, void *);
+    void *tlsext_servername_arg;
+    /* RFC 4507 session ticket keys */
+    unsigned char tlsext_tick_key_name[16];
+    unsigned char tlsext_tick_hmac_key[16];
+    unsigned char tlsext_tick_aes_key[16];
+    /* Callback to support customisation of ticket key setting */
+    int (*tlsext_ticket_key_cb) (SSL *ssl,
+                                 unsigned char *name, unsigned char *iv,
+                                 EVP_CIPHER_CTX *ectx,
+                                 HMAC_CTX *hctx, int enc);
+
+    /* certificate status request info */
+    /* Callback for status request */
+    int (*tlsext_status_cb) (SSL *ssl, void *arg);
+    void *tlsext_status_arg;
+
+    /* draft-rescorla-tls-opaque-prf-input-00.txt information */
+    int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput,
+                                             size_t len, void *arg);
+    void *tlsext_opaque_prf_input_callback_arg;
+#  endif
+
+#  ifndef OPENSSL_NO_PSK
+    char *psk_identity_hint;
+    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
+                                         char *identity,
+                                         unsigned int max_identity_len,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+#  endif
+
+#  ifndef OPENSSL_NO_BUF_FREELISTS
+#   define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
+    unsigned int freelist_max_len;
+    struct ssl3_buf_freelist_st *wbuf_freelist;
+    struct ssl3_buf_freelist_st *rbuf_freelist;
+#  endif
+#  ifndef OPENSSL_NO_SRP
+    SRP_CTX srp_ctx;            /* ctx for SRP authentication */
+#  endif
+
+#  ifndef OPENSSL_NO_TLSEXT
+
+#   ifndef OPENSSL_NO_NEXTPROTONEG
+    /* Next protocol negotiation information */
+    /* (for experimental NPN extension). */
+
+    /*
+     * For a server, this contains a callback function by which the set of
+     * advertised protocols can be provided.
+     */
+    int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf,
+                                      unsigned int *len, void *arg);
+    void *next_protos_advertised_cb_arg;
+    /*
+     * For a client, this contains a callback function that selects the next
+     * protocol from the list provided by the server.
+     */
+    int (*next_proto_select_cb) (SSL *s, unsigned char **out,
+                                 unsigned char *outlen,
+                                 const unsigned char *in,
+                                 unsigned int inlen, void *arg);
+    void *next_proto_select_cb_arg;
+#   endif
+    /* SRTP profiles we are willing to do from RFC 5764 */
+    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+
+    /*
+     * ALPN information (we are in the process of transitioning from NPN to
+     * ALPN.)
+     */
+
+    /*-
+     * For a server, this contains a callback function that allows the
+     * server to select the protocol for the connection.
+     *   out: on successful return, this must point to the raw protocol
+     *        name (without the length prefix).
+     *   outlen: on successful return, this contains the length of |*out|.
+     *   in: points to the client's list of supported protocols in
+     *       wire-format.
+     *   inlen: the length of |in|.
+     */
+    int (*alpn_select_cb) (SSL *s,
+                           const unsigned char **out,
+                           unsigned char *outlen,
+                           const unsigned char *in,
+                           unsigned int inlen, void *arg);
+    void *alpn_select_cb_arg;
+
+    /*
+     * For a client, this contains the list of supported protocols in wire
+     * format.
+     */
+    unsigned char *alpn_client_proto_list;
+    unsigned alpn_client_proto_list_len;
+
+#   ifndef OPENSSL_NO_EC
+    /* EC extension values inherited by SSL structure */
+    size_t tlsext_ecpointformatlist_length;
+    unsigned char *tlsext_ecpointformatlist;
+    size_t tlsext_ellipticcurvelist_length;
+    unsigned char *tlsext_ellipticcurvelist;
+#   endif                       /* OPENSSL_NO_EC */
+#  endif
+};
+
+# endif
+
+# define SSL_SESS_CACHE_OFF                      0x0000
+# define SSL_SESS_CACHE_CLIENT                   0x0001
+# define SSL_SESS_CACHE_SERVER                   0x0002
+# define SSL_SESS_CACHE_BOTH     (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
+# define SSL_SESS_CACHE_NO_AUTO_CLEAR            0x0080
+/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
+# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP       0x0100
+# define SSL_SESS_CACHE_NO_INTERNAL_STORE        0x0200
+# define SSL_SESS_CACHE_NO_INTERNAL \
+        (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+# define SSL_CTX_sess_number(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
+# define SSL_CTX_sess_connect(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
+# define SSL_CTX_sess_connect_good(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
+# define SSL_CTX_sess_connect_renegotiate(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
+# define SSL_CTX_sess_accept(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
+# define SSL_CTX_sess_accept_renegotiate(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
+# define SSL_CTX_sess_accept_good(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
+# define SSL_CTX_sess_hits(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
+# define SSL_CTX_sess_cb_hits(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
+# define SSL_CTX_sess_misses(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
+# define SSL_CTX_sess_timeouts(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+# define SSL_CTX_sess_cache_full(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+                             int (*new_session_cb) (struct ssl_st *ssl,
+                                                    SSL_SESSION *sess));
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
+                                              SSL_SESSION *sess);
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+                                void (*remove_session_cb) (struct ssl_ctx_st
+                                                           *ctx,
+                                                           SSL_SESSION
+                                                           *sess));
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx,
+                                                  SSL_SESSION *sess);
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+                             SSL_SESSION *(*get_session_cb) (struct ssl_st
+                                                             *ssl,
+                                                             unsigned char
+                                                             *data, int len,
+                                                             int *copy));
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
+                                                       unsigned char *Data,
+                                                       int len, int *copy);
+void SSL_CTX_set_info_callback(SSL_CTX *ctx,
+                               void (*cb) (const SSL *ssl, int type,
+                                           int val));
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
+                                                 int val);
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
+                                int (*client_cert_cb) (SSL *ssl, X509 **x509,
+                                                       EVP_PKEY **pkey));
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
+                                                 EVP_PKEY **pkey);
+# ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+# endif
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
+                                    int (*app_gen_cookie_cb) (SSL *ssl,
+                                                              unsigned char
+                                                              *cookie,
+                                                              unsigned int
+                                                              *cookie_len));
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
+                                  int (*app_verify_cookie_cb) (SSL *ssl,
+                                                               unsigned char
+                                                               *cookie,
+                                                               unsigned int
+                                                               cookie_len));
+# ifndef OPENSSL_NO_NEXTPROTONEG
+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
+                                           int (*cb) (SSL *ssl,
+                                                      const unsigned char
+                                                      **out,
+                                                      unsigned int *outlen,
+                                                      void *arg), void *arg);
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+                                      int (*cb) (SSL *ssl,
+                                                 unsigned char **out,
+                                                 unsigned char *outlen,
+                                                 const unsigned char *in,
+                                                 unsigned int inlen,
+                                                 void *arg), void *arg);
+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+                                    unsigned *len);
+# endif
+
+# ifndef OPENSSL_NO_TLSEXT
+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+                          const unsigned char *in, unsigned int inlen,
+                          const unsigned char *client,
+                          unsigned int client_len);
+# endif
+
+# define OPENSSL_NPN_UNSUPPORTED 0
+# define OPENSSL_NPN_NEGOTIATED  1
+# define OPENSSL_NPN_NO_OVERLAP  2
+
+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
+                            unsigned protos_len);
+int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
+                        unsigned protos_len);
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
+                                int (*cb) (SSL *ssl,
+                                           const unsigned char **out,
+                                           unsigned char *outlen,
+                                           const unsigned char *in,
+                                           unsigned int inlen,
+                                           void *arg), void *arg);
+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+                            unsigned *len);
+
+# ifndef OPENSSL_NO_PSK
+/*
+ * the maximum length of the buffer given to callbacks containing the
+ * resulting identity/psk
+ */
+#  define PSK_MAX_IDENTITY_LEN 128
+#  define PSK_MAX_PSK_LEN 256
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+                                     unsigned int (*psk_client_callback) (SSL
+                                                                          *ssl,
+                                                                          const
+                                                                          char
+                                                                          *hint,
+                                                                          char
+                                                                          *identity,
+                                                                          unsigned
+                                                                          int
+                                                                          max_identity_len,
+                                                                          unsigned
+                                                                          char
+                                                                          *psk,
+                                                                          unsigned
+                                                                          int
+                                                                          max_psk_len));
+void SSL_set_psk_client_callback(SSL *ssl,
+                                 unsigned int (*psk_client_callback) (SSL
+                                                                      *ssl,
+                                                                      const
+                                                                      char
+                                                                      *hint,
+                                                                      char
+                                                                      *identity,
+                                                                      unsigned
+                                                                      int
+                                                                      max_identity_len,
+                                                                      unsigned
+                                                                      char
+                                                                      *psk,
+                                                                      unsigned
+                                                                      int
+                                                                      max_psk_len));
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+                                     unsigned int (*psk_server_callback) (SSL
+                                                                          *ssl,
+                                                                          const
+                                                                          char
+                                                                          *identity,
+                                                                          unsigned
+                                                                          char
+                                                                          *psk,
+                                                                          unsigned
+                                                                          int
+                                                                          max_psk_len));
+void SSL_set_psk_server_callback(SSL *ssl,
+                                 unsigned int (*psk_server_callback) (SSL
+                                                                      *ssl,
+                                                                      const
+                                                                      char
+                                                                      *identity,
+                                                                      unsigned
+                                                                      char
+                                                                      *psk,
+                                                                      unsigned
+                                                                      int
+                                                                      max_psk_len));
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+const char *SSL_get_psk_identity_hint(const SSL *s);
+const char *SSL_get_psk_identity(const SSL *s);
+# endif
+
+# ifndef OPENSSL_NO_TLSEXT
+/* Register callbacks to handle custom TLS Extensions for client or server. */
+
+int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb,
+                                  void *parse_arg);
+
+int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb,
+                                  void *parse_arg);
+
+int SSL_extension_supported(unsigned int ext_type);
+
+# endif
+
+# define SSL_NOTHING     1
+# define SSL_WRITING     2
+# define SSL_READING     3
+# define SSL_X509_LOOKUP 4
+
+/* These will only be used when doing non-blocking IO */
+# define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
+# define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
+# define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
+# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+
+# define SSL_MAC_FLAG_READ_MAC_STREAM 1
+# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+struct ssl_st {
+    /*
+     * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
+     * DTLS1_VERSION)
+     */
+    int version;
+    /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
+    int type;
+    /* SSLv3 */
+    const SSL_METHOD *method;
+    /*
+     * There are 2 BIO's even though they are normally both the same.  This
+     * is so data can be read and written to different handlers
+     */
+#  ifndef OPENSSL_NO_BIO
+    /* used by SSL_read */
+    BIO *rbio;
+    /* used by SSL_write */
+    BIO *wbio;
+    /* used during session-id reuse to concatenate messages */
+    BIO *bbio;
+#  else
+    /* used by SSL_read */
+    char *rbio;
+    /* used by SSL_write */
+    char *wbio;
+    char *bbio;
+#  endif
+    /*
+     * This holds a variable that indicates what we were doing when a 0 or -1
+     * is returned.  This is needed for non-blocking IO so we know what
+     * request needs re-doing when in SSL_accept or SSL_connect
+     */
+    int rwstate;
+    /* true when we are actually in SSL_accept() or SSL_connect() */
+    int in_handshake;
+    int (*handshake_func) (SSL *);
+    /*
+     * Imagine that here's a boolean member "init" that is switched as soon
+     * as SSL_set_{accept/connect}_state is called for the first time, so
+     * that "state" and "handshake_func" are properly initialized.  But as
+     * handshake_func is == 0 until then, we use this test instead of an
+     * "init" member.
+     */
+    /* are we the server side? - mostly used by SSL_clear */
+    int server;
+    /*
+     * Generate a new session or reuse an old one.
+     * NB: For servers, the 'new' session may actually be a previously
+     * cached session or even the previous session unless
+     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set
+     */
+    int new_session;
+    /* don't send shutdown packets */
+    int quiet_shutdown;
+    /* we have shut things down, 0x01 sent, 0x02 for received */
+    int shutdown;
+    /* where we are */
+    int state;
+    /* where we are when reading */
+    int rstate;
+    BUF_MEM *init_buf;          /* buffer used during init */
+    void *init_msg;             /* pointer to handshake message body, set by
+                                 * ssl3_get_message() */
+    int init_num;               /* amount read/written */
+    int init_off;               /* amount read/written */
+    /* used internally to point at a raw packet */
+    unsigned char *packet;
+    unsigned int packet_length;
+    struct ssl2_state_st *s2;   /* SSLv2 variables */
+    struct ssl3_state_st *s3;   /* SSLv3 variables */
+    struct dtls1_state_st *d1;  /* DTLSv1 variables */
+    int read_ahead;             /* Read as many input bytes as possible (for
+                                 * non-blocking reads) */
+    /* callback that allows applications to peek at protocol messages */
+    void (*msg_callback) (int write_p, int version, int content_type,
+                          const void *buf, size_t len, SSL *ssl, void *arg);
+    void *msg_callback_arg;
+    int hit;                    /* reusing a previous session */
+    X509_VERIFY_PARAM *param;
+#  if 0
+    int purpose;                /* Purpose setting */
+    int trust;                  /* Trust setting */
+#  endif
+    /* crypto */
+    STACK_OF(SSL_CIPHER) *cipher_list;
+    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+    /*
+     * These are the ones being used, the ones in SSL_SESSION are the ones to
+     * be 'copied' into these ones
+     */
+    int mac_flags;
+    EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
+    EVP_MD_CTX *read_hash;      /* used for mac generation */
+#  ifndef OPENSSL_NO_COMP
+    COMP_CTX *expand;           /* uncompress */
+#  else
+    char *expand;
+#  endif
+    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+    EVP_MD_CTX *write_hash;     /* used for mac generation */
+#  ifndef OPENSSL_NO_COMP
+    COMP_CTX *compress;         /* compression */
+#  else
+    char *compress;
+#  endif
+    /* session info */
+    /* client cert? */
+    /* This is used to hold the server certificate used */
+    struct cert_st /* CERT */ *cert;
+    /*
+     * the session_id_context is used to ensure sessions are only reused in
+     * the appropriate context
+     */
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+    /* This can also be in the session once a session is established */
+    SSL_SESSION *session;
+    /* Default generate session ID callback. */
+    GEN_SESSION_CB generate_session_id;
+    /* Used in SSL2 and SSL3 */
+    /*
+     * 0 don't care about verify failure.
+     * 1 fail if verify fails
+     */
+    int verify_mode;
+    /* fail if callback returns 0 */
+    int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
+    /* optional informational callback */
+    void (*info_callback) (const SSL *ssl, int type, int val);
+    /* error bytes to be written */
+    int error;
+    /* actual code */
+    int error_code;
+#  ifndef OPENSSL_NO_KRB5
+    /* Kerberos 5 context */
+    KSSL_CTX *kssl_ctx;
+#  endif                        /* OPENSSL_NO_KRB5 */
+#  ifndef OPENSSL_NO_PSK
+    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
+                                         char *identity,
+                                         unsigned int max_identity_len,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+#  endif
+    SSL_CTX *ctx;
+    /*
+     * set this flag to 1 and a sleep(1) is put into all SSL_read() and
+     * SSL_write() calls, good for nbio debuging :-)
+     */
+    int debug;
+    /* extra application data */
+    long verify_result;
+    CRYPTO_EX_DATA ex_data;
+    /* for server side, keep the list of CA_dn we can use */
+    STACK_OF(X509_NAME) *client_CA;
+    int references;
+    /* protocol behaviour */
+    unsigned long options;
+    /* API behaviour */
+    unsigned long mode;
+    long max_cert_list;
+    int first_packet;
+    /* what was passed, used for SSLv3/TLS rollback check */
+    int client_version;
+    unsigned int max_send_fragment;
+#  ifndef OPENSSL_NO_TLSEXT
+    /* TLS extension debug callback */
+    void (*tlsext_debug_cb) (SSL *s, int client_server, int type,
+                             unsigned char *data, int len, void *arg);
+    void *tlsext_debug_arg;
+    char *tlsext_hostname;
+    /*-
+     * no further mod of servername
+     * 0 : call the servername extension callback.
+     * 1 : prepare 2, allow last ack just after in server callback.
+     * 2 : don't call servername callback, no ack in server hello
+     */
+    int servername_done;
+    /* certificate status request info */
+    /* Status type or -1 if no status type */
+    int tlsext_status_type;
+    /* Expect OCSP CertificateStatus message */
+    int tlsext_status_expected;
+    /* OCSP status request only */
+    STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
+    X509_EXTENSIONS *tlsext_ocsp_exts;
+    /* OCSP response received or to be sent */
+    unsigned char *tlsext_ocsp_resp;
+    int tlsext_ocsp_resplen;
+    /* RFC4507 session ticket expected to be received or sent */
+    int tlsext_ticket_expected;
+#   ifndef OPENSSL_NO_EC
+    size_t tlsext_ecpointformatlist_length;
+    /* our list */
+    unsigned char *tlsext_ecpointformatlist;
+    size_t tlsext_ellipticcurvelist_length;
+    /* our list */
+    unsigned char *tlsext_ellipticcurvelist;
+#   endif                       /* OPENSSL_NO_EC */
+    /*
+     * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for
+     * handshakes
+     */
+    void *tlsext_opaque_prf_input;
+    size_t tlsext_opaque_prf_input_len;
+    /* TLS Session Ticket extension override */
+    TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
+    /* TLS Session Ticket extension callback */
+    tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
+    void *tls_session_ticket_ext_cb_arg;
+    /* TLS pre-shared secret session resumption */
+    tls_session_secret_cb_fn tls_session_secret_cb;
+    void *tls_session_secret_cb_arg;
+    SSL_CTX *initial_ctx;       /* initial ctx, used to store sessions */
+#   ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * Next protocol negotiation. For the client, this is the protocol that
+     * we sent in NextProtocol and is set when handling ServerHello
+     * extensions. For a server, this is the client's selected_protocol from
+     * NextProtocol and is set when handling the NextProtocol message, before
+     * the Finished message.
+     */
+    unsigned char *next_proto_negotiated;
+    unsigned char next_proto_negotiated_len;
+#   endif
+#   define session_ctx initial_ctx
+    /* What we'll do */
+    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+    /* What's been chosen */
+    SRTP_PROTECTION_PROFILE *srtp_profile;
+        /*-
+         * Is use of the Heartbeat extension negotiated?
+         * 0: disabled
+         * 1: enabled
+         * 2: enabled, but not allowed to send Requests
+         */
+    unsigned int tlsext_heartbeat;
+    /* Indicates if a HeartbeatRequest is in flight */
+    unsigned int tlsext_hb_pending;
+    /* HeartbeatRequest sequence number */
+    unsigned int tlsext_hb_seq;
+#  else
+#   define session_ctx ctx
+#  endif                        /* OPENSSL_NO_TLSEXT */
+    /*-
+     * 1 if we are renegotiating.
+     * 2 if we are a server and are inside a handshake
+     * (i.e. not just sending a HelloRequest)
+     */
+    int renegotiate;
+#  ifndef OPENSSL_NO_SRP
+    /* ctx for SRP authentication */
+    SRP_CTX srp_ctx;
+#  endif
+#  ifndef OPENSSL_NO_TLSEXT
+    /*
+     * For a client, this contains the list of supported protocols in wire
+     * format.
+     */
+    unsigned char *alpn_client_proto_list;
+    unsigned alpn_client_proto_list_len;
+#  endif                        /* OPENSSL_NO_TLSEXT */
+};
+
+# endif
+
+#ifdef __cplusplus
+}
+#endif
+
+# include <openssl/ssl2.h>
+# include <openssl/ssl3.h>
+# include <openssl/tls1.h>      /* This is mostly sslv3 with a few tweaks */
+# include <openssl/dtls1.h>     /* Datagram TLS */
+# include <openssl/ssl23.h>
+# include <openssl/srtp.h>      /* Support for the use_srtp extension */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* compatibility */
+# define SSL_set_app_data(s,arg)         (SSL_set_ex_data(s,0,(char *)arg))
+# define SSL_get_app_data(s)             (SSL_get_ex_data(s,0))
+# define SSL_SESSION_set_app_data(s,a)   (SSL_SESSION_set_ex_data(s,0,(char *)a))
+# define SSL_SESSION_get_app_data(s)     (SSL_SESSION_get_ex_data(s,0))
+# define SSL_CTX_get_app_data(ctx)       (SSL_CTX_get_ex_data(ctx,0))
+# define SSL_CTX_set_app_data(ctx,arg)   (SSL_CTX_set_ex_data(ctx,0,(char *)arg))
+
+/*
+ * The following are the possible values for ssl->state are are used to
+ * indicate where we are up to in the SSL connection establishment. The
+ * macros that follow are about the only things you should need to use and
+ * even then, only when using non-blocking IO. It can also be useful to work
+ * out where you were when the connection failed
+ */
+
+# define SSL_ST_CONNECT                  0x1000
+# define SSL_ST_ACCEPT                   0x2000
+# define SSL_ST_MASK                     0x0FFF
+# define SSL_ST_INIT                     (SSL_ST_CONNECT|SSL_ST_ACCEPT)
+# define SSL_ST_BEFORE                   0x4000
+# define SSL_ST_OK                       0x03
+# define SSL_ST_RENEGOTIATE              (0x04|SSL_ST_INIT)
+# define SSL_ST_ERR                      0x05
+
+# define SSL_CB_LOOP                     0x01
+# define SSL_CB_EXIT                     0x02
+# define SSL_CB_READ                     0x04
+# define SSL_CB_WRITE                    0x08
+# define SSL_CB_ALERT                    0x4000/* used in callback */
+# define SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
+# define SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
+# define SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
+# define SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
+# define SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
+# define SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
+# define SSL_CB_HANDSHAKE_START          0x10
+# define SSL_CB_HANDSHAKE_DONE           0x20
+
+/* Is the SSL_connection established? */
+# define SSL_get_state(a)                SSL_state(a)
+# define SSL_is_init_finished(a)         (SSL_state(a) == SSL_ST_OK)
+# define SSL_in_init(a)                  (SSL_state(a)&SSL_ST_INIT)
+# define SSL_in_before(a)                (SSL_state(a)&SSL_ST_BEFORE)
+# define SSL_in_connect_init(a)          (SSL_state(a)&SSL_ST_CONNECT)
+# define SSL_in_accept_init(a)           (SSL_state(a)&SSL_ST_ACCEPT)
+
+/*
+ * The following 2 states are kept in ssl->rstate when reads fail, you should
+ * not need these
+ */
+# define SSL_ST_READ_HEADER                      0xF0
+# define SSL_ST_READ_BODY                        0xF1
+# define SSL_ST_READ_DONE                        0xF2
+
+/*-
+ * Obtain latest Finished message
+ *   -- that we sent (SSL_get_finished)
+ *   -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes.
+ */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+/*
+ * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are
+ * 'ored' with SSL_VERIFY_PEER if they are desired
+ */
+# define SSL_VERIFY_NONE                 0x00
+# define SSL_VERIFY_PEER                 0x01
+# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+# define SSL_VERIFY_CLIENT_ONCE          0x04
+
+# define OpenSSL_add_ssl_algorithms()    SSL_library_init()
+# define SSLeay_add_ssl_algorithms()     SSL_library_init()
+
+/* this is for backward compatibility */
+# if 0                          /* NEW_SSLEAY */
+#  define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
+#  define SSL_set_pref_cipher(c,n)        SSL_set_cipher_list(c,n)
+#  define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
+#  define SSL_remove_session(a,b)         SSL_CTX_remove_session((a),(b))
+#  define SSL_flush_sessions(a,b)         SSL_CTX_flush_sessions((a),(b))
+# endif
+/* More backward compatibility */
+# define SSL_get_cipher(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+# define SSL_get_cipher_bits(s,np) \
+                SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+# define SSL_get_cipher_version(s) \
+                SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+# define SSL_get_cipher_name(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+# define SSL_get_time(a)         SSL_SESSION_get_time(a)
+# define SSL_set_time(a,b)       SSL_SESSION_set_time((a),(b))
+# define SSL_get_timeout(a)      SSL_SESSION_get_timeout(a)
+# define SSL_set_timeout(a,b)    SSL_SESSION_set_timeout((a),(b))
+
+# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
+# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
+
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+# define SSL_AD_REASON_OFFSET            1000/* offset to get SSL_R_... value
+                                              * from SSL_AD_... */
+/* These alert types are for SSLv3 and TLSv1 */
+# define SSL_AD_CLOSE_NOTIFY             SSL3_AD_CLOSE_NOTIFY
+/* fatal */
+# define SSL_AD_UNEXPECTED_MESSAGE       SSL3_AD_UNEXPECTED_MESSAGE
+/* fatal */
+# define SSL_AD_BAD_RECORD_MAC           SSL3_AD_BAD_RECORD_MAC
+# define SSL_AD_DECRYPTION_FAILED        TLS1_AD_DECRYPTION_FAILED
+# define SSL_AD_RECORD_OVERFLOW          TLS1_AD_RECORD_OVERFLOW
+/* fatal */
+# define SSL_AD_DECOMPRESSION_FAILURE    SSL3_AD_DECOMPRESSION_FAILURE
+/* fatal */
+# define SSL_AD_HANDSHAKE_FAILURE        SSL3_AD_HANDSHAKE_FAILURE
+/* Not for TLS */
+# define SSL_AD_NO_CERTIFICATE           SSL3_AD_NO_CERTIFICATE
+# define SSL_AD_BAD_CERTIFICATE          SSL3_AD_BAD_CERTIFICATE
+# define SSL_AD_UNSUPPORTED_CERTIFICATE  SSL3_AD_UNSUPPORTED_CERTIFICATE
+# define SSL_AD_CERTIFICATE_REVOKED      SSL3_AD_CERTIFICATE_REVOKED
+# define SSL_AD_CERTIFICATE_EXPIRED      SSL3_AD_CERTIFICATE_EXPIRED
+# define SSL_AD_CERTIFICATE_UNKNOWN      SSL3_AD_CERTIFICATE_UNKNOWN
+/* fatal */
+# define SSL_AD_ILLEGAL_PARAMETER        SSL3_AD_ILLEGAL_PARAMETER
+/* fatal */
+# define SSL_AD_UNKNOWN_CA               TLS1_AD_UNKNOWN_CA
+/* fatal */
+# define SSL_AD_ACCESS_DENIED            TLS1_AD_ACCESS_DENIED
+/* fatal */
+# define SSL_AD_DECODE_ERROR             TLS1_AD_DECODE_ERROR
+# define SSL_AD_DECRYPT_ERROR            TLS1_AD_DECRYPT_ERROR
+/* fatal */
+# define SSL_AD_EXPORT_RESTRICTION       TLS1_AD_EXPORT_RESTRICTION
+/* fatal */
+# define SSL_AD_PROTOCOL_VERSION         TLS1_AD_PROTOCOL_VERSION
+/* fatal */
+# define SSL_AD_INSUFFICIENT_SECURITY    TLS1_AD_INSUFFICIENT_SECURITY
+/* fatal */
+# define SSL_AD_INTERNAL_ERROR           TLS1_AD_INTERNAL_ERROR
+# define SSL_AD_USER_CANCELLED           TLS1_AD_USER_CANCELLED
+# define SSL_AD_NO_RENEGOTIATION         TLS1_AD_NO_RENEGOTIATION
+# define SSL_AD_UNSUPPORTED_EXTENSION    TLS1_AD_UNSUPPORTED_EXTENSION
+# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+# define SSL_AD_UNRECOGNIZED_NAME        TLS1_AD_UNRECOGNIZED_NAME
+# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+/* fatal */
+# define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY
+/* fatal */
+# define SSL_AD_INAPPROPRIATE_FALLBACK   TLS1_AD_INAPPROPRIATE_FALLBACK
+# define SSL_ERROR_NONE                  0
+# define SSL_ERROR_SSL                   1
+# define SSL_ERROR_WANT_READ             2
+# define SSL_ERROR_WANT_WRITE            3
+# define SSL_ERROR_WANT_X509_LOOKUP      4
+# define SSL_ERROR_SYSCALL               5/* look at error stack/return
+                                           * value/errno */
+# define SSL_ERROR_ZERO_RETURN           6
+# define SSL_ERROR_WANT_CONNECT          7
+# define SSL_ERROR_WANT_ACCEPT           8
+# define SSL_CTRL_NEED_TMP_RSA                   1
+# define SSL_CTRL_SET_TMP_RSA                    2
+# define SSL_CTRL_SET_TMP_DH                     3
+# define SSL_CTRL_SET_TMP_ECDH                   4
+# define SSL_CTRL_SET_TMP_RSA_CB                 5
+# define SSL_CTRL_SET_TMP_DH_CB                  6
+# define SSL_CTRL_SET_TMP_ECDH_CB                7
+# define SSL_CTRL_GET_SESSION_REUSED             8
+# define SSL_CTRL_GET_CLIENT_CERT_REQUEST        9
+# define SSL_CTRL_GET_NUM_RENEGOTIATIONS         10
+# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS       11
+# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS       12
+# define SSL_CTRL_GET_FLAGS                      13
+# define SSL_CTRL_EXTRA_CHAIN_CERT               14
+# define SSL_CTRL_SET_MSG_CALLBACK               15
+# define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
+/* only applies to datagram connections */
+# define SSL_CTRL_SET_MTU                17
+/* Stats */
+# define SSL_CTRL_SESS_NUMBER                    20
+# define SSL_CTRL_SESS_CONNECT                   21
+# define SSL_CTRL_SESS_CONNECT_GOOD              22
+# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE       23
+# define SSL_CTRL_SESS_ACCEPT                    24
+# define SSL_CTRL_SESS_ACCEPT_GOOD               25
+# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE        26
+# define SSL_CTRL_SESS_HIT                       27
+# define SSL_CTRL_SESS_CB_HIT                    28
+# define SSL_CTRL_SESS_MISSES                    29
+# define SSL_CTRL_SESS_TIMEOUTS                  30
+# define SSL_CTRL_SESS_CACHE_FULL                31
+# define SSL_CTRL_OPTIONS                        32
+# define SSL_CTRL_MODE                           33
+# define SSL_CTRL_GET_READ_AHEAD                 40
+# define SSL_CTRL_SET_READ_AHEAD                 41
+# define SSL_CTRL_SET_SESS_CACHE_SIZE            42
+# define SSL_CTRL_GET_SESS_CACHE_SIZE            43
+# define SSL_CTRL_SET_SESS_CACHE_MODE            44
+# define SSL_CTRL_GET_SESS_CACHE_MODE            45
+# define SSL_CTRL_GET_MAX_CERT_LIST              50
+# define SSL_CTRL_SET_MAX_CERT_LIST              51
+# define SSL_CTRL_SET_MAX_SEND_FRAGMENT          52
+/* see tls1.h for macros based on these */
+# ifndef OPENSSL_NO_TLSEXT
+#  define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB       53
+#  define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG      54
+#  define SSL_CTRL_SET_TLSEXT_HOSTNAME            55
+#  define SSL_CTRL_SET_TLSEXT_DEBUG_CB            56
+#  define SSL_CTRL_SET_TLSEXT_DEBUG_ARG           57
+#  define SSL_CTRL_GET_TLSEXT_TICKET_KEYS         58
+#  define SSL_CTRL_SET_TLSEXT_TICKET_KEYS         59
+#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT    60
+#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61
+#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB       63
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG   64
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE     65
+#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS     66
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS     67
+#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS      68
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS      69
+#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP        70
+#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP        71
+#  define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB       72
+#  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB    75
+#  define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB                76
+#  define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB             77
+#  define SSL_CTRL_SET_SRP_ARG            78
+#  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME               79
+#  define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH               80
+#  define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD               81
+#  ifndef OPENSSL_NO_HEARTBEATS
+#   define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT                         85
+#   define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING          86
+#   define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS      87
+#  endif
+# endif                         /* OPENSSL_NO_TLSEXT */
+# define DTLS_CTRL_GET_TIMEOUT           73
+# define DTLS_CTRL_HANDLE_TIMEOUT        74
+# define DTLS_CTRL_LISTEN                        75
+# define SSL_CTRL_GET_RI_SUPPORT                 76
+# define SSL_CTRL_CLEAR_OPTIONS                  77
+# define SSL_CTRL_CLEAR_MODE                     78
+# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS          82
+# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS        83
+# define SSL_CTRL_CHAIN                          88
+# define SSL_CTRL_CHAIN_CERT                     89
+# define SSL_CTRL_GET_CURVES                     90
+# define SSL_CTRL_SET_CURVES                     91
+# define SSL_CTRL_SET_CURVES_LIST                92
+# define SSL_CTRL_GET_SHARED_CURVE               93
+# define SSL_CTRL_SET_ECDH_AUTO                  94
+# define SSL_CTRL_SET_SIGALGS                    97
+# define SSL_CTRL_SET_SIGALGS_LIST               98
+# define SSL_CTRL_CERT_FLAGS                     99
+# define SSL_CTRL_CLEAR_CERT_FLAGS               100
+# define SSL_CTRL_SET_CLIENT_SIGALGS             101
+# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST        102
+# define SSL_CTRL_GET_CLIENT_CERT_TYPES          103
+# define SSL_CTRL_SET_CLIENT_CERT_TYPES          104
+# define SSL_CTRL_BUILD_CERT_CHAIN               105
+# define SSL_CTRL_SET_VERIFY_CERT_STORE          106
+# define SSL_CTRL_SET_CHAIN_CERT_STORE           107
+# define SSL_CTRL_GET_PEER_SIGNATURE_NID         108
+# define SSL_CTRL_GET_SERVER_TMP_KEY             109
+# define SSL_CTRL_GET_RAW_CIPHERLIST             110
+# define SSL_CTRL_GET_EC_POINT_FORMATS           111
+# define SSL_CTRL_GET_CHAIN_CERTS                115
+# define SSL_CTRL_SELECT_CURRENT_CERT            116
+# define SSL_CTRL_SET_CURRENT_CERT               117
+# define SSL_CTRL_CHECK_PROTO_VERSION            119
+# define DTLS_CTRL_SET_LINK_MTU                  120
+# define DTLS_CTRL_GET_LINK_MIN_MTU              121
+# define SSL_CERT_SET_FIRST                      1
+# define SSL_CERT_SET_NEXT                       2
+# define SSL_CERT_SET_SERVER                     3
+# define DTLSv1_get_timeout(ssl, arg) \
+        SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
+# define DTLSv1_handle_timeout(ssl) \
+        SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
+# define DTLSv1_listen(ssl, peer) \
+        SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
+# define SSL_session_reused(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
+# define SSL_num_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
+# define SSL_clear_num_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
+# define SSL_total_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
+# define SSL_CTX_need_tmp_RSA(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+# define SSL_CTX_set_tmp_rsa(ctx,rsa) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+# define SSL_CTX_set_tmp_dh(ctx,dh) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+# define SSL_need_tmp_RSA(ssl) \
+        SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+# define SSL_set_tmp_rsa(ssl,rsa) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+# define SSL_set_tmp_dh(ssl,dh) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+# define SSL_set_tmp_ecdh(ssl,ecdh) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+# define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+# define SSL_CTX_get_extra_chain_certs(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
+# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509)
+# define SSL_CTX_clear_extra_chain_certs(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
+# define SSL_CTX_set0_chain(ctx,sk) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
+# define SSL_CTX_set1_chain(ctx,sk) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
+# define SSL_CTX_add0_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
+# define SSL_CTX_add1_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
+# define SSL_CTX_get0_chain_certs(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
+# define SSL_CTX_clear_chain_certs(ctx) \
+        SSL_CTX_set0_chain(ctx,NULL)
+# define SSL_CTX_build_cert_chain(ctx, flags) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
+# define SSL_CTX_select_current_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
+# define SSL_CTX_set_current_cert(ctx, op) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+# define SSL_CTX_set0_verify_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
+# define SSL_CTX_set1_verify_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
+# define SSL_CTX_set0_chain_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
+# define SSL_CTX_set1_chain_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
+# define SSL_set0_chain(ctx,sk) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
+# define SSL_set1_chain(ctx,sk) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
+# define SSL_add0_chain_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
+# define SSL_add1_chain_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
+# define SSL_get0_chain_certs(ctx,px509) \
+        SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
+# define SSL_clear_chain_certs(ctx) \
+        SSL_set0_chain(ctx,NULL)
+# define SSL_build_cert_chain(s, flags) \
+        SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
+# define SSL_select_current_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
+# define SSL_set_current_cert(ctx,op) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+# define SSL_set0_verify_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
+# define SSL_set1_verify_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
+# define SSL_set0_chain_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
+# define SSL_set1_chain_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
+# define SSL_get1_curves(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s)
+# define SSL_CTX_set1_curves(ctx, clist, clistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
+# define SSL_CTX_set1_curves_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
+# define SSL_set1_curves(ctx, clist, clistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
+# define SSL_set1_curves_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
+# define SSL_get_shared_curve(s, n) \
+        SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL)
+# define SSL_CTX_set_ecdh_auto(ctx, onoff) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
+# define SSL_set_ecdh_auto(s, onoff) \
+        SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
+# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
+# define SSL_CTX_set1_sigalgs_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
+# define SSL_set1_sigalgs(ctx, slist, slistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
+# define SSL_set1_sigalgs_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
+# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist)
+# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
+# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist)
+# define SSL_set1_client_sigalgs_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
+# define SSL_get0_certificate_types(s, clist) \
+        SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
+# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
+# define SSL_set1_client_certificate_types(s, clist, clistlen) \
+        SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
+# define SSL_get_peer_signature_nid(s, pn) \
+        SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn)
+# define SSL_get_server_tmp_key(s, pk) \
+        SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
+# define SSL_get0_raw_cipherlist(s, plst) \
+        SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,(char *)plst)
+# define SSL_get0_ec_point_formats(s, plst) \
+        SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,(char *)plst)
+# ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_ssl(void);
+BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+int BIO_ssl_copy_session_id(BIO *to, BIO *from);
+void BIO_ssl_shutdown(BIO *ssl_bio);
+
+# endif
+
+int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
+void SSL_CTX_free(SSL_CTX *);
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
+int SSL_want(const SSL *s);
+int SSL_clear(SSL *s);
+
+void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
+
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits);
+char *SSL_CIPHER_get_version(const SSL_CIPHER *c);
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *c);
+unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
+
+int SSL_get_fd(const SSL *s);
+int SSL_get_rfd(const SSL *s);
+int SSL_get_wfd(const SSL *s);
+const char *SSL_get_cipher_list(const SSL *s, int n);
+char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+int SSL_get_read_ahead(const SSL *s);
+int SSL_pending(const SSL *s);
+# ifndef OPENSSL_NO_SOCK
+int SSL_set_fd(SSL *s, int fd);
+int SSL_set_rfd(SSL *s, int fd);
+int SSL_set_wfd(SSL *s, int fd);
+# endif
+# ifndef OPENSSL_NO_BIO
+void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
+BIO *SSL_get_rbio(const SSL *s);
+BIO *SSL_get_wbio(const SSL *s);
+# endif
+int SSL_set_cipher_list(SSL *s, const char *str);
+void SSL_set_read_ahead(SSL *s, int yes);
+int SSL_get_verify_mode(const SSL *s);
+int SSL_get_verify_depth(const SSL *s);
+int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *);
+void SSL_set_verify(SSL *s, int mode,
+                    int (*callback) (int ok, X509_STORE_CTX *ctx));
+void SSL_set_verify_depth(SSL *s, int depth);
+void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg);
+# ifndef OPENSSL_NO_RSA
+int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+# endif
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d,
+                            long len);
+int SSL_use_certificate(SSL *ssl, X509 *x);
+int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+
+# ifndef OPENSSL_NO_TLSEXT
+/* Set serverinfo data for the current active cert. */
+int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
+                           size_t serverinfo_length);
+#  ifndef OPENSSL_NO_STDIO
+int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file);
+#  endif                        /* NO_STDIO */
+
+# endif
+
+# ifndef OPENSSL_NO_STDIO
+int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+/* PEM type */
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+                                        const char *file);
+#  ifndef OPENSSL_SYS_VMS
+/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
+#   ifndef OPENSSL_SYS_MACINTOSH_CLASSIC
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+                                       const char *dir);
+#   endif
+#  endif
+
+# endif
+
+void SSL_load_error_strings(void);
+const char *SSL_state_string(const SSL *s);
+const char *SSL_rstate_string(const SSL *s);
+const char *SSL_state_string_long(const SSL *s);
+const char *SSL_rstate_string_long(const SSL *s);
+long SSL_SESSION_get_time(const SSL_SESSION *s);
+long SSL_SESSION_set_time(SSL_SESSION *s, long t);
+long SSL_SESSION_get_timeout(const SSL_SESSION *s);
+long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+void SSL_copy_session_id(SSL *to, const SSL *from);
+X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
+int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
+                                unsigned int sid_ctx_len);
+
+SSL_SESSION *SSL_SESSION_new(void);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+                                        unsigned int *len);
+unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
+# ifndef OPENSSL_NO_FP_API
+int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
+# endif
+# ifndef OPENSSL_NO_BIO
+int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
+# endif
+void SSL_SESSION_free(SSL_SESSION *ses);
+int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+int SSL_set_session(SSL *to, SSL_SESSION *session);
+int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
+int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+                                unsigned int id_len);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+                             long length);
+
+# ifdef HEADER_X509_H
+X509 *SSL_get_peer_certificate(const SSL *s);
+# endif
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int,
+                                                        X509_STORE_CTX *);
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
+                        int (*callback) (int, X509_STORE_CTX *));
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
+                                      int (*cb) (X509_STORE_CTX *, void *),
+                                      void *arg);
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg),
+                         void *arg);
+# ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+# endif
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
+                                   long len);
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
+                                const unsigned char *d, long len);
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+                                 const unsigned char *d);
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+
+int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+int SSL_check_private_key(const SSL *ctx);
+
+int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
+                                   unsigned int sid_ctx_len);
+
+SSL *SSL_new(SSL_CTX *ctx);
+int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
+                               unsigned int sid_ctx_len);
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+int SSL_set_purpose(SSL *s, int purpose);
+int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+int SSL_set_trust(SSL *s, int trust);
+
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+
+X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+
+# ifndef OPENSSL_NO_SRP
+int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name);
+int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password);
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
+                                        char *(*cb) (SSL *, void *));
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
+                                          int (*cb) (SSL *, void *));
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+                                      int (*cb) (SSL *, int *, void *));
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+                             BIGNUM *sa, BIGNUM *v, char *info);
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
+                                const char *grp);
+
+BIGNUM *SSL_get_srp_g(SSL *s);
+BIGNUM *SSL_get_srp_N(SSL *s);
+
+char *SSL_get_srp_username(SSL *s);
+char *SSL_get_srp_userinfo(SSL *s);
+# endif
+
+void SSL_certs_clear(SSL *s);
+void SSL_free(SSL *ssl);
+int SSL_accept(SSL *ssl);
+int SSL_connect(SSL *ssl);
+int SSL_read(SSL *ssl, void *buf, int num);
+int SSL_peek(SSL *ssl, void *buf, int num);
+int SSL_write(SSL *ssl, const void *buf, int num);
+long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
+long SSL_callback_ctrl(SSL *, int, void (*)(void));
+long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
+long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+
+int SSL_get_error(const SSL *s, int ret_code);
+const char *SSL_get_version(const SSL *s);
+
+/* This sets the 'default' SSL version that SSL_new() will create */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+# ifndef OPENSSL_NO_SSL2_METHOD
+const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
+const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
+const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
+# endif
+
+# ifndef OPENSSL_NO_SSL3_METHOD
+const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
+const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
+const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
+# endif
+
+const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS
+                                        * version */
+const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available
+                                               * SSL/TLS version */
+const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available
+                                               * SSL/TLS version */
+
+const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
+const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
+const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
+
+const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
+const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */
+
+const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
+const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */
+
+const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
+const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */
+
+const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */
+const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */
+const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */
+
+const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */
+const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */
+const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */
+
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+
+int SSL_do_handshake(SSL *s);
+int SSL_renegotiate(SSL *s);
+int SSL_renegotiate_abbreviated(SSL *s);
+int SSL_renegotiate_pending(SSL *s);
+int SSL_shutdown(SSL *s);
+
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
+const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
+const char *SSL_alert_type_string_long(int value);
+const char *SSL_alert_type_string(int value);
+const char *SSL_alert_desc_string_long(int value);
+const char *SSL_alert_desc_string(int value);
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+int SSL_add_client_CA(SSL *ssl, X509 *x);
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
+
+void SSL_set_connect_state(SSL *s);
+void SSL_set_accept_state(SSL *s);
+
+long SSL_get_default_timeout(const SSL *s);
+
+int SSL_library_init(void);
+
+char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size);
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+
+SSL *SSL_dup(SSL *ssl);
+
+X509 *SSL_get_certificate(const SSL *ssl);
+/*
+ * EVP_PKEY
+ */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl);
+
+X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+int SSL_get_quiet_shutdown(const SSL *ssl);
+void SSL_set_shutdown(SSL *ssl, int mode);
+int SSL_get_shutdown(const SSL *ssl);
+int SSL_version(const SSL *ssl);
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                                  const char *CApath);
+# define SSL_get0_session SSL_get_session/* just peek at pointer */
+SSL_SESSION *SSL_get_session(const SSL *ssl);
+SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
+void SSL_set_info_callback(SSL *ssl,
+                           void (*cb) (const SSL *ssl, int type, int val));
+void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type,
+                                               int val);
+int SSL_state(const SSL *ssl);
+void SSL_set_state(SSL *ssl, int state);
+
+void SSL_set_verify_result(SSL *ssl, long v);
+long SSL_get_verify_result(const SSL *ssl);
+
+int SSL_set_ex_data(SSL *ssl, int idx, void *data);
+void *SSL_get_ex_data(const SSL *ssl, int idx);
+int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data);
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
+int SSL_SESSION_get_ex_new_index(long argl, void *argp,
+                                 CRYPTO_EX_new *new_func,
+                                 CRYPTO_EX_dup *dup_func,
+                                 CRYPTO_EX_free *free_func);
+
+int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
+int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                             CRYPTO_EX_dup *dup_func,
+                             CRYPTO_EX_free *free_func);
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+# define SSL_CTX_sess_set_cache_size(ctx,t) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+# define SSL_CTX_sess_get_cache_size(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+# define SSL_CTX_set_session_cache_mode(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+# define SSL_CTX_get_session_cache_mode(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+
+# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
+# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
+# define SSL_CTX_get_read_ahead(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
+# define SSL_CTX_set_read_ahead(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+# define SSL_CTX_get_max_cert_list(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+# define SSL_CTX_set_max_cert_list(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+# define SSL_get_max_cert_list(ssl) \
+        SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+# define SSL_set_max_cert_list(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+
+# define SSL_CTX_set_max_send_fragment(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+# define SSL_set_max_send_fragment(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+
+     /* NB: the keylength is only applicable when is_export is true */
+# ifndef OPENSSL_NO_RSA
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+                                  RSA *(*cb) (SSL *ssl, int is_export,
+                                              int keylength));
+
+void SSL_set_tmp_rsa_callback(SSL *ssl,
+                              RSA *(*cb) (SSL *ssl, int is_export,
+                                          int keylength));
+# endif
+# ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+                                 DH *(*dh) (SSL *ssl, int is_export,
+                                            int keylength));
+void SSL_set_tmp_dh_callback(SSL *ssl,
+                             DH *(*dh) (SSL *ssl, int is_export,
+                                        int keylength));
+# endif
+# ifndef OPENSSL_NO_ECDH
+void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
+                                   EC_KEY *(*ecdh) (SSL *ssl, int is_export,
+                                                    int keylength));
+void SSL_set_tmp_ecdh_callback(SSL *ssl,
+                               EC_KEY *(*ecdh) (SSL *ssl, int is_export,
+                                                int keylength));
+# endif
+
+# ifndef OPENSSL_NO_COMP
+const COMP_METHOD *SSL_get_current_compression(SSL *s);
+const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
+STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
+                                                      *meths);
+void SSL_COMP_free_compression_methods(void);
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
+# else
+const void *SSL_get_current_compression(SSL *s);
+const void *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const void *comp);
+void *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id, void *cm);
+# endif
+
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
+
+/* TLS extensions functions */
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+                                  void *arg);
+
+/* Pre-shared secret session resumption functions */
+int SSL_set_session_secret_cb(SSL *s,
+                              tls_session_secret_cb_fn tls_session_secret_cb,
+                              void *arg);
+
+void SSL_set_debug(SSL *s, int debug);
+int SSL_cache_hit(SSL *s);
+int SSL_is_server(SSL *s);
+
+SSL_CONF_CTX *SSL_CONF_CTX_new(void);
+int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx);
+void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
+unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre);
+
+void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
+void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);
+
+int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value);
+int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
+int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd);
+
+# ifndef OPENSSL_NO_SSL_TRACE
+void SSL_trace(int write_p, int version, int content_type,
+               const void *buf, size_t len, SSL *ssl, void *arg);
+const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
+# endif
+
+# ifndef OPENSSL_NO_UNIT_TEST
+const struct openssl_ssl_test_functions *SSL_test_functions(void);
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_SSL_strings(void);
+
+/* Error codes for the SSL functions. */
+
+/* Function codes. */
+# define SSL_F_CHECK_SUITEB_CIPHER_LIST                   331
+# define SSL_F_CLIENT_CERTIFICATE                         100
+# define SSL_F_CLIENT_FINISHED                            167
+# define SSL_F_CLIENT_HELLO                               101
+# define SSL_F_CLIENT_MASTER_KEY                          102
+# define SSL_F_D2I_SSL_SESSION                            103
+# define SSL_F_DO_DTLS1_WRITE                             245
+# define SSL_F_DO_SSL3_WRITE                              104
+# define SSL_F_DTLS1_ACCEPT                               246
+# define SSL_F_DTLS1_ADD_CERT_TO_BUF                      295
+# define SSL_F_DTLS1_BUFFER_RECORD                        247
+# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM                    316
+# define SSL_F_DTLS1_CLIENT_HELLO                         248
+# define SSL_F_DTLS1_CONNECT                              249
+# define SSL_F_DTLS1_ENC                                  250
+# define SSL_F_DTLS1_GET_HELLO_VERIFY                     251
+# define SSL_F_DTLS1_GET_MESSAGE                          252
+# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT                 253
+# define SSL_F_DTLS1_GET_RECORD                           254
+# define SSL_F_DTLS1_HANDLE_TIMEOUT                       297
+# define SSL_F_DTLS1_HEARTBEAT                            305
+# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN                    255
+# define SSL_F_DTLS1_PREPROCESS_FRAGMENT                  288
+# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE           256
+# define SSL_F_DTLS1_PROCESS_RECORD                       257
+# define SSL_F_DTLS1_READ_BYTES                           258
+# define SSL_F_DTLS1_READ_FAILED                          259
+# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST             260
+# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE              261
+# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE             262
+# define SSL_F_DTLS1_SEND_CLIENT_VERIFY                   263
+# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST            264
+# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE              265
+# define SSL_F_DTLS1_SEND_SERVER_HELLO                    266
+# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE             267
+# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES                 268
+# define SSL_F_GET_CLIENT_FINISHED                        105
+# define SSL_F_GET_CLIENT_HELLO                           106
+# define SSL_F_GET_CLIENT_MASTER_KEY                      107
+# define SSL_F_GET_SERVER_FINISHED                        108
+# define SSL_F_GET_SERVER_HELLO                           109
+# define SSL_F_GET_SERVER_STATIC_DH_KEY                   340
+# define SSL_F_GET_SERVER_VERIFY                          110
+# define SSL_F_I2D_SSL_SESSION                            111
+# define SSL_F_READ_N                                     112
+# define SSL_F_REQUEST_CERTIFICATE                        113
+# define SSL_F_SERVER_FINISH                              239
+# define SSL_F_SERVER_HELLO                               114
+# define SSL_F_SERVER_VERIFY                              240
+# define SSL_F_SSL23_ACCEPT                               115
+# define SSL_F_SSL23_CLIENT_HELLO                         116
+# define SSL_F_SSL23_CONNECT                              117
+# define SSL_F_SSL23_GET_CLIENT_HELLO                     118
+# define SSL_F_SSL23_GET_SERVER_HELLO                     119
+# define SSL_F_SSL23_PEEK                                 237
+# define SSL_F_SSL23_READ                                 120
+# define SSL_F_SSL23_WRITE                                121
+# define SSL_F_SSL2_ACCEPT                                122
+# define SSL_F_SSL2_CONNECT                               123
+# define SSL_F_SSL2_ENC_INIT                              124
+# define SSL_F_SSL2_GENERATE_KEY_MATERIAL                 241
+# define SSL_F_SSL2_PEEK                                  234
+# define SSL_F_SSL2_READ                                  125
+# define SSL_F_SSL2_READ_INTERNAL                         236
+# define SSL_F_SSL2_SET_CERTIFICATE                       126
+# define SSL_F_SSL2_WRITE                                 127
+# define SSL_F_SSL3_ACCEPT                                128
+# define SSL_F_SSL3_ADD_CERT_TO_BUF                       296
+# define SSL_F_SSL3_CALLBACK_CTRL                         233
+# define SSL_F_SSL3_CHANGE_CIPHER_STATE                   129
+# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM              130
+# define SSL_F_SSL3_CHECK_CLIENT_HELLO                    304
+# define SSL_F_SSL3_CHECK_FINISHED                        339
+# define SSL_F_SSL3_CLIENT_HELLO                          131
+# define SSL_F_SSL3_CONNECT                               132
+# define SSL_F_SSL3_CTRL                                  213
+# define SSL_F_SSL3_CTX_CTRL                              133
+# define SSL_F_SSL3_DIGEST_CACHED_RECORDS                 293
+# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC                 292
+# define SSL_F_SSL3_ENC                                   134
+# define SSL_F_SSL3_GENERATE_KEY_BLOCK                    238
+# define SSL_F_SSL3_GENERATE_MASTER_SECRET                388
+# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST               135
+# define SSL_F_SSL3_GET_CERT_STATUS                       289
+# define SSL_F_SSL3_GET_CERT_VERIFY                       136
+# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE                137
+# define SSL_F_SSL3_GET_CLIENT_HELLO                      138
+# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE               139
+# define SSL_F_SSL3_GET_FINISHED                          140
+# define SSL_F_SSL3_GET_KEY_EXCHANGE                      141
+# define SSL_F_SSL3_GET_MESSAGE                           142
+# define SSL_F_SSL3_GET_NEW_SESSION_TICKET                283
+# define SSL_F_SSL3_GET_NEXT_PROTO                        306
+# define SSL_F_SSL3_GET_RECORD                            143
+# define SSL_F_SSL3_GET_SERVER_CERTIFICATE                144
+# define SSL_F_SSL3_GET_SERVER_DONE                       145
+# define SSL_F_SSL3_GET_SERVER_HELLO                      146
+# define SSL_F_SSL3_HANDSHAKE_MAC                         285
+# define SSL_F_SSL3_NEW_SESSION_TICKET                    287
+# define SSL_F_SSL3_OUTPUT_CERT_CHAIN                     147
+# define SSL_F_SSL3_PEEK                                  235
+# define SSL_F_SSL3_READ_BYTES                            148
+# define SSL_F_SSL3_READ_N                                149
+# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST              150
+# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE               151
+# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE              152
+# define SSL_F_SSL3_SEND_CLIENT_VERIFY                    153
+# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE               154
+# define SSL_F_SSL3_SEND_SERVER_HELLO                     242
+# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE              155
+# define SSL_F_SSL3_SETUP_KEY_BLOCK                       157
+# define SSL_F_SSL3_SETUP_READ_BUFFER                     156
+# define SSL_F_SSL3_SETUP_WRITE_BUFFER                    291
+# define SSL_F_SSL3_WRITE_BYTES                           158
+# define SSL_F_SSL3_WRITE_PENDING                         159
+# define SSL_F_SSL_ADD_CERT_CHAIN                         318
+# define SSL_F_SSL_ADD_CERT_TO_BUF                        319
+# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT        298
+# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT                 277
+# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT           307
+# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK         215
+# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK        216
+# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT        299
+# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT                 278
+# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT           308
+# define SSL_F_SSL_BAD_METHOD                             160
+# define SSL_F_SSL_BUILD_CERT_CHAIN                       332
+# define SSL_F_SSL_BYTES_TO_CIPHER_LIST                   161
+# define SSL_F_SSL_CERT_DUP                               221
+# define SSL_F_SSL_CERT_INST                              222
+# define SSL_F_SSL_CERT_INSTANTIATE                       214
+# define SSL_F_SSL_CERT_NEW                               162
+# define SSL_F_SSL_CHECK_PRIVATE_KEY                      163
+# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT               280
+# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG            279
+# define SSL_F_SSL_CIPHER_PROCESS_RULESTR                 230
+# define SSL_F_SSL_CIPHER_STRENGTH_SORT                   231
+# define SSL_F_SSL_CLEAR                                  164
+# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD            165
+# define SSL_F_SSL_CONF_CMD                               334
+# define SSL_F_SSL_CREATE_CIPHER_LIST                     166
+# define SSL_F_SSL_CTRL                                   232
+# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY                  168
+# define SSL_F_SSL_CTX_MAKE_PROFILES                      309
+# define SSL_F_SSL_CTX_NEW                                169
+# define SSL_F_SSL_CTX_SET_CIPHER_LIST                    269
+# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE             290
+# define SSL_F_SSL_CTX_SET_PURPOSE                        226
+# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT             219
+# define SSL_F_SSL_CTX_SET_SSL_VERSION                    170
+# define SSL_F_SSL_CTX_SET_TRUST                          229
+# define SSL_F_SSL_CTX_USE_CERTIFICATE                    171
+# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1               172
+# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE         220
+# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE               173
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY                     174
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1                175
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE                176
+# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT              272
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY                  177
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1             178
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE             179
+# define SSL_F_SSL_CTX_USE_SERVERINFO                     336
+# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE                337
+# define SSL_F_SSL_DO_HANDSHAKE                           180
+# define SSL_F_SSL_GET_NEW_SESSION                        181
+# define SSL_F_SSL_GET_PREV_SESSION                       217
+# define SSL_F_SSL_GET_SERVER_CERT_INDEX                  322
+# define SSL_F_SSL_GET_SERVER_SEND_CERT                   182
+# define SSL_F_SSL_GET_SERVER_SEND_PKEY                   317
+# define SSL_F_SSL_GET_SIGN_PKEY                          183
+# define SSL_F_SSL_INIT_WBIO_BUFFER                       184
+# define SSL_F_SSL_LOAD_CLIENT_CA_FILE                    185
+# define SSL_F_SSL_NEW                                    186
+# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT      300
+# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT               302
+# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT         310
+# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT      301
+# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT               303
+# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT         311
+# define SSL_F_SSL_PEEK                                   270
+# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT             281
+# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT             282
+# define SSL_F_SSL_READ                                   223
+# define SSL_F_SSL_RSA_PRIVATE_DECRYPT                    187
+# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT                     188
+# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT                320
+# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT                321
+# define SSL_F_SSL_SESSION_DUP                            348
+# define SSL_F_SSL_SESSION_NEW                            189
+# define SSL_F_SSL_SESSION_PRINT_FP                       190
+# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT                312
+# define SSL_F_SSL_SESS_CERT_NEW                          225
+# define SSL_F_SSL_SET_CERT                               191
+# define SSL_F_SSL_SET_CIPHER_LIST                        271
+# define SSL_F_SSL_SET_FD                                 192
+# define SSL_F_SSL_SET_PKEY                               193
+# define SSL_F_SSL_SET_PURPOSE                            227
+# define SSL_F_SSL_SET_RFD                                194
+# define SSL_F_SSL_SET_SESSION                            195
+# define SSL_F_SSL_SET_SESSION_ID_CONTEXT                 218
+# define SSL_F_SSL_SET_SESSION_TICKET_EXT                 294
+# define SSL_F_SSL_SET_TRUST                              228
+# define SSL_F_SSL_SET_WFD                                196
+# define SSL_F_SSL_SHUTDOWN                               224
+# define SSL_F_SSL_SRP_CTX_INIT                           313
+# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION               243
+# define SSL_F_SSL_UNDEFINED_FUNCTION                     197
+# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION                244
+# define SSL_F_SSL_USE_CERTIFICATE                        198
+# define SSL_F_SSL_USE_CERTIFICATE_ASN1                   199
+# define SSL_F_SSL_USE_CERTIFICATE_FILE                   200
+# define SSL_F_SSL_USE_PRIVATEKEY                         201
+# define SSL_F_SSL_USE_PRIVATEKEY_ASN1                    202
+# define SSL_F_SSL_USE_PRIVATEKEY_FILE                    203
+# define SSL_F_SSL_USE_PSK_IDENTITY_HINT                  273
+# define SSL_F_SSL_USE_RSAPRIVATEKEY                      204
+# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1                 205
+# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE                 206
+# define SSL_F_SSL_VERIFY_CERT_CHAIN                      207
+# define SSL_F_SSL_WRITE                                  208
+# define SSL_F_TLS12_CHECK_PEER_SIGALG                    333
+# define SSL_F_TLS1_CERT_VERIFY_MAC                       286
+# define SSL_F_TLS1_CHANGE_CIPHER_STATE                   209
+# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT              274
+# define SSL_F_TLS1_ENC                                   210
+# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL                314
+# define SSL_F_TLS1_GET_CURVELIST                         338
+# define SSL_F_TLS1_HEARTBEAT                             315
+# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT            275
+# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT            276
+# define SSL_F_TLS1_PRF                                   284
+# define SSL_F_TLS1_SETUP_KEY_BLOCK                       211
+# define SSL_F_TLS1_SET_SERVER_SIGALGS                    335
+# define SSL_F_WRITE_PENDING                              212
+
+/* Reason codes. */
+# define SSL_R_APP_DATA_IN_HANDSHAKE                      100
+# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
+# define SSL_R_BAD_ALERT_RECORD                           101
+# define SSL_R_BAD_AUTHENTICATION_TYPE                    102
+# define SSL_R_BAD_CHANGE_CIPHER_SPEC                     103
+# define SSL_R_BAD_CHECKSUM                               104
+# define SSL_R_BAD_DATA                                   390
+# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK              106
+# define SSL_R_BAD_DECOMPRESSION                          107
+# define SSL_R_BAD_DH_G_LENGTH                            108
+# define SSL_R_BAD_DH_G_VALUE                             375
+# define SSL_R_BAD_DH_PUB_KEY_LENGTH                      109
+# define SSL_R_BAD_DH_PUB_KEY_VALUE                       393
+# define SSL_R_BAD_DH_P_LENGTH                            110
+# define SSL_R_BAD_DH_P_VALUE                             395
+# define SSL_R_BAD_DIGEST_LENGTH                          111
+# define SSL_R_BAD_DSA_SIGNATURE                          112
+# define SSL_R_BAD_ECC_CERT                               304
+# define SSL_R_BAD_ECDSA_SIGNATURE                        305
+# define SSL_R_BAD_ECPOINT                                306
+# define SSL_R_BAD_HANDSHAKE_LENGTH                       332
+# define SSL_R_BAD_HELLO_REQUEST                          105
+# define SSL_R_BAD_LENGTH                                 271
+# define SSL_R_BAD_MAC_DECODE                             113
+# define SSL_R_BAD_MAC_LENGTH                             333
+# define SSL_R_BAD_MESSAGE_TYPE                           114
+# define SSL_R_BAD_PACKET_LENGTH                          115
+# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER                116
+# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH               316
+# define SSL_R_BAD_RESPONSE_ARGUMENT                      117
+# define SSL_R_BAD_RSA_DECRYPT                            118
+# define SSL_R_BAD_RSA_ENCRYPT                            119
+# define SSL_R_BAD_RSA_E_LENGTH                           120
+# define SSL_R_BAD_RSA_MODULUS_LENGTH                     121
+# define SSL_R_BAD_RSA_SIGNATURE                          122
+# define SSL_R_BAD_SIGNATURE                              123
+# define SSL_R_BAD_SRP_A_LENGTH                           347
+# define SSL_R_BAD_SRP_B_LENGTH                           348
+# define SSL_R_BAD_SRP_G_LENGTH                           349
+# define SSL_R_BAD_SRP_N_LENGTH                           350
+# define SSL_R_BAD_SRP_PARAMETERS                         371
+# define SSL_R_BAD_SRP_S_LENGTH                           351
+# define SSL_R_BAD_SRTP_MKI_VALUE                         352
+# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST           353
+# define SSL_R_BAD_SSL_FILETYPE                           124
+# define SSL_R_BAD_SSL_SESSION_ID_LENGTH                  125
+# define SSL_R_BAD_STATE                                  126
+# define SSL_R_BAD_VALUE                                  384
+# define SSL_R_BAD_WRITE_RETRY                            127
+# define SSL_R_BIO_NOT_SET                                128
+# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  129
+# define SSL_R_BN_LIB                                     130
+# define SSL_R_CA_DN_LENGTH_MISMATCH                      131
+# define SSL_R_CA_DN_TOO_LONG                             132
+# define SSL_R_CCS_RECEIVED_EARLY                         133
+# define SSL_R_CERTIFICATE_VERIFY_FAILED                  134
+# define SSL_R_CERT_CB_ERROR                              377
+# define SSL_R_CERT_LENGTH_MISMATCH                       135
+# define SSL_R_CHALLENGE_IS_DIFFERENT                     136
+# define SSL_R_CIPHER_CODE_WRONG_LENGTH                   137
+# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE                 138
+# define SSL_R_CIPHER_TABLE_SRC_ERROR                     139
+# define SSL_R_CLIENTHELLO_TLSEXT                         226
+# define SSL_R_COMPRESSED_LENGTH_TOO_LONG                 140
+# define SSL_R_COMPRESSION_DISABLED                       343
+# define SSL_R_COMPRESSION_FAILURE                        141
+# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE    307
+# define SSL_R_COMPRESSION_LIBRARY_ERROR                  142
+# define SSL_R_CONNECTION_ID_IS_DIFFERENT                 143
+# define SSL_R_CONNECTION_TYPE_NOT_SET                    144
+# define SSL_R_COOKIE_MISMATCH                            308
+# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              145
+# define SSL_R_DATA_LENGTH_TOO_LONG                       146
+# define SSL_R_DECRYPTION_FAILED                          147
+# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        281
+# define SSL_R_DH_KEY_TOO_SMALL                           372
+# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG            148
+# define SSL_R_DIGEST_CHECK_FAILED                        149
+# define SSL_R_DTLS_MESSAGE_TOO_BIG                       334
+# define SSL_R_DUPLICATE_COMPRESSION_ID                   309
+# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT             317
+# define SSL_R_ECC_CERT_NOT_FOR_SIGNING                   318
+# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE         322
+# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE        323
+# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE              374
+# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER               310
+# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST         354
+# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  150
+# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY               282
+# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              151
+# define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
+# define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
+# define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
+# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS                355
+# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION           356
+# define SSL_R_HTTPS_PROXY_REQUEST                        155
+# define SSL_R_HTTP_REQUEST                               156
+# define SSL_R_ILLEGAL_PADDING                            283
+# define SSL_R_ILLEGAL_SUITEB_DIGEST                      380
+# define SSL_R_INAPPROPRIATE_FALLBACK                     373
+# define SSL_R_INCONSISTENT_COMPRESSION                   340
+# define SSL_R_INVALID_CHALLENGE_LENGTH                   158
+# define SSL_R_INVALID_COMMAND                            280
+# define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
+# define SSL_R_INVALID_NULL_CMD_NAME                      385
+# define SSL_R_INVALID_PURPOSE                            278
+# define SSL_R_INVALID_SERVERINFO_DATA                    388
+# define SSL_R_INVALID_SRP_USERNAME                       357
+# define SSL_R_INVALID_STATUS_RESPONSE                    328
+# define SSL_R_INVALID_TICKET_KEYS_LENGTH                 325
+# define SSL_R_INVALID_TRUST                              279
+# define SSL_R_KEY_ARG_TOO_LONG                           284
+# define SSL_R_KRB5                                       285
+# define SSL_R_KRB5_C_CC_PRINC                            286
+# define SSL_R_KRB5_C_GET_CRED                            287
+# define SSL_R_KRB5_C_INIT                                288
+# define SSL_R_KRB5_C_MK_REQ                              289
+# define SSL_R_KRB5_S_BAD_TICKET                          290
+# define SSL_R_KRB5_S_INIT                                291
+# define SSL_R_KRB5_S_RD_REQ                              292
+# define SSL_R_KRB5_S_TKT_EXPIRED                         293
+# define SSL_R_KRB5_S_TKT_NYV                             294
+# define SSL_R_KRB5_S_TKT_SKEW                            295
+# define SSL_R_LENGTH_MISMATCH                            159
+# define SSL_R_LENGTH_TOO_SHORT                           160
+# define SSL_R_LIBRARY_BUG                                274
+# define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
+# define SSL_R_MESSAGE_TOO_LONG                           296
+# define SSL_R_MISSING_DH_DSA_CERT                        162
+# define SSL_R_MISSING_DH_KEY                             163
+# define SSL_R_MISSING_DH_RSA_CERT                        164
+# define SSL_R_MISSING_DSA_SIGNING_CERT                   165
+# define SSL_R_MISSING_ECDH_CERT                          382
+# define SSL_R_MISSING_ECDSA_SIGNING_CERT                 381
+# define SSL_R_MISSING_EXPORT_TMP_DH_KEY                  166
+# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY                 167
+# define SSL_R_MISSING_RSA_CERTIFICATE                    168
+# define SSL_R_MISSING_RSA_ENCRYPTING_CERT                169
+# define SSL_R_MISSING_RSA_SIGNING_CERT                   170
+# define SSL_R_MISSING_SRP_PARAM                          358
+# define SSL_R_MISSING_TMP_DH_KEY                         171
+# define SSL_R_MISSING_TMP_ECDH_KEY                       311
+# define SSL_R_MISSING_TMP_RSA_KEY                        172
+# define SSL_R_MISSING_TMP_RSA_PKEY                       173
+# define SSL_R_MISSING_VERIFY_MESSAGE                     174
+# define SSL_R_MULTIPLE_SGC_RESTARTS                      346
+# define SSL_R_NON_SSLV2_INITIAL_PACKET                   175
+# define SSL_R_NO_CERTIFICATES_RETURNED                   176
+# define SSL_R_NO_CERTIFICATE_ASSIGNED                    177
+# define SSL_R_NO_CERTIFICATE_RETURNED                    178
+# define SSL_R_NO_CERTIFICATE_SET                         179
+# define SSL_R_NO_CERTIFICATE_SPECIFIED                   180
+# define SSL_R_NO_CIPHERS_AVAILABLE                       181
+# define SSL_R_NO_CIPHERS_PASSED                          182
+# define SSL_R_NO_CIPHERS_SPECIFIED                       183
+# define SSL_R_NO_CIPHER_LIST                             184
+# define SSL_R_NO_CIPHER_MATCH                            185
+# define SSL_R_NO_CLIENT_CERT_METHOD                      331
+# define SSL_R_NO_CLIENT_CERT_RECEIVED                    186
+# define SSL_R_NO_COMPRESSION_SPECIFIED                   187
+# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER           330
+# define SSL_R_NO_METHOD_SPECIFIED                        188
+# define SSL_R_NO_PEM_EXTENSIONS                          389
+# define SSL_R_NO_PRIVATEKEY                              189
+# define SSL_R_NO_PRIVATE_KEY_ASSIGNED                    190
+# define SSL_R_NO_PROTOCOLS_AVAILABLE                     191
+# define SSL_R_NO_PUBLICKEY                               192
+# define SSL_R_NO_RENEGOTIATION                           339
+# define SSL_R_NO_REQUIRED_DIGEST                         324
+# define SSL_R_NO_SHARED_CIPHER                           193
+# define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS              376
+# define SSL_R_NO_SRTP_PROFILES                           359
+# define SSL_R_NO_VERIFY_CALLBACK                         194
+# define SSL_R_NULL_SSL_CTX                               195
+# define SSL_R_NULL_SSL_METHOD_PASSED                     196
+# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED            197
+# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
+# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE       387
+# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE        379
+# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE              297
+# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG                  327
+# define SSL_R_PACKET_LENGTH_TOO_LONG                     198
+# define SSL_R_PARSE_TLSEXT                               227
+# define SSL_R_PATH_TOO_LONG                              270
+# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE          199
+# define SSL_R_PEER_ERROR                                 200
+# define SSL_R_PEER_ERROR_CERTIFICATE                     201
+# define SSL_R_PEER_ERROR_NO_CERTIFICATE                  202
+# define SSL_R_PEER_ERROR_NO_CIPHER                       203
+# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE    204
+# define SSL_R_PEM_NAME_BAD_PREFIX                        391
+# define SSL_R_PEM_NAME_TOO_SHORT                         392
+# define SSL_R_PRE_MAC_LENGTH_TOO_LONG                    205
+# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS          206
+# define SSL_R_PROTOCOL_IS_SHUTDOWN                       207
+# define SSL_R_PSK_IDENTITY_NOT_FOUND                     223
+# define SSL_R_PSK_NO_CLIENT_CB                           224
+# define SSL_R_PSK_NO_SERVER_CB                           225
+# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR                   208
+# define SSL_R_PUBLIC_KEY_IS_NOT_RSA                      209
+# define SSL_R_PUBLIC_KEY_NOT_RSA                         210
+# define SSL_R_READ_BIO_NOT_SET                           211
+# define SSL_R_READ_TIMEOUT_EXPIRED                       312
+# define SSL_R_READ_WRONG_PACKET_TYPE                     212
+# define SSL_R_RECORD_LENGTH_MISMATCH                     213
+# define SSL_R_RECORD_TOO_LARGE                           214
+# define SSL_R_RECORD_TOO_SMALL                           298
+# define SSL_R_RENEGOTIATE_EXT_TOO_LONG                   335
+# define SSL_R_RENEGOTIATION_ENCODING_ERR                 336
+# define SSL_R_RENEGOTIATION_MISMATCH                     337
+# define SSL_R_REQUIRED_CIPHER_MISSING                    215
+# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING    342
+# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO                 216
+# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO                   217
+# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO                 218
+# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           345
+# define SSL_R_SERVERHELLO_TLSEXT                         275
+# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED           277
+# define SSL_R_SHORT_READ                                 219
+# define SSL_R_SHUTDOWN_WHILE_IN_INIT                     407
+# define SSL_R_SIGNATURE_ALGORITHMS_ERROR                 360
+# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE      220
+# define SSL_R_SRP_A_CALC                                 361
+# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES           362
+# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG      363
+# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE            364
+# define SSL_R_SSL23_DOING_SESSION_ID_REUSE               221
+# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG                299
+# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT             321
+# define SSL_R_SSL3_EXT_INVALID_SERVERNAME                319
+# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE           320
+# define SSL_R_SSL3_SESSION_ID_TOO_LONG                   300
+# define SSL_R_SSL3_SESSION_ID_TOO_SHORT                  222
+# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE                1042
+# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC                 1020
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED            1045
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED            1044
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN            1046
+# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE          1030
+# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE              1040
+# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER              1047
+# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE                 1041
+# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE             1010
+# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE        1043
+# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION         228
+# define SSL_R_SSL_HANDSHAKE_FAILURE                      229
+# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS                 230
+# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED             301
+# define SSL_R_SSL_SESSION_ID_CONFLICT                    302
+# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG            273
+# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH              303
+# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT                231
+# define SSL_R_TLSV1_ALERT_ACCESS_DENIED                  1049
+# define SSL_R_TLSV1_ALERT_DECODE_ERROR                   1050
+# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED              1021
+# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR                  1051
+# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION             1060
+# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK         1086
+# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY          1071
+# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR                 1080
+# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION               1100
+# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION               1070
+# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW                1022
+# define SSL_R_TLSV1_ALERT_UNKNOWN_CA                     1048
+# define SSL_R_TLSV1_ALERT_USER_CANCELLED                 1090
+# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE           1114
+# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE      1113
+# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE             1111
+# define SSL_R_TLSV1_UNRECOGNIZED_NAME                    1112
+# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION                1110
+# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER       232
+# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT           365
+# define SSL_R_TLS_HEARTBEAT_PENDING                      366
+# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL                 367
+# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
+# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
+# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    234
+# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER            235
+# define SSL_R_UNABLE_TO_DECODE_DH_CERTS                  236
+# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS                313
+# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY               237
+# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS               238
+# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS             314
+# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS       239
+# define SSL_R_UNABLE_TO_FIND_SSL_METHOD                  240
+# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES           241
+# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES           242
+# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES          243
+# define SSL_R_UNEXPECTED_MESSAGE                         244
+# define SSL_R_UNEXPECTED_RECORD                          245
+# define SSL_R_UNINITIALIZED                              276
+# define SSL_R_UNKNOWN_ALERT_TYPE                         246
+# define SSL_R_UNKNOWN_CERTIFICATE_TYPE                   247
+# define SSL_R_UNKNOWN_CIPHER_RETURNED                    248
+# define SSL_R_UNKNOWN_CIPHER_TYPE                        249
+# define SSL_R_UNKNOWN_CMD_NAME                           386
+# define SSL_R_UNKNOWN_DIGEST                             368
+# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE                  250
+# define SSL_R_UNKNOWN_PKEY_TYPE                          251
+# define SSL_R_UNKNOWN_PROTOCOL                           252
+# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE                  253
+# define SSL_R_UNKNOWN_SSL_VERSION                        254
+# define SSL_R_UNKNOWN_STATE                              255
+# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       338
+# define SSL_R_UNSUPPORTED_CIPHER                         256
+# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM          257
+# define SSL_R_UNSUPPORTED_DIGEST_TYPE                    326
+# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE                 315
+# define SSL_R_UNSUPPORTED_PROTOCOL                       258
+# define SSL_R_UNSUPPORTED_SSL_VERSION                    259
+# define SSL_R_UNSUPPORTED_STATUS_TYPE                    329
+# define SSL_R_USE_SRTP_NOT_NEGOTIATED                    369
+# define SSL_R_WRITE_BIO_NOT_SET                          260
+# define SSL_R_WRONG_CERTIFICATE_TYPE                     383
+# define SSL_R_WRONG_CIPHER_RETURNED                      261
+# define SSL_R_WRONG_CURVE                                378
+# define SSL_R_WRONG_MESSAGE_TYPE                         262
+# define SSL_R_WRONG_NUMBER_OF_KEY_BITS                   263
+# define SSL_R_WRONG_SIGNATURE_LENGTH                     264
+# define SSL_R_WRONG_SIGNATURE_SIZE                       265
+# define SSL_R_WRONG_SIGNATURE_TYPE                       370
+# define SSL_R_WRONG_SSL_VERSION                          266
+# define SSL_R_WRONG_VERSION_NUMBER                       267
+# define SSL_R_X509_LIB                                   268
+# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS           269
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ssl2.h b/Cryptlib/Include/openssl/ssl2.h
new file mode 100644 (file)
index 0000000..03c7dd8
--- /dev/null
@@ -0,0 +1,265 @@
+/* ssl/ssl2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL2_H
+# define HEADER_SSL2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Protocol Version Codes */
+# define SSL2_VERSION            0x0002
+# define SSL2_VERSION_MAJOR      0x00
+# define SSL2_VERSION_MINOR      0x02
+/* #define SSL2_CLIENT_VERSION  0x0002 */
+/* #define SSL2_SERVER_VERSION  0x0002 */
+
+/* Protocol Message Codes */
+# define SSL2_MT_ERROR                   0
+# define SSL2_MT_CLIENT_HELLO            1
+# define SSL2_MT_CLIENT_MASTER_KEY       2
+# define SSL2_MT_CLIENT_FINISHED         3
+# define SSL2_MT_SERVER_HELLO            4
+# define SSL2_MT_SERVER_VERIFY           5
+# define SSL2_MT_SERVER_FINISHED         6
+# define SSL2_MT_REQUEST_CERTIFICATE     7
+# define SSL2_MT_CLIENT_CERTIFICATE      8
+
+/* Error Message Codes */
+# define SSL2_PE_UNDEFINED_ERROR         0x0000
+# define SSL2_PE_NO_CIPHER               0x0001
+# define SSL2_PE_NO_CERTIFICATE          0x0002
+# define SSL2_PE_BAD_CERTIFICATE         0x0004
+# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
+
+/* Cipher Kind Values */
+# define SSL2_CK_NULL_WITH_MD5                   0x02000000/* v3 */
+# define SSL2_CK_RC4_128_WITH_MD5                0x02010080
+# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5       0x02020080
+# define SSL2_CK_RC2_128_CBC_WITH_MD5            0x02030080
+# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5   0x02040080
+# define SSL2_CK_IDEA_128_CBC_WITH_MD5           0x02050080
+# define SSL2_CK_DES_64_CBC_WITH_MD5             0x02060040
+# define SSL2_CK_DES_64_CBC_WITH_SHA             0x02060140/* v3 */
+# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5       0x020700c0
+# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA       0x020701c0/* v3 */
+# define SSL2_CK_RC4_64_WITH_MD5                 0x02080080/* MS hack */
+
+# define SSL2_CK_DES_64_CFB64_WITH_MD5_1         0x02ff0800/* SSLeay */
+# define SSL2_CK_NULL                            0x02ff0810/* SSLeay */
+
+# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1        "DES-CFB-M1"
+# define SSL2_TXT_NULL_WITH_MD5                  "NULL-MD5"
+# define SSL2_TXT_RC4_128_WITH_MD5               "RC4-MD5"
+# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5      "EXP-RC4-MD5"
+# define SSL2_TXT_RC2_128_CBC_WITH_MD5           "RC2-CBC-MD5"
+# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5  "EXP-RC2-CBC-MD5"
+# define SSL2_TXT_IDEA_128_CBC_WITH_MD5          "IDEA-CBC-MD5"
+# define SSL2_TXT_DES_64_CBC_WITH_MD5            "DES-CBC-MD5"
+# define SSL2_TXT_DES_64_CBC_WITH_SHA            "DES-CBC-SHA"
+# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5      "DES-CBC3-MD5"
+# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA      "DES-CBC3-SHA"
+# define SSL2_TXT_RC4_64_WITH_MD5                "RC4-64-MD5"
+
+# define SSL2_TXT_NULL                           "NULL"
+
+/* Flags for the SSL_CIPHER.algorithm2 field */
+# define SSL2_CF_5_BYTE_ENC                      0x01
+# define SSL2_CF_8_BYTE_ENC                      0x02
+
+/* Certificate Type Codes */
+# define SSL2_CT_X509_CERTIFICATE                0x01
+
+/* Authentication Type Code */
+# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION         0x01
+
+# define SSL2_MAX_SSL_SESSION_ID_LENGTH          32
+
+/* Upper/Lower Bounds */
+# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS      256
+# ifdef OPENSSL_SYS_MPE
+#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    29998u
+# else
+#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    32767u
+                                                       /* 2^15-1 */
+# endif
+# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER    16383/* 2^14-1 */
+
+# define SSL2_CHALLENGE_LENGTH   16
+/*
+ * #define SSL2_CHALLENGE_LENGTH 32
+ */
+# define SSL2_MIN_CHALLENGE_LENGTH       16
+# define SSL2_MAX_CHALLENGE_LENGTH       32
+# define SSL2_CONNECTION_ID_LENGTH       16
+# define SSL2_MAX_CONNECTION_ID_LENGTH   16
+# define SSL2_SSL_SESSION_ID_LENGTH      16
+# define SSL2_MAX_CERT_CHALLENGE_LENGTH  32
+# define SSL2_MIN_CERT_CHALLENGE_LENGTH  16
+# define SSL2_MAX_KEY_MATERIAL_LENGTH    24
+
+# ifndef HEADER_SSL_LOCL_H
+#  define  CERT           char
+# endif
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl2_state_st {
+    int three_byte_header;
+    int clear_text;             /* clear text */
+    int escape;                 /* not used in SSLv2 */
+    int ssl2_rollback;          /* used if SSLv23 rolled back to SSLv2 */
+    /*
+     * non-blocking io info, used to make sure the same args were passwd
+     */
+    unsigned int wnum;          /* number of bytes sent so far */
+    int wpend_tot;
+    const unsigned char *wpend_buf;
+    int wpend_off;              /* offset to data to write */
+    int wpend_len;              /* number of bytes passwd to write */
+    int wpend_ret;              /* number of bytes to return to caller */
+    /* buffer raw data */
+    int rbuf_left;
+    int rbuf_offs;
+    unsigned char *rbuf;
+    unsigned char *wbuf;
+    unsigned char *write_ptr;   /* used to point to the start due to 2/3 byte
+                                 * header. */
+    unsigned int padding;
+    unsigned int rlength;       /* passed to ssl2_enc */
+    int ract_data_length;       /* Set when things are encrypted. */
+    unsigned int wlength;       /* passed to ssl2_enc */
+    int wact_data_length;       /* Set when things are decrypted. */
+    unsigned char *ract_data;
+    unsigned char *wact_data;
+    unsigned char *mac_data;
+    unsigned char *read_key;
+    unsigned char *write_key;
+    /* Stuff specifically to do with this SSL session */
+    unsigned int challenge_length;
+    unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
+    unsigned int conn_id_length;
+    unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
+    unsigned int key_material_length;
+    unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2];
+    unsigned long read_sequence;
+    unsigned long write_sequence;
+    struct {
+        unsigned int conn_id_length;
+        unsigned int cert_type;
+        unsigned int cert_length;
+        unsigned int csl;
+        unsigned int clear;
+        unsigned int enc;
+        unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
+        unsigned int cipher_spec_length;
+        unsigned int session_id_length;
+        unsigned int clen;
+        unsigned int rlen;
+    } tmp;
+} SSL2_STATE;
+
+# endif
+
+/* SSLv2 */
+/* client */
+# define SSL2_ST_SEND_CLIENT_HELLO_A             (0x10|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_HELLO_B             (0x11|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_HELLO_A              (0x20|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_HELLO_B              (0x21|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A        (0x30|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B        (0x31|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_FINISHED_A          (0x40|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_FINISHED_B          (0x41|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A       (0x50|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B       (0x51|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C       (0x52|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D       (0x53|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_VERIFY_A             (0x60|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_VERIFY_B             (0x61|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_FINISHED_A           (0x70|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_FINISHED_B           (0x71|SSL_ST_CONNECT)
+# define SSL2_ST_CLIENT_START_ENCRYPTION         (0x80|SSL_ST_CONNECT)
+# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE     (0x90|SSL_ST_CONNECT)
+/* server */
+# define SSL2_ST_GET_CLIENT_HELLO_A              (0x10|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_HELLO_B              (0x11|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_HELLO_C              (0x12|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_HELLO_A             (0x20|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_HELLO_B             (0x21|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_MASTER_KEY_A         (0x30|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_MASTER_KEY_B         (0x31|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_A            (0x40|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_B            (0x41|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_C            (0x42|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_FINISHED_A           (0x50|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_FINISHED_B           (0x51|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_FINISHED_A          (0x60|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_FINISHED_B          (0x61|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A      (0x70|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B      (0x71|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C      (0x72|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D      (0x73|SSL_ST_ACCEPT)
+# define SSL2_ST_SERVER_START_ENCRYPTION         (0x80|SSL_ST_ACCEPT)
+# define SSL2_ST_X509_GET_SERVER_CERTIFICATE     (0x90|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ssl23.h b/Cryptlib/Include/openssl/ssl23.h
new file mode 100644 (file)
index 0000000..9de4685
--- /dev/null
@@ -0,0 +1,84 @@
+/* ssl/ssl23.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL23_H
+# define HEADER_SSL23_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * client
+ */
+/* write to server */
+# define SSL23_ST_CW_CLNT_HELLO_A        (0x210|SSL_ST_CONNECT)
+# define SSL23_ST_CW_CLNT_HELLO_B        (0x211|SSL_ST_CONNECT)
+/* read from server */
+# define SSL23_ST_CR_SRVR_HELLO_A        (0x220|SSL_ST_CONNECT)
+# define SSL23_ST_CR_SRVR_HELLO_B        (0x221|SSL_ST_CONNECT)
+
+/* server */
+/* read from client */
+# define SSL23_ST_SR_CLNT_HELLO_A        (0x210|SSL_ST_ACCEPT)
+# define SSL23_ST_SR_CLNT_HELLO_B        (0x211|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ssl3.h b/Cryptlib/Include/openssl/ssl3.h
new file mode 100644 (file)
index 0000000..e681d50
--- /dev/null
@@ -0,0 +1,774 @@
+/* ssl/ssl3.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-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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H
+# define HEADER_SSL3_H
+
+# ifndef OPENSSL_NO_COMP
+#  include <openssl/comp.h>
+# endif
+# include <openssl/buffer.h>
+# include <openssl/evp.h>
+# include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
+ */
+# define SSL3_CK_SCSV                            0x030000FF
+
+/*
+ * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV)
+ */
+# define SSL3_CK_FALLBACK_SCSV                   0x03005600
+
+# define SSL3_CK_RSA_NULL_MD5                    0x03000001
+# define SSL3_CK_RSA_NULL_SHA                    0x03000002
+# define SSL3_CK_RSA_RC4_40_MD5                  0x03000003
+# define SSL3_CK_RSA_RC4_128_MD5                 0x03000004
+# define SSL3_CK_RSA_RC4_128_SHA                 0x03000005
+# define SSL3_CK_RSA_RC2_40_MD5                  0x03000006
+# define SSL3_CK_RSA_IDEA_128_SHA                0x03000007
+# define SSL3_CK_RSA_DES_40_CBC_SHA              0x03000008
+# define SSL3_CK_RSA_DES_64_CBC_SHA              0x03000009
+# define SSL3_CK_RSA_DES_192_CBC3_SHA            0x0300000A
+
+# define SSL3_CK_DH_DSS_DES_40_CBC_SHA           0x0300000B
+# define SSL3_CK_DH_DSS_DES_64_CBC_SHA           0x0300000C
+# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA         0x0300000D
+# define SSL3_CK_DH_RSA_DES_40_CBC_SHA           0x0300000E
+# define SSL3_CK_DH_RSA_DES_64_CBC_SHA           0x0300000F
+# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA         0x03000010
+
+# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA          0x03000011
+# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA          SSL3_CK_EDH_DSS_DES_40_CBC_SHA
+# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA          0x03000012
+# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA          SSL3_CK_EDH_DSS_DES_64_CBC_SHA
+# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA        0x03000013
+# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA        SSL3_CK_EDH_DSS_DES_192_CBC3_SHA
+# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA          0x03000014
+# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA          SSL3_CK_EDH_RSA_DES_40_CBC_SHA
+# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA          0x03000015
+# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA          SSL3_CK_EDH_RSA_DES_64_CBC_SHA
+# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA        0x03000016
+# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA        SSL3_CK_EDH_RSA_DES_192_CBC3_SHA
+
+# define SSL3_CK_ADH_RC4_40_MD5                  0x03000017
+# define SSL3_CK_ADH_RC4_128_MD5                 0x03000018
+# define SSL3_CK_ADH_DES_40_CBC_SHA              0x03000019
+# define SSL3_CK_ADH_DES_64_CBC_SHA              0x0300001A
+# define SSL3_CK_ADH_DES_192_CBC_SHA             0x0300001B
+
+# if 0
+#  define SSL3_CK_FZA_DMS_NULL_SHA                0x0300001C
+#  define SSL3_CK_FZA_DMS_FZA_SHA                 0x0300001D
+#  if 0                         /* Because it clashes with KRB5, is never
+                                 * used any more, and is safe to remove
+                                 * according to David Hopwood
+                                 * <david.hopwood@zetnet.co.uk> of the
+                                 * ietf-tls list */
+#   define SSL3_CK_FZA_DMS_RC4_SHA                 0x0300001E
+#  endif
+# endif
+
+/*
+ * VRS Additional Kerberos5 entries
+ */
+# define SSL3_CK_KRB5_DES_64_CBC_SHA             0x0300001E
+# define SSL3_CK_KRB5_DES_192_CBC3_SHA           0x0300001F
+# define SSL3_CK_KRB5_RC4_128_SHA                0x03000020
+# define SSL3_CK_KRB5_IDEA_128_CBC_SHA           0x03000021
+# define SSL3_CK_KRB5_DES_64_CBC_MD5             0x03000022
+# define SSL3_CK_KRB5_DES_192_CBC3_MD5           0x03000023
+# define SSL3_CK_KRB5_RC4_128_MD5                0x03000024
+# define SSL3_CK_KRB5_IDEA_128_CBC_MD5           0x03000025
+
+# define SSL3_CK_KRB5_DES_40_CBC_SHA             0x03000026
+# define SSL3_CK_KRB5_RC2_40_CBC_SHA             0x03000027
+# define SSL3_CK_KRB5_RC4_40_SHA                 0x03000028
+# define SSL3_CK_KRB5_DES_40_CBC_MD5             0x03000029
+# define SSL3_CK_KRB5_RC2_40_CBC_MD5             0x0300002A
+# define SSL3_CK_KRB5_RC4_40_MD5                 0x0300002B
+
+# define SSL3_TXT_RSA_NULL_MD5                   "NULL-MD5"
+# define SSL3_TXT_RSA_NULL_SHA                   "NULL-SHA"
+# define SSL3_TXT_RSA_RC4_40_MD5                 "EXP-RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_MD5                "RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_SHA                "RC4-SHA"
+# define SSL3_TXT_RSA_RC2_40_MD5                 "EXP-RC2-CBC-MD5"
+# define SSL3_TXT_RSA_IDEA_128_SHA               "IDEA-CBC-SHA"
+# define SSL3_TXT_RSA_DES_40_CBC_SHA             "EXP-DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_64_CBC_SHA             "DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_192_CBC3_SHA           "DES-CBC3-SHA"
+
+# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA          "EXP-DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA          "DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA        "DH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA          "EXP-DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA          "DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA        "DH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA         "EXP-DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA         "DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA       "DHE-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA         "EXP-DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA         "DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA       "DHE-RSA-DES-CBC3-SHA"
+
+/*
+ * This next block of six "EDH" labels is for backward compatibility with
+ * older versions of OpenSSL.  New code should use the six "DHE" labels above
+ * instead:
+ */
+# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA         "EXP-EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA         "EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA       "EDH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA         "EXP-EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA         "EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA       "EDH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_ADH_RC4_40_MD5                 "EXP-ADH-RC4-MD5"
+# define SSL3_TXT_ADH_RC4_128_MD5                "ADH-RC4-MD5"
+# define SSL3_TXT_ADH_DES_40_CBC_SHA             "EXP-ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_64_CBC_SHA             "ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_192_CBC_SHA            "ADH-DES-CBC3-SHA"
+
+# if 0
+#  define SSL3_TXT_FZA_DMS_NULL_SHA               "FZA-NULL-SHA"
+#  define SSL3_TXT_FZA_DMS_FZA_SHA                "FZA-FZA-CBC-SHA"
+#  define SSL3_TXT_FZA_DMS_RC4_SHA                "FZA-RC4-SHA"
+# endif
+
+# define SSL3_TXT_KRB5_DES_64_CBC_SHA            "KRB5-DES-CBC-SHA"
+# define SSL3_TXT_KRB5_DES_192_CBC3_SHA          "KRB5-DES-CBC3-SHA"
+# define SSL3_TXT_KRB5_RC4_128_SHA               "KRB5-RC4-SHA"
+# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA          "KRB5-IDEA-CBC-SHA"
+# define SSL3_TXT_KRB5_DES_64_CBC_MD5            "KRB5-DES-CBC-MD5"
+# define SSL3_TXT_KRB5_DES_192_CBC3_MD5          "KRB5-DES-CBC3-MD5"
+# define SSL3_TXT_KRB5_RC4_128_MD5               "KRB5-RC4-MD5"
+# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5          "KRB5-IDEA-CBC-MD5"
+
+# define SSL3_TXT_KRB5_DES_40_CBC_SHA            "EXP-KRB5-DES-CBC-SHA"
+# define SSL3_TXT_KRB5_RC2_40_CBC_SHA            "EXP-KRB5-RC2-CBC-SHA"
+# define SSL3_TXT_KRB5_RC4_40_SHA                "EXP-KRB5-RC4-SHA"
+# define SSL3_TXT_KRB5_DES_40_CBC_MD5            "EXP-KRB5-DES-CBC-MD5"
+# define SSL3_TXT_KRB5_RC2_40_CBC_MD5            "EXP-KRB5-RC2-CBC-MD5"
+# define SSL3_TXT_KRB5_RC4_40_MD5                "EXP-KRB5-RC4-MD5"
+
+# define SSL3_SSL_SESSION_ID_LENGTH              32
+# define SSL3_MAX_SSL_SESSION_ID_LENGTH          32
+
+# define SSL3_MASTER_SECRET_SIZE                 48
+# define SSL3_RANDOM_SIZE                        32
+# define SSL3_SESSION_ID_SIZE                    32
+# define SSL3_RT_HEADER_LENGTH                   5
+
+# define SSL3_HM_HEADER_LENGTH                  4
+
+# ifndef SSL3_ALIGN_PAYLOAD
+ /*
+  * Some will argue that this increases memory footprint, but it's not
+  * actually true. Point is that malloc has to return at least 64-bit aligned
+  * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case.
+  * Suggested pre-gaping simply moves these wasted bytes from the end of
+  * allocated region to its front, but makes data payload aligned, which
+  * improves performance:-)
+  */
+#  define SSL3_ALIGN_PAYLOAD                     8
+# else
+#  if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#   error "insane SSL3_ALIGN_PAYLOAD"
+#   undef SSL3_ALIGN_PAYLOAD
+#  endif
+# endif
+
+/*
+ * This is the maximum MAC (digest) size used by the SSL library. Currently
+ * maximum of 20 is used by SHA1, but we reserve for future extension for
+ * 512-bit hashes.
+ */
+
+# define SSL3_RT_MAX_MD_SIZE                     64
+
+/*
+ * Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+# define SSL_RT_MAX_CIPHER_BLOCK_SIZE            16
+
+# define SSL3_RT_MAX_EXTRA                       (16384)
+
+/* Maximum plaintext length: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_PLAIN_LENGTH                16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_COMPRESSED_OVERHEAD         1024
+
+/*
+ * The standards give a maximum encryption overhead of 1024 bytes. In
+ * practice the value is lower than this. The overhead is the maximum number
+ * of padding bytes (256) plus the mac size.
+ */
+# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD  (256 + SSL3_RT_MAX_MD_SIZE)
+
+/*
+ * OpenSSL currently only uses a padding length of at most one block so the
+ * send overhead is smaller.
+ */
+
+# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+                        (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
+# ifdef OPENSSL_NO_COMP
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH           SSL3_RT_MAX_PLAIN_LENGTH
+# else
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH   \
+                (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+# endif
+# define SSL3_RT_MAX_ENCRYPTED_LENGTH    \
+                (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+# define SSL3_RT_MAX_PACKET_SIZE         \
+                (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
+# define SSL3_MD_CLIENT_FINISHED_CONST   "\x43\x4C\x4E\x54"
+# define SSL3_MD_SERVER_FINISHED_CONST   "\x53\x52\x56\x52"
+
+# define SSL3_VERSION                    0x0300
+# define SSL3_VERSION_MAJOR              0x03
+# define SSL3_VERSION_MINOR              0x00
+
+# define SSL3_RT_CHANGE_CIPHER_SPEC      20
+# define SSL3_RT_ALERT                   21
+# define SSL3_RT_HANDSHAKE               22
+# define SSL3_RT_APPLICATION_DATA        23
+# define TLS1_RT_HEARTBEAT               24
+
+/* Pseudo content types to indicate additional parameters */
+# define TLS1_RT_CRYPTO                  0x1000
+# define TLS1_RT_CRYPTO_PREMASTER        (TLS1_RT_CRYPTO | 0x1)
+# define TLS1_RT_CRYPTO_CLIENT_RANDOM    (TLS1_RT_CRYPTO | 0x2)
+# define TLS1_RT_CRYPTO_SERVER_RANDOM    (TLS1_RT_CRYPTO | 0x3)
+# define TLS1_RT_CRYPTO_MASTER           (TLS1_RT_CRYPTO | 0x4)
+
+# define TLS1_RT_CRYPTO_READ             0x0000
+# define TLS1_RT_CRYPTO_WRITE            0x0100
+# define TLS1_RT_CRYPTO_MAC              (TLS1_RT_CRYPTO | 0x5)
+# define TLS1_RT_CRYPTO_KEY              (TLS1_RT_CRYPTO | 0x6)
+# define TLS1_RT_CRYPTO_IV               (TLS1_RT_CRYPTO | 0x7)
+# define TLS1_RT_CRYPTO_FIXED_IV         (TLS1_RT_CRYPTO | 0x8)
+
+/* Pseudo content type for SSL/TLS header info */
+# define SSL3_RT_HEADER                  0x100
+
+# define SSL3_AL_WARNING                 1
+# define SSL3_AL_FATAL                   2
+
+# define SSL3_AD_CLOSE_NOTIFY             0
+# define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */
+# define SSL3_AD_BAD_RECORD_MAC          20/* fatal */
+# define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */
+# define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */
+# define SSL3_AD_NO_CERTIFICATE          41
+# define SSL3_AD_BAD_CERTIFICATE         42
+# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
+# define SSL3_AD_CERTIFICATE_REVOKED     44
+# define SSL3_AD_CERTIFICATE_EXPIRED     45
+# define SSL3_AD_CERTIFICATE_UNKNOWN     46
+# define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */
+
+# define TLS1_HB_REQUEST         1
+# define TLS1_HB_RESPONSE        2
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl3_record_st {
+    /* type of record */
+    /*
+     * r
+     */ int type;
+    /* How many bytes available */
+    /*
+     * rw
+     */ unsigned int length;
+    /* read/write offset into 'buf' */
+    /*
+     * r
+     */ unsigned int off;
+    /* pointer to the record data */
+    /*
+     * rw
+     */ unsigned char *data;
+    /* where the decode bytes are */
+    /*
+     * rw
+     */ unsigned char *input;
+    /* only used with decompression - malloc()ed */
+    /*
+     * r
+     */ unsigned char *comp;
+    /* epoch number, needed by DTLS1 */
+    /*
+     * r
+     */ unsigned long epoch;
+    /* sequence number, needed by DTLS1 */
+    /*
+     * r
+     */ unsigned char seq_num[8];
+} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st {
+    /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */
+    unsigned char *buf;
+    /* buffer size */
+    size_t len;
+    /* where to 'copy from' */
+    int offset;
+    /* how many bytes left */
+    int left;
+} SSL3_BUFFER;
+
+# endif
+
+# define SSL3_CT_RSA_SIGN                        1
+# define SSL3_CT_DSS_SIGN                        2
+# define SSL3_CT_RSA_FIXED_DH                    3
+# define SSL3_CT_DSS_FIXED_DH                    4
+# define SSL3_CT_RSA_EPHEMERAL_DH                5
+# define SSL3_CT_DSS_EPHEMERAL_DH                6
+# define SSL3_CT_FORTEZZA_DMS                    20
+/*
+ * SSL3_CT_NUMBER is used to size arrays and it must be large enough to
+ * contain all of the cert types defined either for SSLv3 and TLSv1.
+ */
+# define SSL3_CT_NUMBER                  9
+
+# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS       0x0001
+# define SSL3_FLAGS_DELAY_CLIENT_FINISHED        0x0002
+# define SSL3_FLAGS_POP_BUFFER                   0x0004
+# define TLS1_FLAGS_TLS_PADDING_BUG              0x0008
+# define TLS1_FLAGS_SKIP_CERT_VERIFY             0x0010
+# define TLS1_FLAGS_KEEP_HANDSHAKE               0x0020
+/*
+ * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+ * Cleared after the message has been processed.
+ */
+# define SSL3_FLAGS_CCS_OK                       0x0080
+
+/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */
+# define SSL3_FLAGS_SGC_RESTART_DONE             0x0040
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl3_state_st {
+    long flags;
+    int delay_buf_pop_ret;
+    unsigned char read_sequence[8];
+    int read_mac_secret_size;
+    unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+    unsigned char write_sequence[8];
+    int write_mac_secret_size;
+    unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+    unsigned char server_random[SSL3_RANDOM_SIZE];
+    unsigned char client_random[SSL3_RANDOM_SIZE];
+    /* flags for countermeasure against known-IV weakness */
+    int need_empty_fragments;
+    int empty_fragment_done;
+    /* The value of 'extra' when the buffers were initialized */
+    int init_extra;
+    SSL3_BUFFER rbuf;           /* read IO goes into here */
+    SSL3_BUFFER wbuf;           /* write IO goes into here */
+    SSL3_RECORD rrec;           /* each decoded record goes in here */
+    SSL3_RECORD wrec;           /* goes out from here */
+    /*
+     * storage for Alert/Handshake protocol data received but not yet
+     * processed by ssl3_read_bytes:
+     */
+    unsigned char alert_fragment[2];
+    unsigned int alert_fragment_len;
+    unsigned char handshake_fragment[4];
+    unsigned int handshake_fragment_len;
+    /* partial write - check the numbers match */
+    unsigned int wnum;          /* number of bytes sent so far */
+    int wpend_tot;              /* number bytes written */
+    int wpend_type;
+    int wpend_ret;              /* number of bytes submitted */
+    const unsigned char *wpend_buf;
+    /* used during startup, digest all incoming/outgoing packets */
+    BIO *handshake_buffer;
+    /*
+     * When set of handshake digests is determined, buffer is hashed and
+     * freed and MD_CTX-es for all required digests are stored in this array
+     */
+    EVP_MD_CTX **handshake_dgst;
+    /*
+     * Set whenever an expected ChangeCipherSpec message is processed.
+     * Unset when the peer's Finished message is received.
+     * Unexpected ChangeCipherSpec messages trigger a fatal alert.
+     */
+    int change_cipher_spec;
+    int warn_alert;
+    int fatal_alert;
+    /*
+     * we allow one fatal and one warning alert to be outstanding, send close
+     * alert via the warning alert
+     */
+    int alert_dispatch;
+    unsigned char send_alert[2];
+    /*
+     * This flag is set when we should renegotiate ASAP, basically when there
+     * is no more data in the read or write buffers
+     */
+    int renegotiate;
+    int total_renegotiations;
+    int num_renegotiations;
+    int in_read_app_data;
+    /*
+     * Opaque PRF input as used for the current handshake. These fields are
+     * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they
+     * are merely present to improve binary compatibility)
+     */
+    void *client_opaque_prf_input;
+    size_t client_opaque_prf_input_len;
+    void *server_opaque_prf_input;
+    size_t server_opaque_prf_input_len;
+    struct {
+        /* actually only needs to be 16+20 */
+        unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2];
+        /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+        unsigned char finish_md[EVP_MAX_MD_SIZE * 2];
+        int finish_md_len;
+        unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2];
+        int peer_finish_md_len;
+        unsigned long message_size;
+        int message_type;
+        /* used to hold the new cipher we are going to use */
+        const SSL_CIPHER *new_cipher;
+#  ifndef OPENSSL_NO_DH
+        DH *dh;
+#  endif
+#  ifndef OPENSSL_NO_ECDH
+        EC_KEY *ecdh;           /* holds short lived ECDH key */
+#  endif
+        /* used when SSL_ST_FLUSH_DATA is entered */
+        int next_state;
+        int reuse_message;
+        /* used for certificate requests */
+        int cert_req;
+        int ctype_num;
+        char ctype[SSL3_CT_NUMBER];
+        STACK_OF(X509_NAME) *ca_names;
+        int use_rsa_tmp;
+        int key_block_length;
+        unsigned char *key_block;
+        const EVP_CIPHER *new_sym_enc;
+        const EVP_MD *new_hash;
+        int new_mac_pkey_type;
+        int new_mac_secret_size;
+#  ifndef OPENSSL_NO_COMP
+        const SSL_COMP *new_compression;
+#  else
+        char *new_compression;
+#  endif
+        int cert_request;
+    } tmp;
+
+    /* Connection binding to prevent renegotiation attacks */
+    unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_client_finished_len;
+    unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_server_finished_len;
+    int send_connection_binding; /* TODOEKR */
+
+#  ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * Set if we saw the Next Protocol Negotiation extension from our peer.
+     */
+    int next_proto_neg_seen;
+#  endif
+
+#  ifndef OPENSSL_NO_TLSEXT
+#   ifndef OPENSSL_NO_EC
+    /*
+     * This is set to true if we believe that this is a version of Safari
+     * running on OS X 10.6 or newer. We wish to know this because Safari on
+     * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support.
+     */
+    char is_probably_safari;
+#   endif                       /* !OPENSSL_NO_EC */
+
+    /*
+     * ALPN information (we are in the process of transitioning from NPN to
+     * ALPN.)
+     */
+
+    /*
+     * In a server these point to the selected ALPN protocol after the
+     * ClientHello has been processed. In a client these contain the protocol
+     * that the server selected once the ServerHello has been processed.
+     */
+    unsigned char *alpn_selected;
+    unsigned alpn_selected_len;
+#  endif                        /* OPENSSL_NO_TLSEXT */
+} SSL3_STATE;
+
+# endif
+
+/* SSLv3 */
+/*
+ * client
+ */
+/* extra state */
+# define SSL3_ST_CW_FLUSH                (0x100|SSL_ST_CONNECT)
+# ifndef OPENSSL_NO_SCTP
+#  define DTLS1_SCTP_ST_CW_WRITE_SOCK                     (0x310|SSL_ST_CONNECT)
+#  define DTLS1_SCTP_ST_CR_READ_SOCK                      (0x320|SSL_ST_CONNECT)
+# endif
+/* write to server */
+# define SSL3_ST_CW_CLNT_HELLO_A         (0x110|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CLNT_HELLO_B         (0x111|SSL_ST_CONNECT)
+/* read from server */
+# define SSL3_ST_CR_SRVR_HELLO_A         (0x120|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_HELLO_B         (0x121|SSL_ST_CONNECT)
+# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
+# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_A               (0x130|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_B               (0x131|SSL_ST_CONNECT)
+# define SSL3_ST_CR_KEY_EXCH_A           (0x140|SSL_ST_CONNECT)
+# define SSL3_ST_CR_KEY_EXCH_B           (0x141|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_REQ_A           (0x150|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_REQ_B           (0x151|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_DONE_A          (0x160|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_DONE_B          (0x161|SSL_ST_CONNECT)
+/* write to server */
+# define SSL3_ST_CW_CERT_A               (0x170|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_B               (0x171|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_C               (0x172|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_D               (0x173|SSL_ST_CONNECT)
+# define SSL3_ST_CW_KEY_EXCH_A           (0x180|SSL_ST_CONNECT)
+# define SSL3_ST_CW_KEY_EXCH_B           (0x181|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_VRFY_A          (0x190|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_VRFY_B          (0x191|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CHANGE_A             (0x1A0|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CHANGE_B             (0x1A1|SSL_ST_CONNECT)
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_ST_CW_NEXT_PROTO_A         (0x200|SSL_ST_CONNECT)
+#  define SSL3_ST_CW_NEXT_PROTO_B         (0x201|SSL_ST_CONNECT)
+# endif
+# define SSL3_ST_CW_FINISHED_A           (0x1B0|SSL_ST_CONNECT)
+# define SSL3_ST_CW_FINISHED_B           (0x1B1|SSL_ST_CONNECT)
+/* read from server */
+# define SSL3_ST_CR_CHANGE_A             (0x1C0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CHANGE_B             (0x1C1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_FINISHED_A           (0x1D0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_FINISHED_B           (0x1D1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SESSION_TICKET_A     (0x1E0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SESSION_TICKET_B     (0x1E1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_STATUS_A        (0x1F0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_STATUS_B        (0x1F1|SSL_ST_CONNECT)
+
+/* server */
+/* extra state */
+# define SSL3_ST_SW_FLUSH                (0x100|SSL_ST_ACCEPT)
+# ifndef OPENSSL_NO_SCTP
+#  define DTLS1_SCTP_ST_SW_WRITE_SOCK                     (0x310|SSL_ST_ACCEPT)
+#  define DTLS1_SCTP_ST_SR_READ_SOCK                      (0x320|SSL_ST_ACCEPT)
+# endif
+/* read from client */
+/* Do not change the number values, they do matter */
+# define SSL3_ST_SR_CLNT_HELLO_A         (0x110|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_B         (0x111|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_C         (0x112|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_D         (0x115|SSL_ST_ACCEPT)
+/* write to client */
+# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
+# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_A          (0x120|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_B          (0x121|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_C          (0x122|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_HELLO_A         (0x130|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_HELLO_B         (0x131|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_A               (0x140|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_B               (0x141|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_KEY_EXCH_A           (0x150|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_KEY_EXCH_B           (0x151|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_REQ_A           (0x160|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_REQ_B           (0x161|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_DONE_A          (0x170|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_DONE_B          (0x171|SSL_ST_ACCEPT)
+/* read from client */
+# define SSL3_ST_SR_CERT_A               (0x180|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_B               (0x181|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_KEY_EXCH_A           (0x190|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_KEY_EXCH_B           (0x191|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_VRFY_A          (0x1A0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_VRFY_B          (0x1A1|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CHANGE_A             (0x1B0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CHANGE_B             (0x1B1|SSL_ST_ACCEPT)
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_ST_SR_NEXT_PROTO_A         (0x210|SSL_ST_ACCEPT)
+#  define SSL3_ST_SR_NEXT_PROTO_B         (0x211|SSL_ST_ACCEPT)
+# endif
+# define SSL3_ST_SR_FINISHED_A           (0x1C0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_FINISHED_B           (0x1C1|SSL_ST_ACCEPT)
+/* write to client */
+# define SSL3_ST_SW_CHANGE_A             (0x1D0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CHANGE_B             (0x1D1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_FINISHED_A           (0x1E0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_FINISHED_B           (0x1E1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SESSION_TICKET_A     (0x1F0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SESSION_TICKET_B     (0x1F1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_STATUS_A        (0x200|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_STATUS_B        (0x201|SSL_ST_ACCEPT)
+
+# define SSL3_MT_HELLO_REQUEST                   0
+# define SSL3_MT_CLIENT_HELLO                    1
+# define SSL3_MT_SERVER_HELLO                    2
+# define SSL3_MT_NEWSESSION_TICKET               4
+# define SSL3_MT_CERTIFICATE                     11
+# define SSL3_MT_SERVER_KEY_EXCHANGE             12
+# define SSL3_MT_CERTIFICATE_REQUEST             13
+# define SSL3_MT_SERVER_DONE                     14
+# define SSL3_MT_CERTIFICATE_VERIFY              15
+# define SSL3_MT_CLIENT_KEY_EXCHANGE             16
+# define SSL3_MT_FINISHED                        20
+# define SSL3_MT_CERTIFICATE_STATUS              22
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_MT_NEXT_PROTO                      67
+# endif
+# define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+# define SSL3_MT_CCS                             1
+
+/* These are used when changing over to a new cipher */
+# define SSL3_CC_READ            0x01
+# define SSL3_CC_WRITE           0x02
+# define SSL3_CC_CLIENT          0x10
+# define SSL3_CC_SERVER          0x20
+# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE)
+# define SSL3_CHANGE_CIPHER_SERVER_READ  (SSL3_CC_SERVER|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_CLIENT_READ  (SSL3_CC_CLIENT|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/stack.h b/Cryptlib/Include/openssl/stack.h
new file mode 100644 (file)
index 0000000..eb07216
--- /dev/null
@@ -0,0 +1,107 @@
+/* crypto/stack/stack.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_STACK_H
+# define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st {
+    int num;
+    char **data;
+    int sorted;
+    int num_alloc;
+    int (*comp) (const void *, const void *);
+} _STACK;                       /* Use STACK_OF(...) instead */
+
+# define M_sk_num(sk)            ((sk) ? (sk)->num:-1)
+# define M_sk_value(sk,n)        ((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
+
+void *sk_set(_STACK *, int, void *);
+
+_STACK *sk_new(int (*cmp) (const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func) (void *));
+_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
+ (const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/symhacks.h b/Cryptlib/Include/openssl/symhacks.h
new file mode 100644 (file)
index 0000000..239fa4f
--- /dev/null
@@ -0,0 +1,516 @@
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * 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_SYMHACKS_H
+# define HEADER_SYMHACKS_H
+
+# include <openssl/e_os2.h>
+
+/*
+ * Hacks to solve the problem with linkers incapable of handling very long
+ * symbol names.  In the case of VMS, the limit is 31 characters on VMS for
+ * VAX.
+ */
+/*
+ * Note that this affects util/libeay.num and util/ssleay.num...  you may
+ * change those manually, but that's not recommended, as those files are
+ * controlled centrally and updated on Unix, and the central definition may
+ * disagree with yours, which in turn may come with shareable library
+ * incompatibilities.
+ */
+# ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+#  undef CRYPTO_get_ex_data_implementation
+#  define CRYPTO_get_ex_data_implementation       CRYPTO_get_ex_data_impl
+#  undef CRYPTO_set_ex_data_implementation
+#  define CRYPTO_set_ex_data_implementation       CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+#  undef ASN1_STRING_set_default_mask_asc
+#  define ASN1_STRING_set_default_mask_asc        ASN1_STRING_set_def_mask_asc
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+#   undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#   define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO       i2d_ASN1_SET_OF_PKCS7_SIGINF
+#   undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#   define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO       d2i_ASN1_SET_OF_PKCS7_SIGINF
+#  endif
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+#   undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+#   define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO        i2d_ASN1_SET_OF_PKCS7_RECINF
+#   undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+#   define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO        d2i_ASN1_SET_OF_PKCS7_RECINF
+#  endif
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+#   undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+#   define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION      i2d_ASN1_SET_OF_ACC_DESC
+#   undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+#   define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION      d2i_ASN1_SET_OF_ACC_DESC
+#  endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+#  undef PEM_read_NETSCAPE_CERT_SEQUENCE
+#  define PEM_read_NETSCAPE_CERT_SEQUENCE         PEM_read_NS_CERT_SEQ
+#  undef PEM_write_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_NETSCAPE_CERT_SEQUENCE        PEM_write_NS_CERT_SEQ
+#  undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_read_bio_NETSCAPE_CERT_SEQUENCE     PEM_read_bio_NS_CERT_SEQ
+#  undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_bio_NETSCAPE_CERT_SEQUENCE    PEM_write_bio_NS_CERT_SEQ
+#  undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+#  undef PEM_read_PKCS8_PRIV_KEY_INFO
+#  define PEM_read_PKCS8_PRIV_KEY_INFO            PEM_read_P8_PRIV_KEY_INFO
+#  undef PEM_write_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_PKCS8_PRIV_KEY_INFO           PEM_write_P8_PRIV_KEY_INFO
+#  undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_read_bio_PKCS8_PRIV_KEY_INFO        PEM_read_bio_P8_PRIV_KEY_INFO
+#  undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_bio_PKCS8_PRIV_KEY_INFO       PEM_write_bio_P8_PRIV_KEY_INFO
+#  undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO    PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+#  undef PEM_write_bio_PKCS8PrivateKey_nid
+#  define PEM_write_bio_PKCS8PrivateKey_nid       PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+#  undef X509_REVOKED_get_ext_by_critical
+#  define X509_REVOKED_get_ext_by_critical        X509_REVOKED_get_ext_by_critic
+#  undef X509_policy_tree_get0_user_policies
+#  define X509_policy_tree_get0_user_policies     X509_pcy_tree_get0_usr_policies
+#  undef X509_policy_node_get0_qualifiers
+#  define X509_policy_node_get0_qualifiers        X509_pcy_node_get0_qualifiers
+#  undef X509_STORE_CTX_get_explicit_policy
+#  define X509_STORE_CTX_get_explicit_policy      X509_STORE_CTX_get_expl_policy
+#  undef X509_STORE_CTX_get0_current_issuer
+#  define X509_STORE_CTX_get0_current_issuer      X509_STORE_CTX_get0_cur_issuer
+
+/* Hack some long CRYPTO names */
+#  undef CRYPTO_set_dynlock_destroy_callback
+#  define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
+#  undef CRYPTO_set_dynlock_create_callback
+#  define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
+#  undef CRYPTO_set_dynlock_lock_callback
+#  define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#  undef CRYPTO_get_dynlock_lock_callback
+#  define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#  undef CRYPTO_get_dynlock_destroy_callback
+#  define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
+#  undef CRYPTO_get_dynlock_create_callback
+#  define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
+#  undef CRYPTO_set_locked_mem_ex_functions
+#  define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
+#  undef CRYPTO_get_locked_mem_ex_functions
+#  define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL/TLS names */
+#  undef SSL_CTX_set_default_verify_paths
+#  define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#  undef SSL_get_ex_data_X509_STORE_CTX_idx
+#  define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
+#  undef SSL_add_file_cert_subjects_to_stack
+#  define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
+#  undef SSL_add_dir_cert_subjects_to_stack
+#  define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
+#  undef SSL_CTX_use_certificate_chain_file
+#  define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
+#  undef SSL_CTX_set_cert_verify_callback
+#  define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#  undef SSL_CTX_set_default_passwd_cb_userdata
+#  define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
+#  undef SSL_COMP_get_compression_methods
+#  define SSL_COMP_get_compression_methods        SSL_COMP_get_compress_methods
+#  undef SSL_COMP_set0_compression_methods
+#  define SSL_COMP_set0_compression_methods       SSL_COMP_set0_compress_methods
+#  undef SSL_COMP_free_compression_methods
+#  define SSL_COMP_free_compression_methods       SSL_COMP_free_compress_methods
+#  undef ssl_add_clienthello_renegotiate_ext
+#  define ssl_add_clienthello_renegotiate_ext     ssl_add_clienthello_reneg_ext
+#  undef ssl_add_serverhello_renegotiate_ext
+#  define ssl_add_serverhello_renegotiate_ext     ssl_add_serverhello_reneg_ext
+#  undef ssl_parse_clienthello_renegotiate_ext
+#  define ssl_parse_clienthello_renegotiate_ext   ssl_parse_clienthello_reneg_ext
+#  undef ssl_parse_serverhello_renegotiate_ext
+#  define ssl_parse_serverhello_renegotiate_ext   ssl_parse_serverhello_reneg_ext
+#  undef SSL_srp_server_param_with_username
+#  define SSL_srp_server_param_with_username      SSL_srp_server_param_with_un
+#  undef SSL_CTX_set_srp_client_pwd_callback
+#  define SSL_CTX_set_srp_client_pwd_callback     SSL_CTX_set_srp_client_pwd_cb
+#  undef SSL_CTX_set_srp_verify_param_callback
+#  define SSL_CTX_set_srp_verify_param_callback   SSL_CTX_set_srp_vfy_param_cb
+#  undef SSL_CTX_set_srp_username_callback
+#  define SSL_CTX_set_srp_username_callback       SSL_CTX_set_srp_un_cb
+#  undef ssl_add_clienthello_use_srtp_ext
+#  define ssl_add_clienthello_use_srtp_ext        ssl_add_clihello_use_srtp_ext
+#  undef ssl_add_serverhello_use_srtp_ext
+#  define ssl_add_serverhello_use_srtp_ext        ssl_add_serhello_use_srtp_ext
+#  undef ssl_parse_clienthello_use_srtp_ext
+#  define ssl_parse_clienthello_use_srtp_ext      ssl_parse_clihello_use_srtp_ext
+#  undef ssl_parse_serverhello_use_srtp_ext
+#  define ssl_parse_serverhello_use_srtp_ext      ssl_parse_serhello_use_srtp_ext
+#  undef SSL_CTX_set_next_protos_advertised_cb
+#  define SSL_CTX_set_next_protos_advertised_cb   SSL_CTX_set_next_protos_adv_cb
+#  undef SSL_CTX_set_next_proto_select_cb
+#  define SSL_CTX_set_next_proto_select_cb        SSL_CTX_set_next_proto_sel_cb
+
+#  undef tls1_send_server_supplemental_data
+#  define tls1_send_server_supplemental_data      tls1_send_server_suppl_data
+#  undef tls1_send_client_supplemental_data
+#  define tls1_send_client_supplemental_data      tls1_send_client_suppl_data
+#  undef tls1_get_server_supplemental_data
+#  define tls1_get_server_supplemental_data       tls1_get_server_suppl_data
+#  undef tls1_get_client_supplemental_data
+#  define tls1_get_client_supplemental_data       tls1_get_client_suppl_data
+
+#  undef ssl3_cbc_record_digest_supported
+#  define ssl3_cbc_record_digest_supported        ssl3_cbc_record_digest_support
+#  undef ssl_check_clienthello_tlsext_late
+#  define ssl_check_clienthello_tlsext_late       ssl_check_clihello_tlsext_late
+#  undef ssl_check_clienthello_tlsext_early
+#  define ssl_check_clienthello_tlsext_early      ssl_check_clihello_tlsext_early
+
+/* Hack some RSA long names */
+#  undef RSA_padding_check_PKCS1_OAEP_mgf1
+#  define RSA_padding_check_PKCS1_OAEP_mgf1       RSA_pad_check_PKCS1_OAEP_mgf1
+
+/* Hack some ENGINE long names */
+#  undef ENGINE_get_default_BN_mod_exp_crt
+#  define ENGINE_get_default_BN_mod_exp_crt       ENGINE_get_def_BN_mod_exp_crt
+#  undef ENGINE_set_default_BN_mod_exp_crt
+#  define ENGINE_set_default_BN_mod_exp_crt       ENGINE_set_def_BN_mod_exp_crt
+#  undef ENGINE_set_load_privkey_function
+#  define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#  undef ENGINE_get_load_privkey_function
+#  define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
+#  undef ENGINE_unregister_pkey_asn1_meths
+#  define ENGINE_unregister_pkey_asn1_meths       ENGINE_unreg_pkey_asn1_meths
+#  undef ENGINE_register_all_pkey_asn1_meths
+#  define ENGINE_register_all_pkey_asn1_meths     ENGINE_reg_all_pkey_asn1_meths
+#  undef ENGINE_set_default_pkey_asn1_meths
+#  define ENGINE_set_default_pkey_asn1_meths      ENGINE_set_def_pkey_asn1_meths
+#  undef ENGINE_get_pkey_asn1_meth_engine
+#  define ENGINE_get_pkey_asn1_meth_engine        ENGINE_get_pkey_asn1_meth_eng
+#  undef ENGINE_set_load_ssl_client_cert_function
+#  define ENGINE_set_load_ssl_client_cert_function \
+                                                ENGINE_set_ld_ssl_clnt_cert_fn
+#  undef ENGINE_get_ssl_client_cert_function
+#  define ENGINE_get_ssl_client_cert_function     ENGINE_get_ssl_client_cert_fn
+
+/* Hack some long OCSP names */
+#  undef OCSP_REQUEST_get_ext_by_critical
+#  define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#  undef OCSP_BASICRESP_get_ext_by_critical
+#  define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
+#  undef OCSP_SINGLERESP_get_ext_by_critical
+#  define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+#  undef _ossl_old_des_ede3_cfb64_encrypt
+#  define _ossl_old_des_ede3_cfb64_encrypt        _ossl_odes_ede3_cfb64_encrypt
+#  undef _ossl_old_des_ede3_ofb64_encrypt
+#  define _ossl_old_des_ede3_ofb64_encrypt        _ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+#  undef OPENSSL_add_all_algorithms_noconf
+#  define OPENSSL_add_all_algorithms_noconf       OPENSSL_add_all_algo_noconf
+#  undef OPENSSL_add_all_algorithms_conf
+#  define OPENSSL_add_all_algorithms_conf         OPENSSL_add_all_algo_conf
+#  undef EVP_PKEY_meth_set_verify_recover
+#  define EVP_PKEY_meth_set_verify_recover        EVP_PKEY_meth_set_vrfy_recover
+
+/* Hack some long EC names */
+#  undef EC_GROUP_set_point_conversion_form
+#  define EC_GROUP_set_point_conversion_form      EC_GROUP_set_point_conv_form
+#  undef EC_GROUP_get_point_conversion_form
+#  define EC_GROUP_get_point_conversion_form      EC_GROUP_get_point_conv_form
+#  undef EC_GROUP_clear_free_all_extra_data
+#  define EC_GROUP_clear_free_all_extra_data      EC_GROUP_clr_free_all_xtra_data
+#  undef EC_KEY_set_public_key_affine_coordinates
+#  define EC_KEY_set_public_key_affine_coordinates \
+                                                EC_KEY_set_pub_key_aff_coords
+#  undef EC_POINT_set_Jprojective_coordinates_GFp
+#  define EC_POINT_set_Jprojective_coordinates_GFp \
+                                                EC_POINT_set_Jproj_coords_GFp
+#  undef EC_POINT_get_Jprojective_coordinates_GFp
+#  define EC_POINT_get_Jprojective_coordinates_GFp \
+                                                EC_POINT_get_Jproj_coords_GFp
+#  undef EC_POINT_set_affine_coordinates_GFp
+#  define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
+#  undef EC_POINT_get_affine_coordinates_GFp
+#  define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
+#  undef EC_POINT_set_compressed_coordinates_GFp
+#  define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+#  undef EC_POINT_set_affine_coordinates_GF2m
+#  define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
+#  undef EC_POINT_get_affine_coordinates_GF2m
+#  define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
+#  undef EC_POINT_set_compressed_coordinates_GF2m
+#  define EC_POINT_set_compressed_coordinates_GF2m \
+                                                EC_POINT_set_compr_coords_GF2m
+#  undef ec_GF2m_simple_group_clear_finish
+#  define ec_GF2m_simple_group_clear_finish       ec_GF2m_simple_grp_clr_finish
+#  undef ec_GF2m_simple_group_check_discriminant
+#  define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim
+#  undef ec_GF2m_simple_point_clear_finish
+#  define ec_GF2m_simple_point_clear_finish       ec_GF2m_simple_pt_clr_finish
+#  undef ec_GF2m_simple_point_set_to_infinity
+#  define ec_GF2m_simple_point_set_to_infinity    ec_GF2m_simple_pt_set_to_inf
+#  undef ec_GF2m_simple_points_make_affine
+#  define ec_GF2m_simple_points_make_affine       ec_GF2m_simple_pts_make_affine
+#  undef ec_GF2m_simple_point_set_affine_coordinates
+#  define ec_GF2m_simple_point_set_affine_coordinates \
+                                                ec_GF2m_smp_pt_set_af_coords
+#  undef ec_GF2m_simple_point_get_affine_coordinates
+#  define ec_GF2m_simple_point_get_affine_coordinates \
+                                                ec_GF2m_smp_pt_get_af_coords
+#  undef ec_GF2m_simple_set_compressed_coordinates
+#  define ec_GF2m_simple_set_compressed_coordinates \
+                                                ec_GF2m_smp_set_compr_coords
+#  undef ec_GFp_simple_group_set_curve_GFp
+#  define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
+#  undef ec_GFp_simple_group_get_curve_GFp
+#  define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#  undef ec_GFp_simple_group_clear_finish
+#  define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#  undef ec_GFp_simple_group_set_generator
+#  define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
+#  undef ec_GFp_simple_group_get0_generator
+#  define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
+#  undef ec_GFp_simple_group_get_cofactor
+#  define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#  undef ec_GFp_simple_point_clear_finish
+#  define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#  undef ec_GFp_simple_point_set_to_infinity
+#  define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
+#  undef ec_GFp_simple_points_make_affine
+#  define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#  undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+#  define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_set_Jproj_coords_GFp
+#  undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+#  define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_get_Jproj_coords_GFp
+#  undef ec_GFp_simple_point_set_affine_coordinates_GFp
+#  define ec_GFp_simple_point_set_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_set_af_coords_GFp
+#  undef ec_GFp_simple_point_get_affine_coordinates_GFp
+#  define ec_GFp_simple_point_get_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_get_af_coords_GFp
+#  undef ec_GFp_simple_set_compressed_coordinates_GFp
+#  define ec_GFp_simple_set_compressed_coordinates_GFp \
+                                                ec_GFp_smp_set_compr_coords_GFp
+#  undef ec_GFp_simple_point_set_affine_coordinates
+#  define ec_GFp_simple_point_set_affine_coordinates \
+                                                ec_GFp_smp_pt_set_af_coords
+#  undef ec_GFp_simple_point_get_affine_coordinates
+#  define ec_GFp_simple_point_get_affine_coordinates \
+                                                ec_GFp_smp_pt_get_af_coords
+#  undef ec_GFp_simple_set_compressed_coordinates
+#  define ec_GFp_simple_set_compressed_coordinates \
+                                                ec_GFp_smp_set_compr_coords
+#  undef ec_GFp_simple_group_check_discriminant
+#  define ec_GFp_simple_group_check_discriminant  ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+#  undef STORE_method_set_initialise_function
+#  define STORE_method_set_initialise_function    STORE_meth_set_initialise_fn
+#  undef STORE_method_set_cleanup_function
+#  define STORE_method_set_cleanup_function       STORE_meth_set_cleanup_fn
+#  undef STORE_method_set_generate_function
+#  define STORE_method_set_generate_function      STORE_meth_set_generate_fn
+#  undef STORE_method_set_modify_function
+#  define STORE_method_set_modify_function        STORE_meth_set_modify_fn
+#  undef STORE_method_set_revoke_function
+#  define STORE_method_set_revoke_function        STORE_meth_set_revoke_fn
+#  undef STORE_method_set_delete_function
+#  define STORE_method_set_delete_function        STORE_meth_set_delete_fn
+#  undef STORE_method_set_list_start_function
+#  define STORE_method_set_list_start_function    STORE_meth_set_list_start_fn
+#  undef STORE_method_set_list_next_function
+#  define STORE_method_set_list_next_function     STORE_meth_set_list_next_fn
+#  undef STORE_method_set_list_end_function
+#  define STORE_method_set_list_end_function      STORE_meth_set_list_end_fn
+#  undef STORE_method_set_update_store_function
+#  define STORE_method_set_update_store_function  STORE_meth_set_update_store_fn
+#  undef STORE_method_set_lock_store_function
+#  define STORE_method_set_lock_store_function    STORE_meth_set_lock_store_fn
+#  undef STORE_method_set_unlock_store_function
+#  define STORE_method_set_unlock_store_function  STORE_meth_set_unlock_store_fn
+#  undef STORE_method_get_initialise_function
+#  define STORE_method_get_initialise_function    STORE_meth_get_initialise_fn
+#  undef STORE_method_get_cleanup_function
+#  define STORE_method_get_cleanup_function       STORE_meth_get_cleanup_fn
+#  undef STORE_method_get_generate_function
+#  define STORE_method_get_generate_function      STORE_meth_get_generate_fn
+#  undef STORE_method_get_modify_function
+#  define STORE_method_get_modify_function        STORE_meth_get_modify_fn
+#  undef STORE_method_get_revoke_function
+#  define STORE_method_get_revoke_function        STORE_meth_get_revoke_fn
+#  undef STORE_method_get_delete_function
+#  define STORE_method_get_delete_function        STORE_meth_get_delete_fn
+#  undef STORE_method_get_list_start_function
+#  define STORE_method_get_list_start_function    STORE_meth_get_list_start_fn
+#  undef STORE_method_get_list_next_function
+#  define STORE_method_get_list_next_function     STORE_meth_get_list_next_fn
+#  undef STORE_method_get_list_end_function
+#  define STORE_method_get_list_end_function      STORE_meth_get_list_end_fn
+#  undef STORE_method_get_update_store_function
+#  define STORE_method_get_update_store_function  STORE_meth_get_update_store_fn
+#  undef STORE_method_get_lock_store_function
+#  define STORE_method_get_lock_store_function    STORE_meth_get_lock_store_fn
+#  undef STORE_method_get_unlock_store_function
+#  define STORE_method_get_unlock_store_function  STORE_meth_get_unlock_store_fn
+
+/* Hack some long TS names */
+#  undef TS_RESP_CTX_set_status_info_cond
+#  define TS_RESP_CTX_set_status_info_cond        TS_RESP_CTX_set_stat_info_cond
+#  undef TS_RESP_CTX_set_clock_precision_digits
+#  define TS_RESP_CTX_set_clock_precision_digits  TS_RESP_CTX_set_clk_prec_digits
+#  undef TS_CONF_set_clock_precision_digits
+#  define TS_CONF_set_clock_precision_digits      TS_CONF_set_clk_prec_digits
+
+/* Hack some long CMS names */
+#  undef CMS_RecipientInfo_ktri_get0_algs
+#  define CMS_RecipientInfo_ktri_get0_algs        CMS_RecipInfo_ktri_get0_algs
+#  undef CMS_RecipientInfo_ktri_get0_signer_id
+#  define CMS_RecipientInfo_ktri_get0_signer_id   CMS_RecipInfo_ktri_get0_sigr_id
+#  undef CMS_OtherRevocationInfoFormat_it
+#  define CMS_OtherRevocationInfoFormat_it        CMS_OtherRevocInfoFormat_it
+#  undef CMS_KeyAgreeRecipientIdentifier_it
+#  define CMS_KeyAgreeRecipientIdentifier_it      CMS_KeyAgreeRecipIdentifier_it
+#  undef CMS_OriginatorIdentifierOrKey_it
+#  define CMS_OriginatorIdentifierOrKey_it        CMS_OriginatorIdOrKey_it
+#  undef cms_SignerIdentifier_get0_signer_id
+#  define cms_SignerIdentifier_get0_signer_id     cms_SignerId_get0_signer_id
+#  undef CMS_RecipientInfo_kari_get0_orig_id
+#  define CMS_RecipientInfo_kari_get0_orig_id     CMS_RecipInfo_kari_get0_orig_id
+#  undef CMS_RecipientInfo_kari_get0_reks
+#  define CMS_RecipientInfo_kari_get0_reks        CMS_RecipInfo_kari_get0_reks
+#  undef CMS_RecipientEncryptedKey_cert_cmp
+#  define CMS_RecipientEncryptedKey_cert_cmp      CMS_RecipEncryptedKey_cert_cmp
+#  undef CMS_RecipientInfo_kari_set0_pkey
+#  define CMS_RecipientInfo_kari_set0_pkey        CMS_RecipInfo_kari_set0_pkey
+#  undef CMS_RecipientEncryptedKey_get0_id
+#  define CMS_RecipientEncryptedKey_get0_id       CMS_RecipEncryptedKey_get0_id
+#  undef CMS_RecipientInfo_kari_orig_id_cmp
+#  define CMS_RecipientInfo_kari_orig_id_cmp      CMS_RecipInfo_kari_orig_id_cmp
+
+/* Hack some long DTLS1 names */
+#  undef dtls1_retransmit_buffered_messages
+#  define dtls1_retransmit_buffered_messages      dtls1_retransmit_buffered_msgs
+
+/* Hack some long SRP names */
+#  undef SRP_generate_server_master_secret
+#  define SRP_generate_server_master_secret       SRP_gen_server_master_secret
+#  undef SRP_generate_client_master_secret
+#  define SRP_generate_client_master_secret       SRP_gen_client_master_secret
+
+/* Hack some long UI names */
+#  undef UI_method_get_prompt_constructor
+#  define UI_method_get_prompt_constructor        UI_method_get_prompt_constructr
+#  undef UI_method_set_prompt_constructor
+#  define UI_method_set_prompt_constructor        UI_method_set_prompt_constructr
+
+# endif                         /* defined OPENSSL_SYS_VMS */
+
+/* Case insensitive linking causes problems.... */
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+#  undef ERR_load_CRYPTO_strings
+#  define ERR_load_CRYPTO_strings                 ERR_load_CRYPTOlib_strings
+#  undef OCSP_crlID_new
+#  define OCSP_crlID_new                          OCSP_crlID2_new
+
+#  undef d2i_ECPARAMETERS
+#  define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#  undef i2d_ECPARAMETERS
+#  define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#  undef d2i_ECPKPARAMETERS
+#  define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#  undef i2d_ECPKPARAMETERS
+#  define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+
+/*
+ * These functions do not seem to exist! However, I'm paranoid... Original
+ * command in x509v3.h: These functions are being redefined in another
+ * directory, and clash when the linker is case-insensitive, so let's hide
+ * them a little, by giving them an extra 'o' at the beginning of the name...
+ */
+#  undef X509v3_cleanup_extensions
+#  define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#  undef X509v3_add_extension
+#  define X509v3_add_extension                    oX509v3_add_extension
+#  undef X509v3_add_netscape_extensions
+#  define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#  undef X509v3_add_standard_extensions
+#  define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+
+/* This one clashes with CMS_data_create */
+#  undef cms_Data_create
+#  define cms_Data_create                         priv_cms_Data_create
+
+# endif
+
+#endif                          /* ! defined HEADER_VMS_IDHACKS_H */
diff --git a/Cryptlib/Include/openssl/tls1.h b/Cryptlib/Include/openssl/tls1.h
new file mode 100644 (file)
index 0000000..7e237d0
--- /dev/null
@@ -0,0 +1,810 @@
+/* ssl/tls1.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-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 OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_TLS1_H
+# define HEADER_TLS1_H
+
+# include <openssl/buffer.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES    0
+
+# define TLS1_VERSION                    0x0301
+# define TLS1_1_VERSION                  0x0302
+# define TLS1_2_VERSION                  0x0303
+# define TLS_MAX_VERSION                 TLS1_2_VERSION
+
+# define TLS1_VERSION_MAJOR              0x03
+# define TLS1_VERSION_MINOR              0x01
+
+# define TLS1_1_VERSION_MAJOR            0x03
+# define TLS1_1_VERSION_MINOR            0x02
+
+# define TLS1_2_VERSION_MAJOR            0x03
+# define TLS1_2_VERSION_MINOR            0x03
+
+# define TLS1_get_version(s) \
+                ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
+
+# define TLS1_get_client_version(s) \
+                ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0)
+
+# define TLS1_AD_DECRYPTION_FAILED       21
+# define TLS1_AD_RECORD_OVERFLOW         22
+# define TLS1_AD_UNKNOWN_CA              48/* fatal */
+# define TLS1_AD_ACCESS_DENIED           49/* fatal */
+# define TLS1_AD_DECODE_ERROR            50/* fatal */
+# define TLS1_AD_DECRYPT_ERROR           51
+# define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */
+# define TLS1_AD_PROTOCOL_VERSION        70/* fatal */
+# define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */
+# define TLS1_AD_INTERNAL_ERROR          80/* fatal */
+# define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */
+# define TLS1_AD_USER_CANCELLED          90
+# define TLS1_AD_NO_RENEGOTIATION        100
+/* codes 110-114 are from RFC3546 */
+# define TLS1_AD_UNSUPPORTED_EXTENSION   110
+# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+# define TLS1_AD_UNRECOGNIZED_NAME       112
+# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+# define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */
+
+/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
+# define TLSEXT_TYPE_server_name                 0
+# define TLSEXT_TYPE_max_fragment_length         1
+# define TLSEXT_TYPE_client_certificate_url      2
+# define TLSEXT_TYPE_trusted_ca_keys             3
+# define TLSEXT_TYPE_truncated_hmac              4
+# define TLSEXT_TYPE_status_request              5
+/* ExtensionType values from RFC4681 */
+# define TLSEXT_TYPE_user_mapping                6
+/* ExtensionType values from RFC5878 */
+# define TLSEXT_TYPE_client_authz                7
+# define TLSEXT_TYPE_server_authz                8
+/* ExtensionType values from RFC6091 */
+# define TLSEXT_TYPE_cert_type           9
+
+/* ExtensionType values from RFC4492 */
+# define TLSEXT_TYPE_elliptic_curves             10
+# define TLSEXT_TYPE_ec_point_formats            11
+
+/* ExtensionType value from RFC5054 */
+# define TLSEXT_TYPE_srp                         12
+
+/* ExtensionType values from RFC5246 */
+# define TLSEXT_TYPE_signature_algorithms        13
+
+/* ExtensionType value from RFC5764 */
+# define TLSEXT_TYPE_use_srtp    14
+
+/* ExtensionType value from RFC5620 */
+# define TLSEXT_TYPE_heartbeat   15
+
+/* ExtensionType value from RFC7301 */
+# define TLSEXT_TYPE_application_layer_protocol_negotiation 16
+
+/*
+ * ExtensionType value for TLS padding extension.
+ * http://tools.ietf.org/html/draft-agl-tls-padding
+ */
+# define TLSEXT_TYPE_padding     21
+
+/* ExtensionType value from RFC4507 */
+# define TLSEXT_TYPE_session_ticket              35
+
+/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
+# if 0
+/*
+ * will have to be provided externally for now ,
+ * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
+ * using whatever extension number you'd like to try
+ */
+#  define TLSEXT_TYPE_opaque_prf_input           ??
+# endif
+
+/* Temporary extension type */
+# define TLSEXT_TYPE_renegotiate                 0xff01
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is not an IANA defined extension number */
+#  define TLSEXT_TYPE_next_proto_neg              13172
+# endif
+
+/* NameType value from RFC3546 */
+# define TLSEXT_NAMETYPE_host_name 0
+/* status request value from RFC3546 */
+# define TLSEXT_STATUSTYPE_ocsp 1
+
+/* ECPointFormat values from RFC4492 */
+# define TLSEXT_ECPOINTFORMAT_first                      0
+# define TLSEXT_ECPOINTFORMAT_uncompressed               0
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime  1
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2  2
+# define TLSEXT_ECPOINTFORMAT_last                       2
+
+/* Signature and hash algorithms from RFC5246 */
+# define TLSEXT_signature_anonymous                      0
+# define TLSEXT_signature_rsa                            1
+# define TLSEXT_signature_dsa                            2
+# define TLSEXT_signature_ecdsa                          3
+
+/* Total number of different signature algorithms */
+# define TLSEXT_signature_num                            4
+
+# define TLSEXT_hash_none                                0
+# define TLSEXT_hash_md5                                 1
+# define TLSEXT_hash_sha1                                2
+# define TLSEXT_hash_sha224                              3
+# define TLSEXT_hash_sha256                              4
+# define TLSEXT_hash_sha384                              5
+# define TLSEXT_hash_sha512                              6
+
+/* Total number of different digest algorithms */
+
+# define TLSEXT_hash_num                                 7
+
+/* Flag set for unrecognised algorithms */
+# define TLSEXT_nid_unknown                              0x1000000
+
+/* ECC curves */
+
+# define TLSEXT_curve_P_256                              23
+# define TLSEXT_curve_P_384                              24
+
+# ifndef OPENSSL_NO_TLSEXT
+
+#  define TLSEXT_MAXLEN_host_name 255
+
+const char *SSL_get_servername(const SSL *s, const int type);
+int SSL_get_servername_type(const SSL *s);
+/*
+ * SSL_export_keying_material exports a value derived from the master secret,
+ * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.) It returns 1 on success and
+ * zero otherwise.
+ */
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                               const char *label, size_t llen,
+                               const unsigned char *p, size_t plen,
+                               int use_context);
+
+int SSL_get_sigalgs(SSL *s, int idx,
+                    int *psign, int *phash, int *psignandhash,
+                    unsigned char *rsig, unsigned char *rhash);
+
+int SSL_get_shared_sigalgs(SSL *s, int idx,
+                           int *psign, int *phash, int *psignandhash,
+                           unsigned char *rsig, unsigned char *rhash);
+
+int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);
+
+#  define SSL_set_tlsext_host_name(s,name) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
+
+#  define SSL_set_tlsext_debug_callback(ssl, cb) \
+SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
+
+#  define SSL_set_tlsext_debug_arg(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_type(ssl, type) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
+
+#  define SSL_get_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#  define SSL_get_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#  define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
+
+#  define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
+
+#  define SSL_TLSEXT_ERR_OK 0
+#  define SSL_TLSEXT_ERR_ALERT_WARNING 1
+#  define SSL_TLSEXT_ERR_ALERT_FATAL 2
+#  define SSL_TLSEXT_ERR_NOACK 3
+
+#  define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
+
+#  define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+#  define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+
+#  define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
+
+#  define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
+
+#  define SSL_set_tlsext_opaque_prf_input(s, src, len) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
+#  define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
+#  define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
+
+#  define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+
+#  ifndef OPENSSL_NO_HEARTBEATS
+#   define SSL_TLSEXT_HB_ENABLED                           0x01
+#   define SSL_TLSEXT_HB_DONT_SEND_REQUESTS        0x02
+#   define SSL_TLSEXT_HB_DONT_RECV_REQUESTS        0x04
+
+#   define SSL_get_tlsext_heartbeat_pending(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL)
+#   define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
+#  endif
+# endif
+
+/* PSK ciphersuites from 4279 */
+# define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+/*
+ * Additional TLS ciphersuites from expired Internet Draft
+ * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if
+ * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c).  We
+ * actually treat them like SSL 3.0 ciphers, which we probably shouldn't.
+ * Note that the first two are actually not in the IDs.
+ */
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5          0x03000060/* not in
+                                                                    * ID */
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5      0x03000061/* not in
+                                                                    * ID */
+# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA         0x03000062
+# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA     0x03000063
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA          0x03000064
+# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA      0x03000065
+# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA                0x03000066
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_CK_RSA_WITH_AES_128_SHA                    0x0300002F
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA                 0x03000030
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA                 0x03000031
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA                0x03000032
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA                0x03000033
+# define TLS1_CK_ADH_WITH_AES_128_SHA                    0x03000034
+
+# define TLS1_CK_RSA_WITH_AES_256_SHA                    0x03000035
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA                 0x03000036
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA                 0x03000037
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA                0x03000038
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA                0x03000039
+# define TLS1_CK_ADH_WITH_AES_256_SHA                    0x0300003A
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_RSA_WITH_NULL_SHA256                    0x0300003B
+# define TLS1_CK_RSA_WITH_AES_128_SHA256                 0x0300003C
+# define TLS1_CK_RSA_WITH_AES_256_SHA256                 0x0300003D
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256              0x0300003E
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256              0x0300003F
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256             0x03000040
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA           0x03000041
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA        0x03000042
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA        0x03000043
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA       0x03000044
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA       0x03000045
+# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA           0x03000046
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256             0x03000067
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256              0x03000068
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256              0x03000069
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256             0x0300006A
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256             0x0300006B
+# define TLS1_CK_ADH_WITH_AES_128_SHA256                 0x0300006C
+# define TLS1_CK_ADH_WITH_AES_256_SHA256                 0x0300006D
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA           0x03000084
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA        0x03000085
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA        0x03000086
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA       0x03000087
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA       0x03000088
+# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA           0x03000089
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
+# define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
+# define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
+# define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
+# define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
+# define TLS1_CK_ADH_WITH_SEED_SHA                       0x0300009B
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256             0x0300009C
+# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384             0x0300009D
+# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256         0x0300009E
+# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384         0x0300009F
+# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256          0x030000A0
+# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384          0x030000A1
+# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256         0x030000A2
+# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384         0x030000A3
+# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256          0x030000A4
+# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384          0x030000A5
+# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256             0x030000A6
+# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384             0x030000A7
+
+/*
+ * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in
+ * draft 13
+ */
+# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
+# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
+# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
+# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
+# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
+
+# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
+# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
+# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
+
+# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
+# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
+# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
+
+# define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
+# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
+# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
+# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
+# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
+
+/* SRP ciphersuites from RFC 5054 */
+# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA           0x0300C01A
+# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA       0x0300C01B
+# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA       0x0300C01C
+# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA            0x0300C01D
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA        0x0300C01E
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA        0x0300C01F
+# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA            0x0300C020
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA        0x0300C021
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA        0x0300C022
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256         0x0300C023
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384         0x0300C024
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256          0x0300C025
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384          0x0300C026
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256           0x0300C027
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384           0x0300C028
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256     0x0300C02B
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384     0x0300C02C
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
+
+/*
+ * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave
+ * some DHE ciphers names with "EDH" + * instead of "DHE".  Going forward, we
+ * should be using DHE + * everywhere, though we may indefinitely maintain
+ * aliases for users + * or configurations that used "EDH" +
+ */
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5         "EXP1024-RC4-MD5"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5     "EXP1024-RC2-CBC-MD5"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA        "EXP1024-DES-CBC-SHA"
+# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA    "EXP1024-DHE-DSS-DES-CBC-SHA"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA         "EXP1024-RC4-SHA"
+# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA     "EXP1024-DHE-DSS-RC4-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA               "DHE-DSS-RC4-SHA"
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_TXT_RSA_WITH_AES_128_SHA                   "AES128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA                "DH-DSS-AES128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA                "DH-RSA-AES128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA               "DHE-DSS-AES128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA               "DHE-RSA-AES128-SHA"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA                   "ADH-AES128-SHA"
+
+# define TLS1_TXT_RSA_WITH_AES_256_SHA                   "AES256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA                "DH-DSS-AES256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA                "DH-RSA-AES256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA               "DHE-DSS-AES256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA               "DHE-RSA-AES256-SHA"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA                   "ADH-AES256-SHA"
+
+/* ECC ciphersuites from RFC4492 */
+# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
+
+/* PSK ciphersuites from RFC 4279 */
+# define TLS1_TXT_PSK_WITH_RC4_128_SHA                   "PSK-RC4-SHA"
+# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA              "PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA               "PSK-AES128-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA               "PSK-AES256-CBC-SHA"
+
+/* SRP ciphersuite from RFC 5054 */
+# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA          "SRP-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA      "SRP-RSA-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA      "SRP-DSS-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA           "SRP-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA       "SRP-RSA-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA       "SRP-DSS-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA           "SRP-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA       "SRP-RSA-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA       "SRP-DSS-AES-256-CBC-SHA"
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA          "CAMELLIA128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA       "DH-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA       "DH-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA      "DHE-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA      "DHE-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA          "ADH-CAMELLIA128-SHA"
+
+# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA          "CAMELLIA256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA       "DH-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA       "DH-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA      "DHE-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA      "DHE-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA          "ADH-CAMELLIA256-SHA"
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
+# define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
+# define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
+# define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_TXT_RSA_WITH_NULL_SHA256                   "NULL-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_128_SHA256                "AES128-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_SHA256                "AES256-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256             "DH-DSS-AES128-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256             "DH-RSA-AES128-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256            "DHE-DSS-AES128-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256            "DHE-RSA-AES128-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256             "DH-DSS-AES256-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256             "DH-RSA-AES256-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256            "DHE-DSS-AES256-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256            "DHE-RSA-AES256-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA256                "ADH-AES128-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA256                "ADH-AES256-SHA256"
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256            "AES128-GCM-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384            "AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256        "DHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384        "DHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256         "DH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384         "DH-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256        "DHE-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384        "DHE-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256         "DH-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384         "DH-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256            "ADH-AES128-GCM-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384            "ADH-AES256-GCM-SHA384"
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384    "ECDHE-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256     "ECDH-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384     "ECDH-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256      "ECDHE-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384      "ECDHE-RSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
+
+# define TLS_CT_RSA_SIGN                 1
+# define TLS_CT_DSS_SIGN                 2
+# define TLS_CT_RSA_FIXED_DH             3
+# define TLS_CT_DSS_FIXED_DH             4
+# define TLS_CT_ECDSA_SIGN               64
+# define TLS_CT_RSA_FIXED_ECDH           65
+# define TLS_CT_ECDSA_FIXED_ECDH         66
+# define TLS_CT_GOST94_SIGN              21
+# define TLS_CT_GOST01_SIGN              22
+/*
+ * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there)
+ */
+# define TLS_CT_NUMBER                   9
+
+# define TLS1_FINISH_MAC_LENGTH          12
+
+# define TLS_MD_MAX_CONST_SIZE                   20
+# define TLS_MD_CLIENT_FINISH_CONST              "client finished"
+# define TLS_MD_CLIENT_FINISH_CONST_SIZE         15
+# define TLS_MD_SERVER_FINISH_CONST              "server finished"
+# define TLS_MD_SERVER_FINISH_CONST_SIZE         15
+# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
+# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_KEY_EXPANSION_CONST              "key expansion"
+# define TLS_MD_KEY_EXPANSION_CONST_SIZE         13
+# define TLS_MD_CLIENT_WRITE_KEY_CONST           "client write key"
+# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
+# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_IV_BLOCK_CONST                   "IV block"
+# define TLS_MD_IV_BLOCK_CONST_SIZE              8
+# define TLS_MD_MASTER_SECRET_CONST              "master secret"
+# define TLS_MD_MASTER_SECRET_CONST_SIZE         13
+
+# ifdef CHARSET_EBCDIC
+#  undef TLS_MD_CLIENT_FINISH_CONST
+/*
+ * client finished
+ */
+#  define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_FINISH_CONST
+/*
+ * server finished
+ */
+#  define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_KEY_EXPANSION_CONST
+/*
+ * key expansion
+ */
+#  define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"
+
+#  undef TLS_MD_CLIENT_WRITE_KEY_CONST
+/*
+ * client write key
+ */
+#  define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_IV_BLOCK_CONST
+/*
+ * IV block
+ */
+#  define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"
+
+#  undef TLS_MD_MASTER_SECRET_CONST
+/*
+ * master secret
+ */
+#  define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
+# endif
+
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st {
+    unsigned short length;
+    void *data;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ts.h b/Cryptlib/Include/openssl/ts.h
new file mode 100644 (file)
index 0000000..a9fe40e
--- /dev/null
@@ -0,0 +1,883 @@
+/* crypto/ts/ts.h */
+/*
+ * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project
+ * 2002, 2003, 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_TS_H
+# define HEADER_TS_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_BUFFER
+#  include <openssl/buffer.h>
+# endif
+# ifndef OPENSSL_NO_EVP
+#  include <openssl/evp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.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
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef WIN32
+/* Under Win32 this is defined in wincrypt.h */
+#  undef X509_NAME
+# endif
+
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+
+/*-
+MessageImprint ::= SEQUENCE  {
+     hashAlgorithm                AlgorithmIdentifier,
+     hashedMessage                OCTET STRING  }
+*/
+
+typedef struct TS_msg_imprint_st {
+    X509_ALGOR *hash_algo;
+    ASN1_OCTET_STRING *hashed_msg;
+} TS_MSG_IMPRINT;
+
+/*-
+TimeStampReq ::= SEQUENCE  {
+   version                  INTEGER  { v1(1) },
+   messageImprint           MessageImprint,
+     --a hash algorithm OID and the hash value of the data to be
+     --time-stamped
+   reqPolicy                TSAPolicyId                OPTIONAL,
+   nonce                    INTEGER                    OPTIONAL,
+   certReq                  BOOLEAN                    DEFAULT FALSE,
+   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
+*/
+
+typedef struct TS_req_st {
+    ASN1_INTEGER *version;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_OBJECT *policy_id;     /* OPTIONAL */
+    ASN1_INTEGER *nonce;        /* OPTIONAL */
+    ASN1_BOOLEAN cert_req;      /* DEFAULT FALSE */
+    STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */
+} TS_REQ;
+
+/*-
+Accuracy ::= SEQUENCE {
+                seconds        INTEGER           OPTIONAL,
+                millis     [0] INTEGER  (1..999) OPTIONAL,
+                micros     [1] INTEGER  (1..999) OPTIONAL  }
+*/
+
+typedef struct TS_accuracy_st {
+    ASN1_INTEGER *seconds;
+    ASN1_INTEGER *millis;
+    ASN1_INTEGER *micros;
+} TS_ACCURACY;
+
+/*-
+TSTInfo ::= SEQUENCE  {
+    version                      INTEGER  { v1(1) },
+    policy                       TSAPolicyId,
+    messageImprint               MessageImprint,
+      -- MUST have the same value as the similar field in
+      -- TimeStampReq
+    serialNumber                 INTEGER,
+     -- Time-Stamping users MUST be ready to accommodate integers
+     -- up to 160 bits.
+    genTime                      GeneralizedTime,
+    accuracy                     Accuracy                 OPTIONAL,
+    ordering                     BOOLEAN             DEFAULT FALSE,
+    nonce                        INTEGER                  OPTIONAL,
+      -- MUST be present if the similar field was present
+      -- in TimeStampReq.  In that case it MUST have the same value.
+    tsa                          [0] GeneralName          OPTIONAL,
+    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
+*/
+
+typedef struct TS_tst_info_st {
+    ASN1_INTEGER *version;
+    ASN1_OBJECT *policy_id;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_INTEGER *serial;
+    ASN1_GENERALIZEDTIME *time;
+    TS_ACCURACY *accuracy;
+    ASN1_BOOLEAN ordering;
+    ASN1_INTEGER *nonce;
+    GENERAL_NAME *tsa;
+    STACK_OF(X509_EXTENSION) *extensions;
+} TS_TST_INFO;
+
+/*-
+PKIStatusInfo ::= SEQUENCE {
+    status        PKIStatus,
+    statusString  PKIFreeText     OPTIONAL,
+    failInfo      PKIFailureInfo  OPTIONAL  }
+
+From RFC 1510 - section 3.1.1:
+PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+        -- text encoded as UTF-8 String (note:  each UTF8String SHOULD
+        -- include an RFC 1766 language tag to indicate the language
+        -- of the contained text)
+*/
+
+/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
+
+# define TS_STATUS_GRANTED                       0
+# define TS_STATUS_GRANTED_WITH_MODS             1
+# define TS_STATUS_REJECTION                     2
+# define TS_STATUS_WAITING                       3
+# define TS_STATUS_REVOCATION_WARNING            4
+# define TS_STATUS_REVOCATION_NOTIFICATION       5
+
+/*
+ * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c
+ */
+
+# define TS_INFO_BAD_ALG                 0
+# define TS_INFO_BAD_REQUEST             2
+# define TS_INFO_BAD_DATA_FORMAT         5
+# define TS_INFO_TIME_NOT_AVAILABLE      14
+# define TS_INFO_UNACCEPTED_POLICY       15
+# define TS_INFO_UNACCEPTED_EXTENSION    16
+# define TS_INFO_ADD_INFO_NOT_AVAILABLE  17
+# define TS_INFO_SYSTEM_FAILURE          25
+
+typedef struct TS_status_info_st {
+    ASN1_INTEGER *status;
+    STACK_OF(ASN1_UTF8STRING) *text;
+    ASN1_BIT_STRING *failure_info;
+} TS_STATUS_INFO;
+
+DECLARE_STACK_OF(ASN1_UTF8STRING)
+DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
+
+/*-
+TimeStampResp ::= SEQUENCE  {
+     status                  PKIStatusInfo,
+     timeStampToken          TimeStampToken     OPTIONAL }
+*/
+
+typedef struct TS_resp_st {
+    TS_STATUS_INFO *status_info;
+    PKCS7 *token;
+    TS_TST_INFO *tst_info;
+} TS_RESP;
+
+/* The structure below would belong to the ESS component. */
+
+/*-
+IssuerSerial ::= SEQUENCE {
+        issuer                   GeneralNames,
+        serialNumber             CertificateSerialNumber
+        }
+*/
+
+typedef struct ESS_issuer_serial {
+    STACK_OF(GENERAL_NAME) *issuer;
+    ASN1_INTEGER *serial;
+} ESS_ISSUER_SERIAL;
+
+/*-
+ESSCertID ::=  SEQUENCE {
+        certHash                 Hash,
+        issuerSerial             IssuerSerial OPTIONAL
+}
+*/
+
+typedef struct ESS_cert_id {
+    ASN1_OCTET_STRING *hash;    /* Always SHA-1 digest. */
+    ESS_ISSUER_SERIAL *issuer_serial;
+} ESS_CERT_ID;
+
+DECLARE_STACK_OF(ESS_CERT_ID)
+DECLARE_ASN1_SET_OF(ESS_CERT_ID)
+
+/*-
+SigningCertificate ::=  SEQUENCE {
+       certs        SEQUENCE OF ESSCertID,
+       policies     SEQUENCE OF PolicyInformation OPTIONAL
+}
+*/
+
+typedef struct ESS_signing_cert {
+    STACK_OF(ESS_CERT_ID) *cert_ids;
+    STACK_OF(POLICYINFO) *policy_info;
+} ESS_SIGNING_CERT;
+
+TS_REQ *TS_REQ_new(void);
+void TS_REQ_free(TS_REQ *a);
+int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
+TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
+
+TS_REQ *TS_REQ_dup(TS_REQ *a);
+
+#ifndef OPENSSL_NO_FP_API
+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+#endif
+TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
+int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
+void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
+int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
+                                   const unsigned char **pp, long length);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+
+#ifndef OPENSSL_NO_FP_API
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+#endif
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a);
+
+TS_RESP *TS_RESP_new(void);
+void TS_RESP_free(TS_RESP *a);
+int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
+TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
+TS_RESP *TS_RESP_dup(TS_RESP *a);
+
+#ifndef OPENSSL_NO_FP_API
+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+#endif
+TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a);
+int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a);
+
+TS_STATUS_INFO *TS_STATUS_INFO_new(void);
+void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
+int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
+TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
+                                   const unsigned char **pp, long length);
+TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
+
+TS_TST_INFO *TS_TST_INFO_new(void);
+void TS_TST_INFO_free(TS_TST_INFO *a);
+int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
+TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
+                             long length);
+TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);
+
+#ifndef OPENSSL_NO_FP_API
+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+#endif
+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a);
+
+TS_ACCURACY *TS_ACCURACY_new(void);
+void TS_ACCURACY_free(TS_ACCURACY *a);
+int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
+TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
+                             long length);
+TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);
+
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
+void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
+int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp);
+ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
+                                         const unsigned char **pp,
+                                         long length);
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+
+ESS_CERT_ID *ESS_CERT_ID_new(void);
+void ESS_CERT_ID_free(ESS_CERT_ID *a);
+int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
+ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
+                             long length);
+ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);
+
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
+void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
+int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp);
+ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
+                                       const unsigned char **pp, long length);
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+
+void ERR_load_TS_strings(void);
+
+int TS_REQ_set_version(TS_REQ *a, long version);
+long TS_REQ_get_version(const TS_REQ *a);
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
+
+int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
+int TS_REQ_get_cert_req(const TS_REQ *a);
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
+void TS_REQ_ext_free(TS_REQ *a);
+int TS_REQ_get_ext_count(TS_REQ *a);
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
+
+/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
+PKCS7 *TS_RESP_get_token(TS_RESP *a);
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
+long TS_TST_INFO_get_version(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
+void TS_TST_INFO_ext_free(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
+
+/*
+ * Declarations related to response generation, defined in ts/ts_resp_sign.c.
+ */
+
+/* Optional flags for response generation. */
+
+/* Don't include the TSA name in response. */
+# define TS_TSA_NAME             0x01
+
+/* Set ordering to true in response. */
+# define TS_ORDERING             0x02
+
+/*
+ * Include the signer certificate and the other specified certificates in
+ * the ESS signing certificate attribute beside the PKCS7 signed data.
+ * Only the signer certificates is included by default.
+ */
+# define TS_ESS_CERT_ID_CHAIN    0x04
+
+/* Forward declaration. */
+struct TS_resp_ctx;
+
+/* This must return a unique number less than 160 bits long. */
+typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *);
+
+/*
+ * This must return the seconds and microseconds since Jan 1, 1970 in the sec
+ * and usec variables allocated by the caller. Return non-zero for success
+ * and zero for failure.
+ */
+typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec,
+                           long *usec);
+
+/*
+ * This must process the given extension. It can modify the TS_TST_INFO
+ * object of the context. Return values: !0 (processed), 0 (error, it must
+ * set the status info/failure info of the response).
+ */
+typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *,
+                                void *);
+
+typedef struct TS_resp_ctx {
+    X509 *signer_cert;
+    EVP_PKEY *signer_key;
+    STACK_OF(X509) *certs;      /* Certs to include in signed data. */
+    STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
+    ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
+    STACK_OF(EVP_MD) *mds;      /* Acceptable message digests. */
+    ASN1_INTEGER *seconds;      /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *millis;       /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *micros;       /* accuracy, 0 means not specified. */
+    unsigned clock_precision_digits; /* fraction of seconds in time stamp
+                                      * token. */
+    unsigned flags;             /* Optional info, see values above. */
+    /* Callback functions. */
+    TS_serial_cb serial_cb;
+    void *serial_cb_data;       /* User data for serial_cb. */
+    TS_time_cb time_cb;
+    void *time_cb_data;         /* User data for time_cb. */
+    TS_extension_cb extension_cb;
+    void *extension_cb_data;    /* User data for extension_cb. */
+    /* These members are used only while creating the response. */
+    TS_REQ *request;
+    TS_RESP *response;
+    TS_TST_INFO *tst_info;
+} TS_RESP_CTX;
+
+DECLARE_STACK_OF(EVP_MD)
+DECLARE_ASN1_SET_OF(EVP_MD)
+
+/* Creates a response context that can be used for generating responses. */
+TS_RESP_CTX *TS_RESP_CTX_new(void);
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
+
+/* No additional certs are included in the response by default. */
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
+
+/*
+ * Adds a new acceptable policy, only the default policy is accepted by
+ * default.
+ */
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
+
+/*
+ * Adds a new acceptable message digest. Note that no message digests are
+ * accepted by default. The md argument is shared with the caller.
+ */
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
+
+/* Accuracy is not included by default. */
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+                             int secs, int millis, int micros);
+
+/*
+ * Clock precision digits, i.e. the number of decimal digits: '0' means sec,
+ * '3' msec, '6' usec, and so on. Default is 0.
+ */
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+                                           unsigned clock_precision_digits);
+/* At most we accept usec precision. */
+# define TS_MAX_CLOCK_PRECISION_DIGITS   6
+
+/* No flags are set by default. */
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
+
+/* Default callback always returns a constant. */
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
+
+/* Default callback uses the gettimeofday() and gmtime() system calls. */
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
+
+/*
+ * Default callback rejects all extensions. The extension callback is called
+ * when the TS_TST_INFO object is already set up and not signed yet.
+ */
+/* FIXME: extension handling is not tested yet. */
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+                                  TS_extension_cb cb, void *data);
+
+/* The following methods can be used in the callbacks. */
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+                                int status, const char *text);
+
+/* Sets the status info only if it is still TS_STATUS_GRANTED. */
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+                                     int status, const char *text);
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
+
+/* The get methods below can be used in the extension callback. */
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
+
+/*
+ * Creates the signed TS_TST_INFO and puts it in TS_RESP.
+ * In case of errors it sets the status info properly.
+ * Returns NULL only in case of memory allocation/fatal error.
+ */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
+
+/*
+ * Declarations related to response verification,
+ * they are defined in ts/ts_resp_verify.c.
+ */
+
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+                             X509_STORE *store, X509 **signer_out);
+
+/* Context structure for the generic verify method. */
+
+/* Verify the signer's certificate and the signature of the response. */
+# define TS_VFY_SIGNATURE        (1u << 0)
+/* Verify the version number of the response. */
+# define TS_VFY_VERSION          (1u << 1)
+/* Verify if the policy supplied by the user matches the policy of the TSA. */
+# define TS_VFY_POLICY           (1u << 2)
+/*
+ * Verify the message imprint provided by the user. This flag should not be
+ * specified with TS_VFY_DATA.
+ */
+# define TS_VFY_IMPRINT          (1u << 3)
+/*
+ * Verify the message imprint computed by the verify method from the user
+ * provided data and the MD algorithm of the response. This flag should not
+ * be specified with TS_VFY_IMPRINT.
+ */
+# define TS_VFY_DATA             (1u << 4)
+/* Verify the nonce value. */
+# define TS_VFY_NONCE            (1u << 5)
+/* Verify if the TSA name field matches the signer certificate. */
+# define TS_VFY_SIGNER           (1u << 6)
+/* Verify if the TSA name field equals to the user provided name. */
+# define TS_VFY_TSA_NAME         (1u << 7)
+
+/* You can use the following convenience constants. */
+# define TS_VFY_ALL_IMPRINT      (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_IMPRINT       \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+# define TS_VFY_ALL_DATA         (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_DATA          \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+
+typedef struct TS_verify_ctx {
+    /* Set this to the union of TS_VFY_... flags you want to carry out. */
+    unsigned flags;
+    /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
+    X509_STORE *store;
+    STACK_OF(X509) *certs;
+    /* Must be set only with TS_VFY_POLICY. */
+    ASN1_OBJECT *policy;
+    /*
+     * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the
+     * algorithm from the response is used.
+     */
+    X509_ALGOR *md_alg;
+    unsigned char *imprint;
+    unsigned imprint_len;
+    /* Must be set only with TS_VFY_DATA. */
+    BIO *data;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    ASN1_INTEGER *nonce;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    GENERAL_NAME *tsa_name;
+} TS_VERIFY_CTX;
+
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
+
+/*
+ * Declarations related to response verification context,
+ * they are defined in ts/ts_verify_ctx.c.
+ */
+
+/* Set all fields to zero. */
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
+
+/*-
+ * If ctx is NULL, it allocates and returns a new object, otherwise
+ * it returns ctx. It initialises all the members as follows:
+ * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
+ * certs = NULL
+ * store = NULL
+ * policy = policy from the request or NULL if absent (in this case
+ *      TS_VFY_POLICY is cleared from flags as well)
+ * md_alg = MD algorithm from request
+ * imprint, imprint_len = imprint from request
+ * data = NULL
+ * nonce, nonce_len = nonce from the request or NULL if absent (in this case
+ *      TS_VFY_NONCE is cleared from flags as well)
+ * tsa_name = NULL
+ * Important: after calling this method TS_VFY_SIGNATURE should be added!
+ */
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
+
+/* Common utility functions defined in ts/ts_lib.c */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
+
+/*
+ * Function declarations for handling configuration options, defined in
+ * ts/ts_conf.c
+ */
+
+#ifndef OPENSSL_NO_STDIO
+X509 *TS_CONF_load_cert(const char *file);
+STACK_OF(X509) *TS_CONF_load_certs(const char *file);
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
+#endif
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+                       TS_RESP_CTX *ctx);
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+                              const char *device);
+int TS_CONF_set_default_engine(const char *name);
+#ifndef OPENSSL_NO_STDIO
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+                            const char *cert, TS_RESP_CTX *ctx);
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+                      TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+                           const char *key, const char *pass,
+                           TS_RESP_CTX *ctx);
+#endif
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+                           const char *policy, TS_RESP_CTX *ctx);
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+                                       TS_RESP_CTX *ctx);
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+                                  TS_RESP_CTX *ctx);
+
+/* -------------------------------------------------- */
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_TS_strings(void);
+
+/* Error codes for the TS functions. */
+
+/* Function codes. */
+# define TS_F_D2I_TS_RESP                                 147
+# define TS_F_DEF_SERIAL_CB                               110
+# define TS_F_DEF_TIME_CB                                 111
+# define TS_F_ESS_ADD_SIGNING_CERT                        112
+# define TS_F_ESS_CERT_ID_NEW_INIT                        113
+# define TS_F_ESS_SIGNING_CERT_NEW_INIT                   114
+# define TS_F_INT_TS_RESP_VERIFY_TOKEN                    149
+# define TS_F_PKCS7_TO_TS_TST_INFO                        148
+# define TS_F_TS_ACCURACY_SET_MICROS                      115
+# define TS_F_TS_ACCURACY_SET_MILLIS                      116
+# define TS_F_TS_ACCURACY_SET_SECONDS                     117
+# define TS_F_TS_CHECK_IMPRINTS                           100
+# define TS_F_TS_CHECK_NONCES                             101
+# define TS_F_TS_CHECK_POLICY                             102
+# define TS_F_TS_CHECK_SIGNING_CERTS                      103
+# define TS_F_TS_CHECK_STATUS_INFO                        104
+# define TS_F_TS_COMPUTE_IMPRINT                          145
+# define TS_F_TS_CONF_INVALID                             151
+# define TS_F_TS_CONF_LOAD_CERT                           153
+# define TS_F_TS_CONF_LOAD_CERTS                          154
+# define TS_F_TS_CONF_LOAD_KEY                            155
+# define TS_F_TS_CONF_LOOKUP_FAIL                         152
+# define TS_F_TS_CONF_SET_DEFAULT_ENGINE                  146
+# define TS_F_TS_GET_STATUS_TEXT                          105
+# define TS_F_TS_MSG_IMPRINT_SET_ALGO                     118
+# define TS_F_TS_REQ_SET_MSG_IMPRINT                      119
+# define TS_F_TS_REQ_SET_NONCE                            120
+# define TS_F_TS_REQ_SET_POLICY_ID                        121
+# define TS_F_TS_RESP_CREATE_RESPONSE                     122
+# define TS_F_TS_RESP_CREATE_TST_INFO                     123
+# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO                124
+# define TS_F_TS_RESP_CTX_ADD_MD                          125
+# define TS_F_TS_RESP_CTX_ADD_POLICY                      126
+# define TS_F_TS_RESP_CTX_NEW                             127
+# define TS_F_TS_RESP_CTX_SET_ACCURACY                    128
+# define TS_F_TS_RESP_CTX_SET_CERTS                       129
+# define TS_F_TS_RESP_CTX_SET_DEF_POLICY                  130
+# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT                 131
+# define TS_F_TS_RESP_CTX_SET_STATUS_INFO                 132
+# define TS_F_TS_RESP_GET_POLICY                          133
+# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION          134
+# define TS_F_TS_RESP_SET_STATUS_INFO                     135
+# define TS_F_TS_RESP_SET_TST_INFO                        150
+# define TS_F_TS_RESP_SIGN                                136
+# define TS_F_TS_RESP_VERIFY_SIGNATURE                    106
+# define TS_F_TS_RESP_VERIFY_TOKEN                        107
+# define TS_F_TS_TST_INFO_SET_ACCURACY                    137
+# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT                 138
+# define TS_F_TS_TST_INFO_SET_NONCE                       139
+# define TS_F_TS_TST_INFO_SET_POLICY_ID                   140
+# define TS_F_TS_TST_INFO_SET_SERIAL                      141
+# define TS_F_TS_TST_INFO_SET_TIME                        142
+# define TS_F_TS_TST_INFO_SET_TSA                         143
+# define TS_F_TS_VERIFY                                   108
+# define TS_F_TS_VERIFY_CERT                              109
+# define TS_F_TS_VERIFY_CTX_NEW                           144
+
+/* Reason codes. */
+# define TS_R_BAD_PKCS7_TYPE                              132
+# define TS_R_BAD_TYPE                                    133
+# define TS_R_CANNOT_LOAD_CERT                            137
+# define TS_R_CANNOT_LOAD_KEY                             138
+# define TS_R_CERTIFICATE_VERIFY_ERROR                    100
+# define TS_R_COULD_NOT_SET_ENGINE                        127
+# define TS_R_COULD_NOT_SET_TIME                          115
+# define TS_R_D2I_TS_RESP_INT_FAILED                      128
+# define TS_R_DETACHED_CONTENT                            134
+# define TS_R_ESS_ADD_SIGNING_CERT_ERROR                  116
+# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR               101
+# define TS_R_INVALID_NULL_POINTER                        102
+# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE          117
+# define TS_R_MESSAGE_IMPRINT_MISMATCH                    103
+# define TS_R_NONCE_MISMATCH                              104
+# define TS_R_NONCE_NOT_RETURNED                          105
+# define TS_R_NO_CONTENT                                  106
+# define TS_R_NO_TIME_STAMP_TOKEN                         107
+# define TS_R_PKCS7_ADD_SIGNATURE_ERROR                   118
+# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR                 119
+# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED                 129
+# define TS_R_POLICY_MISMATCH                             108
+# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE      120
+# define TS_R_RESPONSE_SETUP_ERROR                        121
+# define TS_R_SIGNATURE_FAILURE                           109
+# define TS_R_THERE_MUST_BE_ONE_SIGNER                    110
+# define TS_R_TIME_SYSCALL_ERROR                          122
+# define TS_R_TOKEN_NOT_PRESENT                           130
+# define TS_R_TOKEN_PRESENT                               131
+# define TS_R_TSA_NAME_MISMATCH                           111
+# define TS_R_TSA_UNTRUSTED                               112
+# define TS_R_TST_INFO_SETUP_ERROR                        123
+# define TS_R_TS_DATASIGN                                 124
+# define TS_R_UNACCEPTABLE_POLICY                         125
+# define TS_R_UNSUPPORTED_MD_ALGORITHM                    126
+# define TS_R_UNSUPPORTED_VERSION                         113
+# define TS_R_VAR_BAD_VALUE                               135
+# define TS_R_VAR_LOOKUP_FAILURE                          136
+# define TS_R_WRONG_CONTENT_TYPE                          114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/txt_db.h b/Cryptlib/Include/openssl/txt_db.h
new file mode 100644 (file)
index 0000000..98e23a2
--- /dev/null
@@ -0,0 +1,112 @@
+/* crypto/txt_db/txt_db.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_TXT_DB_H
+# define HEADER_TXT_DB_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/lhash.h>
+
+# define DB_ERROR_OK                     0
+# define DB_ERROR_MALLOC                 1
+# define DB_ERROR_INDEX_CLASH            2
+# define DB_ERROR_INDEX_OUT_OF_RANGE     3
+# define DB_ERROR_NO_INDEX               4
+# define DB_ERROR_INSERT_INDEX_CLASH     5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
+typedef struct txt_db_st {
+    int num_fields;
+    STACK_OF(OPENSSL_PSTRING) *data;
+    LHASH_OF(OPENSSL_STRING) **index;
+    int (**qual) (OPENSSL_STRING *);
+    long error;
+    long arg1;
+    long arg2;
+    OPENSSL_STRING *arg_row;
+} TXT_DB;
+
+# ifndef OPENSSL_NO_BIO
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+# else
+TXT_DB *TXT_DB_read(char *in, int num);
+long TXT_DB_write(char *out, TXT_DB *db);
+# endif
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
+                        LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+void TXT_DB_free(TXT_DB *db);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
+                                    OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/ui.h b/Cryptlib/Include/openssl/ui.h
new file mode 100644 (file)
index 0000000..0dc1633
--- /dev/null
@@ -0,0 +1,415 @@
+/* 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_H
+# define HEADER_UI_H
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/crypto.h>
+# endif
+# include <openssl/safestack.h>
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct ui_st UI; */
+/* typedef struct ui_method_st UI_METHOD; */
+
+/*
+ * All the following functions return -1 or NULL on error and in some cases
+ * (UI_process()) -2 if interrupted or in some other way cancelled. When
+ * everything is fine, they return 0, a positive value or a non-NULL pointer,
+ * all depending on their purpose.
+ */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/*-
+   The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}_<function>_string have the following meanings:
+        add     add a text or prompt string.  The pointers given to these
+                functions are used verbatim, no copying is done.
+        dup     make a copy of the text or prompt string, then add the copy
+                to the collection of strings in the user interface.
+        <function>
+                The function is a name for the functionality that the given
+                string shall be used for.  It can be one of:
+                        input   use the string as data prompt.
+                        verify  use the string as verification prompt.  This
+                                is used to verify a previous input.
+                        info    use the string for informational output.
+                        error   use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is usefull when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+                         char *result_buf, int minsize, int maxsize,
+                         const char *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);
+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);
+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);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+# define UI_INPUT_FLAG_ECHO              0x01
+/*
+ * Use a default password.  Where that password is found is completely up to
+ * the application, it might for example be in the user data set with
+ * UI_add_user_data().  It is not recommended to have more than one input in
+ * each UI being marked with this flag, or the application might get
+ * confused.
+ */
+# define UI_INPUT_FLAG_DEFAULT_PWD       0x02
+
+/*-
+ * The user of these routines may want to define flags of their own.  The core
+ * UI won't look at those, but will pass them on to the method routines.  They
+ * must use higher bits so they don't get confused with the UI bits above.
+ * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+ * example of use is this:
+ *
+ *    #define MY_UI_FLAG1       (0x01 << UI_INPUT_FLAG_USER_BASE)
+ *
+*/
+# define UI_INPUT_FLAG_USER_BASE 16
+
+/*-
+ * The following function helps construct a prompt.  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().
+ *
+ * If the ui_method doesn't contain a pointer to a user-defined prompt
+ * constructor, a default string is built, looking like this:
+ *
+ *       "Enter {object_desc} for {object_name}:"
+ *
+ * So, if object_desc has the value "pass phrase" and object_name has
+ * the value "foo.key", the resulting string is:
+ *
+ *       "Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+                          const char *object_desc, const char *object_name);
+
+/*
+ * The following function is used to store a pointer to user-specific data.
+ * Any previous such pointer will be returned and replaced.
+ *
+ * For callback purposes, this function makes a lot more sense than using
+ * ex_data, since the latter requires that different parts of OpenSSL or
+ * applications share the same ex_data index.
+ *
+ * Note that the UI_OpenSSL() method completely ignores the user data. Other
+ * methods may not, however.
+ */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/*
+ * Give a user interface parametrised control commands.  This can be used to
+ * send down an integer, a data pointer or a function pointer, as well as be
+ * used to get information from a UI.
+ */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void));
+
+/* The commands */
+/*
+ * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+ * OpenSSL error stack before printing any info or added error messages and
+ * before any prompting.
+ */
+# define UI_CTRL_PRINT_ERRORS            1
+/*
+ * Check if a UI_process() is possible to do again with the same instance of
+ * a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+ * if not.
+ */
+# define UI_CTRL_IS_REDOABLE             2
+
+/* Some methods may use extra data */
+# define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+# define UI_get_app_data(s)             UI_get_ex_data(s,0)
+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);
+int UI_set_ex_data(UI *r, int idx, void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+/* ---------- For method writers ---------- */
+/*-
+   A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+        an opener       This function starts a session, maybe by opening
+                        a channel to a tty, or by opening a window.
+        a writer        This function is called to write a given string,
+                        maybe to the tty, maybe as a field label in a
+                        window.
+        a flusher       This function is called to flush everything that
+                        has been output so far.  It can be used to actually
+                        display a dialog box after it has been built.
+        a reader        This function is called to read a given prompt,
+                        maybe from the tty, maybe from a field in a
+                        window.  Note that it's called wth all string
+                        structures, not only the prompt ones, so it must
+                        check such things itself.
+        a closer        This function closes the session, maybe by closing
+                        the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+        0       on error.
+        1       on success.
+        -1      on out-of-band events, for example if some prompting has
+                been canceled (by pressing Ctrl-C, for example).  This is
+                only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/*
+ * The UI_STRING type is the data structure that contains all the needed info
+ * about a string or a prompt, including test data for a verification prompt.
+ */
+typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
+
+/*
+ * The different types of strings that are currently supported. This is only
+ * needed by method authors.
+ */
+enum UI_string_types {
+    UIT_NONE = 0,
+    UIT_PROMPT,                 /* Prompt for a string */
+    UIT_VERIFY,                 /* Prompt for a string and verify */
+    UIT_BOOLEAN,                /* Prompt for a yes/no response */
+    UIT_INFO,                   /* Send info to the user */
+    UIT_ERROR                   /* Send an error message to the user */
+};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui));
+int UI_method_set_writer(UI_METHOD *method,
+                         int (*writer) (UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui));
+int UI_method_set_reader(UI_METHOD *method,
+                         int (*reader) (UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method,
+                                     char *(*prompt_constructor) (UI *ui,
+                                                                  const char
+                                                                  *object_desc,
+                                                                  const char
+                                                                  *object_name));
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *);
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *);
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *);
+char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
+                                                              const char *,
+                                                              const char *);
+
+/*
+ * The following functions are helpers for method writers to access relevant
+ * data from a UI_STRING.
+ */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/*
+ * Return the optional action string to output (the boolean promtp
+ * instruction)
+ */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/*
+ * Return the string to test the result against.  Only useful with verifies.
+ */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
+                           int verify);
+int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
+                    int verify);
+
+/* 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_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+# define UI_F_GENERAL_ALLOCATE_BOOLEAN                    108
+# define UI_F_GENERAL_ALLOCATE_PROMPT                     109
+# define UI_F_GENERAL_ALLOCATE_STRING                     100
+# define UI_F_UI_CTRL                                     111
+# define UI_F_UI_DUP_ERROR_STRING                         101
+# define UI_F_UI_DUP_INFO_STRING                          102
+# define UI_F_UI_DUP_INPUT_BOOLEAN                        110
+# define UI_F_UI_DUP_INPUT_STRING                         103
+# define UI_F_UI_DUP_VERIFY_STRING                        106
+# define UI_F_UI_GET0_RESULT                              107
+# define UI_F_UI_NEW_METHOD                               104
+# define UI_F_UI_SET_RESULT                               105
+
+/* Reason codes. */
+# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS             104
+# define UI_R_INDEX_TOO_LARGE                             102
+# define UI_R_INDEX_TOO_SMALL                             103
+# define UI_R_NO_RESULT_BUFFER                            105
+# define UI_R_RESULT_TOO_LARGE                            100
+# define UI_R_RESULT_TOO_SMALL                            101
+# define UI_R_UNKNOWN_CONTROL_COMMAND                     106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/ui_compat.h b/Cryptlib/Include/openssl/ui_compat.h
new file mode 100644 (file)
index 0000000..bf54154
--- /dev/null
@@ -0,0 +1,88 @@
+/* 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_COMPAT_H
+# define HEADER_UI_COMPAT_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/ui.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following functions were previously part of the DES section, and are
+ * provided here for backward compatibility reasons.
+ */
+
+# define des_read_pw_string(b,l,p,v) \
+        _ossl_old_des_read_pw_string((b),(l),(p),(v))
+# define des_read_pw(b,bf,s,p,v) \
+        _ossl_old_des_read_pw((b),(bf),(s),(p),(v))
+
+int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt,
+                                 int verify);
+int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt,
+                          int verify);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/whrlpool.h b/Cryptlib/Include/openssl/whrlpool.h
new file mode 100644 (file)
index 0000000..73c749d
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef HEADER_WHRLPOOL_H
+# define HEADER_WHRLPOOL_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define WHIRLPOOL_DIGEST_LENGTH (512/8)
+# define WHIRLPOOL_BBLOCK        512
+# define WHIRLPOOL_COUNTER       (256/8)
+
+typedef struct {
+    union {
+        unsigned char c[WHIRLPOOL_DIGEST_LENGTH];
+        /* double q is here to ensure 64-bit alignment */
+        double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)];
+    } H;
+    unsigned char data[WHIRLPOOL_BBLOCK / 8];
+    unsigned int bitoff;
+    size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)];
+} WHIRLPOOL_CTX;
+
+# ifndef OPENSSL_NO_WHIRLPOOL
+#  ifdef OPENSSL_FIPS
+int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+#  endif
+int WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes);
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits);
+int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c);
+unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md);
+# endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/Include/openssl/x509.h b/Cryptlib/Include/openssl/x509.h
new file mode 100644 (file)
index 0000000..fc613ce
--- /dev/null
@@ -0,0 +1,1328 @@
+/* crypto/x509/x509.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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+# define HEADER_X509_H
+
+# include <openssl/e_os2.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_BUFFER
+#  include <openssl/buffer.h>
+# endif
+# ifndef OPENSSL_NO_EVP
+#  include <openssl/evp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+
+# ifndef OPENSSL_NO_EC
+#  include <openssl/ec.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDSA
+#  include <openssl/ecdsa.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDH
+#  include <openssl/ecdh.h>
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  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
+# endif
+
+# ifndef OPENSSL_NO_SHA
+#  include <openssl/sha.h>
+# endif
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#  undef X509_NAME
+#  undef X509_CERT_PAIR
+#  undef X509_EXTENSIONS
+# endif
+
+# define X509_FILETYPE_PEM       1
+# define X509_FILETYPE_ASN1      2
+# define X509_FILETYPE_DEFAULT   3
+
+# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
+# define X509v3_KU_NON_REPUDIATION       0x0040
+# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
+# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
+# define X509v3_KU_KEY_AGREEMENT         0x0008
+# define X509v3_KU_KEY_CERT_SIGN         0x0004
+# define X509v3_KU_CRL_SIGN              0x0002
+# define X509v3_KU_ENCIPHER_ONLY         0x0001
+# define X509v3_KU_DECIPHER_ONLY         0x8000
+# define X509v3_KU_UNDEF                 0xffff
+
+typedef struct X509_objects_st {
+    int nid;
+    int (*a2i) (void);
+    int (*i2a) (void);
+} X509_OBJECTS;
+
+struct X509_algor_st {
+    ASN1_OBJECT *algorithm;
+    ASN1_TYPE *parameter;
+} /* X509_ALGOR */ ;
+
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef STACK_OF(X509_ALGOR) X509_ALGORS;
+
+typedef struct X509_val_st {
+    ASN1_TIME *notBefore;
+    ASN1_TIME *notAfter;
+} X509_VAL;
+
+struct X509_pubkey_st {
+    X509_ALGOR *algor;
+    ASN1_BIT_STRING *public_key;
+    EVP_PKEY *pkey;
+};
+
+typedef struct X509_sig_st {
+    X509_ALGOR *algor;
+    ASN1_OCTET_STRING *digest;
+} X509_SIG;
+
+typedef struct X509_name_entry_st {
+    ASN1_OBJECT *object;
+    ASN1_STRING *value;
+    int set;
+    int size;                   /* temp variable */
+} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st {
+    STACK_OF(X509_NAME_ENTRY) *entries;
+    int modified;               /* true if 'bytes' needs to be built */
+# ifndef OPENSSL_NO_BUFFER
+    BUF_MEM *bytes;
+# else
+    char *bytes;
+# endif
+/*      unsigned long hash; Keep the hash around for lookups */
+    unsigned char *canon_enc;
+    int canon_enclen;
+} /* X509_NAME */ ;
+
+DECLARE_STACK_OF(X509_NAME)
+
+# define X509_EX_V_NETSCAPE_HACK         0x8000
+# define X509_EX_V_INIT                  0x0001
+typedef struct X509_extension_st {
+    ASN1_OBJECT *object;
+    ASN1_BOOLEAN critical;
+    ASN1_OCTET_STRING *value;
+} X509_EXTENSION;
+
+typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st {
+    ASN1_OBJECT *object;
+    int single;                 /* 0 for a set, 1 for a single item (which is
+                                 * wrong) */
+    union {
+        char *ptr;
+        /*
+         * 0
+         */ STACK_OF(ASN1_TYPE) *set;
+        /*
+         * 1
+         */ ASN1_TYPE *single;
+    } value;
+} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+typedef struct X509_req_info_st {
+    ASN1_ENCODING enc;
+    ASN1_INTEGER *version;
+    X509_NAME *subject;
+    X509_PUBKEY *pubkey;
+    /*  d=2 hl=2 l=  0 cons: cont: 00 */
+    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+} X509_REQ_INFO;
+
+typedef struct X509_req_st {
+    X509_REQ_INFO *req_info;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int references;
+} X509_REQ;
+
+typedef struct x509_cinf_st {
+    ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
+    ASN1_INTEGER *serialNumber;
+    X509_ALGOR *signature;
+    X509_NAME *issuer;
+    X509_VAL *validity;
+    X509_NAME *subject;
+    X509_PUBKEY *key;
+    ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
+    ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
+    STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
+    ASN1_ENCODING enc;
+} X509_CINF;
+
+/*
+ * This stuff is certificate "auxiliary info" it contains details which are
+ * useful in certificate stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st {
+    STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
+    STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
+    ASN1_UTF8STRING *alias;     /* "friendly name" */
+    ASN1_OCTET_STRING *keyid;   /* key id of private key */
+    STACK_OF(X509_ALGOR) *other; /* other unspecified info */
+} X509_CERT_AUX;
+
+struct x509_st {
+    X509_CINF *cert_info;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int valid;
+    int references;
+    char *name;
+    CRYPTO_EX_DATA ex_data;
+    /* These contain copies of various extension values */
+    long ex_pathlen;
+    long ex_pcpathlen;
+    unsigned long ex_flags;
+    unsigned long ex_kusage;
+    unsigned long ex_xkusage;
+    unsigned long ex_nscert;
+    ASN1_OCTET_STRING *skid;
+    AUTHORITY_KEYID *akid;
+    X509_POLICY_CACHE *policy_cache;
+    STACK_OF(DIST_POINT) *crldp;
+    STACK_OF(GENERAL_NAME) *altname;
+    NAME_CONSTRAINTS *nc;
+# ifndef OPENSSL_NO_RFC3779
+    STACK_OF(IPAddressFamily) *rfc3779_addr;
+    struct ASIdentifiers_st *rfc3779_asid;
+# endif
+# ifndef OPENSSL_NO_SHA
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+    X509_CERT_AUX *aux;
+} /* X509 */ ;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+    int trust;
+    int flags;
+    int (*check_trust) (struct x509_trust_st *, X509 *, int);
+    char *name;
+    int arg1;
+    void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+    X509 *forward;
+    X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+# define X509_TRUST_DEFAULT      -1/* Only valid in purpose settings */
+
+# define X509_TRUST_COMPAT       1
+# define X509_TRUST_SSL_CLIENT   2
+# define X509_TRUST_SSL_SERVER   3
+# define X509_TRUST_EMAIL        4
+# define X509_TRUST_OBJECT_SIGN  5
+# define X509_TRUST_OCSP_SIGN    6
+# define X509_TRUST_OCSP_REQUEST 7
+# define X509_TRUST_TSA          8
+
+/* Keep these up to date! */
+# define X509_TRUST_MIN          1
+# define X509_TRUST_MAX          8
+
+/* trust_flags values */
+# define X509_TRUST_DYNAMIC      1
+# define X509_TRUST_DYNAMIC_NAME 2
+
+/* check_trust return codes */
+
+# define X509_TRUST_TRUSTED      1
+# define X509_TRUST_REJECTED     2
+# define X509_TRUST_UNTRUSTED    3
+
+/* Flags for X509_print_ex() */
+
+# define X509_FLAG_COMPAT                0
+# define X509_FLAG_NO_HEADER             1L
+# define X509_FLAG_NO_VERSION            (1L << 1)
+# define X509_FLAG_NO_SERIAL             (1L << 2)
+# define X509_FLAG_NO_SIGNAME            (1L << 3)
+# define X509_FLAG_NO_ISSUER             (1L << 4)
+# define X509_FLAG_NO_VALIDITY           (1L << 5)
+# define X509_FLAG_NO_SUBJECT            (1L << 6)
+# define X509_FLAG_NO_PUBKEY             (1L << 7)
+# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
+# define X509_FLAG_NO_SIGDUMP            (1L << 9)
+# define X509_FLAG_NO_AUX                (1L << 10)
+# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
+# define X509_FLAG_NO_IDS                (1L << 12)
+
+/* Flags specific to X509_NAME_print_ex() */
+
+/* The field separator information */
+
+# define XN_FLAG_SEP_MASK        (0xf << 16)
+
+# define XN_FLAG_COMPAT          0/* Traditional SSLeay: use old
+                                   * X509_NAME_print */
+# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
+# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
+# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
+# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */
+
+# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */
+
+/* How the field name is shown */
+
+# define XN_FLAG_FN_MASK         (0x3 << 21)
+
+# define XN_FLAG_FN_SN           0/* Object short name */
+# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
+# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
+# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */
+
+# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */
+
+/*
+ * This determines if we dump fields we don't recognise: RFC2253 requires
+ * this.
+ */
+
+# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
+                                           * characters */
+
+/* Complete set of RFC2253 flags */
+
+# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+                        XN_FLAG_SEP_COMMA_PLUS | \
+                        XN_FLAG_DN_REV | \
+                        XN_FLAG_FN_SN | \
+                        XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+                        ASN1_STRFLGS_ESC_QUOTE | \
+                        XN_FLAG_SEP_CPLUS_SPC | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+                        ASN1_STRFLGS_ESC_MSB | \
+                        XN_FLAG_SEP_MULTILINE | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_LN | \
+                        XN_FLAG_FN_ALIGN)
+
+struct x509_revoked_st {
+    ASN1_INTEGER *serialNumber;
+    ASN1_TIME *revocationDate;
+    STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+    /* Set up if indirect CRL */
+    STACK_OF(GENERAL_NAME) *issuer;
+    /* Revocation reason */
+    int reason;
+    int sequence;               /* load sequence */
+};
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st {
+    ASN1_INTEGER *version;
+    X509_ALGOR *sig_alg;
+    X509_NAME *issuer;
+    ASN1_TIME *lastUpdate;
+    ASN1_TIME *nextUpdate;
+    STACK_OF(X509_REVOKED) *revoked;
+    STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+    ASN1_ENCODING enc;
+} X509_CRL_INFO;
+
+struct X509_crl_st {
+    /* actual signature */
+    X509_CRL_INFO *crl;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int references;
+    int flags;
+    /* Copies of various extensions */
+    AUTHORITY_KEYID *akid;
+    ISSUING_DIST_POINT *idp;
+    /* Convenient breakdown of IDP */
+    int idp_flags;
+    int idp_reasons;
+    /* CRL and base CRL numbers for delta processing */
+    ASN1_INTEGER *crl_number;
+    ASN1_INTEGER *base_crl_number;
+# ifndef OPENSSL_NO_SHA
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+    STACK_OF(GENERAL_NAMES) *issuers;
+    const X509_CRL_METHOD *meth;
+    void *meth_data;
+} /* X509_CRL */ ;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st {
+    int version;
+    /* The PKCS#8 data types */
+    X509_ALGOR *enc_algor;
+    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
+    /* When decrypted, the following will not be NULL */
+    EVP_PKEY *dec_pkey;
+    /* used to encrypt and decrypt */
+    int key_length;
+    char *key_data;
+    int key_free;               /* true if we should auto free key_data */
+    /* expanded version of 'enc_algor' */
+    EVP_CIPHER_INFO cipher;
+    int references;
+} X509_PKEY;
+
+# ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st {
+    X509 *x509;
+    X509_CRL *crl;
+    X509_PKEY *x_pkey;
+    EVP_CIPHER_INFO enc_cipher;
+    int enc_len;
+    char *enc_data;
+    int references;
+} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+# endif
+
+/*
+ * The next 2 structures and their 8 routines were sent to me by Pat Richard
+ * <patr@x509.com> and are used to manipulate Netscapes spki structures -
+ * useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st {
+    X509_PUBKEY *pubkey;
+    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
+} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st {
+    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
+    X509_ALGOR *sig_algor;
+    ASN1_BIT_STRING *signature;
+} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence {
+    ASN1_OBJECT *type;
+    STACK_OF(X509) *certs;
+} NETSCAPE_CERT_SEQUENCE;
+
+/*- Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+        {
+        unsigned char iv[8];
+        } CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+    X509_ALGOR *keyfunc;
+    X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+/* Usually OCTET STRING but could be anything */
+    ASN1_TYPE *salt;
+    ASN1_INTEGER *iter;
+    ASN1_INTEGER *keylength;
+    X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+/* PKCS#8 private key info structure */
+
+struct pkcs8_priv_key_info_st {
+    /* Flag for various broken formats */
+    int broken;
+# define PKCS8_OK                0
+# define PKCS8_NO_OCTET          1
+# define PKCS8_EMBEDDED_PARAM    2
+# define PKCS8_NS_DB             3
+# define PKCS8_NEG_PRIVKEY       4
+    ASN1_INTEGER *version;
+    X509_ALGOR *pkeyalg;
+    /* Should be OCTET STRING but some are broken */
+    ASN1_TYPE *pkey;
+    STACK_OF(X509_ATTRIBUTE) *attributes;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+
+# include <openssl/x509_vfy.h>
+# include <openssl/pkcs7.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define X509_EXT_PACK_UNKNOWN   1
+# define X509_EXT_PACK_STRING    2
+
+# define         X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define      X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+# define         X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+# define         X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
+# define         X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+# define         X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
+# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))
+# define         X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+# define         X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+# define         X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+# define         X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+# define         X509_CRL_get_issuer(x) ((x)->crl->issuer)
+# define         X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+                                     int (*crl_free) (X509_CRL *crl),
+                                     int (*crl_lookup) (X509_CRL *crl,
+                                                        X509_REVOKED **ret,
+                                                        ASN1_INTEGER *ser,
+                                                        X509_NAME *issuer),
+                                     int (*crl_verify) (X509_CRL *crl,
+                                                        EVP_PKEY *pk));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
+/*
+ * This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
+ */
+# define         X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+const char *X509_verify_cert_error_string(long n);
+
+# ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
+int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+                       unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data, const EVP_MD *type,
+                unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+                     unsigned char *md, unsigned int *len);
+# endif
+
+# ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp, X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+                                                PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp, X509 **x509);
+int i2d_X509_bio(BIO *bp, X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+                                                 PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+# endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
+                    void *pval);
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+                     X509_ALGOR *algor);
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+int X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int X509_cmp_current_time(const ASN1_TIME *s);
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+                            int offset_day, long offset_sec, time_t *t);
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *X509_get_default_cert_area(void);
+const char *X509_get_default_cert_dir(void);
+const char *X509_get_default_cert_file(void);
+const char *X509_get_default_cert_dir_env(void);
+const char *X509_get_default_cert_file_env(void);
+const char *X509_get_default_private_dir(void);
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
+# ifndef OPENSSL_NO_RSA
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_DSA
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_EC
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
+# endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+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);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int i2d_X509_AUX(X509 *a, unsigned char **pp);
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
+
+void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+                         const X509 *x);
+int X509_get_signature_nid(const X509 *x);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char *X509_alias_get0(X509 *x, int *len);
+unsigned char *X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+                                                                int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+                            X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+
+X509_PKEY *X509_PKEY_new(void);
+void X509_PKEY_free(X509_PKEY *a);
+int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
+X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
+                         long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+# ifndef OPENSSL_NO_EVP
+X509_INFO *X509_INFO_new(void);
+void X509_INFO_free(X509_INFO *a);
+char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+                unsigned char *md, unsigned int *len);
+
+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);
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
+                     unsigned char *md, unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                     ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
+                   EVP_PKEY *pkey, const EVP_MD *type);
+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);
+# endif
+
+int X509_set_version(X509 *x, long version);
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *X509_get_serialNumber(X509 *x);
+int X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_issuer_name(X509 *a);
+int X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_subject_name(X509 *a);
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
+int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );
+
+int X509_REQ_set_version(X509_REQ *x, long version);
+int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
+int X509_REQ_extension_nid(int nid);
+int *X509_REQ_get_extension_nids(void);
+void X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+                                int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);
+
+int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
+
+int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
+int X509_chain_check_suiteb(int *perror_depth,
+                            X509 *x, STACK_OF(X509) *chain,
+                            unsigned long flags);
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_and_serial_hash(X509 *a);
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_name_hash(X509 *a);
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_subject_name_hash(X509 *x);
+
+# ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *a);
+unsigned long X509_subject_name_hash_old(X509 *x);
+# endif
+
+int X509_cmp(const X509 *a, const X509 *b);
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long X509_NAME_hash(X509_NAME *x);
+unsigned long X509_NAME_hash_old(X509_NAME *x);
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+# ifndef OPENSSL_NO_FP_API
+int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
+                     unsigned long cflag);
+int X509_print_fp(FILE *bp, X509 *x);
+int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
+int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+                          unsigned long flags);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+                       unsigned long flags);
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
+                  unsigned long cflag);
+int X509_print(BIO *bp, X509 *x);
+int X509_ocspid_print(BIO *bp, X509 *x);
+int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
+int X509_CRL_print(BIO *bp, X509_CRL *x);
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
+                      unsigned long cflag);
+int X509_REQ_print(BIO *bp, X509_REQ *req);
+# endif
+
+int X509_NAME_entry_count(X509_NAME *name);
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+                              char *buf, int len);
+
+/*
+ * NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on.
+ */
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+                               int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
+                        int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+                               unsigned char *bytes, int len, int loc,
+                               int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+                               unsigned char *bytes, int len, int loc,
+                               int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+                                               const char *field, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+                                               int type, unsigned char *bytes,
+                                               int len);
+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 *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+                                               ASN1_OBJECT *obj, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+                             const unsigned char *bytes, int len);
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+                          int nid, int lastpos);
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+                          ASN1_OBJECT *obj, int lastpos);
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+                               int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+                                         X509_EXTENSION *ex, int loc);
+
+int X509_get_ext_count(X509 *x);
+int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
+int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                      unsigned long flags);
+
+int X509_CRL_get_ext_count(X509_CRL *x);
+int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
+int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                          unsigned long flags);
+
+int X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
+                                int lastpos);
+int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                              unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+                                             int nid, int crit,
+                                             ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+                                             ASN1_OBJECT *obj, int crit,
+                                             ASN1_OCTET_STRING *data);
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+                           int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+                           ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+                                           X509_ATTRIBUTE *attr);
+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);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, int nid, int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+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);
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
+                              int lastpos, int type);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+                                             const ASN1_OBJECT *obj,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+                                             const char *atrname, int type,
+                                             const unsigned char *bytes,
+                                             int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+                             const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
+                               void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+                                     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+                         const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+                          const unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                           unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+                              unsigned char *salt, int saltlen,
+                              unsigned char *aiv, int prf_nid);
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+                             int prf_nid, int keylen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                    int version, int ptype, void *pval,
+                    unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+                    const unsigned char **pk, int *ppklen,
+                    X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+                           int ptype, void *pval,
+                           unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+                           const unsigned char **pk, int *ppklen,
+                           X509_ALGOR **pa, X509_PUBKEY *pub);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST *X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+                   char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* 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_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+# define X509_F_ADD_CERT_DIR                              100
+# define X509_F_BY_FILE_CTRL                              101
+# define X509_F_CHECK_POLICY                              145
+# define X509_F_DIR_CTRL                                  102
+# define X509_F_GET_CERT_BY_SUBJECT                       103
+# define X509_F_NETSCAPE_SPKI_B64_DECODE                  129
+# define X509_F_NETSCAPE_SPKI_B64_ENCODE                  130
+# define X509_F_X509AT_ADD1_ATTR                          135
+# define X509_F_X509V3_ADD_EXT                            104
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID              136
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ              137
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT              140
+# define X509_F_X509_ATTRIBUTE_GET0_DATA                  139
+# define X509_F_X509_ATTRIBUTE_SET1_DATA                  138
+# define X509_F_X509_CHECK_PRIVATE_KEY                    128
+# define X509_F_X509_CRL_DIFF                             105
+# define X509_F_X509_CRL_PRINT_FP                         147
+# define X509_F_X509_EXTENSION_CREATE_BY_NID              108
+# define X509_F_X509_EXTENSION_CREATE_BY_OBJ              109
+# define X509_F_X509_GET_PUBKEY_PARAMETERS                110
+# define X509_F_X509_LOAD_CERT_CRL_FILE                   132
+# define X509_F_X509_LOAD_CERT_FILE                       111
+# define X509_F_X509_LOAD_CRL_FILE                        112
+# define X509_F_X509_NAME_ADD_ENTRY                       113
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID             114
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT             131
+# define X509_F_X509_NAME_ENTRY_SET_OBJECT                115
+# define X509_F_X509_NAME_ONELINE                         116
+# define X509_F_X509_NAME_PRINT                           117
+# define X509_F_X509_PRINT_EX_FP                          118
+# define X509_F_X509_PUBKEY_GET                           119
+# define X509_F_X509_PUBKEY_SET                           120
+# define X509_F_X509_REQ_CHECK_PRIVATE_KEY                144
+# define X509_F_X509_REQ_PRINT_EX                         121
+# define X509_F_X509_REQ_PRINT_FP                         122
+# define X509_F_X509_REQ_TO_X509                          123
+# define X509_F_X509_STORE_ADD_CERT                       124
+# define X509_F_X509_STORE_ADD_CRL                        125
+# define X509_F_X509_STORE_CTX_GET1_ISSUER                146
+# define X509_F_X509_STORE_CTX_INIT                       143
+# define X509_F_X509_STORE_CTX_NEW                        142
+# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT            134
+# define X509_F_X509_TO_X509_REQ                          126
+# define X509_F_X509_TRUST_ADD                            133
+# define X509_F_X509_TRUST_SET                            141
+# define X509_F_X509_VERIFY_CERT                          127
+
+/* Reason codes. */
+# define X509_R_AKID_MISMATCH                             110
+# define X509_R_BAD_X509_FILETYPE                         100
+# define X509_R_BASE64_DECODE_ERROR                       118
+# define X509_R_CANT_CHECK_DH_KEY                         114
+# define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
+# define X509_R_CRL_ALREADY_DELTA                         127
+# define X509_R_CRL_VERIFY_FAILURE                        131
+# define X509_R_ERR_ASN1_LIB                              102
+# define X509_R_IDP_MISMATCH                              128
+# define X509_R_INVALID_DIRECTORY                         113
+# define X509_R_INVALID_FIELD_NAME                        119
+# define X509_R_INVALID_TRUST                             123
+# define X509_R_ISSUER_MISMATCH                           129
+# define X509_R_KEY_TYPE_MISMATCH                         115
+# define X509_R_KEY_VALUES_MISMATCH                       116
+# define X509_R_LOADING_CERT_DIR                          103
+# define X509_R_LOADING_DEFAULTS                          104
+# define X509_R_METHOD_NOT_SUPPORTED                      124
+# define X509_R_NAME_TOO_LONG                             134
+# define X509_R_NEWER_CRL_NOT_NEWER                       132
+# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
+# define X509_R_NO_CRL_NUMBER                             130
+# define X509_R_PUBLIC_KEY_DECODE_ERROR                   125
+# define X509_R_PUBLIC_KEY_ENCODE_ERROR                   126
+# define X509_R_SHOULD_RETRY                              106
+# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN        107
+# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY            108
+# define X509_R_UNKNOWN_KEY_TYPE                          117
+# define X509_R_UNKNOWN_NID                               109
+# define X509_R_UNKNOWN_PURPOSE_ID                        121
+# define X509_R_UNKNOWN_TRUST_ID                          120
+# define X509_R_UNSUPPORTED_ALGORITHM                     111
+# define X509_R_WRONG_LOOKUP_TYPE                         112
+# define X509_R_WRONG_TYPE                                122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/x509_vfy.h b/Cryptlib/Include/openssl/x509_vfy.h
new file mode 100644 (file)
index 0000000..3790ef5
--- /dev/null
@@ -0,0 +1,650 @@
+/* crypto/x509/x509_vfy.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_X509_H
+# include <openssl/x509.h>
+/*
+ * openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment.
+ */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+# define HEADER_X509_VFY_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_LHASH
+#  include <openssl/lhash.h>
+# endif
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if 0
+/* Outer object */
+typedef struct x509_hash_dir_st {
+    int num_dirs;
+    char **dirs;
+    int *dirs_type;
+    int num_dirs_alloced;
+} X509_HASH_DIR_CTX;
+# endif
+
+typedef struct x509_file_st {
+    int num_paths;              /* number of paths to files or directories */
+    int num_alloced;
+    char **paths;               /* the list of paths or directories */
+    int *path_type;
+} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*-
+SSL_CTX -> X509_STORE
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+
+SSL     -> X509_STORE_CTX
+                ->X509_STORE
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+# define X509_LU_RETRY           -1
+# define X509_LU_FAIL            0
+# define X509_LU_X509            1
+# define X509_LU_CRL             2
+# define X509_LU_PKEY            3
+
+typedef struct x509_object_st {
+    /* one of the above types */
+    int type;
+    union {
+        char *ptr;
+        X509 *x509;
+        X509_CRL *crl;
+        EVP_PKEY *pkey;
+    } data;
+} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st {
+    const char *name;
+    int (*new_item) (X509_LOOKUP *ctx);
+    void (*free) (X509_LOOKUP *ctx);
+    int (*init) (X509_LOOKUP *ctx);
+    int (*shutdown) (X509_LOOKUP *ctx);
+    int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+                 char **ret);
+    int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+                           X509_OBJECT *ret);
+    int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
+    int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
+                               unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+    int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
+                         X509_OBJECT *ret);
+} X509_LOOKUP_METHOD;
+
+typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID;
+
+/*
+ * This structure hold all parameters associated with a verify operation by
+ * including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st {
+    char *name;
+    time_t check_time;          /* Time to use */
+    unsigned long inh_flags;    /* Inheritance flags */
+    unsigned long flags;        /* Various verify flags */
+    int purpose;                /* purpose to check untrusted certificates */
+    int trust;                  /* trust setting to check */
+    int depth;                  /* Verify depth */
+    STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
+    X509_VERIFY_PARAM_ID *id;   /* opaque ID data */
+} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/*
+ * This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify' function is
+ * then called to actually check the cert chain.
+ */
+struct x509_store_st {
+    /* The following is a cache of trusted certs */
+    int cache;                  /* if true, stash any hits */
+    STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
+    /* These are external lookup methods */
+    STACK_OF(X509_LOOKUP) *get_cert_methods;
+    X509_VERIFY_PARAM *param;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    CRYPTO_EX_DATA ex_data;
+    int references;
+} /* X509_STORE */ ;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+# define X509_STORE_set_verify_func(ctx,func)    ((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st {
+    int init;                   /* have we been started */
+    int skip;                   /* don't use us. */
+    X509_LOOKUP_METHOD *method; /* the functions */
+    char *method_data;          /* method data */
+    X509_STORE *store_ctx;      /* who owns us */
+} /* X509_LOOKUP */ ;
+
+/*
+ * This is a used when verifying cert chains.  Since the gathering of the
+ * cert chain can take some time (and have to be 'retried', this needs to be
+ * kept and passed around.
+ */
+struct x509_store_ctx_st {      /* X509_STORE_CTX */
+    X509_STORE *ctx;
+    /* used when looking up certs */
+    int current_method;
+    /* The following are set by the caller */
+    /* The cert to check */
+    X509 *cert;
+    /* chain of X509s - untrusted - passed in */
+    STACK_OF(X509) *untrusted;
+    /* set of CRLs passed in */
+    STACK_OF(X509_CRL) *crls;
+    X509_VERIFY_PARAM *param;
+    /* Other info for use with get_issuer() */
+    void *other_ctx;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    int (*check_policy) (X509_STORE_CTX *ctx);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    /* The following is built up */
+    /* if 0, rebuild chain */
+    int valid;
+    /* index of last untrusted cert */
+    int last_untrusted;
+    /* chain of X509s - built up and trusted */
+    STACK_OF(X509) *chain;
+    /* Valid policy tree */
+    X509_POLICY_TREE *tree;
+    /* Require explicit policy value */
+    int explicit_policy;
+    /* When something goes wrong, this is why */
+    int error_depth;
+    int error;
+    X509 *current_cert;
+    /* cert currently being tested as valid issuer */
+    X509 *current_issuer;
+    /* current CRL */
+    X509_CRL *current_crl;
+    /* score of current CRL */
+    int current_crl_score;
+    /* Reason mask */
+    unsigned int current_reasons;
+    /* For CRL path validation: parent context */
+    X509_STORE_CTX *parent;
+    CRYPTO_EX_DATA ex_data;
+} /* X509_STORE_CTX */ ;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+# define X509_STORE_CTX_set_app_data(ctx,data) \
+        X509_STORE_CTX_set_ex_data(ctx,0,data)
+# define X509_STORE_CTX_get_app_data(ctx) \
+        X509_STORE_CTX_get_ex_data(ctx,0)
+
+# define X509_L_FILE_LOAD        1
+# define X509_L_ADD_DIR          2
+
+# define X509_LOOKUP_load_file(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+# define X509_LOOKUP_add_dir(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+# define         X509_V_OK                                       0
+# define         X509_V_ERR_UNSPECIFIED                          1
+
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
+# define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
+# define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
+# define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
+# define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
+# define         X509_V_ERR_CERT_NOT_YET_VALID                   9
+# define         X509_V_ERR_CERT_HAS_EXPIRED                     10
+# define         X509_V_ERR_CRL_NOT_YET_VALID                    11
+# define         X509_V_ERR_CRL_HAS_EXPIRED                      12
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
+# define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
+# define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
+# define         X509_V_ERR_OUT_OF_MEM                           17
+# define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
+# define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
+# define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
+# define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
+# define         X509_V_ERR_CERT_REVOKED                         23
+# define         X509_V_ERR_INVALID_CA                           24
+# define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
+# define         X509_V_ERR_INVALID_PURPOSE                      26
+# define         X509_V_ERR_CERT_UNTRUSTED                       27
+# define         X509_V_ERR_CERT_REJECTED                        28
+/* These are 'informational' when looking for issuer cert */
+# define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
+# define         X509_V_ERR_AKID_SKID_MISMATCH                   30
+# define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
+# define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
+
+# define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
+# define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
+# define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
+# define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
+# define         X509_V_ERR_INVALID_NON_CA                       37
+# define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+# define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+# define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
+
+# define         X509_V_ERR_INVALID_EXTENSION                    41
+# define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
+# define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
+# define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
+# define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
+
+# define         X509_V_ERR_UNNESTED_RESOURCE                    46
+
+# define         X509_V_ERR_PERMITTED_VIOLATION                  47
+# define         X509_V_ERR_EXCLUDED_VIOLATION                   48
+# define         X509_V_ERR_SUBTREE_MINMAX                       49
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
+# define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
+# define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
+
+/* Suite B mode algorithm violation */
+# define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
+# define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+# define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
+# define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+# define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+# define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+
+/* Host, email and IP check errors */
+# define         X509_V_ERR_HOSTNAME_MISMATCH                    62
+# define         X509_V_ERR_EMAIL_MISMATCH                       63
+# define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+
+/* The application is not happy */
+# define         X509_V_ERR_APPLICATION_VERIFICATION             50
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+# define X509_V_FLAG_CB_ISSUER_CHECK             0x1
+/* Use check time instead of current time */
+# define X509_V_FLAG_USE_CHECK_TIME              0x2
+/* Lookup CRLs */
+# define X509_V_FLAG_CRL_CHECK                   0x4
+/* Lookup CRLs for whole chain */
+# define X509_V_FLAG_CRL_CHECK_ALL               0x8
+/* Ignore unhandled critical extensions */
+# define X509_V_FLAG_IGNORE_CRITICAL             0x10
+/* Disable workarounds for broken certificates */
+# define X509_V_FLAG_X509_STRICT                 0x20
+/* Enable proxy certificate validation */
+# define X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
+/* Enable policy checking */
+# define X509_V_FLAG_POLICY_CHECK                0x80
+/* Policy variable require-explicit-policy */
+# define X509_V_FLAG_EXPLICIT_POLICY             0x100
+/* Policy variable inhibit-any-policy */
+# define X509_V_FLAG_INHIBIT_ANY                 0x200
+/* Policy variable inhibit-policy-mapping */
+# define X509_V_FLAG_INHIBIT_MAP                 0x400
+/* Notify callback that policy is OK */
+# define X509_V_FLAG_NOTIFY_POLICY               0x800
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+# define X509_V_FLAG_EXTENDED_CRL_SUPPORT        0x1000
+/* Delta CRL support */
+# define X509_V_FLAG_USE_DELTAS                  0x2000
+/* Check selfsigned CA signature */
+# define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
+/* Use trusted store first */
+# define X509_V_FLAG_TRUSTED_FIRST               0x8000
+/* Suite B 128 bit only mode: not normally used */
+# define X509_V_FLAG_SUITEB_128_LOS_ONLY         0x10000
+/* Suite B 192 bit only mode */
+# define X509_V_FLAG_SUITEB_192_LOS              0x20000
+/* Suite B 128 bit mode allowing 192 bit algorithms */
+# define X509_V_FLAG_SUITEB_128_LOS              0x30000
+
+/* Allow partial chains if at least one certificate is in trusted store */
+# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
+ * will force the behaviour to match that of previous versions.
+ */
+# define X509_V_FLAG_NO_ALT_CHAINS               0x100000
+/* Do not check certificate/CRL validity against current time */
+# define X509_V_FLAG_NO_CHECK_TIME               0x200000
+
+# define X509_VP_FLAG_DEFAULT                    0x1
+# define X509_VP_FLAG_OVERWRITE                  0x2
+# define X509_VP_FLAG_RESET_FLAGS                0x4
+# define X509_VP_FLAG_LOCKED                     0x8
+# define X509_VP_FLAG_ONCE                       0x10
+
+/* Internal use: mask of policy related options */
+# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+                                | X509_V_FLAG_EXPLICIT_POLICY \
+                                | X509_V_FLAG_INHIBIT_ANY \
+                                | X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+                               X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+                                             int type, X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+                                        X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void);
+void X509_STORE_free(X509_STORE *v);
+
+STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+                              int (*verify_cb) (int, X509_STORE_CTX *));
+
+void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
+                                   STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
+                                                              *ctx,
+                                                              X509_NAME *nm));
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+                        X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+#ifndef OPENSSL_NO_STDIO
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+#endif
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+                              X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+                     long argl, char **ret);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+# endif
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+                           X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+                               unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
+                         X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_STORE_load_locations(X509_STORE *ctx,
+                              const char *file, const char *dir);
+int X509_STORE_set_default_paths(X509_STORE *ctx);
+# endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
+                                    CRYPTO_EX_new *new_func,
+                                    CRYPTO_EX_dup *dup_func,
+                                    CRYPTO_EX_free *free_func);
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
+void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                                   int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+                             time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+                                  int (*verify_cb) (int, X509_STORE_CTX *));
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+                              const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+                           const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
+                                unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+                                  unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+                                  ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+                                    STACK_OF(ASN1_OBJECT) *policies);
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                     unsigned int flags);
+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+                                 const char *email, size_t emaillen);
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+                              const unsigned char *ip, size_t iplen);
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
+                                  const char *ipasc);
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_get_count(void);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+                      STACK_OF(X509) *certs,
+                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+                                               int i);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+                                                           X509_POLICY_TREE
+                                                           *tree);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+                                                                X509_POLICY_TREE
+                                                                *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
+                                              int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+                                                           X509_POLICY_NODE
+                                                           *node);
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+                                                     *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/openssl/x509v3.h b/Cryptlib/Include/openssl/x509v3.h
new file mode 100644 (file)
index 0000000..a2e78aa
--- /dev/null
@@ -0,0 +1,1056 @@
+/* x509v3.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).
+ *
+ */
+#ifndef HEADER_X509V3_H
+# define HEADER_X509V3_H
+
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+# include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#  undef X509_NAME
+#  undef X509_CERT_PAIR
+#  undef X509_EXTENSIONS
+# endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void *(*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE) (void *);
+typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
+typedef int (*X509V3_EXT_I2D) (void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) *
+    (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext,
+                       STACK_OF(CONF_VALUE) *extlist);
+typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx,
+                                STACK_OF(CONF_VALUE) *values);
+typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method,
+                                void *ext);
+typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext,
+                               BIO *out, int indent);
+typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+    int ext_nid;
+    int ext_flags;
+/* If this is set the following four fields are ignored */
+    ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+    X509V3_EXT_NEW ext_new;
+    X509V3_EXT_FREE ext_free;
+    X509V3_EXT_D2I d2i;
+    X509V3_EXT_I2D i2d;
+/* The following pair is used for string extensions */
+    X509V3_EXT_I2S i2s;
+    X509V3_EXT_S2I s2i;
+/* The following pair is used for multi-valued extensions */
+    X509V3_EXT_I2V i2v;
+    X509V3_EXT_V2I v2i;
+/* The following are used for raw extensions */
+    X509V3_EXT_I2R i2r;
+    X509V3_EXT_R2I r2i;
+    void *usr_data;             /* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+    char *(*get_string) (void *db, char *section, char *value);
+    STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section);
+    void (*free_string) (void *db, char *string);
+    void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+# define CTX_TEST 0x1
+    int flags;
+    X509 *issuer_cert;
+    X509 *subject_cert;
+    X509_REQ *subject_req;
+    X509_CRL *crl;
+    X509V3_CONF_METHOD *db_meth;
+    void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DECLARE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+# define X509V3_EXT_DYNAMIC      0x1
+# define X509V3_EXT_CTX_DEP      0x2
+# define X509V3_EXT_MULTILINE    0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+    int ca;
+    ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+typedef struct PKEY_USAGE_PERIOD_st {
+    ASN1_GENERALIZEDTIME *notBefore;
+    ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+    ASN1_OBJECT *type_id;
+    ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+    ASN1_STRING *nameAssigner;
+    ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+# define GEN_OTHERNAME   0
+# define GEN_EMAIL       1
+# define GEN_DNS         2
+# define GEN_X400        3
+# define GEN_DIRNAME     4
+# define GEN_EDIPARTY    5
+# define GEN_URI         6
+# define GEN_IPADD       7
+# define GEN_RID         8
+    int type;
+    union {
+        char *ptr;
+        OTHERNAME *otherName;   /* otherName */
+        ASN1_IA5STRING *rfc822Name;
+        ASN1_IA5STRING *dNSName;
+        ASN1_TYPE *x400Address;
+        X509_NAME *directoryName;
+        EDIPARTYNAME *ediPartyName;
+        ASN1_IA5STRING *uniformResourceIdentifier;
+        ASN1_OCTET_STRING *iPAddress;
+        ASN1_OBJECT *registeredID;
+        /* Old names */
+        ASN1_OCTET_STRING *ip;  /* iPAddress */
+        X509_NAME *dirn;        /* dirn */
+        ASN1_IA5STRING *ia5;    /* rfc822Name, dNSName,
+                                 * uniformResourceIdentifier */
+        ASN1_OBJECT *rid;       /* registeredID */
+        ASN1_TYPE *other;       /* x400Address */
+    } d;
+} GENERAL_NAME;
+
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+typedef struct ACCESS_DESCRIPTION_st {
+    ASN1_OBJECT *method;
+    GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+DECLARE_STACK_OF(GENERAL_NAME)
+DECLARE_ASN1_SET_OF(GENERAL_NAME)
+
+DECLARE_STACK_OF(ACCESS_DESCRIPTION)
+DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+    int type;
+    union {
+        GENERAL_NAMES *fullname;
+        STACK_OF(X509_NAME_ENTRY) *relativename;
+    } name;
+/* If relativename then this contains the full distribution point name */
+    X509_NAME *dpname;
+} DIST_POINT_NAME;
+/* All existing reasons */
+# define CRLDP_ALL_REASONS       0x807f
+
+# define CRL_REASON_NONE                         -1
+# define CRL_REASON_UNSPECIFIED                  0
+# define CRL_REASON_KEY_COMPROMISE               1
+# define CRL_REASON_CA_COMPROMISE                2
+# define CRL_REASON_AFFILIATION_CHANGED          3
+# define CRL_REASON_SUPERSEDED                   4
+# define CRL_REASON_CESSATION_OF_OPERATION       5
+# define CRL_REASON_CERTIFICATE_HOLD             6
+# define CRL_REASON_REMOVE_FROM_CRL              8
+# define CRL_REASON_PRIVILEGE_WITHDRAWN          9
+# define CRL_REASON_AA_COMPROMISE                10
+
+struct DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    ASN1_BIT_STRING *reasons;
+    GENERAL_NAMES *CRLissuer;
+    int dp_reasons;
+};
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DECLARE_STACK_OF(DIST_POINT)
+DECLARE_ASN1_SET_OF(DIST_POINT)
+
+struct AUTHORITY_KEYID_st {
+    ASN1_OCTET_STRING *keyid;
+    GENERAL_NAMES *issuer;
+    ASN1_INTEGER *serial;
+};
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+    ASN1_INTEGER *zone;
+    ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DECLARE_STACK_OF(SXNETID)
+DECLARE_ASN1_SET_OF(SXNETID)
+
+typedef struct SXNET_st {
+    ASN1_INTEGER *version;
+    STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+    ASN1_STRING *organization;
+    STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+    NOTICEREF *noticeref;
+    ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+    ASN1_OBJECT *pqualid;
+    union {
+        ASN1_IA5STRING *cpsuri;
+        USERNOTICE *usernotice;
+        ASN1_TYPE *other;
+    } d;
+} POLICYQUALINFO;
+
+DECLARE_STACK_OF(POLICYQUALINFO)
+DECLARE_ASN1_SET_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+    ASN1_OBJECT *policyid;
+    STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DECLARE_STACK_OF(POLICYINFO)
+DECLARE_ASN1_SET_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+    ASN1_OBJECT *issuerDomainPolicy;
+    ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DECLARE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+    GENERAL_NAME *base;
+    ASN1_INTEGER *minimum;
+    ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DECLARE_STACK_OF(GENERAL_SUBTREE)
+
+struct NAME_CONSTRAINTS_st {
+    STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+    STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+};
+
+typedef struct POLICY_CONSTRAINTS_st {
+    ASN1_INTEGER *requireExplicitPolicy;
+    ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st {
+    ASN1_OBJECT *policyLanguage;
+    ASN1_OCTET_STRING *policy;
+} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st {
+    ASN1_INTEGER *pcPathLengthConstraint;
+    PROXY_POLICY *proxyPolicy;
+} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+struct ISSUING_DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    int onlyuser;
+    int onlyCA;
+    ASN1_BIT_STRING *onlysomereasons;
+    int indirectCRL;
+    int onlyattr;
+};
+
+/* Values in idp_flags field */
+/* IDP present */
+# define IDP_PRESENT     0x1
+/* IDP values inconsistent */
+# define IDP_INVALID     0x2
+/* onlyuser true */
+# define IDP_ONLYUSER    0x4
+/* onlyCA true */
+# define IDP_ONLYCA      0x8
+/* onlyattr true */
+# define IDP_ONLYATTR    0x10
+/* indirectCRL true */
+# define IDP_INDIRECT    0x20
+/* onlysomereasons present */
+# define IDP_REASONS     0x40
+
+# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+# define X509V3_set_ctx_test(ctx) \
+                        X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+                        0,0,0,0, \
+                        0,0, \
+                        (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+                        (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+                        NULL, NULL, \
+                        table}
+
+# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+                        0,0,0,0, \
+                        (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+                        (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+                        0,0,0,0, \
+                        NULL}
+
+# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+/* X509_PURPOSE stuff */
+
+# define EXFLAG_BCONS            0x1
+# define EXFLAG_KUSAGE           0x2
+# define EXFLAG_XKUSAGE          0x4
+# define EXFLAG_NSCERT           0x8
+
+# define EXFLAG_CA               0x10
+/* Really self issued not necessarily self signed */
+# define EXFLAG_SI               0x20
+# define EXFLAG_V1               0x40
+# define EXFLAG_INVALID          0x80
+# define EXFLAG_SET              0x100
+# define EXFLAG_CRITICAL         0x200
+# define EXFLAG_PROXY            0x400
+
+# define EXFLAG_INVALID_POLICY   0x800
+# define EXFLAG_FRESHEST         0x1000
+/* Self signed */
+# define EXFLAG_SS               0x2000
+
+# define KU_DIGITAL_SIGNATURE    0x0080
+# define KU_NON_REPUDIATION      0x0040
+# define KU_KEY_ENCIPHERMENT     0x0020
+# define KU_DATA_ENCIPHERMENT    0x0010
+# define KU_KEY_AGREEMENT        0x0008
+# define KU_KEY_CERT_SIGN        0x0004
+# define KU_CRL_SIGN             0x0002
+# define KU_ENCIPHER_ONLY        0x0001
+# define KU_DECIPHER_ONLY        0x8000
+
+# define NS_SSL_CLIENT           0x80
+# define NS_SSL_SERVER           0x40
+# define NS_SMIME                0x20
+# define NS_OBJSIGN              0x10
+# define NS_SSL_CA               0x04
+# define NS_SMIME_CA             0x02
+# define NS_OBJSIGN_CA           0x01
+# define NS_ANY_CA               (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+# define XKU_SSL_SERVER          0x1
+# define XKU_SSL_CLIENT          0x2
+# define XKU_SMIME               0x4
+# define XKU_CODE_SIGN           0x8
+# define XKU_SGC                 0x10
+# define XKU_OCSP_SIGN           0x20
+# define XKU_TIMESTAMP           0x40
+# define XKU_DVCS                0x80
+# define XKU_ANYEKU              0x100
+
+# define X509_PURPOSE_DYNAMIC    0x1
+# define X509_PURPOSE_DYNAMIC_NAME       0x2
+
+typedef struct x509_purpose_st {
+    int purpose;
+    int trust;                  /* Default trust ID */
+    int flags;
+    int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int);
+    char *name;
+    char *sname;
+    void *usr_data;
+} X509_PURPOSE;
+
+# define X509_PURPOSE_SSL_CLIENT         1
+# define X509_PURPOSE_SSL_SERVER         2
+# define X509_PURPOSE_NS_SSL_SERVER      3
+# define X509_PURPOSE_SMIME_SIGN         4
+# define X509_PURPOSE_SMIME_ENCRYPT      5
+# define X509_PURPOSE_CRL_SIGN           6
+# define X509_PURPOSE_ANY                7
+# define X509_PURPOSE_OCSP_HELPER        8
+# define X509_PURPOSE_TIMESTAMP_SIGN     9
+
+# define X509_PURPOSE_MIN                1
+# define X509_PURPOSE_MAX                9
+
+/* Flags for X509V3_EXT_print() */
+
+# define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
+/* Return error for unknown extensions */
+# define X509V3_EXT_DEFAULT              0
+/* Print error for unknown extensions */
+# define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
+/* ASN1 parse unknown extensions */
+# define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
+/* BIO_dump unknown extensions */
+# define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+# define X509V3_ADD_OP_MASK              0xfL
+# define X509V3_ADD_DEFAULT              0L
+# define X509V3_ADD_APPEND               1L
+# define X509V3_ADD_REPLACE              2L
+# define X509V3_ADD_REPLACE_EXISTING     3L
+# define X509V3_ADD_KEEP_EXISTING        4L
+# define X509V3_ADD_DELETE               5L
+# define X509V3_ADD_SILENT               0x10
+
+DECLARE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen);
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
+                       int userlen);
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user,
+                         int userlen);
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                          ASN1_BIT_STRING *bits,
+                                          STACK_OF(CONF_VALUE) *extlist);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+                                       GENERAL_NAME *gen,
+                                       STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+                                        GENERAL_NAMES *gen,
+                                        STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+                                ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                            ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a);
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                               const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, int gen_type, char *value,
+                               int is_nc);
+
+# ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                  const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, CONF_VALUE *cnf,
+                                  int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                     char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
+                                 char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
+                            STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                         X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                             X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                             X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+                                    X509V3_CTX *ctx, int ext_nid,
+                                    char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                                char *name, char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                        char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+                             STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
+# endif
+
+char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+                    X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+                     STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                           STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+                          STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+                         STACK_OF(CONF_VALUE) **extlist);
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth,
+                                ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+                     int *idx);
+int X509V3_EXT_free(int nid, void *ext_data);
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+                    int crit, unsigned long flags);
+
+char *hex_to_string(const unsigned char *buffer, long len);
+unsigned char *string_to_hex(const char *str, long *len);
+int name_cmp(const char *name, const char *cmp);
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+                        int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+                     int indent);
+#ifndef OPENSSL_NO_FP_API
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+#endif
+int X509V3_extensions_print(BIO *out, char *title,
+                            STACK_OF(X509_EXTENSION) *exts,
+                            unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE *X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
+                     char *name, char *sname, void *arg);
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(X509_PURPOSE *);
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
+/* Flags for X509_check_* functions */
+
+/*
+ * Always check subject name for host match even if subject alt names present
+ */
+# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT    0x1
+/* Disable wildcard matching for dnsName fields and common name. */
+# define X509_CHECK_FLAG_NO_WILDCARDS    0x2
+/* Wildcards must not match a partial label. */
+# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4
+/* Allow (non-partial) wildcards to match multiple labels. */
+# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8
+/* Constraint verifier subdomain patterns to match a single labels. */
+# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
+/*
+ * Match reference identifiers starting with "." to any sub-domain.
+ * This is a non-public flag, turned on implicitly when the subject
+ * reference identity is a DNS name.
+ */
+# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
+
+int X509_check_host(X509 *x, const char *chk, size_t chklen,
+                    unsigned int flags, char **peername);
+int X509_check_email(X509 *x, const char *chk, size_t chklen,
+                     unsigned int flags);
+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+                  unsigned int flags);
+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
+                             unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DECLARE_STACK_OF(X509_POLICY_NODE)
+
+# ifndef OPENSSL_NO_RFC3779
+
+typedef struct ASRange_st {
+    ASN1_INTEGER *min, *max;
+} ASRange;
+
+#  define ASIdOrRange_id          0
+#  define ASIdOrRange_range       1
+
+typedef struct ASIdOrRange_st {
+    int type;
+    union {
+        ASN1_INTEGER *id;
+        ASRange *range;
+    } u;
+} ASIdOrRange;
+
+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
+DECLARE_STACK_OF(ASIdOrRange)
+
+#  define ASIdentifierChoice_inherit              0
+#  define ASIdentifierChoice_asIdsOrRanges        1
+
+typedef struct ASIdentifierChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        ASIdOrRanges *asIdsOrRanges;
+    } u;
+} ASIdentifierChoice;
+
+typedef struct ASIdentifiers_st {
+    ASIdentifierChoice *asnum, *rdi;
+} ASIdentifiers;
+
+DECLARE_ASN1_FUNCTIONS(ASRange)
+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
+
+typedef struct IPAddressRange_st {
+    ASN1_BIT_STRING *min, *max;
+} IPAddressRange;
+
+#  define IPAddressOrRange_addressPrefix  0
+#  define IPAddressOrRange_addressRange   1
+
+typedef struct IPAddressOrRange_st {
+    int type;
+    union {
+        ASN1_BIT_STRING *addressPrefix;
+        IPAddressRange *addressRange;
+    } u;
+} IPAddressOrRange;
+
+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
+DECLARE_STACK_OF(IPAddressOrRange)
+
+#  define IPAddressChoice_inherit                 0
+#  define IPAddressChoice_addressesOrRanges       1
+
+typedef struct IPAddressChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        IPAddressOrRanges *addressesOrRanges;
+    } u;
+} IPAddressChoice;
+
+typedef struct IPAddressFamily_st {
+    ASN1_OCTET_STRING *addressFamily;
+    IPAddressChoice *ipAddressChoice;
+} IPAddressFamily;
+
+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
+DECLARE_STACK_OF(IPAddressFamily)
+
+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * API tag for elements of the ASIdentifer SEQUENCE.
+ */
+#  define V3_ASID_ASNUM   0
+#  define V3_ASID_RDI     1
+
+/*
+ * AFI values, assigned by IANA.  It'd be nice to make the AFI
+ * handling code totally generic, but there are too many little things
+ * that would need to be defined for other address families for it to
+ * be worth the trouble.
+ */
+#  define IANA_AFI_IPV4   1
+#  define IANA_AFI_IPV6   2
+
+/*
+ * Utilities to construct and extract values from RFC3779 extensions,
+ * since some of the encodings (particularly for IP address prefixes
+ * and ranges) are a bit tedious to work with directly.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which);
+int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
+                            ASN1_INTEGER *min, ASN1_INTEGER *max);
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+                        const unsigned afi, const unsigned *safi);
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+                       const unsigned afi, const unsigned *safi,
+                       unsigned char *a, const int prefixlen);
+int v3_addr_add_range(IPAddrBlocks *addr,
+                      const unsigned afi, const unsigned *safi,
+                      unsigned char *min, unsigned char *max);
+unsigned v3_addr_get_afi(const IPAddressFamily *f);
+int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
+                      unsigned char *min, unsigned char *max,
+                      const int length);
+
+/*
+ * Canonical forms.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid);
+int v3_addr_is_canonical(IPAddrBlocks *addr);
+int v3_asid_canonize(ASIdentifiers *asid);
+int v3_addr_canonize(IPAddrBlocks *addr);
+
+/*
+ * Tests for inheritance and containment.
+ */
+int v3_asid_inherits(ASIdentifiers *asid);
+int v3_addr_inherits(IPAddrBlocks *addr);
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
+
+/*
+ * Check whether RFC 3779 extensions nest properly in chains.
+ */
+int v3_asid_validate_path(X509_STORE_CTX *);
+int v3_addr_validate_path(X509_STORE_CTX *);
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+                                  ASIdentifiers *ext, int allow_inheritance);
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+                                  IPAddrBlocks *ext, int allow_inheritance);
+
+# endif                         /* OPENSSL_NO_RFC3779 */
+
+/* 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_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+# define X509V3_F_A2I_GENERAL_NAME                        164
+# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE             161
+# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL         162
+# define X509V3_F_COPY_EMAIL                              122
+# define X509V3_F_COPY_ISSUER                             123
+# define X509V3_F_DO_DIRNAME                              144
+# define X509V3_F_DO_EXT_CONF                             124
+# define X509V3_F_DO_EXT_I2D                              135
+# define X509V3_F_DO_EXT_NCONF                            151
+# define X509V3_F_DO_I2V_NAME_CONSTRAINTS                 148
+# define X509V3_F_GNAMES_FROM_SECTNAME                    156
+# define X509V3_F_HEX_TO_STRING                           111
+# define X509V3_F_I2S_ASN1_ENUMERATED                     121
+# define X509V3_F_I2S_ASN1_IA5STRING                      149
+# define X509V3_F_I2S_ASN1_INTEGER                        120
+# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS               138
+# define X509V3_F_NOTICE_SECTION                          132
+# define X509V3_F_NREF_NOS                                133
+# define X509V3_F_POLICY_SECTION                          131
+# define X509V3_F_PROCESS_PCI_VALUE                       150
+# define X509V3_F_R2I_CERTPOL                             130
+# define X509V3_F_R2I_PCI                                 155
+# define X509V3_F_S2I_ASN1_IA5STRING                      100
+# define X509V3_F_S2I_ASN1_INTEGER                        108
+# define X509V3_F_S2I_ASN1_OCTET_STRING                   112
+# define X509V3_F_S2I_ASN1_SKEY_ID                        114
+# define X509V3_F_S2I_SKEY_ID                             115
+# define X509V3_F_SET_DIST_POINT_NAME                     158
+# define X509V3_F_STRING_TO_HEX                           113
+# define X509V3_F_SXNET_ADD_ID_ASC                        125
+# define X509V3_F_SXNET_ADD_ID_INTEGER                    126
+# define X509V3_F_SXNET_ADD_ID_ULONG                      127
+# define X509V3_F_SXNET_GET_ID_ASC                        128
+# define X509V3_F_SXNET_GET_ID_ULONG                      129
+# define X509V3_F_V2I_ASIDENTIFIERS                       163
+# define X509V3_F_V2I_ASN1_BIT_STRING                     101
+# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS               139
+# define X509V3_F_V2I_AUTHORITY_KEYID                     119
+# define X509V3_F_V2I_BASIC_CONSTRAINTS                   102
+# define X509V3_F_V2I_CRLD                                134
+# define X509V3_F_V2I_EXTENDED_KEY_USAGE                  103
+# define X509V3_F_V2I_GENERAL_NAMES                       118
+# define X509V3_F_V2I_GENERAL_NAME_EX                     117
+# define X509V3_F_V2I_IDP                                 157
+# define X509V3_F_V2I_IPADDRBLOCKS                        159
+# define X509V3_F_V2I_ISSUER_ALT                          153
+# define X509V3_F_V2I_NAME_CONSTRAINTS                    147
+# define X509V3_F_V2I_POLICY_CONSTRAINTS                  146
+# define X509V3_F_V2I_POLICY_MAPPINGS                     145
+# define X509V3_F_V2I_SUBJECT_ALT                         154
+# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL          160
+# define X509V3_F_V3_GENERIC_EXTENSION                    116
+# define X509V3_F_X509V3_ADD1_I2D                         140
+# define X509V3_F_X509V3_ADD_VALUE                        105
+# define X509V3_F_X509V3_EXT_ADD                          104
+# define X509V3_F_X509V3_EXT_ADD_ALIAS                    106
+# define X509V3_F_X509V3_EXT_CONF                         107
+# define X509V3_F_X509V3_EXT_FREE                         165
+# define X509V3_F_X509V3_EXT_I2D                          136
+# define X509V3_F_X509V3_EXT_NCONF                        152
+# define X509V3_F_X509V3_GET_SECTION                      142
+# define X509V3_F_X509V3_GET_STRING                       143
+# define X509V3_F_X509V3_GET_VALUE_BOOL                   110
+# define X509V3_F_X509V3_PARSE_LIST                       109
+# define X509V3_F_X509_PURPOSE_ADD                        137
+# define X509V3_F_X509_PURPOSE_SET                        141
+
+/* Reason codes. */
+# define X509V3_R_BAD_IP_ADDRESS                          118
+# define X509V3_R_BAD_OBJECT                              119
+# define X509V3_R_BN_DEC2BN_ERROR                         100
+# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR                101
+# define X509V3_R_CANNOT_FIND_FREE_FUNCTION               168
+# define X509V3_R_DIRNAME_ERROR                           149
+# define X509V3_R_DISTPOINT_ALREADY_SET                   160
+# define X509V3_R_DUPLICATE_ZONE_ID                       133
+# define X509V3_R_ERROR_CONVERTING_ZONE                   131
+# define X509V3_R_ERROR_CREATING_EXTENSION                144
+# define X509V3_R_ERROR_IN_EXTENSION                      128
+# define X509V3_R_EXPECTED_A_SECTION_NAME                 137
+# define X509V3_R_EXTENSION_EXISTS                        145
+# define X509V3_R_EXTENSION_NAME_ERROR                    115
+# define X509V3_R_EXTENSION_NOT_FOUND                     102
+# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED         103
+# define X509V3_R_EXTENSION_VALUE_ERROR                   116
+# define X509V3_R_ILLEGAL_EMPTY_EXTENSION                 151
+# define X509V3_R_ILLEGAL_HEX_DIGIT                       113
+# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG             152
+# define X509V3_R_INVALID_ASNUMBER                        162
+# define X509V3_R_INVALID_ASRANGE                         163
+# define X509V3_R_INVALID_BOOLEAN_STRING                  104
+# define X509V3_R_INVALID_EXTENSION_STRING                105
+# define X509V3_R_INVALID_INHERITANCE                     165
+# define X509V3_R_INVALID_IPADDRESS                       166
+# define X509V3_R_INVALID_MULTIPLE_RDNS                   161
+# define X509V3_R_INVALID_NAME                            106
+# define X509V3_R_INVALID_NULL_ARGUMENT                   107
+# define X509V3_R_INVALID_NULL_NAME                       108
+# define X509V3_R_INVALID_NULL_VALUE                      109
+# define X509V3_R_INVALID_NUMBER                          140
+# define X509V3_R_INVALID_NUMBERS                         141
+# define X509V3_R_INVALID_OBJECT_IDENTIFIER               110
+# define X509V3_R_INVALID_OPTION                          138
+# define X509V3_R_INVALID_POLICY_IDENTIFIER               134
+# define X509V3_R_INVALID_PROXY_POLICY_SETTING            153
+# define X509V3_R_INVALID_PURPOSE                         146
+# define X509V3_R_INVALID_SAFI                            164
+# define X509V3_R_INVALID_SECTION                         135
+# define X509V3_R_INVALID_SYNTAX                          143
+# define X509V3_R_ISSUER_DECODE_ERROR                     126
+# define X509V3_R_MISSING_VALUE                           124
+# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS           142
+# define X509V3_R_NO_CONFIG_DATABASE                      136
+# define X509V3_R_NO_ISSUER_CERTIFICATE                   121
+# define X509V3_R_NO_ISSUER_DETAILS                       127
+# define X509V3_R_NO_POLICY_IDENTIFIER                    139
+# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED   154
+# define X509V3_R_NO_PUBLIC_KEY                           114
+# define X509V3_R_NO_SUBJECT_DETAILS                      125
+# define X509V3_R_ODD_NUMBER_OF_DIGITS                    112
+# define X509V3_R_OPERATION_NOT_DEFINED                   148
+# define X509V3_R_OTHERNAME_ERROR                         147
+# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED         155
+# define X509V3_R_POLICY_PATH_LENGTH                      156
+# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED      157
+# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED   158
+# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+# define X509V3_R_SECTION_NOT_FOUND                       150
+# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS            122
+# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID              123
+# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT             111
+# define X509V3_R_UNKNOWN_EXTENSION                       129
+# define X509V3_R_UNKNOWN_EXTENSION_NAME                  130
+# define X509V3_R_UNKNOWN_OPTION                          120
+# define X509V3_R_UNSUPPORTED_OPTION                      117
+# define X509V3_R_UNSUPPORTED_TYPE                        167
+# define X509V3_R_USER_TOO_LONG                           132
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/Cryptlib/Include/sgtty.h b/Cryptlib/Include/sgtty.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/signal.h b/Cryptlib/Include/signal.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/stdarg.h b/Cryptlib/Include/stdarg.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/stddef.h b/Cryptlib/Include/stddef.h
new file mode 100644 (file)
index 0000000..8dfc36f
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
diff --git a/Cryptlib/Include/stdio.h b/Cryptlib/Include/stdio.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/stdlib.h b/Cryptlib/Include/stdlib.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/string.h b/Cryptlib/Include/string.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/strings.h b/Cryptlib/Include/strings.h
new file mode 100644 (file)
index 0000000..8dfc36f
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
diff --git a/Cryptlib/Include/sys/ioctl.h b/Cryptlib/Include/sys/ioctl.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/param.h b/Cryptlib/Include/sys/param.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/socket.h b/Cryptlib/Include/sys/socket.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/stat.h b/Cryptlib/Include/sys/stat.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/time.h b/Cryptlib/Include/sys/time.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/times.h b/Cryptlib/Include/sys/times.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/types.h b/Cryptlib/Include/sys/types.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/sys/un.h b/Cryptlib/Include/sys/un.h
new file mode 100644 (file)
index 0000000..ee07f6b
--- /dev/null
@@ -0,0 +1,16 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
diff --git a/Cryptlib/Include/syslog.h b/Cryptlib/Include/syslog.h
new file mode 100644 (file)
index 0000000..8dfc36f
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
diff --git a/Cryptlib/Include/time.h b/Cryptlib/Include/time.h
new file mode 100644 (file)
index 0000000..8dfc36f
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
diff --git a/Cryptlib/Include/unistd.h b/Cryptlib/Include/unistd.h
new file mode 100644 (file)
index 0000000..8dfc36f
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Include file to support building OpenSSL Crypto Library.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
diff --git a/Cryptlib/InternalCryptLib.h b/Cryptlib/InternalCryptLib.h
new file mode 100644 (file)
index 0000000..92cc963
--- /dev/null
@@ -0,0 +1,34 @@
+/** @file  \r
+  Internal include file for BaseCryptLib.\r
+\r
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTERNAL_CRYPT_LIB_H__\r
+#define __INTERNAL_CRYPT_LIB_H__\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
+#include "OpenSslSupport.h"\r
+\r
+#include <openssl/opensslv.h>\r
+\r
+#if OPENSSL_VERSION_NUMBER < 0x10100000L\r
+#define OBJ_get0_data(o) ((o)->data)\r
+#define OBJ_length(o) ((o)->length)\r
+#endif\r
+\r
+#endif\r
+\r
diff --git a/Cryptlib/Library/BaseCryptLib.h b/Cryptlib/Library/BaseCryptLib.h
new file mode 100644 (file)
index 0000000..e9ee62c
--- /dev/null
@@ -0,0 +1,2371 @@
+/** @file\r
+  Defines base cryptographic library APIs.\r
+  The Base Cryptographic Library provides implementations of basic cryptography\r
+  primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security\r
+  functionality enabling.\r
+\r
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __BASE_CRYPT_LIB_H__\r
+#define __BASE_CRYPT_LIB_H__\r
+\r
+#define IN\r
+#define OUT\r
+#define CONST const\r
+\r
+///\r
+/// MD4 digest size in bytes\r
+///\r
+#define MD4_DIGEST_SIZE     16\r
+\r
+///\r
+/// MD5 digest size in bytes\r
+///\r
+#define MD5_DIGEST_SIZE     16\r
+\r
+///\r
+/// SHA-1 digest size in bytes.\r
+///\r
+#define SHA1_DIGEST_SIZE    20\r
+\r
+///\r
+/// SHA-256 digest size in bytes\r
+///\r
+#define SHA256_DIGEST_SIZE  32\r
+\r
+///\r
+/// SHA-384 digest size in bytes\r
+///\r
+#define SHA384_DIGEST_SIZE  48\r
+\r
+///\r
+/// SHA-512 digest size in bytes\r
+///\r
+#define SHA512_DIGEST_SIZE  64\r
+\r
+///\r
+/// TDES block size in bytes\r
+///\r
+#define TDES_BLOCK_SIZE     8\r
+\r
+///\r
+/// AES block size in bytes\r
+///\r
+#define AES_BLOCK_SIZE      16\r
+\r
+///\r
+/// RSA Key Tags Definition used in RsaSetKey() function for key component identification.\r
+///\r
+typedef enum {\r
+  RsaKeyN,      ///< RSA public Modulus (N)\r
+  RsaKeyE,      ///< RSA Public exponent (e)\r
+  RsaKeyD,      ///< RSA Private exponent (d)\r
+  RsaKeyP,      ///< RSA secret prime factor of Modulus (p)\r
+  RsaKeyQ,      ///< RSA secret prime factor of Modules (q)\r
+  RsaKeyDp,     ///< p's CRT exponent (== d mod (p - 1))\r
+  RsaKeyDq,     ///< q's CRT exponent (== d mod (q - 1))\r
+  RsaKeyQInv    ///< The CRT coefficient (== 1/q mod p)\r
+} RSA_KEY_TAG;\r
+\r
+//=====================================================================================\r
+//    One-Way Cryptographic Hash Primitives\r
+//=====================================================================================\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for MD4 hash operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for MD4 hash operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Md4GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Md4Context as MD4 hash context for\r
+  subsequent use.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  Md4Context  Pointer to MD4 context being initialized.\r
+\r
+  @retval TRUE   MD4 context initialization succeeded.\r
+  @retval FALSE  MD4 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Init (\r
+  OUT  VOID  *Md4Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing MD4 context.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If NewMd4Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Md4Context     Pointer to MD4 context being copied.\r
+  @param[out] NewMd4Context  Pointer to new MD4 context.\r
+\r
+  @retval TRUE   MD4 context copy succeeded.\r
+  @retval FALSE  MD4 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Duplicate (\r
+  IN   CONST VOID  *Md4Context,\r
+  OUT  VOID        *NewMd4Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates MD4 context.\r
+\r
+  This function performs MD4 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD4 context should be already correctly intialized by Md4Init(), and should not be finalized\r
+  by Md4Final(). Behavior with invalid context is undefined.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Md4Context  Pointer to the MD4 context.\r
+  @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   MD4 data digest succeeded.\r
+  @retval FALSE  MD4 data digest failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Update (\r
+  IN OUT  VOID        *Md4Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the MD4 digest value.\r
+\r
+  This function completes MD4 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD4 context cannot\r
+  be used again.\r
+  MD4 context should be already correctly intialized by Md4Init(), and should not be\r
+  finalized by Md4Final(). Behavior with invalid MD4 context is undefined.\r
+\r
+  If Md4Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Md4Context  Pointer to the MD4 context.\r
+  @param[out]      HashValue   Pointer to a buffer that receives the MD4 digest\r
+                               value (16 bytes).\r
+\r
+  @retval TRUE   MD4 digest computation succeeded.\r
+  @retval FALSE  MD4 digest computation failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md4Final (\r
+  IN OUT  VOID   *Md4Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for MD5 hash operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for MD5 hash operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Md5GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Md5Context as MD5 hash context for\r
+  subsequent use.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  Md5Context  Pointer to MD5 context being initialized.\r
+\r
+  @retval TRUE   MD5 context initialization succeeded.\r
+  @retval FALSE  MD5 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Init (\r
+  OUT  VOID  *Md5Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing MD5 context.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If NewMd5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Md5Context     Pointer to MD5 context being copied.\r
+  @param[out] NewMd5Context  Pointer to new MD5 context.\r
+\r
+  @retval TRUE   MD5 context copy succeeded.\r
+  @retval FALSE  MD5 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Duplicate (\r
+  IN   CONST VOID  *Md5Context,\r
+  OUT  VOID        *NewMd5Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates MD5 context.\r
+\r
+  This function performs MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized\r
+  by Md5Final(). Behavior with invalid context is undefined.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
+  @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   MD5 data digest succeeded.\r
+  @retval FALSE  MD5 data digest failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Update (\r
+  IN OUT  VOID        *Md5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the MD5 digest value.\r
+\r
+  This function completes MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD5 context cannot\r
+  be used again.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be\r
+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.\r
+\r
+  If Md5Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
+  @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest\r
+                               value (16 bytes).\r
+\r
+  @retval TRUE   MD5 digest computation succeeded.\r
+  @retval FALSE  MD5 digest computation failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Final (\r
+  IN OUT  VOID   *Md5Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-1 hash operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha1GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for\r
+  subsequent use.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.\r
+\r
+  @retval TRUE   SHA-1 context initialization succeeded.\r
+  @retval FALSE  SHA-1 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Init (\r
+  OUT  VOID  *Sha1Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing SHA-1 context.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If NewSha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.\r
+  @param[out] NewSha1Context  Pointer to new SHA-1 context.\r
+\r
+  @retval TRUE   SHA-1 context copy succeeded.\r
+  @retval FALSE  SHA-1 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Duplicate (\r
+  IN   CONST VOID  *Sha1Context,\r
+  OUT  VOID        *NewSha1Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates SHA-1 context.\r
+\r
+  This function performs SHA-1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized\r
+  by Sha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
+  @param[in]       Data         Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize     Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-1 data digest succeeded.\r
+  @retval FALSE  SHA-1 data digest failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Update (\r
+  IN OUT  VOID        *Sha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the SHA-1 digest value.\r
+\r
+  This function completes SHA-1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-1 context cannot\r
+  be used again.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be\r
+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.\r
+\r
+  If Sha1Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
+  @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest\r
+                                value (20 bytes).\r
+\r
+  @retval TRUE   SHA-1 digest computation succeeded.\r
+  @retval FALSE  SHA-1 digest computation failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Final (\r
+  IN OUT  VOID   *Sha1Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha256GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
+  subsequent use.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.\r
+\r
+  @retval TRUE   SHA-256 context initialization succeeded.\r
+  @retval FALSE  SHA-256 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Init (\r
+  OUT  VOID  *Sha256Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing SHA-256 context.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+  If NewSha256Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.\r
+  @param[out] NewSha256Context  Pointer to new SHA-256 context.\r
+\r
+  @retval TRUE   SHA-256 context copy succeeded.\r
+  @retval FALSE  SHA-256 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Duplicate (\r
+  IN   CONST VOID  *Sha256Context,\r
+  OUT  VOID        *NewSha256Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates SHA-256 context.\r
+\r
+  This function performs SHA-256 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized\r
+  by Sha256Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-256 data digest succeeded.\r
+  @retval FALSE  SHA-256 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Update (\r
+  IN OUT  VOID        *Sha256Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the SHA-256 digest value.\r
+\r
+  This function completes SHA-256 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-256 context cannot\r
+  be used again.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be\r
+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.\r
+\r
+  If Sha256Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest\r
+                                  value (32 bytes).\r
+\r
+  @retval TRUE   SHA-256 digest computation succeeded.\r
+  @retval FALSE  SHA-256 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Final (\r
+  IN OUT  VOID   *Sha256Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-384 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-384 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha384GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha384Context as SHA-384 hash context for\r
+  subsequent use.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha384Context  Pointer to SHA-384 context being initialized.\r
+\r
+  @retval TRUE   SHA-384 context initialization succeeded.\r
+  @retval FALSE  SHA-384 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Init (\r
+  OUT  VOID  *Sha384Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing SHA-384 context.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+  If NewSha384Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha384Context     Pointer to SHA-384 context being copied.\r
+  @param[out] NewSha384Context  Pointer to new SHA-384 context.\r
+\r
+  @retval TRUE   SHA-384 context copy succeeded.\r
+  @retval FALSE  SHA-384 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Duplicate (\r
+  IN   CONST VOID  *Sha384Context,\r
+  OUT  VOID        *NewSha384Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates SHA-384 context.\r
+\r
+  This function performs SHA-384 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-384 context should be already correctly intialized by Sha384Init(), and should not be finalized\r
+  by Sha384Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha384Context  Pointer to the SHA-384 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-384 data digest succeeded.\r
+  @retval FALSE  SHA-384 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Update (\r
+  IN OUT  VOID        *Sha384Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the SHA-384 digest value.\r
+\r
+  This function completes SHA-384 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-384 context cannot\r
+  be used again.\r
+  SHA-384 context should be already correctly intialized by Sha384Init(), and should not be\r
+  finalized by Sha384Final(). Behavior with invalid SHA-384 context is undefined.\r
+\r
+  If Sha384Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha384Context  Pointer to the SHA-384 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-384 digest\r
+                                  value (48 bytes).\r
+\r
+  @retval TRUE   SHA-384 digest computation succeeded.\r
+  @retval FALSE  SHA-384 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha384Final (\r
+  IN OUT  VOID   *Sha384Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-512 hash operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for SHA-512 hash operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Sha512GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by Sha512Context as SHA-512 hash context for\r
+  subsequent use.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+\r
+  @param[out]  Sha512Context  Pointer to SHA-512 context being initialized.\r
+\r
+  @retval TRUE   SHA-512 context initialization succeeded.\r
+  @retval FALSE  SHA-512 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Init (\r
+  OUT  VOID  *Sha512Context\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing SHA-512 context.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+  If NewSha512Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Sha512Context     Pointer to SHA-512 context being copied.\r
+  @param[out] NewSha512Context  Pointer to new SHA-512 context.\r
+\r
+  @retval TRUE   SHA-512 context copy succeeded.\r
+  @retval FALSE  SHA-512 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Duplicate (\r
+  IN   CONST VOID  *Sha512Context,\r
+  OUT  VOID        *NewSha512Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates SHA-512 context.\r
+\r
+  This function performs SHA-512 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-512 context should be already correctly intialized by Sha512Init(), and should not be finalized\r
+  by Sha512Final(). Behavior with invalid context is undefined.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha512Context  Pointer to the SHA-512 context.\r
+  @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   SHA-512 data digest succeeded.\r
+  @retval FALSE  SHA-512 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Update (\r
+  IN OUT  VOID        *Sha512Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the SHA-512 digest value.\r
+\r
+  This function completes SHA-512 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-512 context cannot\r
+  be used again.\r
+  SHA-512 context should be already correctly intialized by Sha512Init(), and should not be\r
+  finalized by Sha512Final(). Behavior with invalid SHA-512 context is undefined.\r
+\r
+  If Sha512Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+\r
+  @param[in, out]  Sha512Context  Pointer to the SHA-512 context.\r
+  @param[out]      HashValue      Pointer to a buffer that receives the SHA-512 digest\r
+                                  value (64 bytes).\r
+\r
+  @retval TRUE   SHA-512 digest computation succeeded.\r
+  @retval FALSE  SHA-512 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha512Final (\r
+  IN OUT  VOID   *Sha512Context,\r
+  OUT     UINT8  *HashValue\r
+  );\r
+\r
+//=====================================================================================\r
+//    MAC (Message Authentication Code) Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacMd5GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for\r
+  subsequent use.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.\r
+  @param[in]   Key             Pointer to the user-supplied key.\r
+  @param[in]   KeySize         Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 context initialization succeeded.\r
+  @retval FALSE  HMAC-MD5 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Init (\r
+  OUT  VOID         *HmacMd5Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-MD5 context.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If NewHmacMd5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.\r
+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.\r
+\r
+  @retval TRUE   HMAC-MD5 context copy succeeded.\r
+  @retval FALSE  HMAC-MD5 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Duplicate (\r
+  IN   CONST VOID  *HmacMd5Context,\r
+  OUT  VOID        *NewHmacMd5Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates HMAC-MD5 context.\r
+\r
+  This function performs HMAC-MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 data digest succeeded.\r
+  @retval FALSE  HMAC-MD5 data digest failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Update (\r
+  IN OUT  VOID        *HmacMd5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the HMAC-MD5 digest value.\r
+\r
+  This function completes HMAC-MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-MD5 context cannot\r
+  be used again.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[out]      HashValue       Pointer to a buffer that receives the HMAC-MD5 digest\r
+                                   value (16 bytes).\r
+\r
+  @retval TRUE   HMAC-MD5 digest computation succeeded.\r
+  @retval FALSE  HMAC-MD5 digest computation failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Final (\r
+  IN OUT  VOID   *HmacMd5Context,\r
+  OUT     UINT8  *HmacValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacSha1GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for\r
+  subsequent use.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.\r
+  @param[in]   Key              Pointer to the user-supplied key.\r
+  @param[in]   KeySize          Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 context initialization succeeded.\r
+  @retval FALSE  HMAC-SHA1 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Init (\r
+  OUT  VOID         *HmacSha1Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-SHA1 context.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If NewHmacSha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.\r
+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.\r
+\r
+  @retval TRUE   HMAC-SHA1 context copy succeeded.\r
+  @retval FALSE  HMAC-SHA1 context copy failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Duplicate (\r
+  IN   CONST VOID  *HmacSha1Context,\r
+  OUT  VOID        *NewHmacSha1Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates HMAC-SHA1 context.\r
+\r
+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not\r
+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 data digest succeeded.\r
+  @retval FALSE  HMAC-SHA1 data digest failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Update (\r
+  IN OUT  VOID        *HmacSha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the HMAC-SHA1 digest value.\r
+\r
+  This function completes HMAC-SHA1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot\r
+  be used again.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should\r
+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then return FALSE.\r
+  If HashValue is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.\r
+  @param[out]      HashValue        Pointer to a buffer that receives the HMAC-SHA1 digest\r
+                                    value (20 bytes).\r
+\r
+  @retval TRUE   HMAC-SHA1 digest computation succeeded.\r
+  @retval FALSE  HMAC-SHA1 digest computation failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Final (\r
+  IN OUT  VOID   *HmacSha1Context,\r
+  OUT     UINT8  *HmacValue\r
+  );\r
+\r
+//=====================================================================================\r
+//    Symmetric Cryptography Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for TDES operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+TdesGetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as TDES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
+  In addition, it sets up all TDES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 key options as follows:\r
+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeyLength is not valid, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  TdesContext  Pointer to TDES context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied TDES key.\r
+  @param[in]   KeyLength    Length of TDES key in bits.\r
+\r
+  @retval TRUE   TDES context initialization succeeded.\r
+  @retval FALSE  TDES context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesInit (\r
+  OUT  VOID         *TdesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  );\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for AES operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for AES operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AesGetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as AES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by AesContext as AES context.\r
+  In addition, it sets up all AES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeyLength is not valid, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  AesContext  Pointer to AES context being initialized.\r
+  @param[in]   Key         Pointer to the user-supplied AES key.\r
+  @param[in]   KeyLength   Length of AES key in bits.\r
+\r
+  @retval TRUE   AES context initialization succeeded.\r
+  @retval FALSE  AES context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesInit (\r
+  OUT  VOID         *AesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  );\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
+  If Ivec is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+  If this interface is not supported, then return zero.\r
+\r
+  @return  The size, in bytes, of the context buffer required for ARC4 operations.\r
+  @retval  0   This interface is not supported.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Arc4GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as ARC4 context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.\r
+  In addition, it sets up all ARC4 key materials for subsequent encryption and decryption\r
+  operations.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeySize does not in the range of [5, 256] bytes, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied ARC4 key.\r
+  @param[in]   KeySize      Size of ARC4 key in bytes.\r
+\r
+  @retval TRUE   ARC4 context initialization succeeded.\r
+  @retval FALSE  ARC4 context initialization failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Init (\r
+  OUT  VOID         *Arc4Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Performs ARC4 encryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 encryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the ARC4 encryption output.\r
+\r
+  @retval TRUE   ARC4 encryption succeeded.\r
+  @retval FALSE  ARC4 encryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Encrypt (\r
+  IN OUT  VOID         *Arc4Context,\r
+  IN      CONST UINT8  *Input,\r
+  IN      UINTN        InputSize,\r
+  OUT     UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs ARC4 decryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 decryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If Input is NULL, then return FALSE.\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]   Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the ARC4 decryption output.\r
+\r
+  @retval TRUE   ARC4 decryption succeeded.\r
+  @retval FALSE  ARC4 decryption failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Decrypt (\r
+  IN OUT  VOID   *Arc4Context,\r
+  IN      UINT8  *Input,\r
+  IN      UINTN  InputSize,\r
+  OUT     UINT8  *Output\r
+  );\r
+\r
+/**\r
+  Resets the ARC4 context to the initial state.\r
+\r
+  The function resets the ARC4 context to the state it had immediately after the\r
+  ARC4Init() function call.\r
+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context\r
+  should be already correctly initialized by ARC4Init().\r
+\r
+  If Arc4Context is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+\r
+  @retval TRUE   ARC4 reset succeeded.\r
+  @retval FALSE  ARC4 reset failed.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Reset (\r
+  IN OUT  VOID  *Arc4Context\r
+  );\r
+\r
+//=====================================================================================\r
+//    Asymmetric Cryptography Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Allocates and initializes one RSA context for subsequent use.\r
+\r
+  @return  Pointer to the RSA context that has been initialized.\r
+           If the allocations fails, RsaNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+RsaNew (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release the specified RSA context.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @param[in]  RsaContext  Pointer to the RSA context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RsaFree (\r
+  IN  VOID  *RsaContext\r
+  );\r
+\r
+/**\r
+  Sets the tag-designated key component into the established RSA context.\r
+\r
+  This function sets the tag-designated RSA key component into the established\r
+  RSA context from the user-specified non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[in]       BigNumber   Pointer to octet integer buffer.\r
+                               If NULL, then the specified key componenet in RSA\r
+                               context is cleared.\r
+  @param[in]       BnSize      Size of big number buffer in bytes.\r
+                               If BigNumber is NULL, then it is ignored.\r
+\r
+  @retval  TRUE   RSA key component was set successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaSetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  IN      CONST UINT8  *BigNumber,\r
+  IN      UINTN        BnSize\r
+  );\r
+\r
+/**\r
+  Gets the tag-designated RSA key component from the established RSA context.\r
+\r
+  This function retrieves the tag-designated RSA key component from the\r
+  established RSA context as a non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If specified key component has not been set or has been cleared, then returned\r
+  BnSize is set to 0.\r
+  If the BigNumber buffer is too small to hold the contents of the key, FALSE\r
+  is returned and BnSize is set to the required buffer size to obtain the key.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If BnSize is NULL, then return FALSE.\r
+  If BnSize is large enough but BigNumber is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[out]      BigNumber   Pointer to octet integer buffer.\r
+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.\r
+                               On output, the size of data returned in big number buffer in bytes.\r
+\r
+  @retval  TRUE   RSA key component was retrieved successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+  @retval  FALSE  BnSize is too small.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  OUT     UINT8        *BigNumber,\r
+  IN OUT  UINTN        *BnSize\r
+  );\r
+\r
+/**\r
+  Generates RSA key components.\r
+\r
+  This function generates RSA key components. It takes RSA public exponent E and\r
+  length in bits of RSA modulus N as input, and generates all key components.\r
+  If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.\r
+\r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  RsaContext           Pointer to RSA context being set.\r
+  @param[in]       ModulusLength        Length of RSA modulus N in bits.\r
+  @param[in]       PublicExponent       Pointer to RSA public exponent.\r
+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes.\r
+\r
+  @retval  TRUE   RSA key component was generated successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGenerateKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      UINTN        ModulusLength,\r
+  IN      CONST UINT8  *PublicExponent,\r
+  IN      UINTN        PublicExponentSize\r
+  );\r
+\r
+/**\r
+  Validates key components of RSA context.\r
+  NOTE: This function performs integrity checks on all the RSA key material, so\r
+        the RSA key structure must contain all the private key data.\r
+\r
+  This function validates key compoents of RSA context in following aspects:\r
+  - Whether p is a prime\r
+  - Whether q is a prime\r
+  - Whether n = p * q\r
+  - Whether d*e = 1  mod lcm(p-1,q-1)\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  RsaContext  Pointer to RSA context to check.\r
+\r
+  @retval  TRUE   RSA key components are valid.\r
+  @retval  FALSE  RSA key components are not valid.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaCheckKey (\r
+  IN  VOID  *RsaContext\r
+  );\r
+\r
+/**\r
+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.\r
+\r
+  This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+  If the Signature buffer is too small to hold the contents of signature, FALSE\r
+  is returned and SigSize is set to the required buffer size to obtain the signature.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If MessageHash is NULL, then return FALSE.\r
+  If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.\r
+  If SigSize is large enough but Signature is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]      RsaContext   Pointer to RSA context for signature generation.\r
+  @param[in]      MessageHash  Pointer to octet message hash to be signed.\r
+  @param[in]      HashSize     Size of the message hash in bytes.\r
+  @param[out]     Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.\r
+  @param[in, out] SigSize      On input, the size of Signature buffer in bytes.\r
+                               On output, the size of data returned in Signature buffer in bytes.\r
+\r
+  @retval  TRUE   Signature successfully generated in PKCS1-v1_5.\r
+  @retval  FALSE  Signature generation failed.\r
+  @retval  FALSE  SigSize is too small.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Sign (\r
+  IN      VOID         *RsaContext,\r
+  IN      CONST UINT8  *MessageHash,\r
+  IN      UINTN        HashSize,\r
+  OUT     UINT8        *Signature,\r
+  IN OUT  UINTN        *SigSize\r
+  );\r
+\r
+/**\r
+  Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If MessageHash is NULL, then return FALSE.\r
+  If Signature is NULL, then return FALSE.\r
+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256 digest, then return FALSE.\r
+\r
+  @param[in]  RsaContext   Pointer to RSA context for signature verification.\r
+  @param[in]  MessageHash  Pointer to octet message hash to be checked.\r
+  @param[in]  HashSize     Size of the message hash in bytes.\r
+  @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.\r
+  @param[in]  SigSize      Size of signature in bytes.\r
+\r
+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.\r
+  @retval  FALSE  Invalid signature or invalid RSA context.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Verify (\r
+  IN  VOID         *RsaContext,\r
+  IN  CONST UINT8  *MessageHash,\r
+  IN  UINTN        HashSize,\r
+  IN  CONST UINT8  *Signature,\r
+  IN  UINTN        SigSize\r
+  );\r
+\r
+/**\r
+  Retrieve the RSA Private Key from the password-protected PEM key data.\r
+\r
+  If PemData is NULL, then return FALSE.\r
+  If RsaContext is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  PemData      Pointer to the PEM-encoded key data to be retrieved.\r
+  @param[in]  PemSize      Size of the PEM key data in bytes.\r
+  @param[in]  Password     NULL-terminated passphrase used for encrypted PEM key data.\r
+  @param[out] RsaContext   Pointer to new-generated RSA context which contain the retrieved\r
+                           RSA private key component. Use RsaFree() function to free the\r
+                           resource.\r
+\r
+  @retval  TRUE   RSA Private Key was retrieved successfully.\r
+  @retval  FALSE  Invalid PEM key data or incorrect password.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetPrivateKeyFromPem (\r
+  IN   CONST UINT8  *PemData,\r
+  IN   UINTN        PemSize,\r
+  IN   CONST CHAR8  *Password,\r
+  OUT  VOID         **RsaContext\r
+  );\r
+\r
+/**\r
+  Retrieve the RSA Public Key from one DER-encoded X509 certificate.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If RsaContext is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Cert         Pointer to the DER-encoded X509 certificate.\r
+  @param[in]  CertSize     Size of the X509 certificate in bytes.\r
+  @param[out] RsaContext   Pointer to new-generated RSA context which contain the retrieved\r
+                           RSA public key component. Use RsaFree() function to free the\r
+                           resource.\r
+\r
+  @retval  TRUE   RSA Public Key was retrieved successfully.\r
+  @retval  FALSE  Fail to retrieve RSA public key from X509 certificate.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetPublicKeyFromX509 (\r
+  IN   CONST UINT8  *Cert,\r
+  IN   UINTN        CertSize,\r
+  OUT  VOID         **RsaContext\r
+  );\r
+\r
+/**\r
+  Retrieve the subject bytes from one X.509 certificate.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If SubjectSize is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[out]     CertSubject  Pointer to the retrieved certificate subject bytes.\r
+  @param[in, out] SubjectSize  The size in bytes of the CertSubject buffer on input,\r
+                               and the size of buffer returned CertSubject on output.\r
+\r
+  @retval  TRUE   The certificate subject retrieved successfully.\r
+  @retval  FALSE  Invalid certificate, or the SubjectSize is too small for the result.\r
+                  The SubjectSize will be updated with the required size.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509GetSubjectName (\r
+  IN      CONST UINT8  *Cert,\r
+  IN      UINTN        CertSize,\r
+  OUT     UINT8        *CertSubject,\r
+  IN OUT  UINTN        *SubjectSize\r
+  );\r
+\r
+/**\r
+  Verify one X509 certificate was issued by the trusted CA.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If CACert is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate to be verified.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[in]      CACert       Pointer to the DER-encoded trusted CA certificate.\r
+  @param[in]      CACertSize   Size of the CA Certificate in bytes.\r
+\r
+  @retval  TRUE   The certificate was issued by the trusted CA.\r
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given\r
+                  trusted CA.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509VerifyCert (\r
+  IN  CONST UINT8  *Cert,\r
+  IN  UINTN        CertSize,\r
+  IN  CONST UINT8  *CACert,\r
+  IN  UINTN        CACertSize\r
+  );\r
+\r
+/**\r
+  Construct a X509 object from DER-encoded certificate data.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If SingleX509Cert is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Cert            Pointer to the DER-encoded certificate data.\r
+  @param[in]  CertSize        The size of certificate data in bytes.\r
+  @param[out] SingleX509Cert  The generated X509 object.\r
+\r
+  @retval     TRUE            The X509 object generation succeeded.\r
+  @retval     FALSE           The operation failed.\r
+  @retval     FALSE           This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509ConstructCertificate (\r
+  IN   CONST UINT8  *Cert,\r
+  IN   UINTN        CertSize,\r
+  OUT  UINT8        **SingleX509Cert\r
+  );\r
+\r
+/**\r
+  Construct a X509 stack object from a list of DER-encoded certificate data.\r
+\r
+  If X509Stack is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  X509Stack  On input, pointer to an existing or NULL X509 stack object.\r
+                              On output, pointer to the X509 stack object with new\r
+                              inserted X509 certificate.\r
+  @param           ...        A list of DER-encoded single certificate data followed\r
+                              by certificate size. A NULL terminates the list. The\r
+                              pairs are the arguments to X509ConstructCertificate().\r
+\r
+  @retval     TRUE            The X509 stack construction succeeded.\r
+  @retval     FALSE           The construction operation failed.\r
+  @retval     FALSE           This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509ConstructCertificateStack (\r
+  IN OUT  UINT8  **X509Stack,\r
+  ...\r
+  );\r
+\r
+/**\r
+  Release the specified X509 object.\r
+\r
+  If the interface is not supported, then ASSERT().\r
+\r
+  @param[in]  X509Cert  Pointer to the X509 object to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+X509Free (\r
+  IN  VOID  *X509Cert\r
+  );\r
+\r
+/**\r
+  Release the specified X509 stack object.\r
+\r
+  If the interface is not supported, then ASSERT().\r
+\r
+  @param[in]  X509Stack  Pointer to the X509 stack object to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+X509StackFree (\r
+  IN  VOID  *X509Stack\r
+  );\r
+\r
+/**\r
+  Retrieve the TBSCertificate from one given X.509 certificate.\r
+\r
+  @param[in]      Cert         Pointer to the given DER-encoded X509 certificate.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[out]     TBSCert      DER-Encoded To-Be-Signed certificate.\r
+  @param[out]     TBSCertSize  Size of the TBS certificate in bytes.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If TBSCert is NULL, then return FALSE.\r
+  If TBSCertSize is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @retval  TRUE   The TBSCertificate was retrieved successfully.\r
+  @retval  FALSE  Invalid X.509 certificate.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509GetTBSCert (\r
+  IN  CONST UINT8  *Cert,\r
+  IN  UINTN        CertSize,\r
+  OUT UINT8        **TBSCert,\r
+  OUT UINTN        *TBSCertSize\r
+  );\r
+\r
+/**\r
+  Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:\r
+  Cryptographic Message Syntax Standard". The input signed data could be wrapped\r
+  in a ContentInfo structure.\r
+\r
+  If P7Data, CertStack, StackLength, TrustedCert or CertLength is NULL, then\r
+  return FALSE. If P7Length overflow, then return FAlSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[out] CertStack    Pointer to Signer's certificates retrieved from P7Data.\r
+                           It's caller's responsiblity to free the buffer.\r
+  @param[out] StackLength  Length of signer's certificates in bytes.\r
+  @param[out] TrustedCert  Pointer to a trusted certificate from Signer's certificates.\r
+                           It's caller's responsiblity to free the buffer.\r
+  @param[out] CertLength   Length of the trusted certificate in bytes.\r
+\r
+  @retval  TRUE            The operation is finished successfully.\r
+  @retval  FALSE           Error occurs during the operation.\r
+  @retval  FALSE           This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetSigners (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT UINT8        **CertStack,\r
+  OUT UINTN        *StackLength,\r
+  OUT UINT8        **TrustedCert,\r
+  OUT UINTN        *CertLength\r
+  );\r
+\r
+/**\r
+  Wrap function to use free() to free allocated memory for certificates.\r
+\r
+  If this interface is not supported, then ASSERT().\r
+\r
+  @param[in]  Certs        Pointer to the certificates to be freed.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Pkcs7FreeSigners (\r
+  IN  UINT8        *Certs\r
+  );\r
+\r
+/**\r
+  Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message\r
+  Syntax Standard, version 1.5". This interface is only intended to be used for\r
+  application to perform PKCS#7 functionality validation.\r
+\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  PrivateKey       Pointer to the PEM-formatted private key data for\r
+                               data signing.\r
+  @param[in]  PrivateKeySize   Size of the PEM private key data in bytes.\r
+  @param[in]  KeyPassword      NULL-terminated passphrase used for encrypted PEM\r
+                               key data.\r
+  @param[in]  InData           Pointer to the content to be signed.\r
+  @param[in]  InDataSize       Size of InData in bytes.\r
+  @param[in]  SignCert         Pointer to signer's DER-encoded certificate to sign with.\r
+  @param[in]  OtherCerts       Pointer to an optional additional set of certificates to\r
+                               include in the PKCS#7 signedData (e.g. any intermediate\r
+                               CAs in the chain).\r
+  @param[out] SignedData       Pointer to output PKCS#7 signedData.\r
+  @param[out] SignedDataSize   Size of SignedData in bytes.\r
+\r
+  @retval     TRUE             PKCS#7 data signing succeeded.\r
+  @retval     FALSE            PKCS#7 data signing failed.\r
+  @retval     FALSE            This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7Sign (\r
+  IN   CONST UINT8  *PrivateKey,\r
+  IN   UINTN        PrivateKeySize,\r
+  IN   CONST UINT8  *KeyPassword,\r
+  IN   UINT8        *InData,\r
+  IN   UINTN        InDataSize,\r
+  IN   UINT8        *SignCert,\r
+  IN   UINT8        *OtherCerts      OPTIONAL,\r
+  OUT  UINT8        **SignedData,\r
+  OUT  UINTN        *SignedDataSize\r
+  );\r
+\r
+/**\r
+  Verifies the validility of a PKCS#7 signed data as described in "PKCS #7:\r
+  Cryptographic Message Syntax Standard". The input signed data could be wrapped\r
+  in a ContentInfo structure.\r
+\r
+  If P7Data, TrustedCert or InData is NULL, then return FALSE.\r
+  If P7Length, CertLength or DataLength overflow, then return FAlSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which\r
+                           is used for certificate chain verification.\r
+  @param[in]  CertLength   Length of the trusted certificate in bytes.\r
+  @param[in]  InData       Pointer to the content to be verified.\r
+  @param[in]  DataLength   Length of InData in bytes.\r
+\r
+  @retval  TRUE  The specified PKCS#7 signed data is valid.\r
+  @retval  FALSE Invalid PKCS#7 signed data.\r
+  @retval  FALSE This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7Verify (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  IN  CONST UINT8  *TrustedCert,\r
+  IN  UINTN        CertLength,\r
+  IN  CONST UINT8  *InData,\r
+  IN  UINTN        DataLength\r
+  );\r
+\r
+/**\r
+  Extracts the attached content from a PKCS#7 signed data if existed. The input signed\r
+  data could be wrapped in a ContentInfo structure.\r
+\r
+  If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,\r
+  then return FAlSE. If the P7Data is not correctly formatted, then return FALSE.\r
+\r
+  Caution: This function may receive untrusted input. So this function will do\r
+           basic check for PKCS#7 data structure.\r
+\r
+  @param[in]   P7Data       Pointer to the PKCS#7 signed data to process.\r
+  @param[in]   P7Length     Length of the PKCS#7 signed data in bytes.\r
+  @param[out]  Content      Pointer to the extracted content from the PKCS#7 signedData.\r
+                            It's caller's responsiblity to free the buffer.\r
+  @param[out]  ContentSize  The size of the extracted content in bytes.\r
+\r
+  @retval     TRUE          The P7Data was correctly formatted for processing.\r
+  @retval     FALSE         The P7Data was not correctly formatted for processing.\r
+\r
+*/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetAttachedContent (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT VOID         **Content,\r
+  OUT UINTN        *ContentSize\r
+  );\r
+\r
+/**\r
+  Verifies the validility of a PE/COFF Authenticode Signature as described in "Windows\r
+  Authenticode Portable Executable Signature Format".\r
+\r
+  If AuthData is NULL, then return FALSE.\r
+  If ImageHash is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  AuthData     Pointer to the Authenticode Signature retrieved from signed\r
+                           PE/COFF image to be verified.\r
+  @param[in]  DataSize     Size of the Authenticode Signature in bytes.\r
+  @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which\r
+                           is used for certificate chain verification.\r
+  @param[in]  CertSize     Size of the trusted certificate in bytes.\r
+  @param[in]  ImageHash    Pointer to the original image file hash value. The procudure\r
+                           for calculating the image hash value is described in Authenticode\r
+                           specification.\r
+  @param[in]  HashSize     Size of Image hash value in bytes.\r
+\r
+  @retval  TRUE   The specified Authenticode Signature is valid.\r
+  @retval  FALSE  Invalid Authenticode Signature.\r
+  @retval  FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AuthenticodeVerify (\r
+  IN  CONST UINT8  *AuthData,\r
+  IN  UINTN        DataSize,\r
+  IN  CONST UINT8  *TrustedCert,\r
+  IN  UINTN        CertSize,\r
+  IN  CONST UINT8  *ImageHash,\r
+  IN  UINTN        HashSize\r
+  );\r
+\r
+/**\r
+  Verifies the validility of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode\r
+  signature.\r
+\r
+  If AuthData is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  AuthData     Pointer to the Authenticode Signature retrieved from signed\r
+                           PE/COFF image to be verified.\r
+  @param[in]  DataSize     Size of the Authenticode Signature in bytes.\r
+  @param[in]  TsaCert      Pointer to a trusted/root TSA certificate encoded in DER, which\r
+                           is used for TSA certificate chain verification.\r
+  @param[in]  CertSize     Size of the trusted certificate in bytes.\r
+  @param[out] SigningTime  Return the time of timestamp generation time if the timestamp\r
+                           signature is valid.\r
+\r
+  @retval  TRUE   The specified Authenticode includes a valid RFC3161 Timestamp CounterSignature.\r
+  @retval  FALSE  No valid RFC3161 Timestamp CounterSignature in the specified Authenticode data.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ImageTimestampVerify (\r
+  IN  CONST UINT8  *AuthData,\r
+  IN  UINTN        DataSize,\r
+  IN  CONST UINT8  *TsaCert,\r
+  IN  UINTN        CertSize,\r
+  OUT EFI_TIME     *SigningTime\r
+  );\r
+\r
+//=====================================================================================\r
+//    DH Key Exchange Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
+\r
+  @return  Pointer to the Diffie-Hellman Context that has been initialized.\r
+           If the allocations fails, DhNew() returns NULL.\r
+           If the interface is not supported, DhNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DhNew (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release the specified DH context.\r
+\r
+  If the interface is not supported, then ASSERT().\r
+\r
+  @param[in]  DhContext  Pointer to the DH context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DhFree (\r
+  IN  VOID  *DhContext\r
+  );\r
+\r
+/**\r
+  Generates DH parameter.\r
+\r
+  Given generator g, and length of prime number p in bits, this function generates p,\r
+  and sets DH context according to value of g and p.\r
+\r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If DhContext is NULL, then return FALSE.\r
+  If Prime is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.\r
+\r
+  @retval TRUE   DH pamameter generation succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateParameter (\r
+  IN OUT  VOID   *DhContext,\r
+  IN      UINTN  Generator,\r
+  IN      UINTN  PrimeLength,\r
+  OUT     UINT8  *Prime\r
+  );\r
+\r
+/**\r
+  Sets generator and prime parameters for DH.\r
+\r
+  Given generator g, and prime number p, this function and sets DH\r
+  context accordingly.\r
+\r
+  If DhContext is NULL, then return FALSE.\r
+  If Prime is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[in]       Prime        Pointer to the prime number.\r
+\r
+  @retval TRUE   DH pamameter setting succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  Value of Generator is not suitable for the Prime.\r
+  @retval FALSE  Value of Prime is not a prime number.\r
+  @retval FALSE  Value of Prime is not a safe prime number.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhSetParameter (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      UINTN        Generator,\r
+  IN      UINTN        PrimeLength,\r
+  IN      CONST UINT8  *Prime\r
+  );\r
+\r
+/**\r
+  Generates DH public key.\r
+\r
+  This function generates random secret exponent, and computes the public key, which is\r
+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.\r
+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and\r
+  PublicKeySize is set to the required buffer size to obtain the public key.\r
+\r
+  If DhContext is NULL, then return FALSE.\r
+  If PublicKeySize is NULL, then return FALSE.\r
+  If PublicKeySize is large enough but PublicKey is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  DhContext      Pointer to the DH context.\r
+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.\r
+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.\r
+                                 On output, the size of data returned in PublicKey buffer in bytes.\r
+\r
+  @retval TRUE   DH public key generation succeeded.\r
+  @retval FALSE  DH public key generation failed.\r
+  @retval FALSE  PublicKeySize is not large enough.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateKey (\r
+  IN OUT  VOID   *DhContext,\r
+  OUT     UINT8  *PublicKey,\r
+  IN OUT  UINTN  *PublicKeySize\r
+  );\r
+\r
+/**\r
+  Computes exchanged common key.\r
+\r
+  Given peer's public key, this function computes the exchanged common key, based on its own\r
+  context including value of prime modulus and random secret exponent.\r
+\r
+  If DhContext is NULL, then return FALSE.\r
+  If PeerPublicKey is NULL, then return FALSE.\r
+  If KeySize is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeySize is not large enough, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in, out]  DhContext          Pointer to the DH context.\r
+  @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.\r
+  @param[out]      Key                Pointer to the buffer to receive generated key.\r
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.\r
+                                     On output, the size of data returned in Key buffer in bytes.\r
+\r
+  @retval TRUE   DH exchanged key generation succeeded.\r
+  @retval FALSE  DH exchanged key generation failed.\r
+  @retval FALSE  KeySize is not large enough.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhComputeKey (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      CONST UINT8  *PeerPublicKey,\r
+  IN      UINTN        PeerPublicKeySize,\r
+  OUT     UINT8        *Key,\r
+  IN OUT  UINTN        *KeySize\r
+  );\r
+\r
+//=====================================================================================\r
+//    Pseudo-Random Generation Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Sets up the seed value for the pseudorandom number generator.\r
+\r
+  This function sets up the seed value for the pseudorandom number generator.\r
+  If Seed is not NULL, then the seed passed in is used.\r
+  If Seed is NULL, then default seed is used.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[in]  Seed      Pointer to seed value.\r
+                        If NULL, default seed is used.\r
+  @param[in]  SeedSize  Size of seed value.\r
+                        If Seed is NULL, this parameter is ignored.\r
+\r
+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.\r
+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomSeed (\r
+  IN  CONST  UINT8  *Seed  OPTIONAL,\r
+  IN  UINTN         SeedSize\r
+  );\r
+\r
+/**\r
+  Generates a pseudorandom byte stream of the specified size.\r
+\r
+  If Output is NULL, then return FALSE.\r
+  If this interface is not supported, then return FALSE.\r
+\r
+  @param[out]  Output  Pointer to buffer to receive random value.\r
+  @param[in]   Size    Size of randome bytes to generate.\r
+\r
+  @retval TRUE   Pseudorandom byte stream generated successfully.\r
+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomBytes (\r
+  OUT  UINT8  *Output,\r
+  IN   UINTN  Size\r
+  );\r
+\r
+#endif // __BASE_CRYPT_LIB_H__\r
diff --git a/Cryptlib/Library/BaseLib.h b/Cryptlib/Library/BaseLib.h
new file mode 100644 (file)
index 0000000..4c99fa9
--- /dev/null
@@ -0,0 +1,2 @@
+#include <efi.h>
+#include <efilib.h>
diff --git a/Cryptlib/Library/BaseMemoryLib.h b/Cryptlib/Library/BaseMemoryLib.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Cryptlib/Library/DebugLib.h b/Cryptlib/Library/DebugLib.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Cryptlib/Library/MemoryAllocationLib.h b/Cryptlib/Library/MemoryAllocationLib.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile
new file mode 100644 (file)
index 0000000..a028979
--- /dev/null
@@ -0,0 +1,53 @@
+
+EFI_INCLUDES   = -IInclude -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+
+CFLAGS         = -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \
+                 -Wall $(EFI_INCLUDES) -std=gnu89 \
+                 -ffreestanding -I$(shell $(CC) -print-file-name=include)
+
+ifeq ($(ARCH),x86_64)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
+               -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DNO_BUILTIN_VA_FUNCS \
+               -DMDE_CPU_IA64
+endif
+ifeq ($(ARCH),ia32)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32 \
+               -DMDE_CPU_IA32
+endif
+ifeq ($(ARCH),aarch64)
+       CFLAGS  += -DMDE_CPU_AARCH64
+endif
+LDFLAGS                = -nostdlib -znocombreloc
+
+TARGET         = libcryptlib.a
+OBJS           =   Hash/CryptMd4.o \
+                   Hash/CryptMd5.o \
+                   Hash/CryptSha1.o \
+                   Hash/CryptSha256.o \
+                   Hash/CryptSha512.o \
+                   Hmac/CryptHmacMd5.o \
+                   Hmac/CryptHmacSha1.o \
+                   Cipher/CryptAes.o \
+                   Cipher/CryptTdes.o \
+                   Cipher/CryptArc4.o \
+                   Rand/CryptRand.o \
+                   Pk/CryptRsaBasic.o \
+                   Pk/CryptRsaExtNull.o \
+                   Pk/CryptPkcs7SignNull.o \
+                   Pk/CryptPkcs7Verify.o \
+                   Pk/CryptDhNull.o \
+                   Pk/CryptTs.o \
+                   Pk/CryptX509.o \
+                   Pk/CryptAuthenticode.o \
+                   Pem/CryptPem.o \
+                   SysCall/CrtWrapper.o \
+                   SysCall/TimerWrapper.o \
+                   SysCall/BaseMemAllocation.o \
+                   SysCall/BaseStrings.o
+
+all: $(TARGET)
+
+libcryptlib.a: $(OBJS)
+       ar rcs libcryptlib.a $(OBJS)
+clean:
+       rm -f $(TARGET) $(OBJS)
diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
new file mode 100644 (file)
index 0000000..1b80e02
--- /dev/null
@@ -0,0 +1,472 @@
+
+EFI_INCLUDES   = -I../Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -Icrypto/asn1 -Icrypto/evp -Icrypto/modes
+
+CFLAGS         = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \
+                 -ffreestanding -std=gnu89 -I$(shell $(CC) -print-file-name=include) \
+                 -Wall $(EFI_INCLUDES) -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
+
+ifeq ($(ARCH),x86_64)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
+               -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \
+               -UNO_BUILTIN_VA_FUNCS -DMDE_CPU_IA64
+endif
+ifeq ($(ARCH),ia32)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
+               -m32 -DMDE_CPU_IA32
+endif
+ifeq ($(ARCH),aarch64)
+       CFLAGS  += -O2 -DMDE_CPU_AARCH64
+endif
+ifeq ($(ARCH),arm)
+       CFLAGS  += -O2 -DMDE_CPU_ARM
+endif
+LDFLAGS                = -nostdlib -znocombreloc
+
+TARGET         = libopenssl.a
+OBJS           =   crypto/cryptlib.o \
+  crypto/mem.o \
+  crypto/mem_clr.o \
+  crypto/mem_dbg.o \
+  crypto/cversion.o \
+  crypto/ex_data.o \
+  crypto/cpt_err.o \
+  crypto/ebcdic.o \
+  crypto/uid.o \
+  crypto/o_time.o \
+  crypto/o_str.o \
+  crypto/o_dir.o \
+  crypto/o_fips.o \
+  crypto/o_init.o \
+  crypto/fips_ers.o \
+  crypto/md4/md4_dgst.o \
+  crypto/md4/md4_one.o \
+  crypto/md5/md5_dgst.o \
+  crypto/md5/md5_one.o \
+  crypto/sha/sha_dgst.o \
+  crypto/sha/sha1dgst.o \
+  crypto/sha/sha_one.o \
+  crypto/sha/sha1_one.o \
+  crypto/sha/sha256.o \
+  crypto/sha/sha512.o \
+  crypto/hmac/hmac.o \
+  crypto/hmac/hm_ameth.o \
+  crypto/hmac/hm_pmeth.o \
+  crypto/des/set_key.o \
+  crypto/des/ecb_enc.o \
+  crypto/des/cbc_enc.o \
+  crypto/des/ecb3_enc.o \
+  crypto/des/cfb64enc.o \
+  crypto/des/cfb64ede.o \
+  crypto/des/cfb_enc.o \
+  crypto/des/ofb64ede.o \
+  crypto/des/enc_read.o \
+  crypto/des/enc_writ.o \
+  crypto/des/ofb64enc.o \
+  crypto/des/ofb_enc.o \
+  crypto/des/str2key.o \
+  crypto/des/pcbc_enc.o \
+  crypto/des/qud_cksm.o \
+  crypto/des/rand_key.o \
+  crypto/des/des_enc.o \
+  crypto/des/fcrypt_b.o \
+  crypto/des/fcrypt.o \
+  crypto/des/xcbc_enc.o \
+  crypto/des/rpc_enc.o \
+  crypto/des/cbc_cksm.o \
+  crypto/des/ede_cbcm_enc.o \
+  crypto/des/des_old.o \
+  crypto/des/des_old2.o \
+  crypto/des/read2pwd.o \
+  crypto/rc4/rc4_enc.o \
+  crypto/rc4/rc4_skey.o \
+  crypto/rc4/rc4_utl.o \
+  crypto/aes/aes_misc.o \
+  crypto/aes/aes_ecb.o \
+  crypto/aes/aes_cfb.o \
+  crypto/aes/aes_ofb.o \
+  crypto/aes/aes_ctr.o \
+  crypto/aes/aes_ige.o \
+  crypto/aes/aes_wrap.o \
+  crypto/aes/aes_core.o \
+  crypto/aes/aes_cbc.o \
+  crypto/modes/cbc128.o \
+  crypto/modes/ctr128.o \
+  crypto/modes/cts128.o \
+  crypto/modes/cfb128.o \
+  crypto/modes/ofb128.o \
+  crypto/modes/gcm128.o \
+  crypto/modes/ccm128.o \
+  crypto/modes/xts128.o \
+  crypto/modes/wrap128.o \
+  crypto/bn/bn_add.o \
+  crypto/bn/bn_div.o \
+  crypto/bn/bn_exp.o \
+  crypto/bn/bn_lib.o \
+  crypto/bn/bn_ctx.o \
+  crypto/bn/bn_mul.o \
+  crypto/bn/bn_mod.o \
+  crypto/bn/bn_print.o \
+  crypto/bn/bn_rand.o \
+  crypto/bn/bn_shift.o \
+  crypto/bn/bn_word.o \
+  crypto/bn/bn_blind.o \
+  crypto/bn/bn_kron.o \
+  crypto/bn/bn_sqrt.o \
+  crypto/bn/bn_gcd.o \
+  crypto/bn/bn_prime.o \
+  crypto/bn/bn_err.o \
+  crypto/bn/bn_sqr.o \
+  crypto/bn/bn_asm.o \
+  crypto/bn/bn_recp.o \
+  crypto/bn/bn_mont.o \
+  crypto/bn/bn_mpi.o \
+  crypto/bn/bn_exp2.o \
+  crypto/bn/bn_gf2m.o \
+  crypto/bn/bn_nist.o \
+  crypto/bn/bn_depr.o \
+  crypto/bn/bn_x931p.o \
+  crypto/bn/bn_const.o \
+  crypto/rsa/rsa_eay.o \
+  crypto/rsa/rsa_gen.o \
+  crypto/rsa/rsa_lib.o \
+  crypto/rsa/rsa_sign.o \
+  crypto/rsa/rsa_saos.o \
+  crypto/rsa/rsa_err.o \
+  crypto/rsa/rsa_pk1.o \
+  crypto/rsa/rsa_ssl.o \
+  crypto/rsa/rsa_none.o \
+  crypto/rsa/rsa_oaep.o \
+  crypto/rsa/rsa_chk.o \
+  crypto/rsa/rsa_null.o \
+  crypto/rsa/rsa_pss.o \
+  crypto/rsa/rsa_x931.o \
+  crypto/rsa/rsa_asn1.o \
+  crypto/rsa/rsa_depr.o \
+  crypto/rsa/rsa_ameth.o \
+  crypto/rsa/rsa_prn.o \
+  crypto/rsa/rsa_pmeth.o \
+  crypto/rsa/rsa_crpt.o \
+  crypto/dso/dso_dl.o \
+  crypto/dso/dso_dlfcn.o \
+  crypto/dso/dso_err.o \
+  crypto/dso/dso_lib.o \
+  crypto/dso/dso_null.o \
+  crypto/dso/dso_openssl.o \
+  crypto/dso/dso_win32.o \
+  crypto/dso/dso_vms.o \
+  crypto/dso/dso_beos.o \
+  crypto/dh/dh_asn1.o \
+  crypto/dh/dh_gen.o \
+  crypto/dh/dh_key.o \
+  crypto/dh/dh_lib.o \
+  crypto/dh/dh_check.o \
+  crypto/dh/dh_err.o \
+  crypto/dh/dh_depr.o \
+  crypto/dh/dh_ameth.o \
+  crypto/dh/dh_pmeth.o \
+  crypto/dh/dh_prn.o \
+  crypto/dh/dh_rfc5114.o \
+  crypto/buffer/buffer.o \
+  crypto/buffer/buf_str.o \
+  crypto/buffer/buf_err.o \
+  crypto/bio/bio_lib.o \
+  crypto/bio/bio_cb.o \
+  crypto/bio/bio_err.o \
+  crypto/bio/bss_mem.o \
+  crypto/bio/bss_null.o \
+  crypto/bio/bss_fd.o \
+  crypto/bio/bss_file.o \
+  crypto/bio/bss_sock.o \
+  crypto/bio/bss_conn.o \
+  crypto/bio/bf_null.o \
+  crypto/bio/bf_buff.o \
+  crypto/bio/b_dump.o \
+  crypto/bio/b_print.o \
+  crypto/bio/b_sock.o \
+  crypto/bio/bss_acpt.o \
+  crypto/bio/bf_nbio.o \
+  crypto/bio/bss_log.o \
+  crypto/bio/bss_bio.o \
+  crypto/bio/bss_dgram.o \
+  crypto/stack/stack.o \
+  crypto/lhash/lhash.o \
+  crypto/lhash/lh_stats.o \
+  crypto/rand/md_rand.o \
+  crypto/rand/randfile.o \
+  crypto/rand/rand_lib.o \
+  crypto/rand/rand_err.o \
+  crypto/rand/rand_unix.o \
+  crypto/err/err.o \
+  crypto/err/err_all.o \
+  crypto/err/err_prn.o \
+  crypto/objects/o_names.o \
+  crypto/objects/obj_dat.o \
+  crypto/objects/obj_lib.o \
+  crypto/objects/obj_err.o \
+  crypto/objects/obj_xref.o \
+  crypto/evp/encode.o \
+  crypto/evp/digest.o \
+  crypto/evp/evp_enc.o \
+  crypto/evp/evp_key.o \
+  crypto/evp/evp_acnf.o \
+  crypto/evp/evp_cnf.o \
+  crypto/evp/e_des.o \
+  crypto/evp/e_bf.o \
+  crypto/evp/e_idea.o \
+  crypto/evp/e_des3.o \
+  crypto/evp/e_camellia.o \
+  crypto/evp/e_rc4.o \
+  crypto/evp/e_aes.o \
+  crypto/evp/names.o \
+  crypto/evp/e_seed.o \
+  crypto/evp/e_xcbc_d.o \
+  crypto/evp/e_rc2.o \
+  crypto/evp/e_cast.o \
+  crypto/evp/e_rc5.o \
+  crypto/evp/m_null.o \
+  crypto/evp/m_md2.o \
+  crypto/evp/m_md4.o \
+  crypto/evp/m_md5.o \
+  crypto/evp/m_sha.o \
+  crypto/evp/m_sha1.o \
+  crypto/evp/m_wp.o \
+  crypto/evp/m_dss.o \
+  crypto/evp/m_dss1.o \
+  crypto/evp/m_mdc2.o \
+  crypto/evp/m_ripemd.o \
+  crypto/evp/m_ecdsa.o \
+  crypto/evp/p_open.o \
+  crypto/evp/p_seal.o \
+  crypto/evp/p_sign.o \
+  crypto/evp/p_verify.o \
+  crypto/evp/p_lib.o \
+  crypto/evp/p_enc.o \
+  crypto/evp/p_dec.o \
+  crypto/evp/bio_md.o \
+  crypto/evp/bio_b64.o \
+  crypto/evp/bio_enc.o \
+  crypto/evp/evp_err.o \
+  crypto/evp/e_null.o \
+  crypto/evp/c_all.o \
+  crypto/evp/c_allc.o \
+  crypto/evp/c_alld.o \
+  crypto/evp/evp_lib.o \
+  crypto/evp/bio_ok.o \
+  crypto/evp/evp_pkey.o \
+  crypto/evp/evp_pbe.o \
+  crypto/evp/p5_crpt.o \
+  crypto/evp/p5_crpt2.o \
+  crypto/evp/e_old.o \
+  crypto/evp/pmeth_lib.o \
+  crypto/evp/pmeth_fn.o \
+  crypto/evp/pmeth_gn.o \
+  crypto/evp/m_sigver.o \
+  crypto/evp/e_aes_cbc_hmac_sha1.o \
+  crypto/evp/e_aes_cbc_hmac_sha256.o \
+  crypto/evp/e_rc4_hmac_md5.o \
+  crypto/asn1/a_object.o \
+  crypto/asn1/a_bitstr.o \
+  crypto/asn1/a_utctm.o \
+  crypto/asn1/a_gentm.o \
+  crypto/asn1/a_time.o \
+  crypto/asn1/a_int.o \
+  crypto/asn1/a_octet.o \
+  crypto/asn1/a_print.o \
+  crypto/asn1/a_type.o \
+  crypto/asn1/a_set.o \
+  crypto/asn1/a_dup.o \
+  crypto/asn1/a_d2i_fp.o \
+  crypto/asn1/a_i2d_fp.o \
+  crypto/asn1/a_enum.o \
+  crypto/asn1/a_utf8.o \
+  crypto/asn1/a_sign.o \
+  crypto/asn1/a_digest.o \
+  crypto/asn1/a_verify.o \
+  crypto/asn1/a_mbstr.o \
+  crypto/asn1/a_strex.o \
+  crypto/asn1/x_algor.o \
+  crypto/asn1/x_val.o \
+  crypto/asn1/x_pubkey.o \
+  crypto/asn1/x_sig.o \
+  crypto/asn1/x_req.o \
+  crypto/asn1/x_attrib.o \
+  crypto/asn1/x_bignum.o \
+  crypto/asn1/x_long.o \
+  crypto/asn1/x_name.o \
+  crypto/asn1/x_x509.o \
+  crypto/asn1/x_x509a.o \
+  crypto/asn1/x_crl.o \
+  crypto/asn1/x_info.o \
+  crypto/asn1/x_spki.o \
+  crypto/asn1/nsseq.o \
+  crypto/asn1/x_nx509.o \
+  crypto/asn1/d2i_pu.o \
+  crypto/asn1/d2i_pr.o \
+  crypto/asn1/i2d_pu.o \
+  crypto/asn1/i2d_pr.o \
+  crypto/asn1/t_req.o \
+  crypto/asn1/t_x509.o \
+  crypto/asn1/t_x509a.o \
+  crypto/asn1/t_crl.o \
+  crypto/asn1/t_pkey.o \
+  crypto/asn1/t_spki.o \
+  crypto/asn1/t_bitst.o \
+  crypto/asn1/tasn_new.o \
+  crypto/asn1/tasn_fre.o \
+  crypto/asn1/tasn_enc.o \
+  crypto/asn1/tasn_dec.o \
+  crypto/asn1/tasn_utl.o \
+  crypto/asn1/tasn_typ.o \
+  crypto/asn1/tasn_prn.o \
+  crypto/asn1/ameth_lib.o \
+  crypto/asn1/f_int.o \
+  crypto/asn1/f_string.o \
+  crypto/asn1/n_pkey.o \
+  crypto/asn1/f_enum.o \
+  crypto/asn1/x_pkey.o \
+  crypto/asn1/a_bool.o \
+  crypto/asn1/x_exten.o \
+  crypto/asn1/bio_asn1.o \
+  crypto/asn1/bio_ndef.o \
+  crypto/asn1/asn_mime.o \
+  crypto/asn1/asn1_gen.o \
+  crypto/asn1/asn1_par.o \
+  crypto/asn1/asn1_lib.o \
+  crypto/asn1/asn1_err.o \
+  crypto/asn1/a_bytes.o \
+  crypto/asn1/a_strnid.o \
+  crypto/asn1/evp_asn1.o \
+  crypto/asn1/asn_pack.o \
+  crypto/asn1/p5_pbe.o \
+  crypto/asn1/p5_pbev2.o \
+  crypto/asn1/p8_pkey.o \
+  crypto/asn1/asn_moid.o \
+  crypto/pem/pem_sign.o \
+  crypto/pem/pem_seal.o \
+  crypto/pem/pem_info.o \
+  crypto/pem/pem_lib.o \
+  crypto/pem/pem_all.o \
+  crypto/pem/pem_err.o \
+  crypto/pem/pem_x509.o \
+  crypto/pem/pem_xaux.o \
+  crypto/pem/pem_oth.o \
+  crypto/pem/pem_pk8.o \
+  crypto/pem/pem_pkey.o \
+  crypto/pem/pvkfmt.o \
+  crypto/x509/x509_def.o \
+  crypto/x509/x509_d2.o \
+  crypto/x509/x509_r2x.o \
+  crypto/x509/x509_cmp.o \
+  crypto/x509/x509_obj.o \
+  crypto/x509/x509_req.o \
+  crypto/x509/x509spki.o \
+  crypto/x509/x509_vfy.o \
+  crypto/x509/x509_set.o \
+  crypto/x509/x509cset.o \
+  crypto/x509/x509rset.o \
+  crypto/x509/x509_err.o \
+  crypto/x509/x509name.o \
+  crypto/x509/x509_v3.o \
+  crypto/x509/x509_ext.o \
+  crypto/x509/x509_att.o \
+  crypto/x509/x509type.o \
+  crypto/x509/x509_lu.o \
+  crypto/x509/x_all.o \
+  crypto/x509/x509_txt.o \
+  crypto/x509/x509_trs.o \
+  crypto/x509/x509_vpm.o \
+  crypto/x509v3/v3_bcons.o \
+  crypto/x509v3/v3_bitst.o \
+  crypto/x509v3/v3_conf.o \
+  crypto/x509v3/v3_extku.o \
+  crypto/x509v3/v3_ia5.o \
+  crypto/x509v3/v3_lib.o \
+  crypto/x509v3/v3_prn.o \
+  crypto/x509v3/v3_utl.o \
+  crypto/x509v3/v3err.o \
+  crypto/x509v3/v3_genn.o \
+  crypto/x509v3/v3_alt.o \
+  crypto/x509v3/v3_skey.o \
+  crypto/x509v3/v3_akey.o \
+  crypto/x509v3/v3_pku.o \
+  crypto/x509v3/v3_int.o \
+  crypto/x509v3/v3_enum.o \
+  crypto/x509v3/v3_sxnet.o \
+  crypto/x509v3/v3_cpols.o \
+  crypto/x509v3/v3_crld.o \
+  crypto/x509v3/v3_purp.o \
+  crypto/x509v3/v3_info.o \
+  crypto/x509v3/v3_ocsp.o \
+  crypto/x509v3/v3_akeya.o \
+  crypto/x509v3/v3_pmaps.o \
+  crypto/x509v3/v3_pcons.o \
+  crypto/x509v3/v3_ncons.o \
+  crypto/x509v3/v3_pcia.o \
+  crypto/x509v3/v3_pci.o \
+  crypto/x509v3/pcy_cache.o \
+  crypto/x509v3/pcy_node.o \
+  crypto/x509v3/pcy_data.o \
+  crypto/x509v3/pcy_map.o \
+  crypto/x509v3/pcy_tree.o \
+  crypto/x509v3/pcy_lib.o \
+  crypto/x509v3/v3_asid.o \
+  crypto/x509v3/v3_addr.o \
+  crypto/conf/conf_err.o \
+  crypto/conf/conf_lib.o \
+  crypto/conf/conf_api.o \
+  crypto/conf/conf_def.o \
+  crypto/conf/conf_mod.o \
+  crypto/conf/conf_mall.o \
+  crypto/conf/conf_sap.o \
+  crypto/txt_db/txt_db.o \
+  crypto/pkcs7/pk7_asn1.o \
+  crypto/pkcs7/pk7_lib.o \
+  crypto/pkcs7/pkcs7err.o \
+  crypto/pkcs7/pk7_doit.o \
+  crypto/pkcs7/pk7_smime.o \
+  crypto/pkcs7/pk7_attr.o \
+  crypto/pkcs7/pk7_mime.o \
+  crypto/pkcs7/bio_pk7.o \
+  crypto/pkcs12/p12_add.o \
+  crypto/pkcs12/p12_asn.o \
+  crypto/pkcs12/p12_attr.o \
+  crypto/pkcs12/p12_crpt.o \
+  crypto/pkcs12/p12_crt.o \
+  crypto/pkcs12/p12_decr.o \
+  crypto/pkcs12/p12_init.o \
+  crypto/pkcs12/p12_key.o \
+  crypto/pkcs12/p12_kiss.o \
+  crypto/pkcs12/p12_mutl.o \
+  crypto/pkcs12/p12_utl.o \
+  crypto/pkcs12/p12_npas.o \
+  crypto/pkcs12/pk12err.o \
+  crypto/pkcs12/p12_p8d.o \
+  crypto/pkcs12/p12_p8e.o \
+  crypto/comp/comp_lib.o \
+  crypto/comp/comp_err.o \
+  crypto/comp/c_rle.o \
+  crypto/comp/c_zlib.o \
+  crypto/ocsp/ocsp_asn.o \
+  crypto/ocsp/ocsp_ext.o \
+  crypto/ocsp/ocsp_ht.o \
+  crypto/ocsp/ocsp_lib.o \
+  crypto/ocsp/ocsp_cl.o \
+  crypto/ocsp/ocsp_srv.o \
+  crypto/ocsp/ocsp_prn.o \
+  crypto/ocsp/ocsp_vfy.o \
+  crypto/ocsp/ocsp_err.o \
+  crypto/ui/ui_lib.o \
+  crypto/ui/ui_util.o \
+  crypto/ui/ui_compat.o \
+  crypto/krb5/krb5_asn.o \
+  crypto/cmac/cmac.o \
+  crypto/cmac/cm_ameth.o \
+  crypto/cmac/cm_pmeth.o \
+
+all: $(TARGET)
+
+libopenssl.a: $(OBJS)
+       ar rcs libopenssl.a $(OBJS)
+
+clean:
+       rm -f $(TARGET) $(OBJS)
diff --git a/Cryptlib/OpenSSL/buildinf.h b/Cryptlib/OpenSSL/buildinf.h
new file mode 100644 (file)
index 0000000..673bf78
--- /dev/null
@@ -0,0 +1,2 @@
+#define PLATFORM  "UEFI"\r
+#define DATE      "Mon Mar 8 14:17:05 PDT 2010"\r
diff --git a/Cryptlib/OpenSSL/crypto/LPdir_nyi.c b/Cryptlib/OpenSSL/crypto/LPdir_nyi.c
new file mode 100644 (file)
index 0000000..283d5b0
--- /dev/null
@@ -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 (file)
index 0000000..805d0e2
--- /dev/null
@@ -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 (file)
index 0000000..1225000
--- /dev/null
@@ -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 (file)
index 0000000..7019b5d
--- /dev/null
@@ -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 (file)
index 0000000..9e760c4
--- /dev/null
@@ -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 (file)
index 0000000..52151a5
--- /dev/null
@@ -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 (file)
index 0000000..8f2b770
--- /dev/null
@@ -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 (file)
index 0000000..7acd74e
--- /dev/null
@@ -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 (file)
index 0000000..fafad4d
--- /dev/null
@@ -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 (file)
index 0000000..64a08ca
--- /dev/null
@@ -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 (file)
index 0000000..b7b64d5
--- /dev/null
@@ -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 (file)
index 0000000..f906188
--- /dev/null
@@ -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 (file)
index 0000000..1b85bc9
--- /dev/null
@@ -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 (file)
index 0000000..385b539
--- /dev/null
@@ -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 (file)
index 0000000..51b6f24
--- /dev/null
@@ -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 (file)
index 0000000..7cbc475
--- /dev/null
@@ -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 (file)
index 0000000..349ab56
--- /dev/null
@@ -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 (file)
index 0000000..c3498ac
--- /dev/null
@@ -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 (file)
index 0000000..fa76dca
--- /dev/null
@@ -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 (file)
index 0000000..0f56cd4
--- /dev/null
@@ -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 (file)
index 0000000..7e26704
--- /dev/null
@@ -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 (file)
index 0000000..6935efe
--- /dev/null
@@ -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 (file)
index 0000000..27f9c16
--- /dev/null
@@ -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 (file)
index 0000000..1a6e9ca
--- /dev/null
@@ -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 (file)
index 0000000..d83e4ad
--- /dev/null
@@ -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 (file)
index 0000000..bf3f971
--- /dev/null
@@ -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 (file)
index 0000000..51c6a0c
--- /dev/null
@@ -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 (file)
index 0000000..9f39bff
--- /dev/null
@@ -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 (file)
index 0000000..5224345
--- /dev/null
@@ -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 (file)
index 0000000..fcb2d56
--- /dev/null
@@ -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 (file)
index 0000000..bb166e8
--- /dev/null
@@ -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 (file)
index 0000000..724a10b
--- /dev/null
@@ -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 (file)
index 0000000..23dc2e8
--- /dev/null
@@ -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 (file)
index 0000000..3ffd934
--- /dev/null
@@ -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 (file)
index 0000000..5389c04
--- /dev/null
@@ -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 (file)
index 0000000..fd4ac8d
--- /dev/null
@@ -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 (file)
index 0000000..6574923
--- /dev/null
@@ -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 (file)
index 0000000..874b1af
--- /dev/null
@@ -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 (file)
index 0000000..4c004fa
--- /dev/null
@@ -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 (file)
index 0000000..e85e339
--- /dev/null
@@ -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 (file)
index 0000000..96110c5
--- /dev/null
@@ -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 (file)
index 0000000..fab2dd9
--- /dev/null
@@ -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 (file)
index 0000000..366caf0
--- /dev/null
@@ -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 (file)
index 0000000..60189b3
--- /dev/null
@@ -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 (file)
index 0000000..31949b8
--- /dev/null
@@ -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 (file)
index 0000000..3305ad1
--- /dev/null
@@ -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 (file)
index 0000000..d21829a
--- /dev/null
@@ -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 (file)
index 0000000..33542dd
--- /dev/null
@@ -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 (file)
index 0000000..5876afa
--- /dev/null
@@ -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 (file)
index 0000000..591c3b5
--- /dev/null
@@ -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 (file)
index 0000000..4a81f81
--- /dev/null
@@ -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 (file)
index 0000000..6a6cf34
--- /dev/null
@@ -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 (file)
index 0000000..4d338ac
--- /dev/null
@@ -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 (file)
index 0000000..b8ed355
--- /dev/null
@@ -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 (file)
index 0000000..bede55c
--- /dev/null
@@ -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 (file)
index 0000000..f2f7cba
--- /dev/null
@@ -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 (file)
index 0000000..bdbfdcd
--- /dev/null
@@ -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 (file)
index 0000000..73ba4a3
--- /dev/null
@@ -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 (file)
index 0000000..0a425cd
--- /dev/null
@@ -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 (file)
index 0000000..d5cf3c7
--- /dev/null
@@ -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 (file)
index 0000000..0dfaf0b
--- /dev/null
@@ -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 (file)
index 0000000..735c342
--- /dev/null
@@ -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 (file)
index 0000000..024553a
--- /dev/null
@@ -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 (file)
index 0000000..3bf48db
--- /dev/null
@@ -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 (file)
index 0000000..8888396
--- /dev/null
@@ -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 (file)
index 0000000..f4b8f94
--- /dev/null
@@ -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 (file)
index 0000000..6bdcd5c
--- /dev/null
@@ -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 (file)
index 0000000..f7f83e5
--- /dev/null
@@ -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 (file)
index 0000000..aeea4ef
--- /dev/null
@@ -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 (file)
index 0000000..b0c73be
--- /dev/null
@@ -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 (file)
index 0000000..5e7d53e
--- /dev/null
@@ -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 (file)
index 0000000..740e86d
--- /dev/null
@@ -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 (file)
index 0000000..41726d8
--- /dev/null
@@ -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 (file)
index 0000000..fd7d16d
--- /dev/null
@@ -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 (file)
index 0000000..93ef53b
--- /dev/null
@@ -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 (file)
index 0000000..eaf0466
--- /dev/null
@@ -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 (file)
index 0000000..0279503
--- /dev/null
@@ -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 (file)
index 0000000..00a9580
--- /dev/null
@@ -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 (file)
index 0000000..067fd72
--- /dev/null
@@ -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 (file)
index 0000000..3aed44a
--- /dev/null
@@ -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 (file)
index 0000000..a858c29
--- /dev/null
@@ -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 (file)
index 0000000..5aa0ed5
--- /dev/null
@@ -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 (file)
index 0000000..2da23e4
--- /dev/null
@@ -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 (file)
index 0000000..6c57a79
--- /dev/null
@@ -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 (file)
index 0000000..ae293aa
--- /dev/null
@@ -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 (file)
index 0000000..dd33720
--- /dev/null
@@ -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 (file)
index 0000000..1df6b87
--- /dev/null
@@ -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 (file)
index 0000000..ee75a1e
--- /dev/null
@@ -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 (file)
index 0000000..e31e1e7
--- /dev/null
@@ -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 (file)
index 0000000..ad93592
--- /dev/null
@@ -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 (file)
index 0000000..ccf0e28
--- /dev/null
@@ -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 (file)
index 0000000..dfc26bc
--- /dev/null
@@ -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 (file)
index 0000000..5bad0a2
--- /dev/null
@@ -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 (file)
index 0000000..478fa16
--- /dev/null
@@ -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 (file)
index 0000000..a04f32a
--- /dev/null
@@ -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 (file)
index 0000000..e0c79e8
--- /dev/null
@@ -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 (file)
index 0000000..d3e8606
--- /dev/null
@@ -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 (file)
index 0000000..d9007aa
--- /dev/null
@@ -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 (file)
index 0000000..741884d
--- /dev/null
@@ -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 (file)
index 0000000..07934f8
--- /dev/null
@@ -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 (file)
index 0000000..4a5e39b
--- /dev/null
@@ -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 (file)
index 0000000..4d8727f
--- /dev/null
@@ -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 (file)
index 0000000..7d15ad2
--- /dev/null
@@ -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 (file)
index 0000000..bdd7bf8
--- /dev/null
@@ -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 (file)
index 0000000..5f4e344
--- /dev/null
@@ -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 (file)
index 0000000..bfba93e
--- /dev/null
@@ -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 (file)
index 0000000..1283a52
--- /dev/null
@@ -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 (file)
index 0000000..b0394a9
--- /dev/null
@@ -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 (file)
index 0000000..6a03fa2
--- /dev/null
@@ -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 (file)
index 0000000..6194d2c
--- /dev/null
@@ -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 (file)
index 0000000..86264ae
--- /dev/null
@@ -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 (file)
index 0000000..2f3d110
--- /dev/null
@@ -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 (file)
index 0000000..03a33cf
--- /dev/null
@@ -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 (file)
index 0000000..d448daa
--- /dev/null
@@ -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 (file)
index 0000000..12c3208
--- /dev/null
@@ -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 (file)
index 0000000..526c6a0
--- /dev/null
@@ -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 (file)
index 0000000..34895f5
--- /dev/null
@@ -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 (file)
index 0000000..72e6ce3
--- /dev/null
@@ -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 (file)
index 0000000..e7a7038
--- /dev/null
@@ -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 (file)
index 0000000..1670f01
--- /dev/null
@@ -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 (file)
index 0000000..43fd204
--- /dev/null
@@ -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 (file)
index 0000000..ce59fe7
--- /dev/null
@@ -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 (file)
index 0000000..2c61da1
--- /dev/null
@@ -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 (file)
index 0000000..88d731a
--- /dev/null
@@ -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 (file)
index 0000000..00f4f09
--- /dev/null
@@ -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 (file)
index 0000000..80105ff
--- /dev/null
@@ -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 (file)
index 0000000..ffbce89
--- /dev/null
@@ -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 (file)
index 0000000..be95bd5
--- /dev/null
@@ -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 (file)
index 0000000..3bd40bb
--- /dev/null
@@ -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 (file)
index 0000000..b174850
--- /dev/null
@@ -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 (file)
index 0000000..4a45404
--- /dev/null
@@ -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 (file)
index 0000000..ad641c3
--- /dev/null
@@ -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 (file)
index 0000000..5cf0de1
--- /dev/null
@@ -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 (file)
index 0000000..bfa31ef
--- /dev/null
@@ -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 (file)
index 0000000..f9fb2e9
--- /dev/null
@@ -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 (file)
index 0000000..f047040
--- /dev/null
@@ -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 (file)
index 0000000..9673d9a
--- /dev/null
@@ -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 (file)
index 0000000..3ca6987
--- /dev/null
@@ -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 (file)
index 0000000..232af99
--- /dev/null
@@ -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 (file)
index 0000000..b031a60
--- /dev/null
@@ -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 (file)
index 0000000..efa48bd
--- /dev/null
@@ -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 (file)
index 0000000..229e181
--- /dev/null
@@ -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 (file)
index 0000000..631eec3
--- /dev/null
@@ -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 (file)
index 0000000..fa0d608
--- /dev/null
@@ -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 (file)
index 0000000..eff3e08
--- /dev/null
@@ -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 (file)
index 0000000..bf933e0
--- /dev/null
@@ -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 (file)
index 0000000..a2300df
--- /dev/null
@@ -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 (file)
index 0000000..2954b6e
--- /dev/null
@@ -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 (file)
index 0000000..e9aabbd
--- /dev/null
@@ -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 (file)
index 0000000..9c32614
--- /dev/null
@@ -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 (file)
index 0000000..8ca159b
--- /dev/null
@@ -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 (file)
index 0000000..bd4eb7a
--- /dev/null
@@ -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 (file)
index 0000000..4cf7553
--- /dev/null
@@ -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 (file)
index 0000000..3d308c7
--- /dev/null
@@ -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 (file)
index 0000000..7d897b8
--- /dev/null
@@ -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 (file)
index 0000000..bb5e2fe
--- /dev/null
@@ -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 (file)
index 0000000..952b545
--- /dev/null
@@ -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 (file)
index 0000000..b4dbd66
--- /dev/null
@@ -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 (file)
index 0000000..5e0a482
--- /dev/null
@@ -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 (file)
index 0000000..a25b636
--- /dev/null
@@ -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 (file)
index 0000000..c786aea
--- /dev/null
@@ -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 (file)
index 0000000..a513838
--- /dev/null
@@ -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 (file)
index 0000000..da4b34d
--- /dev/null
@@ -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 (file)
index 0000000..3e3ea5e
--- /dev/null
@@ -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 (file)
index 0000000..bfff699
--- /dev/null
@@ -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 (file)
index 0000000..f89b5b9
--- /dev/null
@@ -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 (file)
index 0000000..7ee3599
--- /dev/null
@@ -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 (file)
index 0000000..5d709c1
--- /dev/null
@@ -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 (file)
index 0000000..7346774
--- /dev/null
@@ -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 (file)
index 0000000..bd0e299
--- /dev/null
@@ -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 (file)
index 0000000..c0b062d
--- /dev/null
@@ -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 (file)
index 0000000..23ea9d3
--- /dev/null
@@ -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 (file)
index 0000000..c5c5a00
--- /dev/null
@@ -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 (file)
index 0000000..247ff8d
--- /dev/null
@@ -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 (file)
index 0000000..276de2b
--- /dev/null
@@ -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 (file)
index 0000000..c49fbd4
--- /dev/null
@@ -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 (file)
index 0000000..f97fd97
--- /dev/null
@@ -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 (file)
index 0000000..86f27d0
--- /dev/null
@@ -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 (file)
index 0000000..fcb6654
--- /dev/null
@@ -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 (file)
index 0000000..bfaabde
--- /dev/null
@@ -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 (file)
index 0000000..111f1e4
--- /dev/null
@@ -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 (file)
index 0000000..b9e8738
--- /dev/null
@@ -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 (file)
index 0000000..ab267cb
--- /dev/null
@@ -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 (file)
index 0000000..45c6750
--- /dev/null
@@ -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 (file)
index 0000000..8e72dec
--- /dev/null
@@ -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 (file)
index 0000000..02a7877
--- /dev/null
@@ -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 (file)
index 0000000..144d5ed
--- /dev/null
@@ -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 (file)
index 0000000..2a168a5
--- /dev/null
@@ -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 (file)
index 0000000..b75cc5f
--- /dev/null
@@ -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 (file)
index 0000000..7633139
--- /dev/null
@@ -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 (file)
index 0000000..4db9062
--- /dev/null
@@ -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 (file)
index 0000000..f5a84c5
--- /dev/null
@@ -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 (file)
index 0000000..8fd8fe1
--- /dev/null
@@ -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 (file)
index 0000000..e85d310
--- /dev/null
@@ -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 (file)
index 0000000..38a478c
--- /dev/null
@@ -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 (file)
index 0000000..6fe021b
--- /dev/null
@@ -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 (file)
index 0000000..ac72468
--- /dev/null
@@ -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 (file)
index 0000000..f470214
--- /dev/null
@@ -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 (file)
index 0000000..0277041
--- /dev/null
@@ -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 (file)
index 0000000..b622119
--- /dev/null
@@ -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 (file)
index 0000000..b890cca
--- /dev/null
@@ -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 (file)
index 0000000..5bedb66
--- /dev/null
@@ -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 (file)
index 0000000..1d80fb2
--- /dev/null
@@ -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 (file)
index 0000000..bebc160
--- /dev/null
@@ -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 (file)
index 0000000..926be98
--- /dev/null
@@ -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 (file)
index 0000000..5d6c3a3
--- /dev/null
@@ -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 (file)
index 0000000..e96e2aa
--- /dev/null
@@ -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 (file)
index 0000000..68ebcd8
--- /dev/null
@@ -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 (file)
index 0000000..ceedf66
--- /dev/null
@@ -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 (file)
index 0000000..78df723
--- /dev/null
@@ -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 (file)
index 0000000..e143cc0
--- /dev/null
@@ -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 (file)
index 0000000..2beb7c1
--- /dev/null
@@ -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 (file)
index 0000000..20122d1
--- /dev/null
@@ -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 (file)
index 0000000..087e989
--- /dev/null
@@ -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 (file)
index 0000000..1efd84b
--- /dev/null
@@ -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 (file)
index 0000000..706e754
--- /dev/null
@@ -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 (file)
index 0000000..fd6df92
--- /dev/null
@@ -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 (file)
index 0000000..e77d963
--- /dev/null
@@ -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 (file)
index 0000000..d7575a7
--- /dev/null
@@ -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 (file)
index 0000000..6e352ef
--- /dev/null
@@ -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 (file)
index 0000000..538b520
--- /dev/null
@@ -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 (file)
index 0000000..363e024
--- /dev/null
@@ -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 (file)
index 0000000..f0b0c0c
--- /dev/null
@@ -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 (file)
index 0000000..5c32e35
--- /dev/null
@@ -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 (file)
index 0000000..a3ed00d
--- /dev/null
@@ -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 (file)
index 0000000..280e584
--- /dev/null
@@ -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 (file)
index 0000000..fdbe3ee
--- /dev/null
@@ -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 (file)
index 0000000..5b642b2
--- /dev/null
@@ -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 (file)
index 0000000..1734a82
--- /dev/null
@@ -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 (file)
index 0000000..6dfd590
--- /dev/null
@@ -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 (file)
index 0000000..46c9d03
--- /dev/null
@@ -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 (file)
index 0000000..d6a0178
--- /dev/null
@@ -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 (file)
index 0000000..f273f9c
--- /dev/null
@@ -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 (file)
index 0000000..3f74548
--- /dev/null
@@ -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 (file)
index 0000000..8ca65cd
--- /dev/null
@@ -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 (file)
index 0000000..0e910d6
--- /dev/null
@@ -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 (file)
index 0000000..cac72b3
--- /dev/null
@@ -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 (file)
index 0000000..599fcb8
--- /dev/null
@@ -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 (file)
index 0000000..a23d143
--- /dev/null
@@ -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 (file)
index 0000000..718cc86
--- /dev/null
@@ -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 (file)
index 0000000..08e48f3
--- /dev/null
@@ -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 (file)
index 0000000..2da1117
--- /dev/null
@@ -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 (file)
index 0000000..f17e99d
--- /dev/null
@@ -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 (file)
index 0000000..7249d1b
--- /dev/null
@@ -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 (file)
index 0000000..3430df9
--- /dev/null
@@ -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 (file)
index 0000000..c6c775e
--- /dev/null
@@ -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 (file)
index 0000000..9703116
--- /dev/null
@@ -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 (file)
index 0000000..6fd3a6d
--- /dev/null
@@ -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 (file)
index 0000000..7d7be24
--- /dev/null
@@ -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 (file)
index 0000000..15cf553
--- /dev/null
@@ -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 (file)
index 0000000..63c8866
--- /dev/null
@@ -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 (file)
index 0000000..7e0bab9
--- /dev/null
@@ -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 (file)
index 0000000..2bb709a
--- /dev/null
@@ -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 (file)
index 0000000..7934c95
--- /dev/null
@@ -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 (file)
index 0000000..6a45629
--- /dev/null
@@ -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 (file)
index 0000000..1478448
--- /dev/null
@@ -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 (file)
index 0000000..e36fabf
--- /dev/null
@@ -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 (file)
index 0000000..803d314
--- /dev/null
@@ -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 (file)
index 0000000..3c4cd7b
--- /dev/null
@@ -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 (file)
index 0000000..851de69
--- /dev/null
@@ -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 (file)
index 0000000..e5d5f71
--- /dev/null
@@ -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 (file)
index 0000000..94e12a6
--- /dev/null
@@ -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 (file)
index 0000000..017e1fe
--- /dev/null
@@ -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 (file)
index 0000000..81de0ef
--- /dev/null
@@ -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 (file)
index 0000000..e1e22e0
--- /dev/null
@@ -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 (file)
index 0000000..a74e6b7
--- /dev/null
@@ -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 (file)
index 0000000..4492d20
--- /dev/null
@@ -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 (file)
index 0000000..a890939
--- /dev/null
@@ -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 (file)
index 0000000..ff115a3
--- /dev/null
@@ -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 (file)
index 0000000..d06ab90
--- /dev/null
@@ -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 (file)
index 0000000..f2ae1e5
--- /dev/null
@@ -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 (file)
index 0000000..225b8b4
--- /dev/null
@@ -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 (file)
index 0000000..f565f33
--- /dev/null
@@ -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 (file)
index 0000000..c017124
--- /dev/null
@@ -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 (file)
index 0000000..229eb64
--- /dev/null
@@ -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 (file)
index 0000000..ba9dfff
--- /dev/null
@@ -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 (file)
index 0000000..1b9ba06
--- /dev/null
@@ -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 (file)
index 0000000..65e1e21
--- /dev/null
@@ -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 (file)
index 0000000..a8b7f2f
--- /dev/null
@@ -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 (file)
index 0000000..6435f1b
--- /dev/null
@@ -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 (file)
index 0000000..9f81d10
--- /dev/null
@@ -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 (file)
index 0000000..f96a517
--- /dev/null
@@ -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 (file)
index 0000000..1788ed2
--- /dev/null
@@ -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 (file)
index 0000000..944c6c8
--- /dev/null
@@ -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 (file)
index 0000000..0ffff79
--- /dev/null
@@ -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 (file)
index 0000000..51a0a3e
--- /dev/null
@@ -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 (file)
index 0000000..d9851e9
--- /dev/null
@@ -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 (file)
index 0000000..0bfec23
--- /dev/null
@@ -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 (file)
index 0000000..53c5c13
--- /dev/null
@@ -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 (file)
index 0000000..96828d2
--- /dev/null
@@ -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 (file)
index 0000000..614fca0
--- /dev/null
@@ -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 (file)
index 0000000..dc86a86
--- /dev/null
@@ -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 (file)
index 0000000..32ebd5f
--- /dev/null
@@ -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 (file)
index 0000000..2b51946
--- /dev/null
@@ -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 (file)
index 0000000..82e6921
--- /dev/null
@@ -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 (file)
index 0000000..4ac882e
--- /dev/null
@@ -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 (file)
index 0000000..fdad49b
--- /dev/null
@@ -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 (file)
index 0000000..ab85344
--- /dev/null
@@ -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 (file)
index 0000000..8525ded
--- /dev/null
@@ -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 (file)
index 0000000..c13caea
--- /dev/null
@@ -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 (file)
index 0000000..c1ded0f
--- /dev/null
@@ -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 (file)
index 0000000..d4ecbd0
--- /dev/null
@@ -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 (file)
index 0000000..bcafd6b
--- /dev/null
@@ -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 (file)
index 0000000..137be59
--- /dev/null
@@ -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 (file)
index 0000000..e299131
--- /dev/null
@@ -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 (file)
index 0000000..fe14ec7
--- /dev/null
@@ -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 (file)
index 0000000..4dbaccd
--- /dev/null
@@ -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 (file)
index 0000000..3849783
--- /dev/null
@@ -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 (file)
index 0000000..8f2af58
--- /dev/null
@@ -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 (file)
index 0000000..f9dbed8
--- /dev/null
@@ -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 (file)
index 0000000..bf45a14
--- /dev/null
@@ -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 (file)
index 0000000..f56d5bb
--- /dev/null
@@ -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 (file)
index 0000000..2088388
--- /dev/null
@@ -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 (file)
index 0000000..7e61cde
--- /dev/null
@@ -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 (file)
index 0000000..fa512eb
--- /dev/null
@@ -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 (file)
index 0000000..635dae1
--- /dev/null
@@ -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 (file)
index 0000000..f192c6d
--- /dev/null
@@ -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 (file)
index 0000000..2485992
--- /dev/null
@@ -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 (file)
index 0000000..aca382a
--- /dev/null
@@ -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 (file)
index 0000000..b7e3cf2
--- /dev/null
@@ -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 (file)
index 0000000..238aaa5
--- /dev/null
@@ -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 (file)
index 0000000..8851baf
--- /dev/null
@@ -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 (file)
index 0000000..97b305d
--- /dev/null
@@ -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 (file)
index 0000000..e453e99
--- /dev/null
@@ -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 (file)
index 0000000..e2e52e7
--- /dev/null
@@ -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 (file)
index 0000000..b3612c8
--- /dev/null
@@ -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 (file)
index 0000000..722043c
--- /dev/null
@@ -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 (file)
index 0000000..c19648c
--- /dev/null
@@ -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 (file)
index 0000000..88b26b3
--- /dev/null
@@ -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 (file)
index 0000000..cabf539
--- /dev/null
@@ -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 (file)
index 0000000..47d5f83
--- /dev/null
@@ -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 (file)
index 0000000..2ec2c63
--- /dev/null
@@ -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 (file)
index 0000000..d4a257c
--- /dev/null
@@ -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 (file)
index 0000000..0e5be63
--- /dev/null
@@ -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 (file)
index 0000000..e1f4fdb
--- /dev/null
@@ -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 (file)
index 0000000..4d736a1
--- /dev/null
@@ -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 (file)
index 0000000..e25cc68
--- /dev/null
@@ -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 (file)
index 0000000..1dd3bd7
--- /dev/null
@@ -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 (file)
index 0000000..9edca4d
--- /dev/null
@@ -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 (file)
index 0000000..04d6319
--- /dev/null
@@ -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 (file)
index 0000000..a5c1812
--- /dev/null
@@ -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 (file)
index 0000000..b5e5c29
--- /dev/null
@@ -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 (file)
index 0000000..3c20ff2
--- /dev/null
@@ -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 (file)
index 0000000..c523430
--- /dev/null
@@ -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 (file)
index 0000000..6186446
--- /dev/null
@@ -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 (file)
index 0000000..d9f03a3
--- /dev/null
@@ -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 (file)
index 0000000..370ddbd
--- /dev/null
@@ -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 (file)
index 0000000..fff3ba1
--- /dev/null
@@ -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 (file)
index 0000000..9c2dcab
--- /dev/null
@@ -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 (file)
index 0000000..7d2aeef
--- /dev/null
@@ -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 (file)
index 0000000..b40ea10
--- /dev/null
@@ -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 (file)
index 0000000..0322df9
--- /dev/null
@@ -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 (file)
index 0000000..99b8260
--- /dev/null
@@ -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 (file)
index 0000000..9aa3c90
--- /dev/null
@@ -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 (file)
index 0000000..a927782
--- /dev/null
@@ -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 (file)
index 0000000..a89b61a
--- /dev/null
@@ -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 (file)
index 0000000..3cc7a9f
--- /dev/null
@@ -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 (file)
index 0000000..861a087
--- /dev/null
@@ -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 (file)
index 0000000..a0b992e
--- /dev/null
@@ -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 (file)
index 0000000..e58710b
--- /dev/null
@@ -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 (file)
index 0000000..fae1c56
--- /dev/null
@@ -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 (file)
index 0000000..9c0a439
--- /dev/null
@@ -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 (file)
index 0000000..88922ef
--- /dev/null
@@ -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 (file)
index 0000000..946aaa6
--- /dev/null
@@ -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 (file)
index 0000000..0c5fcaa
--- /dev/null
@@ -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 (file)
index 0000000..62fb299
--- /dev/null
@@ -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 (file)
index 0000000..e75c4b2
--- /dev/null
@@ -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 (file)
index 0000000..323513f
--- /dev/null
@@ -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 (file)
index 0000000..5c13d57
--- /dev/null
@@ -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 (file)
index 0000000..55d86ea
--- /dev/null
@@ -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 (file)
index 0000000..f9fda3e
--- /dev/null
@@ -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 (file)
index 0000000..88a78d3
--- /dev/null
@@ -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 (file)
index 0000000..f60fac6
--- /dev/null
@@ -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 (file)
index 0000000..9537c56
--- /dev/null
@@ -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 (file)
index 0000000..0f0a248
--- /dev/null
@@ -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 (file)
index 0000000..faf8742
--- /dev/null
@@ -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 (file)
index 0000000..06890d1
--- /dev/null
@@ -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 (file)
index 0000000..cbd4a24
--- /dev/null
@@ -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 (file)
index 0000000..ddead3d
--- /dev/null
@@ -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 (file)
index 0000000..aff8b58
--- /dev/null
@@ -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 (file)
index 0000000..607faa0
--- /dev/null
@@ -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 (file)
index 0000000..5c416b5
--- /dev/null
@@ -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 (file)
index 0000000..32f0c88
--- /dev/null
@@ -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 (file)
index 0000000..b147fff
--- /dev/null
@@ -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 (file)
index 0000000..0bab05e
--- /dev/null
@@ -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 (file)
index 0000000..7f7dca3
--- /dev/null
@@ -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 (file)
index 0000000..a6805de
--- /dev/null
@@ -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 (file)
index 0000000..3e88187
--- /dev/null
@@ -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 (file)
index 0000000..982b31f
--- /dev/null
@@ -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 (file)
index 0000000..241b431
--- /dev/null
@@ -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 (file)
index 0000000..9c2a943
--- /dev/null
@@ -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 (file)
index 0000000..efa1fd3
--- /dev/null
@@ -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 (file)
index 0000000..2036355
--- /dev/null
@@ -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 (file)
index 0000000..076f871
--- /dev/null
@@ -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 (file)
index 0000000..41bc084
--- /dev/null
@@ -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 (file)
index 0000000..e400236
--- /dev/null
@@ -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 (file)
index 0000000..82ca832
--- /dev/null
@@ -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 (file)
index 0000000..746e01f
--- /dev/null
@@ -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 (file)
index 0000000..725ead0
--- /dev/null
@@ -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 (file)
index 0000000..a6dd760
--- /dev/null
@@ -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 (file)
index 0000000..a67f1fe
--- /dev/null
@@ -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 (file)
index 0000000..72a1159
--- /dev/null
@@ -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 (file)
index 0000000..3bf66ae
--- /dev/null
@@ -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 (file)
index 0000000..f77cf5e
--- /dev/null
@@ -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 (file)
index 0000000..03bd411
--- /dev/null
@@ -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 (file)
index 0000000..0930b98
--- /dev/null
@@ -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 (file)
index 0000000..fa50083
--- /dev/null
@@ -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 (file)
index 0000000..f9b42ac
--- /dev/null
@@ -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 (file)
index 0000000..e79d54e
--- /dev/null
@@ -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 (file)
index 0000000..2f58035
--- /dev/null
@@ -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 (file)
index 0000000..bebc13a
--- /dev/null
@@ -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 (file)
index 0000000..80dd40e
--- /dev/null
@@ -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 (file)
index 0000000..90694c6
--- /dev/null
@@ -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 (file)
index 0000000..9c55def
--- /dev/null
@@ -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 (file)
index 0000000..bd59281
--- /dev/null
@@ -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 (file)
index 0000000..49c71b9
--- /dev/null
@@ -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 (file)
index 0000000..50ca2a6
--- /dev/null
@@ -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 (file)
index 0000000..25c5537
--- /dev/null
@@ -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 (file)
index 0000000..1e779fe
--- /dev/null
@@ -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 (file)
index 0000000..fb4e311
--- /dev/null
@@ -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 (file)
index 0000000..50120a4
--- /dev/null
@@ -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 (file)
index 0000000..3de3ac7
--- /dev/null
@@ -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 (file)
index 0000000..0ff439c
--- /dev/null
@@ -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 (file)
index 0000000..01795f4
--- /dev/null
@@ -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 (file)
index 0000000..5b802bd
--- /dev/null
@@ -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 (file)
index 0000000..11e0763
--- /dev/null
@@ -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 (file)
index 0000000..3d46d3f
--- /dev/null
@@ -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 (file)
index 0000000..4a03445
--- /dev/null
@@ -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 (file)
index 0000000..25e8a89
--- /dev/null
@@ -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 (file)
index 0000000..1ac15a8
--- /dev/null
@@ -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 (file)
index 0000000..24ca35b
--- /dev/null
@@ -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 (file)
index 0000000..6ea601f
--- /dev/null
@@ -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 (file)
index 0000000..80e273e
--- /dev/null
@@ -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 (file)
index 0000000..2df84ea
--- /dev/null
@@ -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 (file)
index 0000000..9219f75
--- /dev/null
@@ -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 (file)
index 0000000..0f26c54
--- /dev/null
@@ -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 (file)
index 0000000..09ebbca
--- /dev/null
@@ -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 (file)
index 0000000..c8f41f2
--- /dev/null
@@ -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 (file)
index 0000000..90e9970
--- /dev/null
@@ -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 (file)
index 0000000..b5075f9
--- /dev/null
@@ -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 (file)
index 0000000..dbb2983
--- /dev/null
@@ -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 (file)
index 0000000..b99eb91
--- /dev/null
@@ -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 (file)
index 0000000..d6c9176
--- /dev/null
@@ -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 (file)
index 0000000..09b8691
--- /dev/null
@@ -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 (file)
index 0000000..94cfed0
--- /dev/null
@@ -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 (file)
index 0000000..e920270
--- /dev/null
@@ -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 (file)
index 0000000..2cc85b7
--- /dev/null
@@ -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 (file)
index 0000000..22ec202
--- /dev/null
@@ -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 (file)
index 0000000..2a32c9d
--- /dev/null
@@ -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 (file)
index 0000000..dc00b9c
--- /dev/null
@@ -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 (file)
index 0000000..b7bb3b5
--- /dev/null
@@ -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 (file)
index 0000000..eeff8bd
--- /dev/null
@@ -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 (file)
index 0000000..d97f622
--- /dev/null
@@ -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 (file)
index 0000000..d3e1d1b
--- /dev/null
@@ -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 (file)
index 0000000..7678664
--- /dev/null
@@ -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 (file)
index 0000000..6092c2e
--- /dev/null
@@ -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 (file)
index 0000000..7f40bfa
--- /dev/null
@@ -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 (file)
index 0000000..c170a55
--- /dev/null
@@ -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 (file)
index 0000000..e052a34
--- /dev/null
@@ -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 (file)
index 0000000..8bfdb37
--- /dev/null
@@ -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 (file)
index 0000000..8350429
--- /dev/null
@@ -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 (file)
index 0000000..2855269
--- /dev/null
@@ -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 (file)
index 0000000..b151eac
--- /dev/null
@@ -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 (file)
index 0000000..12f12a7
--- /dev/null
@@ -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 (file)
index 0000000..e53c82e
--- /dev/null
@@ -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 (file)
index 0000000..cfccb97
--- /dev/null
@@ -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 (file)
index 0000000..dd01c44
--- /dev/null
@@ -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 (file)
index 0000000..a168343
--- /dev/null
@@ -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 (file)
index 0000000..acc9c6d
--- /dev/null
@@ -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 (file)
index 0000000..845be67
--- /dev/null
@@ -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 (file)
index 0000000..1cede04
--- /dev/null
@@ -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 (file)
index 0000000..a4e6a93
--- /dev/null
@@ -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 (file)
index 0000000..43b9cb9
--- /dev/null
@@ -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 (file)
index 0000000..bcc1be7
--- /dev/null
@@ -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
+}
diff --git a/Cryptlib/OpenSSL/e_os.h b/Cryptlib/OpenSSL/e_os.h
new file mode 100644 (file)
index 0000000..3e9dae2
--- /dev/null
@@ -0,0 +1,782 @@
+/* e_os.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_E_OS_H
+# define HEADER_E_OS_H
+
+# include <openssl/opensslconf.h>
+
+# include <openssl/e_os2.h>
+/*
+ * <openssl/e_os2.h> contains what we can justify to make visible to the
+ * outside; this file e_os.h is not part of the exported interface.
+ */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+# ifdef REF_PRINT
+#  undef REF_PRINT
+#  define REF_PRINT(a,b)  fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
+# endif
+
+# ifndef DEVRANDOM
+/*
+ * set this to a comma-separated list of 'random' device files to try out. My
+ * default, we will try to read at least one of these files
+ */
+#  define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
+# endif
+# ifndef DEVRANDOM_EGD
+/*
+ * set this to a comma-seperated list of 'egd' sockets to try out. These
+ * sockets will be tried in the order listed in case accessing the device
+ * files listed in DEVRANDOM did not return enough entropy.
+ */
+#  define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
+# endif
+
+# if defined(OPENSSL_SYS_VXWORKS)
+#  define NO_SYS_PARAM_H
+#  define NO_CHMOD
+#  define NO_SYSLOG
+# endif
+
+# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+#  if macintosh==1
+#   ifndef MAC_OS_GUSI_SOURCE
+#    define MAC_OS_pre_X
+#    define NO_SYS_TYPES_H
+#   endif
+#   define NO_SYS_PARAM_H
+#   define NO_CHMOD
+#   define NO_SYSLOG
+#   undef  DEVRANDOM
+#   define GETPID_IS_MEANINGLESS
+#  endif
+# endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+/*
+ * The following is used because of the small stack in some Microsoft
+ * operating systems
+ */
+# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32)
+#  define MS_STATIC     static
+# else
+#  define MS_STATIC
+# endif
+
+# if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
+#  define WIN32
+# endif
+# if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+# endif
+# if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS)
+#  define MSDOS
+# endif
+
+# if (defined(MSDOS) || defined(OPENSSL_SYS_UEFI)) && !defined(GETPID_IS_MEANINGLESS)
+#  define GETPID_IS_MEANINGLESS
+# endif
+
+# ifdef WIN32
+#  define get_last_sys_error()    GetLastError()
+#  define clear_sys_error()       SetLastError(0)
+#  if !defined(WINNT)
+#   define WIN_CONSOLE_BUG
+#  endif
+# else
+#  define get_last_sys_error()    errno
+#  define clear_sys_error()       errno=0
+# endif
+
+# if defined(WINDOWS)
+#  define get_last_socket_error() WSAGetLastError()
+#  define clear_socket_error()    WSASetLastError(0)
+#  define readsocket(s,b,n)       recv((s),(b),(n),0)
+#  define writesocket(s,b,n)      send((s),(b),(n),0)
+# elif defined(__DJGPP__)
+#  define WATT32
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define closesocket(s)          close_s(s)
+#  define readsocket(s,b,n)       read_s(s,b,n)
+#  define writesocket(s,b,n)      send(s,b,n,0)
+# elif defined(MAC_OS_pre_X)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define closesocket(s)          MacSocket_close(s)
+#  define readsocket(s,b,n)       MacSocket_recv((s),(b),(n),true)
+#  define writesocket(s,b,n)      MacSocket_send((s),(b),(n))
+# elif defined(OPENSSL_SYS_VMS)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#  define closesocket(s)          close(s)
+#  define readsocket(s,b,n)       recv((s),(b),(n),0)
+#  define writesocket(s,b,n)      send((s),(b),(n),0)
+# elif defined(OPENSSL_SYS_VXWORKS)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)          ioctl((a),(b),(int)(c))
+#  define closesocket(s)              close(s)
+#  define readsocket(s,b,n)           read((s),(b),(n))
+#  define writesocket(s,b,n)          write((s),(char *)(b),(n))
+# elif defined(OPENSSL_SYS_BEOS_R5)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define FIONBIO SO_NONBLOCK
+#  define ioctlsocket(a,b,c)                setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c)))
+#  define readsocket(s,b,n)       recv((s),(b),(n),0)
+#  define writesocket(s,b,n)      send((s),(b),(n),0)
+# elif defined(OPENSSL_SYS_NETWARE)
+#  if defined(NETWARE_BSDSOCK)
+#   define get_last_socket_error() errno
+#   define clear_socket_error()    errno=0
+#   define closesocket(s)          close(s)
+#   define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#   if defined(NETWARE_LIBC)
+#    define readsocket(s,b,n)       recv((s),(b),(n),0)
+#    define writesocket(s,b,n)      send((s),(b),(n),0)
+#   else
+#    define readsocket(s,b,n)       recv((s),(char*)(b),(n),0)
+#    define writesocket(s,b,n)      send((s),(char*)(b),(n),0)
+#   endif
+#  else
+#   define get_last_socket_error() WSAGetLastError()
+#   define clear_socket_error()    WSASetLastError(0)
+#   define readsocket(s,b,n)               recv((s),(b),(n),0)
+#   define writesocket(s,b,n)              send((s),(b),(n),0)
+#  endif
+# else
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#  define closesocket(s)          close(s)
+#  define readsocket(s,b,n)       read((s),(b),(n))
+#  define writesocket(s,b,n)      write((s),(b),(n))
+# endif
+
+# ifdef WIN16                   /* never the case */
+#  define MS_CALLBACK   _far _loadds
+#  define MS_FAR        _far
+# else
+#  define MS_CALLBACK
+#  define MS_FAR
+# endif
+
+# ifdef OPENSSL_NO_STDIO
+#  undef OPENSSL_NO_FP_API
+#  define OPENSSL_NO_FP_API
+# endif
+
+# if (defined(WINDOWS) || defined(MSDOS))
+
+#  ifdef __DJGPP__
+#   include <unistd.h>
+#   include <sys/stat.h>
+#   include <sys/socket.h>
+#   include <tcp.h>
+#   include <netdb.h>
+#   define _setmode setmode
+#   define _O_TEXT O_TEXT
+#   define _O_BINARY O_BINARY
+#   undef DEVRANDOM
+#   define DEVRANDOM "/dev/urandom\x24"
+#  endif                        /* __DJGPP__ */
+
+#  ifndef S_IFDIR
+#   define S_IFDIR     _S_IFDIR
+#  endif
+
+#  ifndef S_IFMT
+#   define S_IFMT      _S_IFMT
+#  endif
+
+#  if !defined(WINNT) && !defined(__DJGPP__)
+#   define NO_SYSLOG
+#  endif
+#  define NO_DIRENT
+
+#  ifdef WINDOWS
+#   if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT)
+       /*
+        * Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
+        * Most notably we ought to check for availability of each specific
+        * routine with GetProcAddress() and/or guard NT-specific calls with
+        * GetVersion() < 0x80000000. One can argue that in latter "or" case
+        * we ought to /DELAYLOAD some .DLLs in order to protect ourselves
+        * against run-time link errors. This doesn't seem to be necessary,
+        * because it turned out that already Windows 95, first non-NT Win32
+        * implementation, is equipped with at least NT 3.51 stubs, dummy
+        * routines with same name, but which do nothing. Meaning that it's
+        * apparently sufficient to guard "vanilla" NT calls with GetVersion
+        * alone, while NT 4.0 and above interfaces ought to be linked with
+        * GetProcAddress at run-time.
+        */
+#    define _WIN32_WINNT 0x0400
+#   endif
+#   if !defined(OPENSSL_NO_SOCK) && (defined(_WIN32_WINNT) || defined(_WIN32_WCE))
+       /*
+        * Just like defining _WIN32_WINNT including winsock2.h implies
+        * certain "discipline" for maintaining [broad] binary compatibility.
+        * As long as structures are invariant among Winsock versions,
+        * it's sufficient to check for specific Winsock2 API availability
+        * at run-time [DSO_global_lookup is recommended]...
+        */
+#    include <winsock2.h>
+#    include <ws2tcpip.h>
+       /* yes, they have to be #included prior to <windows.h> */
+#   endif
+#   include <windows.h>
+#   include <stdio.h>
+#   include <stddef.h>
+#   include <errno.h>
+#   if defined(_WIN32_WCE) && !defined(EACCES)
+#    define EACCES   13
+#   endif
+#   include <string.h>
+#   ifdef _WIN64
+#    define strlen(s) _strlen31(s)
+/* cut strings to 2GB */
+static __inline unsigned int _strlen31(const char *str)
+{
+    unsigned int len = 0;
+    while (*str && len < 0x80000000U)
+        str++, len++;
+    return len & 0x7FFFFFFF;
+}
+#   endif
+#   include <malloc.h>
+#   if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
+       /* compensate for bug in VC6 ctype.h */
+#    undef isspace
+#    undef isdigit
+#    undef isalnum
+#    undef isupper
+#    undef isxdigit
+#   endif
+#   if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin)
+#    if _MSC_VER>=1300 && _MSC_VER<1600
+#     undef stdin
+#     undef stdout
+#     undef stderr
+FILE *__iob_func();
+#     define stdin  (&__iob_func()[0])
+#     define stdout (&__iob_func()[1])
+#     define stderr (&__iob_func()[2])
+#    elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049)
+#     undef stdin
+#     undef stdout
+#     undef stderr
+         /*
+          * pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
+          * or in other words with /MD. Declaring implicit import, i.e. with
+          * _imp_ prefix, works correctly with all compiler options, but
+          * without /MD results in LINK warning LNK4049: 'locally defined
+          * symbol "__iob" imported'.
+          */
+extern FILE *_imp___iob;
+#     define stdin  (&_imp___iob[0])
+#     define stdout (&_imp___iob[1])
+#     define stderr (&_imp___iob[2])
+#    endif
+#   endif
+#  endif
+#  include <io.h>
+#  include <fcntl.h>
+
+#  ifdef OPENSSL_SYS_WINCE
+#   define OPENSSL_NO_POSIX_IO
+#  endif
+
+#  if defined (__BORLANDC__)
+#   define _setmode setmode
+#   define _O_TEXT O_TEXT
+#   define _O_BINARY O_BINARY
+#   define _int64 __int64
+#   define _kbhit kbhit
+#  endif
+
+#  define EXIT(n) exit(n)
+#  define LIST_SEPARATOR_CHAR ';'
+#  ifndef X_OK
+#   define X_OK        0
+#  endif
+#  ifndef W_OK
+#   define W_OK        2
+#  endif
+#  ifndef R_OK
+#   define R_OK        4
+#  endif
+#  define OPENSSL_CONF  "openssl.cnf"
+#  define SSLEAY_CONF   OPENSSL_CONF
+#  define NUL_DEV       "nul"
+#  define RFILE         ".rnd"
+#  ifdef OPENSSL_SYS_WINCE
+#   define DEFAULT_HOME  ""
+#  else
+#   define DEFAULT_HOME  "C:"
+#  endif
+
+/* Avoid Visual Studio 13 GetVersion deprecated problems */
+#  if defined(_MSC_VER) && _MSC_VER>=1800
+#   define check_winnt() (1)
+#   define check_win_minplat(x) (1)
+#  else
+#   define check_winnt() (GetVersion() < 0x80000000)
+#   define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x))
+#  endif
+
+# else                          /* The non-microsoft world */
+
+#  ifdef OPENSSL_SYS_VMS
+#   define VMS 1
+  /*
+   * some programs don't include stdlib, so exit() and others give implicit
+   * function warnings
+   */
+#   include <stdlib.h>
+#   if defined(__DECC)
+#    include <unistd.h>
+#   else
+#    include <unixlib.h>
+#   endif
+#   define OPENSSL_CONF        "openssl.cnf"
+#   define SSLEAY_CONF         OPENSSL_CONF
+#   define RFILE               ".rnd"
+#   define LIST_SEPARATOR_CHAR ','
+#   define NUL_DEV             "NLA0:"
+  /* We don't have any well-defined random devices on VMS, yet... */
+#   undef DEVRANDOM
+  /*-
+     We need to do this since VMS has the following coding on status codes:
+
+     Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
+               The important thing to know is that odd numbers are considered
+               good, while even ones are considered errors.
+     Bits 3-15: actual status number
+     Bits 16-27: facility number.  0 is considered "unknown"
+     Bits 28-31: control bits.  If bit 28 is set, the shell won't try to
+                 output the message (which, for random codes, just looks ugly)
+
+     So, what we do here is to change 0 to 1 to get the default success status,
+     and everything else is shifted up to fit into the status number field, and
+     the status is tagged as an error, which I believe is what is wanted here.
+     -- Richard Levitte
+  */
+#   define EXIT(n)             do { int __VMS_EXIT = n; \
+                                     if (__VMS_EXIT == 0) \
+                                       __VMS_EXIT = 1; \
+                                     else \
+                                       __VMS_EXIT = (n << 3) | 2; \
+                                     __VMS_EXIT |= 0x10000000; \
+                                     exit(__VMS_EXIT); } while(0)
+#   define NO_SYS_PARAM_H
+
+#  elif defined(OPENSSL_SYS_NETWARE)
+#   include <fcntl.h>
+#   include <unistd.h>
+#   define NO_SYS_TYPES_H
+#   undef  DEVRANDOM
+#   ifdef NETWARE_CLIB
+#    define getpid GetThreadID
+extern int GetThreadID(void);
+/* #      include <conio.h> */
+extern int kbhit(void);
+#   else
+#    include <screen.h>
+#   endif
+#   define NO_SYSLOG
+#   define _setmode setmode
+#   define _kbhit kbhit
+#   define _O_TEXT O_TEXT
+#   define _O_BINARY O_BINARY
+#   define OPENSSL_CONF   "openssl.cnf"
+#   define SSLEAY_CONF    OPENSSL_CONF
+#   define RFILE    ".rnd"
+#   define LIST_SEPARATOR_CHAR ';'
+#   define EXIT(n)  { if (n) printf("ERROR: %d\n", (int)n); exit(n); }
+
+#  else
+     /* !defined VMS */
+#   ifdef OPENSSL_SYS_MPE
+#    define NO_SYS_PARAM_H
+#   endif
+#   ifdef OPENSSL_UNISTD
+#    include OPENSSL_UNISTD
+#   else
+#    include <unistd.h>
+#   endif
+#   ifndef NO_SYS_TYPES_H
+#    include <sys/types.h>
+#   endif
+#   if defined(NeXT) || defined(OPENSSL_SYS_NEWS4)
+#    define pid_t int           /* pid_t is missing on NEXTSTEP/OPENSTEP
+                                 * (unless when compiling with
+                                 * -D_POSIX_SOURCE, which doesn't work for
+                                 * us) */
+#   endif
+#   ifdef OPENSSL_SYS_NEWS4     /* setvbuf is missing on mips-sony-bsd */
+#    define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
+typedef unsigned long clock_t;
+#   endif
+#   ifdef OPENSSL_SYS_WIN32_CYGWIN
+#    include <io.h>
+#    include <fcntl.h>
+#   endif
+
+#   define OPENSSL_CONF        "openssl.cnf"
+#   define SSLEAY_CONF         OPENSSL_CONF
+#   define RFILE               ".rnd"
+#   define LIST_SEPARATOR_CHAR ':'
+#   define NUL_DEV             "/dev/null"
+#   define EXIT(n)             exit(n)
+#  endif
+
+#  define SSLeay_getpid()       getpid()
+
+# endif
+
+/*************/
+
+# if defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_DGRAM)
+#  define OPENSSL_NO_DGRAM
+# endif
+
+# ifdef USE_SOCKETS
+#  if defined(WINDOWS) || defined(MSDOS)
+      /* windows world */
+
+#   ifdef OPENSSL_NO_SOCK
+#    define SSLeay_Write(a,b,c)       (-1)
+#    define SSLeay_Read(a,b,c)        (-1)
+#    define SHUTDOWN(fd)              close(fd)
+#    define SHUTDOWN2(fd)             close(fd)
+#   elif !defined(__DJGPP__)
+#    if defined(_WIN32_WCE) && _WIN32_WCE<410
+#     define getservbyname _masked_declaration_getservbyname
+#    endif
+#    if !defined(IPPROTO_IP)
+         /* winsock[2].h was included already? */
+#     include <winsock.h>
+#    endif
+#    ifdef getservbyname
+#     undef getservbyname
+         /* this is used to be wcecompat/include/winsock_extras.h */
+struct servent *PASCAL getservbyname(const char *, const char *);
+#    endif
+
+#    ifdef _WIN64
+/*
+ * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
+ * the value constitutes an index in per-process table of limited size
+ * and not a real pointer.
+ */
+#     define socket(d,t,p)   ((int)socket(d,t,p))
+#     define accept(s,f,l)   ((int)accept(s,f,l))
+#    endif
+#    define SSLeay_Write(a,b,c)       send((a),(b),(c),0)
+#    define SSLeay_Read(a,b,c)        recv((a),(b),(c),0)
+#    define SHUTDOWN(fd)              { shutdown((fd),0); closesocket(fd); }
+#    define SHUTDOWN2(fd)             { shutdown((fd),2); closesocket(fd); }
+#   else
+#    define SSLeay_Write(a,b,c)       write_s(a,b,c,0)
+#    define SSLeay_Read(a,b,c)        read_s(a,b,c)
+#    define SHUTDOWN(fd)              close_s(fd)
+#    define SHUTDOWN2(fd)             close_s(fd)
+#   endif
+
+#  elif defined(MAC_OS_pre_X)
+
+#   include "MacSocket.h"
+#   define SSLeay_Write(a,b,c)         MacSocket_send((a),(b),(c))
+#   define SSLeay_Read(a,b,c)          MacSocket_recv((a),(b),(c),true)
+#   define SHUTDOWN(fd)                MacSocket_close(fd)
+#   define SHUTDOWN2(fd)               MacSocket_close(fd)
+
+#  elif defined(OPENSSL_SYS_NETWARE)
+         /*
+          * NetWare uses the WinSock2 interfaces by default, but can be
+          * configured for BSD
+          */
+#   if defined(NETWARE_BSDSOCK)
+#    include <sys/socket.h>
+#    include <netinet/in.h>
+#    include <sys/time.h>
+#    if defined(NETWARE_CLIB)
+#     include <sys/bsdskt.h>
+#    else
+#     include <sys/select.h>
+#    endif
+#    define INVALID_SOCKET (int)(~0)
+#   else
+#    include <novsock2.h>
+#   endif
+#   define SSLeay_Write(a,b,c)   send((a),(b),(c),0)
+#   define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
+#   define SHUTDOWN(fd)    { shutdown((fd),0); closesocket(fd); }
+#   define SHUTDOWN2(fd)      { shutdown((fd),2); closesocket(fd); }
+
+#  else
+
+#   ifndef NO_SYS_PARAM_H
+#    include <sys/param.h>
+#   endif
+#   ifdef OPENSSL_SYS_VXWORKS
+#    include <time.h>
+#   elif !defined(OPENSSL_SYS_MPE)
+#    include <sys/time.h>       /* Needed under linux for FD_XXX */
+#   endif
+
+#   include <netdb.h>
+#   if defined(OPENSSL_SYS_VMS_NODECC)
+#    include <socket.h>
+#    include <in.h>
+#    include <inet.h>
+#   else
+#    include <sys/socket.h>
+#    ifdef FILIO_H
+#     include <sys/filio.h>     /* Added for FIONBIO under unixware */
+#    endif
+#    include <netinet/in.h>
+#    if !defined(OPENSSL_SYS_BEOS_R5)
+#     include <arpa/inet.h>
+#    endif
+#   endif
+
+#   if defined(NeXT) || defined(_NEXT_SOURCE)
+#    include <sys/fcntl.h>
+#    include <sys/types.h>
+#   endif
+
+#   ifdef OPENSSL_SYS_AIX
+#    include <sys/select.h>
+#   endif
+
+#   ifdef __QNX__
+#    include <sys/select.h>
+#   endif
+
+#   if defined(__sun) || defined(sun)
+#    include <sys/filio.h>
+#   else
+#    ifndef VMS
+#     include <sys/ioctl.h>
+#    else
+         /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+#     if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+#      include <sys/ioctl.h>
+#     endif
+#    endif
+#   endif
+
+#   ifdef VMS
+#    include <unixio.h>
+#    if defined(TCPIP_TYPE_SOCKETSHR)
+#     include <socketshr.h>
+#    endif
+#   endif
+
+#   define SSLeay_Read(a,b,c)     read((a),(b),(c))
+#   define SSLeay_Write(a,b,c)    write((a),(b),(c))
+#   define SHUTDOWN(fd)    { shutdown((fd),0); closesocket((fd)); }
+#   define SHUTDOWN2(fd)   { shutdown((fd),2); closesocket((fd)); }
+#   ifndef INVALID_SOCKET
+#    define INVALID_SOCKET      (-1)
+#   endif                       /* INVALID_SOCKET */
+#  endif
+
+/*
+ * Some IPv6 implementations are broken, disable them in known bad versions.
+ */
+#  if !defined(OPENSSL_USE_IPV6)
+#   if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB)
+#    define OPENSSL_USE_IPV6 1
+#   else
+#    define OPENSSL_USE_IPV6 0
+#   endif
+#  endif
+
+# endif
+
+# if (defined(__sun) || defined(sun)) && !defined(__svr4__) && !defined(__SVR4)
+  /* include headers first, so our defines don't break it */
+#  include <stdlib.h>
+#  include <string.h>
+  /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */
+#  define memmove(s1,s2,n) bcopy((s2),(s1),(n))
+#  define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b)))
+extern char *sys_errlist[];
+extern int sys_nerr;
+#  define strerror(errnum) \
+        (((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum])
+  /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */
+#  include "crypto/o_str.h"
+#  define memcmp OPENSSL_memcmp
+# endif
+
+# ifndef OPENSSL_EXIT
+#  if defined(MONOLITH) && !defined(OPENSSL_C)
+#   define OPENSSL_EXIT(n) return(n)
+#  else
+#   define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0)
+#  endif
+# endif
+
+/***********************************************/
+
+# define DG_GCC_BUG             /* gcc < 2.6.3 on DGUX */
+
+# ifdef sgi
+#  define IRIX_CC_BUG           /* all version of IRIX I've tested (4.* 5.*) */
+# endif
+# ifdef OPENSSL_SYS_SNI
+#  define IRIX_CC_BUG           /* CDS++ up to V2.0Bsomething suffered from
+                                 * the same bug. */
+# endif
+
+# if defined(OPENSSL_SYS_WINDOWS)
+#  define strcasecmp _stricmp
+#  define strncasecmp _strnicmp
+# elif defined(OPENSSL_SYS_VMS)
+/* VMS below version 7.0 doesn't have strcasecmp() */
+#  include "o_str.h"
+#  define strcasecmp OPENSSL_strcasecmp
+#  define strncasecmp OPENSSL_strncasecmp
+#  define OPENSSL_IMPLEMENTS_strncasecmp
+# elif defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+#  define strcasecmp stricmp
+#  define strncasecmp strnicmp
+# elif defined(OPENSSL_SYS_NETWARE)
+#  include <string.h>
+#  if defined(NETWARE_CLIB)
+#   define strcasecmp stricmp
+#   define strncasecmp strnicmp
+#  endif                        /* NETWARE_CLIB */
+# endif
+
+# if defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+#  include <io.h>
+#  include <fcntl.h>
+#  define NO_SYSLOG
+# endif
+
+/* vxworks */
+# if defined(OPENSSL_SYS_VXWORKS)
+#  include <ioLib.h>
+#  include <tickLib.h>
+#  include <sysLib.h>
+
+#  define TTY_STRUCT int
+
+#  define sleep(a) taskDelay((a) * sysClkRateGet())
+
+#  include <vxWorks.h>
+#  include <sockLib.h>
+#  include <taskLib.h>
+
+#  define getpid taskIdSelf
+
+/*
+ * NOTE: these are implemented by helpers in database app! if the database is
+ * not linked, we need to implement them elswhere
+ */
+struct hostent *gethostbyname(const char *name);
+struct hostent *gethostbyaddr(const char *addr, int length, int type);
+struct servent *getservbyname(const char *name, const char *proto);
+
+# endif
+/* end vxworks */
+
+/* beos */
+# if defined(OPENSSL_SYS_BEOS_R5)
+#  define SO_ERROR 0
+#  define NO_SYS_UN
+#  define IPPROTO_IP 0
+#  include <OS.h>
+# endif
+
+# if !defined(inline) && !defined(__cplusplus)
+#  if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+   /* do nothing, inline works */
+#  elif defined(__GNUC__) && __GNUC__>=2
+#   define inline __inline__
+#  elif defined(_MSC_VER)
+  /*
+   * Visual Studio: inline is available in C++ only, however
+   * __inline is available for C, see
+   * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
+   */
+#   define inline __inline
+#  else
+#   define inline
+#  endif
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/openssl-bio-b_print-disable-sse.patch b/Cryptlib/OpenSSL/openssl-bio-b_print-disable-sse.patch
new file mode 100644 (file)
index 0000000..4a9c76a
--- /dev/null
@@ -0,0 +1,70 @@
+diff --git a/Cryptlib/OpenSSL/crypto/bio/b_print.c b/Cryptlib/OpenSSL/crypto/bio/b_print.c
+index 90248fa..dfc26bc 100644
+--- a/Cryptlib/OpenSSL/crypto/bio/b_print.c
++++ b/Cryptlib/OpenSSL/crypto/bio/b_print.c
+@@ -129,8 +129,10 @@ 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,
+@@ -173,7 +175,9 @@ _dopr(char **sbuffer,
+ {
+     char ch;
+     LLONG value;
++#ifndef OPENSSL_SYS_UEFI
+     LDOUBLE fvalue;
++#endif
+     char *strvalue;
+     int min;
+     int max;
+@@ -276,10 +280,12 @@ _dopr(char **sbuffer,
+                 cflags = DP_C_LLONG;
+                 ch = *format++;
+                 break;
++#ifndef OPENSSL_SYS_UEFI
+             case 'L':
+                 cflags = DP_C_LDOUBLE;
+                 ch = *format++;
+                 break;
++#endif
+             default:
+                 break;
+             }
+@@ -333,6 +339,7 @@ _dopr(char **sbuffer,
+                             min, max, flags))
+                     return 0;
+                 break;
++#ifndef OPENSSL_SYS_UEFI
+             case 'f':
+                 if (cflags == DP_C_LDOUBLE)
+                     fvalue = va_arg(args, LDOUBLE);
+@@ -358,6 +365,7 @@ _dopr(char **sbuffer,
+                 else
+                     fvalue = va_arg(args, double);
+                 break;
++#endif
+             case 'c':
+                 if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                             va_arg(args, int)))
+@@ -575,6 +583,7 @@ fmtint(char **sbuffer,
+     return 1;
+ }
++#ifndef OPENSSL_SYS_UEFI
+ static LDOUBLE abs_val(LDOUBLE value)
+ {
+     LDOUBLE result = value;
+@@ -733,6 +742,7 @@ fmtfp(char **sbuffer,
+     }
+     return 1;
+ }
++#endif
+ #define BUFFER_INC  1024
diff --git a/Cryptlib/OpenSSL/update.sh b/Cryptlib/OpenSSL/update.sh
new file mode 100755 (executable)
index 0000000..88929df
--- /dev/null
@@ -0,0 +1,483 @@
+#/bin/sh
+DIR=$1
+version="1.0.2h"
+
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/e_os.h e_os.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/constant_time_locl.h crypto/constant_time_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md32_common.h crypto/md32_common.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cryptlib.h crypto/cryptlib.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cryptlib.c crypto/cryptlib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/mem.c crypto/mem.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/mem_clr.c crypto/mem_clr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/mem_dbg.c crypto/mem_dbg.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cversion.c crypto/cversion.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ex_data.c crypto/ex_data.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cpt_err.c crypto/cpt_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ebcdic.c crypto/ebcdic.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/uid.c crypto/uid.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_time.h crypto/o_time.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_time.c crypto/o_time.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_str.h crypto/o_str.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_str.c crypto/o_str.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_dir.h crypto/o_dir.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_dir.c crypto/o_dir.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_fips.c crypto/o_fips.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/o_init.c crypto/o_init.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/fips_ers.c crypto/fips_ers.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/LPdir_nyi.c crypto/LPdir_nyi.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md4/md4_locl.h crypto/md4/md4_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md4/md4_dgst.c crypto/md4/md4_dgst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md4/md4_one.c crypto/md4/md4_one.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md5/md5_locl.h crypto/md5/md5_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md5/md5_dgst.c crypto/md5/md5_dgst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/md5/md5_one.c crypto/md5/md5_one.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha_locl.h crypto/sha/sha_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha_dgst.c crypto/sha/sha_dgst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha1dgst.c crypto/sha/sha1dgst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha_one.c crypto/sha/sha_one.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha1_one.c crypto/sha/sha1_one.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha256.c crypto/sha/sha256.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/sha/sha512.c crypto/sha/sha512.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/hmac/hmac.c crypto/hmac/hmac.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/hmac/hm_ameth.c crypto/hmac/hm_ameth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/hmac/hm_pmeth.c crypto/hmac/hm_pmeth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/des_locl.h crypto/des/des_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/des_ver.h crypto/des/des_ver.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/spr.h crypto/des/spr.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/rpc_des.h crypto/des/rpc_des.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/set_key.c crypto/des/set_key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ecb_enc.c crypto/des/ecb_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/cbc_enc.c crypto/des/cbc_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ncbc_enc.c crypto/des/ncbc_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ecb3_enc.c crypto/des/ecb3_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/cfb64enc.c crypto/des/cfb64enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/cfb64ede.c crypto/des/cfb64ede.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/cfb_enc.c crypto/des/cfb_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ofb64ede.c crypto/des/ofb64ede.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/enc_read.c crypto/des/enc_read.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/enc_writ.c crypto/des/enc_writ.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ofb64enc.c crypto/des/ofb64enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ofb_enc.c crypto/des/ofb_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/str2key.c crypto/des/str2key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/pcbc_enc.c crypto/des/pcbc_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/qud_cksm.c crypto/des/qud_cksm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/rand_key.c crypto/des/rand_key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/des_enc.c crypto/des/des_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/fcrypt_b.c crypto/des/fcrypt_b.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/fcrypt.c crypto/des/fcrypt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/xcbc_enc.c crypto/des/xcbc_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/rpc_enc.c crypto/des/rpc_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/cbc_cksm.c crypto/des/cbc_cksm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/ede_cbcm_enc.c crypto/des/ede_cbcm_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/des_old.c crypto/des/des_old.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/des_old2.c crypto/des/des_old2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/des/read2pwd.c crypto/des/read2pwd.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rc4/rc4_locl.h crypto/rc4/rc4_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rc4/rc4_enc.c crypto/rc4/rc4_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rc4/rc4_skey.c crypto/rc4/rc4_skey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rc4/rc4_utl.c crypto/rc4/rc4_utl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_locl.h crypto/aes/aes_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_misc.c crypto/aes/aes_misc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_ecb.c crypto/aes/aes_ecb.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_cfb.c crypto/aes/aes_cfb.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_ofb.c crypto/aes/aes_ofb.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_ctr.c crypto/aes/aes_ctr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_ige.c crypto/aes/aes_ige.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_wrap.c crypto/aes/aes_wrap.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_core.c crypto/aes/aes_core.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/aes/aes_cbc.c crypto/aes/aes_cbc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/modes_lcl.h crypto/modes/modes_lcl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/cbc128.c crypto/modes/cbc128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/ctr128.c crypto/modes/ctr128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/cts128.c crypto/modes/cts128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/cfb128.c crypto/modes/cfb128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/ofb128.c crypto/modes/ofb128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/gcm128.c crypto/modes/gcm128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/ccm128.c crypto/modes/ccm128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/xts128.c crypto/modes/xts128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/modes/wrap128.c crypto/modes/wrap128.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn.h crypto/bn/bn.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_lcl.h crypto/bn/bn_lcl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_prime.h crypto/bn/bn_prime.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_add.c crypto/bn/bn_add.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_div.c crypto/bn/bn_div.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_exp.c crypto/bn/bn_exp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_lib.c crypto/bn/bn_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_ctx.c crypto/bn/bn_ctx.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_mul.c crypto/bn/bn_mul.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_mod.c crypto/bn/bn_mod.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_print.c crypto/bn/bn_print.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_rand.c crypto/bn/bn_rand.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_shift.c crypto/bn/bn_shift.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_word.c crypto/bn/bn_word.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_blind.c crypto/bn/bn_blind.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_kron.c crypto/bn/bn_kron.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_sqrt.c crypto/bn/bn_sqrt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_gcd.c crypto/bn/bn_gcd.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_prime.c crypto/bn/bn_prime.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_err.c crypto/bn/bn_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_sqr.c crypto/bn/bn_sqr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_asm.c crypto/bn/bn_asm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_recp.c crypto/bn/bn_recp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_mont.c crypto/bn/bn_mont.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_mpi.c crypto/bn/bn_mpi.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_exp2.c crypto/bn/bn_exp2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_gf2m.c crypto/bn/bn_gf2m.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_nist.c crypto/bn/bn_nist.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_depr.c crypto/bn/bn_depr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_x931p.c crypto/bn/bn_x931p.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/bn_const.c crypto/bn/bn_const.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bn/rsaz_exp.h crypto/bn/rsaz_exp.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_locl.h crypto/rsa/rsa_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_eay.c crypto/rsa/rsa_eay.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_gen.c crypto/rsa/rsa_gen.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_lib.c crypto/rsa/rsa_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_sign.c crypto/rsa/rsa_sign.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_saos.c crypto/rsa/rsa_saos.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_err.c crypto/rsa/rsa_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_pk1.c crypto/rsa/rsa_pk1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_ssl.c crypto/rsa/rsa_ssl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_none.c crypto/rsa/rsa_none.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_oaep.c crypto/rsa/rsa_oaep.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_chk.c crypto/rsa/rsa_chk.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_null.c crypto/rsa/rsa_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_pss.c crypto/rsa/rsa_pss.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_x931.c crypto/rsa/rsa_x931.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_asn1.c crypto/rsa/rsa_asn1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_depr.c crypto/rsa/rsa_depr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_ameth.c crypto/rsa/rsa_ameth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_prn.c crypto/rsa/rsa_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_pmeth.c crypto/rsa/rsa_pmeth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rsa/rsa_crpt.c crypto/rsa/rsa_crpt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_dl.c crypto/dso/dso_dl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_dlfcn.c crypto/dso/dso_dlfcn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_err.c crypto/dso/dso_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_lib.c crypto/dso/dso_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_null.c crypto/dso/dso_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_openssl.c crypto/dso/dso_openssl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_win32.c crypto/dso/dso_win32.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_vms.c crypto/dso/dso_vms.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dso/dso_beos.c crypto/dso/dso_beos.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_asn1.c crypto/dh/dh_asn1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_gen.c crypto/dh/dh_gen.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_key.c crypto/dh/dh_key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_lib.c crypto/dh/dh_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_check.c crypto/dh/dh_check.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_err.c crypto/dh/dh_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_depr.c crypto/dh/dh_depr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_ameth.c crypto/dh/dh_ameth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_pmeth.c crypto/dh/dh_pmeth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_prn.c crypto/dh/dh_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/dh/dh_rfc5114.c crypto/dh/dh_rfc5114.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/buffer/buffer.c crypto/buffer/buffer.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/buffer/buf_str.c crypto/buffer/buf_str.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/buffer/buf_err.c crypto/buffer/buf_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bio_lcl.h crypto/bio/bio_lcl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bio_lib.c crypto/bio/bio_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bio_cb.c crypto/bio/bio_cb.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bio_err.c crypto/bio/bio_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_mem.c crypto/bio/bss_mem.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_null.c crypto/bio/bss_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_fd.c crypto/bio/bss_fd.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_file.c crypto/bio/bss_file.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_sock.c crypto/bio/bss_sock.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_conn.c crypto/bio/bss_conn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bf_null.c crypto/bio/bf_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bf_buff.c crypto/bio/bf_buff.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/b_dump.c crypto/bio/b_dump.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/b_print.c crypto/bio/b_print.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/b_sock.c crypto/bio/b_sock.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_acpt.c crypto/bio/bss_acpt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bf_nbio.c crypto/bio/bf_nbio.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_log.c crypto/bio/bss_log.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_bio.c crypto/bio/bss_bio.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/bio/bss_dgram.c crypto/bio/bss_dgram.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/stack/stack.c crypto/stack/stack.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/lhash/lhash.c crypto/lhash/lhash.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/lhash/lh_stats.c crypto/lhash/lh_stats.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/rand_lcl.h crypto/rand/rand_lcl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/md_rand.c crypto/rand/md_rand.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/randfile.c crypto/rand/randfile.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/rand_lib.c crypto/rand/rand_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/rand_err.c crypto/rand/rand_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/rand/rand_unix.c crypto/rand/rand_unix.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/err/err.c crypto/err/err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/err/err_all.c crypto/err/err_all.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/err/err_prn.c crypto/err/err_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/o_names.c crypto/objects/o_names.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_dat.h crypto/objects/obj_dat.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_dat.c crypto/objects/obj_dat.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_lib.c crypto/objects/obj_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_err.c crypto/objects/obj_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_xref.h crypto/objects/obj_xref.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/objects/obj_xref.c crypto/objects/obj_xref.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_locl.h crypto/evp/evp_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/encode.c crypto/evp/encode.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/digest.c crypto/evp/digest.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_enc.c crypto/evp/evp_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_key.c crypto/evp/evp_key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_acnf.c crypto/evp/evp_acnf.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_cnf.c crypto/evp/evp_cnf.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_des.c crypto/evp/e_des.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_bf.c crypto/evp/e_bf.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_idea.c crypto/evp/e_idea.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_des3.c crypto/evp/e_des3.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_camellia.c crypto/evp/e_camellia.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_rc4.c crypto/evp/e_rc4.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_aes.c crypto/evp/e_aes.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/names.c crypto/evp/names.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_seed.c crypto/evp/e_seed.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_xcbc_d.c crypto/evp/e_xcbc_d.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_rc2.c crypto/evp/e_rc2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_cast.c crypto/evp/e_cast.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_rc5.c crypto/evp/e_rc5.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_null.c crypto/evp/m_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_md2.c crypto/evp/m_md2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_md4.c crypto/evp/m_md4.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_md5.c crypto/evp/m_md5.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_sha.c crypto/evp/m_sha.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_sha1.c crypto/evp/m_sha1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_wp.c crypto/evp/m_wp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_dss.c crypto/evp/m_dss.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_dss1.c crypto/evp/m_dss1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_mdc2.c crypto/evp/m_mdc2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_ripemd.c crypto/evp/m_ripemd.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_ecdsa.c crypto/evp/m_ecdsa.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_open.c crypto/evp/p_open.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_seal.c crypto/evp/p_seal.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_sign.c crypto/evp/p_sign.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_verify.c crypto/evp/p_verify.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_lib.c crypto/evp/p_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_enc.c crypto/evp/p_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p_dec.c crypto/evp/p_dec.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/bio_md.c crypto/evp/bio_md.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/bio_b64.c crypto/evp/bio_b64.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/bio_enc.c crypto/evp/bio_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_err.c crypto/evp/evp_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_null.c crypto/evp/e_null.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/c_all.c crypto/evp/c_all.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/c_allc.c crypto/evp/c_allc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/c_alld.c crypto/evp/c_alld.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_lib.c crypto/evp/evp_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/bio_ok.c crypto/evp/bio_ok.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_pkey.c crypto/evp/evp_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/evp_pbe.c crypto/evp/evp_pbe.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p5_crpt.c crypto/evp/p5_crpt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/p5_crpt2.c crypto/evp/p5_crpt2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_old.c crypto/evp/e_old.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/pmeth_lib.c crypto/evp/pmeth_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/pmeth_fn.c crypto/evp/pmeth_fn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/pmeth_gn.c crypto/evp/pmeth_gn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/m_sigver.c crypto/evp/m_sigver.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_aes_cbc_hmac_sha1.c crypto/evp/e_aes_cbc_hmac_sha1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_aes_cbc_hmac_sha256.c crypto/evp/e_aes_cbc_hmac_sha256.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/evp/e_rc4_hmac_md5.c crypto/evp/e_rc4_hmac_md5.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn1_locl.h crypto/asn1/asn1_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/charmap.h crypto/asn1/charmap.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_object.c crypto/asn1/a_object.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_bitstr.c crypto/asn1/a_bitstr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_utctm.c crypto/asn1/a_utctm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_gentm.c crypto/asn1/a_gentm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_time.c crypto/asn1/a_time.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_int.c crypto/asn1/a_int.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_octet.c crypto/asn1/a_octet.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_print.c crypto/asn1/a_print.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_type.c crypto/asn1/a_type.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_set.c crypto/asn1/a_set.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_dup.c crypto/asn1/a_dup.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_d2i_fp.c crypto/asn1/a_d2i_fp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_i2d_fp.c crypto/asn1/a_i2d_fp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_enum.c crypto/asn1/a_enum.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_utf8.c crypto/asn1/a_utf8.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_sign.c crypto/asn1/a_sign.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_digest.c crypto/asn1/a_digest.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_verify.c crypto/asn1/a_verify.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_mbstr.c crypto/asn1/a_mbstr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_strex.c crypto/asn1/a_strex.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_algor.c crypto/asn1/x_algor.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_val.c crypto/asn1/x_val.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_pubkey.c crypto/asn1/x_pubkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_sig.c crypto/asn1/x_sig.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_req.c crypto/asn1/x_req.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_attrib.c crypto/asn1/x_attrib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_bignum.c crypto/asn1/x_bignum.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_long.c crypto/asn1/x_long.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_name.c crypto/asn1/x_name.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_x509.c crypto/asn1/x_x509.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_x509a.c crypto/asn1/x_x509a.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_crl.c crypto/asn1/x_crl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_info.c crypto/asn1/x_info.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_spki.c crypto/asn1/x_spki.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/nsseq.c crypto/asn1/nsseq.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_nx509.c crypto/asn1/x_nx509.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/d2i_pu.c crypto/asn1/d2i_pu.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/d2i_pr.c crypto/asn1/d2i_pr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/i2d_pu.c crypto/asn1/i2d_pu.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/i2d_pr.c crypto/asn1/i2d_pr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_req.c crypto/asn1/t_req.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_x509.c crypto/asn1/t_x509.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_x509a.c crypto/asn1/t_x509a.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_crl.c crypto/asn1/t_crl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_pkey.c crypto/asn1/t_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_spki.c crypto/asn1/t_spki.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/t_bitst.c crypto/asn1/t_bitst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_new.c crypto/asn1/tasn_new.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_fre.c crypto/asn1/tasn_fre.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_enc.c crypto/asn1/tasn_enc.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_dec.c crypto/asn1/tasn_dec.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_utl.c crypto/asn1/tasn_utl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_typ.c crypto/asn1/tasn_typ.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/tasn_prn.c crypto/asn1/tasn_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/ameth_lib.c crypto/asn1/ameth_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/f_int.c crypto/asn1/f_int.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/f_string.c crypto/asn1/f_string.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/n_pkey.c crypto/asn1/n_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/f_enum.c crypto/asn1/f_enum.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_pkey.c crypto/asn1/x_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_bool.c crypto/asn1/a_bool.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/x_exten.c crypto/asn1/x_exten.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/bio_asn1.c crypto/asn1/bio_asn1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/bio_ndef.c crypto/asn1/bio_ndef.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn_mime.c crypto/asn1/asn_mime.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn1_gen.c crypto/asn1/asn1_gen.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn1_par.c crypto/asn1/asn1_par.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn1_lib.c crypto/asn1/asn1_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn1_err.c crypto/asn1/asn1_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_bytes.c crypto/asn1/a_bytes.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/a_strnid.c crypto/asn1/a_strnid.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/evp_asn1.c crypto/asn1/evp_asn1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn_pack.c crypto/asn1/asn_pack.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/p5_pbe.c crypto/asn1/p5_pbe.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/p5_pbev2.c crypto/asn1/p5_pbev2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/p8_pkey.c crypto/asn1/p8_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/asn1/asn_moid.c crypto/asn1/asn_moid.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_sign.c crypto/pem/pem_sign.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_seal.c crypto/pem/pem_seal.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_info.c crypto/pem/pem_info.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_lib.c crypto/pem/pem_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_all.c crypto/pem/pem_all.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_err.c crypto/pem/pem_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_x509.c crypto/pem/pem_x509.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_xaux.c crypto/pem/pem_xaux.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_oth.c crypto/pem/pem_oth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_pk8.c crypto/pem/pem_pk8.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pem_pkey.c crypto/pem/pem_pkey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pem/pvkfmt.c crypto/pem/pvkfmt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/vpm_int.h crypto/x509/vpm_int.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_def.c crypto/x509/x509_def.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_d2.c crypto/x509/x509_d2.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_r2x.c crypto/x509/x509_r2x.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_cmp.c crypto/x509/x509_cmp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_obj.c crypto/x509/x509_obj.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_req.c crypto/x509/x509_req.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509spki.c crypto/x509/x509spki.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_vfy.c crypto/x509/x509_vfy.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_set.c crypto/x509/x509_set.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509cset.c crypto/x509/x509cset.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509rset.c crypto/x509/x509rset.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_err.c crypto/x509/x509_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509name.c crypto/x509/x509name.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_v3.c crypto/x509/x509_v3.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_ext.c crypto/x509/x509_ext.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_att.c crypto/x509/x509_att.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509type.c crypto/x509/x509type.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_lu.c crypto/x509/x509_lu.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x_all.c crypto/x509/x_all.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_txt.c crypto/x509/x509_txt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_trs.c crypto/x509/x509_trs.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509/x509_vpm.c crypto/x509/x509_vpm.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/ext_dat.h crypto/x509v3/ext_dat.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_int.h crypto/x509v3/pcy_int.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_bcons.c crypto/x509v3/v3_bcons.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_bitst.c crypto/x509v3/v3_bitst.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_conf.c crypto/x509v3/v3_conf.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_extku.c crypto/x509v3/v3_extku.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_ia5.c crypto/x509v3/v3_ia5.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_lib.c crypto/x509v3/v3_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_prn.c crypto/x509v3/v3_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_utl.c crypto/x509v3/v3_utl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3err.c crypto/x509v3/v3err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_genn.c crypto/x509v3/v3_genn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_alt.c crypto/x509v3/v3_alt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_skey.c crypto/x509v3/v3_skey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_akey.c crypto/x509v3/v3_akey.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_pku.c crypto/x509v3/v3_pku.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_int.c crypto/x509v3/v3_int.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_enum.c crypto/x509v3/v3_enum.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_sxnet.c crypto/x509v3/v3_sxnet.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_cpols.c crypto/x509v3/v3_cpols.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_crld.c crypto/x509v3/v3_crld.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_purp.c crypto/x509v3/v3_purp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_info.c crypto/x509v3/v3_info.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_ocsp.c crypto/x509v3/v3_ocsp.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_akeya.c crypto/x509v3/v3_akeya.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_pmaps.c crypto/x509v3/v3_pmaps.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_pcons.c crypto/x509v3/v3_pcons.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_ncons.c crypto/x509v3/v3_ncons.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_pcia.c crypto/x509v3/v3_pcia.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_pci.c crypto/x509v3/v3_pci.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_cache.c crypto/x509v3/pcy_cache.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_node.c crypto/x509v3/pcy_node.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_data.c crypto/x509v3/pcy_data.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_map.c crypto/x509v3/pcy_map.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_tree.c crypto/x509v3/pcy_tree.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/pcy_lib.c crypto/x509v3/pcy_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_asid.c crypto/x509v3/v3_asid.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/x509v3/v3_addr.c crypto/x509v3/v3_addr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_err.c crypto/conf/conf_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_lib.c crypto/conf/conf_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_api.c crypto/conf/conf_api.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_def.h crypto/conf/conf_def.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_def.c crypto/conf/conf_def.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_mod.c crypto/conf/conf_mod.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_mall.c crypto/conf/conf_mall.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/conf/conf_sap.c crypto/conf/conf_sap.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/txt_db/txt_db.c crypto/txt_db/txt_db.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_asn1.c crypto/pkcs7/pk7_asn1.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_lib.c crypto/pkcs7/pk7_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pkcs7err.c crypto/pkcs7/pkcs7err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_doit.c crypto/pkcs7/pk7_doit.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_smime.c crypto/pkcs7/pk7_smime.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_attr.c crypto/pkcs7/pk7_attr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/pk7_mime.c crypto/pkcs7/pk7_mime.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs7/bio_pk7.c crypto/pkcs7/bio_pk7.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_add.c crypto/pkcs12/p12_add.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_asn.c crypto/pkcs12/p12_asn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_attr.c crypto/pkcs12/p12_attr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_crpt.c crypto/pkcs12/p12_crpt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_crt.c crypto/pkcs12/p12_crt.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_decr.c crypto/pkcs12/p12_decr.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_init.c crypto/pkcs12/p12_init.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_key.c crypto/pkcs12/p12_key.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_kiss.c crypto/pkcs12/p12_kiss.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_mutl.c crypto/pkcs12/p12_mutl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_utl.c crypto/pkcs12/p12_utl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_npas.c crypto/pkcs12/p12_npas.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/pk12err.c crypto/pkcs12/pk12err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_p8d.c crypto/pkcs12/p12_p8d.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/pkcs12/p12_p8e.c crypto/pkcs12/p12_p8e.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/comp/comp_lib.c crypto/comp/comp_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/comp/comp_err.c crypto/comp/comp_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/comp/c_rle.c crypto/comp/c_rle.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/comp/c_zlib.c crypto/comp/c_zlib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_asn.c crypto/ocsp/ocsp_asn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_ext.c crypto/ocsp/ocsp_ext.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_ht.c crypto/ocsp/ocsp_ht.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_lib.c crypto/ocsp/ocsp_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_cl.c crypto/ocsp/ocsp_cl.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_srv.c crypto/ocsp/ocsp_srv.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_prn.c crypto/ocsp/ocsp_prn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_vfy.c crypto/ocsp/ocsp_vfy.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ocsp/ocsp_err.c crypto/ocsp/ocsp_err.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ui/ui_locl.h crypto/ui/ui_locl.h
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ui/ui_lib.c crypto/ui/ui_lib.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ui/ui_util.c crypto/ui/ui_util.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/ui/ui_compat.c crypto/ui/ui_compat.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/krb5/krb5_asn.c crypto/krb5/krb5_asn.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cmac/cmac.c crypto/cmac/cmac.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cmac/cm_ameth.c crypto/cmac/cm_ameth.c
+install -D $DIR/CryptoPkg/Library/OpensslLib/openssl-$version/crypto/cmac/cm_pmeth.c crypto/cmac/cm_pmeth.c
+
+find . -name "*.[ch]" -exec chmod -x {} \;
+
+patch -p3 < openssl-bio-b_print-disable-sse.patch
diff --git a/Cryptlib/Pem/CryptPem.c b/Cryptlib/Pem/CryptPem.c
new file mode 100644 (file)
index 0000000..51e648b
--- /dev/null
@@ -0,0 +1,135 @@
+/** @file\r
+  PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/pem.h>\r
+\r
+/**\r
+  Callback function for password phrase conversion used for retrieving the encrypted PEM.\r
+\r
+  @param[out]  Buf      Pointer to the buffer to write the passphrase to.\r
+  @param[in]   Size     Maximum length of the passphrase (i.e. the size of Buf).\r
+  @param[in]   Flag     A flag which is set to 0 when reading and 1 when writing.\r
+  @param[in]   Key      Key data to be passed to the callback routine.\r
+\r
+  @retval  The number of characters in the passphrase or 0 if an error occurred.\r
+\r
+**/\r
+INTN\r
+PasswordCallback (\r
+  OUT  CHAR8  *Buf, \r
+  IN   INTN   Size, \r
+  IN   INTN   Flag, \r
+  IN   VOID   *Key\r
+  )\r
+{\r
+  INTN  KeyLength;\r
+\r
+  ZeroMem ((VOID *) Buf, (UINTN) Size);\r
+  if (Key != NULL) {\r
+    //\r
+    // Duplicate key phrase directly.\r
+    //\r
+    KeyLength = (INTN) AsciiStrLen ((CHAR8 *)Key);\r
+    KeyLength = (KeyLength > Size ) ? Size : KeyLength;\r
+    CopyMem (Buf, Key, (UINTN) KeyLength);\r
+    return KeyLength;\r
+  } else {\r
+    return 0;\r
+  }\r
+}\r
+\r
+/**\r
+  Retrieve the RSA Private Key from the password-protected PEM key data.\r
+\r
+  @param[in]  PemData      Pointer to the PEM-encoded key data to be retrieved.\r
+  @param[in]  PemSize      Size of the PEM key data in bytes.\r
+  @param[in]  Password     NULL-terminated passphrase used for encrypted PEM key data.\r
+  @param[out] RsaContext   Pointer to new-generated RSA context which contain the retrieved\r
+                           RSA private key component. Use RsaFree() function to free the\r
+                           resource.\r
+\r
+  If PemData is NULL, then return FALSE.\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @retval  TRUE   RSA Private Key was retrieved successfully.\r
+  @retval  FALSE  Invalid PEM key data or incorrect password.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetPrivateKeyFromPem (\r
+  IN   CONST UINT8  *PemData,\r
+  IN   UINTN        PemSize,\r
+  IN   CONST CHAR8  *Password,\r
+  OUT  VOID         **RsaContext\r
+  )\r
+{\r
+  BOOLEAN  Status;\r
+  BIO      *PemBio;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (PemData == NULL || RsaContext == NULL || PemSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Add possible block-cipher descriptor for PEM data decryption.\r
+  // NOTE: Only support most popular ciphers (3DES, AES) for the encrypted PEM.\r
+  //\r
+  if (EVP_add_cipher (EVP_des_ede3_cbc ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Read encrypted PEM Data.\r
+  //\r
+  PemBio = BIO_new (BIO_s_mem ());\r
+  if (PemBio == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  if (BIO_write (PemBio, PemData, (int) PemSize) <= 0) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Retrieve RSA Private Key from encrypted PEM data.\r
+  //\r
+  *RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *) &PasswordCallback, (void *) Password);\r
+  if (*RsaContext != NULL) {\r
+    Status = TRUE;\r
+  }\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources.\r
+  //\r
+  BIO_free (PemBio);\r
+\r
+  return Status;\r
+}\r
diff --git a/Cryptlib/Pk/CryptAuthenticode.c b/Cryptlib/Pk/CryptAuthenticode.c
new file mode 100644 (file)
index 0000000..857281d
--- /dev/null
@@ -0,0 +1,198 @@
+/** @file\r
+  Authenticode Portable Executable Signature Verification over OpenSSL.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This library will have external input - signature (e.g. PE/COFF Authenticode).\r
+  This external input must be validated carefully to avoid security issue like\r
+  buffer overflow, integer overflow.\r
+\r
+  AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for\r
+  data structure.\r
+\r
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+#include <openssl/objects.h>\r
+#include <openssl/x509.h>\r
+#include <openssl/pkcs7.h>\r
+\r
+//\r
+// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID\r
+//\r
+UINT8 mSpcIndirectOidValue[] = {\r
+  0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04\r
+  };\r
+\r
+/**\r
+  Verifies the validility of a PE/COFF Authenticode Signature as described in "Windows\r
+  Authenticode Portable Executable Signature Format".\r
+\r
+  If AuthData is NULL, then return FALSE.\r
+  If ImageHash is NULL, then return FALSE.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  PE/COFF Authenticode is external input, so this function will do basic check for\r
+  Authenticode data structure.\r
+\r
+  @param[in]  AuthData     Pointer to the Authenticode Signature retrieved from signed\r
+                           PE/COFF image to be verified.\r
+  @param[in]  DataSize     Size of the Authenticode Signature in bytes.\r
+  @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which\r
+                           is used for certificate chain verification.\r
+  @param[in]  CertSize     Size of the trusted certificate in bytes.\r
+  @param[in]  ImageHash    Pointer to the original image file hash value. The procudure\r
+                           for calculating the image hash value is described in Authenticode\r
+                           specification.\r
+  @param[in]  HashSize     Size of Image hash value in bytes.\r
+\r
+  @retval  TRUE   The specified Authenticode Signature is valid.\r
+  @retval  FALSE  Invalid Authenticode Signature.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AuthenticodeVerify (\r
+  IN  CONST UINT8  *AuthData,\r
+  IN  UINTN        DataSize,\r
+  IN  CONST UINT8  *TrustedCert,\r
+  IN  UINTN        CertSize,\r
+  IN  CONST UINT8  *ImageHash,\r
+  IN  UINTN        HashSize\r
+  )\r
+{\r
+  BOOLEAN      Status;\r
+  PKCS7        *Pkcs7;\r
+  CONST UINT8  *Temp;\r
+  CONST UINT8  *OrigAuthData;\r
+  UINT8        *SpcIndirectDataContent;\r
+  UINT8        Asn1Byte;\r
+  UINTN        ContentSize;\r
+  CONST UINT8  *SpcIndirectDataOid;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if ((AuthData == NULL) || (TrustedCert == NULL) || (ImageHash == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((DataSize > INT_MAX) || (CertSize > INT_MAX) || (HashSize > INT_MAX)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status       = FALSE;\r
+  Pkcs7        = NULL;\r
+  OrigAuthData = AuthData;\r
+\r
+  //\r
+  // Retrieve & Parse PKCS#7 Data (DER encoding) from Authenticode Signature\r
+  //\r
+  Temp  = AuthData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, &Temp, (int)DataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // NOTE: OpenSSL PKCS7 Decoder didn't work for Authenticode-format signed data due to\r
+  //       some authenticode-specific structure. Use opaque ASN.1 string to retrieve\r
+  //       PKCS#7 ContentInfo here.\r
+  //\r
+  SpcIndirectDataOid = OBJ_get0_data(Pkcs7->d.sign->contents->type);\r
+  if (OBJ_length(Pkcs7->d.sign->contents->type) != sizeof(mSpcIndirectOidValue) ||\r
+      CompareMem (\r
+        SpcIndirectDataOid,\r
+        mSpcIndirectOidValue,\r
+        sizeof (mSpcIndirectOidValue)\r
+        ) != 0) {\r
+    //\r
+    // Un-matched SPC_INDIRECT_DATA_OBJID.\r
+    //\r
+    goto _Exit;\r
+  }\r
+\r
+\r
+  SpcIndirectDataContent = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data);\r
+\r
+  //\r
+  // Retrieve the SEQUENCE data size from ASN.1-encoded SpcIndirectDataContent.\r
+  //\r
+  Asn1Byte = *(SpcIndirectDataContent + 1);\r
+\r
+  if ((Asn1Byte & 0x80) == 0) {\r
+    //\r
+    // Short Form of Length Encoding (Length < 128)\r
+    //\r
+    ContentSize = (UINTN) (Asn1Byte & 0x7F);\r
+    //\r
+    // Skip the SEQUENCE Tag;\r
+    //\r
+    SpcIndirectDataContent += 2;\r
+\r
+  } else if ((Asn1Byte & 0x81) == 0x81) {\r
+    //\r
+    // Long Form of Length Encoding (128 <= Length < 255, Single Octet)\r
+    //\r
+    ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));\r
+    //\r
+    // Skip the SEQUENCE Tag;\r
+    //\r
+    SpcIndirectDataContent += 3;\r
+\r
+  } else if ((Asn1Byte & 0x82) == 0x82) {\r
+    //\r
+    // Long Form of Length Encoding (Length > 255, Two Octet)\r
+    //\r
+    ContentSize = (UINTN) (*(UINT8 *)(SpcIndirectDataContent + 2));\r
+    ContentSize = (ContentSize << 8) + (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 3));\r
+    //\r
+    // Skip the SEQUENCE Tag;\r
+    //\r
+    SpcIndirectDataContent += 4;\r
+\r
+  } else {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Compare the original file hash value to the digest retrieve from SpcIndirectDataContent\r
+  // defined in Authenticode\r
+  // NOTE: Need to double-check HashLength here!\r
+  //\r
+  if (CompareMem (SpcIndirectDataContent + ContentSize - HashSize, ImageHash, HashSize) != 0) {\r
+    //\r
+    // Un-matched PE/COFF Hash Value\r
+    //\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Verifies the PKCS#7 Signed Data in PE/COFF Authenticode Signature\r
+  //\r
+  Status = (BOOLEAN) Pkcs7Verify (OrigAuthData, DataSize, TrustedCert, CertSize, SpcIndirectDataContent, ContentSize);\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  PKCS7_free (Pkcs7);\r
+\r
+  return Status;\r
+}\r
diff --git a/Cryptlib/Pk/CryptDhNull.c b/Cryptlib/Pk/CryptDhNull.c
new file mode 100644 (file)
index 0000000..35045db
--- /dev/null
@@ -0,0 +1,156 @@
+/** @file\r
+  Diffie-Hellman Wrapper Implementation which does not provide\r
+  real capabilities.\r
+\r
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+/**\r
+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
+\r
+  @return  Pointer to the Diffie-Hellman Context that has been initialized.\r
+           If the interface is not supported, DhNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DhNew (\r
+  VOID\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Release the specified DH context.\r
+\r
+  If the interface is not supported, then ASSERT().\r
+\r
+  @param[in]  DhContext  Pointer to the DH context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DhFree (\r
+  IN  VOID  *DhContext\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+  Generates DH parameter.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateParameter (\r
+  IN OUT  VOID   *DhContext,\r
+  IN      UINTN  Generator,\r
+  IN      UINTN  PrimeLength,\r
+  OUT     UINT8  *Prime\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Sets generator and prime parameters for DH.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[in]       Prime        Pointer to the prime number.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhSetParameter (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      UINTN        Generator,\r
+  IN      UINTN        PrimeLength,\r
+  IN      CONST UINT8  *Prime\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE; \r
+}\r
+\r
+/**\r
+  Generates DH public key.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  DhContext      Pointer to the DH context.\r
+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.\r
+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.\r
+                                  On output, the size of data returned in PublicKey buffer in bytes.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateKey (\r
+  IN OUT  VOID   *DhContext,\r
+  OUT     UINT8  *PublicKey,\r
+  IN OUT  UINTN  *PublicKeySize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Computes exchanged common key.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  DhContext          Pointer to the DH context.\r
+  @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.\r
+  @param[out]      Key                Pointer to the buffer to receive generated key.\r
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.\r
+                                      On output, the size of data returned in Key buffer in bytes.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhComputeKey (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      CONST UINT8  *PeerPublicKey,\r
+  IN      UINTN        PeerPublicKeySize,\r
+  OUT     UINT8        *Key,\r
+  IN OUT  UINTN        *KeySize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
diff --git a/Cryptlib/Pk/CryptPkcs7SignNull.c b/Cryptlib/Pk/CryptPkcs7SignNull.c
new file mode 100644 (file)
index 0000000..539bb6b
--- /dev/null
@@ -0,0 +1,59 @@
+/** @file\r
+  PKCS#7 SignedData Sign Wrapper Implementation which does not provide real\r
+  capabilities.\r
+\r
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+/**\r
+  Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message\r
+  Syntax Standard, version 1.5". This interface is only intended to be used for\r
+  application to perform PKCS#7 functionality validation.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in]  PrivateKey       Pointer to the PEM-formatted private key data for\r
+                               data signing.\r
+  @param[in]  PrivateKeySize   Size of the PEM private key data in bytes.\r
+  @param[in]  KeyPassword      NULL-terminated passphrase used for encrypted PEM\r
+                               key data.\r
+  @param[in]  InData           Pointer to the content to be signed.\r
+  @param[in]  InDataSize       Size of InData in bytes.\r
+  @param[in]  SignCert         Pointer to signer's DER-encoded certificate to sign with.\r
+  @param[in]  OtherCerts       Pointer to an optional additional set of certificates to\r
+                               include in the PKCS#7 signedData (e.g. any intermediate\r
+                               CAs in the chain).\r
+  @param[out] SignedData       Pointer to output PKCS#7 signedData.\r
+  @param[out] SignedDataSize   Size of SignedData in bytes.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7Sign (\r
+  IN   CONST UINT8  *PrivateKey,\r
+  IN   UINTN        PrivateKeySize,\r
+  IN   CONST UINT8  *KeyPassword,\r
+  IN   UINT8        *InData,\r
+  IN   UINTN        InDataSize,\r
+  IN   UINT8        *SignCert,\r
+  IN   UINT8        *OtherCerts      OPTIONAL,\r
+  OUT  UINT8        **SignedData,\r
+  OUT  UINTN        *SignedDataSize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c
new file mode 100644 (file)
index 0000000..efa3796
--- /dev/null
@@ -0,0 +1,1004 @@
+/** @file\r
+  PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This library will have external input - signature (e.g. UEFI Authenticated\r
+  Variable). It may by input in SMM mode.\r
+  This external input must be validated carefully to avoid security issue like\r
+  buffer overflow, integer overflow.\r
+\r
+  WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated\r
+  Variable and will do basic check for data structure.\r
+\r
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+#include <openssl/objects.h>\r
+#include <openssl/x509.h>\r
+#include <openssl/x509v3.h>\r
+#include <openssl/pkcs7.h>\r
+\r
+UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };\r
+\r
+/**\r
+  Check input P7Data is a wrapped ContentInfo structure or not. If not construct\r
+  a new structure to wrap P7Data.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  UEFI Authenticated Variable is external input, so this function will do basic\r
+  check for PKCS#7 data structure.\r
+\r
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[out] WrapFlag     If TRUE P7Data is a ContentInfo structure, otherwise\r
+                           return FALSE.\r
+  @param[out] WrapData     If return status of this function is TRUE:\r
+                           1) when WrapFlag is TRUE, pointer to P7Data.\r
+                           2) when WrapFlag is FALSE, pointer to a new ContentInfo\r
+                           structure. It's caller's responsibility to free this\r
+                           buffer.\r
+  @param[out] WrapDataSize Length of ContentInfo structure in bytes.\r
+\r
+  @retval     TRUE         The operation is finished successfully.\r
+  @retval     FALSE        The operation is failed due to lack of resources.\r
+\r
+**/\r
+BOOLEAN\r
+WrapPkcs7Data (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT BOOLEAN      *WrapFlag,\r
+  OUT UINT8        **WrapData,\r
+  OUT UINTN        *WrapDataSize\r
+  )\r
+{\r
+  BOOLEAN          Wrapped;\r
+  UINT8            *SignedData;\r
+\r
+  //\r
+  // Check whether input P7Data is a wrapped ContentInfo structure or not.\r
+  //\r
+  Wrapped = FALSE;\r
+  if ((P7Data[4] == 0x06) && (P7Data[5] == 0x09)) {\r
+    if (CompareMem (P7Data + 6, mOidValue, sizeof (mOidValue)) == 0) {\r
+      if ((P7Data[15] == 0xA0) && (P7Data[16] == 0x82)) {\r
+        Wrapped = TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (Wrapped) {\r
+    *WrapData     = (UINT8 *) P7Data;\r
+    *WrapDataSize = P7Length;\r
+  } else {\r
+    //\r
+    // Wrap PKCS#7 signeddata to a ContentInfo structure - add a header in 19 bytes.\r
+    //\r
+    *WrapDataSize = P7Length + 19;\r
+    *WrapData     = malloc (*WrapDataSize);\r
+    if (*WrapData == NULL) {\r
+      *WrapFlag = Wrapped;\r
+      return FALSE;\r
+    }\r
+\r
+    SignedData = *WrapData;\r
+\r
+    //\r
+    // Part1: 0x30, 0x82.\r
+    //\r
+    SignedData[0] = 0x30;\r
+    SignedData[1] = 0x82;\r
+\r
+    //\r
+    // Part2: Length1 = P7Length + 19 - 4, in big endian.\r
+    //\r
+    SignedData[2] = (UINT8) (((UINT16) (*WrapDataSize - 4)) >> 8);\r
+    SignedData[3] = (UINT8) (((UINT16) (*WrapDataSize - 4)) & 0xff);\r
+\r
+    //\r
+    // Part3: 0x06, 0x09.\r
+    //\r
+    SignedData[4] = 0x06;\r
+    SignedData[5] = 0x09;\r
+\r
+    //\r
+    // Part4: OID value -- 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x07 0x02.\r
+    //\r
+    CopyMem (SignedData + 6, mOidValue, sizeof (mOidValue));\r
+\r
+    //\r
+    // Part5: 0xA0, 0x82.\r
+    //\r
+    SignedData[15] = 0xA0;\r
+    SignedData[16] = 0x82;\r
+\r
+    //\r
+    // Part6: Length2 = P7Length, in big endian.\r
+    //\r
+    SignedData[17] = (UINT8) (((UINT16) P7Length) >> 8);\r
+    SignedData[18] = (UINT8) (((UINT16) P7Length) & 0xff);\r
+\r
+    //\r
+    // Part7: P7Data.\r
+    //\r
+    CopyMem (SignedData + 19, P7Data, P7Length);\r
+  }\r
+\r
+  *WrapFlag = Wrapped;\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Pop single certificate from STACK_OF(X509).\r
+\r
+  If X509Stack, Cert, or CertSize is NULL, then return FALSE.\r
+\r
+  @param[in]  X509Stack       Pointer to a X509 stack object.\r
+  @param[out] Cert            Pointer to a X509 certificate.\r
+  @param[out] CertSize        Length of output X509 certificate in bytes.\r
+\r
+  @retval     TRUE            The X509 stack pop succeeded.\r
+  @retval     FALSE           The pop operation failed.\r
+\r
+**/\r
+BOOLEAN\r
+X509PopCertificate (\r
+  IN  VOID  *X509Stack,\r
+  OUT UINT8 **Cert,\r
+  OUT UINTN *CertSize\r
+  )\r
+{\r
+  BIO             *CertBio;\r
+  X509            *X509Cert;\r
+  STACK_OF(X509)  *CertStack;\r
+  BOOLEAN         Status;\r
+  INT32           Result;\r
+  INT32           Length;\r
+  VOID            *Buffer;\r
+\r
+  Status = FALSE;\r
+\r
+  if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) {\r
+    return Status;\r
+  }\r
+\r
+  CertStack = (STACK_OF(X509) *) X509Stack;\r
+\r
+  X509Cert = sk_X509_pop (CertStack);\r
+\r
+  if (X509Cert == NULL) {\r
+    return Status;\r
+  }\r
+\r
+  Buffer = NULL;\r
+\r
+  CertBio = BIO_new (BIO_s_mem ());\r
+  if (CertBio == NULL) {\r
+    return Status;\r
+  }\r
+\r
+  Result = i2d_X509_bio (CertBio, X509Cert);\r
+  if (Result == 0) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Length = (INT32)(((BUF_MEM *) CertBio->ptr)->length);\r
+  if (Length <= 0) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Buffer = malloc (Length);\r
+  if (Buffer == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Result = BIO_read (CertBio, Buffer, Length);\r
+  if (Result != Length) {\r
+    goto _Exit;\r
+  }\r
+\r
+  *Cert     = Buffer;\r
+  *CertSize = Length;\r
+\r
+  Status = TRUE;\r
+\r
+_Exit:\r
+\r
+  BIO_free (CertBio);\r
+\r
+  if (!Status && (Buffer != NULL)) {\r
+    free (Buffer);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:\r
+  Cryptographic Message Syntax Standard". The input signed data could be wrapped\r
+  in a ContentInfo structure.\r
+\r
+  If P7Data, CertStack, StackLength, TrustedCert or CertLength is NULL, then\r
+  return FALSE. If P7Length overflow, then return FAlSE.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  UEFI Authenticated Variable is external input, so this function will do basic\r
+  check for PKCS#7 data structure.\r
+\r
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[out] CertStack    Pointer to Signer's certificates retrieved from P7Data.\r
+                           It's caller's responsiblity to free the buffer.\r
+  @param[out] StackLength  Length of signer's certificates in bytes.\r
+  @param[out] TrustedCert  Pointer to a trusted certificate from Signer's certificates.\r
+                           It's caller's responsiblity to free the buffer.\r
+  @param[out] CertLength   Length of the trusted certificate in bytes.\r
+\r
+  @retval  TRUE            The operation is finished successfully.\r
+  @retval  FALSE           Error occurs during the operation.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetSigners (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT UINT8        **CertStack,\r
+  OUT UINTN        *StackLength,\r
+  OUT UINT8        **TrustedCert,\r
+  OUT UINTN        *CertLength\r
+  )\r
+{\r
+  PKCS7            *Pkcs7;\r
+  BOOLEAN          Status;\r
+  UINT8            *SignedData;\r
+  CONST UINT8      *Temp;\r
+  UINTN            SignedDataSize;\r
+  BOOLEAN          Wrapped;\r
+  STACK_OF(X509)   *Stack;\r
+  UINT8            Index;\r
+  UINT8            *CertBuf;\r
+  UINT8            *OldBuf;\r
+  UINTN            BufferSize;\r
+  UINTN            OldSize;\r
+  UINT8            *SingleCert;\r
+  UINTN            SingleCertSize;\r
+\r
+  if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||\r
+      (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);\r
+  if (!Status) {\r
+    return Status;\r
+  }\r
+\r
+  Status     = FALSE;\r
+  Pkcs7      = NULL;\r
+  Stack      = NULL;\r
+  CertBuf    = NULL;\r
+  OldBuf     = NULL;\r
+  SingleCert = NULL;\r
+\r
+  //\r
+  // Retrieve PKCS#7 Data (DER encoding)\r
+  //\r
+  if (SignedDataSize > INT_MAX) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Temp = SignedData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) SignedDataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Stack = PKCS7_get0_signers(Pkcs7, NULL, PKCS7_BINARY);\r
+  if (Stack == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Convert CertStack to buffer in following format:\r
+  // UINT8  CertNumber;\r
+  // UINT32 Cert1Length;\r
+  // UINT8  Cert1[];\r
+  // UINT32 Cert2Length;\r
+  // UINT8  Cert2[];\r
+  // ...\r
+  // UINT32 CertnLength;\r
+  // UINT8  Certn[];\r
+  //\r
+  BufferSize = sizeof (UINT8);\r
+  OldSize    = BufferSize;\r
+\r
+  for (Index = 0; ; Index++) {\r
+    Status = X509PopCertificate (Stack, &SingleCert, &SingleCertSize);\r
+    if (!Status) {\r
+      break;\r
+    }\r
+\r
+    OldSize    = BufferSize;\r
+    OldBuf     = CertBuf;\r
+    BufferSize = OldSize + SingleCertSize + sizeof (UINT32);\r
+    CertBuf    = malloc (BufferSize);\r
+\r
+    if (CertBuf == NULL) {\r
+      goto _Exit;\r
+    }\r
+\r
+    if (OldBuf != NULL) {\r
+      CopyMem (CertBuf, OldBuf, OldSize);\r
+      free (OldBuf);\r
+      OldBuf = NULL;\r
+    }\r
+\r
+    WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) SingleCertSize);\r
+    CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);\r
+\r
+    free (SingleCert);\r
+    SingleCert = NULL;\r
+  }\r
+\r
+  if (CertBuf != NULL) {\r
+    //\r
+    // Update CertNumber.\r
+    //\r
+    CertBuf[0] = Index;\r
+\r
+    *CertLength = BufferSize - OldSize - sizeof (UINT32);\r
+    *TrustedCert = malloc (*CertLength);\r
+    if (*TrustedCert == NULL) {\r
+      goto _Exit;\r
+    }\r
+\r
+    CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);\r
+    *CertStack   = CertBuf;\r
+    *StackLength = BufferSize;\r
+    Status = TRUE;\r
+  }\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  if (!Wrapped) {\r
+    free (SignedData);\r
+  }\r
+\r
+  if (Pkcs7 != NULL) {\r
+    PKCS7_free (Pkcs7);\r
+  }\r
+\r
+  if (Stack != NULL) {\r
+    sk_X509_pop_free(Stack, X509_free);\r
+  }\r
+\r
+  if (SingleCert !=  NULL) {\r
+    free (SingleCert);\r
+  }\r
+\r
+  if (!Status && (CertBuf != NULL)) {\r
+    free (CertBuf);\r
+    *CertStack = NULL;\r
+  }\r
+\r
+  if (OldBuf != NULL) {\r
+    free (OldBuf);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Wrap function to use free() to free allocated memory for certificates.\r
+\r
+  @param[in]  Certs        Pointer to the certificates to be freed.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Pkcs7FreeSigners (\r
+  IN  UINT8        *Certs\r
+  )\r
+{\r
+  if (Certs == NULL) {\r
+    return;\r
+  }\r
+\r
+  free (Certs);\r
+}\r
+\r
+/**\r
+  Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:\r
+  Cryptographic Message Syntax Standard", and outputs two certificate lists chained and\r
+  unchained to the signer's certificates.\r
+  The input signed data could be wrapped in a ContentInfo structure.\r
+\r
+  @param[in]  P7Data            Pointer to the PKCS#7 message.\r
+  @param[in]  P7Length          Length of the PKCS#7 message in bytes.\r
+  @param[out] SignerChainCerts  Pointer to the certificates list chained to signer's\r
+                                certificate. It's caller's responsiblity to free the buffer.\r
+  @param[out] ChainLength       Length of the chained certificates list buffer in bytes.\r
+  @param[out] UnchainCerts      Pointer to the unchained certificates lists. It's caller's\r
+                                responsiblity to free the buffer.\r
+  @param[out] UnchainLength     Length of the unchained certificates list buffer in bytes.\r
+\r
+  @retval  TRUE         The operation is finished successfully.\r
+  @retval  FALSE        Error occurs during the operation.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetCertificatesList (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT UINT8        **SignerChainCerts,\r
+  OUT UINTN        *ChainLength,\r
+  OUT UINT8        **UnchainCerts,\r
+  OUT UINTN        *UnchainLength\r
+  )\r
+{\r
+  BOOLEAN          Status;\r
+  UINT8            *NewP7Data;\r
+  UINTN            NewP7Length;\r
+  BOOLEAN          Wrapped;\r
+  UINT8            Index;\r
+  PKCS7            *Pkcs7;\r
+  X509_STORE_CTX   CertCtx;\r
+  STACK_OF(X509)   *Signers;\r
+  X509             *Signer;\r
+  X509             *Cert;\r
+  X509             *TempCert;\r
+  X509             *Issuer;\r
+  UINT8            *CertBuf;\r
+  UINT8            *OldBuf;\r
+  UINTN            BufferSize;\r
+  UINTN            OldSize;\r
+  UINT8            *SingleCert;\r
+  UINTN            CertSize;\r
+\r
+  //\r
+  // Initializations\r
+  //\r
+  Status         = FALSE;\r
+  NewP7Data      = NULL;\r
+  Pkcs7          = NULL;\r
+  Cert           = NULL;\r
+  TempCert       = NULL;\r
+  SingleCert     = NULL;\r
+  CertBuf        = NULL;\r
+  OldBuf         = NULL;\r
+  Signers        = NULL;\r
+\r
+  ZeroMem (&CertCtx, sizeof (CertCtx));\r
+\r
+  //\r
+  // Parameter Checking\r
+  //\r
+  if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||\r
+      (UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX)) {\r
+    return Status;\r
+  }\r
+\r
+  *SignerChainCerts = NULL;\r
+  *ChainLength      = 0;\r
+  *UnchainCerts     = NULL;\r
+  *UnchainLength    = 0;\r
+\r
+  //\r
+  // Construct a new PKCS#7 data wrapping with ContentInfo structure if needed.\r
+  //\r
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &NewP7Data, &NewP7Length);\r
+  if (!Status || (NewP7Length > INT_MAX)) {\r
+    goto _Error;\r
+  }\r
+\r
+  //\r
+  // Decodes PKCS#7 SignedData\r
+  //\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &NewP7Data, (int) NewP7Length);\r
+  if ((Pkcs7 == NULL) || (!PKCS7_type_is_signed (Pkcs7))) {\r
+    goto _Error;\r
+  }\r
+\r
+  //\r
+  // Obtains Signer's Certificate from PKCS#7 data\r
+  // NOTE: Only one signer case will be handled in this function, which means SignerInfos\r
+  //       should include only one signer's certificate.\r
+  //\r
+  Signers = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);\r
+  if ((Signers == NULL) || (sk_X509_num (Signers) != 1)) {\r
+    goto _Error;\r
+  }\r
+  Signer = sk_X509_value (Signers, 0);\r
+\r
+  if (!X509_STORE_CTX_init (&CertCtx, NULL, Signer, Pkcs7->d.sign->cert)) {\r
+    goto _Error;\r
+  }\r
+  //\r
+  // Initialize Chained & Untrusted stack\r
+  //\r
+  if (CertCtx.chain == NULL) {\r
+    if (((CertCtx.chain = sk_X509_new_null ()) == NULL) ||\r
+        (!sk_X509_push (CertCtx.chain, CertCtx.cert))) {\r
+      goto _Error;\r
+    }\r
+  }\r
+  (VOID)sk_X509_delete_ptr (CertCtx.untrusted, Signer);\r
+\r
+  //\r
+  // Build certificates stack chained from Signer's certificate.\r
+  //\r
+  Cert = Signer;\r
+  for (; ;) {\r
+    //\r
+    // Self-Issue checking\r
+    //\r
+    if (CertCtx.check_issued (&CertCtx, Cert, Cert)) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Found the issuer of the current certificate\r
+    //\r
+    if (CertCtx.untrusted != NULL) {\r
+      Issuer = NULL;\r
+      for (Index = 0; Index < sk_X509_num (CertCtx.untrusted); Index++) {\r
+        TempCert = sk_X509_value (CertCtx.untrusted, Index);\r
+        if (CertCtx.check_issued (&CertCtx, Cert, TempCert)) {\r
+          Issuer = TempCert;\r
+          break;\r
+        }\r
+      }\r
+      if (Issuer != NULL) {\r
+        if (!sk_X509_push (CertCtx.chain, Issuer)) {\r
+          goto _Error;\r
+        }\r
+        (VOID)sk_X509_delete_ptr (CertCtx.untrusted, Issuer);\r
+\r
+        Cert = Issuer;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    break;\r
+  }\r
+\r
+  //\r
+  // Converts Chained and Untrusted Certificate to Certificate Buffer in following format:\r
+  //      UINT8  CertNumber;\r
+  //      UINT32 Cert1Length;\r
+  //      UINT8  Cert1[];\r
+  //      UINT32 Cert2Length;\r
+  //      UINT8  Cert2[];\r
+  //      ...\r
+  //      UINT32 CertnLength;\r
+  //      UINT8  Certn[];\r
+  //\r
+\r
+  if (CertCtx.chain != NULL) {\r
+    BufferSize = sizeof (UINT8);\r
+    OldSize    = BufferSize;\r
+    CertBuf    = NULL;\r
+\r
+    for (Index = 0; ; Index++) {\r
+      Status = X509PopCertificate (CertCtx.chain, &SingleCert, &CertSize);\r
+      if (!Status) {\r
+        break;\r
+      }\r
+\r
+      OldSize    = BufferSize;\r
+      OldBuf     = CertBuf;\r
+      BufferSize = OldSize + CertSize + sizeof (UINT32);\r
+      CertBuf    = malloc (BufferSize);\r
+\r
+      if (CertBuf == NULL) {\r
+        Status = FALSE;\r
+        goto _Error;\r
+      }\r
+      if (OldBuf != NULL) {\r
+        CopyMem (CertBuf, OldBuf, OldSize);\r
+        free (OldBuf);\r
+        OldBuf = NULL;\r
+      }\r
+\r
+      WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) CertSize);\r
+      CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);\r
+\r
+      free (SingleCert);\r
+      SingleCert = NULL;\r
+    }\r
+\r
+    if (CertBuf != NULL) {\r
+      //\r
+      // Update CertNumber.\r
+      //\r
+      CertBuf[0] = Index;\r
+\r
+      *SignerChainCerts = CertBuf;\r
+      *ChainLength      = BufferSize;\r
+    }\r
+  }\r
+\r
+  if (CertCtx.untrusted != NULL) {\r
+    BufferSize = sizeof (UINT8);\r
+    OldSize    = BufferSize;\r
+    CertBuf    = NULL;\r
+\r
+    for (Index = 0; ; Index++) {\r
+      Status = X509PopCertificate (CertCtx.untrusted, &SingleCert, &CertSize);\r
+      if (!Status) {\r
+        break;\r
+      }\r
+\r
+      OldSize    = BufferSize;\r
+      OldBuf     = CertBuf;\r
+      BufferSize = OldSize + CertSize + sizeof (UINT32);\r
+      CertBuf    = malloc (BufferSize);\r
+\r
+      if (CertBuf == NULL) {\r
+        Status = FALSE;\r
+        goto _Error;\r
+      }\r
+      if (OldBuf != NULL) {\r
+        CopyMem (CertBuf, OldBuf, OldSize);\r
+        free (OldBuf);\r
+        OldBuf = NULL;\r
+      }\r
+\r
+      WriteUnaligned32 ((UINT32 *) (CertBuf + OldSize), (UINT32) CertSize);\r
+      CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);\r
+\r
+      free (SingleCert);\r
+      SingleCert = NULL;\r
+    }\r
+\r
+    if (CertBuf != NULL) {\r
+      //\r
+      // Update CertNumber.\r
+      //\r
+      CertBuf[0] = Index;\r
+\r
+      *UnchainCerts  = CertBuf;\r
+      *UnchainLength = BufferSize;\r
+    }\r
+  }\r
+\r
+  Status = TRUE;\r
+\r
+_Error:\r
+  //\r
+  // Release Resources.\r
+  //\r
+  if (!Wrapped && (NewP7Data != NULL)) {\r
+    free (NewP7Data);\r
+  }\r
+\r
+  if (Pkcs7 != NULL) {\r
+    PKCS7_free (Pkcs7);\r
+  }\r
+  sk_X509_free (Signers);\r
+\r
+  X509_STORE_CTX_cleanup (&CertCtx);\r
+\r
+  if (SingleCert != NULL) {\r
+    free (SingleCert);\r
+  }\r
+\r
+  if (OldBuf != NULL) {\r
+    free (OldBuf);\r
+  }\r
+\r
+  if (!Status && (CertBuf != NULL)) {\r
+    free (CertBuf);\r
+    *SignerChainCerts = NULL;\r
+    *UnchainCerts     = NULL;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Verifies the validility of a PKCS#7 signed data as described in "PKCS #7:\r
+  Cryptographic Message Syntax Standard". The input signed data could be wrapped\r
+  in a ContentInfo structure.\r
+\r
+  If P7Data, TrustedCert or InData is NULL, then return FALSE.\r
+  If P7Length, CertLength or DataLength overflow, then return FAlSE.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  UEFI Authenticated Variable is external input, so this function will do basic\r
+  check for PKCS#7 data structure.\r
+\r
+  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
+  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which\r
+                           is used for certificate chain verification.\r
+  @param[in]  CertLength   Length of the trusted certificate in bytes.\r
+  @param[in]  InData       Pointer to the content to be verified.\r
+  @param[in]  DataLength   Length of InData in bytes.\r
+\r
+  @retval  TRUE  The specified PKCS#7 signed data is valid.\r
+  @retval  FALSE Invalid PKCS#7 signed data.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7Verify (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  IN  CONST UINT8  *TrustedCert,\r
+  IN  UINTN        CertLength,\r
+  IN  CONST UINT8  *InData,\r
+  IN  UINTN        DataLength\r
+  )\r
+{\r
+  PKCS7       *Pkcs7;\r
+  BIO         *DataBio;\r
+  BOOLEAN     Status;\r
+  X509        *Cert;\r
+  X509_STORE  *CertStore;\r
+  UINT8       *SignedData;\r
+  CONST UINT8 *Temp;\r
+  UINTN       SignedDataSize;\r
+  BOOLEAN     Wrapped;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (P7Data == NULL || TrustedCert == NULL || InData == NULL ||\r
+    P7Length > INT_MAX || CertLength > INT_MAX || DataLength > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  Pkcs7     = NULL;\r
+  DataBio   = NULL;\r
+  Cert      = NULL;\r
+  CertStore = NULL;\r
+\r
+  //\r
+  // Register & Initialize necessary digest algorithms for PKCS#7 Handling\r
+  //\r
+  if (EVP_add_digest (EVP_md5 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_digest (EVP_sha1 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_digest (EVP_sha256 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_digest (EVP_sha384 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_digest (EVP_sha512 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+  if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);\r
+  if (!Status) {\r
+    return Status;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Retrieve PKCS#7 Data (DER encoding)\r
+  //\r
+  if (SignedDataSize > INT_MAX) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Temp = SignedData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) SignedDataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Read DER-encoded root certificate and Construct X509 Certificate\r
+  //\r
+  Temp = TrustedCert;\r
+  Cert = d2i_X509 (NULL, &Temp, (long) CertLength);\r
+  if (Cert == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Setup X509 Store for trusted certificate\r
+  //\r
+  CertStore = X509_STORE_new ();\r
+  if (CertStore == NULL) {\r
+    goto _Exit;\r
+  }\r
+  if (!(X509_STORE_add_cert (CertStore, Cert))) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // For generic PKCS#7 handling, InData may be NULL if the content is present\r
+  // in PKCS#7 structure. So ignore NULL checking here.\r
+  //\r
+  DataBio = BIO_new (BIO_s_mem ());\r
+  if (DataBio == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  if (BIO_write (DataBio, InData, (int) DataLength) <= 0) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Allow partial certificate chains, terminated by a non-self-signed but\r
+  // still trusted intermediate certificate. Also disable time checks.\r
+  //\r
+  X509_STORE_set_flags (CertStore,\r
+                        X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);\r
+\r
+  //\r
+  // OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and\r
+  // doesn't support the extended key usage for Authenticode Code Signing.\r
+  // Bypass the certificate purpose checking by enabling any purposes setting.\r
+  //\r
+  X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);\r
+\r
+  //\r
+  // Verifies the PKCS#7 signedData structure\r
+  //\r
+  Status = (BOOLEAN) PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, PKCS7_BINARY);\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  BIO_free (DataBio);\r
+  X509_free (Cert);\r
+  X509_STORE_free (CertStore);\r
+  PKCS7_free (Pkcs7);\r
+\r
+  if (!Wrapped) {\r
+    OPENSSL_free (SignedData);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Extracts the attached content from a PKCS#7 signed data if existed. The input signed\r
+  data could be wrapped in a ContentInfo structure.\r
+\r
+  If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,\r
+  then return FAlSE. If the P7Data is not correctly formatted, then return FALSE.\r
+\r
+  Caution: This function may receive untrusted input. So this function will do\r
+           basic check for PKCS#7 data structure.\r
+\r
+  @param[in]   P7Data       Pointer to the PKCS#7 signed data to process.\r
+  @param[in]   P7Length     Length of the PKCS#7 signed data in bytes.\r
+  @param[out]  Content      Pointer to the extracted content from the PKCS#7 signedData.\r
+                            It's caller's responsiblity to free the buffer.\r
+  @param[out]  ContentSize  The size of the extracted content in bytes.\r
+\r
+  @retval     TRUE          The P7Data was correctly formatted for processing.\r
+  @retval     FALSE         The P7Data was not correctly formatted for processing.\r
+\r
+*/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetAttachedContent (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT VOID         **Content,\r
+  OUT UINTN        *ContentSize\r
+  )\r
+{\r
+  BOOLEAN            Status;\r
+  PKCS7              *Pkcs7;\r
+  UINT8              *SignedData;\r
+  UINTN              SignedDataSize;\r
+  BOOLEAN            Wrapped;\r
+  CONST UINT8        *Temp;\r
+  ASN1_OCTET_STRING  *OctStr;\r
+\r
+  //\r
+  // Check input parameter.\r
+  //\r
+  if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  *Content   = NULL;\r
+  Pkcs7      = NULL;\r
+  SignedData = NULL;\r
+  OctStr     = NULL;\r
+\r
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);\r
+  if (!Status || (SignedDataSize > INT_MAX)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Decoding PKCS#7 SignedData\r
+  //\r
+  Temp  = SignedData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // The type of Pkcs7 must be signedData\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check for detached or attached content\r
+  //\r
+  if (PKCS7_get_detached (Pkcs7)) {\r
+    //\r
+    // No Content supplied for PKCS7 detached signedData\r
+    //\r
+    *Content     = NULL;\r
+    *ContentSize = 0;\r
+  } else {\r
+    //\r
+    // Retrieve the attached content in PKCS7 signedData\r
+    //\r
+    OctStr = Pkcs7->d.sign->contents->d.data;\r
+    if ((OctStr->length > 0) && (OctStr->data != NULL)) {\r
+      *ContentSize = OctStr->length;\r
+      *Content     = malloc (*ContentSize);\r
+      if (*Content == NULL) {\r
+        *ContentSize = 0;\r
+        goto _Exit;\r
+      }\r
+      CopyMem (*Content, OctStr->data, *ContentSize);\r
+    }\r
+  }\r
+  Status = TRUE;\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  PKCS7_free (Pkcs7);\r
+\r
+  if (!Wrapped) {\r
+    OPENSSL_free (SignedData);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/Cryptlib/Pk/CryptRsaBasic.c b/Cryptlib/Pk/CryptRsaBasic.c
new file mode 100644 (file)
index 0000000..e49db51
--- /dev/null
@@ -0,0 +1,336 @@
+/** @file\r
+  RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.\r
+\r
+  This file implements following APIs which provide basic capabilities for RSA:\r
+  1) RsaNew\r
+  2) RsaFree\r
+  3) RsaSetKey\r
+  4) RsaPkcs1Verify\r
+\r
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+#include <openssl/bn.h>\r
+#include <openssl/rsa.h>\r
+#include <openssl/objects.h>\r
+\r
+/**\r
+  Allocates and initializes one RSA context for subsequent use.\r
+\r
+  @return  Pointer to the RSA context that has been initialized.\r
+           If the allocations fails, RsaNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+RsaNew (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Allocates & Initializes RSA Context by OpenSSL RSA_new()\r
+  //\r
+  return (VOID *) RSA_new ();\r
+}\r
+\r
+/**\r
+  Release the specified RSA context.\r
+\r
+  @param[in]  RsaContext  Pointer to the RSA context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RsaFree (\r
+  IN  VOID  *RsaContext\r
+  )\r
+{\r
+  //\r
+  // Free OpenSSL RSA Context\r
+  //\r
+  RSA_free ((RSA *) RsaContext);\r
+}\r
+\r
+/**\r
+  Sets the tag-designated key component into the established RSA context.\r
+\r
+  This function sets the tag-designated RSA key component into the established\r
+  RSA context from the user-specified non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[in]       BigNumber   Pointer to octet integer buffer.\r
+                               If NULL, then the specified key componenet in RSA\r
+                               context is cleared.\r
+  @param[in]       BnSize      Size of big number buffer in bytes.\r
+                               If BigNumber is NULL, then it is ignored.\r
+\r
+  @retval  TRUE   RSA key component was set successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaSetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  IN      CONST UINT8  *BigNumber,\r
+  IN      UINTN        BnSize\r
+  )\r
+{\r
+  RSA  *RsaKey;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (RsaContext == NULL || BnSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  RsaKey = (RSA *) RsaContext;\r
+  //\r
+  // Set RSA Key Components by converting octet string to OpenSSL BN representation.\r
+  // NOTE: For RSA public key (used in signature verification), only public components\r
+  //       (N, e) are needed.\r
+  //\r
+  switch (KeyTag) {\r
+\r
+  //\r
+  // RSA Public Modulus (N)\r
+  //\r
+  case RsaKeyN:\r
+    if (RsaKey->n != NULL) {\r
+      BN_free (RsaKey->n);\r
+    }\r
+    RsaKey->n = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);\r
+    if (RsaKey->n == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // RSA Public Exponent (e)\r
+  //\r
+  case RsaKeyE:\r
+    if (RsaKey->e != NULL) {\r
+      BN_free (RsaKey->e);\r
+    }\r
+    RsaKey->e = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);\r
+    if (RsaKey->e == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // RSA Private Exponent (d)\r
+  //\r
+  case RsaKeyD:\r
+    if (RsaKey->d != NULL) {\r
+      BN_free (RsaKey->d);\r
+    }\r
+    RsaKey->d = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);\r
+    if (RsaKey->d == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // RSA Secret Prime Factor of Modulus (p)\r
+  //\r
+  case RsaKeyP:\r
+    if (RsaKey->p != NULL) {\r
+      BN_free (RsaKey->p);\r
+    }\r
+    RsaKey->p = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);\r
+    if (RsaKey->p == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // RSA Secret Prime Factor of Modules (q)\r
+  //\r
+  case RsaKeyQ:\r
+    if (RsaKey->q != NULL) {\r
+      BN_free (RsaKey->q);\r
+    }\r
+    RsaKey->q = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);\r
+    if (RsaKey->q == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // p's CRT Exponent (== d mod (p - 1))\r
+  //\r
+  case RsaKeyDp:\r
+    if (RsaKey->dmp1 != NULL) {\r
+      BN_free (RsaKey->dmp1);\r
+    }\r
+    RsaKey->dmp1 = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);\r
+    if (RsaKey->dmp1 == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // q's CRT Exponent (== d mod (q - 1))\r
+  //\r
+  case RsaKeyDq:\r
+    if (RsaKey->dmq1 != NULL) {\r
+      BN_free (RsaKey->dmq1);\r
+    }\r
+    RsaKey->dmq1 = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);\r
+    if (RsaKey->dmq1 == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  //\r
+  // The CRT Coefficient (== 1/q mod p)\r
+  //\r
+  case RsaKeyQInv:\r
+    if (RsaKey->iqmp != NULL) {\r
+      BN_free (RsaKey->iqmp);\r
+    }\r
+    RsaKey->iqmp = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);\r
+    if (RsaKey->iqmp == NULL) {\r
+      return FALSE;\r
+    }\r
+\r
+    break;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+\r
+  If RsaContext is NULL, then return FALSE.\r
+  If MessageHash is NULL, then return FALSE.\r
+  If Signature is NULL, then return FALSE.\r
+  If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.\r
+\r
+  @param[in]  RsaContext   Pointer to RSA context for signature verification.\r
+  @param[in]  MessageHash  Pointer to octet message hash to be checked.\r
+  @param[in]  HashSize     Size of the message hash in bytes.\r
+  @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.\r
+  @param[in]  SigSize      Size of signature in bytes.\r
+\r
+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.\r
+  @retval  FALSE  Invalid signature or invalid RSA context.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Verify (\r
+  IN  VOID         *RsaContext,\r
+  IN  CONST UINT8  *MessageHash,\r
+  IN  UINTN        HashSize,\r
+  IN  CONST UINT8  *Signature,\r
+  IN  UINTN        SigSize\r
+  )\r
+{\r
+  INT32    DigestType;\r
+  UINT8    *SigBuf;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (SigSize > INT_MAX || SigSize == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Determine the message digest algorithm according to digest size.\r
+  //   Only MD5, SHA-1 or SHA-256 algorithm is supported. \r
+  //\r
+  switch (HashSize) {\r
+  case MD5_DIGEST_SIZE:\r
+    DigestType = NID_md5;\r
+    break;\r
+    \r
+  case SHA1_DIGEST_SIZE:\r
+    DigestType = NID_sha1;\r
+    break;\r
+    \r
+  case SHA256_DIGEST_SIZE:\r
+    DigestType = NID_sha256;\r
+    break;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+\r
+  SigBuf = (UINT8 *) Signature;\r
+  return (BOOLEAN) RSA_verify (\r
+                     DigestType,\r
+                     MessageHash,\r
+                     (UINT32) HashSize,\r
+                     SigBuf,\r
+                     (UINT32) SigSize,\r
+                     (RSA *) RsaContext\r
+                     );\r
+}\r
diff --git a/Cryptlib/Pk/CryptRsaExtNull.c b/Cryptlib/Pk/CryptRsaExtNull.c
new file mode 100644 (file)
index 0000000..e44cdde
--- /dev/null
@@ -0,0 +1,125 @@
+/** @file\r
+  RSA Asymmetric Cipher Wrapper Implementation over OpenSSL.\r
+\r
+  This file does not provide real capabilities for following APIs in RSA handling:\r
+  1) RsaGetKey\r
+  2) RsaGenerateKey\r
+  3) RsaCheckKey\r
+  4) RsaPkcs1Sign\r
+\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+/**\r
+  Gets the tag-designated RSA key component from the established RSA context.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[out]      BigNumber   Pointer to octet integer buffer.\r
+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.\r
+                               On output, the size of data returned in big number buffer in bytes.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  OUT     UINT8        *BigNumber,\r
+  IN OUT  UINTN        *BnSize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Generates RSA key components.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in, out]  RsaContext           Pointer to RSA context being set.\r
+  @param[in]       ModulusLength        Length of RSA modulus N in bits.\r
+  @param[in]       PublicExponent       Pointer to RSA public exponent.\r
+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes. \r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGenerateKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      UINTN        ModulusLength,\r
+  IN      CONST UINT8  *PublicExponent,\r
+  IN      UINTN        PublicExponentSize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Validates key components of RSA context.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in]  RsaContext  Pointer to RSA context to check.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaCheckKey (\r
+  IN  VOID  *RsaContext\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.\r
+\r
+  Return FALSE to indicate this interface is not supported.\r
+\r
+  @param[in]       RsaContext   Pointer to RSA context for signature generation.\r
+  @param[in]       MessageHash  Pointer to octet message hash to be signed.\r
+  @param[in]       HashSize     Size of the message hash in bytes.\r
+  @param[out]      Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.\r
+  @param[in, out]  SigSize      On input, the size of Signature buffer in bytes.\r
+                                On output, the size of data returned in Signature buffer in bytes.\r
+\r
+  @retval FALSE  This interface is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Sign (\r
+  IN      VOID         *RsaContext,\r
+  IN      CONST UINT8  *MessageHash,\r
+  IN      UINTN        HashSize,\r
+  OUT     UINT8        *Signature,\r
+  IN OUT  UINTN        *SigSize\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+  return FALSE;\r
+}\r
+\r
+\r
diff --git a/Cryptlib/Pk/CryptTs.c b/Cryptlib/Pk/CryptTs.c
new file mode 100644 (file)
index 0000000..d495812
--- /dev/null
@@ -0,0 +1,657 @@
+/** @file\r
+  RFC3161 Timestamp Countersignature Verification over OpenSSL.\r
+  The timestamp is generated by a TimeStamping Authority (TSA) and asserts that a\r
+  publisher's signature existed before the specified time. The timestamp extends\r
+  the lifetime of the signature when a signing certificate expires or is later\r
+  revoked.\r
+\r
+Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+\r
+#include <openssl/asn1.h>\r
+#include <openssl/asn1t.h>\r
+#include <openssl/x509.h>\r
+#include <openssl/x509v3.h>\r
+#include <openssl/pkcs7.h>\r
+\r
+//\r
+// OID ASN.1 Value for SPC_RFC3161_OBJID ("1.3.6.1.4.1.311.3.3.1")\r
+//\r
+UINT8 mSpcRFC3161OidValue[] = {\r
+  0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01\r
+  };\r
+\r
+///\r
+/// The messageImprint field SHOULD contain the hash of the datum to be\r
+/// time-stamped.  The hash is represented as an OCTET STRING.  Its\r
+/// length MUST match the length of the hash value for that algorithm\r
+/// (e.g., 20 bytes for SHA-1 or 16 bytes for MD5).\r
+///\r
+/// MessageImprint ::= SEQUENCE  {\r
+///   hashAlgorithm                AlgorithmIdentifier,\r
+///   hashedMessage                OCTET STRING  }\r
+///\r
+typedef struct {\r
+  X509_ALGOR         *HashAlgorithm;\r
+  ASN1_OCTET_STRING  *HashedMessage;\r
+} TS_MESSAGE_IMPRINT;\r
+\r
+//\r
+// ASN.1 Functions for TS_MESSAGE_IMPRINT\r
+//\r
+DECLARE_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)\r
+ASN1_SEQUENCE (TS_MESSAGE_IMPRINT) = {\r
+  ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashAlgorithm, X509_ALGOR),\r
+  ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashedMessage, ASN1_OCTET_STRING)\r
+} ASN1_SEQUENCE_END (TS_MESSAGE_IMPRINT)\r
+IMPLEMENT_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)\r
+\r
+///\r
+/// Accuracy represents the time deviation around the UTC time contained\r
+/// in GeneralizedTime of time-stamp token.\r
+///\r
+/// Accuracy ::= SEQUENCE {\r
+///       seconds        INTEGER              OPTIONAL,\r
+///       millis     [0] INTEGER  (1..999)    OPTIONAL,\r
+///       micros     [1] INTEGER  (1..999)    OPTIONAL  }\r
+///\r
+typedef struct {\r
+  ASN1_INTEGER  *Seconds;\r
+  ASN1_INTEGER  *Millis;\r
+  ASN1_INTEGER  *Micros;\r
+} TS_ACCURACY;\r
+\r
+//\r
+// ASN.1 Functions for TS_ACCURACY\r
+//\r
+DECLARE_ASN1_FUNCTIONS (TS_ACCURACY)\r
+ASN1_SEQUENCE (TS_ACCURACY) = {\r
+  ASN1_OPT     (TS_ACCURACY, Seconds, ASN1_INTEGER),\r
+  ASN1_IMP_OPT (TS_ACCURACY, Millis,  ASN1_INTEGER, 0),\r
+  ASN1_IMP_OPT (TS_ACCURACY, Micros,  ASN1_INTEGER, 1)\r
+} ASN1_SEQUENCE_END (TS_ACCURACY)\r
+IMPLEMENT_ASN1_FUNCTIONS (TS_ACCURACY)\r
+\r
+///\r
+/// The timestamp token info resulting from a successful timestamp request,\r
+/// as defined in RFC 3161.\r
+///\r
+///  TSTInfo ::= SEQUENCE  {\r
+///     version                      INTEGER  { v1(1) },\r
+///     policy                       TSAPolicyId,\r
+///     messageImprint               MessageImprint,\r
+///       -- MUST have the same value as the similar field in\r
+///       -- TimeStampReq\r
+///     serialNumber                 INTEGER,\r
+///       -- Time-Stamping users MUST be ready to accommodate integers\r
+///       -- up to 160 bits.\r
+///     genTime                      GeneralizedTime,\r
+///     accuracy                     Accuracy                 OPTIONAL,\r
+///     ordering                     BOOLEAN             DEFAULT FALSE,\r
+///     nonce                        INTEGER                  OPTIONAL,\r
+///       -- MUST be present if the similar field was present\r
+///       -- in TimeStampReq.  In that case it MUST have the same value.\r
+///     tsa                          [0] GeneralName          OPTIONAL,\r
+///     extensions                   [1] IMPLICIT Extensions   OPTIONAL  }\r
+///\r
+typedef struct {\r
+  ASN1_INTEGER              *Version;\r
+  ASN1_OBJECT               *Policy;\r
+  TS_MESSAGE_IMPRINT        *MessageImprint;\r
+  ASN1_INTEGER              *SerialNumber;\r
+  ASN1_GENERALIZEDTIME      *GenTime;\r
+  TS_ACCURACY               *Accuracy;\r
+  ASN1_BOOLEAN              Ordering;\r
+  ASN1_INTEGER              *Nonce;\r
+  GENERAL_NAME              *Tsa;\r
+  STACK_OF(X509_EXTENSION)  *Extensions;\r
+} TS_TST_INFO;\r
+\r
+//\r
+// ASN.1 Functions for TS_TST_INFO\r
+//\r
+DECLARE_ASN1_FUNCTIONS (TS_TST_INFO)\r
+ASN1_SEQUENCE (TS_TST_INFO) = {\r
+  ASN1_SIMPLE (TS_TST_INFO, Version, ASN1_INTEGER),\r
+  ASN1_SIMPLE (TS_TST_INFO, Policy, ASN1_OBJECT),\r
+  ASN1_SIMPLE (TS_TST_INFO, MessageImprint, TS_MESSAGE_IMPRINT),\r
+  ASN1_SIMPLE (TS_TST_INFO, SerialNumber, ASN1_INTEGER),\r
+  ASN1_SIMPLE (TS_TST_INFO, GenTime, ASN1_GENERALIZEDTIME),\r
+  ASN1_OPT    (TS_TST_INFO, Accuracy, TS_ACCURACY),\r
+  ASN1_OPT    (TS_TST_INFO, Ordering, ASN1_FBOOLEAN),\r
+  ASN1_OPT    (TS_TST_INFO, Nonce, ASN1_INTEGER),\r
+  ASN1_EXP_OPT(TS_TST_INFO, Tsa, GENERAL_NAME, 0),\r
+  ASN1_IMP_SEQUENCE_OF_OPT (TS_TST_INFO, Extensions, X509_EXTENSION, 1)\r
+} ASN1_SEQUENCE_END (TS_TST_INFO)\r
+IMPLEMENT_ASN1_FUNCTIONS (TS_TST_INFO)\r
+\r
+\r
+/**\r
+  Convert ASN.1 GeneralizedTime to EFI Time.\r
+\r
+  @param[in]  Asn1Time         Pointer to the ASN.1 GeneralizedTime to be converted.\r
+  @param[out] SigningTime      Return the corresponding EFI Time.\r
+\r
+  @retval  TRUE   The time convertion succeeds.\r
+  @retval  FALSE  Invalid parameters.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ConvertAsn1TimeToEfiTime (\r
+  IN  ASN1_TIME  *Asn1Time,\r
+  OUT EFI_TIME   *EfiTime\r
+  )\r
+{\r
+  CONST CHAR8  *Str;\r
+  UINTN        Index;\r
+\r
+  if ((Asn1Time == NULL) || (EfiTime == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Str = (CONST CHAR8*)Asn1Time->data;\r
+  SetMem (EfiTime, 0, sizeof (EFI_TIME));\r
+\r
+  Index = 0;\r
+  if (Asn1Time->type == V_ASN1_UTCTIME) {               /* two digit year */\r
+    EfiTime->Year  = (Str[Index++] - '0') * 10;\r
+    EfiTime->Year += (Str[Index++] - '0');\r
+    if (EfiTime->Year < 70) {\r
+      EfiTime->Year += 100;\r
+    }\r
+  } else if (Asn1Time->type == V_ASN1_GENERALIZEDTIME) { /* four digit year */\r
+    EfiTime->Year  = (Str[Index++] - '0') * 1000;\r
+    EfiTime->Year += (Str[Index++] - '0') * 100;\r
+    EfiTime->Year += (Str[Index++] - '0') * 10;\r
+    EfiTime->Year += (Str[Index++] - '0');\r
+    if ((EfiTime->Year < 1900) || (EfiTime->Year > 9999)) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  EfiTime->Month   = (Str[Index++] - '0') * 10;\r
+  EfiTime->Month  += (Str[Index++] - '0');\r
+  if ((EfiTime->Month < 1) || (EfiTime->Month > 12)) {\r
+    return FALSE;\r
+  }\r
+\r
+  EfiTime->Day     = (Str[Index++] - '0') * 10;\r
+  EfiTime->Day    += (Str[Index++] - '0');\r
+  if ((EfiTime->Day < 1) || (EfiTime->Day > 31)) {\r
+    return FALSE;\r
+  }\r
+\r
+  EfiTime->Hour    = (Str[Index++] - '0') * 10;\r
+  EfiTime->Hour   += (Str[Index++] - '0');\r
+  if (EfiTime->Hour > 23) {\r
+    return FALSE;\r
+  }\r
+\r
+  EfiTime->Minute  = (Str[Index++] - '0') * 10;\r
+  EfiTime->Minute += (Str[Index++] - '0');\r
+  if (EfiTime->Minute > 59) {\r
+    return FALSE;\r
+  }\r
+\r
+  EfiTime->Second  = (Str[Index++] - '0') * 10;\r
+  EfiTime->Second += (Str[Index++] - '0');\r
+  if (EfiTime->Second > 59) {\r
+    return FALSE;\r
+  }\r
+\r
+  /* Note: we did not adjust the time based on time zone information */\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+\r
+  Check the validity of TimeStamp Token Information.\r
+\r
+  @param[in]  TstInfo          Pointer to the TS_TST_INFO structure.\r
+  @param[in]  TimestampedData  Pointer to the data to be time-stamped.\r
+  @param[in]  DataSize         Size of timestamped data in bytes.\r
+\r
+  @retval  TRUE   The TimeStamp Token Information is valid.\r
+  @retval  FALSE  Invalid TimeStamp Token Information.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckTSTInfo (\r
+  IN  CONST TS_TST_INFO  *TstInfo,\r
+  IN  CONST UINT8        *TimestampedData,\r
+  IN  UINTN              DataSize\r
+  )\r
+{\r
+  BOOLEAN             Status;\r
+  TS_MESSAGE_IMPRINT  *Imprint;\r
+  X509_ALGOR          *HashAlgo;\r
+  CONST EVP_MD        *Md;\r
+  EVP_MD_CTX          MdCtx;\r
+  UINTN               MdSize;\r
+  UINT8               *HashedMsg;\r
+\r
+  //\r
+  // Initialization\r
+  //\r
+  Status    = FALSE;\r
+  HashAlgo  = NULL;\r
+  HashedMsg = NULL;\r
+\r
+  //\r
+  // -- Check version number of Timestamp:\r
+  //   The version field (currently v1) describes the version of the time-stamp token.\r
+  //   Conforming time-stamping servers MUST be able to provide version 1 time-stamp tokens.\r
+  //\r
+  if ((ASN1_INTEGER_get (TstInfo->Version)) != 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // -- Check Policies\r
+  //   The policy field MUST indicate the TSA's policy under which the response was produced.\r
+  //\r
+  if (TstInfo->Policy == NULL) {\r
+    /// NOTE: Need to check if the requested and returned policies.\r
+    ///       We have no information about the Requested TSA Policy.\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // -- Compute & Check Message Imprint\r
+  //\r
+  Imprint  = TstInfo->MessageImprint;\r
+  HashAlgo = X509_ALGOR_dup (Imprint->HashAlgorithm);\r
+\r
+  Md = EVP_get_digestbyobj (HashAlgo->algorithm);\r
+  if (Md == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  MdSize = EVP_MD_size (Md);\r
+  HashedMsg = AllocateZeroPool (MdSize);\r
+  if (HashedMsg == NULL) {\r
+    goto _Exit;\r
+  }\r
+  EVP_DigestInit (&MdCtx, Md);\r
+  EVP_DigestUpdate (&MdCtx, TimestampedData, DataSize);\r
+  EVP_DigestFinal (&MdCtx, HashedMsg, NULL);\r
+  if ((MdSize == (UINTN)ASN1_STRING_length (Imprint->HashedMessage)) &&\r
+      (CompareMem (HashedMsg, ASN1_STRING_data (Imprint->HashedMessage), MdSize) != 0)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // -- Check Nonces\r
+  //\r
+  if (TstInfo->Nonce != NULL) {\r
+    //\r
+    // Nonces is optional, No error if no nonce is returned;\r
+    //\r
+  }\r
+\r
+  //\r
+  // -- Check if the TSA name and signer certificate is matched.\r
+  //\r
+  if (TstInfo->Tsa != NULL) {\r
+    //\r
+    //  Ignored the optional Tsa field checking.\r
+    //\r
+  }\r
+\r
+  Status = TRUE;\r
+\r
+_Exit:\r
+  X509_ALGOR_free (HashAlgo);\r
+  if (HashedMsg != NULL) {\r
+    FreePool (HashedMsg);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Verifies the validility of a TimeStamp Token as described in RFC 3161 ("Internet\r
+  X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)").\r
+\r
+  If TSToken is NULL, then return FALSE.\r
+  If TimestampedData is NULL, then return FALSE.\r
+\r
+  @param[in]  TSToken          Pointer to the RFC3161 TimeStamp Token, which is generated\r
+                               by a TSA and located in the software publisher's SignerInfo\r
+                               structure.\r
+  @param[in]  TokenSize        Size of the TimeStamp Token in bytes.\r
+  @param[in]  TsaCert          Pointer to a trusted/root TSA certificate encoded in DER.\r
+  @param[in]  CertSize         Size of the trusted TSA certificate in bytes.\r
+  @param[in]  TimestampedData  Pointer to the data to be time-stamped.\r
+  @param[in]  DataSize         Size of timestamped data in bytes.\r
+  @param[out] SigningTime      Return the time of timestamp generation time if the timestamp\r
+                               signature is valid.\r
+\r
+  @retval  TRUE   The specified timestamp token is valid.\r
+  @retval  FALSE  Invalid timestamp token.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TimestampTokenVerify (\r
+  IN  CONST UINT8  *TSToken,\r
+  IN  UINTN        TokenSize,\r
+  IN  CONST UINT8  *TsaCert,\r
+  IN  UINTN        CertSize,\r
+  IN  CONST UINT8  *TimestampedData,\r
+  IN  UINTN        DataSize,\r
+  OUT EFI_TIME     *SigningTime\r
+  )\r
+{\r
+  BOOLEAN      Status;\r
+  CONST UINT8  *TokenTemp;\r
+  PKCS7        *Pkcs7;\r
+  X509         *Cert;\r
+  CONST UINT8  *CertTemp;\r
+  X509_STORE   *CertStore;\r
+  BIO          *OutBio;\r
+  UINT8        *TstData;\r
+  UINTN        TstSize;\r
+  CONST UINT8  *TstTemp;\r
+  TS_TST_INFO  *TstInfo;\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Check input parameters\r
+  //\r
+  if ((TSToken == NULL) || (TsaCert == NULL) || (TimestampedData == NULL) ||\r
+      (TokenSize > INT_MAX) || (CertSize > INT_MAX) || (DataSize > INT_MAX)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Initializations\r
+  //\r
+  if (SigningTime != NULL) {\r
+    SetMem (SigningTime, sizeof (EFI_TIME), 0);\r
+  }\r
+  Pkcs7     = NULL;\r
+  Cert      = NULL;\r
+  CertStore = NULL;\r
+  OutBio    = NULL;\r
+  TstData   = NULL;\r
+  TstInfo   = NULL;\r
+\r
+  //\r
+  // TimeStamp Token should contain one valid DER-encoded ASN.1 PKCS#7 structure.\r
+  //\r
+  TokenTemp = TSToken;\r
+  Pkcs7     = d2i_PKCS7 (NULL, (const unsigned char **) &TokenTemp, (int) TokenSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // The timestamp signature (TSA's response) will be one PKCS#7 signed data.\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Read the trusted TSA certificate (DER-encoded), and Construct X509 Certificate.\r
+  //\r
+  CertTemp = TsaCert;\r
+  Cert = d2i_X509 (NULL, &CertTemp, (long) CertSize);\r
+  if (Cert == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Setup X509 Store for trusted certificate.\r
+  //\r
+  CertStore = X509_STORE_new ();\r
+  if ((CertStore == NULL) || !(X509_STORE_add_cert (CertStore, Cert))) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Allow partial certificate chains, terminated by a non-self-signed but\r
+  // still trusted intermediate certificate. Also disable time checks.\r
+  //\r
+  X509_STORE_set_flags (CertStore,\r
+                        X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);\r
+\r
+  X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);\r
+\r
+  //\r
+  // Verifies the PKCS#7 signedData structure, and output the signed contents.\r
+  //\r
+  OutBio = BIO_new (BIO_s_mem ());\r
+  if (OutBio == NULL) {\r
+    goto _Exit;\r
+  }\r
+  if (!PKCS7_verify (Pkcs7, NULL, CertStore, NULL, OutBio, PKCS7_BINARY)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Read the signed contents detached in timestamp signature.\r
+  //\r
+  TstData = AllocateZeroPool (2048);\r
+  if (TstData == NULL) {\r
+    goto _Exit;\r
+  }\r
+  TstSize = BIO_read (OutBio, (void *) TstData, 2048);\r
+\r
+  //\r
+  // Construct TS_TST_INFO structure from the signed contents.\r
+  //\r
+  TstTemp = TstData;\r
+  TstInfo = d2i_TS_TST_INFO (NULL, (const unsigned char **) &TstTemp,\r
+              (int)TstSize);\r
+  if (TstInfo == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check TS_TST_INFO structure.\r
+  //\r
+  Status = CheckTSTInfo (TstInfo, TimestampedData, DataSize);\r
+  if (!Status) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Retrieve the signing time from TS_TST_INFO structure.\r
+  //\r
+  if (SigningTime != NULL) {\r
+    SetMem (SigningTime, sizeof (EFI_TIME), 0);\r
+    Status = ConvertAsn1TimeToEfiTime (TstInfo->GenTime, SigningTime);\r
+  }\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  PKCS7_free (Pkcs7);\r
+  X509_free (Cert);\r
+  X509_STORE_free (CertStore);\r
+  BIO_free (OutBio);\r
+  TS_TST_INFO_free (TstInfo);\r
+\r
+  if (TstData != NULL) {\r
+    FreePool (TstData);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Verifies the validility of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode\r
+  signature.\r
+\r
+  If AuthData is NULL, then return FALSE.\r
+\r
+  @param[in]  AuthData     Pointer to the Authenticode Signature retrieved from signed\r
+                           PE/COFF image to be verified.\r
+  @param[in]  DataSize     Size of the Authenticode Signature in bytes.\r
+  @param[in]  TsaCert      Pointer to a trusted/root TSA certificate encoded in DER, which\r
+                           is used for TSA certificate chain verification.\r
+  @param[in]  CertSize     Size of the trusted certificate in bytes.\r
+  @param[out] SigningTime  Return the time of timestamp generation time if the timestamp\r
+                           signature is valid.\r
+\r
+  @retval  TRUE   The specified Authenticode includes a valid RFC3161 Timestamp CounterSignature.\r
+  @retval  FALSE  No valid RFC3161 Timestamp CounterSignature in the specified Authenticode data.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ImageTimestampVerify (\r
+  IN  CONST UINT8  *AuthData,\r
+  IN  UINTN        DataSize,\r
+  IN  CONST UINT8  *TsaCert,\r
+  IN  UINTN        CertSize,\r
+  OUT EFI_TIME     *SigningTime\r
+  )\r
+{\r
+  BOOLEAN                      Status;\r
+  PKCS7                        *Pkcs7;\r
+  CONST UINT8                  *Temp;\r
+  STACK_OF(PKCS7_SIGNER_INFO)  *SignerInfos;\r
+  PKCS7_SIGNER_INFO            *SignInfo;\r
+  UINTN                        Index;\r
+  STACK_OF(X509_ATTRIBUTE)     *Sk;\r
+  X509_ATTRIBUTE               *Xa;\r
+  ASN1_OBJECT                  *XaObj;\r
+  ASN1_TYPE                    *Asn1Type;\r
+  ASN1_OCTET_STRING            *EncDigest;\r
+  UINT8                        *TSToken;\r
+  UINTN                        TokenSize;\r
+\r
+  //\r
+  // Input Parameters Checking.\r
+  //\r
+  if ((AuthData == NULL) || (TsaCert == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Register & Initialize necessary digest algorithms for PKCS#7 Handling.\r
+  //\r
+  if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||\r
+      (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Initialization.\r
+  //\r
+  Status    = FALSE;\r
+  Pkcs7     = NULL;\r
+  SignInfo  = NULL;\r
+\r
+  //\r
+  // Decode ASN.1-encoded Authenticode data into PKCS7 structure.\r
+  //\r
+  Temp  = AuthData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) DataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check if there is one and only one signer.\r
+  //\r
+  SignerInfos = PKCS7_get_signer_info (Pkcs7);\r
+  if (!SignerInfos || (sk_PKCS7_SIGNER_INFO_num (SignerInfos) != 1)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Locate the TimeStamp CounterSignature.\r
+  //\r
+  SignInfo = sk_PKCS7_SIGNER_INFO_value (SignerInfos, 0);\r
+  if (SignInfo == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Locate Message Digest which will be the data to be time-stamped.\r
+  //\r
+  EncDigest = SignInfo->enc_digest;\r
+  if (EncDigest == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // The RFC3161 timestamp counterSignature is contained in unauthenticatedAttributes field\r
+  // of SignerInfo.\r
+  //\r
+  Sk = SignInfo->unauth_attr;\r
+  if (Sk == NULL) {             // No timestamp counterSignature.\r
+    goto _Exit;\r
+  }\r
+\r
+  Asn1Type = NULL;\r
+  for (Index = 0; Index < (UINTN) sk_X509_ATTRIBUTE_num (Sk); Index++) {\r
+    //\r
+    // Search valid RFC3161 timestamp counterSignature based on OBJID.\r
+    //\r
+    Xa = sk_X509_ATTRIBUTE_value (Sk, (int)Index);\r
+    if (Xa == NULL) {\r
+      continue;\r
+    }\r
+    XaObj = X509_ATTRIBUTE_get0_object(Xa);\r
+    if (XaObj == NULL) {\r
+      continue;\r
+    }\r
+    if ((OBJ_length(XaObj) != sizeof (mSpcRFC3161OidValue)) ||\r
+        (CompareMem (OBJ_get0_data(XaObj), mSpcRFC3161OidValue, sizeof (mSpcRFC3161OidValue)) != 0)) {\r
+      continue;\r
+    }\r
+    Asn1Type = X509_ATTRIBUTE_get0_type(Xa, 0);\r
+  }\r
+\r
+  if (Asn1Type == NULL) {\r
+    Status = FALSE;\r
+    goto _Exit;\r
+  }\r
+  TSToken   = Asn1Type->value.octet_string->data;\r
+  TokenSize = Asn1Type->value.octet_string->length;\r
+\r
+  //\r
+  // TimeStamp counterSignature (Token) verification.\r
+  //\r
+  Status = TimestampTokenVerify (\r
+             TSToken,\r
+             TokenSize,\r
+             TsaCert,\r
+             CertSize,\r
+             EncDigest->data,\r
+             EncDigest->length,\r
+             SigningTime\r
+             );\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  PKCS7_free (Pkcs7);\r
+\r
+  return Status;\r
+}\r
diff --git a/Cryptlib/Pk/CryptX509.c b/Cryptlib/Pk/CryptX509.c
new file mode 100644 (file)
index 0000000..7dc4596
--- /dev/null
@@ -0,0 +1,580 @@
+/** @file\r
+  X.509 Certificate Handler Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/x509.h>\r
+#include <openssl/rsa.h>\r
+\r
+/**\r
+  Construct a X509 object from DER-encoded certificate data.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If SingleX509Cert is NULL, then return FALSE.\r
+\r
+  @param[in]  Cert            Pointer to the DER-encoded certificate data.\r
+  @param[in]  CertSize        The size of certificate data in bytes.\r
+  @param[out] SingleX509Cert  The generated X509 object.\r
+\r
+  @retval     TRUE            The X509 object generation succeeded.\r
+  @retval     FALSE           The operation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509ConstructCertificate (\r
+  IN   CONST UINT8  *Cert,\r
+  IN   UINTN        CertSize,\r
+  OUT  UINT8        **SingleX509Cert\r
+  )\r
+{\r
+  X509         *X509Cert;\r
+  CONST UINT8  *Temp;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Cert == NULL || SingleX509Cert == NULL || CertSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Read DER-encoded X509 Certificate and Construct X509 object.\r
+  //\r
+  Temp     = Cert;\r
+  X509Cert = d2i_X509 (NULL, &Temp, (long) CertSize);\r
+  if (X509Cert == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  *SingleX509Cert = (UINT8 *) X509Cert;\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Construct a X509 stack object from a list of DER-encoded certificate data.\r
+\r
+  If X509Stack is NULL, then return FALSE.\r
+\r
+  @param[in, out]  X509Stack  On input, pointer to an existing or NULL X509 stack object.\r
+                              On output, pointer to the X509 stack object with new\r
+                              inserted X509 certificate.\r
+  @param           ...        A list of DER-encoded single certificate data followed\r
+                              by certificate size. A NULL terminates the list. The\r
+                              pairs are the arguments to X509ConstructCertificate().\r
+                                 \r
+  @retval     TRUE            The X509 stack construction succeeded.\r
+  @retval     FALSE           The construction operation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509ConstructCertificateStack (\r
+  IN OUT  UINT8  **X509Stack,\r
+  ...  \r
+  )\r
+{\r
+  UINT8           *Cert;\r
+  UINTN           CertSize;\r
+  X509            *X509Cert;\r
+  STACK_OF(X509)  *CertStack;\r
+  BOOLEAN         Status;\r
+  VA_LIST         Args;\r
+  UINTN           Index;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (X509Stack == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Initialize X509 stack object.\r
+  //\r
+  CertStack = (STACK_OF(X509) *) (*X509Stack);\r
+  if (CertStack == NULL) {\r
+    CertStack = sk_X509_new_null ();\r
+    if (CertStack == NULL) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  VA_START (Args, X509Stack);\r
+\r
+  for (Index = 0; ; Index++) {\r
+    //\r
+    // If Cert is NULL, then it is the end of the list.\r
+    //\r
+    Cert = VA_ARG (Args, UINT8 *);\r
+    if (Cert == NULL) {\r
+      break;\r
+    }\r
+\r
+    CertSize = VA_ARG (Args, UINTN);\r
+    if (CertSize == 0) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Construct X509 Object from the given DER-encoded certificate data.\r
+    //\r
+    X509Cert = NULL;\r
+    Status = X509ConstructCertificate (\r
+               (CONST UINT8 *) Cert,\r
+               CertSize,\r
+               (UINT8 **) &X509Cert\r
+               );\r
+    if (!Status) {\r
+      if (X509Cert != NULL) {\r
+        X509_free (X509Cert);\r
+      }\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Insert the new X509 object into X509 stack object.\r
+    //\r
+    sk_X509_push (CertStack, X509Cert);\r
+  }\r
+\r
+  VA_END (Args);\r
+\r
+  if (!Status) {\r
+    sk_X509_pop_free (CertStack, X509_free);\r
+  } else {\r
+    *X509Stack = (UINT8 *) CertStack;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Release the specified X509 object.\r
+\r
+  If X509Cert is NULL, then return FALSE.\r
+\r
+  @param[in]  X509Cert  Pointer to the X509 object to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+X509Free (\r
+  IN  VOID  *X509Cert\r
+  )\r
+{ \r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (X509Cert == NULL) {\r
+    return;\r
+  }\r
+  \r
+  //\r
+  // Free OpenSSL X509 object.\r
+  //\r
+  X509_free ((X509 *) X509Cert);\r
+}\r
+\r
+/**\r
+  Release the specified X509 stack object.\r
+\r
+  If X509Stack is NULL, then return FALSE.\r
+\r
+  @param[in]  X509Stack  Pointer to the X509 stack object to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+X509StackFree (\r
+  IN  VOID  *X509Stack\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (X509Stack == NULL) {\r
+    return;\r
+  }\r
+  \r
+  //\r
+  // Free OpenSSL X509 stack object.\r
+  //\r
+  sk_X509_pop_free ((STACK_OF(X509) *) X509Stack, X509_free);\r
+}\r
+\r
+/**\r
+  Retrieve the subject bytes from one X.509 certificate.\r
+\r
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[out]     CertSubject  Pointer to the retrieved certificate subject bytes.\r
+  @param[in, out] SubjectSize  The size in bytes of the CertSubject buffer on input,\r
+                               and the size of buffer returned CertSubject on output.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If SubjectSize is NULL, then return FALSE.\r
+\r
+  @retval  TRUE   The certificate subject retrieved successfully.\r
+  @retval  FALSE  Invalid certificate, or the SubjectSize is too small for the result.\r
+                  The SubjectSize will be updated with the required size.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509GetSubjectName (\r
+  IN      CONST UINT8  *Cert,\r
+  IN      UINTN        CertSize,\r
+  OUT     UINT8        *CertSubject,\r
+  IN OUT  UINTN        *SubjectSize\r
+  )\r
+{\r
+  BOOLEAN    Status;\r
+  X509       *X509Cert;\r
+  X509_NAME  *X509Name;\r
+  UINTN      X509NameSize;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Cert == NULL || SubjectSize == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  X509Cert = NULL;\r
+\r
+  //\r
+  // Read DER-encoded X509 Certificate and Construct X509 object.\r
+  //\r
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);\r
+  if ((X509Cert == NULL) || (!Status)) {\r
+    Status = FALSE;\r
+    goto _Exit;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Retrieve subject name from certificate object.\r
+  //\r
+  X509Name = X509_get_subject_name (X509Cert);\r
+  if (X509Name == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  X509NameSize = i2d_X509_NAME(X509Name, NULL);\r
+  if (*SubjectSize < X509NameSize) {\r
+    *SubjectSize = X509NameSize;\r
+    goto _Exit;\r
+  }\r
+  *SubjectSize = X509NameSize;\r
+  if (CertSubject != NULL) {\r
+    i2d_X509_NAME(X509Name, &CertSubject);\r
+    Status = TRUE;\r
+  }\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources.\r
+  //\r
+  if (X509Cert != NULL) {\r
+    X509_free (X509Cert);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Retrieve the RSA Public Key from one DER-encoded X509 certificate.\r
+\r
+  @param[in]  Cert         Pointer to the DER-encoded X509 certificate.\r
+  @param[in]  CertSize     Size of the X509 certificate in bytes.\r
+  @param[out] RsaContext   Pointer to new-generated RSA context which contain the retrieved\r
+                           RSA public key component. Use RsaFree() function to free the\r
+                           resource.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If RsaContext is NULL, then return FALSE.\r
+\r
+  @retval  TRUE   RSA Public Key was retrieved successfully.\r
+  @retval  FALSE  Fail to retrieve RSA public key from X509 certificate.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetPublicKeyFromX509 (\r
+  IN   CONST UINT8  *Cert,\r
+  IN   UINTN        CertSize,\r
+  OUT  VOID         **RsaContext\r
+  )\r
+{\r
+  BOOLEAN   Status;\r
+  EVP_PKEY  *Pkey;\r
+  X509      *X509Cert;\r
+  \r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Cert == NULL || RsaContext == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Pkey     = NULL;\r
+  X509Cert = NULL;\r
+\r
+  //\r
+  // Read DER-encoded X509 Certificate and Construct X509 object.\r
+  //\r
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);\r
+  if ((X509Cert == NULL) || (!Status)) {\r
+    Status = FALSE;\r
+    goto _Exit;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Retrieve and check EVP_PKEY data from X509 Certificate.\r
+  //\r
+  Pkey = X509_get_pubkey (X509Cert);\r
+  if ((Pkey == NULL) || (Pkey->type != EVP_PKEY_RSA)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Duplicate RSA Context from the retrieved EVP_PKEY.\r
+  //\r
+  if ((*RsaContext = RSAPublicKey_dup (Pkey->pkey.rsa)) != NULL) {\r
+    Status = TRUE;\r
+  }\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources.\r
+  //\r
+  if (X509Cert != NULL) {\r
+    X509_free (X509Cert);\r
+  }\r
+\r
+  if (Pkey != NULL) {\r
+    EVP_PKEY_free (Pkey);\r
+  }  \r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Verify one X509 certificate was issued by the trusted CA.\r
+\r
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate to be verified.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[in]      CACert       Pointer to the DER-encoded trusted CA certificate.\r
+  @param[in]      CACertSize   Size of the CA Certificate in bytes.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If CACert is NULL, then return FALSE.\r
+\r
+  @retval  TRUE   The certificate was issued by the trusted CA.\r
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given\r
+                  trusted CA.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509VerifyCert (\r
+  IN  CONST UINT8  *Cert,\r
+  IN  UINTN        CertSize,\r
+  IN  CONST UINT8  *CACert,\r
+  IN  UINTN        CACertSize\r
+  )\r
+{\r
+  BOOLEAN         Status;\r
+  X509            *X509Cert;\r
+  X509            *X509CACert;\r
+  X509_STORE      *CertStore;\r
+  X509_STORE_CTX  CertCtx;\r
+  \r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Cert == NULL || CACert == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status     = FALSE;\r
+  X509Cert   = NULL;\r
+  X509CACert = NULL;\r
+  CertStore  = NULL;\r
+\r
+  //\r
+  // Register & Initialize necessary digest algorithms for certificate verification.\r
+  //\r
+  if (EVP_add_digest (EVP_md5 ()) == 0) {\r
+    goto _Exit;\r
+  }\r
+  if (EVP_add_digest (EVP_sha1 ()) == 0) {\r
+    goto _Exit;\r
+  }\r
+  if (EVP_add_digest (EVP_sha256 ()) == 0) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Read DER-encoded certificate to be verified and Construct X509 object.\r
+  //\r
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert);\r
+  if ((X509Cert == NULL) || (!Status)) {\r
+    Status = FALSE;\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Read DER-encoded root certificate and Construct X509 object.\r
+  //\r
+  Status = X509ConstructCertificate (CACert, CACertSize, (UINT8 **) &X509CACert);\r
+  if ((X509CACert == NULL) || (!Status)) {\r
+    Status = FALSE;\r
+    goto _Exit;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Set up X509 Store for trusted certificate.\r
+  //\r
+  CertStore = X509_STORE_new ();\r
+  if (CertStore == NULL) {\r
+    goto _Exit;\r
+  }\r
+  if (!(X509_STORE_add_cert (CertStore, X509CACert))) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Allow partial certificate chains, terminated by a non-self-signed but\r
+  // still trusted intermediate certificate. Also disable time checks.\r
+  //\r
+  X509_STORE_set_flags (CertStore,\r
+                        X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);\r
+\r
+  //\r
+  // Set up X509_STORE_CTX for the subsequent verification operation.\r
+  //\r
+  if (!X509_STORE_CTX_init (&CertCtx, CertStore, X509Cert, NULL)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // X509 Certificate Verification.\r
+  //\r
+  Status = (BOOLEAN) X509_verify_cert (&CertCtx);\r
+  X509_STORE_CTX_cleanup (&CertCtx);\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources.\r
+  //\r
+  if (X509Cert != NULL) {\r
+    X509_free (X509Cert);\r
+  }\r
+\r
+  if (X509CACert != NULL) {\r
+    X509_free (X509CACert);\r
+  }\r
+\r
+  if (CertStore != NULL) {\r
+    X509_STORE_free (CertStore);\r
+  }\r
+  \r
+  return Status;\r
+}\r
+\r
+/**\r
+  Retrieve the TBSCertificate from one given X.509 certificate.\r
+\r
+  @param[in]      Cert         Pointer to the given DER-encoded X509 certificate.\r
+  @param[in]      CertSize     Size of the X509 certificate in bytes.\r
+  @param[out]     TBSCert      DER-Encoded To-Be-Signed certificate.\r
+  @param[out]     TBSCertSize  Size of the TBS certificate in bytes.\r
+\r
+  If Cert is NULL, then return FALSE.\r
+  If TBSCert is NULL, then return FALSE.\r
+  If TBSCertSize is NULL, then return FALSE.\r
+\r
+  @retval  TRUE   The TBSCertificate was retrieved successfully.\r
+  @retval  FALSE  Invalid X.509 certificate.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+X509GetTBSCert (\r
+  IN  CONST UINT8  *Cert,\r
+  IN  UINTN        CertSize,\r
+  OUT UINT8        **TBSCert,\r
+  OUT UINTN        *TBSCertSize\r
+  )\r
+{\r
+  CONST UINT8  *Temp;\r
+  INTN         Asn1Tag;\r
+  INTN         ObjClass;\r
+  UINTN        Length;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if ((Cert == NULL) || (TBSCert == NULL) ||\r
+      (TBSCertSize == NULL) || (CertSize > INT_MAX)) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // An X.509 Certificate is: (defined in RFC3280)\r
+  //   Certificate  ::=  SEQUENCE  {\r
+  //     tbsCertificate       TBSCertificate,\r
+  //     signatureAlgorithm   AlgorithmIdentifier,\r
+  //     signature            BIT STRING }\r
+  //\r
+  // and\r
+  //\r
+  //  TBSCertificate  ::=  SEQUENCE  {\r
+  //    version         [0]  Version DEFAULT v1,\r
+  //    ...\r
+  //    }\r
+  //\r
+  // So we can just ASN1-parse the x.509 DER-encoded data. If we strip\r
+  // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.\r
+  //\r
+  Temp = Cert;\r
+  ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);\r
+\r
+  if (Asn1Tag != V_ASN1_SEQUENCE) {\r
+    return FALSE;\r
+  }\r
+\r
+  *TBSCert = (UINT8 *)Temp;\r
+\r
+  ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);\r
+  //\r
+  // Verify the parsed TBSCertificate is one correct SEQUENCE data.\r
+  //\r
+  if (Asn1Tag != V_ASN1_SEQUENCE) {\r
+    return FALSE;\r
+  }\r
+\r
+  *TBSCertSize = Length + (Temp - *TBSCert);\r
+  \r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/Rand/CryptRand.c b/Cryptlib/Rand/CryptRand.c
new file mode 100644 (file)
index 0000000..895ce83
--- /dev/null
@@ -0,0 +1,110 @@
+/** @file\r
+  Pseudorandom Number Generator Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/rand.h>\r
+#include <openssl/evp.h>\r
+\r
+//\r
+// Default seed for UEFI Crypto Library\r
+//\r
+CONST UINT8  DefaultSeed[] = "UEFI Crypto Library default seed";\r
+\r
+/**\r
+  Sets up the seed value for the pseudorandom number generator.\r
+\r
+  This function sets up the seed value for the pseudorandom number generator.\r
+  If Seed is not NULL, then the seed passed in is used.\r
+  If Seed is NULL, then default seed is used.\r
+\r
+  @param[in]  Seed      Pointer to seed value.\r
+                        If NULL, default seed is used.\r
+  @param[in]  SeedSize  Size of seed value.\r
+                        If Seed is NULL, this parameter is ignored.\r
+\r
+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.\r
+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomSeed (\r
+  IN  CONST  UINT8  *Seed  OPTIONAL,\r
+  IN  UINTN         SeedSize\r
+  )\r
+{\r
+  if (SeedSize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // The software PRNG implementation built in OpenSSL depends on message digest algorithm.\r
+  // Make sure SHA-1 digest algorithm is available here.\r
+  //\r
+  if (EVP_add_digest (EVP_sha1 ()) == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Seed the pseudorandom number generator with user-supplied value.\r
+  // NOTE: A cryptographic PRNG must be seeded with unpredictable data.\r
+  //\r
+  if (Seed != NULL) {\r
+    RAND_seed (Seed, (UINT32) SeedSize);\r
+  } else {\r
+    RAND_seed (DefaultSeed, sizeof (DefaultSeed));\r
+  }\r
+\r
+  if (RAND_status () == 1) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Generates a pseudorandom byte stream of the specified size.\r
+\r
+  If Output is NULL, then return FALSE.\r
+\r
+  @param[out]  Output  Pointer to buffer to receive random value.\r
+  @param[in]   Size    Size of randome bytes to generate.\r
+\r
+  @retval TRUE   Pseudorandom byte stream generated successfully.\r
+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomBytes (\r
+  OUT  UINT8  *Output,\r
+  IN   UINTN  Size\r
+  )\r
+{\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (Output == NULL || Size > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Generate random data.\r
+  //\r
+  if (RAND_bytes (Output, (UINT32) Size) != 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
diff --git a/Cryptlib/SysCall/BaseMemAllocation.c b/Cryptlib/SysCall/BaseMemAllocation.c
new file mode 100644 (file)
index 0000000..792b29e
--- /dev/null
@@ -0,0 +1,48 @@
+/** @file\r
+  Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL\r
+  during PEI & DXE phases.\r
+\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
+//\r
+// -- Memory-Allocation Routines --\r
+//\r
+\r
+/* Allocates memory blocks */\r
+void *malloc (size_t size)\r
+{\r
+  return AllocatePool ((UINTN) size);\r
+}\r
+\r
+/* Reallocate memory blocks */\r
+void *realloc (void *ptr, size_t size)\r
+{\r
+  //\r
+  // BUG: hardcode OldSize == size! We have no any knowledge about\r
+  // memory size of original pointer ptr.\r
+  //\r
+  return ReallocatePool (ptr, (UINTN) size, (UINTN) size);\r
+}\r
+\r
+/* De-allocates or frees a memory block */\r
+void free (void *ptr)\r
+{\r
+  //\r
+  // In Standard C, free() handles a null pointer argument transparently. This\r
+  // is not true of FreePool() below, so protect it.\r
+  //\r
+  if (ptr != NULL) {\r
+    FreePool (ptr);\r
+  }\r
+}\r
diff --git a/Cryptlib/SysCall/BaseStrings.c b/Cryptlib/SysCall/BaseStrings.c
new file mode 100644 (file)
index 0000000..4387571
--- /dev/null
@@ -0,0 +1,67 @@
+#include <OpenSslSupport.h>
+
+CHAR8 *
+AsciiStrCat(CHAR8 *Destination, CHAR8 *Source)
+{
+       UINTN dest_len = strlena(Destination);
+       UINTN i;
+
+       for (i = 0; Source[i] != '\0'; i++)
+               Destination[dest_len + i] = Source[i];
+       Destination[dest_len + i] = '\0';
+
+       return Destination;
+}
+
+CHAR8 *
+AsciiStrCpy(CHAR8 *Destination, CHAR8 *Source)
+{
+       UINTN i;
+
+       for (i=0; Source[i] != '\0'; i++)
+               Destination[i] = Source[i];
+       Destination[i] = '\0';
+
+       return Destination;
+}
+
+CHAR8 *
+AsciiStrnCpy(CHAR8 *Destination, CHAR8 *Source, UINTN count)
+{
+       UINTN i;
+
+       for (i=0; i < count && Source[i] != '\0'; i++)
+               Destination[i] = Source[i];
+       for ( ; i < count; i++) 
+               Destination[i] = '\0';
+
+       return Destination;
+}
+
+CHAR8 *
+ScanMem8(CHAR8 *str, UINTN count, CHAR8 ch)
+{
+       UINTN i;
+
+       for (i = 0; i < count; i++) {
+               if (str[i] == ch)
+                       return str + i;
+       }
+       return NULL;
+}
+
+UINT32
+WriteUnaligned32(UINT32 *Buffer, UINT32 Value)
+{
+       *Buffer = Value;
+
+       return Value;
+}
+
+UINTN
+AsciiStrSize(CHAR8 *string)
+{
+       return strlena(string) + 1;
+}
+
+
diff --git a/Cryptlib/SysCall/CrtWrapper.c b/Cryptlib/SysCall/CrtWrapper.c
new file mode 100644 (file)
index 0000000..3a852b9
--- /dev/null
@@ -0,0 +1,440 @@
+/** @file\r
+  C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based\r
+  Cryptographic Library.\r
+\r
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
+int errno = 0;\r
+\r
+FILE  *stderr = NULL;\r
+FILE  *stdin  = NULL;\r
+FILE  *stdout = NULL;\r
+\r
+typedef\r
+int\r
+(*SORT_COMPARE)(\r
+  IN  VOID  *Buffer1,\r
+  IN  VOID  *Buffer2\r
+  );\r
+\r
+//\r
+// Duplicated from EDKII BaseSortLib for qsort() wrapper\r
+//\r
+STATIC\r
+VOID\r
+QuickSortWorker (\r
+  IN OUT    VOID          *BufferToSort,\r
+  IN CONST  UINTN         Count,\r
+  IN CONST  UINTN         ElementSize,\r
+  IN        SORT_COMPARE  CompareFunction,\r
+  IN        VOID          *Buffer\r
+  )\r
+{\r
+  VOID        *Pivot;\r
+  UINTN       LoopCount;\r
+  UINTN       NextSwapLocation;\r
+\r
+  ASSERT(BufferToSort    != NULL);\r
+  ASSERT(CompareFunction != NULL);\r
+  ASSERT(Buffer          != NULL);\r
+\r
+  if (Count < 2 || ElementSize  < 1) {\r
+    return;\r
+  }\r
+\r
+  NextSwapLocation = 0;\r
+\r
+  //\r
+  // Pick a pivot (we choose last element)\r
+  //\r
+  Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));\r
+\r
+  //\r
+  // Now get the pivot such that all on "left" are below it\r
+  // and everything "right" are above it\r
+  //\r
+  for (LoopCount = 0; LoopCount < Count - 1;  LoopCount++)\r
+  {\r
+    //\r
+    // If the element is less than the pivot\r
+    //\r
+    if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {\r
+      //\r
+      // Swap\r
+      //\r
+      CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);\r
+      CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) * ElementSize), ElementSize);\r
+      CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);\r
+\r
+      //\r
+      // Increment NextSwapLocation\r
+      //\r
+      NextSwapLocation++;\r
+    }\r
+  }\r
+  //\r
+  // Swap pivot to it's final position (NextSwapLocaiton)\r
+  //\r
+  CopyMem (Buffer, Pivot, ElementSize);\r
+  CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);\r
+  CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);\r
+\r
+  //\r
+  // Now recurse on 2 paritial lists.  Neither of these will have the 'pivot' element.\r
+  // IE list is sorted left half, pivot element, sorted right half...\r
+  //\r
+  QuickSortWorker (\r
+    BufferToSort,\r
+    NextSwapLocation,\r
+    ElementSize,\r
+    CompareFunction,\r
+    Buffer\r
+    );\r
+\r
+  QuickSortWorker (\r
+    (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,\r
+    Count - NextSwapLocation - 1,\r
+    ElementSize,\r
+    CompareFunction,\r
+    Buffer\r
+    );\r
+\r
+  return;\r
+}\r
+\r
+//---------------------------------------------------------\r
+// Standard C Run-time Library Interface Wrapper\r
+//---------------------------------------------------------\r
+\r
+//\r
+// -- String Manipulation Routines --\r
+//\r
+\r
+/* Scan a string for the last occurrence of a character */\r
+char *strrchr (const char *str, int c)\r
+{\r
+  char * save;\r
+\r
+  for (save = NULL; ; ++str) {\r
+    if (*str == c) {\r
+      save = (char *)str;\r
+    }\r
+    if (*str == 0) {\r
+      return (save);\r
+    }\r
+  }\r
+}\r
+\r
+/* Read formatted data from a string */\r
+int sscanf (const char *buffer, const char *format, ...)\r
+{\r
+  //\r
+  // Null sscanf() function implementation to satisfy the linker, since\r
+  // no direct functionality logic dependency in present UEFI cases.\r
+  //\r
+  return 0;\r
+}\r
+\r
+//\r
+// -- Character Classification Routines --\r
+//\r
+\r
+/* Determines if a particular character is a decimal-digit character */\r
+int isdigit (int c)\r
+{\r
+  //\r
+  // <digit> ::= [0-9]\r
+  //\r
+  return (('0' <= (c)) && ((c) <= '9'));\r
+}\r
+\r
+/* Determine if an integer represents character that is a hex digit */\r
+int isxdigit (int c)\r
+{\r
+  //\r
+  // <hexdigit> ::= [0-9] | [a-f] | [A-F]\r
+  //\r
+  return ((('0' <= (c)) && ((c) <= '9')) ||\r
+          (('a' <= (c)) && ((c) <= 'f')) ||\r
+          (('A' <= (c)) && ((c) <= 'F')));\r
+}\r
+\r
+/* Determines if a particular character represents a space character */\r
+int isspace (int c)\r
+{\r
+  //\r
+  // <space> ::= [ ]\r
+  //\r
+  return ((c) == ' ');\r
+}\r
+\r
+/* Determine if a particular character is an alphanumeric character */\r
+int isalnum (int c)\r
+{\r
+  //\r
+  // <alnum> ::= [0-9] | [a-z] | [A-Z]\r
+  //\r
+  return ((('0' <= (c)) && ((c) <= '9')) ||\r
+          (('a' <= (c)) && ((c) <= 'z')) ||\r
+          (('A' <= (c)) && ((c) <= 'Z')));\r
+}\r
+\r
+/* Determines if a particular character is in upper case */\r
+int isupper (int c)\r
+{\r
+  //\r
+  // <uppercase letter> := [A-Z]\r
+  //\r
+  return (('A' <= (c)) && ((c) <= 'Z'));\r
+}\r
+\r
+//\r
+// -- Data Conversion Routines --\r
+//\r
+\r
+/* Convert strings to a long-integer value */\r
+long strtol (const char *nptr, char **endptr, int base)\r
+{\r
+  //\r
+  // Null strtol() function implementation to satisfy the linker, since there is\r
+  // no direct functionality logic dependency in present UEFI cases.\r
+  //\r
+  return 0;\r
+}\r
+\r
+/* Convert strings to an unsigned long-integer value */\r
+unsigned long strtoul (const char *nptr, char **endptr, int base)\r
+{\r
+  //\r
+  // Null strtoul() function implementation to satisfy the linker, since there is\r
+  // no direct functionality logic dependency in present UEFI cases.\r
+  //\r
+  return 0;\r
+}\r
+\r
+/* Convert character to lowercase */\r
+int tolower (int c)\r
+{\r
+  if (('A' <= (c)) && ((c) <= 'Z')) {\r
+    return (c - ('A' - 'a'));\r
+  }\r
+  return (c);\r
+}\r
+\r
+//\r
+// -- Searching and Sorting Routines --\r
+//\r
+\r
+/* Performs a quick sort */\r
+void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *))\r
+{\r
+  VOID  *Buffer;\r
+\r
+  ASSERT (base    != NULL);\r
+  ASSERT (compare != NULL);\r
+\r
+  //\r
+  // Use CRT-style malloc to cover BS and RT memory allocation.\r
+  //\r
+  Buffer = malloc (width);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.\r
+  //\r
+  QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);\r
+\r
+  free (Buffer);\r
+  return;\r
+}\r
+\r
+//\r
+// -- Process and Environment Control Routines --\r
+//\r
+\r
+/* Get a value from the current environment */\r
+char *getenv (const char *varname)\r
+{\r
+  //\r
+  // Null getenv() function implementation to satisfy the linker, since there is\r
+  // no direct functionality logic dependency in present UEFI cases.\r
+  //\r
+  return NULL;\r
+}\r
+\r
+//\r
+// -- Stream I/O Routines --\r
+//\r
+\r
+/* Write formatted output using a pointer to a list of arguments */\r
+int vfprintf (FILE *stream, const char *format, VA_LIST arg)\r
+{\r
+  return 0;\r
+}\r
+\r
+/* Write data to a stream */\r
+size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream)\r
+{\r
+  return 0;\r
+}\r
+\r
+//\r
+//  -- Dummy OpenSSL Support Routines --\r
+//\r
+\r
+void *UI_OpenSSL(void)\r
+{\r
+  return NULL;\r
+}\r
+\r
+int X509_load_cert_file (VOID *ctx, const char *file, int type)\r
+{\r
+  return 0;\r
+}\r
+\r
+int X509_load_crl_file (VOID *ctx, const char *file, int type)\r
+{\r
+  return 0;\r
+}\r
+\r
+int chmod (const char *c, mode_t m)\r
+{\r
+  return -1;\r
+}\r
+\r
+int close (int f)\r
+{\r
+  return -1;\r
+}\r
+\r
+void closelog (void)\r
+{\r
+\r
+}\r
+\r
+#ifdef __GNUC__\r
+\r
+typedef\r
+VOID\r
+(EFIAPI *NoReturnFuncPtr)(\r
+  VOID\r
+  ) __attribute__((__noreturn__));\r
+\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+NopFunction (\r
+  VOID\r
+  )\r
+{\r
+}\r
+\r
+\r
+void exit (int e)\r
+{\r
+  NoReturnFuncPtr NoReturnFunc;\r
+\r
+  NoReturnFunc = (NoReturnFuncPtr) NopFunction;\r
+\r
+  NoReturnFunc ();\r
+}\r
+\r
+#else\r
+\r
+void exit (int e)\r
+{\r
+}\r
+\r
+#endif\r
+\r
+int fclose (FILE *f)\r
+{\r
+  return 0;\r
+}\r
+\r
+FILE *fopen (const char *c, const char *m)\r
+{\r
+  return NULL;\r
+}\r
+\r
+size_t fread (void *b, size_t c, size_t i, FILE *f)\r
+{\r
+  return 0;\r
+}\r
+\r
+int fprintf (FILE *f, const char *s, ...)\r
+{\r
+  return 0;\r
+}\r
+\r
+uid_t getuid (void)\r
+{\r
+  return 0;\r
+}\r
+\r
+uid_t geteuid (void)\r
+{\r
+  return 0;\r
+}\r
+\r
+gid_t getgid (void)\r
+{\r
+  return 0;\r
+}\r
+\r
+gid_t getegid (void)\r
+{\r
+  return 0;\r
+}\r
+\r
+off_t lseek (int a, off_t o, int d)\r
+{\r
+  return 0;\r
+}\r
+\r
+void openlog (const char *c, int a, int b)\r
+{\r
+\r
+}\r
+\r
+ssize_t read (int f, void *b, size_t c)\r
+{\r
+  return 0;\r
+}\r
+\r
+int stat (const char *c, struct stat *s)\r
+{\r
+  return -1;\r
+}\r
+\r
+int strcasecmp (const char *c, const char *s)\r
+{\r
+  return 0;\r
+}\r
+\r
+int strncasecmp (const char *c, const char *s, size_t l)\r
+{\r
+  return 0;\r
+}\r
+\r
+void syslog (int a, const char *c, ...)\r
+{\r
+\r
+}\r
+\r
+ssize_t write (int f, const void *b, size_t l)\r
+{\r
+  return 0;\r
+}\r
diff --git a/Cryptlib/SysCall/TimerWrapper.c b/Cryptlib/SysCall/TimerWrapper.c
new file mode 100644 (file)
index 0000000..27ac44a
--- /dev/null
@@ -0,0 +1,168 @@
+/** @file\r
+  C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation\r
+  for OpenSSL-based Cryptographic Library (used in DXE & RUNTIME).\r
+\r
+Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <OpenSslSupport.h>\r
+\r
+//\r
+// -- Time Management Routines --\r
+//\r
+\r
+#define IsLeap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))\r
+#define SECSPERMIN  (60)\r
+#define SECSPERHOUR (60 * 60)\r
+#define SECSPERDAY  (24 * SECSPERHOUR)\r
+\r
+//\r
+//  The arrays give the cumulative number of days up to the first of the\r
+//  month number used as the index (1 -> 12) for regular and leap years.\r
+//  The value at index 13 is for the whole year.\r
+//\r
+UINTN CumulativeDays[2][14] = {\r
+  {\r
+    0,\r
+    0,\r
+    31,\r
+    31 + 28,\r
+    31 + 28 + 31,\r
+    31 + 28 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31\r
+  },\r
+  {\r
+    0,\r
+    0,\r
+    31,\r
+    31 + 29,\r
+    31 + 29 + 31,\r
+    31 + 29 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 \r
+  }\r
+};\r
+\r
+/* Get the system time as seconds elapsed since midnight, January 1, 1970. */\r
+//INTN time(\r
+//  INTN *timer\r
+//  )\r
+time_t time (time_t *timer)\r
+{\r
+  EFI_TIME  Time;\r
+  time_t    CalTime;\r
+  UINTN     Year;\r
+\r
+  //\r
+  // Get the current time and date information\r
+  //\r
+  uefi_call_wrapper(RT->GetTime, 2, &Time, NULL);\r
+\r
+  //\r
+  // Years Handling\r
+  // UTime should now be set to 00:00:00 on Jan 1 of the current year.\r
+  //\r
+  for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {\r
+    CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);\r
+  }\r
+\r
+  //\r
+  // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment\r
+  //\r
+  CalTime = CalTime + \r
+            (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +\r
+            (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) + \r
+            (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) + \r
+            (time_t)(Time.Hour * SECSPERHOUR) + \r
+            (time_t)(Time.Minute * 60) + \r
+            (time_t)Time.Second;\r
+\r
+  if (timer != NULL) {\r
+    *timer = CalTime;\r
+  }\r
+\r
+  return CalTime;\r
+}\r
+\r
+//\r
+// Convert a time value from type time_t to struct tm.\r
+//\r
+struct tm * gmtime (const time_t *timer)\r
+{\r
+  struct tm  *GmTime;\r
+  UINT16     DayNo;\r
+  UINT16     DayRemainder;\r
+  time_t     Year;\r
+  time_t     YearNo;\r
+  UINT16     TotalDays;\r
+  UINT16     MonthNo;\r
+\r
+  if (timer == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  GmTime = malloc (sizeof (struct tm));\r
+  if (GmTime == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  ZeroMem ((VOID *) GmTime, (UINTN) sizeof (struct tm));\r
+\r
+  DayNo        = (UINT16) (*timer / SECSPERDAY);\r
+  DayRemainder = (UINT16) (*timer % SECSPERDAY);\r
+\r
+  GmTime->tm_sec  = (int) (DayRemainder % SECSPERMIN);\r
+  GmTime->tm_min  = (int) ((DayRemainder % SECSPERHOUR) / SECSPERMIN);\r
+  GmTime->tm_hour = (int) (DayRemainder / SECSPERHOUR);\r
+  GmTime->tm_wday = (int) ((DayNo + 4) % 7);\r
+\r
+  for (Year = 1970, YearNo = 0; DayNo > 0; Year++) {\r
+    TotalDays = (UINT16) (IsLeap (Year) ? 366 : 365);\r
+    if (DayNo >= TotalDays) {\r
+      DayNo = (UINT16) (DayNo - TotalDays);\r
+      YearNo++;\r
+    } else {\r
+      break;\r
+    }\r
+  }\r
+\r
+  GmTime->tm_year = (int) (YearNo + (1970 - 1900));\r
+  GmTime->tm_yday = (int) DayNo;\r
+\r
+  for (MonthNo = 12; MonthNo > 1; MonthNo--) {\r
+    if (DayNo >= CumulativeDays[IsLeap(Year)][MonthNo]) {\r
+      DayNo = (UINT16) (DayNo - (UINT16) (CumulativeDays[IsLeap(Year)][MonthNo]));\r
+      break;\r
+    }\r
+  }\r
+\r
+  GmTime->tm_mon  = (int) MonthNo - 1;\r
+  GmTime->tm_mday = (int) DayNo + 1;\r
+\r
+  GmTime->tm_isdst  = 0;\r
+  GmTime->tm_gmtoff = 0;\r
+  GmTime->tm_zone   = NULL;\r
+\r
+  return GmTime;\r
+}\r
diff --git a/Cryptlib/update.sh b/Cryptlib/update.sh
new file mode 100755 (executable)
index 0000000..e9b3f84
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+DIR=$1
+OPENSSL_VERSION="1.0.2h"
+
+cp $DIR/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h InternalCryptLib.h
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd4.c Hash/CryptMd4.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c Hash/CryptMd5.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c Hash/CryptSha1.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c Hash/CryptSha256.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c Hmac/CryptHmacMd5.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c Hmac/CryptHmacSha1.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c Cipher/CryptAes.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c Cipher/CryptTdes.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c Cipher/CryptArc4.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c Rand/CryptRand.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaBasic.c Pk/CryptRsaBasic.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaExtNull.c Pk/CryptRsaExtNull.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7SignNull.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c Pk/CryptPkcs7Verify.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptDhNull.c Pk/CryptDhNull.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c Pk/CryptTs.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c Pk/CryptX509.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c Pk/CryptAuthenticode.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c Pem/CryptPem.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c SysCall/CrtWrapper.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c SysCall/TimerWrapper.c
+cp $DIR/CryptoPkg/Library/BaseCryptLib/SysCall/BaseMemAllocation.c SysCall/BaseMemAllocation.c
+
+cp $DIR/CryptoPkg/Library/OpensslLib/openssl-${OPENSSL_VERSION}/include/openssl/* Include/openssl/
+
+patch -p2 <Cryptlib.diff
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..c02cc94
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,222 @@
+VERSION                = 0.9
+RELEASE                :=
+ifneq ($(RELEASE),"")
+       RELEASE:="-$(RELEASE)"
+endif
+
+CC             = $(CROSS_COMPILE)gcc
+LD             = $(CROSS_COMPILE)ld
+OBJCOPY                = $(CROSS_COMPILE)objcopy
+
+ARCH           = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,)
+OBJCOPY_GTE224  = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.*\((.*)\|version\) //g' | cut -f1-2 -d.` \>= 2.24)
+
+SUBDIRS                = Cryptlib lib
+
+EFI_INCLUDE    := /usr/include/efi
+EFI_INCLUDES   = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -I$(shell pwd)/include
+
+LIB_GCC                = $(shell $(CC) -print-libgcc-file-name)
+EFI_LIBS       = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC) 
+
+EFI_CRT_OBJS   = $(EFI_PATH)/crt0-efi-$(ARCH).o
+EFI_LDS                = elf_$(ARCH)_efi.lds
+
+DEFAULT_LOADER := \\\\grub.efi
+CFLAGS         = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
+                 -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
+                 -Werror=sign-compare -ffreestanding -std=gnu89 \
+                 -I$(shell $(CC) -print-file-name=include) \
+                 "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
+                 "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
+                 $(EFI_INCLUDES)
+SHIMNAME       = shim
+MMNAME         = MokManager
+FBNAME         = fallback
+
+ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
+       CFLAGS  += -DOVERRIDE_SECURITY_POLICY
+endif
+
+ifneq ($(origin ENABLE_HTTPBOOT), undefined)
+       CFLAGS  += -DENABLE_HTTPBOOT
+endif
+
+ifeq ($(ARCH),x86_64)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
+               -maccumulate-outgoing-args \
+               -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \
+               -DNO_BUILTIN_VA_FUNCS \
+               -DMDE_CPU_X64 "-DEFI_ARCH=L\"x64\"" -DPAGE_SIZE=4096 \
+               "-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/x64-$(VERSION)$(RELEASE)/\""
+       MMNAME  = mmx64
+       FBNAME  = fbx64
+       SHIMNAME= shimx64
+       EFI_PATH:=/usr/lib64/gnuefi
+       LIB_PATH:=/usr/lib64
+
+endif
+ifeq ($(ARCH),ia32)
+       CFLAGS  += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
+               -maccumulate-outgoing-args -m32 \
+               -DMDE_CPU_IA32 "-DEFI_ARCH=L\"ia32\"" -DPAGE_SIZE=4096 \
+               "-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/ia32-$(VERSION)$(RELEASE)/\""
+       MMNAME  = mmia32
+       FBNAME  = fbia32
+       SHIMNAME= shimia32
+       EFI_PATH:=/usr/lib/gnuefi
+       LIB_PATH:=/usr/lib
+endif
+ifeq ($(ARCH),aarch64)
+       CFLAGS += -DMDE_CPU_AARCH64 "-DEFI_ARCH=L\"aa64\"" -DPAGE_SIZE=4096 \
+               "-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/aa64-$(VERSION)$(RELEASE)/\""
+       MMNAME  = mmaa64
+       FBNAME  = fbaa64
+       SHIMNAME= shimaa64
+       EFI_PATH:=/usr/lib64/gnuefi
+       LIB_PATH:=/usr/lib64
+endif
+
+ifneq ($(origin VENDOR_CERT_FILE), undefined)
+       CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
+endif
+ifneq ($(origin VENDOR_DBX_FILE), undefined)
+       CFLAGS += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\"
+endif
+
+LDFLAGS                = --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) --build-id=sha1
+
+TARGET = $(SHIMNAME).efi $(MMNAME).efi.signed $(FBNAME).efi.signed
+OBJS   = shim.o netboot.o cert.o replacements.o tpm.o version.o
+KEYS   = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
+SOURCES        = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h tpm.c tpm.h version.c version.h
+MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o
+MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h
+FALLBACK_OBJS = fallback.o
+FALLBACK_SRCS = fallback.c
+
+ifneq ($(origin ENABLE_HTTPBOOT), undefined)
+       OBJS += httpboot.o
+       SOURCES += httpboot.c httpboot.h
+endif
+
+all: $(TARGET)
+
+shim.crt:
+       ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 </dev/null
+
+shim.cer: shim.crt
+       openssl x509 -outform der -in $< -out $@
+
+shim_cert.h: shim.cer
+       echo "static UINT8 shim_cert[] = {" > $@
+       hexdump -v -e '1/1 "0x%02x, "' $< >> $@
+       echo "};" >> $@
+
+version.c : version.c.in
+       sed     -e "s,@@VERSION@@,$(VERSION)," \
+               -e "s,@@UNAME@@,$(shell uname -a)," \
+               -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \
+               < version.c.in > version.c
+
+certdb/secmod.db: shim.crt
+       -mkdir certdb
+       pk12util -d certdb/ -i shim.p12 -W "" -K ""
+       certutil -d certdb/ -A -i shim.crt -n shim -t u
+
+shim.o: $(SOURCES) shim_cert.h
+shim.o: $(wildcard *.h)
+
+cert.o : cert.S
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+$(SHIMNAME).so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+       $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
+
+fallback.o: $(FALLBACK_SRCS)
+
+$(FBNAME).so: $(FALLBACK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+       $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
+
+MokManager.o: $(MOK_SOURCES)
+
+$(MMNAME).so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+       $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
+
+Cryptlib/libcryptlib.a:
+       $(MAKE) -C Cryptlib
+
+Cryptlib/OpenSSL/libopenssl.a:
+       $(MAKE) -C Cryptlib/OpenSSL
+
+lib/lib.a:
+       $(MAKE) CFLAGS="$(CFLAGS)" -C lib
+
+ifeq ($(ARCH),aarch64)
+FORMAT         := -O binary
+SUBSYSTEM      := 0xa
+LDFLAGS                += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
+endif
+
+ifeq ($(ARCH),arm)
+FORMAT         := -O binary
+SUBSYSTEM      := 0xa
+LDFLAGS                += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
+endif
+
+FORMAT         ?= --target efi-app-$(ARCH)
+
+%.efi: %.so
+ifneq ($(OBJCOPY_GTE224),1)
+       $(error objcopy >= 2.24 is required)
+endif
+       $(OBJCOPY) -j .text -j .sdata -j .data \
+               -j .dynamic -j .dynsym  -j .rel* \
+               -j .rela* -j .reloc -j .eh_frame \
+               -j .vendor_cert \
+               $(FORMAT)  $^ $@
+       $(OBJCOPY) -j .text -j .sdata -j .data \
+               -j .dynamic -j .dynsym  -j .rel* \
+               -j .rela* -j .reloc -j .eh_frame \
+               -j .debug_info -j .debug_abbrev -j .debug_aranges \
+               -j .debug_line -j .debug_str -j .debug_ranges \
+               -j .note.gnu.build-id \
+               $(FORMAT) $^ $@.debug
+
+%.efi.signed: %.efi certdb/secmod.db
+       pesign -n certdb -i $< -c "shim" -s -o $@ -f
+
+clean:
+       $(MAKE) -C Cryptlib clean
+       $(MAKE) -C Cryptlib/OpenSSL clean
+       $(MAKE) -C lib clean
+       rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb
+       rm -f *.debug *.so *.efi *.tar.* version.c
+
+GITTAG = $(VERSION)
+
+test-archive:
+       @rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
+       @mkdir -p /tmp/shim-$(VERSION)-tmp
+       @git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
+       @git diff | ( cd /tmp/shim-$(VERSION)-tmp/ ; patch -s -p1 -b -z .gitdiff )
+       @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
+       @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
+       @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
+       @rm -rf /tmp/shim-$(VERSION)
+       @echo "The archive is in shim-$(VERSION).tar.bz2"
+
+tag:
+       git tag --sign $(GITTAG) refs/heads/master
+
+archive: tag
+       @rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
+       @mkdir -p /tmp/shim-$(VERSION)-tmp
+       @git archive --format=tar $(GITTAG) | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
+       @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
+       @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
+       @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
+       @rm -rf /tmp/shim-$(VERSION)
+       @echo "The archive is in shim-$(VERSION).tar.bz2"
+
+export ARCH CC LD OBJCOPY EFI_INCLUDE
diff --git a/MokManager.c b/MokManager.c
new file mode 100644 (file)
index 0000000..ebc85db
--- /dev/null
@@ -0,0 +1,2547 @@
+#include <efi.h>
+#include <efilib.h>
+#include <stdarg.h>
+#include <Library/BaseCryptLib.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#include "shim.h"
+#include "PeImage.h"
+#include "PasswordCrypt.h"
+
+#include "guid.h"
+#include "console.h"
+#include "variables.h"
+#include "simple_file.h"
+#include "efiauthenticated.h"
+
+#define PASSWORD_MAX 256
+#define PASSWORD_MIN 1
+#define SB_PASSWORD_LEN 16
+
+#define NAME_LINE_MAX 70
+
+#ifndef SHIM_VENDOR
+#define SHIM_VENDOR L"Shim"
+#endif
+
+EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+EFI_GUID EFI_CERT_SHA224_GUID = { 0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} };
+EFI_GUID EFI_CERT_SHA384_GUID = { 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} };
+EFI_GUID EFI_CERT_SHA512_GUID = { 0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} };
+
+#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
+#define HASH_STRING L"Select a file to trust:\n\n"
+
+struct menu_item {
+       CHAR16 *text;
+       INTN (* callback)(void *data, void *data2, void *data3);
+       void *data;
+       void *data2;
+       void *data3;
+       UINTN colour;
+};
+
+typedef struct {
+       UINT32 MokSize;
+       UINT8 *Mok;
+       EFI_GUID Type;
+} __attribute__ ((packed)) MokListNode;
+
+typedef struct {
+       UINT32 MokSBState;
+       UINT32 PWLen;
+       CHAR16 Password[SB_PASSWORD_LEN];
+} __attribute__ ((packed)) MokSBvar;
+
+typedef struct {
+       UINT32 MokDBState;
+       UINT32 PWLen;
+       CHAR16 Password[SB_PASSWORD_LEN];
+} __attribute__ ((packed)) MokDBvar;
+
+static EFI_STATUS get_sha1sum (void *Data, int DataSize, UINT8 *hash)
+{
+       EFI_STATUS status;
+       unsigned int ctxsize;
+       void *ctx = NULL;
+
+       ctxsize = Sha1GetContextSize();
+       ctx = AllocatePool(ctxsize);
+
+       if (!ctx) {
+               console_notify(L"Unable to allocate memory for hash context");
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       if (!Sha1Init(ctx)) {
+               console_notify(L"Unable to initialise hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       if (!(Sha1Update(ctx, Data, DataSize))) {
+               console_notify(L"Unable to generate hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       if (!(Sha1Final(ctx, hash))) {
+               console_notify(L"Unable to finalise hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       status = EFI_SUCCESS;
+done:
+       return status;
+}
+
+static BOOLEAN is_sha2_hash (EFI_GUID Type)
+{
+       EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
+       EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+       EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+       EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
+
+       if (CompareGuid(&Type, &Sha224) == 0)
+               return TRUE;
+       else if (CompareGuid(&Type, &Sha256) == 0)
+               return TRUE;
+       else if (CompareGuid(&Type, &Sha384) == 0)
+               return TRUE;
+       else if (CompareGuid(&Type, &Sha512) == 0)
+               return TRUE;
+
+       return FALSE;
+}
+
+static UINT32 sha_size (EFI_GUID Type)
+{
+       EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+       EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
+       EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+       EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+       EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
+
+       if (CompareGuid(&Type, &Sha1) == 0)
+               return SHA1_DIGEST_SIZE;
+       else if (CompareGuid(&Type, &Sha224) == 0)
+               return SHA224_DIGEST_LENGTH;
+       else if (CompareGuid(&Type, &Sha256) == 0)
+               return SHA256_DIGEST_SIZE;
+       else if (CompareGuid(&Type, &Sha384) == 0)
+               return SHA384_DIGEST_LENGTH;
+       else if (CompareGuid(&Type, &Sha512) == 0)
+               return SHA512_DIGEST_LENGTH;
+
+       return 0;
+}
+
+static BOOLEAN is_valid_siglist (EFI_GUID Type, UINT32 SigSize)
+{
+       EFI_GUID CertType = X509_GUID;
+       UINT32 hash_sig_size;
+
+       if (CompareGuid (&Type, &CertType) == 0 && SigSize != 0)
+               return TRUE;
+
+       if (!is_sha2_hash (Type))
+               return FALSE;
+
+       hash_sig_size = sha_size (Type) + sizeof(EFI_GUID);
+       if (SigSize != hash_sig_size)
+               return FALSE;
+
+       return TRUE;
+}
+
+static UINT32 count_keys(void *Data, UINTN DataSize)
+{
+       EFI_SIGNATURE_LIST *CertList = Data;
+       UINTN dbsize = DataSize;
+       UINT32 MokNum = 0;
+       void *end = Data + DataSize;
+
+       while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+
+               /* Use ptr arithmetics to ensure bounded access. Do not allow 0
+                * SignatureListSize that will cause endless loop.
+                */
+               if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+                       console_notify(L"Invalid MOK detected! Ignoring MOK List.");
+                       return 0;
+               }
+
+               if (CertList->SignatureListSize == 0 ||
+                   CertList->SignatureListSize <= CertList->SignatureSize) {
+                       console_errorbox(L"Corrupted signature list");
+                       return 0;
+               }
+
+               if (!is_valid_siglist(CertList->SignatureType, CertList->SignatureSize)) {
+                       console_errorbox(L"Invalid signature list found");
+                       return 0;
+               }
+
+               MokNum++;
+               dbsize -= CertList->SignatureListSize;
+               CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+                                                 CertList->SignatureListSize);
+       }
+
+       return MokNum;
+}
+
+static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
+       MokListNode *list;
+       EFI_SIGNATURE_LIST *CertList = Data;
+       EFI_SIGNATURE_DATA *Cert;
+       EFI_GUID CertType = X509_GUID;
+       UINTN dbsize = DataSize;
+       UINTN count = 0;
+       void *end = Data + DataSize;
+
+       list = AllocatePool(sizeof(MokListNode) * num);
+
+       if (!list) {
+               console_notify(L"Unable to allocate MOK list");
+               return NULL;
+       }
+
+       while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+               /* CertList out of bounds? */
+               if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+                       FreePool(list);
+                       return NULL;
+               }
+
+               /* Omit the signature check here since we already did it
+                  in count_keys() */
+
+               Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
+                 sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+
+               /* Cert out of bounds? */
+               if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) {
+                       FreePool(list);
+                       return NULL;
+               }
+
+               list[count].Type = CertList->SignatureType;
+               if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
+                       list[count].MokSize = CertList->SignatureSize -
+                                             sizeof(EFI_GUID);
+                       list[count].Mok = (void *)Cert->SignatureData;
+               } else {
+                       list[count].MokSize = CertList->SignatureListSize -
+                                             sizeof(EFI_SIGNATURE_LIST);
+                       list[count].Mok = (void *)Cert;
+               }
+
+               /* MOK out of bounds? */
+               if (list[count].MokSize > (unsigned long)end -
+                                         (unsigned long)list[count].Mok) {
+                       FreePool(list);
+                       return NULL;
+               }
+
+               count++;
+               dbsize -= CertList->SignatureListSize;
+               CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+                                                 CertList->SignatureListSize);
+       }
+
+       return list;
+}
+
+typedef struct {
+       int nid;
+       CHAR16 *name;
+} NidName;
+
+static NidName nidname[] = {
+       {NID_commonName, L"CN"},
+       {NID_organizationName, L"O"},
+       {NID_countryName, L"C"},
+       {NID_stateOrProvinceName, L"ST"},
+       {NID_localityName, L"L"},
+       {-1, NULL}
+};
+
+static CHAR16* get_x509_name (X509_NAME *X509Name)
+{
+       CHAR16 name[NAME_LINE_MAX+1];
+       CHAR16 part[NAME_LINE_MAX+1];
+       char str[NAME_LINE_MAX];
+       int i, len, rest, first;
+
+       name[0] = '\0';
+       rest = NAME_LINE_MAX;
+       first = 1;
+       for (i = 0; nidname[i].name != NULL; i++) {
+               int add;
+               len = X509_NAME_get_text_by_NID (X509Name, nidname[i].nid,
+                                                str, NAME_LINE_MAX);
+               if (len <= 0)
+                       continue;
+
+               if (first)
+                       add = len + (int)StrLen(nidname[i].name) + 1;
+               else
+                       add = len + (int)StrLen(nidname[i].name) + 3;
+
+               if (add > rest)
+                       continue;
+
+               if (first) {
+                       SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L"%s=%a",
+                              nidname[i].name, str);
+               } else {
+                       SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L", %s=%a",
+                              nidname[i].name, str);
+               }
+               StrCat(name, part);
+               rest -= add;
+               first = 0;
+       }
+
+       if (rest >= 0 && rest < NAME_LINE_MAX)
+               return PoolPrint(L"%s", name);
+
+       return NULL;
+}
+
+static CHAR16* get_x509_time (ASN1_TIME *time)
+{
+       BIO *bio = BIO_new (BIO_s_mem());
+       char str[30];
+       int len;
+
+       ASN1_TIME_print (bio, time);
+       len = BIO_read(bio, str, 29);
+       if (len < 0)
+               len = 0;
+       str[len] = '\0';
+       BIO_free (bio);
+
+       return PoolPrint(L"%a", str);
+}
+
+static void show_x509_info (X509 *X509Cert, UINT8 *hash)
+{
+       ASN1_INTEGER *serial;
+       BIGNUM *bnser;
+       unsigned char hexbuf[30];
+       X509_NAME *X509Name;
+       ASN1_TIME *time;
+       CHAR16 *issuer = NULL;
+       CHAR16 *subject = NULL;
+       CHAR16 *from = NULL;
+       CHAR16 *until = NULL;
+       EXTENDED_KEY_USAGE *extusage;
+       POOL_PRINT hash_string1;
+       POOL_PRINT hash_string2;
+       POOL_PRINT serial_string;
+       int fields = 0;
+       CHAR16 **text;
+       int i = 0;
+
+       ZeroMem(&hash_string1, sizeof(hash_string1));
+       ZeroMem(&hash_string2, sizeof(hash_string2));
+       ZeroMem(&serial_string, sizeof(serial_string));
+
+       serial = X509_get_serialNumber(X509Cert);
+       if (serial) {
+               int i, n;
+               bnser = ASN1_INTEGER_to_BN(serial, NULL);
+               n = BN_bn2bin(bnser, hexbuf);
+               for (i = 0; i < n; i++) {
+                       CatPrint(&serial_string, L"%02x:", hexbuf[i]);
+               }
+       }
+
+       if (serial_string.str)
+               fields++;
+
+       X509Name = X509_get_issuer_name(X509Cert);
+       if (X509Name) {
+               issuer = get_x509_name(X509Name);
+               if (issuer)
+                       fields++;
+       }
+
+       X509Name = X509_get_subject_name(X509Cert);
+       if (X509Name) {
+               subject = get_x509_name(X509Name);
+               if (subject)
+                       fields++;
+       }
+
+       time = X509_get_notBefore(X509Cert);
+       if (time) {
+               from = get_x509_time(time);
+               if (from)
+                       fields++;
+       }
+
+       time = X509_get_notAfter(X509Cert);
+       if (time) {
+               until = get_x509_time(time);
+               if (until)
+                       fields++;
+       }
+
+       for (i=0; i<10; i++)
+               CatPrint(&hash_string1, L"%02x ", hash[i]);
+       for (i=10; i<20; i++)
+               CatPrint(&hash_string2, L"%02x ", hash[i]);
+
+       if (hash_string1.str)
+               fields++;
+
+       if (hash_string2.str)
+               fields++;
+
+       if (!fields)
+               return;
+
+       i = 0;
+
+       extusage = X509_get_ext_d2i(X509Cert, NID_ext_key_usage, NULL, NULL);
+       text = AllocateZeroPool(sizeof(CHAR16 *) * (fields*3 + sk_ASN1_OBJECT_num(extusage) + 3));
+
+       if (extusage) {
+               int j = 0;
+
+               text[i++] = StrDuplicate(L"[Extended Key Usage]");
+
+               for (j = 0; j < sk_ASN1_OBJECT_num(extusage); j++) {
+                       POOL_PRINT extkeyusage;
+                       ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(extusage, j);
+                       int buflen = 80;
+                       char buf[buflen];
+
+                       ZeroMem(&extkeyusage, sizeof(extkeyusage));
+
+                       OBJ_obj2txt(buf, buflen, obj, 0);
+                       CatPrint(&extkeyusage, L"OID: %a", buf);
+                       text[i++] = StrDuplicate(extkeyusage.str);
+                       FreePool(extkeyusage.str);
+               }
+               text[i++] = StrDuplicate(L"");
+               EXTENDED_KEY_USAGE_free(extusage);
+       }
+
+       if (serial_string.str) {
+               text[i++] = StrDuplicate(L"[Serial Number]");
+               text[i++] = serial_string.str;
+               text[i++] = StrDuplicate(L"");
+       }
+       if (issuer) {
+               text[i++] = StrDuplicate(L"[Issuer]");
+               text[i++] = issuer;
+               text[i++] = StrDuplicate(L"");
+       }
+       if (subject) {
+               text[i++] = StrDuplicate(L"[Subject]");
+               text[i++] = subject;
+               text[i++] = StrDuplicate(L"");
+       }
+       if (from) {
+               text[i++] = StrDuplicate(L"[Valid Not Before]");
+               text[i++] = from;
+               text[i++] = StrDuplicate(L"");
+       }
+       if (until) {
+               text[i++] = StrDuplicate(L"[Valid Not After]");
+               text[i++] = until;
+               text[i++] = StrDuplicate(L"");
+       }
+       if (hash_string1.str) {
+               text[i++] = StrDuplicate(L"[Fingerprint]");
+               text[i++] = hash_string1.str;
+       }
+       if (hash_string2.str) {
+               text[i++] = hash_string2.str;
+               text[i++] = StrDuplicate(L"");
+       }
+       text[i] = NULL;
+
+       console_print_box(text, -1);
+
+       for (i=0; text[i] != NULL; i++)
+               FreePool(text[i]);
+
+       FreePool(text);
+}
+
+static void show_sha_digest (EFI_GUID Type, UINT8 *hash)
+{
+       EFI_GUID Sha1 = EFI_CERT_SHA1_GUID;
+       EFI_GUID Sha224 = EFI_CERT_SHA224_GUID;
+       EFI_GUID Sha256 = EFI_CERT_SHA256_GUID;
+       EFI_GUID Sha384 = EFI_CERT_SHA384_GUID;
+       EFI_GUID Sha512 = EFI_CERT_SHA512_GUID;
+       CHAR16 *text[5];
+       POOL_PRINT hash_string1;
+       POOL_PRINT hash_string2;
+       int i;
+       int length;
+
+       if (CompareGuid(&Type, &Sha1) == 0) {
+               length = SHA1_DIGEST_SIZE;
+               text[0] = L"SHA1 hash";
+       } else if (CompareGuid(&Type, &Sha224) == 0) {
+               length = SHA224_DIGEST_LENGTH;
+               text[0] = L"SHA224 hash";
+       } else if (CompareGuid(&Type, &Sha256) == 0) {
+               length = SHA256_DIGEST_SIZE;
+               text[0] = L"SHA256 hash";
+       } else if (CompareGuid(&Type, &Sha384) == 0) {
+               length = SHA384_DIGEST_LENGTH;
+               text[0] = L"SHA384 hash";
+       } else if (CompareGuid(&Type, &Sha512) == 0) {
+               length = SHA512_DIGEST_LENGTH;
+               text[0] = L"SHA512 hash";
+       } else {
+               return;
+       }
+
+       ZeroMem(&hash_string1, sizeof(hash_string1));
+       ZeroMem(&hash_string2, sizeof(hash_string2));
+
+       text[1] = L"";
+
+       for (i=0; i<length/2; i++)
+               CatPrint(&hash_string1, L"%02x ", hash[i]);
+       for (i=length/2; i<length; i++)
+               CatPrint(&hash_string2, L"%02x ", hash[i]);
+
+       text[2] = hash_string1.str;
+       text[3] = hash_string2.str;
+       text[4] = NULL;
+
+       console_print_box(text, -1);
+
+       if (hash_string1.str)
+               FreePool(hash_string1.str);
+
+       if (hash_string2.str)
+               FreePool(hash_string2.str);
+}
+
+static void show_efi_hash (EFI_GUID Type, void *Mok, UINTN MokSize)
+{
+       UINTN sig_size;
+       UINTN hash_num;
+       UINT8 *hash;
+       CHAR16 **menu_strings;
+       UINTN key_num = 0;
+       UINTN i;
+
+       sig_size = sha_size(Type) + sizeof(EFI_GUID);
+       if ((MokSize % sig_size) != 0) {
+               console_errorbox(L"Corrupted Hash List");
+               return;
+       }
+       hash_num = MokSize / sig_size;
+
+       if (hash_num == 1) {
+               hash = (UINT8 *)Mok + sizeof(EFI_GUID);
+               show_sha_digest(Type, hash);
+               return;
+       }
+
+       menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (hash_num + 2));
+       if (!menu_strings) {
+               console_errorbox(L"Out of Resources");
+               return;
+       }
+       for (i=0; i<hash_num; i++) {
+               menu_strings[i] = PoolPrint(L"View hash %d", i);
+       }
+       menu_strings[i] = StrDuplicate(L"Back");
+       menu_strings[i+1] = NULL;
+
+       while (key_num < hash_num) {
+               key_num = console_select((CHAR16 *[]){ L"[Hash List]", NULL },
+                                        menu_strings, key_num);
+
+               if (key_num < 0 || key_num >= hash_num)
+                       break;
+
+               hash = (UINT8 *)Mok + sig_size*key_num + sizeof(EFI_GUID);
+               show_sha_digest(Type, hash);
+       }
+
+       for (i=0; menu_strings[i] != NULL; i++)
+               FreePool(menu_strings[i]);
+
+       FreePool(menu_strings);
+}
+
+static void show_mok_info (EFI_GUID Type, void *Mok, UINTN MokSize)
+{
+       EFI_STATUS efi_status;
+       EFI_GUID CertType = X509_GUID;
+
+       if (!Mok || MokSize == 0)
+               return;
+
+       if (CompareGuid (&Type, &CertType) == 0) {
+               UINT8 hash[SHA1_DIGEST_SIZE];
+               X509 *X509Cert;
+               efi_status = get_sha1sum(Mok, MokSize, hash);
+
+               if (efi_status != EFI_SUCCESS) {
+                       console_notify(L"Failed to compute MOK fingerprint");
+                       return;
+               }
+
+               if (X509ConstructCertificate(Mok, MokSize,
+                                (UINT8 **) &X509Cert) && X509Cert != NULL) {
+                       show_x509_info(X509Cert, hash);
+                       X509_free(X509Cert);
+               } else {
+                       console_notify(L"Not a valid X509 certificate");
+                       return;
+               }
+       } else if (is_sha2_hash(Type)) {
+               show_efi_hash(Type, Mok, MokSize);
+       }
+}
+
+static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
+{
+       UINTN MokNum = 0;
+       MokListNode *keys = NULL;
+       UINT32 key_num = 0;
+       CHAR16 **menu_strings;
+       unsigned int i;
+
+       if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) +
+                          sizeof(EFI_SIGNATURE_DATA))) {
+               console_notify(L"No MOK keys found");
+               return EFI_NOT_FOUND;
+       }
+
+       MokNum = count_keys(KeyList, KeyListSize);
+       if (MokNum == 0) {
+               console_errorbox(L"Invalid key list");
+               return EFI_ABORTED;
+       }
+       keys = build_mok_list(MokNum, KeyList, KeyListSize);
+       if (!keys) {
+               console_errorbox(L"Failed to construct key list");
+               return EFI_ABORTED;
+       }
+
+       menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (MokNum + 2));
+
+       if (!menu_strings)
+               return EFI_OUT_OF_RESOURCES;
+
+       for (i=0; i<MokNum; i++) {
+               menu_strings[i] = PoolPrint(L"View key %d", i);
+       }
+       menu_strings[i] = StrDuplicate(L"Continue");
+
+       menu_strings[i+1] = NULL;
+
+       while (key_num < MokNum) {
+               key_num = console_select((CHAR16 *[]){ title, NULL },
+                                        menu_strings, key_num);
+
+               if (key_num < 0 || key_num >= MokNum)
+                       break;
+
+               show_mok_info(keys[key_num].Type, keys[key_num].Mok,
+                             keys[key_num].MokSize);
+       }
+
+       for (i=0; menu_strings[i] != NULL; i++)
+               FreePool(menu_strings[i]);
+
+       FreePool(menu_strings);
+
+       FreePool(keys);
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show)
+{
+       EFI_INPUT_KEY key;
+       EFI_STATUS status;
+       unsigned int count = 0;
+
+       do {
+               status = console_get_keystroke(&key);
+               if (EFI_ERROR (status)) {
+                       console_error(L"Failed to read the keystroke", status);
+                       *length = 0;
+                       return status;
+               }
+
+               if ((count >= line_max &&
+                    key.UnicodeChar != CHAR_BACKSPACE) ||
+                   key.UnicodeChar == CHAR_NULL ||
+                   key.UnicodeChar == CHAR_TAB  ||
+                   key.UnicodeChar == CHAR_LINEFEED ||
+                   key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+                       continue;
+               }
+
+               if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+                       continue;
+               } else if (key.UnicodeChar == CHAR_BACKSPACE) {
+                       if (show) {
+                               Print(L"\b");
+                       }
+                       line[--count] = '\0';
+                       continue;
+               }
+
+               if (show) {
+                       Print(L"%c", key.UnicodeChar);
+               }
+
+               line[count++] = key.UnicodeChar;
+       } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+       Print(L"\n");
+
+       *length = count;
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
+                                  UINT32 pw_length, UINT8 *hash)
+{
+       EFI_STATUS status;
+       unsigned int ctxsize;
+       void *ctx = NULL;
+
+       ctxsize = Sha256GetContextSize();
+       ctx = AllocatePool(ctxsize);
+
+       if (!ctx) {
+               console_notify(L"Unable to allocate memory for hash context");
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       if (!Sha256Init(ctx)) {
+               console_notify(L"Unable to initialise hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       if (Data && DataSize) {
+               if (!(Sha256Update(ctx, Data, DataSize))) {
+                       console_notify(L"Unable to generate hash");
+                       status = EFI_OUT_OF_RESOURCES;
+                       goto done;
+               }
+       }
+
+       if (!(Sha256Update(ctx, password, pw_length))) {
+               console_notify(L"Unable to generate hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       if (!(Sha256Final(ctx, hash))) {
+               console_notify(L"Unable to finalise hash");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       status = EFI_SUCCESS;
+done:
+       return status;
+}
+
+static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
+{
+       if (!SavedMode) {
+               Print(L"Invalid parameter: SavedMode\n");
+               return;
+       }
+
+       CopyMem(SavedMode, ST->ConOut->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
+       uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
+       uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
+                         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+}
+
+static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
+{
+       uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
+                         SavedMode->CursorVisible);
+       uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
+                         SavedMode->CursorColumn, SavedMode->CursorRow);
+       uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
+                         SavedMode->Attribute);
+}
+
+static UINT32 get_password (CHAR16 *prompt, CHAR16 *password, UINT32 max)
+{
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       CHAR16 *str;
+       CHAR16 *message[2];
+       UINTN length;
+       UINT32 pw_length;
+
+       if (!prompt)
+               prompt = L"Password:";
+
+       console_save_and_set_mode(&SavedMode);
+
+       str = PoolPrint(L"%s            ", prompt);
+       if (!str) {
+               console_errorbox(L"Failed to allocate prompt");
+               return 0;
+       }
+
+       message[0] = str;
+       message[1] = NULL;
+       length = StrLen(message[0]);
+       console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
+       get_line(&pw_length, password, max, 0);
+
+       console_restore_mode(&SavedMode);
+
+       FreePool(str);
+
+       return pw_length;
+}
+
+static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
+                                 void *Data, UINTN DataSize,
+                                 UINT8 *auth, CHAR16 *prompt)
+{
+       EFI_STATUS status;
+       UINT8 hash[128];
+       UINT8 *auth_hash;
+       UINT32 auth_size;
+       CHAR16 password[PASSWORD_MAX];
+       UINT32 pw_length;
+       UINT8 fail_count = 0;
+       unsigned int i;
+
+       if (pw_crypt) {
+               auth_hash = pw_crypt->hash;
+               auth_size = get_hash_size (pw_crypt->method);
+               if (auth_size == 0)
+                       return EFI_INVALID_PARAMETER;
+       } else if (auth) {
+               auth_hash = auth;
+               auth_size = SHA256_DIGEST_SIZE;
+       } else {
+               return EFI_INVALID_PARAMETER;
+       }
+
+       while (fail_count < 3) {
+               pw_length = get_password(prompt, password, PASSWORD_MAX);
+
+               if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) {
+                       console_errorbox(L"Invalid password length");
+                       fail_count++;
+                       continue;
+               }
+
+               /*
+                * Compute password hash
+                */
+               if (pw_crypt) {
+                       char pw_ascii[PASSWORD_MAX + 1];
+                       for (i = 0; i < pw_length; i++)
+                               pw_ascii[i] = (char)password[i];
+                       pw_ascii[pw_length] = '\0';
+
+                       status = password_crypt(pw_ascii, pw_length, pw_crypt, hash);
+               } else {
+                       /*
+                        * For backward compatibility
+                        */
+                       status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
+                                                pw_length * sizeof(CHAR16), hash);
+               }
+               if (status != EFI_SUCCESS) {
+                       console_errorbox(L"Unable to generate password hash");
+                       fail_count++;
+                       continue;
+               }
+
+               if (CompareMem(auth_hash, hash, auth_size) != 0) {
+                       console_errorbox(L"Password doesn't match");
+                       fail_count++;
+                       continue;
+               }
+
+               break;
+       }
+
+       if (fail_count >= 3)
+               return EFI_ACCESS_DENIED;
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS write_db (CHAR16 *db_name, void *MokNew, UINTN MokNewSize)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS status;
+       UINT32 attributes;
+       void *old_data = NULL;
+       void *new_data = NULL;
+       UINTN old_size;
+       UINTN new_size;
+
+       status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                  &shim_lock_guid,
+                                  EFI_VARIABLE_NON_VOLATILE
+                                  | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                  | EFI_VARIABLE_APPEND_WRITE,
+                                  MokNewSize, MokNew);
+       if (status == EFI_SUCCESS || status != EFI_INVALID_PARAMETER) {
+               return status;
+       }
+
+       status = get_variable_attr(db_name, (UINT8 **)&old_data, &old_size,
+                                  shim_lock_guid, &attributes);
+       if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               return status;
+       }
+
+       /* Check if the old db is compromised or not */
+       if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+               FreePool(old_data);
+               old_data = NULL;
+               old_size = 0;
+       }
+
+       new_size = old_size + MokNewSize;
+       new_data = AllocatePool(new_size);
+       if (new_data == NULL) {
+               status = EFI_OUT_OF_RESOURCES;
+               goto out;
+       }
+
+       CopyMem(new_data, old_data, old_size);
+       CopyMem(new_data + old_size, MokNew, MokNewSize);
+
+       status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                  &shim_lock_guid,
+                                  EFI_VARIABLE_NON_VOLATILE
+                                  | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                  new_size, new_data);
+
+out:
+       if (old_size > 0) {
+               FreePool(old_data);
+       }
+
+       if (new_data != NULL) {
+               FreePool(new_data);
+       }
+
+       return status;
+}
+
+static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate,
+                             BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       CHAR16 *db_name;
+       CHAR16 *auth_name;
+       UINT8 auth[PASSWORD_CRYPT_SIZE];
+       UINTN auth_size = PASSWORD_CRYPT_SIZE;
+       UINT32 attributes;
+
+       if (MokX) {
+               db_name = L"MokListX";
+               auth_name = L"MokXAuth";
+       } else {
+               db_name = L"MokList";
+               auth_name = L"MokAuth";
+       }
+
+       if (authenticate) {
+               efi_status = uefi_call_wrapper(RT->GetVariable, 5, auth_name,
+                                              &shim_lock_guid,
+                                              &attributes, &auth_size, auth);
+
+               if (efi_status != EFI_SUCCESS ||
+                   (auth_size != SHA256_DIGEST_SIZE &&
+                    auth_size != PASSWORD_CRYPT_SIZE)) {
+                       if (MokX)
+                               console_error(L"Failed to get MokXAuth", efi_status);
+                       else
+                               console_error(L"Failed to get MokAuth", efi_status);
+                       return efi_status;
+               }
+
+               if (auth_size == PASSWORD_CRYPT_SIZE) {
+                       efi_status = match_password((PASSWORD_CRYPT *)auth,
+                                                   NULL, 0, NULL, NULL);
+               } else {
+                       efi_status = match_password(NULL, MokNew, MokNewSize,
+                                                   auth, NULL);
+               }
+               if (efi_status != EFI_SUCCESS)
+                       return EFI_ACCESS_DENIED;
+       }
+
+       if (!MokNewSize) {
+               /* Delete MOK */
+               efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                              &shim_lock_guid,
+                                              EFI_VARIABLE_NON_VOLATILE
+                                              | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                              0, NULL);
+       } else {
+               /* Write new MOK */
+               efi_status = write_db(db_name, MokNew, MokNewSize);
+       }
+
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Failed to set variable", efi_status);
+               return efi_status;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static INTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth,
+                                   BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       CHAR16 *title;
+
+       if (MokX)
+               title = L"[Enroll MOKX]";
+       else
+               title = L"[Enroll MOK]";
+
+       if (list_keys(MokNew, MokNewSize, title) != EFI_SUCCESS)
+               return 0;
+
+       if (console_yes_no((CHAR16 *[]){L"Enroll the key(s)?", NULL}) == 0)
+               return 0;
+
+       efi_status = store_keys(MokNew, MokNewSize, auth, MokX);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Failed to enroll keys\n");
+               return -1;
+       }
+
+       if (auth) {
+               if (MokX) {
+                       LibDeleteVariable(L"MokXNew", &shim_lock_guid);
+                       LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+               } else {
+                       LibDeleteVariable(L"MokNew", &shim_lock_guid);
+                       LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+               }
+
+               console_notify(L"The system must now be rebooted");
+               uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+                                 EFI_SUCCESS, 0, NULL);
+               console_notify(L"Failed to reboot");
+               return -1;
+       }
+
+       return 0;
+}
+
+static INTN mok_reset_prompt (BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       CHAR16 *prompt;
+
+       uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+       if (MokX)
+               prompt = L"Erase all stored keys in MokListX?";
+       else
+               prompt = L"Erase all stored keys in MokList?";
+       if (console_yes_no((CHAR16 *[]){prompt, NULL }) == 0)
+               return 0;
+
+       efi_status = store_keys(NULL, 0, TRUE, MokX);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Failed to erase keys\n");
+               return -1;
+       }
+
+       if (MokX) {
+               LibDeleteVariable(L"MokXNew", &shim_lock_guid);
+               LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+       } else {
+               LibDeleteVariable(L"MokNew", &shim_lock_guid);
+               LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+       }
+
+       console_notify(L"The system must now be rebooted");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+                         EFI_SUCCESS, 0, NULL);
+       console_notify(L"Failed to reboot\n");
+       return -1;
+}
+
+static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num,
+                                      BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_GUID CertType = X509_GUID;
+       EFI_STATUS efi_status;
+       EFI_SIGNATURE_LIST *CertList;
+       EFI_SIGNATURE_DATA *CertData;
+       void *Data = NULL, *ptr;
+       INTN DataSize = 0;
+       int i;
+       CHAR16 *db_name;
+
+       if (MokX)
+               db_name = L"MokListX";
+       else
+               db_name = L"MokList";
+
+       for (i = 0; i < key_num; i++) {
+               if (list[i].Mok == NULL)
+                       continue;
+
+               DataSize += sizeof(EFI_SIGNATURE_LIST);
+               if (CompareGuid(&(list[i].Type), &CertType) == 0)
+                       DataSize += sizeof(EFI_GUID);
+               DataSize += list[i].MokSize;
+       }
+
+       Data = AllocatePool(DataSize);
+       if (Data == NULL && DataSize != 0)
+               return EFI_OUT_OF_RESOURCES;
+
+       ptr = Data;
+
+       for (i = 0; i < key_num; i++) {
+               if (list[i].Mok == NULL)
+                       continue;
+
+               CertList = (EFI_SIGNATURE_LIST *)ptr;
+               CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
+                          sizeof(EFI_SIGNATURE_LIST));
+
+               CertList->SignatureType = list[i].Type;
+               CertList->SignatureHeaderSize = 0;
+
+               if (CompareGuid(&(list[i].Type), &CertType) == 0) {
+                       CertList->SignatureListSize = list[i].MokSize +
+                                                     sizeof(EFI_SIGNATURE_LIST) +
+                                                     sizeof(EFI_GUID);
+                       CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID);
+
+                       CertData->SignatureOwner = shim_lock_guid;
+                       CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize);
+               } else {
+                       CertList->SignatureListSize = list[i].MokSize +
+                                                     sizeof(EFI_SIGNATURE_LIST);
+                       CertList->SignatureSize = sha_size(list[i].Type) + sizeof(EFI_GUID);
+
+                       CopyMem(CertData, list[i].Mok, list[i].MokSize);
+               }
+               ptr = (uint8_t *)ptr + CertList->SignatureListSize;
+       }
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                      &shim_lock_guid,
+                                      EFI_VARIABLE_NON_VOLATILE
+                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                      DataSize, Data);
+       if (Data)
+               FreePool(Data);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Failed to set variable", efi_status);
+               return efi_status;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static void delete_cert (void *key, UINT32 key_size,
+                        MokListNode *mok, INTN mok_num)
+{
+       EFI_GUID CertType = X509_GUID;
+       int i;
+
+       for (i = 0; i < mok_num; i++) {
+               if (CompareGuid(&(mok[i].Type), &CertType) != 0)
+                       continue;
+
+               if (mok[i].MokSize == key_size &&
+                   CompareMem(key, mok[i].Mok, key_size) == 0) {
+                       /* Remove the key */
+                       mok[i].Mok = NULL;
+                       mok[i].MokSize = 0;
+               }
+       }
+}
+
+static int match_hash (UINT8 *hash, UINT32 hash_size, int start,
+                      void *hash_list, UINT32 list_num)
+{
+       UINT8 *ptr;
+       UINTN i;
+
+       ptr = hash_list + sizeof(EFI_GUID);
+       for (i = start; i < list_num; i++) {
+               if (CompareMem(hash, ptr, hash_size) == 0)
+                       return i;
+               ptr += hash_size + sizeof(EFI_GUID);
+       }
+
+       return -1;
+}
+
+static void mem_move (void *dest, void *src, UINTN size)
+{
+       UINT8 *d, *s;
+       UINTN i;
+
+       d = (UINT8 *)dest;
+       s = (UINT8 *)src;
+       for (i = 0; i < size; i++)
+               d[i] = s[i];
+}
+
+static void delete_hash_in_list (EFI_GUID Type, UINT8 *hash, UINT32 hash_size,
+                                MokListNode *mok, INTN mok_num)
+{
+       UINT32 sig_size;
+       UINT32 list_num;
+       int i, del_ind;
+       void *start, *end;
+       UINT32 remain;
+
+       sig_size = hash_size + sizeof(EFI_GUID);
+
+       for (i = 0; i < mok_num; i++) {
+               if ((CompareGuid(&(mok[i].Type), &Type) != 0) ||
+                   (mok[i].MokSize < sig_size))
+                       continue;
+
+               list_num = mok[i].MokSize / sig_size;
+
+               del_ind = match_hash(hash, hash_size, 0, mok[i].Mok,
+                                    list_num);
+               while (del_ind >= 0) {
+                       /* Remove the hash */
+                       if (sig_size == mok[i].MokSize) {
+                               mok[i].Mok = NULL;
+                               mok[i].MokSize = 0;
+                               break;
+                       }
+
+                       start = mok[i].Mok + del_ind * sig_size;
+                       end = start + sig_size;
+                       remain = mok[i].MokSize - (del_ind + 1)*sig_size;
+
+                       mem_move(start, end, remain);
+                       mok[i].MokSize -= sig_size;
+                       list_num--;
+
+                       del_ind = match_hash(hash, hash_size, del_ind,
+                                            mok[i].Mok, list_num);
+               }
+       }
+}
+
+static void delete_hash_list (EFI_GUID Type, void *hash_list, UINT32 list_size,
+                             MokListNode *mok, INTN mok_num)
+{
+       UINT32 hash_size;
+       UINT32 hash_num;
+       UINT32 sig_size;
+       UINT8 *hash;
+       UINT32 i;
+
+       hash_size = sha_size (Type);
+       sig_size = hash_size + sizeof(EFI_GUID);
+       if (list_size < sig_size)
+               return;
+
+       hash_num = list_size / sig_size;
+
+       hash = hash_list + sizeof(EFI_GUID);
+
+       for (i = 0; i < hash_num; i++) {
+               delete_hash_in_list (Type, hash, hash_size, mok, mok_num);
+               hash += sig_size;
+       }
+}
+
+static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_GUID CertType = X509_GUID;
+       EFI_STATUS efi_status;
+       CHAR16 *db_name;
+       CHAR16 *auth_name;
+       CHAR16 *err_str1;
+       CHAR16 *err_str2;
+       UINT8 auth[PASSWORD_CRYPT_SIZE];
+       UINTN auth_size = PASSWORD_CRYPT_SIZE;
+       UINT32 attributes;
+       UINT8 *MokListData = NULL;
+       UINTN MokListDataSize = 0;
+       MokListNode *mok, *del_key;
+       INTN mok_num, del_num;
+       int i;
+
+       if (MokX) {
+               db_name = L"MokListX";
+               auth_name = L"MokXDelAuth";
+       } else {
+               db_name = L"MokList";
+               auth_name = L"MokDelAuth";
+       }
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, auth_name,
+                                      &shim_lock_guid,
+                                      &attributes, &auth_size, auth);
+
+       if (efi_status != EFI_SUCCESS ||
+           (auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
+               if (MokX)
+                       console_error(L"Failed to get MokXDelAuth", efi_status);
+               else
+                       console_error(L"Failed to get MokDelAuth", efi_status);
+               return efi_status;
+       }
+
+       if (auth_size == PASSWORD_CRYPT_SIZE) {
+               efi_status = match_password((PASSWORD_CRYPT *)auth, NULL, 0,
+                                           NULL, NULL);
+       } else {
+               efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
+       }
+       if (efi_status != EFI_SUCCESS)
+               return EFI_ACCESS_DENIED;
+
+       efi_status = get_variable_attr (db_name, &MokListData, &MokListDataSize,
+                                       shim_lock_guid, &attributes);
+       if (efi_status != EFI_SUCCESS) {
+               if (MokX)
+                       console_errorbox(L"Failed to retrieve MokListX");
+               else
+                       console_errorbox(L"Failed to retrieve MokList");
+               return EFI_ABORTED;
+       } else if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+               if (MokX) {
+                       err_str1 = L"MokListX is compromised!";
+                       err_str2 = L"Erase all keys in MokListX!";
+               } else {
+                       err_str1 = L"MokList is compromised!";
+                       err_str2 = L"Erase all keys in MokList!";
+               }
+               console_alertbox((CHAR16 *[]){err_str1, err_str2, NULL});
+               uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                 &shim_lock_guid,
+                                 EFI_VARIABLE_NON_VOLATILE |
+                                 EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                 0, NULL);
+               return EFI_ACCESS_DENIED;
+       }
+
+       /* Nothing to do */
+       if (!MokListData || MokListDataSize == 0)
+               return EFI_SUCCESS;
+
+       /* Construct lists */
+       mok_num = count_keys(MokListData, MokListDataSize);
+       if (mok_num == 0) {
+               if (MokX) {
+                       err_str1 = L"Failed to construct the key list of MokListX";
+                       err_str2 = L"Reset MokListX!";
+               } else {
+                       err_str1 = L"Failed to construct the key list of MokList";
+                       err_str2 = L"Reset MokList!";
+               }
+               console_alertbox((CHAR16 *[]){err_str1, err_str2, NULL});
+               uefi_call_wrapper(RT->SetVariable, 5, db_name,
+                                 &shim_lock_guid,
+                                 EFI_VARIABLE_NON_VOLATILE |
+                                 EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                 0, NULL);
+               efi_status = EFI_ABORTED;
+               goto error;
+       }
+       mok = build_mok_list(mok_num, MokListData, MokListDataSize);
+       if (!mok) {
+               console_errorbox(L"Failed to construct key list");
+               efi_status = EFI_ABORTED;
+               goto error;
+       }
+       del_num = count_keys(MokDel, MokDelSize);
+       if (del_num == 0) {
+               console_errorbox(L"Invalid key delete list");
+               efi_status = EFI_ABORTED;
+               goto error;
+       }
+       del_key = build_mok_list(del_num, MokDel, MokDelSize);
+       if (!del_key) {
+               console_errorbox(L"Failed to construct key list");
+               efi_status = EFI_ABORTED;
+               goto error;
+       }
+
+       /* Search and destroy */
+       for (i = 0; i < del_num; i++) {
+               if (CompareGuid(&(del_key[i].Type), &CertType) == 0) {
+                       delete_cert(del_key[i].Mok, del_key[i].MokSize,
+                                   mok, mok_num);
+               } else if (is_sha2_hash(del_key[i].Type)) {
+                       delete_hash_list(del_key[i].Type, del_key[i].Mok,
+                                        del_key[i].MokSize, mok, mok_num);
+               }
+       }
+
+       efi_status = write_back_mok_list(mok, mok_num, MokX);
+
+error:
+       if (MokListData)
+               FreePool(MokListData);
+       if (mok)
+               FreePool(mok);
+       if (del_key)
+               FreePool(del_key);
+
+       return efi_status;
+}
+
+static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       CHAR16 *title;
+
+       if (MokX)
+               title = L"[Delete MOKX]";
+       else
+               title = L"[Delete MOK]";
+
+       if (list_keys(MokDel, MokDelSize, title) != EFI_SUCCESS) {
+               return 0;
+       }
+
+        if (console_yes_no((CHAR16 *[]){L"Delete the key(s)?", NULL}) == 0)
+                return 0;
+
+       efi_status = delete_keys(MokDel, MokDelSize, MokX);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Failed to delete keys");
+               return -1;
+       }
+
+       if (MokX) {
+               LibDeleteVariable(L"MokXDel", &shim_lock_guid);
+               LibDeleteVariable(L"MokXDelAuth", &shim_lock_guid);
+       } else {
+               LibDeleteVariable(L"MokDel", &shim_lock_guid);
+               LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+       }
+
+       console_notify(L"The system must now be rebooted");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+                         EFI_SUCCESS, 0, NULL);
+       console_notify(L"Failed to reboot");
+       return -1;
+}
+
+static CHAR16 get_password_charater (CHAR16 *prompt)
+{
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       EFI_STATUS status;
+       CHAR16 *message[2];
+       CHAR16 character;
+       UINTN length;
+       UINT32 pw_length;
+
+       if (!prompt)
+               prompt = L"Password charater: ";
+
+       console_save_and_set_mode(&SavedMode);
+
+       message[0] = prompt;
+       message[1] = NULL;
+       length = StrLen(message[0]);
+       console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
+       status = get_line(&pw_length, &character, 1, 0);
+       if (EFI_ERROR(status))
+               character = 0;
+
+       console_restore_mode(&SavedMode);
+
+       return character;
+}
+
+static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       MokSBvar *var = MokSB;
+       CHAR16 *message[4];
+       CHAR16 pass1, pass2, pass3;
+       CHAR16 *str;
+       UINT8 fail_count = 0;
+       UINT8 sbval = 1;
+       UINT8 pos1, pos2, pos3;
+       int ret;
+
+       if (MokSBSize != sizeof(MokSBvar)) {
+               console_notify(L"Invalid MokSB variable contents");
+               return -1;
+       }
+
+       uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+       message[0] = L"Change Secure Boot state";
+       message[1] = NULL;
+
+       console_save_and_set_mode(&SavedMode);
+       console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+       console_restore_mode(&SavedMode);
+
+       while (fail_count < 3) {
+               RandomBytes (&pos1, sizeof(pos1));
+               pos1 = (pos1 % var->PWLen);
+
+               do {
+                       RandomBytes (&pos2, sizeof(pos2));
+                       pos2 = (pos2 % var->PWLen);
+               } while (pos2 == pos1);
+
+               do {
+                       RandomBytes (&pos3, sizeof(pos3));
+                       pos3 = (pos3 % var->PWLen) ;
+               } while (pos3 == pos2 || pos3 == pos1);
+
+               str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass1 = get_password_charater(str);
+               FreePool(str);
+
+               str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass2 = get_password_charater(str);
+               FreePool(str);
+
+               str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass3 = get_password_charater(str);
+               FreePool(str);
+
+               if (pass1 != var->Password[pos1] ||
+                   pass2 != var->Password[pos2] ||
+                   pass3 != var->Password[pos3]) {
+                       Print(L"Invalid character\n");
+                       fail_count++;
+               } else {
+                       break;
+               }
+       }
+
+       if (fail_count >= 3) {
+               console_notify(L"Password limit reached");
+               return -1;
+       }
+
+       if (var->MokSBState == 0)
+               ret = console_yes_no((CHAR16 *[]){L"Disable Secure Boot", NULL});
+       else
+               ret = console_yes_no((CHAR16 *[]){L"Enable Secure Boot", NULL});
+
+       if (ret == 0) {
+               LibDeleteVariable(L"MokSB", &shim_lock_guid);
+               return -1;
+       }
+
+       if (var->MokSBState == 0) {
+               efi_status = uefi_call_wrapper(RT->SetVariable,
+                                              5, L"MokSBState",
+                                              &shim_lock_guid,
+                                              EFI_VARIABLE_NON_VOLATILE |
+                                              EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                              1, &sbval);
+               if (efi_status != EFI_SUCCESS) {
+                       console_notify(L"Failed to set Secure Boot state");
+                       return -1;
+               }
+       } else {
+               efi_status = uefi_call_wrapper(RT->SetVariable,
+                                              5, L"MokSBState",
+                                              &shim_lock_guid,
+                                              EFI_VARIABLE_NON_VOLATILE |
+                                              EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                              0, NULL);
+               if (efi_status != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete Secure Boot state");
+                       return -1;
+               }
+       }
+
+       console_notify(L"The system must now be rebooted");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+                         EFI_SUCCESS, 0, NULL);
+       console_notify(L"Failed to reboot");
+       return -1;
+}
+
+static INTN mok_db_prompt (void *MokDB, UINTN MokDBSize) {
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       MokDBvar *var = MokDB;
+       CHAR16 *message[4];
+       CHAR16 pass1, pass2, pass3;
+       CHAR16 *str;
+       UINT8 fail_count = 0;
+       UINT8 dbval = 1;
+       UINT8 pos1, pos2, pos3;
+       int ret;
+
+       if (MokDBSize != sizeof(MokDBvar)) {
+               console_notify(L"Invalid MokDB variable contents");
+               return -1;
+       }
+
+       uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+       message[0] = L"Change DB state";
+       message[1] = NULL;
+
+       console_save_and_set_mode(&SavedMode);
+       console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+       console_restore_mode(&SavedMode);
+
+       while (fail_count < 3) {
+               RandomBytes (&pos1, sizeof(pos1));
+               pos1 = (pos1 % var->PWLen);
+
+               do {
+                       RandomBytes (&pos2, sizeof(pos2));
+                       pos2 = (pos2 % var->PWLen);
+               } while (pos2 == pos1);
+
+               do {
+                       RandomBytes (&pos3, sizeof(pos3));
+                       pos3 = (pos3 % var->PWLen) ;
+               } while (pos3 == pos2 || pos3 == pos1);
+
+               str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass1 = get_password_charater(str);
+               FreePool(str);
+
+               str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass2 = get_password_charater(str);
+               FreePool(str);
+
+               str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
+               if (!str) {
+                       console_errorbox(L"Failed to allocate buffer");
+                       return -1;
+               }
+               pass3 = get_password_charater(str);
+               FreePool(str);
+
+               if (pass1 != var->Password[pos1] ||
+                   pass2 != var->Password[pos2] ||
+                   pass3 != var->Password[pos3]) {
+                       Print(L"Invalid character\n");
+                       fail_count++;
+               } else {
+                       break;
+               }
+       }
+
+       if (fail_count >= 3) {
+               console_notify(L"Password limit reached");
+               return -1;
+       }
+
+       if (var->MokDBState == 0)
+               ret = console_yes_no((CHAR16 *[]){L"Ignore DB certs/hashes", NULL});
+       else
+               ret = console_yes_no((CHAR16 *[]){L"Use DB certs/hashes", NULL});
+
+       if (ret == 0) {
+               LibDeleteVariable(L"MokDB", &shim_lock_guid);
+               return -1;
+       }
+
+       if (var->MokDBState == 0) {
+               efi_status = uefi_call_wrapper(RT->SetVariable,
+                                              5, L"MokDBState",
+                                              &shim_lock_guid,
+                                              EFI_VARIABLE_NON_VOLATILE |
+                                              EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                              1, &dbval);
+               if (efi_status != EFI_SUCCESS) {
+                       console_notify(L"Failed to set DB state");
+                       return -1;
+               }
+       } else {
+               efi_status = uefi_call_wrapper(RT->SetVariable, 5,
+                                              L"MokDBState",
+                                              &shim_lock_guid,
+                                              EFI_VARIABLE_NON_VOLATILE |
+                                              EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                              0, NULL);
+               if (efi_status != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete DB state");
+                       return -1;
+               }
+       }
+
+       console_notify(L"The system must now be rebooted");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+                         EFI_SUCCESS, 0, NULL);
+       console_notify(L"Failed to reboot");
+       return -1;
+}
+
+static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       UINT8 hash[PASSWORD_CRYPT_SIZE];
+       UINT8 clear = 0;
+
+       if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) {
+               console_notify(L"Invalid MokPW variable contents");
+               return -1;
+       }
+
+       uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+       SetMem(hash, PASSWORD_CRYPT_SIZE, 0);
+
+       if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+               if (CompareMem(MokPW, hash, PASSWORD_CRYPT_SIZE) == 0)
+                       clear = 1;
+       } else {
+               if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
+                       clear = 1;
+       }
+
+       if (clear) {
+               if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0)
+                       return 0;
+
+               uefi_call_wrapper(RT->SetVariable, 5, L"MokPWStore",
+                                 &shim_lock_guid,
+                                 EFI_VARIABLE_NON_VOLATILE
+                                 | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                 0, NULL);
+               LibDeleteVariable(L"MokPW", &shim_lock_guid);
+               console_notify(L"The system must now be rebooted");
+               uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0,
+                                 NULL);
+               console_notify(L"Failed to reboot");
+               return -1;
+       }
+
+       if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+               efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0,
+                                           NULL, L"Confirm MOK passphrase: ");
+       } else {
+               efi_status = match_password(NULL, NULL, 0, MokPW,
+                                           L"Confirm MOK passphrase: ");
+       }
+
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Password limit reached");
+               return -1;
+       }
+
+       if (console_yes_no((CHAR16 *[]){L"Set MOK password?", NULL}) == 0)
+               return 0;
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5,
+                                      L"MokPWStore",
+                                      &shim_lock_guid,
+                                      EFI_VARIABLE_NON_VOLATILE |
+                                      EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                      MokPWSize, MokPW);
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Failed to set MOK password");
+               return -1;
+       }
+
+       LibDeleteVariable(L"MokPW", &shim_lock_guid);
+
+       console_notify(L"The system must now be rebooted");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0,
+                         NULL);
+       console_notify(L"Failed to reboot");
+       return -1;
+}
+
+static BOOLEAN verify_certificate(UINT8 *cert, UINTN size)
+{
+       X509 *X509Cert;
+       UINTN length;
+       if (!cert || size < 0)
+               return FALSE;
+
+       /*
+        * A DER encoding x509 certificate starts with SEQUENCE(0x30),
+        * the number of length bytes, and the number of value bytes.
+        * The size of a x509 certificate is usually between 127 bytes
+        * and 64KB. For convenience, assume the number of value bytes
+        * is 2, i.e. the second byte is 0x82.
+        */
+       if (cert[0] != 0x30 || cert[1] != 0x82) {
+               console_notify(L"Not a DER encoding X509 certificate");
+               return FALSE;
+       }
+
+       length = (cert[2]<<8 | cert[3]);
+       if (length != (size - 4)) {
+               console_notify(L"Invalid X509 certificate: Inconsistent size");
+               return FALSE;
+       }
+
+       if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) ||
+           X509Cert == NULL) {
+               console_notify(L"Invalid X509 certificate");
+               return FALSE;
+       }
+
+       X509_free(X509Cert);
+       return TRUE;
+}
+
+static EFI_STATUS enroll_file (void *data, UINTN datasize, BOOLEAN hash)
+{
+       EFI_STATUS status = EFI_SUCCESS;
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_SIGNATURE_LIST *CertList;
+       EFI_SIGNATURE_DATA *CertData;
+       UINTN mokbuffersize;
+       void *mokbuffer = NULL;
+
+       if (hash) {
+               UINT8 sha256[SHA256_DIGEST_SIZE];
+               UINT8 sha1[SHA1_DIGEST_SIZE];
+               SHIM_LOCK *shim_lock;
+               EFI_GUID shim_guid = SHIM_LOCK_GUID;
+               PE_COFF_LOADER_IMAGE_CONTEXT context;
+       
+               status = LibLocateProtocol(&shim_guid, (VOID **)&shim_lock);
+
+               if (status != EFI_SUCCESS)
+                       goto out;
+
+               mokbuffersize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) +
+                       SHA256_DIGEST_SIZE;
+
+               mokbuffer = AllocatePool(mokbuffersize);
+
+               if (!mokbuffer)
+                       goto out;
+
+               status = shim_lock->Context(data, datasize, &context);
+
+               if (status != EFI_SUCCESS)
+                       goto out;
+       
+               status = shim_lock->Hash(data, datasize, &context, sha256,
+                                        sha1);
+
+               if (status != EFI_SUCCESS)
+                       goto out;
+
+               CertList = mokbuffer;
+               CertList->SignatureType = EFI_CERT_SHA256_GUID;
+               CertList->SignatureSize = 16 + SHA256_DIGEST_SIZE;
+               CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) +
+                                                 sizeof(EFI_SIGNATURE_LIST));
+               CopyMem(CertData->SignatureData, sha256, SHA256_DIGEST_SIZE);
+       } else {
+               mokbuffersize = datasize + sizeof(EFI_SIGNATURE_LIST) +
+                       sizeof(EFI_GUID);
+               mokbuffer = AllocatePool(mokbuffersize);
+
+               if (!mokbuffer)
+                       goto out;
+
+               CertList = mokbuffer;
+               CertList->SignatureType = X509_GUID;
+               CertList->SignatureSize = 16 + datasize;
+
+               memcpy(mokbuffer + sizeof(EFI_SIGNATURE_LIST) + 16, data,
+                      datasize);
+
+               CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) +
+                                                 sizeof(EFI_SIGNATURE_LIST));
+       }
+
+       CertList->SignatureListSize = mokbuffersize;
+       CertList->SignatureHeaderSize = 0;
+       CertData->SignatureOwner = shim_lock_guid;
+
+       if (!hash) {
+               if (!verify_certificate(CertData->SignatureData, datasize))
+                       goto out;
+       }
+
+       mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE, FALSE);
+out:
+       if (mokbuffer)
+               FreePool(mokbuffer);
+
+       return status;
+}
+
+static void mok_hash_enroll(void)
+{
+       EFI_STATUS efi_status;
+        CHAR16 *file_name = NULL;
+       EFI_HANDLE im = NULL;
+       EFI_FILE *file = NULL;
+       UINTN filesize;
+       void *data;
+
+       simple_file_selector(&im, (CHAR16 *[]){
+      L"Select Binary",
+      L"",
+      L"The Selected Binary will have its hash Enrolled",
+      L"This means it will Subsequently Boot with no prompting",
+      L"Remember to make sure it is a genuine binary before Enroling its hash",
+      NULL
+             }, L"\\", L"", &file_name);
+
+       if (!file_name)
+               return;
+
+       efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Unable to open file", efi_status);
+               return;
+       }
+
+       simple_file_read_all(file, &filesize, &data);
+       simple_file_close(file);
+
+       if (!filesize) {
+               console_error(L"Unable to read file", efi_status);
+               return;
+       }
+
+       efi_status = enroll_file(data, filesize, TRUE);
+
+       if (efi_status != EFI_SUCCESS)
+               console_error(L"Hash failed (did you select a valid EFI binary?)", efi_status);
+
+       FreePool(data);
+}
+
+static CHAR16 *der_suffix[] = {
+       L".cer",
+       L".der",
+       L".crt",
+       NULL
+};
+
+static BOOLEAN check_der_suffix (CHAR16 *file_name)
+{
+       CHAR16 suffix[5];
+       int i;
+
+       if (!file_name || StrLen(file_name) <= 4)
+               return FALSE;
+
+       suffix[0] = '\0';
+       StrCat(suffix, file_name + StrLen(file_name) - 4);
+
+       StrLwr (suffix);
+       for (i = 0; der_suffix[i] != NULL; i++) {
+               if (StrCmp(suffix, der_suffix[i]) == 0) {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+static void mok_key_enroll(void)
+{
+       EFI_STATUS efi_status;
+        CHAR16 *file_name = NULL;
+       EFI_HANDLE im = NULL;
+       EFI_FILE *file = NULL;
+       UINTN filesize;
+       void *data;
+
+       simple_file_selector(&im, (CHAR16 *[]){
+      L"Select Key",
+      L"",
+      L"The selected key will be enrolled into the MOK database",
+      L"This means any binaries signed with it will be run without prompting",
+      L"Remember to make sure it is a genuine key before Enroling it",
+      NULL
+             }, L"\\", L"", &file_name);
+
+       if (!file_name)
+               return;
+
+       if (!check_der_suffix(file_name)) {
+               console_alertbox((CHAR16 *[]){
+                       L"Unsupported Format",
+                       L"",
+                       L"Only DER encoded certificate (*.cer/der/crt) is supported",
+                       NULL});
+               return;
+       }
+
+       efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Unable to open file", efi_status);
+               return;
+       }
+
+       simple_file_read_all(file, &filesize, &data);
+       simple_file_close(file);
+
+       if (!filesize) {
+               console_error(L"Unable to read file", efi_status);
+               return;
+       }
+
+       enroll_file(data, filesize, FALSE);
+       FreePool(data);
+}
+
+static BOOLEAN verify_pw(BOOLEAN *protected)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       UINT8 pwhash[PASSWORD_CRYPT_SIZE];
+       UINTN size = PASSWORD_CRYPT_SIZE;
+       UINT32 attributes;
+       CHAR16 *message[2];
+
+       *protected = FALSE;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
+                                      &shim_lock_guid, &attributes, &size,
+                                      pwhash);
+
+       /*
+        * If anything can attack the password it could just set it to a
+        * known value, so there's no safety advantage in failing to validate
+        * purely because of a failure to read the variable
+        */
+       if (efi_status != EFI_SUCCESS ||
+           (size != SHA256_DIGEST_SIZE && size != PASSWORD_CRYPT_SIZE))
+               return TRUE;
+
+       if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
+               return TRUE;
+
+       uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+       /* Draw the background */
+       console_save_and_set_mode(&SavedMode);
+       message[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
+       message[1] = NULL;
+       console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+       FreePool(message[0]);
+       console_restore_mode(&SavedMode);
+
+       if (size == PASSWORD_CRYPT_SIZE) {
+               efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0,
+                                           NULL, L"Enter MOK password:");
+       } else {
+               efi_status = match_password(NULL, NULL, 0, pwhash,
+                                           L"Enter MOK password:");
+       }
+       if (efi_status != EFI_SUCCESS) {
+               console_notify(L"Password limit reached");
+               return FALSE;
+       }
+
+       *protected = TRUE;
+
+       return TRUE;
+}
+
+static int draw_countdown()
+{
+       SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+       EFI_INPUT_KEY key;
+       EFI_STATUS status;
+       UINTN cols, rows;
+       CHAR16 *title[2];
+       CHAR16 *message =  L"Press any key to perform MOK management";
+       int timeout = 10, wait = 10000000;
+
+       console_save_and_set_mode (&SavedMode);
+
+       title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
+       title[1] = NULL;
+
+       console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1);
+
+       uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+                         ST->ConOut->Mode->Mode, &cols, &rows);
+
+       PrintAt((cols - StrLen(message))/2, rows/2, message);
+       while (1) {
+               if (timeout > 1)
+                       PrintAt(2, rows - 3, L"Booting in %d seconds  ", timeout);
+               else if (timeout)
+                       PrintAt(2, rows - 3, L"Booting in %d second   ", timeout);
+
+               status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait);
+
+               if (status != EFI_TIMEOUT) {
+                       /* Clear the key in the queue */
+                       uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
+                                         ST->ConIn, &key);
+                       break;
+               }
+
+               timeout--;
+               if (!timeout)
+                       break;
+       }
+
+       FreePool(title[0]);
+
+       console_restore_mode(&SavedMode);
+
+       return timeout;
+}
+
+typedef enum {
+       MOK_CONTINUE_BOOT,
+       MOK_RESET_MOK,
+       MOK_RESET_MOKX,
+       MOK_ENROLL_MOK,
+       MOK_ENROLL_MOKX,
+       MOK_DELETE_MOK,
+       MOK_DELETE_MOKX,
+       MOK_CHANGE_SB,
+       MOK_SET_PW,
+       MOK_CHANGE_DB,
+       MOK_KEY_ENROLL,
+       MOK_HASH_ENROLL
+} mok_menu_item;
+
+static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
+                                void *MokNew, UINTN MokNewSize,
+                                void *MokDel, UINTN MokDelSize,
+                                void *MokSB, UINTN MokSBSize,
+                                void *MokPW, UINTN MokPWSize,
+                                void *MokDB, UINTN MokDBSize,
+                                void *MokXNew, UINTN MokXNewSize,
+                                void *MokXDel, UINTN MokXDelSize)
+{
+       CHAR16 **menu_strings;
+       mok_menu_item *menu_item;
+       int choice = 0;
+       UINT32 MokAuth = 0;
+       UINT32 MokDelAuth = 0;
+       UINT32 MokXAuth = 0;
+       UINT32 MokXDelAuth = 0;
+       UINTN menucount = 3, i = 0;
+       EFI_STATUS efi_status;
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       UINT8 auth[PASSWORD_CRYPT_SIZE];
+       UINTN auth_size = PASSWORD_CRYPT_SIZE;
+       UINT32 attributes;
+       BOOLEAN protected;
+       EFI_STATUS ret = EFI_SUCCESS;
+
+       if (verify_pw(&protected) == FALSE)
+               return EFI_ACCESS_DENIED;
+       
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
+                                              &shim_lock_guid,
+                                              &attributes, &auth_size, auth);
+
+       if ((efi_status == EFI_SUCCESS) &&
+           (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+               MokAuth = 1;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+                                              &shim_lock_guid,
+                                              &attributes, &auth_size, auth);
+
+       if ((efi_status == EFI_SUCCESS) &&
+          (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+               MokDelAuth = 1;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokXAuth",
+                                              &shim_lock_guid,
+                                              &attributes, &auth_size, auth);
+
+       if ((efi_status == EFI_SUCCESS) &&
+           (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+               MokXAuth = 1;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokXDelAuth",
+                                              &shim_lock_guid,
+                                              &attributes, &auth_size, auth);
+
+       if ((efi_status == EFI_SUCCESS) &&
+          (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+               MokXDelAuth = 1;
+
+       if (MokNew || MokAuth)
+               menucount++;
+
+       if (MokDel || MokDelAuth)
+               menucount++;
+
+       if (MokXNew || MokXAuth)
+               menucount++;
+
+       if (MokXDel || MokXDelAuth)
+               menucount++;
+
+       if (MokSB)
+               menucount++;
+
+       if (MokPW)
+               menucount++;
+
+       if (MokDB)
+               menucount++;
+
+       menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (menucount + 1));
+
+       if (!menu_strings)
+               return EFI_OUT_OF_RESOURCES;
+
+       menu_item = AllocateZeroPool(sizeof(mok_menu_item) * menucount);
+
+       if (!menu_item) {
+               FreePool(menu_strings);
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       menu_strings[i] = L"Continue boot";
+       menu_item[i] = MOK_CONTINUE_BOOT;
+
+       i++;
+
+       if (MokNew || MokAuth) {
+               if (!MokNew) {
+                       menu_strings[i] = L"Reset MOK";
+                       menu_item[i] = MOK_RESET_MOK;
+               } else {
+                       menu_strings[i] = L"Enroll MOK";
+                       menu_item[i] = MOK_ENROLL_MOK;
+               }
+               i++;
+       }
+
+       if (MokDel || MokDelAuth) {
+               menu_strings[i] = L"Delete MOK";
+               menu_item[i] = MOK_DELETE_MOK;
+               i++;
+       }
+
+       if (MokXNew || MokXAuth) {
+               if (!MokXNew) {
+                       menu_strings[i] = L"Reset MOKX";
+                       menu_item[i] = MOK_RESET_MOKX;
+               } else {
+                       menu_strings[i] = L"Enroll MOKX";
+                       menu_item[i] = MOK_ENROLL_MOKX;
+               }
+               i++;
+       }
+
+       if (MokXDel || MokXDelAuth) {
+               menu_strings[i] = L"Delete MOKX";
+               menu_item[i] = MOK_DELETE_MOKX;
+               i++;
+       }
+
+       if (MokSB) {
+               menu_strings[i] = L"Change Secure Boot state";
+               menu_item[i] = MOK_CHANGE_SB;
+               i++;
+       }
+
+       if (MokPW) {
+               menu_strings[i] = L"Set MOK password";
+               menu_item[i] = MOK_SET_PW;
+               i++;
+       }
+
+       if (MokDB) {
+               menu_strings[i] = L"Change DB state";
+               menu_item[i] = MOK_CHANGE_DB;
+               i++;
+       }
+
+       menu_strings[i] = L"Enroll key from disk";
+       menu_item[i] = MOK_KEY_ENROLL;
+       i++;
+
+       menu_strings[i] = L"Enroll hash from disk";
+       menu_item[i] = MOK_HASH_ENROLL;
+       i++;
+
+       menu_strings[i] = NULL;
+
+       if (protected == FALSE && draw_countdown() == 0)
+               goto out;
+
+       while (choice >= 0) {
+               choice = console_select((CHAR16 *[]){ L"Perform MOK management", NULL },
+                                       menu_strings, 0);
+
+               if (choice < 0)
+                       goto out;
+
+               switch (menu_item[choice]) {
+               case MOK_CONTINUE_BOOT:
+                       goto out;
+               case MOK_RESET_MOK:
+                       mok_reset_prompt(FALSE);
+                       break;
+               case MOK_ENROLL_MOK:
+                       mok_enrollment_prompt(MokNew, MokNewSize, TRUE, FALSE);
+                       break;
+               case MOK_DELETE_MOK:
+                       mok_deletion_prompt(MokDel, MokDelSize, FALSE);
+                       break;
+               case MOK_RESET_MOKX:
+                       mok_reset_prompt(TRUE);
+                       break;
+               case MOK_ENROLL_MOKX:
+                       mok_enrollment_prompt(MokXNew, MokXNewSize, TRUE, TRUE);
+                       break;
+               case MOK_DELETE_MOKX:
+                       mok_deletion_prompt(MokXDel, MokXDelSize, TRUE);
+                       break;
+               case MOK_CHANGE_SB:
+                       mok_sb_prompt(MokSB, MokSBSize);
+                       break;
+               case MOK_SET_PW:
+                       mok_pw_prompt(MokPW, MokPWSize);
+                       break;
+               case MOK_CHANGE_DB:
+                       mok_db_prompt(MokDB, MokDBSize);
+                       break;
+               case MOK_KEY_ENROLL:
+                       mok_key_enroll();
+                       break;
+               case MOK_HASH_ENROLL:
+                       mok_hash_enroll();
+                       break;
+               }
+       }
+
+out:
+       console_reset();
+
+       FreePool(menu_strings);
+
+       if (menu_item)
+               FreePool(menu_item);
+
+       return ret;
+}
+
+static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0;
+       UINTN MokDBSize = 0, MokXNewSize = 0, MokXDelSize = 0;
+       void *MokNew = NULL;
+       void *MokDel = NULL;
+       void *MokSB = NULL;
+       void *MokPW = NULL;
+       void *MokDB = NULL;
+       void *MokXNew = NULL;
+       void *MokXDel = NULL;
+       EFI_STATUS status;
+
+       status = get_variable(L"MokNew", (UINT8 **)&MokNew, &MokNewSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokNew");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokNew", status);
+       }
+
+       status = get_variable(L"MokDel", (UINT8 **)&MokDel, &MokDelSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokDel", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokDel");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokDel", status);
+       }
+
+       status = get_variable(L"MokSB", (UINT8 **)&MokSB, &MokSBSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokSB");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokSB", status);
+       }
+
+       status = get_variable(L"MokPW", (UINT8 **)&MokPW, &MokPWSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokPW", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokPW");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokPW", status);
+       }
+
+       status = get_variable(L"MokDB", (UINT8 **)&MokDB, &MokDBSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokDB", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokDB");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokDB", status);
+       }
+
+       status = get_variable(L"MokXNew", (UINT8 **)&MokXNew, &MokXNewSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokXNew", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokXNew");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokXNew", status);
+       }
+
+       status = get_variable(L"MokXDel", (UINT8 **)&MokXDel, &MokXDelSize,
+                               shim_lock_guid);
+       if (status == EFI_SUCCESS) {
+               if (LibDeleteVariable(L"MokXDel", &shim_lock_guid) != EFI_SUCCESS) {
+                       console_notify(L"Failed to delete MokXDel");
+               }
+       } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+               console_error(L"Could not retrieve MokXDel", status);
+       }
+
+       enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
+                      MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize,
+                      MokXNew, MokXNewSize, MokXDel, MokXDelSize);
+
+       if (MokNew)
+               FreePool (MokNew);
+
+       if (MokDel)
+               FreePool (MokDel);
+
+       if (MokSB)
+               FreePool (MokSB);
+
+       if (MokPW)
+               FreePool (MokPW);
+
+       if (MokDB)
+               FreePool (MokDB);
+
+       if (MokXNew)
+               FreePool (MokXNew);
+
+       if (MokXDel)
+               FreePool (MokXDel);
+
+       LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+       LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+       LibDeleteVariable(L"MokXAuth", &shim_lock_guid);
+       LibDeleteVariable(L"MokXDelAuth", &shim_lock_guid);
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS setup_rand (void)
+{
+       EFI_TIME time;
+       EFI_STATUS efi_status;
+       UINT64 seed;
+       BOOLEAN status;
+
+       efi_status = uefi_call_wrapper(RT->GetTime, 2, &time, NULL);
+
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       seed = ((UINT64)time.Year << 48) | ((UINT64)time.Month << 40) |
+               ((UINT64)time.Day << 32) | ((UINT64)time.Hour << 24) |
+               ((UINT64)time.Minute << 16) | ((UINT64)time.Second << 8) |
+               ((UINT64)time.Daylight);
+
+       status = RandomSeed((UINT8 *)&seed, sizeof(seed));
+
+       if (!status)
+               return EFI_ABORTED;
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
+{
+       EFI_STATUS efi_status;
+
+       InitializeLib(image_handle, systab);
+
+       setup_console(1);
+
+       setup_rand();
+
+       efi_status = check_mok_request(image_handle);
+
+       setup_console(0);
+       return efi_status;
+}
diff --git a/MokVars.txt b/MokVars.txt
new file mode 100644 (file)
index 0000000..cac5349
--- /dev/null
@@ -0,0 +1,74 @@
+Variables used by Shim and Mokmanager
+
+Request variables:
+
+MokPW: Set by MokUtil when setting a password. A SHA-256 hash of the 
+UCS-2 representation of the password. The user will be asked to 
+re-enter the password to confirm. If the hash of the entered password 
+matches the contents of MokPW, the user will be prompted to copy MokPW 
+into MokPWState. BS,RT,NV
+
+MokSB: Set by MokUtil when requesting a change in state of signature 
+validation. A packed structure as follows:
+
+typedef struct {
+        UINT32 MokSBState;
+        UINT32 PWLen;
+        CHAR16 Password[PASSWORD_MAX];
+} __attribute__ ((packed)) MokSBvar;
+
+If MokSBState is 0, the user will be prompted to disable signature 
+validation. Otherwise, the user will be prompted to enable it. PWLen 
+is the length of the password, in characters. Password is a UCS-2 
+representation of the password. The user will be prompted to enter 
+three randomly chosen characters from the password. If successful, 
+they will then be prompted to change the signature validation 
+according to MokSBState. BS,RT,NV
+
+MokDB: Set by MokUtil when requesting a change in state of validation 
+using db hashes and certs. A packed structure as follows:
+
+typedef struct {
+        UINT32 MokDBState;
+        UINT32 PWLen;
+        CHAR16 Password[PASSWORD_MAX];
+} __attribute__ ((packed)) MokDBvar;
+
+If MokDBState is 0, the user will be prompted to disable usage of db for 
+validation. Otherwise, the user will be prompted to allow it. PWLen 
+is the length of the password, in characters. Password is a UCS-2 
+representation of the password. The user will be prompted to enter 
+three randomly chosen characters from the password. If successful, 
+they will then be prompted to change the signature validation 
+according to MokDBState. BS,RT,NV
+
+MokNew: Set by MokUtil when requesting the addition or removal of keys 
+from MokList. Is an EFI_SIGNATURE_LIST as described in the UEFI 
+specification. BS,RT,NV
+
+MokAuth: A hash dependent upon the contents of MokNew and the sealing 
+password. The user's password in UCS-2 form should be appended to the 
+contents of MokNew and a SHA-256 hash generated and stored in MokAuth. 
+The hash will be regenerated by MokManager after the user is requested 
+to enter their password to confirm enrolment of the keys. If the hash 
+matches MokAuth, the user will be prompted to enrol the keys. BS,RT,NV
+
+State variables:
+
+MokList: A list of whitelisted keys and hashes. An EFI_SIGNATURE_LIST 
+as described in the UEFI specification. BS,NV
+
+MokListRT: A copy of MokList made available to the kernel at runtime. RT
+
+MokSBState: An 8-bit unsigned integer. If 1, shim will switch to 
+insecure mode. BS,NV
+
+MokDBState: An 8-bit unsigned integer. If 1, shim will not use db for 
+verification. BS,NV
+
+MokIgnoreDB: An 8-bit unsigned integer.  This allows the OS to query whether
+or not to import DB certs for its own verification purposes.
+
+MokPWStore: A SHA-256 representation of the password set by the user 
+via MokPW. The user will be prompted to enter this password in order 
+to interact with MokManager.
diff --git a/PasswordCrypt.c b/PasswordCrypt.c
new file mode 100644 (file)
index 0000000..e0a82cf
--- /dev/null
@@ -0,0 +1,342 @@
+#include <efi.h>
+#include <efilib.h>
+#include <Library/BaseCryptLib.h>
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+#include <openssl/des.h>
+#include "PasswordCrypt.h"
+#include "crypt_blowfish.h"
+
+#define TRAD_DES_HASH_SIZE 13 /* (64/6+1) + (12/6) */
+#define BSDI_DES_HASH_SIZE 20 /* (64/6+1) + (24/6) + 4 + 1 */
+#define BLOWFISH_HASH_SIZE 31 /* 184/6+1 */
+
+UINT16 get_hash_size (const UINT16 method)
+{
+       switch (method) {
+       case TRADITIONAL_DES:
+               return TRAD_DES_HASH_SIZE;
+       case EXTEND_BSDI_DES:
+               return BSDI_DES_HASH_SIZE;
+       case MD5_BASED:
+               return MD5_DIGEST_LENGTH;
+       case SHA256_BASED:
+               return SHA256_DIGEST_LENGTH;
+       case SHA512_BASED:
+               return SHA512_DIGEST_LENGTH;
+       case BLOWFISH_BASED:
+               return BLOWFISH_HASH_SIZE;
+       }
+
+       return 0;
+}
+
+static EFI_STATUS trad_des_crypt (const char *key, const char *salt, UINT8 *hash)
+{
+       char result[TRAD_DES_HASH_SIZE + 1];
+       char *ret;
+
+       ret = DES_fcrypt(key, salt, result);
+       if (ret) {
+               CopyMem(hash, result, TRAD_DES_HASH_SIZE);
+               return EFI_SUCCESS;
+       }
+
+       return EFI_UNSUPPORTED;
+}
+
+static const char md5_salt_prefix[] = "$1$";
+
+static EFI_STATUS md5_crypt (const char *key,  UINT32 key_len,
+                            const char *salt, UINT32 salt_size,
+                            UINT8 *hash)
+{
+       MD5_CTX ctx, alt_ctx;
+       UINT8 alt_result[MD5_DIGEST_LENGTH];
+       UINTN cnt;
+
+       MD5_Init(&ctx);
+       MD5_Update(&ctx, key, key_len);
+       MD5_Update(&ctx, md5_salt_prefix, sizeof(md5_salt_prefix) - 1);
+       MD5_Update(&ctx, salt, salt_size);
+
+       MD5_Init(&alt_ctx);
+       MD5_Update(&alt_ctx, key, key_len);
+       MD5_Update(&alt_ctx, salt, salt_size);
+       MD5_Update(&alt_ctx, key, key_len);
+       MD5_Final(alt_result, &alt_ctx);
+
+       for (cnt = key_len; cnt > 16; cnt -= 16)
+               MD5_Update(&ctx, alt_result, 16);
+       MD5_Update(&ctx, alt_result, cnt);
+
+       *alt_result = '\0';
+
+       for (cnt = key_len; cnt > 0; cnt >>= 1) {
+               if ((cnt & 1) != 0) {
+                       MD5_Update(&ctx, alt_result, 1);
+               } else {
+                       MD5_Update(&ctx, key, 1);
+               }
+       }
+       MD5_Final(alt_result, &ctx);
+
+       for (cnt = 0; cnt < 1000; ++cnt) {
+               MD5_Init(&ctx);
+
+               if ((cnt & 1) != 0)
+                       MD5_Update(&ctx, key, key_len);
+               else
+                       MD5_Update(&ctx, alt_result, 16);
+
+               if (cnt % 3 != 0)
+                       MD5_Update(&ctx, salt, salt_size);
+
+               if (cnt % 7 != 0)
+                       MD5_Update(&ctx, key, key_len);
+
+               if ((cnt & 1) != 0)
+                       MD5_Update(&ctx, alt_result, 16);
+               else
+                       MD5_Update(&ctx, key, key_len);
+
+               MD5_Final(alt_result, &ctx);
+       }
+
+       CopyMem(hash, alt_result, MD5_DIGEST_LENGTH);
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS sha256_crypt (const char *key,  UINT32 key_len,
+                               const char *salt, UINT32 salt_size,
+                               const UINT32 rounds, UINT8 *hash)
+{
+       SHA256_CTX ctx, alt_ctx;
+       UINT8 alt_result[SHA256_DIGEST_SIZE];
+       UINT8 tmp_result[SHA256_DIGEST_SIZE];
+       UINT8 *cp, *p_bytes, *s_bytes;
+       UINTN cnt;
+
+       SHA256_Init(&ctx);
+       SHA256_Update(&ctx, key, key_len);
+       SHA256_Update(&ctx, salt, salt_size);
+
+       SHA256_Init(&alt_ctx);
+       SHA256_Update(&alt_ctx, key, key_len);
+       SHA256_Update(&alt_ctx, salt, salt_size);
+       SHA256_Update(&alt_ctx, key, key_len);
+       SHA256_Final(alt_result, &alt_ctx);
+
+       for (cnt = key_len; cnt > 32; cnt -= 32)
+               SHA256_Update(&ctx, alt_result, 32);
+       SHA256_Update(&ctx, alt_result, cnt);
+
+       for (cnt = key_len; cnt > 0; cnt >>= 1) {
+               if ((cnt & 1) != 0) {
+                       SHA256_Update(&ctx, alt_result, 32);
+               } else {
+                       SHA256_Update(&ctx, key, key_len);
+               }
+       }
+       SHA256_Final(alt_result, &ctx);
+
+       SHA256_Init(&alt_ctx);
+       for (cnt = 0; cnt < key_len; ++cnt)
+               SHA256_Update(&alt_ctx, key, key_len);
+       SHA256_Final(tmp_result, &alt_ctx);
+
+       cp = p_bytes = AllocatePool(key_len);
+       for (cnt = key_len; cnt >= 32; cnt -= 32) {
+               CopyMem(cp, tmp_result, 32);
+               cp += 32;
+       }
+       CopyMem(cp, tmp_result, cnt);
+
+       SHA256_Init(&alt_ctx);
+       for (cnt = 0; cnt < 16ul + alt_result[0]; ++cnt)
+               SHA256_Update(&alt_ctx, salt, salt_size);
+       SHA256_Final(tmp_result, &alt_ctx);
+
+       cp = s_bytes = AllocatePool(salt_size);
+       for (cnt = salt_size; cnt >= 32; cnt -= 32) {
+               CopyMem(cp, tmp_result, 32);
+               cp += 32;
+       }
+       CopyMem(cp, tmp_result, cnt);
+
+       for (cnt = 0; cnt < rounds; ++cnt) {
+               SHA256_Init(&ctx);
+
+               if ((cnt & 1) != 0)
+                       SHA256_Update(&ctx, p_bytes, key_len);
+               else
+                       SHA256_Update(&ctx, alt_result, 32);
+
+               if (cnt % 3 != 0)
+                       SHA256_Update(&ctx, s_bytes, salt_size);
+
+               if (cnt % 7 != 0)
+                       SHA256_Update(&ctx, p_bytes, key_len);
+
+               if ((cnt & 1) != 0)
+                       SHA256_Update(&ctx, alt_result, 32);
+               else
+                       SHA256_Update(&ctx, p_bytes, key_len);
+
+               SHA256_Final(alt_result, &ctx);
+       }
+
+       CopyMem(hash, alt_result, SHA256_DIGEST_SIZE);
+
+       FreePool(p_bytes);
+       FreePool(s_bytes);
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS sha512_crypt (const char *key,  UINT32 key_len,
+                               const char *salt, UINT32 salt_size,
+                               const UINT32 rounds, UINT8 *hash)
+{
+       SHA512_CTX ctx, alt_ctx;
+       UINT8 alt_result[SHA512_DIGEST_LENGTH];
+       UINT8 tmp_result[SHA512_DIGEST_LENGTH];
+       UINT8 *cp, *p_bytes, *s_bytes;
+       UINTN cnt;
+
+       SHA512_Init(&ctx);
+       SHA512_Update(&ctx, key, key_len);
+       SHA512_Update(&ctx, salt, salt_size);
+
+       SHA512_Init(&alt_ctx);
+       SHA512_Update(&alt_ctx, key, key_len);
+       SHA512_Update(&alt_ctx, salt, salt_size);
+       SHA512_Update(&alt_ctx, key, key_len);
+
+       SHA512_Final(alt_result, &alt_ctx);
+
+       for (cnt = key_len; cnt > 64; cnt -= 64)
+               SHA512_Update(&ctx, alt_result, 64);
+       SHA512_Update(&ctx, alt_result, cnt);
+
+       for (cnt = key_len; cnt > 0; cnt >>= 1) {
+               if ((cnt & 1) != 0) {
+                       SHA512_Update(&ctx, alt_result, 64);
+               } else {
+                       SHA512_Update(&ctx, key, key_len);
+               }
+       }
+       SHA512_Final(alt_result, &ctx);
+
+       SHA512_Init(&alt_ctx);
+       for (cnt = 0; cnt < key_len; ++cnt)
+               SHA512_Update(&alt_ctx, key, key_len);
+       SHA512_Final(tmp_result, &alt_ctx);
+
+       cp = p_bytes = AllocatePool(key_len);
+       for (cnt = key_len; cnt >= 64; cnt -= 64) {
+               CopyMem(cp, tmp_result, 64);
+               cp += 64;
+       }
+       CopyMem(cp, tmp_result, cnt);
+
+       SHA512_Init(&alt_ctx);
+       for (cnt = 0; cnt < 16ul + alt_result[0]; ++cnt)
+               SHA512_Update(&alt_ctx, salt, salt_size);
+       SHA512_Final(tmp_result, &alt_ctx);
+
+       cp = s_bytes = AllocatePool(salt_size);
+       for (cnt = salt_size; cnt >= 64; cnt -= 64) {
+               CopyMem(cp, tmp_result, 64);
+               cp += 64;
+       }
+       CopyMem(cp, tmp_result, cnt);
+
+       for (cnt = 0; cnt < rounds; ++cnt) {
+               SHA512_Init(&ctx);
+
+               if ((cnt & 1) != 0)
+                       SHA512_Update(&ctx, p_bytes, key_len);
+               else
+                       SHA512_Update(&ctx, alt_result, 64);
+
+               if (cnt % 3 != 0)
+                       SHA512_Update(&ctx, s_bytes, salt_size);
+
+               if (cnt % 7 != 0)
+                       SHA512_Update(&ctx, p_bytes, key_len);
+
+               if ((cnt & 1) != 0)
+                       SHA512_Update(&ctx, alt_result, 64);
+               else
+                       SHA512_Update(&ctx, p_bytes, key_len);
+
+               SHA512_Final(alt_result, &ctx);
+       }
+
+       CopyMem(hash, alt_result, SHA512_DIGEST_LENGTH);
+
+       FreePool(p_bytes);
+       FreePool(s_bytes);
+
+       return EFI_SUCCESS;
+}
+
+#define BF_RESULT_SIZE (7 + 22 + 31 + 1)
+
+static EFI_STATUS blowfish_crypt (const char *key, const char *salt, UINT8 *hash)
+{
+       char *retval, result[BF_RESULT_SIZE];
+
+       retval = crypt_blowfish_rn (key, salt, result, BF_RESULT_SIZE);
+       if (!retval)
+               return EFI_UNSUPPORTED;
+
+       CopyMem(hash, result + 7 + 22, BF_RESULT_SIZE);
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS password_crypt (const char *password, UINT32 pw_length,
+                          const PASSWORD_CRYPT *pw_crypt, UINT8 *hash)
+{
+       EFI_STATUS status;
+
+       if (!pw_crypt)
+               return EFI_INVALID_PARAMETER;
+
+       switch (pw_crypt->method) {
+       case TRADITIONAL_DES:
+               status = trad_des_crypt (password, (char *)pw_crypt->salt, hash);
+               break;
+       case EXTEND_BSDI_DES:
+               status = EFI_UNSUPPORTED;
+               break;
+       case MD5_BASED:
+               status = md5_crypt (password, pw_length, (char *)pw_crypt->salt,
+                                   pw_crypt->salt_size, hash);
+               break;
+       case SHA256_BASED:
+               status = sha256_crypt(password, pw_length, (char *)pw_crypt->salt,
+                                     pw_crypt->salt_size, pw_crypt->iter_count,
+                                     hash);
+               break;
+       case SHA512_BASED:
+               status = sha512_crypt(password, pw_length, (char *)pw_crypt->salt,
+                                     pw_crypt->salt_size, pw_crypt->iter_count,
+                                     hash);
+               break;
+       case BLOWFISH_BASED:
+               if (pw_crypt->salt_size != (7 + 22 + 1)) {
+                       status = EFI_INVALID_PARAMETER;
+                       break;
+               }
+               status = blowfish_crypt(password, (char *)pw_crypt->salt, hash);
+               break;
+       default:
+               return EFI_INVALID_PARAMETER;
+       }
+
+       return status;
+}
diff --git a/PasswordCrypt.h b/PasswordCrypt.h
new file mode 100644 (file)
index 0000000..b726f32
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __PASSWORD_CRYPT_H__
+#define __PASSWORD_CRYPT_H__
+
+enum HashMethod {
+       TRADITIONAL_DES = 0,
+       EXTEND_BSDI_DES,
+       MD5_BASED,
+       SHA256_BASED,
+       SHA512_BASED,
+       BLOWFISH_BASED
+};
+
+typedef struct {
+       UINT16 method;
+       UINT64 iter_count;
+       UINT16 salt_size;
+       UINT8  salt[32];
+       UINT8  hash[128];
+} __attribute__ ((packed)) PASSWORD_CRYPT;
+
+#define PASSWORD_CRYPT_SIZE sizeof(PASSWORD_CRYPT)
+
+EFI_STATUS password_crypt (const char *password, UINT32 pw_length,
+                          const PASSWORD_CRYPT *pw_hash, UINT8 *hash);
+UINT16 get_hash_size (const UINT16 method);
+
+#endif /* __PASSWORD_CRYPT_H__ */
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..24a39df
--- /dev/null
+++ b/README
@@ -0,0 +1,16 @@
+shim is a trivial EFI application that, when run, attempts to open and
+execute another application. It will initially attempt to do this via the
+standard EFI LoadImage() and StartImage() calls. If these fail (because secure
+boot is enabled and the binary is not signed with an appropriate key, for
+instance) it will then validate the binary against a built-in certificate. If
+this succeeds and if the binary or signing key are not blacklisted then shim
+will relocate and execute the binary.
+
+shim will also install a protocol which permits the second-stage bootloader
+to perform similar binary validation. This protocol has a GUID as described
+in the shim.h header file and provides a single entry point. On 64-bit systems
+this entry point expects to be called with SysV ABI rather than MSABI, and
+so calls to it should not be wrapped.
+
+To use shim, simply place a DER-encoded public certificate in a file such as
+pub.cer and build with "make VENDOR_CERT_FILE=pub.cer".
diff --git a/README.fallback b/README.fallback
new file mode 100644 (file)
index 0000000..3f91c1a
--- /dev/null
@@ -0,0 +1,60 @@
+Somebody mailed me this:
+
+> I am trying to understand how fallback.efi works.  I have been reading
+> shim.c and see that fallback is called when
+> should_use_fallback(EFI_HANDLE image_handle) returns a 1.  But in
+> should_use_fallback(EFI_HANDLE image_handle), there is a comparison of
+> bootpath to \\EFI\\BOOT\\BOOT.  Why is it compare to \\EFI\\BOOT\\BOOT
+> since bootpath always return \EFI\Boot\shim.efi?
+
+And it seems like a common enough question that we need some
+documentation of how to properly use shim and fallback.  Here's the
+basics of it:
+
+It doesn't always return \EFI\boot\shim.efi - in fact, not ever if
+installed correctly.  The FS layouts are like this:
+
+for removable media:
+\EFI\BOOT\BOOTX64.EFI <-- shim
+\EFI\BOOT\MokManager.efi
+\EFI\BOOT\grubx64.efi
+\EFI\BOOT\grub.cfg
+
+for an installed system:
+\EFI\BOOT\BOOTX64.EFI    <-- shim
+\EFI\BOOT\MokManager.efi
+\EFI\BOOT\fallback.efi
+\EFI\BOOT\BOOT.CSV
+\EFI\fedora\shim.efi
+\EFI\fedora\MokManager.efi
+\EFI\fedora\grubx64.efi
+\EFI\fedora\grub.cfg
+
+When you boot removable media, it'll be in \EFI\BOOT , but fallback.efi
+won't be there, so it goes ahead and boots the normal bootloader
+(grubx64.efi).  When you boot a normal system through a boot variable,
+the boot variable is configured to start \EFI\fedora\shim.efi (or
+whatever your distro's EFI directory is.)  In that case it won't try to
+invoke fallback.  But if the boot variables are missing or corrupted,
+the firmware will eventually try to boot the hard disk as removable
+media.  In that case, it'll invoke \EFI\BOOT\BOOTX64.EFI (or whatever
+filename is right for your architecture.)  In that case it'll be in
+\EFI\BOOT, so it'll check for fallback.efi , and it'll find it and run
+it.  When it runs, fallback will look for every directory in \EFI\ with
+a BOOT${ARCH}.CSV in it, or BOOT.CSV if that's not found.  It'll parse that,
+and create new boot variables from what it finds.  Then it'll try to boot one
+of them.
+
+BOOT.CSV is a UCS-2 LE formatted CSV file.  So it has the LE byte order
+marker, and after that it's just a series of lines, each having
+comma-separated date.  It looks like this on Fedora:
+
+shim.efi,Fedora,,This is the boot entry for Fedora
+
+so basically it's:
+
+$FILENAME,$LABEL,$LOADER_DATA,$COMMENT0[,$COMMENT1[,...]]
+
+Where $FILENAME has to be the name of a file in the same directory as
+BOOT.CSV .
+
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..029b0bf
--- /dev/null
+++ b/TODO
@@ -0,0 +1,23 @@
+Versioned protocol:
+- Make shim and the bootloaders using it express how enlightened they
+  are to one another, so we can stop earlier without tricks like
+  the one above
+MokListRT signing:
+- For kexec and hybernate to work right, MokListRT probably needs to
+  be an authenticated variable.  It's probable this needs to be done
+  in the kernel boot stub instead, just because it'll need an
+  ephemeral key to be generated, and that means we need some entropy
+  to build up.
+New security protocol:
+- TBD
+kexec MoK Management:
+Modsign enforcement mgmt MoK:
+- This is part of the plan for SecureBoot patches.  Basically these
+  features need to be disableable/enableable in MokManager.
+Variable for debug:
+- basically we need to be able to set a UEFI variable and get debug
+  output.  Right now some code uses SHIM_VERBOSE but that needs a fair
+  amount of work to actually be useful.
+Hashing of option roms:
+- hash option roms and add them to MokListRT
+- probably belongs in MokManager
diff --git a/cert.S b/cert.S
new file mode 100644 (file)
index 0000000..cfc4525
--- /dev/null
+++ b/cert.S
@@ -0,0 +1,65 @@
+       .globl cert_table
+       .type   cert_table, %object
+       .size   cert_table, 4
+       .section .vendor_cert, "a", %progbits
+cert_table:
+#if defined(VENDOR_CERT_FILE)
+       .long   vendor_cert_priv_end - vendor_cert_priv
+#else
+       .long   0
+#endif
+#if defined(VENDOR_DBX_FILE)
+       .long   vendor_dbx_priv_end - vendor_dbx_priv
+#else
+       .long   0
+#endif
+       .long   vendor_cert_priv - cert_table
+       .long   vendor_dbx_priv - cert_table
+#if defined(VENDOR_CERT_FILE)
+       .data
+       .align  1
+       .type   vendor_cert_priv, %object
+       .size   vendor_cert_priv, vendor_cert_priv_end-vendor_cert_priv
+       .section .vendor_cert, "a", %progbits
+vendor_cert_priv:
+.incbin VENDOR_CERT_FILE
+vendor_cert_priv_end:
+#else
+       .bss
+       .type   vendor_cert_priv, %object
+       .size   vendor_cert_priv, 1
+       .section .vendor_cert, "a", %progbits
+vendor_cert_priv:
+       .zero   1
+
+       .data
+       .align 4
+       .type   vendor_cert_size_priv, %object
+       .size   vendor_cert_size_priv, 4
+       .section .vendor_cert, "a", %progbits
+vendor_cert_priv_end:
+#endif
+#if defined(VENDOR_DBX_FILE)
+       .data
+       .align  1
+       .type   vendor_dbx_priv, %object
+       .size   vendor_dbx_priv, vendor_dbx_priv_end-vendor_dbx_priv
+       .section .vendor_cert, "a", %progbits
+vendor_dbx_priv:
+.incbin VENDOR_DBX_FILE
+vendor_dbx_priv_end:
+#else
+       .bss
+       .type   vendor_dbx_priv, %object
+       .size   vendor_dbx_priv, 1
+       .section .vendor_cert, "a", %progbits
+vendor_dbx_priv:
+       .zero   1
+
+       .data
+       .align 4
+       .type   vendor_dbx_size_priv, %object
+       .size   vendor_dbx_size_priv, 4
+       .section .vendor_cert, "a", %progbits
+vendor_dbx_priv_end:
+#endif
diff --git a/crypt_blowfish.c b/crypt_blowfish.c
new file mode 100644 (file)
index 0000000..366a81a
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * The crypt_blowfish homepage is:
+ *
+ *     http://www.openwall.com/crypt/
+ *
+ * This code comes from John the Ripper password cracker, with reentrant
+ * and crypt(3) interfaces added, but optimizations specific to password
+ * cracking removed.
+ *
+ * Written by Solar Designer <solar at openwall.com> in 1998-2011.
+ * No copyright is claimed, and the software is hereby placed in the public
+ * domain.  In case this attempt to disclaim copyright and place the software
+ * in the public domain is deemed null and void, then the software is
+ * Copyright (c) 1998-2011 Solar Designer and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * It is my intent that you should be able to use this on your system,
+ * as part of a software package, or anywhere else to improve security,
+ * ensure compatibility, or for any other purpose.  I would appreciate
+ * it if you give credit where it is due and keep your modifications in
+ * the public domain as well, but I don't require that in order to let
+ * you place this code and any modifications you make under a license
+ * of your choice.
+ *
+ * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
+ * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
+ * ideas.  The password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu>.  For more information on the level of compatibility,
+ * prefer refer to the comments in BF_set_key() below and to the included
+ * crypt(3) man page.
+ *
+ * There's a paper on the algorithm that explains its design decisions:
+ *
+ *     http://www.usenix.org/events/usenix99/provos.html
+ *
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
+ * Blowfish library (I can't be sure if I would think of something if I
+ * hadn't seen his code).
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+/* Just to make sure the prototypes match the actual definitions */
+#include "crypt_blowfish.h"
+
+typedef unsigned int BF_word;
+typedef signed int BF_word_signed;
+
+/* Number of Blowfish rounds, this is also hardcoded into a few places */
+#define BF_N                           16
+
+typedef BF_word BF_key[BF_N + 2];
+
+typedef struct {
+       BF_word S[4][0x100];
+       BF_key P;
+} BF_ctx;
+
+/*
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
+ */
+static BF_word BF_magic_w[6] = {
+       0x4F727068, 0x65616E42, 0x65686F6C,
+       0x64657253, 0x63727944, 0x6F756274
+};
+
+/*
+ * P-box and S-box tables initialized with digits of Pi.
+ */
+static BF_ctx BF_init_state = {
+       {
+               {
+                       0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+                       0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+                       0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+                       0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+                       0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+                       0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+                       0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+                       0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+                       0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+                       0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+                       0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+                       0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+                       0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+                       0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+                       0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+                       0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+                       0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+                       0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+                       0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+                       0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+                       0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+                       0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+                       0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+                       0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+                       0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+                       0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+                       0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+                       0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+                       0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+                       0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+                       0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+                       0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+                       0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+                       0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+                       0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+                       0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+                       0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+                       0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+                       0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+                       0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+                       0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+                       0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+                       0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+                       0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+                       0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+                       0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+                       0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+                       0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+                       0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+                       0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+                       0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+                       0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+                       0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+                       0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+                       0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+                       0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+                       0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+                       0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+                       0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+                       0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+                       0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+                       0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+                       0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+                       0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+               }, {
+                       0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+                       0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+                       0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+                       0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+                       0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+                       0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+                       0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+                       0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+                       0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+                       0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+                       0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+                       0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+                       0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+                       0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+                       0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+                       0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+                       0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+                       0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+                       0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+                       0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+                       0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+                       0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+                       0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+                       0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+                       0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+                       0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+                       0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+                       0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+                       0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+                       0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+                       0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+                       0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+                       0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+                       0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+                       0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+                       0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+                       0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+                       0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+                       0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+                       0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+                       0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+                       0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+                       0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+                       0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+                       0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+                       0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+                       0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+                       0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+                       0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+                       0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+                       0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+                       0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+                       0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+                       0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+                       0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+                       0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+                       0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+                       0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+                       0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+                       0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+                       0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+                       0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+                       0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+                       0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+               }, {
+                       0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+                       0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+                       0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+                       0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+                       0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+                       0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+                       0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+                       0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+                       0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+                       0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+                       0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+                       0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+                       0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+                       0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+                       0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+                       0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+                       0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+                       0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+                       0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+                       0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+                       0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+                       0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+                       0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+                       0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+                       0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+                       0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+                       0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+                       0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+                       0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+                       0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+                       0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+                       0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+                       0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+                       0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+                       0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+                       0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+                       0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+                       0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+                       0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+                       0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+                       0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+                       0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+                       0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+                       0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+                       0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+                       0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+                       0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+                       0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+                       0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+                       0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+                       0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+                       0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+                       0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+                       0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+                       0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+                       0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+                       0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+                       0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+                       0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+                       0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+                       0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+                       0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+                       0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+                       0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+               }, {
+                       0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+                       0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+                       0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+                       0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+                       0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+                       0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+                       0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+                       0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+                       0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+                       0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+                       0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+                       0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+                       0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+                       0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+                       0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+                       0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+                       0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+                       0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+                       0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+                       0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+                       0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+                       0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+                       0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+                       0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+                       0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+                       0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+                       0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+                       0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+                       0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+                       0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+                       0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+                       0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+                       0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+                       0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+                       0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+                       0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+                       0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+                       0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+                       0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+                       0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+                       0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+                       0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+                       0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+                       0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+                       0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+                       0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+                       0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+                       0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+                       0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+                       0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+                       0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+                       0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+                       0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+                       0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+                       0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+                       0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+                       0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+                       0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+                       0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+                       0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+                       0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+                       0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+                       0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+                       0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+               }
+       }, {
+               0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+               0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+               0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+               0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+               0x9216d5d9, 0x8979fb1b
+       }
+};
+
+static unsigned char BF_itoa64[64 + 1] =
+       "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static unsigned char BF_atoi64[0x60] = {
+       64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
+       54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
+       64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
+       64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+       43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
+};
+
+#define BF_safe_atoi64(dst, src) \
+{ \
+       tmp = (unsigned char)(src); \
+       if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
+       tmp = BF_atoi64[tmp]; \
+       if (tmp > 63) return -1; \
+       (dst) = tmp; \
+}
+
+static int BF_decode(BF_word *dst, const char *src, int size)
+{
+       unsigned char *dptr = (unsigned char *)dst;
+       unsigned char *end = dptr + size;
+       const unsigned char *sptr = (const unsigned char *)src;
+       unsigned int tmp, c1, c2, c3, c4;
+
+       do {
+               BF_safe_atoi64(c1, *sptr++);
+               BF_safe_atoi64(c2, *sptr++);
+               *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+               if (dptr >= end) break;
+
+               BF_safe_atoi64(c3, *sptr++);
+               *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
+               if (dptr >= end) break;
+
+               BF_safe_atoi64(c4, *sptr++);
+               *dptr++ = ((c3 & 0x03) << 6) | c4;
+       } while (dptr < end);
+
+       return 0;
+}
+
+static void BF_encode(char *dst, const BF_word *src, int size)
+{
+       const unsigned char *sptr = (const unsigned char *)src;
+       const unsigned char *end = sptr + size;
+       unsigned char *dptr = (unsigned char *)dst;
+       unsigned int c1, c2;
+
+       do {
+               c1 = *sptr++;
+               *dptr++ = BF_itoa64[c1 >> 2];
+               c1 = (c1 & 0x03) << 4;
+               if (sptr >= end) {
+                       *dptr++ = BF_itoa64[c1];
+                       break;
+               }
+
+               c2 = *sptr++;
+               c1 |= c2 >> 4;
+               *dptr++ = BF_itoa64[c1];
+               c1 = (c2 & 0x0f) << 2;
+               if (sptr >= end) {
+                       *dptr++ = BF_itoa64[c1];
+                       break;
+               }
+
+               c2 = *sptr++;
+               c1 |= c2 >> 6;
+               *dptr++ = BF_itoa64[c1];
+               *dptr++ = BF_itoa64[c2 & 0x3f];
+       } while (sptr < end);
+}
+
+static void BF_swap(BF_word *x, int count)
+{
+       static int endianness_check = 1;
+       char *is_little_endian = (char *)&endianness_check;
+       BF_word tmp;
+
+       if (*is_little_endian)
+       do {
+               tmp = *x;
+               tmp = (tmp << 16) | (tmp >> 16);
+               *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
+       } while (--count);
+}
+
+/* Architectures which can shift addresses left by 2 bits with no extra cost */
+#define BF_ROUND(L, R, N) \
+       tmp1 = L & 0xFF; \
+       tmp2 = L >> 8; \
+       tmp2 &= 0xFF; \
+       tmp3 = L >> 16; \
+       tmp3 &= 0xFF; \
+       tmp4 = L >> 24; \
+       tmp1 = data.ctx.S[3][tmp1]; \
+       tmp2 = data.ctx.S[2][tmp2]; \
+       tmp3 = data.ctx.S[1][tmp3]; \
+       tmp3 += data.ctx.S[0][tmp4]; \
+       tmp3 ^= tmp2; \
+       R ^= data.ctx.P[N + 1]; \
+       tmp3 += tmp1; \
+       R ^= tmp3;
+
+/*
+ * Encrypt one block, BF_N is hardcoded here.
+ */
+#define BF_ENCRYPT \
+       L ^= data.ctx.P[0]; \
+       BF_ROUND(L, R, 0); \
+       BF_ROUND(R, L, 1); \
+       BF_ROUND(L, R, 2); \
+       BF_ROUND(R, L, 3); \
+       BF_ROUND(L, R, 4); \
+       BF_ROUND(R, L, 5); \
+       BF_ROUND(L, R, 6); \
+       BF_ROUND(R, L, 7); \
+       BF_ROUND(L, R, 8); \
+       BF_ROUND(R, L, 9); \
+       BF_ROUND(L, R, 10); \
+       BF_ROUND(R, L, 11); \
+       BF_ROUND(L, R, 12); \
+       BF_ROUND(R, L, 13); \
+       BF_ROUND(L, R, 14); \
+       BF_ROUND(R, L, 15); \
+       tmp4 = R; \
+       R = L; \
+       L = tmp4 ^ data.ctx.P[BF_N + 1];
+
+#define BF_body() \
+       L = R = 0; \
+       ptr = data.ctx.P; \
+       do { \
+               ptr += 2; \
+               BF_ENCRYPT; \
+               *(ptr - 2) = L; \
+               *(ptr - 1) = R; \
+       } while (ptr < &data.ctx.P[BF_N + 2]); \
+\
+       ptr = data.ctx.S[0]; \
+       do { \
+               ptr += 2; \
+               BF_ENCRYPT; \
+               *(ptr - 2) = L; \
+               *(ptr - 1) = R; \
+       } while (ptr < &data.ctx.S[3][0xFF]);
+
+static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
+    unsigned char flags)
+{
+       const char *ptr = key;
+       unsigned int bug, i, j;
+       BF_word safety, sign, diff, tmp[2];
+
+/*
+ * There was a sign extension bug in older revisions of this function.  While
+ * we would have liked to simply fix the bug and move on, we have to provide
+ * a backwards compatibility feature (essentially the bug) for some systems and
+ * a safety measure for some others.  The latter is needed because for certain
+ * multiple inputs to the buggy algorithm there exist easily found inputs to
+ * the correct algorithm that produce the same hash.  Thus, we optionally
+ * deviate from the correct algorithm just enough to avoid such collisions.
+ * While the bug itself affected the majority of passwords containing
+ * characters with the 8th bit set (although only a percentage of those in a
+ * collision-producing way), the anti-collision safety measure affects
+ * only a subset of passwords containing the '\xff' character (not even all of
+ * those passwords, just some of them).  This character is not found in valid
+ * UTF-8 sequences and is rarely used in popular 8-bit character encodings.
+ * Thus, the safety measure is unlikely to cause much annoyance, and is a
+ * reasonable tradeoff to use when authenticating against existing hashes that
+ * are not reliably known to have been computed with the correct algorithm.
+ *
+ * We use an approach that tries to minimize side-channel leaks of password
+ * information - that is, we mostly use fixed-cost bitwise operations instead
+ * of branches or table lookups.  (One conditional branch based on password
+ * length remains.  It is not part of the bug aftermath, though, and is
+ * difficult and possibly unreasonable to avoid given the use of C strings by
+ * the caller, which results in similar timing leaks anyway.)
+ *
+ * For actual implementation, we set an array index in the variable "bug"
+ * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
+ * variable "safety" (bit 16 is set when the safety measure is requested).
+ * Valid combinations of settings are:
+ *
+ * Prefix "$2a$": bug = 0, safety = 0x10000
+ * Prefix "$2x$": bug = 1, safety = 0
+ * Prefix "$2y$": bug = 0, safety = 0
+ */
+       bug = (unsigned int)flags & 1;
+       safety = ((BF_word)flags & 2) << 15;
+
+       sign = diff = 0;
+
+       for (i = 0; i < BF_N + 2; i++) {
+               tmp[0] = tmp[1] = 0;
+               for (j = 0; j < 4; j++) {
+                       tmp[0] <<= 8;
+                       tmp[0] |= (unsigned char)*ptr; /* correct */
+                       tmp[1] <<= 8;
+                       tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */
+/*
+ * Sign extension in the first char has no effect - nothing to overwrite yet,
+ * and those extra 24 bits will be fully shifted out of the 32-bit word.  For
+ * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
+ * extension in tmp[1] occurs.  Once this flag is set, it remains set.
+ */
+                       if (j)
+                               sign |= tmp[1] & 0x80;
+                       if (!*ptr)
+                               ptr = key;
+                       else
+                               ptr++;
+               }
+               diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
+
+               expanded[i] = tmp[bug];
+               initial[i] = BF_init_state.P[i] ^ tmp[bug];
+       }
+
+/*
+ * At this point, "diff" is zero iff the correct and buggy algorithms produced
+ * exactly the same result.  If so and if "sign" is non-zero, which indicates
+ * that there was a non-benign sign extension, this means that we have a
+ * collision between the correctly computed hash for this password and a set of
+ * passwords that could be supplied to the buggy algorithm.  Our safety measure
+ * is meant to protect from such many-buggy to one-correct collisions, by
+ * deviating from the correct algorithm in such cases.  Let's check for this.
+ */
+       diff |= diff >> 16; /* still zero iff exact match */
+       diff &= 0xffff; /* ditto */
+       diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
+       sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
+       sign &= ~diff & safety; /* action needed? */
+
+/*
+ * If we have determined that we need to deviate from the correct algorithm,
+ * flip bit 16 in initial expanded key.  (The choice of 16 is arbitrary, but
+ * let's stick to it now.  It came out of the approach we used above, and it's
+ * not any worse than any other choice we could make.)
+ *
+ * It is crucial that we don't do the same to the expanded key used in the main
+ * Eksblowfish loop.  By doing it to only one of these two, we deviate from a
+ * state that could be directly specified by a password to the buggy algorithm
+ * (and to the fully correct one as well, but that's a side-effect).
+ */
+       initial[0] ^= sign;
+}
+
+static char *BF_crypt(const char *key, const char *setting,
+                     char *output, int size,
+                     BF_word min)
+{
+       static const unsigned char flags_by_subtype[26] =
+               {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
+       struct {
+               BF_ctx ctx;
+               BF_key expanded_key;
+               union {
+                       BF_word salt[4];
+                       BF_word output[6];
+               } binary;
+       } data;
+       BF_word L, R;
+       BF_word tmp1, tmp2, tmp3, tmp4;
+       BF_word *ptr;
+       BF_word count;
+       int i;
+
+       if (size < 7 + 22 + 31 + 1) {
+               return NULL;
+       }
+
+       if (setting[0] != '$' ||
+           setting[1] != '2' ||
+           setting[2] < 'a' || setting[2] > 'z' ||
+           !flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] ||
+           setting[3] != '$' ||
+           setting[4] < '0' || setting[4] > '3' ||
+           setting[5] < '0' || setting[5] > '9' ||
+           (setting[4] == '3' && setting[5] > '1') ||
+           setting[6] != '$') {
+               return NULL;
+       }
+
+       count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
+       if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
+               return NULL;
+       }
+       BF_swap(data.binary.salt, 4);
+
+       BF_set_key(key, data.expanded_key, data.ctx.P,
+                  flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']);
+
+       CopyMem(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
+
+       L = R = 0;
+       for (i = 0; i < BF_N + 2; i += 2) {
+               L ^= data.binary.salt[i & 2];
+               R ^= data.binary.salt[(i & 2) + 1];
+               BF_ENCRYPT;
+               data.ctx.P[i] = L;
+               data.ctx.P[i + 1] = R;
+       }
+
+       ptr = data.ctx.S[0];
+       do {
+               ptr += 4;
+               L ^= data.binary.salt[(BF_N + 2) & 3];
+               R ^= data.binary.salt[(BF_N + 3) & 3];
+               BF_ENCRYPT;
+               *(ptr - 4) = L;
+               *(ptr - 3) = R;
+
+               L ^= data.binary.salt[(BF_N + 4) & 3];
+               R ^= data.binary.salt[(BF_N + 5) & 3];
+               BF_ENCRYPT;
+               *(ptr - 2) = L;
+               *(ptr - 1) = R;
+       } while (ptr < &data.ctx.S[3][0xFF]);
+
+       do {
+               int done;
+
+               for (i = 0; i < BF_N + 2; i += 2) {
+                       data.ctx.P[i] ^= data.expanded_key[i];
+                       data.ctx.P[i + 1] ^= data.expanded_key[i + 1];
+               }
+
+               done = 0;
+               do {
+                       BF_body();
+                       if (done)
+                               break;
+                       done = 1;
+
+                       tmp1 = data.binary.salt[0];
+                       tmp2 = data.binary.salt[1];
+                       tmp3 = data.binary.salt[2];
+                       tmp4 = data.binary.salt[3];
+                       for (i = 0; i < BF_N; i += 4) {
+                               data.ctx.P[i] ^= tmp1;
+                               data.ctx.P[i + 1] ^= tmp2;
+                               data.ctx.P[i + 2] ^= tmp3;
+                               data.ctx.P[i + 3] ^= tmp4;
+                       }
+                       data.ctx.P[16] ^= tmp1;
+                       data.ctx.P[17] ^= tmp2;
+               } while (1);
+       } while (--count);
+
+       for (i = 0; i < 6; i += 2) {
+               L = BF_magic_w[i];
+               R = BF_magic_w[i + 1];
+
+               count = 64;
+               do {
+                       BF_ENCRYPT;
+               } while (--count);
+
+               data.binary.output[i] = L;
+               data.binary.output[i + 1] = R;
+       }
+
+       CopyMem(output, (void *)setting, 7 + 22 - 1);
+       output[7 + 22 - 1] = BF_itoa64[(int)
+               BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
+
+/* This has to be bug-compatible with the original implementation, so
+ * only encode 23 of the 24 bytes. :-) */
+       BF_swap(data.binary.output, 6);
+       BF_encode(&output[7 + 22], data.binary.output, 23);
+       output[7 + 22 + 31] = '\0';
+
+       return output;
+}
+
+int _crypt_output_magic(const char *setting, char *output, int size)
+{
+       if (size < 3)
+               return -1;
+
+       output[0] = '*';
+       output[1] = '0';
+       output[2] = '\0';
+
+       if (setting[0] == '*' && setting[1] == '0')
+               output[1] = '1';
+
+       return 0;
+}
+
+/*
+ * Please preserve the runtime self-test.  It serves two purposes at once:
+ *
+ * 1. We really can't afford the risk of producing incompatible hashes e.g.
+ * when there's something like gcc bug 26587 again, whereas an application or
+ * library integrating this code might not also integrate our external tests or
+ * it might not run them after every build.  Even if it does, the miscompile
+ * might only occur on the production build, but not on a testing build (such
+ * as because of different optimization settings).  It is painful to recover
+ * from incorrectly-computed hashes - merely fixing whatever broke is not
+ * enough.  Thus, a proactive measure like this self-test is needed.
+ *
+ * 2. We don't want to leave sensitive data from our actual password hash
+ * computation on the stack or in registers.  Previous revisions of the code
+ * would do explicit cleanups, but simply running the self-test after hash
+ * computation is more reliable.
+ *
+ * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
+ * setting.
+ */
+char *crypt_blowfish_rn(const char *key, const char *setting,
+                       char *output, int size)
+{
+       const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
+       const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
+       static const char * const test_hash[2] =
+               {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
+               "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
+       char *retval;
+       const char *p;
+       int ok;
+       struct {
+               char s[7 + 22 + 1];
+               char o[7 + 22 + 31 + 1 + 1 + 1];
+       } buf;
+
+/* Hash the supplied password */
+       _crypt_output_magic(setting, output, size);
+       retval = BF_crypt(key, setting, output, size, 16);
+
+/*
+ * Do a quick self-test.  It is important that we make both calls to BF_crypt()
+ * from the same scope such that they likely use the same stack locations,
+ * which makes the second call overwrite the first call's sensitive data on the
+ * stack and makes it more likely that any alignment related issues would be
+ * detected by the self-test.
+ */
+       CopyMem(buf.s, (void *)test_setting, sizeof(buf.s));
+       if (retval)
+               buf.s[2] = setting[2];
+       SetMem(buf.o, sizeof(buf.o), 0x55);
+       buf.o[sizeof(buf.o) - 1] = 0;
+       p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1);
+
+       ok = (p == buf.o &&
+           !CompareMem((void *)p, (void *)buf.s, 7 + 22) &&
+           !CompareMem((void *)(p + (7 + 22)),
+           (void *)test_hash[(unsigned int)(unsigned char)buf.s[2] & 1],
+           31 + 1 + 1 + 1));
+
+       {
+               const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
+               BF_key ae, ai, ye, yi;
+               BF_set_key(k, ae, ai, 2); /* $2a$ */
+               BF_set_key(k, ye, yi, 4); /* $2y$ */
+               ai[0] ^= 0x10000; /* undo the safety (for comparison) */
+               ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
+                   !CompareMem(ae, ye, sizeof(ae)) &&
+                   !CompareMem(ai, yi, sizeof(ai));
+       }
+
+       if (ok)
+               return retval;
+
+/* Should not happen */
+       _crypt_output_magic(setting, output, size);
+       return NULL;
+}
diff --git a/crypt_blowfish.h b/crypt_blowfish.h
new file mode 100644 (file)
index 0000000..dc3bd56
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
+ * No copyright is claimed, and the software is hereby placed in the public
+ * domain.  In case this attempt to disclaim copyright and place the software
+ * in the public domain is deemed null and void, then the software is
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See crypt_blowfish.c for more information.
+ */
+
+#ifndef _CRYPT_BLOWFISH_H
+#define _CRYPT_BLOWFISH_H
+
+char *crypt_blowfish_rn(const char *key, const char *setting,
+                       char *output, int size);
+#endif
diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds
new file mode 100644 (file)
index 0000000..77770c2
--- /dev/null
@@ -0,0 +1,68 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+  .text 0x0 : {
+    _text = .;
+    *(.text.head)
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.srodata)
+    *(.rodata*)
+    . = ALIGN(16);
+    _etext = .;
+  }
+  .dynamic  : { *(.dynamic) }
+  .data :
+  {
+   _data = .;
+   *(.sdata)
+   *(.data)
+   *(.data1)
+   *(.data.*)
+   *(.got.plt)
+   *(.got)
+
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   . = ALIGN(16);
+   _bss = .;
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(16);
+   _bss_end = .;
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+
+  . = ALIGN(4096);
+  .vendor_cert :
+  {
+    *(.vendor_cert)
+  }
+  . = ALIGN(4096);
+
+  .rela.dyn : { *(.rela.dyn) }
+  .rela.plt : { *(.rela.plt) }
+  .rela.got : { *(.rela.got) }
+  .rela.data : { *(.rela.data) *(.rela.data*) }
+  _edata = .;
+  _data_size = . - _data;
+
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  /DISCARD/ :
+  {
+    *(.rel.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+}
diff --git a/elf_arm_efi.lds b/elf_arm_efi.lds
new file mode 100644 (file)
index 0000000..ffa1eeb
--- /dev/null
@@ -0,0 +1,68 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  .text 0x0 : {
+    _text = .;
+    *(.text.head)
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.srodata)
+    *(.rodata*)
+    . = ALIGN(16);
+    _etext = .;
+  }
+  .dynamic  : { *(.dynamic) }
+  .data :
+  {
+   _data = .;
+   *(.sdata)
+   *(.data)
+   *(.data1)
+   *(.data*)
+   *(.got.plt)
+   *(.got)
+
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   . = ALIGN(16);
+   _bss = .;
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(16);
+   _bss_end = .;
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+
+   . = ALIGN(4096);
+  .vendor_cert :
+  {
+    *(.vendor_cert)
+  }
+  . = ALIGN(4096);
+
+  .rel.dyn : { *(.rel.dyn) }
+  .rel.plt : { *(.rel.plt) }
+  .rel.got : { *(.rel.got) }
+  .rel.data : { *(.rel.data) *(.rel.data*) }
+  _edata = .;
+  _data_size = . - _data;
+
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  /DISCARD/ :
+  {
+    *(.rel.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+}
diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds
new file mode 100644 (file)
index 0000000..9da8109
--- /dev/null
@@ -0,0 +1,75 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0;
+  ImageBase = .;
+  .hash : { *(.hash) } /* this MUST come first! */
+  . = ALIGN(4096);
+  .text :
+  {
+   _text = .;
+   *(.text)
+   *(.text.*)
+   *(.gnu.linkonce.t.*)
+   _etext = .;
+  }
+  .reloc :
+  {
+   *(.reloc)
+  }
+  . = ALIGN(4096);
+  .data :
+  {
+   _data = .;
+   *(.rodata*)
+   *(.data)
+   *(.data1)
+   *(.data.*)
+   *(.sdata)
+   *(.got.plt)
+   *(.got)
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  . = ALIGN(4096);
+  .vendor_cert :
+  {
+   *(.vendor_cert)
+  }
+  . = ALIGN(4096);
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .rel :
+  {
+    *(.rel.data)
+    *(.rel.data.*)
+    *(.rel.got)
+    *(.rel.stab)
+    *(.data.rel.ro.local)
+    *(.data.rel.local)
+    *(.data.rel.ro)
+    *(.data.rel*)
+  }
+  _edata = .;
+  _data_size = . - _data;
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  /DISCARD/ :
+  {
+    *(.rel.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+}
diff --git a/elf_ia64_efi.lds b/elf_ia64_efi.lds
new file mode 100644 (file)
index 0000000..39ffdda
--- /dev/null
@@ -0,0 +1,82 @@
+OUTPUT_FORMAT("elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start_plabel)
+SECTIONS
+{
+  . = 0;
+  ImageBase = .;
+  .hash : { *(.hash) } /* this MUST come first! */
+  . = ALIGN(4096);
+  .text :
+  {
+   _text = .;
+   *(.text)
+   *(.text.*)
+   *(.gnu.linkonce.t.*)
+   _etext = .;
+  }
+  . = ALIGN(4096);
+  __gp = ALIGN (8) + 0x200000;
+  .sdata :
+  {
+   _data = .;
+   *(.got.plt)
+   *(.got)
+   *(.srodata)
+   *(.sdata)
+   *(.sbss)
+   *(.scommon)
+  }
+  . = ALIGN(4096);
+  .data :
+  {
+   *(.rodata*)
+   *(.ctors)
+   *(.data*)
+   *(.gnu.linkonce.d*)
+   *(.plabel)  /* data whose relocs we want to ignore */
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  . = ALIGN(4096);
+  .vendor_cert :
+  {
+   *(.vendor_cert)
+  }
+  . = ALIGN(4096);
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .rela :
+  {
+    *(.rela.text)
+    *(.rela.data*)
+    *(.rela.sdata)
+    *(.rela.got)
+    *(.rela.gnu.linkonce.d*)
+    *(.rela.stab)
+    *(.rela.ctors)
+  }
+  _edata = .;
+  _data_size = . - _data;
+  . = ALIGN(4096);
+  .reloc :             /* This is the PECOFF .reloc section! */
+  {
+    *(.reloc)
+  }
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  /DISCARD/ :
+  {
+    *(.rela.plabel)
+    *(.rela.reloc)
+    *(.IA_64.unwind*)
+    *(.IA64.unwind*)
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+}
diff --git a/elf_x86_64_efi.lds b/elf_x86_64_efi.lds
new file mode 100644 (file)
index 0000000..bb21bbb
--- /dev/null
@@ -0,0 +1,76 @@
+/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0;
+  ImageBase = .;
+  .hash : { *(.hash) } /* this MUST come first! */
+  . = ALIGN(4096);
+  .eh_frame : 
+  { 
+    *(.eh_frame)
+  }
+  . = ALIGN(4096);
+  .text :
+  {
+   _text = .;
+   *(.text)
+   _etext = .;
+  }
+  . = ALIGN(4096);
+  .reloc :
+  {
+   *(.reloc)
+  }
+  . = ALIGN(4096);
+  .data :
+  {
+   _data = .;
+   *(.rodata*)
+   *(.got.plt)
+   *(.got)
+   *(.data*)
+   *(.sdata)
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   *(.rel.local)
+  }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  . = ALIGN(4096);
+  .vendor_cert :
+  {
+   *(.vendor_cert)
+  }
+  . = ALIGN(4096);
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .rela :
+  {
+    *(.rela.data*)
+    *(.rela.got)
+    *(.rela.stab)
+  }
+  _edata = .;
+  _data_size = . - _data;
+
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  .ignored.reloc :
+  {
+    *(.rela.reloc)
+    *(.eh_frame)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+}
diff --git a/fallback.c b/fallback.c
new file mode 100644 (file)
index 0000000..5e4a396
--- /dev/null
@@ -0,0 +1,877 @@
+/*
+ * Copyright 2012-2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * See "COPYING" for license terms.
+ *
+ * Author(s): Peter Jones <pjones@redhat.com>
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "ucs2.h"
+#include "variables.h"
+
+EFI_LOADED_IMAGE *this_image = NULL;
+
+static EFI_STATUS
+FindSubDevicePath(EFI_DEVICE_PATH *In, UINT8 Type, UINT8 SubType,
+                 EFI_DEVICE_PATH **Out)
+{
+       EFI_DEVICE_PATH *dp = In;
+       if (!In || !Out)
+               return EFI_INVALID_PARAMETER;
+
+       for (dp = In; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
+               if (DevicePathType(dp) == Type &&
+                               DevicePathSubType(dp) == SubType) {
+                       *Out = DuplicateDevicePath(dp);
+                       if (!*Out)
+                               return EFI_OUT_OF_RESOURCES;
+                       return EFI_SUCCESS;
+               }
+       }
+       *Out = NULL;
+       return EFI_NOT_FOUND;
+}
+
+static EFI_STATUS
+get_file_size(EFI_FILE_HANDLE fh, UINTN *retsize)
+{
+       EFI_STATUS rc;
+       void *buffer = NULL;
+       UINTN bs = 0;
+       EFI_GUID finfo = EFI_FILE_INFO_ID;
+
+       /* The API here is "Call it once with bs=0, it fills in bs,
+        * then allocate a buffer and ask again to get it filled. */
+       rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, &bs, NULL);
+       if (rc == EFI_BUFFER_TOO_SMALL) {
+               buffer = AllocateZeroPool(bs);
+               if (!buffer) {
+                       Print(L"Could not allocate memory\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+               rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo,
+                                       &bs, buffer);
+       }
+       /* This checks *either* the error from the first GetInfo, if it isn't
+        * the EFI_BUFFER_TOO_SMALL we're expecting, or the second GetInfo call
+        * in *any* case. */
+       if (EFI_ERROR(rc)) {
+               Print(L"Could not get file info: %d\n", rc);
+               if (buffer)
+                       FreePool(buffer);
+               return rc;
+       }
+       EFI_FILE_INFO *fi = buffer;
+       *retsize = fi->FileSize;
+       FreePool(buffer);
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+read_file(EFI_FILE_HANDLE fh, CHAR16 *fullpath, CHAR16 **buffer, UINT64 *bs)
+{
+       EFI_FILE_HANDLE fh2;
+       EFI_STATUS rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, fullpath,
+                               EFI_FILE_READ_ONLY, 0);
+       if (EFI_ERROR(rc)) {
+               Print(L"Couldn't open \"%s\": %d\n", fullpath, rc);
+               return rc;
+       }
+
+       UINTN len = 0;
+       CHAR16 *b = NULL;
+       rc = get_file_size(fh2, &len);
+       if (EFI_ERROR(rc)) {
+               uefi_call_wrapper(fh2->Close, 1, fh2);
+               return rc;
+       }
+
+       b = AllocateZeroPool(len + 2);
+       if (!buffer) {
+               Print(L"Could not allocate memory\n");
+               uefi_call_wrapper(fh2->Close, 1, fh2);
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       rc = uefi_call_wrapper(fh->Read, 3, fh, &len, b);
+       if (EFI_ERROR(rc)) {
+               FreePool(buffer);
+               uefi_call_wrapper(fh2->Close, 1, fh2);
+               Print(L"Could not read file: %d\n", rc);
+               return rc;
+       }
+       *buffer = b;
+       *bs = len;
+       uefi_call_wrapper(fh2->Close, 1, fh2);
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen)
+{
+       UINT64 len;
+       
+       len = StrLen(L"\\EFI\\") + StrLen(dirname)
+           + StrLen(L"\\") + StrLen(filename)
+           + 2;
+
+       CHAR16 *fullpath = AllocateZeroPool(len*sizeof(CHAR16));
+       if (!fullpath) {
+               Print(L"Could not allocate memory\n");
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       StrCat(fullpath, L"\\EFI\\");
+       StrCat(fullpath, dirname);
+       StrCat(fullpath, L"\\");
+       StrCat(fullpath, filename);
+
+       *out = fullpath;
+       *outlen = len;
+       return EFI_SUCCESS;
+}
+
+CHAR16 *bootorder = NULL;
+int nbootorder = 0;
+
+EFI_DEVICE_PATH *first_new_option = NULL;
+VOID *first_new_option_args = NULL;
+UINTN first_new_option_size = 0;
+
+EFI_STATUS
+add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
+               CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
+{
+       static int i = 0;
+       CHAR16 varname[] = L"Boot0000";
+       CHAR16 hexmap[] = L"0123456789ABCDEF";
+       EFI_GUID global = EFI_GLOBAL_VARIABLE;
+       EFI_STATUS rc;
+
+       for(; i <= 0xffff; i++) {
+               varname[4] = hexmap[(i & 0xf000) >> 12];
+               varname[5] = hexmap[(i & 0x0f00) >> 8];
+               varname[6] = hexmap[(i & 0x00f0) >> 4];
+               varname[7] = hexmap[(i & 0x000f) >> 0];
+
+               void *var = LibGetVariable(varname, &global);
+               if (!var) {
+                       int size = sizeof(UINT32) + sizeof (UINT16) +
+                               StrLen(label)*2 + 2 + DevicePathSize(hddp) +
+                               StrLen(arguments) * 2;
+
+                       CHAR8 *data = AllocateZeroPool(size + 2);
+                       CHAR8 *cursor = data;
+                       *(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
+                       cursor += sizeof (UINT32);
+                       *(UINT16 *)cursor = DevicePathSize(hddp);
+                       cursor += sizeof (UINT16);
+                       StrCpy((CHAR16 *)cursor, label);
+                       cursor += StrLen(label)*2 + 2;
+                       CopyMem(cursor, hddp, DevicePathSize(hddp));
+                       cursor += DevicePathSize(hddp);
+                       StrCpy((CHAR16 *)cursor, arguments);
+
+                       Print(L"Creating boot entry \"%s\" with label \"%s\" "
+                                       L"for file \"%s\"\n",
+                               varname, label, filename);
+
+                       if (!first_new_option) {
+                               first_new_option = DuplicateDevicePath(fulldp);
+                               first_new_option_args = arguments;
+                               first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
+                       }
+
+                       rc = uefi_call_wrapper(RT->SetVariable, 5, varname,
+                               &global, EFI_VARIABLE_NON_VOLATILE |
+                                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                        EFI_VARIABLE_RUNTIME_ACCESS,
+                               size, data);
+
+                       FreePool(data);
+
+                       if (EFI_ERROR(rc)) {
+                               Print(L"Could not create variable: %d\n", rc);
+                               return rc;
+                       }
+
+                       CHAR16 *newbootorder = AllocateZeroPool(sizeof (CHAR16)
+                                                       * (nbootorder + 1));
+                       if (!newbootorder)
+                               return EFI_OUT_OF_RESOURCES;
+
+                       int j = 0;
+                       newbootorder[0] = i & 0xffff;
+                       if (nbootorder) {
+                               for (j = 0; j < nbootorder; j++)
+                                       newbootorder[j+1] = bootorder[j];
+                               FreePool(bootorder);
+                       }
+                       bootorder = newbootorder;
+                       nbootorder += 1;
+#ifdef DEBUG_FALLBACK
+                       Print(L"nbootorder: %d\nBootOrder: ", nbootorder);
+                       for (j = 0 ; j < nbootorder ; j++)
+                               Print(L"%04x ", bootorder[j]);
+                       Print(L"\n");
+#endif
+
+                       return EFI_SUCCESS;
+               }
+       }
+       return EFI_OUT_OF_RESOURCES;
+}
+
+EFI_STATUS
+find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp,
+                 CHAR16 *filename, CHAR16 *label, CHAR16 *arguments,
+                 UINT16 *optnum)
+{
+       unsigned int size = sizeof(UINT32) + sizeof (UINT16) +
+               StrLen(label)*2 + 2 + DevicePathSize(dp) +
+               StrLen(arguments) * 2;
+
+       CHAR8 *data = AllocateZeroPool(size + 2);
+       if (!data)
+               return EFI_OUT_OF_RESOURCES;
+       CHAR8 *cursor = data;
+       *(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
+       cursor += sizeof (UINT32);
+       *(UINT16 *)cursor = DevicePathSize(dp);
+       cursor += sizeof (UINT16);
+       StrCpy((CHAR16 *)cursor, label);
+       cursor += StrLen(label)*2 + 2;
+       CopyMem(cursor, dp, DevicePathSize(dp));
+       cursor += DevicePathSize(dp);
+       StrCpy((CHAR16 *)cursor, arguments);
+
+       int i = 0;
+       CHAR16 varname[] = L"Boot0000";
+       CHAR16 hexmap[] = L"0123456789ABCDEF";
+       EFI_GUID global = EFI_GLOBAL_VARIABLE;
+       EFI_STATUS rc;
+
+       CHAR8 *candidate = AllocateZeroPool(size);
+       if (!candidate) {
+               FreePool(data);
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       for(i = 0; i < nbootorder && i < 0x10000; i++) {
+               varname[4] = hexmap[(bootorder[i] & 0xf000) >> 12];
+               varname[5] = hexmap[(bootorder[i] & 0x0f00) >> 8];
+               varname[6] = hexmap[(bootorder[i] & 0x00f0) >> 4];
+               varname[7] = hexmap[(bootorder[i] & 0x000f) >> 0];
+
+               UINTN candidate_size = size;
+               rc = uefi_call_wrapper(RT->GetVariable, 5, varname, &global,
+                                       NULL, &candidate_size, candidate);
+               if (EFI_ERROR(rc))
+                       continue;
+
+               if (candidate_size != size)
+                       continue;
+
+               if (CompareMem(candidate, data, size))
+                       continue;
+
+               /* at this point, we have duplicate data. */
+               if (!first_new_option) {
+                       first_new_option = DuplicateDevicePath(fulldp);
+                       first_new_option_args = arguments;
+                       first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
+               }
+
+               *optnum = i;
+               FreePool(candidate);
+               FreePool(data);
+               return EFI_SUCCESS;
+       }
+       FreePool(candidate);
+       FreePool(data);
+       return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+set_boot_order(void)
+{
+       CHAR16 *oldbootorder;
+       UINTN size;
+       EFI_GUID global = EFI_GLOBAL_VARIABLE;
+
+       oldbootorder = LibGetVariableAndSize(L"BootOrder", &global, &size);
+       if (oldbootorder) {
+               nbootorder = size / sizeof (CHAR16);
+               bootorder = oldbootorder;
+       }
+       return EFI_SUCCESS;
+
+}
+
+EFI_STATUS
+update_boot_order(void)
+{
+       UINTN size;
+       UINTN len = 0;
+       EFI_GUID global = EFI_GLOBAL_VARIABLE;
+       CHAR16 *newbootorder = NULL;
+       EFI_STATUS rc;
+
+       size = nbootorder * sizeof(CHAR16);
+       newbootorder = AllocateZeroPool(size);
+       if (!newbootorder)
+               return EFI_OUT_OF_RESOURCES;
+       CopyMem(newbootorder, bootorder, size);
+
+#ifdef DEBUG_FALLBACK
+       Print(L"nbootorder: %d\nBootOrder: ", size / sizeof (CHAR16));
+       UINTN j;
+       for (j = 0 ; j < size / sizeof (CHAR16); j++)
+               Print(L"%04x ", newbootorder[j]);
+       Print(L"\n");
+#endif
+       rc = uefi_call_wrapper(RT->GetVariable, 5, L"BootOrder", &global,
+                              NULL, &len, NULL);
+       if (rc == EFI_BUFFER_TOO_SMALL)
+               LibDeleteVariable(L"BootOrder", &global);
+
+       rc = uefi_call_wrapper(RT->SetVariable, 5, L"BootOrder", &global,
+                                       EFI_VARIABLE_NON_VOLATILE |
+                                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                        EFI_VARIABLE_RUNTIME_ACCESS,
+                                       size, newbootorder);
+       FreePool(newbootorder);
+       return rc;
+}
+
+EFI_STATUS
+add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
+{
+       CHAR16 *fullpath = NULL;
+       UINT64 pathlen = 0;
+       EFI_STATUS rc = EFI_SUCCESS;
+
+       rc = make_full_path(dirname, filename, &fullpath, &pathlen);
+       if (EFI_ERROR(rc))
+               return rc;
+       
+       EFI_DEVICE_PATH *dph = NULL;
+       EFI_DEVICE_PATH *file = NULL;
+       EFI_DEVICE_PATH *full_device_path = NULL;
+       EFI_DEVICE_PATH *dp = NULL;
+       
+       dph = DevicePathFromHandle(this_image->DeviceHandle);
+       if (!dph) {
+               rc = EFI_OUT_OF_RESOURCES;
+               goto err;
+       }
+
+       file = FileDevicePath(fh, fullpath);
+       if (!file) {
+               rc = EFI_OUT_OF_RESOURCES;
+               goto err;
+       }
+
+       full_device_path = AppendDevicePath(dph, file);
+       if (!full_device_path) {
+               rc = EFI_OUT_OF_RESOURCES;
+               goto err;
+       }
+
+       rc = FindSubDevicePath(full_device_path,
+                               MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, &dp);
+       if (EFI_ERROR(rc)) {
+               if (rc == EFI_NOT_FOUND) {
+                       dp = full_device_path;
+               } else {
+                       rc = EFI_OUT_OF_RESOURCES;
+                       goto err;
+               }
+       }
+
+#ifdef DEBUG_FALLBACK
+       {
+       UINTN s = DevicePathSize(dp);
+       UINTN i;
+       UINT8 *dpv = (void *)dp;
+       for (i = 0; i < s; i++) {
+               if (i > 0 && i % 16 == 0)
+                       Print(L"\n");
+               Print(L"%02x ", dpv[i]);
+       }
+       Print(L"\n");
+
+       CHAR16 *dps = DevicePathToStr(dp);
+       Print(L"device path: \"%s\"\n", dps);
+       }
+#endif
+
+       UINT16 option;
+       rc = find_boot_option(dp, full_device_path, fullpath, label, arguments, &option);
+       if (EFI_ERROR(rc)) {
+               add_boot_option(dp, full_device_path, fullpath, label, arguments);
+       } else if (option != 0) {
+               CHAR16 *newbootorder;
+               newbootorder = AllocateZeroPool(sizeof (CHAR16) * nbootorder);
+               if (!newbootorder)
+                       return EFI_OUT_OF_RESOURCES;
+
+               newbootorder[0] = bootorder[option];
+               CopyMem(newbootorder + 1, bootorder, sizeof (CHAR16) * option);
+               CopyMem(newbootorder + option + 1, bootorder + option + 1,
+                       sizeof (CHAR16) * (nbootorder - option - 1));
+               FreePool(bootorder);
+               bootorder = newbootorder;
+       }
+
+err:
+       if (file)
+               FreePool(file);
+       if (full_device_path)
+               FreePool(full_device_path);
+       if (dp)
+               FreePool(dp);
+       if (fullpath)
+               FreePool(fullpath);
+       return rc;
+}
+
+EFI_STATUS
+populate_stanza(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *csv)
+{
+#ifdef DEBUG_FALLBACK
+       Print(L"CSV data: \"%s\"\n", csv);
+#endif
+       CHAR16 *file = csv;
+
+       UINTN comma0 = StrCSpn(csv, L",");
+       if (comma0 == 0)
+               return EFI_INVALID_PARAMETER;
+       file[comma0] = L'\0';
+#ifdef DEBUG_FALLBACK
+       Print(L"filename: \"%s\"\n", file);
+#endif
+
+       CHAR16 *label = csv + comma0 + 1;
+       UINTN comma1 = StrCSpn(label, L",");
+       if (comma1 == 0)
+               return EFI_INVALID_PARAMETER;
+       label[comma1] = L'\0';
+#ifdef DEBUG_FALLBACK
+       Print(L"label: \"%s\"\n", label);
+#endif
+
+       CHAR16 *arguments = csv + comma0 +1 + comma1 +1;
+       UINTN comma2 = StrCSpn(arguments, L",");
+       arguments[comma2] = L'\0';
+       /* This one is optional, so don't check if comma2 is 0 */
+#ifdef DEBUG_FALLBACK
+       Print(L"arguments: \"%s\"\n", arguments);
+#endif
+
+       add_to_boot_list(fh, dirname, file, label, arguments);
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+try_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename)
+{
+       CHAR16 *fullpath = NULL;
+       UINT64 pathlen = 0;
+       EFI_STATUS rc;
+
+       rc = make_full_path(dirname, filename, &fullpath, &pathlen);
+       if (EFI_ERROR(rc))
+               return rc;
+
+#ifdef DEBUG_FALLBACK
+       Print(L"Found file \"%s\"\n", fullpath);
+#endif
+
+       CHAR16 *buffer;
+       UINT64 bs;
+       rc = read_file(fh, fullpath, &buffer, &bs);
+       if (EFI_ERROR(rc)) {
+               Print(L"Could not read file \"%s\": %d\n", fullpath, rc);
+               FreePool(fullpath);
+               return rc;
+       }
+       FreePool(fullpath);
+
+#ifdef DEBUG_FALLBACK
+       Print(L"File looks like:\n%s\n", buffer);
+#endif
+
+       CHAR16 *start = buffer;
+       /* The file may or may not start with the Unicode byte order marker.
+        * Sadness ensues.  Since UEFI is defined as LE, I'm going to decree
+        * that these files must also be LE.
+        *
+        * IT IS THUS SO.
+        *
+        * But if we find the LE byte order marker, just skip it.
+        */
+       if (*start == 0xfeff)
+               start++;
+       while (*start) {
+               while (*start == L'\r' || *start == L'\n')
+                       start++;
+               UINTN l = StrCSpn(start, L"\r\n");
+               if (l == 0) {
+                       if (start[l] == L'\0')
+                               break;
+                       start++;
+                       continue;
+               }
+               CHAR16 c = start[l];
+               start[l] = L'\0';
+
+               populate_stanza(fh, dirname, filename, start);
+
+               start[l] = c;
+               start += l;
+       }
+
+       FreePool(buffer);
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+find_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname)
+{
+       EFI_STATUS rc;
+       void *buffer = NULL;
+       UINTN bs = 0;
+       EFI_GUID finfo = EFI_FILE_INFO_ID;
+
+       /* The API here is "Call it once with bs=0, it fills in bs,
+        * then allocate a buffer and ask again to get it filled. */
+       rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, &bs, NULL);
+       if (rc == EFI_BUFFER_TOO_SMALL) {
+               buffer = AllocateZeroPool(bs);
+               if (!buffer) {
+                       Print(L"Could not allocate memory\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+               rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo,
+                                       &bs, buffer);
+       }
+       /* This checks *either* the error from the first GetInfo, if it isn't
+        * the EFI_BUFFER_TOO_SMALL we're expecting, or the second GetInfo call
+        * in *any* case. */
+       if (EFI_ERROR(rc)) {
+               Print(L"Could not get info for \"%s\": %d\n", dirname, rc);
+               if (buffer)
+                       FreePool(buffer);
+               return rc;
+       }
+
+       EFI_FILE_INFO *fi = buffer;
+       if (!(fi->Attribute & EFI_FILE_DIRECTORY)) {
+               FreePool(buffer);
+               return EFI_SUCCESS;
+       }
+       FreePool(buffer);
+       buffer = NULL;
+
+       CHAR16 *bootcsv=NULL, *bootarchcsv=NULL;
+
+       bs = 0;
+       do {
+               bs = 0;
+               rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, NULL);
+               if (EFI_ERROR(rc) && rc != EFI_BUFFER_TOO_SMALL) {
+                       Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc);
+                       if (buffer)
+                               FreePool(buffer);
+                       return rc;
+               }
+
+               buffer = AllocateZeroPool(bs);
+               if (!buffer) {
+                       Print(L"Could not allocate memory\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+
+               rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, buffer);
+               if (EFI_ERROR(rc)) {
+                       Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc);
+                       FreePool(buffer);
+                       return rc;
+               }
+
+               if (bs == 0)
+                       break;
+
+               fi = buffer;
+
+               if (!bootcsv && !StrCaseCmp(fi->FileName, L"boot.csv"))
+                       bootcsv = StrDuplicate(fi->FileName);
+
+               if (!bootarchcsv &&
+                   !StrCaseCmp(fi->FileName, L"boot" EFI_ARCH L".csv"))
+                       bootarchcsv = StrDuplicate(fi->FileName);
+
+               FreePool(buffer);
+               buffer = NULL;
+       } while (bs != 0);
+
+       rc = EFI_SUCCESS;
+       if (bootarchcsv) {
+               EFI_FILE_HANDLE fh2;
+               rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2,
+                                      bootarchcsv, EFI_FILE_READ_ONLY, 0);
+               if (EFI_ERROR(rc) || fh2 == NULL) {
+                       Print(L"Couldn't open \\EFI\\%s\\%s: %d\n",
+                             dirname, bootarchcsv, rc);
+               } else {
+                       rc = try_boot_csv(fh2, dirname, bootarchcsv);
+                       uefi_call_wrapper(fh2->Close, 1, fh2);
+               }
+       }
+       if ((EFI_ERROR(rc) || !bootarchcsv) && bootcsv) {
+               EFI_FILE_HANDLE fh2;
+               rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2,
+                                      bootcsv, EFI_FILE_READ_ONLY, 0);
+               if (EFI_ERROR(rc) || fh2 == NULL) {
+                       Print(L"Couldn't open \\EFI\\%s\\%s: %d\n",
+                             dirname, bootcsv, rc);
+               } else {
+                       rc = try_boot_csv(fh2, dirname, bootcsv);
+                       uefi_call_wrapper(fh2->Close, 1, fh2);
+               }
+       }
+       rc = EFI_SUCCESS;
+
+       return rc;
+}
+
+EFI_STATUS
+find_boot_options(EFI_HANDLE device)
+{
+       EFI_STATUS rc = EFI_SUCCESS;
+
+       EFI_FILE_IO_INTERFACE *fio = NULL;
+       rc = uefi_call_wrapper(BS->HandleProtocol, 3, device,
+                               &FileSystemProtocol, (void **)&fio);
+       if (EFI_ERROR(rc)) {
+               Print(L"Couldn't find file system: %d\n", rc);
+               return rc;
+       }
+
+       /* EFI_FILE_HANDLE is a pointer to an EFI_FILE, and I have
+        * *no idea* what frees the memory allocated here. Hopefully
+        * Close() does. */
+       EFI_FILE_HANDLE fh = NULL;
+       rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &fh);
+       if (EFI_ERROR(rc) || fh == NULL) {
+               Print(L"Couldn't open file system: %d\n", rc);
+               return rc;
+       }
+
+       EFI_FILE_HANDLE fh2 = NULL;
+       rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, L"EFI",
+                                               EFI_FILE_READ_ONLY, 0);
+       if (EFI_ERROR(rc) || fh2 == NULL) {
+               Print(L"Couldn't open EFI: %d\n", rc);
+               uefi_call_wrapper(fh->Close, 1, fh);
+               return rc;
+       }
+       rc = uefi_call_wrapper(fh2->SetPosition, 2, fh2, 0);
+       if (EFI_ERROR(rc)) {
+               Print(L"Couldn't set file position: %d\n", rc);
+               uefi_call_wrapper(fh2->Close, 1, fh2);
+               uefi_call_wrapper(fh->Close, 1, fh);
+               return rc;
+       }
+
+       void *buffer;
+       UINTN bs;
+       do {
+               bs = 0;
+               rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, NULL);
+               if (rc == EFI_BUFFER_TOO_SMALL ||
+                               (rc == EFI_SUCCESS && bs != 0)) {
+                       buffer = AllocateZeroPool(bs);
+                       if (!buffer) {
+                               Print(L"Could not allocate memory\n");
+                               /* sure, this might work, why not? */
+                               uefi_call_wrapper(fh2->Close, 1, fh2);
+                               uefi_call_wrapper(fh->Close, 1, fh);
+                               return EFI_OUT_OF_RESOURCES;
+                       }
+
+                       rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, buffer);
+               }
+               if (bs == 0)
+                       break;
+
+               if (EFI_ERROR(rc)) {
+                       Print(L"Could not read \\EFI\\: %d\n", rc);
+                       if (buffer) {
+                               FreePool(buffer);
+                               buffer = NULL;
+                       }
+                       uefi_call_wrapper(fh2->Close, 1, fh2);
+                       uefi_call_wrapper(fh->Close, 1, fh);
+                       return rc;
+               }
+               EFI_FILE_INFO *fi = buffer;
+
+               if (!(fi->Attribute & EFI_FILE_DIRECTORY)) {
+                       FreePool(buffer);
+                       buffer = NULL;
+                       continue;
+               }
+               if (!StrCmp(fi->FileName, L".") ||
+                               !StrCmp(fi->FileName, L"..") ||
+                               !StrCaseCmp(fi->FileName, L"BOOT")) {
+                       FreePool(buffer);
+                       buffer = NULL;
+                       continue;
+               }
+#ifdef DEBUG_FALLBACK
+               Print(L"Found directory named \"%s\"\n", fi->FileName);
+#endif
+
+               EFI_FILE_HANDLE fh3;
+               rc = uefi_call_wrapper(fh->Open, 5, fh2, &fh3, fi->FileName,
+                                               EFI_FILE_READ_ONLY, 0);
+               if (EFI_ERROR(rc)) {
+                       Print(L"%d Couldn't open %s: %d\n", __LINE__, fi->FileName, rc);
+                       FreePool(buffer);
+                       buffer = NULL;
+                       continue;
+               }
+
+               rc = find_boot_csv(fh3, fi->FileName);
+               FreePool(buffer);
+               buffer = NULL;
+               if (rc == EFI_OUT_OF_RESOURCES)
+                       break;
+
+       } while (1);
+
+       if (rc == EFI_SUCCESS && nbootorder > 0)
+               rc = update_boot_order();
+
+       uefi_call_wrapper(fh2->Close, 1, fh2);
+       uefi_call_wrapper(fh->Close, 1, fh);
+       return rc;
+}
+
+static EFI_STATUS
+try_start_first_option(EFI_HANDLE parent_image_handle)
+{
+       EFI_STATUS rc;
+       EFI_HANDLE image_handle;
+
+       if (!first_new_option) {
+               return EFI_SUCCESS;
+       }
+
+       rc = uefi_call_wrapper(BS->LoadImage, 6, 0, parent_image_handle,
+                              first_new_option, NULL, 0,
+                              &image_handle);
+       if (EFI_ERROR(rc)) {
+               CHAR16 *dps = DevicePathToStr(first_new_option);
+               UINTN s = DevicePathSize(first_new_option);
+               unsigned int i;
+               UINT8 *dpv = (void *)first_new_option;
+               Print(L"LoadImage failed: %d\nDevice path: \"%s\"\n", rc, dps);
+               for (i = 0; i < s; i++) {
+                       if (i > 0 && i % 16 == 0)
+                               Print(L"\n");
+                       Print(L"%02x ", dpv[i]);
+               }
+               Print(L"\n");
+
+               uefi_call_wrapper(BS->Stall, 1, 500000000);
+               return rc;
+       }
+
+       EFI_LOADED_IMAGE *image;
+       rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, &LoadedImageProtocol, (void *)&image);
+       if (!EFI_ERROR(rc)) {
+               image->LoadOptions = first_new_option_args;
+               image->LoadOptionsSize = first_new_option_size;
+       }
+
+       rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL);
+       if (EFI_ERROR(rc)) {
+               Print(L"StartImage failed: %d\n", rc);
+               uefi_call_wrapper(BS->Stall, 1, 500000000);
+       }
+       return rc;
+}
+
+EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+extern EFI_STATUS
+efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
+
+static void
+__attribute__((__optimize__("0")))
+debug_hook(void)
+{
+       EFI_GUID guid = SHIM_LOCK_GUID;
+       UINT8 *data = NULL;
+       UINTN dataSize = 0;
+       EFI_STATUS efi_status;
+       volatile register int x = 0;
+       extern char _etext, _edata;
+
+       efi_status = get_variable(L"SHIM_DEBUG", &data, &dataSize, guid);
+       if (EFI_ERROR(efi_status)) {
+               return;
+       }
+
+       if (x)
+               return;
+
+       x = 1;
+       Print(L"add-symbol-file "DEBUGDIR
+             L"fb" EFI_ARCH L".efi.debug %p -s .data %p\n", &_etext,
+             &_edata);
+}
+
+EFI_STATUS
+efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+       EFI_STATUS rc;
+
+       InitializeLib(image, systab);
+
+       /*
+        * if SHIM_DEBUG is set, wait for a debugger to attach.
+        */
+       debug_hook();
+
+       rc = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (void *)&this_image);
+       if (EFI_ERROR(rc)) {
+               Print(L"Error: could not find loaded image: %d\n", rc);
+               return rc;
+       }
+
+       Print(L"System BootOrder not found.  Initializing defaults.\n");
+
+       set_boot_order();
+
+       rc = find_boot_options(this_image->DeviceHandle);
+       if (EFI_ERROR(rc)) {
+               Print(L"Error: could not find boot options: %d\n", rc);
+               return rc;
+       }
+
+       try_start_first_option(image);
+
+       Print(L"Reset System\n");
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold,
+                         EFI_SUCCESS, 0, NULL);
+
+       return EFI_SUCCESS;
+}
diff --git a/hexdump.h b/hexdump.h
new file mode 100644 (file)
index 0000000..d5ece4d
--- /dev/null
+++ b/hexdump.h
@@ -0,0 +1,104 @@
+#ifndef STATIC_HEXDUMP_H
+#define STATIC_HEXDUMP_H
+
+static int
+__attribute__((__unused__))
+isprint(char c)
+{
+       if (c < 0x20)
+               return 0;
+       if (c > 0x7e)
+               return 0;
+       return 1;
+}
+
+static UINTN
+__attribute__((__unused__))
+format_hex(UINT8 *data, UINTN size, CHAR16 *buf)
+{
+       UINTN sz = (UINTN)data % 16;
+       CHAR16 hexchars[] = L"0123456789abcdef";
+       int offset = 0;
+       UINTN i;
+       UINTN j;
+
+       for (i = 0; i < sz; i++) {
+               buf[offset++] = L' ';
+               buf[offset++] = L' ';
+               buf[offset++] = L' ';
+               if (i == 7)
+                       buf[offset++] = L' ';
+       }
+       for (j = sz; j < 16 && j < size; j++) {
+               UINT8 d = data[j-sz];
+               buf[offset++] = hexchars[(d & 0xf0) >> 4];
+               buf[offset++] = hexchars[(d & 0x0f)];
+               if (j != 15)
+                       buf[offset++] = L' ';
+               if (j == 7)
+                       buf[offset++] = L' ';
+       }
+       for (i = j; i < 16; i++) {
+               buf[offset++] = L' ';
+               buf[offset++] = L' ';
+               if (i != 15)
+                       buf[offset++] = L' ';
+               if (i == 7)
+                       buf[offset++] = L' ';
+       }
+       buf[offset] = L'\0';
+       return j - sz;
+}
+
+static void
+__attribute__((__unused__))
+format_text(UINT8 *data, UINTN size, CHAR16 *buf)
+{
+       UINTN sz = (UINTN)data % 16;
+       int offset = 0;
+       UINTN i;
+       UINTN j;
+
+       for (i = 0; i < sz; i++)
+               buf[offset++] = L' ';
+       buf[offset++] = L'|';
+       for (j = sz; j < 16 && j < size; j++) {
+               if (isprint(data[j-sz]))
+                       buf[offset++] = data[j-sz];
+               else
+                       buf[offset++] = L'.';
+       }
+       buf[offset++] = L'|';
+       for (i = j; i < 16; i++)
+               buf[offset++] = L' ';
+       buf[offset] = L'\0';
+}
+
+static void
+__attribute__((__unused__))
+hexdump(UINT8 *data, UINTN size)
+{
+       UINTN display_offset = (UINTN)data & 0xffffffff;
+       UINTN offset = 0;
+       //Print(L"hexdump: data=0x%016x size=0x%x\n", data, size);
+
+       while (offset < size) {
+               CHAR16 hexbuf[49];
+               CHAR16 txtbuf[19];
+               UINTN sz;
+
+               sz = format_hex(data+offset, size-offset, hexbuf);
+               if (sz == 0)
+                       return;
+               uefi_call_wrapper(BS->Stall, 1, 200000);
+
+               format_text(data+offset, size-offset, txtbuf);
+               Print(L"%08x  %s  %s\n", display_offset, hexbuf, txtbuf);
+               uefi_call_wrapper(BS->Stall, 1, 200000);
+
+               display_offset += sz;
+               offset += sz;
+       }
+}
+
+#endif
diff --git a/httpboot.c b/httpboot.c
new file mode 100644 (file)
index 0000000..ad01b8d
--- /dev/null
@@ -0,0 +1,774 @@
+/*
+ * Copyright 2015 SUSE LINUX GmbH <glin@suse.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#include <efi.h>
+#include <efilib.h>
+#include "str.h"
+#include "Http.h"
+#include "Ip4Config2.h"
+#include "Ip6Config.h"
+
+extern UINT8 in_protocol;
+
+#define perror(fmt, ...) ({                                            \
+               UINTN __perror_ret = 0;                                 \
+               if (!in_protocol)                                       \
+                       __perror_ret = Print((fmt), ##__VA_ARGS__);     \
+               __perror_ret;                                           \
+       })
+
+static UINTN
+ascii_to_int (CONST CHAR8 *str)
+{
+    UINTN u;
+    CHAR8 c;
+
+    // skip preceeding white space
+    while (*str && *str == ' ') {
+        str += 1;
+    }
+
+    // convert digits
+    u = 0;
+    while ((c = *(str++))) {
+        if (c >= '0' && c <= '9') {
+            u = (u * 10) + c - '0';
+        } else {
+            break;
+        }
+    }
+
+    return u;
+}
+
+static UINTN
+convert_http_status_code (EFI_HTTP_STATUS_CODE status_code)
+{
+       if (status_code >= HTTP_STATUS_100_CONTINUE &&
+           status_code <  HTTP_STATUS_200_OK) {
+               return (status_code - HTTP_STATUS_100_CONTINUE + 100);
+       } else if (status_code >= HTTP_STATUS_200_OK &&
+                  status_code <  HTTP_STATUS_300_MULTIPLE_CHIOCES) {
+               return (status_code - HTTP_STATUS_200_OK + 200);
+       } else if (status_code >= HTTP_STATUS_300_MULTIPLE_CHIOCES &&
+                  status_code <  HTTP_STATUS_400_BAD_REQUEST) {
+               return (status_code - HTTP_STATUS_300_MULTIPLE_CHIOCES + 300);
+       } else if (status_code >= HTTP_STATUS_400_BAD_REQUEST &&
+                  status_code <  HTTP_STATUS_500_INTERNAL_SERVER_ERROR) {
+               return (status_code - HTTP_STATUS_400_BAD_REQUEST + 400);
+       } else if (status_code >= HTTP_STATUS_500_INTERNAL_SERVER_ERROR) {
+               return (status_code - HTTP_STATUS_500_INTERNAL_SERVER_ERROR + 500);
+       }
+
+       return 0;
+}
+
+static EFI_DEVICE_PATH *devpath;
+static EFI_MAC_ADDRESS mac_addr;
+static IPv4_DEVICE_PATH ip4_node;
+static IPv6_DEVICE_PATH ip6_node;
+static BOOLEAN is_ip6;
+static CHAR8 *uri;
+
+BOOLEAN
+find_httpboot (EFI_HANDLE device)
+{
+       EFI_DEVICE_PATH *unpacked;
+       EFI_DEVICE_PATH *Node;
+       EFI_DEVICE_PATH *NextNode;
+       MAC_ADDR_DEVICE_PATH *MacNode;
+       URI_DEVICE_PATH *UriNode;
+       UINTN uri_size;
+
+       if (!uri)
+               FreePool(uri);
+
+       devpath = DevicePathFromHandle(device);
+       if (!devpath) {
+               perror(L"Failed to get device path\n");
+               return FALSE;
+       }
+
+       unpacked = UnpackDevicePath(devpath);
+       if (!unpacked) {
+               perror(L"Failed to unpack device path\n");
+               return FALSE;
+       }
+       Node = unpacked;
+
+       /* Traverse the device path to find IPv4()/Uri() or IPv6()/Uri() */
+       while (!IsDevicePathEnd(Node)) {
+               /* Save the MAC node so we can match the net card later */
+               if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
+                   DevicePathSubType(Node) == MSG_MAC_ADDR_DP) {
+                       MacNode = (MAC_ADDR_DEVICE_PATH *)Node;
+                       CopyMem(&mac_addr, &MacNode->MacAddress, sizeof(EFI_MAC_ADDRESS));
+               }
+
+               if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
+                   (DevicePathSubType(Node) == MSG_IPv4_DP ||
+                    DevicePathSubType(Node) == MSG_IPv6_DP)) {
+                       /* Save the IP node so we can set up the connection later */
+                       if (DevicePathSubType(Node) == MSG_IPv6_DP) {
+                               CopyMem(&ip6_node, Node, sizeof(IPv6_DEVICE_PATH));
+                               is_ip6 = TRUE;
+                       } else {
+                               CopyMem(&ip4_node, Node, sizeof(IPv4_DEVICE_PATH));
+                               is_ip6 = FALSE;
+                       }
+
+                       Node = NextDevicePathNode(Node);
+                       NextNode = NextDevicePathNode(Node);
+                       if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
+                           DevicePathSubType(Node) == MSG_URI_DP &&
+                           IsDevicePathEnd(NextNode)) {
+                               /* Save the current URI */
+                               UriNode = (URI_DEVICE_PATH *)Node;
+                               uri_size = strlena(UriNode->Uri);
+                               uri = AllocatePool(uri_size + 1);
+                               if (!uri) {
+                                       perror(L"Failed to allocate uri\n");
+                                       return FALSE;
+                               }
+                               CopyMem(uri, UriNode->Uri, uri_size + 1);
+                               FreePool(unpacked);
+                               return TRUE;
+                       }
+               }
+               Node = NextDevicePathNode(Node);
+       }
+
+       FreePool(unpacked);
+       return FALSE;
+}
+
+static EFI_STATUS
+generate_next_uri (CONST CHAR8 *current_uri, CONST CHAR8 *next_loader,
+                  CHAR8 **uri)
+{
+       CONST CHAR8 *ptr;
+       UINTN next_len;
+       UINTN path_len = 0;
+       UINTN count = 0;
+
+       if (strncmpa(current_uri, (CHAR8 *)"http://", 7) == 0) {
+               ptr = current_uri + 7;
+               count += 7;
+       } else {
+               return EFI_INVALID_PARAMETER;
+       }
+
+       /* Extract the path */
+       next_len = strlena(next_loader);
+       while (*ptr != '\0') {
+               count++;
+               if (*ptr == '/')
+                       path_len = count;
+               ptr++;
+       }
+
+       *uri = AllocatePool(sizeof(CHAR8) * (path_len + next_len + 1));
+       if (!*uri)
+               return EFI_OUT_OF_RESOURCES;
+
+       CopyMem(*uri, current_uri, path_len);
+       CopyMem(*uri + path_len, next_loader, next_len);
+       (*uri)[path_len + next_len] = '\0';
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS
+extract_hostname (CONST CHAR8 *url, CHAR8 **hostname)
+{
+       CONST CHAR8 *ptr, *start;
+       UINTN host_len = 0;
+
+       if (strncmpa(url, (CHAR8 *)"http://", 7) == 0)
+               start = url + 7;
+       else
+               return EFI_INVALID_PARAMETER;
+
+       ptr = start;
+       while (*ptr != '/' && *ptr != '\0') {
+               host_len++;
+               ptr++;
+       }
+
+       *hostname = AllocatePool(sizeof(CHAR8) * (host_len + 1));
+       if (!*hostname)
+               return EFI_OUT_OF_RESOURCES;
+
+       CopyMem(*hostname, start, host_len);
+       (*hostname)[host_len] = '\0';
+
+       return EFI_SUCCESS;
+}
+
+#define SAME_MAC_ADDR(a, b) (!CompareMem(a, b, sizeof(EFI_MAC_ADDRESS)))
+
+static EFI_HANDLE
+get_nic_handle (EFI_MAC_ADDRESS *mac)
+{
+       EFI_GUID http_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID;
+       EFI_DEVICE_PATH *unpacked = NULL;
+       EFI_DEVICE_PATH *Node;
+       EFI_DEVICE_PATH *temp_path = NULL;
+       MAC_ADDR_DEVICE_PATH *MacNode;
+       EFI_HANDLE handle = NULL;
+       EFI_HANDLE *buffer;
+       UINTN NoHandles;
+       UINTN i;
+       EFI_STATUS status;
+
+       /* Get the list of handles that support the HTTP service binding
+          protocol */
+       status = uefi_call_wrapper(BS->LocateHandleBuffer, 5,
+                                  ByProtocol,
+                                  &http_binding_guid,
+                                  NULL,
+                                  &NoHandles,
+                                  &buffer);
+       if (EFI_ERROR(status))
+               return NULL;
+
+       for (i = 0; i < NoHandles; i++) {
+               temp_path = DevicePathFromHandle(buffer[i]);
+
+               /* Match the MAC address */
+               unpacked = UnpackDevicePath(temp_path);
+               if (!unpacked) {
+                       perror(L"Failed to unpack device path\n");
+                       continue;
+               }
+               Node = unpacked;
+               while (!IsDevicePathEnd(Node)) {
+                       if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
+                           DevicePathSubType(Node) == MSG_MAC_ADDR_DP) {
+                               MacNode = (MAC_ADDR_DEVICE_PATH *)Node;
+                               if (SAME_MAC_ADDR(mac, &MacNode->MacAddress)) {
+                                       handle = buffer[i];
+                                       goto out;
+                               }
+                       }
+                       Node = NextDevicePathNode(Node);
+               }
+               FreePool(unpacked);
+               unpacked = NULL;
+       }
+
+out:
+       if (unpacked)
+               FreePool(unpacked);
+       FreePool(buffer);
+
+       return handle;
+}
+
+static BOOLEAN
+is_unspecified_addr (EFI_IPv6_ADDRESS ip6)
+{
+       UINT8 i;
+
+       for (i = 0; i<16; i++) {
+               if (ip6.Addr[i] != 0)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static EFI_STATUS
+set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
+{
+       EFI_GUID ip6_config_guid = EFI_IP6_CONFIG_PROTOCOL_GUID;
+       EFI_IP6_CONFIG_PROTOCOL *ip6cfg;
+       EFI_IP6_CONFIG_MANUAL_ADDRESS ip6;
+       EFI_IPv6_ADDRESS gateway;
+       EFI_STATUS status;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3,
+                                  nic,
+                                  &ip6_config_guid,
+                                  (VOID **)&ip6cfg);
+       if (EFI_ERROR (status))
+               return status;
+
+       ip6.Address = ip6node->LocalIpAddress;
+       ip6.PrefixLength = ip6node->PrefixLength;
+       ip6.IsAnycast = FALSE;
+       status = uefi_call_wrapper(ip6cfg->SetData, 4,
+                                  ip6cfg,
+                                  Ip6ConfigDataTypeManualAddress,
+                                  sizeof(ip6),
+                                  &ip6);
+       if (EFI_ERROR (status))
+               return status;
+
+       gateway = ip6node->GatewayIpAddress;
+       if (is_unspecified_addr(gateway))
+               return EFI_SUCCESS;
+
+       status = uefi_call_wrapper(ip6cfg->SetData, 4,
+                                  ip6cfg,
+                                  Ip6ConfigDataTypeGateway,
+                                  sizeof(gateway),
+                                  &gateway);
+       if (EFI_ERROR (status))
+               return status;
+
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS
+set_ip4(EFI_HANDLE *nic, IPv4_DEVICE_PATH *ip4node)
+{
+       EFI_GUID ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID;
+       EFI_IP4_CONFIG2_PROTOCOL *ip4cfg2;
+       EFI_IP4_CONFIG2_MANUAL_ADDRESS ip4;
+       EFI_IPv4_ADDRESS gateway;
+       EFI_STATUS status;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3,
+                                  nic,
+                                  &ip4_config2_guid,
+                                  (VOID **)&ip4cfg2);
+       if (EFI_ERROR (status))
+               return status;
+
+       ip4.Address = ip4node->LocalIpAddress;
+       ip4.SubnetMask = ip4node->SubnetMask;
+       status = uefi_call_wrapper(ip4cfg2->SetData, 4,
+                                  ip4cfg2,
+                                  Ip4Config2DataTypeManualAddress,
+                                  sizeof(ip4),
+                                  &ip4);
+       if (EFI_ERROR (status))
+               return status;
+
+       gateway = ip4node->GatewayIpAddress;
+       status = uefi_call_wrapper(ip4cfg2->SetData, 4,
+                                  ip4cfg2,
+                                  Ip4Config2DataTypeGateway,
+                                  sizeof(gateway),
+                                  &gateway);
+       if (EFI_ERROR (status))
+               return status;
+
+       return EFI_SUCCESS;
+}
+
+static VOID EFIAPI
+httpnotify (EFI_EVENT Event, VOID *Context)
+{
+       *((BOOLEAN *) Context) = TRUE;
+}
+
+static EFI_STATUS
+configure_http (EFI_HTTP_PROTOCOL *http, BOOLEAN is_ip6)
+{
+       EFI_HTTP_CONFIG_DATA http_mode;
+       EFI_HTTPv4_ACCESS_POINT ip4node;
+       EFI_HTTPv6_ACCESS_POINT ip6node;
+
+       /* Configure HTTP */
+       ZeroMem(&http_mode, sizeof(http_mode));
+       http_mode.HttpVersion = HttpVersion11;
+       /* use the default time out */
+       http_mode.TimeOutMillisec = 0;
+
+       if (!is_ip6) {
+               http_mode.LocalAddressIsIPv6 = FALSE;
+               ZeroMem(&ip4node, sizeof(ip4node));
+               ip4node.UseDefaultAddress = TRUE;
+               http_mode.AccessPoint.IPv4Node = &ip4node;
+       } else {
+               http_mode.LocalAddressIsIPv6 = TRUE;
+               ZeroMem(&ip6node, sizeof(ip6node));
+               http_mode.AccessPoint.IPv6Node = &ip6node;
+       }
+
+       return uefi_call_wrapper(http->Configure, 2, http, &http_mode);
+}
+
+static EFI_STATUS
+send_http_request (EFI_HTTP_PROTOCOL *http, CHAR8 *hostname, CHAR8 *uri)
+{
+       EFI_HTTP_TOKEN tx_token;
+       EFI_HTTP_MESSAGE tx_message;
+       EFI_HTTP_REQUEST_DATA request;
+       EFI_HTTP_HEADER headers[3];
+       BOOLEAN request_done;
+       CHAR16 *Url = NULL;
+       EFI_STATUS status;
+       EFI_STATUS event_status;
+
+       /* Convert the ascii string to the UCS2 string */
+       Url = PoolPrint(L"%a", uri);
+       if (!Url)
+               return EFI_OUT_OF_RESOURCES;
+
+       request.Method = HttpMethodGet;
+       request.Url = Url;
+
+       /* Prepare the HTTP headers */
+       headers[0].FieldName = (CHAR8 *)"Host";
+       headers[0].FieldValue = hostname;
+       headers[1].FieldName = (CHAR8 *)"Accept";
+       headers[1].FieldValue = (CHAR8 *)"*/*";
+       headers[2].FieldName = (CHAR8 *)"User-Agent";
+       headers[2].FieldValue = (CHAR8 *)"UefiHttpBoot/1.0";
+
+       tx_message.Data.Request = &request;
+       tx_message.HeaderCount = 3;
+       tx_message.Headers = headers;
+       tx_message.BodyLength = 0;
+       tx_message.Body = NULL;
+
+       tx_token.Status = EFI_NOT_READY;
+       tx_token.Message = &tx_message;
+       tx_token.Event = NULL;
+       request_done = FALSE;
+       status = uefi_call_wrapper(BS->CreateEvent, 5,
+                                  EVT_NOTIFY_SIGNAL,
+                                  TPL_NOTIFY,
+                                  httpnotify,
+                                  &request_done,
+                                  &tx_token.Event);
+       if (EFI_ERROR(status)) {
+               perror(L"Failed to Create Event for HTTP request: %r\n", status);
+               goto no_event;
+       }
+
+       /* Send out the request */
+       status = uefi_call_wrapper(http->Request, 2, http, &tx_token);
+       if (EFI_ERROR(status)) {
+               perror(L"HTTP request failed: %r\n", status);
+               goto error;
+       }
+
+       /* Wait for the response */
+       while (!request_done)
+               uefi_call_wrapper(http->Poll, 1, http);
+
+       if (EFI_ERROR(tx_token.Status)) {
+               perror(L"HTTP request: %r\n", tx_token.Status);
+               status = tx_token.Status;
+       }
+
+error:
+       event_status = uefi_call_wrapper(BS->CloseEvent, 1, tx_token.Event);
+       if (EFI_ERROR(event_status)) {
+               perror(L"Failed to close Event for HTTP request: %r\n",
+                      event_status);
+       }
+
+no_event:
+       if (Url)
+               FreePool(Url);
+
+       return status;
+}
+
+static EFI_STATUS
+receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINTN *buf_size)
+{
+       EFI_HTTP_TOKEN rx_token;
+       EFI_HTTP_MESSAGE rx_message;
+       EFI_HTTP_RESPONSE_DATA response;
+       EFI_HTTP_STATUS_CODE http_status;
+       BOOLEAN response_done;
+       UINTN i, downloaded;
+       CHAR8 rx_buffer[9216];
+       EFI_STATUS status;
+       EFI_STATUS event_status;
+
+       /* Initialize the rx message and buffer */
+       response.StatusCode = HTTP_STATUS_UNSUPPORTED_STATUS;
+       rx_message.Data.Response = &response;
+       rx_message.HeaderCount = 0;
+       rx_message.Headers = 0;
+       rx_message.BodyLength = sizeof(rx_buffer);
+       rx_message.Body = rx_buffer;
+
+       rx_token.Status = EFI_NOT_READY;
+       rx_token.Message = &rx_message;
+       rx_token.Event = NULL;
+       response_done = FALSE;
+       status = uefi_call_wrapper(BS->CreateEvent, 5,
+                                  EVT_NOTIFY_SIGNAL,
+                                  TPL_NOTIFY,
+                                  httpnotify,
+                                  &response_done,
+                                  &rx_token.Event);
+       if (EFI_ERROR(status)) {
+               perror(L"Failed to Create Event for HTTP response: %r\n", status);
+               goto no_event;
+       }
+
+       /* Notify the firmware to receive the HTTP messages */
+       status = uefi_call_wrapper(http->Response, 2, http, &rx_token);
+       if (EFI_ERROR(status)) {
+               perror(L"HTTP response failed: %r\n", status);
+               goto error;
+       }
+
+       /* Wait for the response */
+       while (!response_done)
+               uefi_call_wrapper(http->Poll, 1, http);
+
+       if (EFI_ERROR(rx_token.Status)) {
+               perror(L"HTTP response: %r\n", rx_token.Status);
+               status = rx_token.Status;
+               goto error;
+       }
+
+       /* Check the HTTP status code */
+       http_status = rx_token.Message->Data.Response->StatusCode;
+       if (http_status != HTTP_STATUS_200_OK) {
+               perror(L"HTTP Status Code: %d\n",
+                      convert_http_status_code(http_status));
+               status = EFI_ABORTED;
+               goto error;
+       }
+
+       /* Check the length of the file */
+       for (i = 0; i < rx_message.HeaderCount; i++) {
+               if (!strcmpa(rx_message.Headers[i].FieldName, (CHAR8 *)"Content-Length")) {
+                       *buf_size = ascii_to_int(rx_message.Headers[i].FieldValue);
+               }
+       }
+
+       if (*buf_size == 0) {
+               perror(L"Failed to get Content-Lenght\n");
+               goto error;
+       }
+
+       *buffer = AllocatePool(*buf_size);
+       if (!*buffer) {
+               perror(L"Failed to allocate new rx buffer\n");
+               goto error;
+       }
+
+       downloaded = rx_message.BodyLength;
+
+       CopyMem(*buffer, rx_buffer, downloaded);
+
+       /* Retreive the rest of the message */
+       while (downloaded < *buf_size) {
+               if (rx_message.Headers) {
+                       FreePool(rx_message.Headers);
+               }
+               rx_message.Headers = NULL;
+               rx_message.HeaderCount = 0;
+               rx_message.Data.Response = NULL;
+               rx_message.BodyLength = sizeof(rx_buffer);
+               rx_message.Body = rx_buffer;
+
+               rx_token.Status = EFI_NOT_READY;
+               response_done = FALSE;
+
+               status = uefi_call_wrapper(http->Response, 2, http, &rx_token);
+               if (EFI_ERROR(status)) {
+                       perror(L"HTTP response failed: %r\n", status);
+                       goto error;
+               }
+
+               while (!response_done)
+                       uefi_call_wrapper(http->Poll, 1, http);
+
+               if (EFI_ERROR(rx_token.Status)) {
+                       perror(L"HTTP response: %r\n", rx_token.Status);
+                       status = rx_token.Status;
+                       goto error;
+               }
+
+               if (rx_message.BodyLength + downloaded > *buf_size) {
+                       status = EFI_BAD_BUFFER_SIZE;
+                       goto error;
+               }
+
+               CopyMem(*buffer + downloaded, rx_buffer, rx_message.BodyLength);
+
+               downloaded += rx_message.BodyLength;
+       }
+
+error:
+       event_status = uefi_call_wrapper(BS->CloseEvent, 1, rx_token.Event);
+       if (EFI_ERROR(event_status)) {
+               perror(L"Failed to close Event for HTTP response: %r\n",
+                      event_status);
+       }
+
+no_event:
+       if (EFI_ERROR(status) && *buffer)
+               FreePool(*buffer);
+
+       return status;
+}
+
+static EFI_STATUS
+http_fetch (EFI_HANDLE image, EFI_HANDLE device,
+           CHAR8 *hostname, CHAR8 *uri, BOOLEAN is_ip6,
+           VOID **buffer, UINTN *buf_size)
+{
+       EFI_GUID http_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID;
+       EFI_GUID http_protocol_guid = EFI_HTTP_PROTOCOL_GUID;
+       EFI_SERVICE_BINDING *service;
+       EFI_HANDLE http_handle;
+       EFI_HTTP_PROTOCOL *http;
+       EFI_STATUS status;
+       EFI_STATUS child_status;
+
+       *buffer = NULL;
+       *buf_size = 0;
+
+       /* Open HTTP Service Binding Protocol */
+       status = uefi_call_wrapper(BS->OpenProtocol, 6, device,
+                                  &http_binding_guid, (VOID **)&service,
+                                  image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+       if (EFI_ERROR (status))
+               return status;
+
+       /* Create the ChildHandle from the Service Binding */
+       /* Set the handle to NULL to request a new handle */
+       http_handle = NULL;
+       status = uefi_call_wrapper(service->CreateChild, 2, service,
+                                  &http_handle);
+       if (EFI_ERROR (status))
+               return status;
+
+       /* Get the http protocol */
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, http_handle,
+                                  &http_protocol_guid, (VOID **)&http);
+       if (EFI_ERROR (status)) {
+               perror(L"Failed to get http\n");
+               goto error;
+       }
+
+       status = configure_http(http, is_ip6);
+       if (EFI_ERROR (status)) {
+               perror(L"Failed to configure http: %r\n", status);
+               goto error;
+       }
+
+       status = send_http_request(http, hostname, uri);
+       if (EFI_ERROR(status)) {
+               perror(L"Failed to send HTTP request: %r\n", status);
+               goto error;
+       }
+
+       status = receive_http_response(http, buffer, buf_size);
+       if (EFI_ERROR(status)) {
+               perror(L"Failed to receive HTTP response: %r\n", status);
+               goto error;
+       }
+
+error:
+       child_status = uefi_call_wrapper(service->DestroyChild, 2, service,
+                                        http_handle);
+
+       if (EFI_ERROR(status)) {
+               return status;
+       } else if (EFI_ERROR(child_status)) {
+               return child_status;
+       }
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINTN *buf_size)
+{
+       EFI_STATUS status;
+       EFI_HANDLE nic;
+       CHAR8 *next_loader = NULL;
+       CHAR8 *next_uri = NULL;
+       CHAR8 *hostname = NULL;
+
+       if (!uri)
+               return EFI_NOT_READY;
+
+       next_loader = translate_slashes(DEFAULT_LOADER_CHAR);
+
+       /* Create the URI for the next loader based on the original URI */
+       status = generate_next_uri(uri, next_loader, &next_uri);
+       if (EFI_ERROR (status)) {
+               perror(L"Next URI: %a, %r\n", next_uri, status);
+               goto error;
+       }
+
+       /* Extract the hostname (or IP) from URI */
+       status = extract_hostname(uri, &hostname);
+       if (EFI_ERROR (status)) {
+               perror(L"hostname: %a, %r\n", hostname, status);
+               goto error;
+       }
+
+       /* Get the handle that associates with the NIC we are using and
+          also supports the HTTP service binding protocol */
+       nic = get_nic_handle(&mac_addr);
+       if (!nic) {
+               goto error;
+       }
+
+       /* UEFI stops DHCP after fetching the image and stores the related
+          information in the device path node. We have to set up the
+          connection on our own for the further operations. */
+       if (!is_ip6)
+               status = set_ip4(nic, &ip4_node);
+       else
+               status = set_ip6(nic, &ip6_node);
+       if (EFI_ERROR (status)) {
+               perror(L"Failed to set IP for HTTPBoot: %r\n", status);
+               goto error;
+       }
+
+       /* Use HTTP protocl to fetch the remote file */
+       status = http_fetch (image, nic, hostname, next_uri, is_ip6,
+                            buffer, buf_size);
+       if (EFI_ERROR (status)) {
+               perror(L"Failed to fetch image: %r\n", status);
+               goto error;
+       }
+
+error:
+       FreePool(uri);
+       uri = NULL;
+       if (next_uri)
+               FreePool(next_uri);
+       if (hostname)
+               FreePool(hostname);
+
+       return status;
+}
diff --git a/httpboot.h b/httpboot.h
new file mode 100644 (file)
index 0000000..79ee465
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015 SUSE LINUX GmbH <glin@suse.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#ifndef _HTTPBOOT_H_
+#define _HTTPBOOT_H_
+
+BOOLEAN find_httpboot (EFI_DEVICE_PATH *devpath);
+
+EFI_STATUS httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINTN *buf_size);
+
+#endif
diff --git a/include/Http.h b/include/Http.h
new file mode 100644 (file)
index 0000000..cd77703
--- /dev/null
@@ -0,0 +1,517 @@
+/** @file
+  This file defines the EFI HTTP Protocol interface. It is split into
+  the following two main sections:
+  HTTP Service Binding Protocol (HTTPSB)
+  HTTP Protocol (HTTP)
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.5
+
+**/
+
+#ifndef __EFI_HTTP_PROTOCOL_H__
+#define __EFI_HTTP_PROTOCOL_H__
+
+#define EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c } \
+  }
+
+#define EFI_HTTP_PROTOCOL_GUID \
+  { \
+    0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b } \
+  }
+
+typedef struct _EFI_HTTP_PROTOCOL EFI_HTTP_PROTOCOL;
+
+///
+/// EFI_HTTP_VERSION
+///
+typedef enum {
+  HttpVersion10,
+  HttpVersion11,
+  HttpVersionUnsupported
+} EFI_HTTP_VERSION;
+
+///
+/// EFI_HTTP_METHOD
+///
+typedef enum {
+  HttpMethodGet,
+  HttpMethodPost,
+  HttpMethodPatch,
+  HttpMethodOptions,
+  HttpMethodConnect,
+  HttpMethodHead,
+  HttpMethodPut,
+  HttpMethodDelete,
+  HttpMethodTrace,
+  HttpMethodMax
+} EFI_HTTP_METHOD;
+
+///
+/// EFI_HTTP_STATUS_CODE
+///
+typedef enum {
+  HTTP_STATUS_UNSUPPORTED_STATUS = 0,
+  HTTP_STATUS_100_CONTINUE,
+  HTTP_STATUS_101_SWITCHING_PROTOCOLS,
+  HTTP_STATUS_200_OK,
+  HTTP_STATUS_201_CREATED,
+  HTTP_STATUS_202_ACCEPTED,
+  HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION,
+  HTTP_STATUS_204_NO_CONTENT,
+  HTTP_STATUS_205_RESET_CONTENT,
+  HTTP_STATUS_206_PARTIAL_CONTENT,
+  HTTP_STATUS_300_MULTIPLE_CHIOCES,
+  HTTP_STATUS_301_MOVED_PERMANENTLY,
+  HTTP_STATUS_302_FOUND,
+  HTTP_STATUS_303_SEE_OTHER,
+  HTTP_STATUS_304_NOT_MODIFIED,
+  HTTP_STATUS_305_USE_PROXY,
+  HTTP_STATUS_307_TEMPORARY_REDIRECT,
+  HTTP_STATUS_400_BAD_REQUEST,
+  HTTP_STATUS_401_UNAUTHORIZED,
+  HTTP_STATUS_402_PAYMENT_REQUIRED,
+  HTTP_STATUS_403_FORBIDDEN,
+  HTTP_STATUS_404_NOT_FOUND,
+  HTTP_STATUS_405_METHOD_NOT_ALLOWED,
+  HTTP_STATUS_406_NOT_ACCEPTABLE,
+  HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED,
+  HTTP_STATUS_408_REQUEST_TIME_OUT,
+  HTTP_STATUS_409_CONFLICT,
+  HTTP_STATUS_410_GONE,
+  HTTP_STATUS_411_LENGTH_REQUIRED,
+  HTTP_STATUS_412_PRECONDITION_FAILED,
+  HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE,
+  HTTP_STATUS_414_REQUEST_URI_TOO_LARGE,
+  HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE,
+  HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED,
+  HTTP_STATUS_417_EXPECTATION_FAILED,
+  HTTP_STATUS_500_INTERNAL_SERVER_ERROR,
+  HTTP_STATUS_501_NOT_IMPLEMENTED,
+  HTTP_STATUS_502_BAD_GATEWAY,
+  HTTP_STATUS_503_SERVICE_UNAVAILABLE,
+  HTTP_STATUS_504_GATEWAY_TIME_OUT,
+  HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED
+} EFI_HTTP_STATUS_CODE;
+
+///
+/// EFI_HTTPv4_ACCESS_POINT
+///
+typedef struct {
+  ///
+  /// Set to TRUE to instruct the EFI HTTP instance to use the default address
+  /// information in every TCP connection made by this instance. In addition, when set
+  /// to TRUE, LocalAddress and LocalSubnet are ignored.
+  ///
+  BOOLEAN                       UseDefaultAddress;
+  ///
+  /// If UseDefaultAddress is set to FALSE, this defines the local IP address to be
+  /// used in every TCP connection opened by this instance.
+  ///
+  EFI_IPv4_ADDRESS              LocalAddress;
+  ///
+  /// If UseDefaultAddress is set to FALSE, this defines the local subnet to be used
+  /// in every TCP connection opened by this instance.
+  ///
+  EFI_IPv4_ADDRESS              LocalSubnet;
+  ///
+  /// This defines the local port to be used in
+  /// every TCP connection opened by this instance.
+  ///
+  UINT16                        LocalPort;
+} EFI_HTTPv4_ACCESS_POINT;
+
+///
+/// EFI_HTTPv6_ACCESS_POINT
+///
+typedef struct {
+  ///
+  /// Local IP address to be used in every TCP connection opened by this instance.
+  ///
+  EFI_IPv6_ADDRESS              LocalAddress;
+  ///
+  /// Local port to be used in every TCP connection opened by this instance.
+  ///
+  UINT16                        LocalPort;
+} EFI_HTTPv6_ACCESS_POINT;
+
+///
+/// EFI_HTTP_CONFIG_DATA_ACCESS_POINT
+///
+
+
+typedef struct {
+  ///
+  /// HTTP version that this instance will support.
+  ///
+  EFI_HTTP_VERSION                   HttpVersion;
+  ///
+  /// Time out (in milliseconds) when blocking for requests.
+  ///
+  UINT32                             TimeOutMillisec;
+  ///
+  /// Defines behavior of EFI DNS and TCP protocols consumed by this instance. If
+  /// FALSE, this instance will use EFI_DNS4_PROTOCOL and EFI_TCP4_PROTOCOL. If TRUE,
+  /// this instance will use EFI_DNS6_PROTOCOL and EFI_TCP6_PROTOCOL.
+  ///
+  BOOLEAN                            LocalAddressIsIPv6;
+
+  union {
+    ///
+    /// When LocalAddressIsIPv6 is FALSE, this points to the local address, subnet, and
+    /// port used by the underlying TCP protocol.
+    ///
+    EFI_HTTPv4_ACCESS_POINT          *IPv4Node;
+    ///
+    /// When LocalAddressIsIPv6 is TRUE, this points to the local IPv6 address and port
+    /// used by the underlying TCP protocol.
+    ///
+    EFI_HTTPv6_ACCESS_POINT          *IPv6Node;
+  } AccessPoint;
+} EFI_HTTP_CONFIG_DATA;
+
+///
+/// EFI_HTTP_REQUEST_DATA
+///
+typedef struct {
+  ///
+  /// The HTTP method (e.g. GET, POST) for this HTTP Request.
+  ///
+  EFI_HTTP_METHOD               Method;
+  ///
+  /// The URI of a remote host. From the information in this field, the HTTP instance
+  /// will be able to determine whether to use HTTP or HTTPS and will also be able to
+  /// determine the port number to use. If no port number is specified, port 80 (HTTP)
+  /// is assumed. See RFC 3986 for more details on URI syntax.
+  ///
+  CHAR16                        *Url;
+} EFI_HTTP_REQUEST_DATA;
+
+///
+/// EFI_HTTP_RESPONSE_DATA
+///
+typedef struct {
+  ///
+  /// Response status code returned by the remote host.
+  ///
+  EFI_HTTP_STATUS_CODE          StatusCode;
+} EFI_HTTP_RESPONSE_DATA;
+
+///
+/// EFI_HTTP_HEADER
+///
+typedef struct {
+  ///
+  /// Null terminated string which describes a field name. See RFC 2616 Section 14 for
+  /// detailed information about field names.
+  ///
+  CHAR8                         *FieldName;
+  ///
+  /// Null terminated string which describes the corresponding field value. See RFC 2616
+  /// Section 14 for detailed information about field values.
+  ///
+  CHAR8                         *FieldValue;
+} EFI_HTTP_HEADER;
+
+///
+/// EFI_HTTP_MESSAGE
+///
+typedef struct {
+  ///
+  /// HTTP message data.
+  ///
+  union {
+    ///
+    /// When the token is used to send a HTTP request, Request is a pointer to storage that
+    /// contains such data as URL and HTTP method.
+    ///
+    EFI_HTTP_REQUEST_DATA       *Request;
+    ///
+    /// When used to await a response, Response points to storage containing HTTP response
+    /// status code.
+    ///
+    EFI_HTTP_RESPONSE_DATA      *Response;
+  } Data;
+  ///
+  /// Number of HTTP header structures in Headers list. On request, this count is
+  /// provided by the caller. On response, this count is provided by the HTTP driver.
+  ///
+  UINTN                         HeaderCount;
+  ///
+  /// Array containing list of HTTP headers. On request, this array is populated by the
+  /// caller. On response, this array is allocated and populated by the HTTP driver. It
+  /// is the responsibility of the caller to free this memory on both request and
+  /// response.
+  ///
+  EFI_HTTP_HEADER               *Headers;
+  ///
+  /// Length in bytes of the HTTP body. This can be zero depending on the HttpMethod type.
+  ///
+  UINTN                         BodyLength;
+  ///
+  /// Body associated with the HTTP request or response. This can be NULL depending on
+  /// the HttpMethod type.
+  ///
+  VOID                          *Body;
+} EFI_HTTP_MESSAGE;
+
+
+///
+/// EFI_HTTP_TOKEN
+///
+typedef struct {
+  ///
+  /// This Event will be signaled after the Status field is updated by the EFI HTTP
+  /// Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. The Task Priority
+  /// Level (TPL) of Event must be lower than or equal to TPL_CALLBACK.
+  ///
+  EFI_EVENT                     Event;
+  ///
+  /// Status will be set to one of the following value if the HTTP request is
+  /// successfully sent or if an unexpected error occurs:
+  ///   EFI_SUCCESS:      The HTTP request was successfully sent to the remote host.
+  ///   EFI_HTTP_ERROR:   The response message was successfully received but contains a
+  ///                     HTTP error. The response status code is returned in token.
+  ///   EFI_ABORTED:      The HTTP request was cancelled by the caller and removed from
+  ///                     the transmit queue.
+  ///   EFI_TIMEOUT:      The HTTP request timed out before reaching the remote host.
+  ///   EFI_DEVICE_ERROR: An unexpected system or network error occurred.
+  ///
+  EFI_STATUS                    Status;
+  ///
+  /// Pointer to storage containing HTTP message data.
+  ///
+  EFI_HTTP_MESSAGE              *Message;
+} EFI_HTTP_TOKEN;
+
+/**
+  Returns the operational parameters for the current HTTP child instance.
+
+  The GetModeData() function is used to read the current mode data (operational
+  parameters) for this HTTP protocol instance.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+  @param[out] HttpConfigData      Point to buffer for operational parameters of this
+                                  HTTP instance.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_INVALID_PARAMETER   This is NULL.
+                                  HttpConfigData is NULL.
+                                  HttpInstance->LocalAddressIsIPv6 is FALSE and
+                                  HttpConfigData->IPv4Node is NULL.
+                                  HttpInstance->LocalAddressIsIPv6 is TRUE and
+                                  HttpConfigData->IPv6Node is NULL.
+  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_HTTP_GET_MODE_DATA)(
+  IN  EFI_HTTP_PROTOCOL         *This,
+  OUT EFI_HTTP_CONFIG_DATA      *HttpConfigData
+  );
+
+/**
+  Initialize or brutally reset the operational parameters for this EFI HTTP instance.
+
+  The Configure() function does the following:
+  When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring
+  timeout, local address, port, etc.
+  When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active
+  connections with remote hosts, canceling all asynchronous tokens, and flush request
+  and response buffers without informing the appropriate hosts.
+
+  No other EFI HTTP function can be executed by this instance until the Configure()
+  function is executed and returns successfully.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+  @param[in]  HttpConfigData      Pointer to the configure data to configure the instance.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  HttpConfigData is NULL.
+                                  HttpConfigData->LocalAddressIsIPv6 is FALSE and
+                                  HttpConfigData->IPv4Node is NULL.
+                                  HttpConfigData->LocalAddressIsIPv6 is TRUE and
+                                  HttpConfigData->IPv6Node is NULL.
+  @retval EFI_ALREADY_STARTED     Reinitialize this HTTP instance without calling
+                                  Configure() with NULL to reset it.
+  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources when
+                                  executing Configure().
+  @retval EFI_UNSUPPORTED         One or more options in ConfigData are not supported
+                                  in the implementation.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_HTTP_CONFIGURE)(
+  IN  EFI_HTTP_PROTOCOL         *This,
+  IN  EFI_HTTP_CONFIG_DATA      *HttpConfigData
+  );
+
+/**
+  The Request() function queues an HTTP request to this HTTP instance,
+  similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
+  successfully, or if there is an error, Status in token will be updated and Event will
+  be signaled.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+  @param[in]  Token               Pointer to storage containing HTTP request token.
+
+  @retval EFI_SUCCESS             Outgoing data was processed.
+  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
+  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
+  @retval EFI_TIMEOUT             Data was dropped out of the transmit or receive queue.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Token is NULL.
+                                  Token->Message is NULL.
+                                  Token->Message->Body is not NULL,
+                                  Token->Message->BodyLength is non-zero, and
+                                  Token->Message->Data is NULL, but a previous call to
+                                  Request()has not been completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
+  @retval EFI_UNSUPPORTED         The HTTP method is not supported in current implementation.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HTTP_REQUEST) (
+  IN  EFI_HTTP_PROTOCOL         *This,
+  IN  EFI_HTTP_TOKEN            *Token
+  );
+
+/**
+  Abort an asynchronous HTTP request or response token.
+
+  The Cancel() function aborts a pending HTTP request or response transaction. If
+  Token is not NULL and the token is in transmit or receive queues when it is being
+  cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will
+  be signaled. If the token is not in one of the queues, which usually means that the
+  asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL,
+  all asynchronous tokens issued by Request() or Response() will be aborted.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+  @param[in]  Token               Point to storage containing HTTP request or response
+                                  token.
+
+  @retval EFI_SUCCESS             Request and Response queues are successfully flushed.
+  @retval EFI_INVALID_PARAMETER   This is NULL.
+  @retval EFI_NOT_STARTED         This instance hasn't been configured.
+  @retval EFI_NOT_FOUND           The asynchronous request or response token is not
+                                  found.
+  @retval EFI_UNSUPPORTED         The implementation does not support this function.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HTTP_CANCEL)(
+  IN  EFI_HTTP_PROTOCOL         *This,
+  IN  EFI_HTTP_TOKEN            *Token
+  );
+
+/**
+  The Response() function queues an HTTP response to this HTTP instance, similar to
+  Receive() function in the EFI TCP driver. When the HTTP Response is received successfully,
+  or if there is an error, Status in token will be updated and Event will be signaled.
+
+  The HTTP driver will queue a receive token to the underlying TCP instance. When data
+  is received in the underlying TCP instance, the data will be parsed and Token will
+  be populated with the response data. If the data received from the remote host
+  contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting
+  (asynchronously) for more data to be sent from the remote host before signaling
+  Event in Token.
+
+  It is the responsibility of the caller to allocate a buffer for Body and specify the
+  size in BodyLength. If the remote host provides a response that contains a content
+  body, up to BodyLength bytes will be copied from the receive buffer into Body and
+  BodyLength will be updated with the amount of bytes received and copied to Body. This
+  allows the client to download a large file in chunks instead of into one contiguous
+  block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is
+  non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive
+  token to underlying TCP instance. If data arrives in the receive buffer, up to
+  BodyLength bytes of data will be copied to Body. The HTTP driver will then update
+  BodyLength with the amount of bytes received and copied to Body.
+
+  If the HTTP driver does not have an open underlying TCP connection with the host
+  specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is
+  consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain
+  an open TCP connection between client and host.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+  @param[in]  Token               Pointer to storage containing HTTP response token.
+
+  @retval EFI_SUCCESS             Allocation succeeded.
+  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been
+                                  initialized.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Token is NULL.
+                                  Token->Message->Headers is NULL.
+                                  Token->Message is NULL.
+                                  Token->Message->Body is not NULL,
+                                  Token->Message->BodyLength is non-zero, and
+                                  Token->Message->Data is NULL, but a previous call to
+                                  Response() has not been completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
+  @retval EFI_ACCESS_DENIED       An open TCP connection is not present with the host
+                                  specified by response URL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HTTP_RESPONSE) (
+  IN  EFI_HTTP_PROTOCOL         *This,
+  IN  EFI_HTTP_TOKEN            *Token
+  );
+
+/**
+  The Poll() function can be used by network drivers and applications to increase the
+  rate that data packets are moved between the communication devices and the transmit
+  and receive queues.
+
+  In some systems, the periodic timer event in the managed network driver may not poll
+  the underlying communications device fast enough to transmit and/or receive all data
+  packets without missing incoming packets or dropping outgoing packets. Drivers and
+  applications that are experiencing packet loss should try calling the Poll() function
+  more often.
+
+  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
+
+  @retval EFI_SUCCESS             Incoming or outgoing data was processed..
+  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred
+  @retval EFI_INVALID_PARAMETER   This is NULL.
+  @retval EFI_NOT_READY           No incoming or outgoing data is processed.
+  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HTTP_POLL) (
+  IN  EFI_HTTP_PROTOCOL         *This
+  );
+
+///
+/// The EFI HTTP protocol is designed to be used by EFI drivers and applications to
+/// create and transmit HTTP Requests, as well as handle HTTP responses that are
+/// returned by a remote host. This EFI protocol uses and relies on an underlying EFI
+/// TCP protocol.
+///
+struct _EFI_HTTP_PROTOCOL {
+  EFI_HTTP_GET_MODE_DATA        GetModeData;
+  EFI_HTTP_CONFIGURE            Configure;
+  EFI_HTTP_REQUEST              Request;
+  EFI_HTTP_CANCEL               Cancel;
+  EFI_HTTP_RESPONSE             Response;
+  EFI_HTTP_POLL                 Poll;
+};
+
+#endif
diff --git a/include/Ip4Config2.h b/include/Ip4Config2.h
new file mode 100644 (file)
index 0000000..b4f1d84
--- /dev/null
@@ -0,0 +1,315 @@
+/** @file
+  This file provides a definition of the EFI IPv4 Configuration II
+  Protocol.
+
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at<BR>
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+@par Revision Reference:
+This Protocol is introduced in UEFI Specification 2.5
+
+**/
+#ifndef __EFI_IP4CONFIG2_PROTOCOL_H__
+#define __EFI_IP4CONFIG2_PROTOCOL_H__
+
+#include <efiip.h>
+
+#define EFI_IP4_CONFIG2_PROTOCOL_GUID \
+  { \
+    0x5b446ed1, 0xe30b, 0x4faa, {0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \
+  }
+
+typedef struct _EFI_IP4_CONFIG2_PROTOCOL EFI_IP4_CONFIG2_PROTOCOL;
+
+
+///
+/// EFI_IP4_CONFIG2_DATA_TYPE
+///
+typedef enum {
+  ///
+  /// The interface information of the communication device this EFI
+  /// IPv4 Configuration II Protocol instance manages. This type of
+  /// data is read only. The corresponding Data is of type
+  /// EFI_IP4_CONFIG2_INTERFACE_INFO.
+  ///
+  Ip4Config2DataTypeInterfaceInfo,
+  ///
+  /// The general configuration policy for the EFI IPv4 network stack
+  /// running on the communication device this EFI IPv4
+  /// Configuration II Protocol instance manages. The policy will
+  /// affect other configuration settings. The corresponding Data is of
+  /// type EFI_IP4_CONFIG2_POLICY.
+  ///
+  Ip4Config2DataTypePolicy,
+  ///
+  /// The station addresses set manually for the EFI IPv4 network
+  /// stack. It is only configurable when the policy is
+  /// Ip4Config2PolicyStatic. The corresponding Data is of
+  /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS.
+  ///
+  Ip4Config2DataTypeManualAddress,
+  ///
+  /// The gateway addresses set manually for the EFI IPv4 network
+  /// stack running on the communication device this EFI IPv4
+  /// Configuration II Protocol manages. It is not configurable when
+  /// the policy is Ip4Config2PolicyDhcp. The gateway
+  /// addresses must be unicast IPv4 addresses. The corresponding
+  /// Data is a pointer to an array of EFI_IPv4_ADDRESS instances.
+  ///
+  Ip4Config2DataTypeGateway,
+  ///
+  /// The DNS server list for the EFI IPv4 network stack running on
+  /// the communication device this EFI IPv4 Configuration II
+  /// Protocol manages. It is not configurable when the policy is
+  /// Ip4Config2PolicyDhcp. The DNS server addresses must be
+  /// unicast IPv4 addresses. The corresponding Data is a pointer to
+  /// an array of EFI_IPv4_ADDRESS instances.
+  ///
+  Ip4Config2DataTypeDnsServer,
+  Ip4Config2DataTypeMaximum
+} EFI_IP4_CONFIG2_DATA_TYPE;
+
+///
+/// EFI_IP4_CONFIG2_INTERFACE_INFO related definitions
+///
+#define EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE 32
+
+///
+/// EFI_IP4_CONFIG2_INTERFACE_INFO
+///
+typedef struct {
+  ///
+  /// The name of the interface. It is a NULL-terminated Unicode string.
+  ///
+  CHAR16                Name[EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE];
+  ///
+  /// The interface type of the network interface. See RFC 1700,
+  /// section "Number Hardware Type".
+  ///
+  UINT8                 IfType;
+  ///
+  /// The size, in bytes, of the network interface's hardware address.
+  ///
+  UINT32                HwAddressSize;
+  ///
+  /// The hardware address for the network interface.
+  ///
+  EFI_MAC_ADDRESS       HwAddress;
+  ///
+  /// The station IPv4 address of this EFI IPv4 network stack.
+  ///
+  EFI_IPv4_ADDRESS      StationAddress;
+  ///
+  /// The subnet address mask that is associated with the station address.
+  ///
+  EFI_IPv4_ADDRESS      SubnetMask;
+  ///
+  /// Size of the following RouteTable, in bytes. May be zero.
+  ///
+  UINT32                RouteTableSize;
+  ///
+  /// The route table of the IPv4 network stack runs on this interface.
+  /// Set to NULL if RouteTableSize is zero. Type EFI_IP4_ROUTE_TABLE is defined in
+  /// EFI_IP4_PROTOCOL.GetModeData().
+  ///
+  EFI_IP4_ROUTE_TABLE   *RouteTable     OPTIONAL;
+} EFI_IP4_CONFIG2_INTERFACE_INFO;
+
+///
+/// EFI_IP4_CONFIG2_POLICY
+///
+typedef enum {
+  ///
+  /// Under this policy, the Ip4Config2DataTypeManualAddress,
+  /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration
+  /// data are required to be set manually. The EFI IPv4 Protocol will get all
+  /// required configuration such as IPv4 address, subnet mask and
+  /// gateway settings from the EFI IPv4 Configuration II protocol.
+  ///
+  Ip4Config2PolicyStatic,
+  ///
+  /// Under this policy, the Ip4Config2DataTypeManualAddress,
+  /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration data are
+  /// not allowed to set via SetData(). All of these configurations are retrieved from DHCP
+  /// server or other auto-configuration mechanism.
+  ///
+  Ip4Config2PolicyDhcp,
+  Ip4Config2PolicyMax
+} EFI_IP4_CONFIG2_POLICY;
+
+///
+/// EFI_IP4_CONFIG2_MANUAL_ADDRESS
+///
+typedef struct {
+  ///
+  /// The IPv4 unicast address.
+  ///
+  EFI_IPv4_ADDRESS        Address;
+  ///
+  /// The subnet mask.
+  ///
+  EFI_IPv4_ADDRESS        SubnetMask;
+} EFI_IP4_CONFIG2_MANUAL_ADDRESS;
+
+/**
+  Set the configuration for the EFI IPv4 network stack running on the communication device this EFI
+  IPv4 Configuration II Protocol instance manages.
+
+  This function is used to set the configuration data of type DataType for the EFI IPv4 network stack
+  running on the communication device this EFI IPv4 Configuration II Protocol instance manages.
+  The successfully configured data is valid after system reset or power-off.
+  The DataSize is used to calculate the count of structure instances in the Data for some
+  DataType that multiple structure instances are allowed.
+  This function is always non-blocking. When setting some typeof configuration data, an
+  asynchronous process is invoked to check the correctness of the data, such as doing address conflict
+  detection on the manually set local IPv4 address. EFI_NOT_READY is returned immediately to
+  indicate that such an asynchronous process is invoked and the process is not finished yet. The caller
+  willing to get the result of the asynchronous process is required to call RegisterDataNotify()
+  to register an event on the specified configuration data. Once the event is signaled, the caller can call
+  GetData()to get back the configuration data in order to know the result. For other types of
+  configuration data that do not require an asynchronous configuration process, the result of the
+  operation is immediately returned.
+
+  @param[in]   This               Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
+  @param[in]   DataType           The type of data to set.
+  @param[in]   DataSize           Size of the buffer pointed to by Data in bytes.
+  @param[in]   Data               The data buffer to set. The type ofthe data buffer is associated
+                                  with the DataType.
+
+  @retval EFI_SUCCESS             The specified configuration data for the EFI IPv4 network stack is set
+                                  successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  One or more fields in Data do not match the requirement of the data type
+                                  indicated by DataType.
+  @retval EFI_WRITE_PROTECTED     The specified configuration data is read-only or the specified configuration
+                                  data can not be set under the current policy.
+  @retval EFI_ACCESS_DENIED       Another set operation on the specified configuration data is already in process.
+  @retval EFI_NOT_READY           An asynchronous process is invoked to set the specified configuration data and
+                                  the process is not finished yet.
+  @retval EFI_BAD_BUFFER_SIZE     The DataSize does not match the size of the type indicated by DataType.
+  @retval EFI_UNSUPPORTED         This DataType is not supported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+  @retval EFI_DEVICE_ERROR        An unexpected system error or network error occurred.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CONFIG2_SET_DATA) (
+  IN EFI_IP4_CONFIG2_PROTOCOL   *This,
+  IN EFI_IP4_CONFIG2_DATA_TYPE  DataType,
+  IN UINTN                      DataSize,
+  IN VOID                       *Data
+  );
+
+/**
+  Get the configuration data for the EFI IPv4 network stack running on the communication device this
+  EFI IPv4 Configuration II Protocol instance manages.
+
+  This function returns the configuration data of type DataType for the EFI IPv4 network stack
+  running on the communication device this EFI IPv4 Configuration II Protocol instance manages.
+  The caller is responsible for allocating the buffer usedto return the specified configuration data and
+  the required size will be returned to the caller if the size of the buffer is too small.
+  EFI_NOT_READY is returned if the specified configuration data is not ready due to an already in
+  progress asynchronous configuration process. The caller can call RegisterDataNotify() to
+  register an event on the specified configuration data. Once the asynchronous configuration process is
+  finished, the event will be signaled and a subsequent GetData() call will return the specified
+  configuration data.
+
+  @param[in]   This               Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
+  @param[in]   DataType           The type of data to get.
+  @param[out]  DataSize           On input, in bytes, the size of Data. On output, in bytes, the size
+                                  of buffer required to store the specified configuration data.
+  @param[in]   Data               The data buffer in which the configuration data is returned. The
+                                  type of the data buffer is associated with the DataType. Ignored
+                                  if DataSize is 0.
+
+  @retval EFI_SUCCESS             The specified configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the followings are TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSizeis not zero.
+  @retval EFI_BUFFER_TOO_SMALL    The size of Data is too small for the specified configuration data
+                                  and the required size is returned in DataSize.
+  @retval EFI_NOT_READY           The specified configuration data is not ready due to an already in
+                                  progress asynchronous configuration process.
+  @retval EFI_NOT_FOUND           The specified configuration data is not found.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CONFIG2_GET_DATA) (
+  IN EFI_IP4_CONFIG2_PROTOCOL     *This,
+  IN EFI_IP4_CONFIG2_DATA_TYPE    DataType,
+  IN OUT UINTN                    *DataSize,
+  IN VOID                         *Data        OPTIONAL
+  );
+
+/**
+  Register an event that is to be signaled whenever a configuration process on the specified
+  configuration data is done.
+
+  This function registers an event that is to be signaled whenever a configuration process on the
+  specified configuration data is done. An event can be registered for different DataType
+  simultaneously and the caller is responsible for determining which type of configuration data causes
+  the signaling of the event in such case.
+
+  @param[in]   This               Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
+  @param[in]   DataType           The type of data to unregister the event for.
+  @param[in]   Event              The event to register.
+
+  @retval EFI_SUCCESS             The notification event for the specified configuration data is
+                                  registered.
+  @retval EFI_INVALID_PARAMETER   This is NULL or Event is NULL.
+  @retval EFI_UNSUPPORTED         The configuration data type specified by DataType is not supported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+  @retval EFI_ACCESS_DENIED       The Event is already registered for the DataType.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CONFIG2_REGISTER_NOTIFY) (
+  IN EFI_IP4_CONFIG2_PROTOCOL     *This,
+  IN EFI_IP4_CONFIG2_DATA_TYPE    DataType,
+  IN EFI_EVENT                    Event
+  );
+
+/**
+  Remove a previously registered event for the specified configuration data.
+
+  This function removes a previously registeredevent for the specified configuration data.
+
+  @param[in]   This               Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
+  @param[in]   DataType           The type of data to remove the previously registered event for.
+  @param[in]   Event              The event to unregister.
+
+  @retval EFI_SUCCESS             The event registered for the specified configuration data is removed.
+  @retval EFI_INVALID_PARAMETER   This is NULL or Event is NULL.
+  @retval EFI_NOT_FOUND           The Eventhas not been registered for the specified DataType.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP4_CONFIG2_UNREGISTER_NOTIFY) (
+  IN EFI_IP4_CONFIG2_PROTOCOL     *This,
+  IN EFI_IP4_CONFIG2_DATA_TYPE    DataType,
+  IN EFI_EVENT                    Event
+  );
+
+///
+/// The EFI_IP4_CONFIG2_PROTOCOL is designed to be the central repository for the common
+/// configurations and the administrator configurable settings for the EFI IPv4 network stack.
+/// An EFI IPv4 Configuration II Protocol instance will be installed on each communication device that
+/// the EFI IPv4 network stack runs on.
+///
+struct _EFI_IP4_CONFIG2_PROTOCOL {
+  EFI_IP4_CONFIG2_SET_DATA           SetData;
+  EFI_IP4_CONFIG2_GET_DATA           GetData;
+  EFI_IP4_CONFIG2_REGISTER_NOTIFY    RegisterDataNotify;
+  EFI_IP4_CONFIG2_UNREGISTER_NOTIFY  UnregisterDataNotify;
+};
+
+#endif
diff --git a/include/Ip6Config.h b/include/Ip6Config.h
new file mode 100644 (file)
index 0000000..003e50e
--- /dev/null
@@ -0,0 +1,366 @@
+/** @file
+  This file provides a definition of the EFI IPv6 Configuration
+  Protocol.
+
+Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at<BR>
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef __EFI_IP6CONFIG_PROTOCOL_H__
+#define __EFI_IP6CONFIG_PROTOCOL_H__
+
+#include <efiip.h>
+
+#define EFI_IP6_CONFIG_PROTOCOL_GUID \
+  { \
+    0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
+  }
+
+typedef struct _EFI_IP6_CONFIG_PROTOCOL EFI_IP6_CONFIG_PROTOCOL;
+
+///
+/// EFI_IP6_CONFIG_DATA_TYPE
+///
+typedef enum {
+  ///
+  /// The interface information of the communication
+  /// device this EFI IPv6 Configuration Protocol instance manages.
+  /// This type of data is read only.The corresponding Data is of type
+  /// EFI_IP6_CONFIG_INTERFACE_INFO.
+  ///
+  Ip6ConfigDataTypeInterfaceInfo,
+  ///
+  /// The alternative interface ID for the
+  /// communication device this EFI IPv6 Configuration Protocol
+  /// instance manages if the link local IPv6 address generated from
+  /// the interfaced ID based on the default source the EFI IPv6
+  /// Protocol uses is a duplicate address. The length of the interface
+  /// ID is 64 bit. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_INTERFACE_ID.
+  ///
+  Ip6ConfigDataTypeAltInterfaceId,
+  ///
+  /// The general configuration policy for the EFI IPv6 network
+  /// stack running on the communication device this EFI IPv6
+  /// Configuration Protocol instance manages. The policy will affect
+  /// other configuration settings. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_POLICY.
+  ///
+  Ip6ConfigDataTypePolicy,
+  ///
+  /// The number of consecutive
+  /// Neighbor Solicitation messages sent while performing Duplicate
+  /// Address Detection on a tentative address. A value of zero
+  /// indicates that Duplicate Address Detection will not be performed
+  /// on tentative addresses. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS.
+  ///
+  Ip6ConfigDataTypeDupAddrDetectTransmits,
+  ///
+  /// The station addresses set manually for the EFI
+  /// IPv6 network stack. It is only configurable when the policy is
+  /// Ip6ConfigPolicyManual. The corresponding Data is a
+  /// pointer to an array of EFI_IPv6_ADDRESS instances.
+  ///
+  Ip6ConfigDataTypeManualAddress,
+  ///
+  /// The gateway addresses set manually for the EFI IPv6
+  /// network stack running on the communication device this EFI
+  /// IPv6 Configuration Protocol manages. It is not configurable when
+  /// the policy is Ip6ConfigPolicyAutomatic. The gateway
+  /// addresses must be unicast IPv6 addresses. The corresponding
+  /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  ///
+  Ip6ConfigDataTypeGateway,
+  ///
+  /// The DNS server list for the EFI IPv6 network stack
+  /// running on the communication device this EFI IPv6
+  /// Configuration Protocol manages. It is not configurable when the
+  /// policy is Ip6ConfigPolicyAutomatic.The DNS server
+  /// addresses must be unicast IPv6 addresses. The corresponding
+  /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  ///
+  Ip6ConfigDataTypeDnsServer,
+  ///
+  /// The number of this enumeration memebers.
+  ///
+  Ip6ConfigDataTypeMaximum
+} EFI_IP6_CONFIG_DATA_TYPE;
+
+///
+/// EFI_IP6_CONFIG_INTERFACE_INFO
+/// describes the operational state of the interface this
+/// EFI IPv6 Configuration Protocol instance manages.
+///
+typedef struct {
+  ///
+  /// The name of the interface. It is a NULL-terminated string.
+  ///
+  CHAR16                Name[32];
+  ///
+  /// The interface type of the network interface.
+  ///
+  UINT8                 IfType;
+  ///
+  /// The size, in bytes, of the network interface's hardware address.
+  ///
+  UINT32                HwAddressSize;
+  ///
+  /// The hardware address for the network interface.
+  ///
+  EFI_MAC_ADDRESS       HwAddress;
+  ///
+  /// Number of EFI_IP6_ADDRESS_INFO structures pointed to by AddressInfo.
+  ///
+  UINT32                AddressInfoCount;
+  ///
+  /// Pointer to an array of EFI_IP6_ADDRESS_INFO instances
+  /// which contain the local IPv6 addresses and the corresponding
+  /// prefix length information. Set to NULL if AddressInfoCount
+  /// is zero.
+  ///
+  EFI_IP6_ADDRESS_INFO  *AddressInfo;
+  ///
+  /// Number of route table entries in the following RouteTable.
+  ///
+  UINT32                RouteCount;
+  ///
+  /// The route table of the IPv6 network stack runs on this interface.
+  /// Set to NULL if RouteCount is zero.
+  ///
+  EFI_IP6_ROUTE_TABLE   *RouteTable;
+} EFI_IP6_CONFIG_INTERFACE_INFO;
+
+///
+/// EFI_IP6_CONFIG_INTERFACE_ID
+/// describes the 64-bit interface ID.
+///
+typedef struct {
+  UINT8                 Id[8];
+} EFI_IP6_CONFIG_INTERFACE_ID;
+
+///
+/// EFI_IP6_CONFIG_POLICY
+/// defines the general configuration policy the EFI IPv6
+/// Configuration Protocol supports.
+///
+typedef enum {
+  ///
+  /// Under this policy, the IpI6ConfigDataTypeManualAddress,
+  /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
+  /// configuration data are required to be set manually.
+  /// The EFI IPv6 Protocol will get all required configuration
+  /// such as address, prefix and gateway settings from the EFI
+  /// IPv6 Configuration protocol.
+  ///
+  Ip6ConfigPolicyManual,
+  ///
+  /// Under this policy, the IpI6ConfigDataTypeManualAddress,
+  /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
+  /// configuration data are not allowed to set via SetData().
+  /// All of these configurations are retrieved from some auto
+  /// configuration mechanism.
+  /// The EFI IPv6 Protocol will use the IPv6 stateless address
+  /// autoconfiguration mechanism and/or the IPv6 stateful address
+  /// autoconfiguration mechanism described in the related RFCs to
+  /// get address and other configuration information
+  ///
+  Ip6ConfigPolicyAutomatic
+} EFI_IP6_CONFIG_POLICY;
+
+///
+/// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
+/// describes the number of consecutive Neighbor Solicitation messages sent
+/// while performing Duplicate Address Detection on a tentative address.
+/// The default value for a newly detected communication device is 1.
+///
+typedef struct {
+  UINT32    DupAddrDetectTransmits;  ///< The number of consecutive Neighbor Solicitation messages sent.
+} EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS;
+
+///
+/// EFI_IP6_CONFIG_MANUAL_ADDRESS
+/// is used to set the station address information for the EFI IPv6 network
+/// stack manually when the policy is Ip6ConfigPolicyManual.
+///
+typedef struct {
+  EFI_IPv6_ADDRESS      Address;       ///< The IPv6 unicast address.
+  BOOLEAN               IsAnycast;     ///< Set to TRUE if Address is anycast.
+  UINT8                 PrefixLength;  ///< The length, in bits, of the prefix associated with this Address.
+} EFI_IP6_CONFIG_MANUAL_ADDRESS;
+
+
+/**
+  Set the configuration for the EFI IPv6 network stack running on the communication
+  device this EFI IPv6 Configuration Protocol instance manages.
+
+  This function is used to set the configuration data of type DataType for the EFI
+  IPv6 network stack running on the communication device this EFI IPv6 Configuration
+  Protocol instance manages.
+
+  The DataSize is used to calculate the count of structure instances in the Data for
+  some DataType that multiple structure instances are allowed.
+
+  This function is always non-blocking. When setting some type of configuration data,
+  an asynchronous process is invoked to check the correctness of the data, such as
+  doing Duplicate Address Detection on the manually set local IPv6 addresses.
+  EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
+  is invoked and the process is not finished yet. The caller willing to get the result
+  of the asynchronous process is required to call RegisterDataNotify() to register an
+  event on the specified configuration data. Once the event is signaled, the caller
+  can call GetData() to get back the configuration data in order to know the result.
+  For other types of configuration data that do not require an asynchronous configuration
+  process, the result of the operation is immediately returned.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to set.
+  @param[in]     DataSize       Size of the buffer pointed to by Data in bytes.
+  @param[in]     Data           The data buffer to set. The type of the data buffer is
+                                associated with the DataType.
+
+  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
+                                network stack is set successfully.
+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
+                                - This is NULL.
+                                - Data is NULL.
+                                - One or more fields in Data do not match the requirement of the
+                                  data type indicated by DataType.
+  @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified
+                                configuration data can not be set under the current policy
+  @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration
+                                data is already in process.
+  @retval EFI_NOT_READY         An asynchronous process is invoked to set the specified
+                                configuration data and the process is not finished yet.
+  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type
+                                indicated by DataType.
+  @retval EFI_UNSUPPORTED       This DataType is not supported.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_DEVICE_ERROR      An unexpected system error or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_SET_DATA)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN UINTN                      DataSize,
+  IN VOID                       *Data
+  );
+
+/**
+  Get the configuration data for the EFI IPv6 network stack running on the communication
+  device this EFI IPv6 Configuration Protocol instance manages.
+
+  This function returns the configuration data of type DataType for the EFI IPv6 network
+  stack running on the communication device this EFI IPv6 Configuration Protocol instance
+  manages.
+
+  The caller is responsible for allocating the buffer used to return the specified
+  configuration data and the required size will be returned to the caller if the size of
+  the buffer is too small.
+
+  EFI_NOT_READY is returned if the specified configuration data is not ready due to an
+  already in progress asynchronous configuration process. The caller can call RegisterDataNotify()
+  to register an event on the specified configuration data. Once the asynchronous configuration
+  process is finished, the event will be signaled and a subsequent GetData() call will return
+  the specified configuration data.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to get.
+  @param[in,out] DataSize       On input, in bytes, the size of Data. On output, in bytes, the
+                                size of buffer required to store the specified configuration data.
+  @param[in]     Data           The data buffer in which the configuration data is returned. The
+                                type of the data buffer is associated with the DataType.
+
+  @retval EFI_SUCCESS           The specified configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
+                                - This is NULL.
+                                - DataSize is NULL.
+                                - Data is NULL if *DataSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL  The size of Data is too small for the specified configuration data
+                                and the required size is returned in DataSize.
+  @retval EFI_NOT_READY         The specified configuration data is not ready due to an already in
+                                progress asynchronous configuration process.
+  @retval EFI_NOT_FOUND         The specified configuration data is not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_GET_DATA)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN OUT UINTN                  *DataSize,
+  IN VOID                       *Data   OPTIONAL
+  );
+
+/**
+  Register an event that is to be signaled whenever a configuration process on the specified
+  configuration data is done.
+
+  This function registers an event that is to be signaled whenever a configuration process
+  on the specified configuration data is done. An event can be registered for different DataType
+  simultaneously and the caller is responsible for determining which type of configuration data
+  causes the signaling of the event in such case.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to unregister the event for.
+  @param[in]     Event          The event to register.
+
+  @retval EFI_SUCCESS           The notification event for the specified configuration data is
+                                registered.
+  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+  @retval EFI_UNSUPPORTED       The configuration data type specified by DataType is not
+                                supported.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_ACCESS_DENIED     The Event is already registered for the DataType.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_REGISTER_NOTIFY)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN EFI_EVENT                  Event
+  );
+
+/**
+  Remove a previously registered event for the specified configuration data.
+
+  This function removes a previously registered event for the specified configuration data.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to remove the previously registered event for.
+  @param[in]     Event          The event to unregister.
+
+  @retval EFI_SUCCESS           The event registered for the specified configuration data is removed.
+  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+  @retval EFI_NOT_FOUND         The Event has not been registered for the specified
+                                DataType.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_UNREGISTER_NOTIFY)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN EFI_EVENT                  Event
+  );
+
+///
+/// The EFI_IP6_CONFIG_PROTOCOL provides the mechanism to set and get various
+/// types of configurations for the EFI IPv6 network stack.
+///
+struct _EFI_IP6_CONFIG_PROTOCOL {
+  EFI_IP6_CONFIG_SET_DATA           SetData;
+  EFI_IP6_CONFIG_GET_DATA           GetData;
+  EFI_IP6_CONFIG_REGISTER_NOTIFY    RegisterDataNotify;
+  EFI_IP6_CONFIG_UNREGISTER_NOTIFY  UnregisterDataNotify;
+};
+
+#endif
diff --git a/include/PeImage.h b/include/PeImage.h
new file mode 100644 (file)
index 0000000..17f186c
--- /dev/null
@@ -0,0 +1,789 @@
+/** @file\r
+  EFI image format for PE32, PE32+ and TE. Please note some data structures are \r
+  different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and \r
+  EFI_IMAGE_NT_HEADERS64 is for PE32+. \r
+\r
+  This file is coded to the Visual Studio, Microsoft Portable Executable and \r
+  Common Object File Format Specification, Revision 8.0 - May 16, 2006. \r
+  This file also includes some definitions in PI Specification, Revision 1.0.\r
+\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php.                                           \r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+**/\r
+\r
+#ifndef __PE_IMAGE_H__\r
+#define __PE_IMAGE_H__\r
+\r
+#include <wincert.h>\r
+\r
+#define SIGNATURE_16(A, B)        ((A) | (B << 8))\r
+#define SIGNATURE_32(A, B, C, D)  (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))\r
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \\r
+       (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))\r
+\r
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))\r
+#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))\r
+\r
+//\r
+// PE32+ Subsystem type for EFI images\r
+//\r
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10\r
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11\r
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12\r
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13 ///< defined PI Specification, 1.0\r
+\r
+\r
+//\r
+// PE32+ Machine type for EFI images\r
+//\r
+#define IMAGE_FILE_MACHINE_I386            0x014c\r
+#define IMAGE_FILE_MACHINE_IA64            0x0200\r
+#define IMAGE_FILE_MACHINE_EBC             0x0EBC\r
+#define IMAGE_FILE_MACHINE_X64             0x8664\r
+#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED  0x01c2\r
+#define IMAGE_FILE_MACHINE_ARM64          0xaa64\r
+\r
+//\r
+// EXE file formats\r
+//\r
+#define EFI_IMAGE_DOS_SIGNATURE     SIGNATURE_16('M', 'Z')\r
+#define EFI_IMAGE_OS2_SIGNATURE     SIGNATURE_16('N', 'E')\r
+#define EFI_IMAGE_OS2_SIGNATURE_LE  SIGNATURE_16('L', 'E')\r
+#define EFI_IMAGE_NT_SIGNATURE      SIGNATURE_32('P', 'E', '\0', '\0')\r
+\r
+///\r
+/// PE images can start with an optional DOS header, so if an image is run\r
+/// under DOS it can print an error message.\r
+///\r
+typedef struct {\r
+  UINT16  e_magic;    ///< Magic number.\r
+  UINT16  e_cblp;     ///< Bytes on last page of file.\r
+  UINT16  e_cp;       ///< Pages in file.\r
+  UINT16  e_crlc;     ///< Relocations.\r
+  UINT16  e_cparhdr;  ///< Size of header in paragraphs.\r
+  UINT16  e_minalloc; ///< Minimum extra paragraphs needed.\r
+  UINT16  e_maxalloc; ///< Maximum extra paragraphs needed.\r
+  UINT16  e_ss;       ///< Initial (relative) SS value.\r
+  UINT16  e_sp;       ///< Initial SP value.\r
+  UINT16  e_csum;     ///< Checksum.\r
+  UINT16  e_ip;       ///< Initial IP value.\r
+  UINT16  e_cs;       ///< Initial (relative) CS value.\r
+  UINT16  e_lfarlc;   ///< File address of relocation table.\r
+  UINT16  e_ovno;     ///< Overlay number.\r
+  UINT16  e_res[4];   ///< Reserved words.\r
+  UINT16  e_oemid;    ///< OEM identifier (for e_oeminfo).\r
+  UINT16  e_oeminfo;  ///< OEM information; e_oemid specific.\r
+  UINT16  e_res2[10]; ///< Reserved words.\r
+  UINT32  e_lfanew;   ///< File address of new exe header.\r
+} EFI_IMAGE_DOS_HEADER;\r
+\r
+///\r
+/// COFF File Header (Object and Image).\r
+///\r
+typedef struct {\r
+  UINT16  Machine;\r
+  UINT16  NumberOfSections;\r
+  UINT32  TimeDateStamp;\r
+  UINT32  PointerToSymbolTable;\r
+  UINT32  NumberOfSymbols;\r
+  UINT16  SizeOfOptionalHeader;\r
+  UINT16  Characteristics;\r
+} EFI_IMAGE_FILE_HEADER;\r
+\r
+///\r
+/// Size of EFI_IMAGE_FILE_HEADER.\r
+///\r
+#define EFI_IMAGE_SIZEOF_FILE_HEADER        20\r
+\r
+//\r
+// Characteristics\r
+//\r
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED      (1 << 0)     ///< 0x0001  Relocation info stripped from file.\r
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE     (1 << 1)     ///< 0x0002  File is executable  (i.e. no unresolved externel references).\r
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED   (1 << 2)     ///< 0x0004  Line nunbers stripped from file.\r
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED  (1 << 3)     ///< 0x0008  Local symbols stripped from file.\r
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO    (1 << 7)     ///< 0x0080  Bytes of machine word are reversed.\r
+#define EFI_IMAGE_FILE_32BIT_MACHINE        (1 << 8)     ///< 0x0100  32 bit word machine.\r
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED       (1 << 9)     ///< 0x0200  Debugging info stripped from file in .DBG file.\r
+#define EFI_IMAGE_FILE_SYSTEM               (1 << 12)    ///< 0x1000  System File.\r
+#define EFI_IMAGE_FILE_DLL                  (1 << 13)    ///< 0x2000  File is a DLL.\r
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI    (1 << 15)    ///< 0x8000  Bytes of machine word are reversed.\r
+\r
+///\r
+/// Header Data Directories.\r
+///\r
+typedef struct {\r
+  UINT32  VirtualAddress;\r
+  UINT32  Size;\r
+} EFI_IMAGE_DATA_DIRECTORY;\r
+\r
+//\r
+// Directory Entries\r
+//\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT      0\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT      1\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE    2\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION   3\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY    4\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC   5\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG       6\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT   7\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR   8\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS         9\r
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10\r
+\r
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16\r
+\r
+///\r
+/// @attention\r
+/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and \r
+/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary\r
+/// after NT additional fields.\r
+///\r
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b\r
+          \r
+///\r
+/// Optional Header Standard Fields for PE32.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Standard fields.\r
+  ///\r
+  UINT16                    Magic;\r
+  UINT8                     MajorLinkerVersion;\r
+  UINT8                     MinorLinkerVersion;\r
+  UINT32                    SizeOfCode;\r
+  UINT32                    SizeOfInitializedData;\r
+  UINT32                    SizeOfUninitializedData;\r
+  UINT32                    AddressOfEntryPoint;\r
+  UINT32                    BaseOfCode;\r
+  UINT32                    BaseOfData;  ///< PE32 contains this additional field, which is absent in PE32+.\r
+  ///\r
+  /// Optional Header Windows-Specific Fields.\r
+  ///\r
+  UINT32                    ImageBase;\r
+  UINT32                    SectionAlignment;\r
+  UINT32                    FileAlignment;\r
+  UINT16                    MajorOperatingSystemVersion;\r
+  UINT16                    MinorOperatingSystemVersion;\r
+  UINT16                    MajorImageVersion;\r
+  UINT16                    MinorImageVersion;\r
+  UINT16                    MajorSubsystemVersion;\r
+  UINT16                    MinorSubsystemVersion;\r
+  UINT32                    Win32VersionValue;\r
+  UINT32                    SizeOfImage;\r
+  UINT32                    SizeOfHeaders;\r
+  UINT32                    CheckSum;\r
+  UINT16                    Subsystem;\r
+  UINT16                    DllCharacteristics;\r
+  UINT32                    SizeOfStackReserve;\r
+  UINT32                    SizeOfStackCommit;\r
+  UINT32                    SizeOfHeapReserve;\r
+  UINT32                    SizeOfHeapCommit;\r
+  UINT32                    LoaderFlags;\r
+  UINT32                    NumberOfRvaAndSizes;\r
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];\r
+} EFI_IMAGE_OPTIONAL_HEADER32;\r
+\r
+///\r
+/// @attention\r
+/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and \r
+/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary\r
+/// after NT additional fields.\r
+///\r
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b\r
+\r
+///\r
+/// Optional Header Standard Fields for PE32+.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Standard fields.\r
+  ///\r
+  UINT16                    Magic;\r
+  UINT8                     MajorLinkerVersion;\r
+  UINT8                     MinorLinkerVersion;\r
+  UINT32                    SizeOfCode;\r
+  UINT32                    SizeOfInitializedData;\r
+  UINT32                    SizeOfUninitializedData;\r
+  UINT32                    AddressOfEntryPoint;\r
+  UINT32                    BaseOfCode;\r
+  ///\r
+  /// Optional Header Windows-Specific Fields.\r
+  ///\r
+  UINT64                    ImageBase;\r
+  UINT32                    SectionAlignment;\r
+  UINT32                    FileAlignment;\r
+  UINT16                    MajorOperatingSystemVersion;\r
+  UINT16                    MinorOperatingSystemVersion;\r
+  UINT16                    MajorImageVersion;\r
+  UINT16                    MinorImageVersion;\r
+  UINT16                    MajorSubsystemVersion;\r
+  UINT16                    MinorSubsystemVersion;\r
+  UINT32                    Win32VersionValue;\r
+  UINT32                    SizeOfImage;\r
+  UINT32                    SizeOfHeaders;\r
+  UINT32                    CheckSum;\r
+  UINT16                    Subsystem;\r
+  UINT16                    DllCharacteristics;\r
+  UINT64                    SizeOfStackReserve;\r
+  UINT64                    SizeOfStackCommit;\r
+  UINT64                    SizeOfHeapReserve;\r
+  UINT64                    SizeOfHeapCommit;\r
+  UINT32                    LoaderFlags;\r
+  UINT32                    NumberOfRvaAndSizes;\r
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];\r
+} EFI_IMAGE_OPTIONAL_HEADER64;\r
+\r
+\r
+///\r
+/// @attention\r
+/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools.\r
+///\r
+typedef struct {\r
+  UINT32                      Signature;\r
+  EFI_IMAGE_FILE_HEADER       FileHeader;\r
+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;\r
+} EFI_IMAGE_NT_HEADERS32;\r
+\r
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)\r
+\r
+///\r
+/// @attention\r
+/// EFI_IMAGE_HEADERS64 is for use ONLY by tools.\r
+///\r
+typedef struct {\r
+  UINT32                      Signature;\r
+  EFI_IMAGE_FILE_HEADER       FileHeader;\r
+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;\r
+} EFI_IMAGE_NT_HEADERS64;\r
+\r
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)\r
+\r
+//\r
+// Other Windows Subsystem Values\r
+//\r
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN     0\r
+#define EFI_IMAGE_SUBSYSTEM_NATIVE      1\r
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2\r
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3\r
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI     5\r
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI   7\r
+\r
+///\r
+/// Length of ShortName.\r
+///\r
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8\r
+\r
+///\r
+/// Section Table. This table immediately follows the optional header.\r
+///\r
+typedef struct {\r
+  UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];\r
+  union {\r
+    UINT32  PhysicalAddress;\r
+    UINT32  VirtualSize;\r
+  } Misc;\r
+  UINT32  VirtualAddress;\r
+  UINT32  SizeOfRawData;\r
+  UINT32  PointerToRawData;\r
+  UINT32  PointerToRelocations;\r
+  UINT32  PointerToLinenumbers;\r
+  UINT16  NumberOfRelocations;\r
+  UINT16  NumberOfLinenumbers;\r
+  UINT32  Characteristics;\r
+} EFI_IMAGE_SECTION_HEADER;\r
+\r
+///\r
+/// Size of EFI_IMAGE_SECTION_HEADER.\r
+///\r
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER       40\r
+\r
+//\r
+// Section Flags Values\r
+//\r
+#define EFI_IMAGE_SCN_TYPE_NO_PAD                  0x00000008  ///< Reserved.\r
+#define EFI_IMAGE_SCN_CNT_CODE                     0x00000020\r
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA         0x00000040\r
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA       0x00000080\r
+\r
+#define EFI_IMAGE_SCN_LNK_OTHER                    0x00000100  ///< Reserved.\r
+#define EFI_IMAGE_SCN_LNK_INFO                     0x00000200  ///< Section contains comments or some other type of information.\r
+#define EFI_IMAGE_SCN_LNK_REMOVE                   0x00000800  ///< Section contents will not become part of image.\r
+#define EFI_IMAGE_SCN_LNK_COMDAT                   0x00001000\r
+\r
+#define EFI_IMAGE_SCN_ALIGN_1BYTES                 0x00100000\r
+#define EFI_IMAGE_SCN_ALIGN_2BYTES                 0x00200000\r
+#define EFI_IMAGE_SCN_ALIGN_4BYTES                 0x00300000\r
+#define EFI_IMAGE_SCN_ALIGN_8BYTES                 0x00400000\r
+#define EFI_IMAGE_SCN_ALIGN_16BYTES                0x00500000\r
+#define EFI_IMAGE_SCN_ALIGN_32BYTES                0x00600000\r
+#define EFI_IMAGE_SCN_ALIGN_64BYTES                0x00700000\r
+\r
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE              0x02000000\r
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED               0x04000000\r
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED                0x08000000\r
+#define EFI_IMAGE_SCN_MEM_SHARED                   0x10000000\r
+#define EFI_IMAGE_SCN_MEM_EXECUTE                  0x20000000\r
+#define EFI_IMAGE_SCN_MEM_READ                     0x40000000\r
+#define EFI_IMAGE_SCN_MEM_WRITE                    0x80000000\r
+\r
+///\r
+/// Size of a Symbol Table Record.\r
+///\r
+#define EFI_IMAGE_SIZEOF_SYMBOL 18\r
+\r
+//\r
+// Symbols have a section number of the section in which they are\r
+// defined. Otherwise, section numbers have the following meanings:\r
+//\r
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0  ///< Symbol is undefined or is common.\r
+#define EFI_IMAGE_SYM_ABSOLUTE  (UINT16) -1 ///< Symbol is an absolute value.\r
+#define EFI_IMAGE_SYM_DEBUG     (UINT16) -2 ///< Symbol is a special debug item.\r
+\r
+//\r
+// Symbol Type (fundamental) values.\r
+//\r
+#define EFI_IMAGE_SYM_TYPE_NULL   0   ///< no type.\r
+#define EFI_IMAGE_SYM_TYPE_VOID   1   ///< no valid type.\r
+#define EFI_IMAGE_SYM_TYPE_CHAR   2   ///< type character.\r
+#define EFI_IMAGE_SYM_TYPE_SHORT  3   ///< type short integer.\r
+#define EFI_IMAGE_SYM_TYPE_INT    4\r
+#define EFI_IMAGE_SYM_TYPE_LONG   5\r
+#define EFI_IMAGE_SYM_TYPE_FLOAT  6\r
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7\r
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8\r
+#define EFI_IMAGE_SYM_TYPE_UNION  9\r
+#define EFI_IMAGE_SYM_TYPE_ENUM   10  ///< enumeration.\r
+#define EFI_IMAGE_SYM_TYPE_MOE    11  ///< member of enumeration.\r
+#define EFI_IMAGE_SYM_TYPE_BYTE   12\r
+#define EFI_IMAGE_SYM_TYPE_WORD   13\r
+#define EFI_IMAGE_SYM_TYPE_UINT   14\r
+#define EFI_IMAGE_SYM_TYPE_DWORD  15\r
+\r
+//\r
+// Symbol Type (derived) values.\r
+//\r
+#define EFI_IMAGE_SYM_DTYPE_NULL      0 ///< no derived type.\r
+#define EFI_IMAGE_SYM_DTYPE_POINTER   1\r
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION  2\r
+#define EFI_IMAGE_SYM_DTYPE_ARRAY     3\r
+\r
+//\r
+// Storage classes.\r
+//\r
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION   ((UINT8) -1)\r
+#define EFI_IMAGE_SYM_CLASS_NULL              0\r
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC         1\r
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL          2\r
+#define EFI_IMAGE_SYM_CLASS_STATIC            3\r
+#define EFI_IMAGE_SYM_CLASS_REGISTER          4\r
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF      5\r
+#define EFI_IMAGE_SYM_CLASS_LABEL             6\r
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL   7\r
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT  8\r
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT          9\r
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG        10\r
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION   11\r
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG         12\r
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION   13\r
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC  14\r
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG          15\r
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM    16\r
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM    17\r
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD         18\r
+#define EFI_IMAGE_SYM_CLASS_BLOCK             100\r
+#define EFI_IMAGE_SYM_CLASS_FUNCTION          101\r
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT     102\r
+#define EFI_IMAGE_SYM_CLASS_FILE              103\r
+#define EFI_IMAGE_SYM_CLASS_SECTION           104\r
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL     105\r
+\r
+//\r
+// type packing constants\r
+//\r
+#define EFI_IMAGE_N_BTMASK  017\r
+#define EFI_IMAGE_N_TMASK   060\r
+#define EFI_IMAGE_N_TMASK1  0300\r
+#define EFI_IMAGE_N_TMASK2  0360\r
+#define EFI_IMAGE_N_BTSHFT  4\r
+#define EFI_IMAGE_N_TSHIFT  2\r
+\r
+//\r
+// Communal selection types.\r
+//\r
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES    1\r
+#define EFI_IMAGE_COMDAT_SELECT_ANY             2\r
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE       3\r
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH     4\r
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE     5\r
+                                       \r
+//\r
+// the following values only be referred in PeCoff, not defined in PECOFF.\r
+//\r
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1\r
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2\r
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3\r
+\r
+///\r
+/// Relocation format.\r
+///\r
+typedef struct {\r
+  UINT32  VirtualAddress;\r
+  UINT32  SymbolTableIndex;\r
+  UINT16  Type;\r
+} EFI_IMAGE_RELOCATION;\r
+\r
+///\r
+/// Size of EFI_IMAGE_RELOCATION\r
+///\r
+#define EFI_IMAGE_SIZEOF_RELOCATION 10\r
+\r
+//\r
+// I386 relocation types.\r
+//\r
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000  ///< Reference is absolute, no relocation is necessary.\r
+#define EFI_IMAGE_REL_I386_DIR16    0x0001  ///< Direct 16-bit reference to the symbols virtual address.\r
+#define EFI_IMAGE_REL_I386_REL16    0x0002  ///< PC-relative 16-bit reference to the symbols virtual address.\r
+#define EFI_IMAGE_REL_I386_DIR32    0x0006  ///< Direct 32-bit reference to the symbols virtual address.\r
+#define EFI_IMAGE_REL_I386_DIR32NB  0x0007  ///< Direct 32-bit reference to the symbols virtual address, base not included.\r
+#define EFI_IMAGE_REL_I386_SEG12    0x0009  ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address.\r
+#define EFI_IMAGE_REL_I386_SECTION  0x000A\r
+#define EFI_IMAGE_REL_I386_SECREL   0x000B\r
+#define EFI_IMAGE_REL_I386_REL32    0x0014  ///< PC-relative 32-bit reference to the symbols virtual address.\r
+\r
+// \r
+// x64 processor relocation types.\r
+// \r
+#define IMAGE_REL_AMD64_ABSOLUTE  0x0000\r
+#define IMAGE_REL_AMD64_ADDR64    0x0001\r
+#define IMAGE_REL_AMD64_ADDR32    0x0002\r
+#define IMAGE_REL_AMD64_ADDR32NB  0x0003\r
+#define IMAGE_REL_AMD64_REL32     0x0004\r
+#define IMAGE_REL_AMD64_REL32_1   0x0005\r
+#define IMAGE_REL_AMD64_REL32_2   0x0006\r
+#define IMAGE_REL_AMD64_REL32_3   0x0007\r
+#define IMAGE_REL_AMD64_REL32_4   0x0008\r
+#define IMAGE_REL_AMD64_REL32_5   0x0009\r
+#define IMAGE_REL_AMD64_SECTION   0x000A\r
+#define IMAGE_REL_AMD64_SECREL    0x000B\r
+#define IMAGE_REL_AMD64_SECREL7   0x000C\r
+#define IMAGE_REL_AMD64_TOKEN     0x000D\r
+#define IMAGE_REL_AMD64_SREL32    0x000E\r
+#define IMAGE_REL_AMD64_PAIR      0x000F\r
+#define IMAGE_REL_AMD64_SSPAN32   0x0010\r
+\r
+///\r
+/// Based relocation format.\r
+///\r
+typedef struct {\r
+  UINT32  VirtualAddress;\r
+  UINT32  SizeOfBlock;\r
+} EFI_IMAGE_BASE_RELOCATION;\r
+\r
+///\r
+/// Size of EFI_IMAGE_BASE_RELOCATION.\r
+///\r
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION  8\r
+\r
+//\r
+// Based relocation types.\r
+//\r
+#define EFI_IMAGE_REL_BASED_ABSOLUTE        0\r
+#define EFI_IMAGE_REL_BASED_HIGH            1\r
+#define EFI_IMAGE_REL_BASED_LOW             2\r
+#define EFI_IMAGE_REL_BASED_HIGHLOW         3\r
+#define EFI_IMAGE_REL_BASED_HIGHADJ         4\r
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR    5\r
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A      5\r
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T      7\r
+#define EFI_IMAGE_REL_BASED_IA64_IMM64      9\r
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16  9\r
+#define EFI_IMAGE_REL_BASED_DIR64           10\r
+\r
+///\r
+/// Line number format.\r
+///\r
+typedef struct {\r
+  union {\r
+    UINT32  SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0.\r
+    UINT32  VirtualAddress;   ///< Virtual address of line number.\r
+  } Type;\r
+  UINT16  Linenumber;         ///< Line number.\r
+} EFI_IMAGE_LINENUMBER;\r
+\r
+///\r
+/// Size of EFI_IMAGE_LINENUMBER.\r
+///\r
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6\r
+\r
+//\r
+// Archive format.\r
+//\r
+#define EFI_IMAGE_ARCHIVE_START_SIZE        8\r
+#define EFI_IMAGE_ARCHIVE_START             "!<arch>\n"\r
+#define EFI_IMAGE_ARCHIVE_END               "`\n"\r
+#define EFI_IMAGE_ARCHIVE_PAD               "\n"\r
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER     "/               "\r
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER  "//              "\r
+\r
+///\r
+/// Archive Member Headers\r
+///\r
+typedef struct {\r
+  UINT8 Name[16];     ///< File member name - `/' terminated.\r
+  UINT8 Date[12];     ///< File member date - decimal.\r
+  UINT8 UserID[6];    ///< File member user id - decimal.\r
+  UINT8 GroupID[6];   ///< File member group id - decimal.\r
+  UINT8 Mode[8];      ///< File member mode - octal.\r
+  UINT8 Size[10];     ///< File member size - decimal.\r
+  UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A).\r
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;\r
+\r
+///\r
+/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER.\r
+///\r
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60\r
+\r
+\r
+//\r
+// DLL Support\r
+//\r
+\r
+///\r
+/// Export Directory Table.\r
+///\r
+typedef struct {\r
+  UINT32  Characteristics;\r
+  UINT32  TimeDateStamp;\r
+  UINT16  MajorVersion;\r
+  UINT16  MinorVersion;\r
+  UINT32  Name;\r
+  UINT32  Base;\r
+  UINT32  NumberOfFunctions;\r
+  UINT32  NumberOfNames;\r
+  UINT32  AddressOfFunctions;\r
+  UINT32  AddressOfNames;\r
+  UINT32  AddressOfNameOrdinals;\r
+} EFI_IMAGE_EXPORT_DIRECTORY;\r
+\r
+///\r
+/// Hint/Name Table.\r
+///\r
+typedef struct {\r
+  UINT16  Hint;\r
+  UINT8   Name[1];\r
+} EFI_IMAGE_IMPORT_BY_NAME;\r
+\r
+///\r
+/// Import Address Table RVA (Thunk Table).\r
+///\r
+typedef struct {\r
+  union {\r
+    UINT32                    Function;\r
+    UINT32                    Ordinal;\r
+    EFI_IMAGE_IMPORT_BY_NAME  *AddressOfData;\r
+  } u1;\r
+} EFI_IMAGE_THUNK_DATA;\r
+\r
+#define EFI_IMAGE_ORDINAL_FLAG              BIT31    ///< Flag for PE32.\r
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal)  ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)\r
+#define EFI_IMAGE_ORDINAL(Ordinal)          (Ordinal & 0xffff)\r
+\r
+///\r
+/// Import Directory Table\r
+///\r
+typedef struct {\r
+  UINT32                Characteristics;\r
+  UINT32                TimeDateStamp;\r
+  UINT32                ForwarderChain;\r
+  UINT32                Name;\r
+  EFI_IMAGE_THUNK_DATA  *FirstThunk;\r
+} EFI_IMAGE_IMPORT_DESCRIPTOR;\r
+\r
+\r
+///\r
+/// Debug Directory Format.\r
+///\r
+typedef struct {\r
+  UINT32  Characteristics;\r
+  UINT32  TimeDateStamp;\r
+  UINT16  MajorVersion;\r
+  UINT16  MinorVersion;\r
+  UINT32  Type;\r
+  UINT32  SizeOfData;\r
+  UINT32  RVA;           ///< The address of the debug data when loaded, relative to the image base.\r
+  UINT32  FileOffset;    ///< The file pointer to the debug data.\r
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;\r
+\r
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2     ///< The Visual C++ debug information.\r
+\r
+///\r
+/// Debug Data Structure defined in Microsoft C++.\r
+///\r
+#define CODEVIEW_SIGNATURE_NB10  SIGNATURE_32('N', 'B', '1', '0')\r
+typedef struct {\r
+  UINT32  Signature;                        ///< "NB10"\r
+  UINT32  Unknown;\r
+  UINT32  Unknown2;\r
+  UINT32  Unknown3;\r
+  //\r
+  // Filename of .PDB goes here\r
+  //\r
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;\r
+\r
+///\r
+/// Debug Data Structure defined in Microsoft C++.\r
+///\r
+#define CODEVIEW_SIGNATURE_RSDS  SIGNATURE_32('R', 'S', 'D', 'S')\r
+typedef struct {\r
+  UINT32  Signature;                        ///< "RSDS".\r
+  UINT32  Unknown;\r
+  UINT32  Unknown2;\r
+  UINT32  Unknown3;\r
+  UINT32  Unknown4;\r
+  UINT32  Unknown5;\r
+  //\r
+  // Filename of .PDB goes here\r
+  //\r
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;\r
+\r
+\r
+///\r
+/// Debug Data Structure defined by Apple Mach-O to Coff utility.\r
+///\r
+#define CODEVIEW_SIGNATURE_MTOC  SIGNATURE_32('M', 'T', 'O', 'C')\r
+typedef struct {\r
+  UINT32    Signature;                       ///< "MTOC".\r
+  EFI_GUID      MachOUuid;\r
+  //\r
+  //  Filename of .DLL (Mach-O with debug info) goes here\r
+  //\r
+} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;\r
+\r
+///\r
+/// Resource format.\r
+///\r
+typedef struct {\r
+  UINT32  Characteristics;\r
+  UINT32  TimeDateStamp;\r
+  UINT16  MajorVersion;\r
+  UINT16  MinorVersion;\r
+  UINT16  NumberOfNamedEntries;\r
+  UINT16  NumberOfIdEntries;\r
+  //\r
+  // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here.\r
+  //\r
+} EFI_IMAGE_RESOURCE_DIRECTORY;\r
+\r
+///\r
+/// Resource directory entry format.\r
+///\r
+typedef struct {\r
+  union {\r
+    struct {\r
+      UINT32  NameOffset:31;\r
+      UINT32  NameIsString:1;\r
+    } s;\r
+    UINT32  Id;\r
+  } u1;\r
+  union {\r
+    UINT32  OffsetToData;\r
+    struct {\r
+      UINT32  OffsetToDirectory:31;\r
+      UINT32  DataIsDirectory:1;\r
+    } s;\r
+  } u2;\r
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;\r
+\r
+///\r
+/// Resource directory entry for string.\r
+///\r
+typedef struct {\r
+  UINT16  Length;\r
+  CHAR16  String[1];\r
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;\r
+\r
+///\r
+/// Resource directory entry for data array.\r
+///\r
+typedef struct {\r
+  UINT32  OffsetToData;\r
+  UINT32  Size;\r
+  UINT32  CodePage;\r
+  UINT32  Reserved;\r
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;\r
+\r
+///\r
+/// Header format for TE images, defined in the PI Specification, 1.0.\r
+///\r
+typedef struct {\r
+  UINT16                    Signature;            ///< The signature for TE format = "VZ".\r
+  UINT16                    Machine;              ///< From the original file header.\r
+  UINT8                     NumberOfSections;     ///< From the original file header.\r
+  UINT8                     Subsystem;            ///< From original optional header.\r
+  UINT16                    StrippedSize;         ///< Number of bytes we removed from the header.\r
+  UINT32                    AddressOfEntryPoint;  ///< Offset to entry point -- from original optional header.\r
+  UINT32                    BaseOfCode;           ///< From original image -- required for ITP debug.\r
+  UINT64                    ImageBase;            ///< From original file header.\r
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[2];     ///< Only base relocation and debug directory.\r
+} EFI_TE_IMAGE_HEADER;\r
+\r
+\r
+#define EFI_TE_IMAGE_HEADER_SIGNATURE  SIGNATURE_16('V', 'Z')\r
+\r
+//\r
+// Data directory indexes in our TE image header\r
+//\r
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC  0\r
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG      1\r
+\r
+\r
+///\r
+/// Union of PE32, PE32+, and TE headers.\r
+///\r
+typedef union {\r
+  EFI_IMAGE_NT_HEADERS32   Pe32;\r
+  EFI_IMAGE_NT_HEADERS64   Pe32Plus;\r
+  EFI_TE_IMAGE_HEADER      Te;\r
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;\r
+\r
+typedef union {\r
+  EFI_IMAGE_NT_HEADERS32            *Pe32;\r
+  EFI_IMAGE_NT_HEADERS64            *Pe32Plus;\r
+  EFI_TE_IMAGE_HEADER               *Te;\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION   *Union;\r
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;\r
+\r
+typedef struct {\r
+       WIN_CERTIFICATE Hdr;\r
+       UINT8           CertData[1];\r
+} WIN_CERTIFICATE_EFI_PKCS;\r
+\r
+#define SHA256_DIGEST_SIZE  32\r
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002\r
+\r
+typedef struct {\r
+       UINT64 ImageAddress;\r
+       UINT64 ImageSize;\r
+       UINT64 EntryPoint;\r
+       UINTN SizeOfHeaders;\r
+       UINT16 ImageType;\r
+       UINT16 NumberOfSections;\r
+       UINT32 SectionAlignment;\r
+       EFI_IMAGE_SECTION_HEADER *FirstSection;\r
+       EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
+       EFI_IMAGE_DATA_DIRECTORY *SecDir;\r
+       UINT64 NumberOfRvaAndSizes;\r
+       EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr;\r
+} PE_COFF_LOADER_IMAGE_CONTEXT;\r
+\r
+#endif\r
diff --git a/include/configtable.h b/include/configtable.h
new file mode 100644 (file)
index 0000000..fa2b505
--- /dev/null
@@ -0,0 +1,68 @@
+/* definitions straight from TianoCore */
+
+typedef UINT32 EFI_IMAGE_EXECUTION_ACTION;
+
+#define EFI_IMAGE_EXECUTION_AUTHENTICATION      0x00000007 
+#define EFI_IMAGE_EXECUTION_AUTH_UNTESTED       0x00000000
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED     0x00000001
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED     0x00000002
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND  0x00000003
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND      0x00000004
+#define EFI_IMAGE_EXECUTION_POLICY_FAILED       0x00000005
+#define EFI_IMAGE_EXECUTION_INITIALIZED         0x00000008
+
+typedef struct {
+  ///
+  /// Describes the action taken by the firmware regarding this image.
+  ///
+  EFI_IMAGE_EXECUTION_ACTION    Action;
+  ///
+  /// Size of all of the entire structure.
+  ///
+  UINT32                        InfoSize;
+  ///
+  /// If this image was a UEFI device driver (for option ROM, for example) this is the 
+  /// null-terminated, user-friendly name for the device. If the image was for an application, 
+  /// then this is the name of the application. If this cannot be determined, then a simple 
+  /// NULL character should be put in this position.
+  /// CHAR16                    Name[];
+  ///
+
+  ///
+  /// For device drivers, this is the device path of the device for which this device driver 
+  /// was intended. In some cases, the driver itself may be stored as part of the system 
+  /// firmware, but this field should record the device's path, not the firmware path. For 
+  /// applications, this is the device path of the application. If this cannot be determined, 
+  /// a simple end-of-path device node should be put in this position.
+  /// EFI_DEVICE_PATH_PROTOCOL  DevicePath;
+  ///
+
+  ///
+  /// Zero or more image signatures. If the image contained no signatures, 
+  /// then this field is empty.
+  ///
+  ///EFI_SIGNATURE_LIST            Signature;
+  UINT8 Data[];
+} EFI_IMAGE_EXECUTION_INFO;
+
+typedef struct {
+  ///
+  /// Number of EFI_IMAGE_EXECUTION_INFO structures.
+  ///
+  UINTN                     NumberOfImages; 
+  ///
+  /// Number of image instances of EFI_IMAGE_EXECUTION_INFO structures.
+  ///
+  EFI_IMAGE_EXECUTION_INFO  InformationInfo[];
+} EFI_IMAGE_EXECUTION_INFO_TABLE;
+
+
+void *
+configtable_get_table(EFI_GUID *guid);
+EFI_IMAGE_EXECUTION_INFO_TABLE *
+configtable_get_image_table(void);
+EFI_IMAGE_EXECUTION_INFO *
+configtable_find_image(const EFI_DEVICE_PATH *DevicePath);
+int
+configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath);
+
diff --git a/include/console.h b/include/console.h
new file mode 100644 (file)
index 0000000..d59e3b4
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef _SHIM_LIB_CONSOLE_H
+#define _SHIM_LIB_CONSOLE_H 1
+
+EFI_STATUS
+console_get_keystroke(EFI_INPUT_KEY *key);
+void
+console_print_box_at(CHAR16 *str_arr[], int highlight,
+                    int start_col, int start_row,
+                    int size_cols, int size_rows,
+                    int offset, int lines);
+void
+console_print_box(CHAR16 *str_arr[], int highlight);
+int
+console_yes_no(CHAR16 *str_arr[]);
+int
+console_select(CHAR16 *title[], CHAR16* selectors[], unsigned int start);
+void
+console_errorbox(CHAR16 *err);
+void
+console_error(CHAR16 *err, EFI_STATUS);
+void
+console_alertbox(CHAR16 **title);
+void
+console_notify(CHAR16 *string);
+void
+console_reset(void);
+#define NOSEL 0x7fffffff
+
+#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
+  { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} }
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL   EFI_CONSOLE_CONTROL_PROTOCOL;
+
+typedef enum {
+  EfiConsoleControlScreenText,
+  EfiConsoleControlScreenGraphics,
+  EfiConsoleControlScreenMaxValue
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   *Mode,
+  OUT BOOLEAN                           *GopUgaExists,  OPTIONAL  
+  OUT BOOLEAN                           *StdInLocked    OPTIONAL
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE   Mode
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) (
+  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
+  IN CHAR16                             *Password
+  );
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+  EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE           GetMode;
+  EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE           SetMode;
+  EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN        LockStdIn;
+};
+
+extern VOID setup_console (int text);
+extern VOID setup_verbosity(VOID);
+extern UINT8 verbose;
+#define dprint(fmt, ...) ({                                            \
+               UINTN __dprint_ret = 0;                                 \
+               if (verbose)                                            \
+                       __dprint_ret = Print((fmt), ##__VA_ARGS__);     \
+               __dprint_ret;                                           \
+       })
+#define dprinta(fmt, ...) ({                                                                   \
+               UINTN __dprinta_ret = 0;                                                        \
+               if (verbose) {                                                                  \
+                       UINTN __dprinta_i;                                                      \
+                       CHAR16 *__dprinta_str = AllocateZeroPool((strlena(fmt) + 1) * 2);       \
+                       for (__dprinta_i = 0; fmt[__dprinta_i] != '\0'; __dprinta_i++)          \
+                               __dprinta_str[__dprinta_i] = fmt[__dprinta_i];                  \
+                       __dprinta_ret = Print((__dprinta_str), ##__VA_ARGS__);                  \
+                       FreePool(__dprinta_str);                                                \
+               }                                                                               \
+               __dprinta_ret;                                                                  \
+       })
+
+#endif /* _SHIM_LIB_CONSOLE_H */
diff --git a/include/efiauthenticated.h b/include/efiauthenticated.h
new file mode 100644 (file)
index 0000000..f7d6bcb
--- /dev/null
@@ -0,0 +1,222 @@
+#ifndef _INC_EFIAUTHENTICATED_H
+#define _INC_EFIAUTHENTICATED_H
+#include <wincert.h>
+//***********************************************************************
+// Signature Database
+//***********************************************************************
+///
+/// The format of a signature database. 
+///
+#pragma pack(1)
+
+typedef struct {
+  ///
+  /// An identifier which identifies the agent which added the signature to the list.
+  ///
+  EFI_GUID          SignatureOwner;
+  ///
+  /// The format of the signature is defined by the SignatureType.
+  ///
+  UINT8             SignatureData[1];
+} EFI_SIGNATURE_DATA;
+
+typedef struct {
+  ///
+  /// Type of the signature. GUID signature types are defined in below.
+  ///
+  EFI_GUID            SignatureType;
+  ///
+  /// Total size of the signature list, including this header.
+  ///
+  UINT32              SignatureListSize;
+  ///
+  /// Size of the signature header which precedes the array of signatures.
+  ///
+  UINT32              SignatureHeaderSize;
+  ///
+  /// Size of each signature.
+  ///
+  UINT32              SignatureSize; 
+  ///
+  /// Header before the array of signatures. The format of this header is specified 
+  /// by the SignatureType.
+  /// UINT8           SignatureHeader[SignatureHeaderSize];
+  ///
+  /// An array of signatures. Each signature is SignatureSize bytes in length. 
+  /// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
+  ///
+} EFI_SIGNATURE_LIST;
+
+#pragma pack()
+
+//
+// _WIN_CERTIFICATE.wCertificateType
+// 
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
+#define WIN_CERT_TYPE_EFI_PKCS115      0x0EF0
+#define WIN_CERT_TYPE_EFI_GUID         0x0EF1
+
+#define EFI_CERT_X509_GUID \
+  (EFI_GUID){                                                          \
+    0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} \
+  }
+
+#define EFI_CERT_RSA2048_GUID \
+  (EFI_GUID){                                                          \
+    0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} \
+  }
+
+
+#define EFI_CERT_TYPE_PKCS7_GUID \
+  (EFI_GUID){                                                          \
+    0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
+  }
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertType
+/// 
+#define EFI_CERT_TYPE_RSA2048_SHA256_GUID \
+  {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } }
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertData
+/// 
+typedef struct {
+  EFI_GUID  HashType;
+  UINT8     PublicKey[256];
+  UINT8     Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
+
+///
+/// Certificate which encapsulates a GUID-specific digital signature
+///
+typedef struct {
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where
+  /// wCertificateType is set to WIN_CERT_TYPE_UEFI_GUID. 
+  ///                         
+  WIN_CERTIFICATE   Hdr;
+  ///
+  /// This is the unique id which determines the 
+  /// format of the CertData. .
+  ///
+  EFI_GUID          CertType;
+  /// 
+  /// The following is the certificate data. The format of
+  /// the data is determined by the CertType. 
+  /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
+  /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
+  ///
+  UINT8            CertData[1];
+} WIN_CERTIFICATE_UEFI_GUID;
+
+
+///   
+/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
+///  
+/// The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from
+/// WIN_CERTIFICATE and encapsulate the information needed to  
+/// implement the RSASSA-PKCS1-v1_5 digital signature algorithm as  
+/// specified in RFC2437.  
+///  
+typedef struct {     
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where 
+  /// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15.                       
+  ///
+  WIN_CERTIFICATE Hdr;
+  ///
+  /// This is the hashing algorithm which was performed on the
+  /// UEFI executable when creating the digital signature. 
+  ///
+  EFI_GUID        HashAlgorithm;
+  ///
+  /// The following is the actual digital signature. The   
+  /// size of the signature is the same size as the key 
+  /// (1024-bit key is 128 bytes) and can be determined by 
+  /// subtracting the length of the other parts of this header
+  /// from the total length of the certificate as found in 
+  /// Hdr.dwLength.                               
+  ///
+  /// UINT8 Signature[];
+  ///
+} WIN_CERTIFICATE_EFI_PKCS1_15;
+
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+
+///
+/// Attributes of Authenticated Variable
+///
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS              0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS   0x00000020
+#define EFI_VARIABLE_APPEND_WRITE                            0x00000040
+
+///   
+/// AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+/// WIN_CERTIFICATE_UEFI_GUID and the CertType
+/// EFI_CERT_TYPE_RSA2048_SHA256_GUID. If the attribute specifies
+/// authenticated access, then the Data buffer should begin with an
+/// authentication descriptor prior to the data payload and DataSize
+/// should reflect the the data.and descriptor size. The caller
+/// shall digest the Monotonic Count value and the associated data
+/// for the variable update using the SHA-256 1-way hash algorithm.
+/// The ensuing the 32-byte digest will be signed using the private
+/// key associated w/ the public/private 2048-bit RSA key-pair. The
+/// WIN_CERTIFICATE shall be used to describe the signature of the
+/// Variable data *Data. In addition, the signature will also
+/// include the MonotonicCount value to guard against replay attacks.
+///  
+typedef struct {
+  ///
+  /// Included in the signature of        
+  /// AuthInfo.Used to ensure freshness/no
+  /// replay. Incremented during each     
+  /// "Write" access.   
+  ///                  
+  UINT64                      MonotonicCount;
+  ///
+  /// Provides the authorization for the variable 
+  /// access. It is a signature across the        
+  /// variable data and the  Monotonic Count      
+  /// value. Caller uses Private key that is      
+  /// associated with a public key that has been  
+  /// provisioned via the key exchange.           
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+
+///
+/// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is 
+/// set, then the Data buffer shall begin with an instance of a complete (and serialized)
+/// EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new 
+/// variable value and DataSize shall reflect the combined size of the descriptor and the new 
+/// variable value. The authentication descriptor is not part of the variable data and is not 
+/// returned by subsequent calls to GetVariable().
+///
+typedef struct {
+  ///
+  /// For the TimeStamp value, components Pad1, Nanosecond, TimeZone, Daylight and 
+  /// Pad2 shall be set to 0. This means that the time shall always be expressed in GMT.
+  ///
+  EFI_TIME                    TimeStamp;
+  /// 
+  /// Only a CertType of  EFI_CERT_TYPE_PKCS7_GUID is accepted.
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+ } EFI_VARIABLE_AUTHENTICATION_2;
+
+///
+/// Size of AuthInfo prior to the data payload.
+///
+#define AUTHINFO_SIZE ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \
+                       (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \
+                       sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))
+
+#define AUTHINFO2_SIZE(VarAuth2) ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
+                                  (UINTN) ((EFI_VARIABLE_AUTHENTICATION_2 *) (VarAuth2))->AuthInfo.Hdr.dwLength)
+
+#define OFFSET_OF_AUTHINFO2_CERT_DATA ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
+                                       (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)))
+
+#endif
diff --git a/include/errors.h b/include/errors.h
new file mode 100644 (file)
index 0000000..0da4bb5
--- /dev/null
@@ -0,0 +1,9 @@
+#include <efierr.h>
+
+#ifndef EFI_INCOMPATIBLE_VERSION
+#define EFI_INCOMPATIBLE_VERSION       EFIERR(25)
+#endif
+#ifndef EFI_SECURITY_VIOLATION
+#define EFI_SECURITY_VIOLATION         EFIERR(26)
+#endif
+
diff --git a/include/execute.h b/include/execute.h
new file mode 100644 (file)
index 0000000..9aecbff
--- /dev/null
@@ -0,0 +1,5 @@
+EFI_STATUS
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li,
+             EFI_DEVICE_PATH **path, CHAR16 **PathName);
+EFI_STATUS
+execute(EFI_HANDLE image, CHAR16 *name);
diff --git a/include/guid.h b/include/guid.h
new file mode 100644 (file)
index 0000000..86b709b
--- /dev/null
@@ -0,0 +1,14 @@
+#include <efi.h>
+
+extern EFI_GUID GV_GUID;
+extern EFI_GUID SIG_DB;
+extern EFI_GUID X509_GUID;
+extern EFI_GUID RSA2048_GUID;
+extern EFI_GUID PKCS7_GUID;
+extern EFI_GUID IMAGE_PROTOCOL;
+extern EFI_GUID SIMPLE_FS_PROTOCOL;
+extern EFI_GUID EFI_CERT_SHA1_GUID;
+extern EFI_GUID EFI_CERT_SHA256_GUID;
+extern EFI_GUID MOK_OWNER;
+extern EFI_GUID SECURITY_PROTOCOL_GUID;
+extern EFI_GUID SECURITY2_PROTOCOL_GUID;
diff --git a/include/security_policy.h b/include/security_policy.h
new file mode 100644 (file)
index 0000000..7854db1
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _SHIM_LIB_SECURITY_POLICY_H
+#define _SHIM_LIB_SECURITY_POLICY_H 1
+
+#if defined(OVERRIDE_SECURITY_POLICY)
+typedef EFI_STATUS (*SecurityHook) (void *data, UINT32 len);
+
+EFI_STATUS
+security_policy_install(SecurityHook authentication);
+EFI_STATUS
+security_policy_uninstall(void);
+void
+security_protocol_set_hashes(unsigned char *esl, int len);
+#endif /* OVERRIDE_SECURITY_POLICY */
+
+#endif /* SHIM_LIB_SECURITY_POLICY_H */
diff --git a/include/shell.h b/include/shell.h
new file mode 100644 (file)
index 0000000..9cb5d47
--- /dev/null
@@ -0,0 +1,2 @@
+EFI_STATUS
+argsplit(EFI_HANDLE image, int *argc, CHAR16*** ARGV);
diff --git a/include/simple_file.h b/include/simple_file.h
new file mode 100644 (file)
index 0000000..fe4fd97
--- /dev/null
@@ -0,0 +1,21 @@
+EFI_STATUS
+simple_file_open (EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode);
+EFI_STATUS
+simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UINT64 mode);
+EFI_STATUS
+simple_file_read_all(EFI_FILE *file, UINTN *size, void **buffer);
+EFI_STATUS
+simple_file_write_all(EFI_FILE *file, UINTN size, void *buffer);
+void
+simple_file_close(EFI_FILE *file);
+EFI_STATUS
+simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **Entries,
+                   int *count);
+EFI_STATUS
+simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
+                 CHAR16 ***result, int *count, EFI_FILE_INFO **entries);
+void
+simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
+                    CHAR16 *filter, CHAR16 **result);
+EFI_STATUS
+simple_volume_selector(CHAR16 **title, CHAR16 **selected, EFI_HANDLE *h);
diff --git a/include/str.h b/include/str.h
new file mode 100644 (file)
index 0000000..9a74836
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef SHIM_STR_H
+#define SHIM_STR_H
+
+static inline
+__attribute__((unused))
+unsigned long strnlena(const CHAR8 *s, unsigned long n)
+{
+       unsigned long i;
+       for (i = 0; i <= n; i++)
+               if (s[i] == '\0')
+                       break;
+       return i;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
+{
+       unsigned long i;
+
+       for (i = 0; i < n && src[i] != '\0'; i++)
+               dest[i] = src[i];
+       for (; i < n; i++)
+               dest[i] = '\0';
+
+       return dest;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strcata(CHAR8 *dest, const CHAR8 *src)
+{
+       unsigned long dest_len = strlena(dest);
+       unsigned long i;
+
+       for (i = 0; src[i] != '\0'; i++)
+               dest[dest_len + i] = src[i];
+       dest[dest_len + i] = '\0';
+
+       return dest;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+translate_slashes(char *str)
+{
+       int i;
+       int j;
+       if (str == NULL)
+               return (CHAR8 *)str;
+
+       for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
+               if (str[i] == '\\') {
+                       str[j] = '/';
+                       if (str[i+1] == '\\')
+                               i++;
+               }
+       }
+       return (CHAR8 *)str;
+}
+
+#endif /* SHIM_STR_H */
diff --git a/include/variables.h b/include/variables.h
new file mode 100644 (file)
index 0000000..deed269
--- /dev/null
@@ -0,0 +1,59 @@
+#include <efiauthenticated.h>
+
+#include <PeImage.h>           /* for SHA256_DIGEST_SIZE */
+
+#define certlist_for_each_certentry(cl, cl_init, s, s_init)            \
+       for (cl = (EFI_SIGNATURE_LIST *)(cl_init), s = (s_init);        \
+               s > 0 && s >= cl->SignatureListSize;                    \
+               s -= cl->SignatureListSize,                             \
+               cl = (EFI_SIGNATURE_LIST *) ((UINT8 *)cl + cl->SignatureListSize))
+
+/*
+ * Warning: this assumes (cl)->SignatureHeaderSize is zero.  It is for all
+ * the signatures we process (X509, RSA2048, SHA256)
+ */
+#define certentry_for_each_cert(c, cl) \
+  for (c = (EFI_SIGNATURE_DATA *)((UINT8 *) (cl) + sizeof(EFI_SIGNATURE_LIST) + (cl)->SignatureHeaderSize); \
+       (UINT8 *)c < ((UINT8 *)(cl)) + (cl)->SignatureListSize; \
+       c = (EFI_SIGNATURE_DATA *)((UINT8 *)c + (cl)->SignatureSize))
+
+EFI_STATUS
+CreatePkX509SignatureList (
+  IN   UINT8                       *X509Data,
+  IN   UINTN                       X509DataSize,
+  IN   EFI_GUID                    owner,
+  OUT   EFI_SIGNATURE_LIST          **PkCert 
+                          );
+EFI_STATUS
+CreateTimeBasedPayload (
+  IN OUT UINTN            *DataSize,
+  IN OUT UINT8            **Data
+                       );
+EFI_STATUS
+SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner, UINT32 options, int createtimebased);
+EFI_STATUS
+get_variable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner);
+EFI_STATUS
+get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
+                 UINT32 *attributes);
+EFI_STATUS
+find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen);
+EFI_STATUS
+find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen);
+
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
+
+UINT64
+GetOSIndications(void);
+EFI_STATUS
+SETOSIndicationsAndReboot(UINT64 indications);
+int
+variable_is_secureboot(void);
+int
+variable_is_setupmode(int default_return);
+EFI_STATUS
+variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
+                    UINT8 hash[SHA256_DIGEST_SIZE]);
+EFI_STATUS
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
+                   void **out, int *outlen);
diff --git a/include/version.h b/include/version.h
new file mode 100644 (file)
index 0000000..09fd44a
--- /dev/null
@@ -0,0 +1,8 @@
+#define VERSION "1.3.4"
+
+static void
+version(const char *progname)
+{
+       printf("%s " VERSION "\n", progname);
+}
+
diff --git a/include/wincert.h b/include/wincert.h
new file mode 100644 (file)
index 0000000..68d1974
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _INC_WINCERT_H
+#define _INC_WINCERT_H
+
+///
+/// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
+///
+typedef struct {
+  ///
+  /// The length of the entire certificate,  
+  /// including the length of the header, in bytes.                                
+  ///
+  UINT32  dwLength;
+  ///
+  /// The revision level of the WIN_CERTIFICATE 
+  /// structure. The current revision level is 0x0200.                                   
+  ///
+  UINT16  wRevision;
+  ///
+  /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI      
+  /// certificate types. The UEFI specification reserves the range of 
+  /// certificate type values from 0x0EF0 to 0x0EFF.                          
+  ///
+  UINT16  wCertificateType;
+  ///
+  /// The following is the actual certificate. The format of   
+  /// the certificate depends on wCertificateType.
+  ///
+  /// UINT8 bCertificate[ANYSIZE_ARRAY];
+  ///
+} WIN_CERTIFICATE;
+
+
+#endif
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..d93a26d
--- /dev/null
@@ -0,0 +1,15 @@
+TARGET = lib.a
+
+LIBFILES = simple_file.o guid.o console.o execute.o configtable.o shell.o variables.o security_policy.o
+
+EFI_INCLUDES    = -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -I../include
+
+lib.a: $(LIBFILES)
+       ar rcs lib.a $(LIBFILES)
+
+all: $(TARGET)
+
+clean:
+       rm -f lib.a
+       rm -f $(LIBFILES)
+
diff --git a/lib/configtable.c b/lib/configtable.c
new file mode 100644 (file)
index 0000000..edf2ed7
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * read some platform configuration tables
+ */
+#include <efi.h>
+#include <efilib.h>
+
+#include <guid.h>
+#include <configtable.h>
+
+void *
+configtable_get_table(EFI_GUID *guid)
+{
+       unsigned int i;
+
+       for (i = 0; i < ST->NumberOfTableEntries; i++) {
+               EFI_CONFIGURATION_TABLE *CT = &ST->ConfigurationTable[i];
+
+               if (CompareGuid(guid, &CT->VendorGuid) == 0) {
+                       return CT->VendorTable;
+               }
+       }
+       return NULL;
+}
+
+EFI_IMAGE_EXECUTION_INFO_TABLE *
+configtable_get_image_table(void)
+{
+       return configtable_get_table(&SIG_DB);
+}
+
+EFI_IMAGE_EXECUTION_INFO *
+configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
+{
+       EFI_IMAGE_EXECUTION_INFO_TABLE *t = configtable_get_image_table();
+
+       if (!t)
+               return NULL;
+
+       int entries = t->NumberOfImages;
+       EFI_IMAGE_EXECUTION_INFO *e = t->InformationInfo;
+
+       int i;
+       for (i = 0; i < entries; i++) {
+#ifdef DEBUG_CONFIG
+               Print(L"InfoSize = %d  Action = %d\n", e->InfoSize, e->Action);
+
+               /* print what we have for debugging */
+               UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+               d += 16;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+               d += 16;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+               d += 16;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+               d += 16;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+               d += 16;
+               Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+                     d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
+#endif
+               CHAR16 *name = (CHAR16 *)(e->Data);
+               int skip = 0;
+
+               /* There's a bug in a lot of EFI platforms and they forget to
+                * put the name here.  The only real way of detecting it is to
+                * look for either a UC16 NULL or ASCII as UC16 */
+               if (name[0] == '\0' || (e->Data[1] == 0 && e->Data[3] == 0)) {
+                       skip = StrSize(name);
+#ifdef DEBUG_CONFIG
+                       Print(L"FOUND NAME %s (%d)\n", name, skip);
+#endif
+               }
+               EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)(e->Data + skip), *dpn = dp;
+               if (dp->Type == 0 || dp->Type > 6 || dp->SubType == 0
+                   || ((unsigned)((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
+                       /* Parse error, table corrupt, bail */
+                       Print(L"Image Execution Information table corrupt\n");
+                       break;
+               }
+
+               UINTN Size;
+               DevicePathInstance(&dpn, &Size);
+#ifdef DEBUG_CONFIG
+               Print(L"Path: %s\n", DevicePathToStr(dp));
+               Print(L"Device Path Size %d\n", Size);
+#endif
+               if (Size > e->InfoSize) {
+                       /* parse error; the platform obviously has a 
+                        * corrupted image table; bail */
+                       Print(L"Image Execution Information table corrupt\n");
+                       break;
+               }
+               
+               if (CompareMem(dp, (void *)DevicePath, Size) == 0) {
+#ifdef DEBUG_CONFIG
+                       Print(L"***FOUND\n");
+                       console_get_keystroke();
+#endif
+                       return e;
+               }
+               e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
+       }
+
+#ifdef DEBUG_CONFIG
+       Print(L"***NOT FOUND\n");
+       console_get_keystroke();
+#endif
+
+       return NULL;
+}
+
+int
+configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath)
+{
+       EFI_IMAGE_EXECUTION_INFO *e = configtable_find_image(DevicePath);
+
+       /* Image may not be in DB if it gets executed successfully If it is,
+        * and EFI_IMAGE_EXECUTION_INITIALIZED is not set, then the image
+        * isn't authenticated.  If there's no signature, usually
+        * EFI_IMAGE_EXECUTION_AUTH_UNTESTED is set, if the hash is in dbx,
+        * EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND is returned, and if the key is
+        * in dbx, EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED is returned*/
+
+       if (e && (e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND
+                 || e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED)) {
+               /* this means the images signing key is in dbx */
+#ifdef DEBUG_CONFIG
+               Print(L"SIGNATURE IS IN DBX, FORBIDDING EXECUTION\n");
+#endif
+               return 1;
+       }
+
+       return 0;
+}
diff --git a/lib/console.c b/lib/console.c
new file mode 100644 (file)
index 0000000..3fee403
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ * Copyright 2013 Red Hat Inc. <pjones@redhat.com>
+ *
+ * see COPYING file
+ */
+#include <efi.h>
+#include <efilib.h>
+
+#include <console.h>
+#include <variables.h>
+#include <errors.h>
+
+static EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+
+static int min(int a, int b)
+{
+       if (a < b)
+               return a;
+       return b;
+}
+
+static int
+count_lines(CHAR16 *str_arr[])
+{
+       int i = 0;
+
+       while (str_arr[i])
+               i++;
+       return i;
+}
+
+static void
+SetMem16(CHAR16 *dst, UINT32 n, CHAR16 c)
+{
+       unsigned int i;
+
+       for (i = 0; i < n/2; i++) {
+               dst[i] = c;
+       }
+}
+
+EFI_STATUS
+console_get_keystroke(EFI_INPUT_KEY *key)
+{
+       UINTN EventIndex;
+       EFI_STATUS status;
+
+       do {
+               uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &EventIndex);
+               status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, key);
+       } while (status == EFI_NOT_READY);
+
+       return status;
+}
+
+void
+console_print_box_at(CHAR16 *str_arr[], int highlight,
+                    int start_col, int start_row,
+                    int size_cols, int size_rows,
+                    int offset, int lines)
+{
+       int i;
+       SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+       UINTN rows, cols;
+       CHAR16 *Line;
+
+       if (lines == 0)
+               return;
+
+       uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
+
+       /* last row on screen is unusable without scrolling, so ignore it */
+       rows--;
+
+       if (size_rows < 0)
+               size_rows = rows + size_rows + 1;
+       if (size_cols < 0)
+               size_cols = cols + size_cols + 1;
+
+       if (start_col < 0)
+               start_col = (cols + start_col + 2)/2;
+       if (start_row < 0)
+               start_row = (rows + start_row + 2)/2;
+       if (start_col < 0)
+               start_col = 0;
+       if (start_row < 0)
+               start_row = 0;
+
+       if (start_col > (int)cols || start_row > (int)rows) {
+               Print(L"Starting Position (%d,%d) is off screen\n",
+                     start_col, start_row);
+               return;
+       }
+       if (size_cols + start_col > (int)cols)
+               size_cols = cols - start_col;
+       if (size_rows + start_row > (int)rows)
+               size_rows = rows - start_row;
+
+       if (lines > size_rows - 2)
+               lines = size_rows - 2;
+
+       Line = AllocatePool((size_cols+1)*sizeof(CHAR16));
+       if (!Line) {
+               Print(L"Failed Allocation\n");
+               return;
+       }
+
+       SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
+
+       Line[0] = BOXDRAW_DOWN_RIGHT;
+       Line[size_cols - 1] = BOXDRAW_DOWN_LEFT;
+       Line[size_cols] = L'\0';
+       uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, start_row);
+       uefi_call_wrapper(co->OutputString, 2, co, Line);
+
+       int start;
+       if (offset == 0)
+               /* middle */
+               start = (size_rows - lines)/2 + start_row + offset;
+       else if (offset < 0)
+               /* from bottom */
+               start = start_row + size_rows - lines + offset - 1;
+       else
+               /* from top */
+               start = start_row + offset;
+
+       for (i = start_row + 1; i < size_rows + start_row - 1; i++) {
+               int line = i - start;
+
+               SetMem16 (Line, size_cols*2, L' ');
+               Line[0] = BOXDRAW_VERTICAL;
+               Line[size_cols - 1] = BOXDRAW_VERTICAL;
+               Line[size_cols] = L'\0';
+               if (line >= 0 && line < lines) {
+                       CHAR16 *s = str_arr[line];
+                       int len = StrLen(s);
+                       int col = (size_cols - 2 - len)/2;
+
+                       if (col < 0)
+                               col = 0;
+
+                       CopyMem(Line + col + 1, s, min(len, size_cols - 2)*2);
+               }
+               if (line >= 0 && line == highlight)
+                       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
+               uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
+               uefi_call_wrapper(co->OutputString, 2, co, Line);
+               if (line >= 0 && line == highlight)
+                       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+
+       }
+       SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
+       Line[0] = BOXDRAW_UP_RIGHT;
+       Line[size_cols - 1] = BOXDRAW_UP_LEFT;
+       Line[size_cols] = L'\0';
+       uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
+       uefi_call_wrapper(co->OutputString, 2, co, Line);
+
+       FreePool (Line);
+
+}
+
+void
+console_print_box(CHAR16 *str_arr[], int highlight)
+{
+       SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
+       SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+       EFI_INPUT_KEY key;
+
+       CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
+       uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
+       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+
+       console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0,
+                            count_lines(str_arr));
+
+       console_get_keystroke(&key);
+
+       uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
+       uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
+       uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
+}
+
+int
+console_select(CHAR16 *title[], CHAR16* selectors[], unsigned int start)
+{
+       SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
+       SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+       EFI_INPUT_KEY k;
+       EFI_STATUS status;
+       int selector;
+       unsigned int selector_lines = count_lines(selectors);
+       int selector_max_cols = 0;
+       unsigned int i;
+       int offs_col, offs_row, size_cols, size_rows, lines;
+       unsigned int selector_offset;
+       UINTN cols, rows;
+
+       uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
+
+       for (i = 0; i < selector_lines; i++) {
+               int len = StrLen(selectors[i]);
+
+               if (len > selector_max_cols)
+                       selector_max_cols = len;
+       }
+
+       if (start < 0)
+               start = 0;
+       if (start >= selector_lines)
+               start = selector_lines - 1;
+
+       offs_col = - selector_max_cols - 4;
+       size_cols = selector_max_cols + 4;
+
+       if (selector_lines > rows - 10) {
+               int title_lines = count_lines(title);
+               offs_row =  title_lines + 1;
+               size_rows = rows - 3 - title_lines;
+               lines = size_rows - 2;
+       } else {
+               offs_row = - selector_lines - 4;
+               size_rows = selector_lines + 2;
+               lines = selector_lines;
+       }
+
+       if (start > (unsigned)lines) {
+               selector = lines;
+               selector_offset = start - lines;
+       } else {
+               selector = start;
+               selector_offset = 0;
+       }
+
+       CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
+       uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
+       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+
+       console_print_box_at(title, -1, 0, 0, -1, -1, 1, count_lines(title));
+
+       console_print_box_at(selectors, selector, offs_col, offs_row,
+                            size_cols, size_rows, 0, lines);
+
+       do {
+               status = console_get_keystroke(&k);
+               if (EFI_ERROR (status)) {
+                       Print(L"Failed to read the keystroke: %r", status);
+                       selector = -1;
+                       break;
+               }
+
+               if (k.ScanCode == SCAN_ESC) {
+                       selector = -1;
+                       break;
+               }
+
+               if (k.ScanCode == SCAN_UP) {
+                       if (selector > 0)
+                               selector--;
+                       else if (selector_offset > 0)
+                               selector_offset--;
+               } else if (k.ScanCode == SCAN_DOWN) {
+                       if (selector < lines - 1)
+                               selector++;
+                       else if (selector_offset < (selector_lines - lines))
+                               selector_offset++;
+               }
+
+               console_print_box_at(&selectors[selector_offset], selector,
+                                    offs_col, offs_row,
+                                    size_cols, size_rows, 0, lines);
+       } while (!(k.ScanCode == SCAN_NULL
+                  && k.UnicodeChar == CHAR_CARRIAGE_RETURN));
+
+       uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
+       uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
+       uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
+
+       if (selector < 0)
+               /* ESC pressed */
+               return selector;
+       return selector + selector_offset;
+}
+
+
+int
+console_yes_no(CHAR16 *str_arr[])
+{
+       return console_select(str_arr, (CHAR16 *[]){ L"No", L"Yes", NULL }, 0);
+}
+
+void
+console_alertbox(CHAR16 **title)
+{
+       console_select(title, (CHAR16 *[]){ L"OK", 0 }, 0);
+}
+
+void
+console_errorbox(CHAR16 *err)
+{
+       CHAR16 **err_arr = (CHAR16 *[]){
+               L"ERROR",
+               L"",
+               0,
+               0,
+       };
+
+       err_arr[2] = err;
+
+       console_alertbox(err_arr);
+}
+
+void
+console_notify(CHAR16 *string)
+{
+       CHAR16 **str_arr = (CHAR16 *[]){
+               0,
+               0,
+       };
+
+       str_arr[0] = string;
+
+       console_alertbox(str_arr);
+}
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+/* Copy of gnu-efi-3.0 with the added secure boot strings */
+static struct {
+    EFI_STATUS      Code;
+    WCHAR          *Desc;
+} error_table[] = {
+       {  EFI_SUCCESS,                L"Success"},
+       {  EFI_LOAD_ERROR,             L"Load Error"},
+       {  EFI_INVALID_PARAMETER,      L"Invalid Parameter"},
+       {  EFI_UNSUPPORTED,            L"Unsupported"},
+       {  EFI_BAD_BUFFER_SIZE,        L"Bad Buffer Size"},
+       {  EFI_BUFFER_TOO_SMALL,       L"Buffer Too Small"},
+       {  EFI_NOT_READY,              L"Not Ready"},
+       {  EFI_DEVICE_ERROR,           L"Device Error"},
+       {  EFI_WRITE_PROTECTED,        L"Write Protected"},
+       {  EFI_OUT_OF_RESOURCES,       L"Out of Resources"},
+       {  EFI_VOLUME_CORRUPTED,       L"Volume Corrupt"},
+       {  EFI_VOLUME_FULL,            L"Volume Full"},
+       {  EFI_NO_MEDIA,               L"No Media"},
+       {  EFI_MEDIA_CHANGED,          L"Media changed"},
+       {  EFI_NOT_FOUND,              L"Not Found"},
+       {  EFI_ACCESS_DENIED,          L"Access Denied"},
+       {  EFI_NO_RESPONSE,            L"No Response"},
+       {  EFI_NO_MAPPING,             L"No mapping"},
+       {  EFI_TIMEOUT,                L"Time out"},
+       {  EFI_NOT_STARTED,            L"Not started"},
+       {  EFI_ALREADY_STARTED,        L"Already started"},
+       {  EFI_ABORTED,                L"Aborted"},
+       {  EFI_ICMP_ERROR,             L"ICMP Error"},
+       {  EFI_TFTP_ERROR,             L"TFTP Error"},
+       {  EFI_PROTOCOL_ERROR,         L"Protocol Error"},
+       {  EFI_INCOMPATIBLE_VERSION,   L"Incompatible Version"},
+       {  EFI_SECURITY_VIOLATION,     L"Security Violation"},
+
+       // warnings
+       {  EFI_WARN_UNKOWN_GLYPH,      L"Warning Unknown Glyph"},
+       {  EFI_WARN_DELETE_FAILURE,    L"Warning Delete Failure"},
+       {  EFI_WARN_WRITE_FAILURE,     L"Warning Write Failure"},
+       {  EFI_WARN_BUFFER_TOO_SMALL,  L"Warning Buffer Too Small"},
+       {  0, NULL}
+} ;
+
+
+static CHAR16 *
+err_string (
+    IN EFI_STATUS       Status
+    )
+{
+       UINTN           Index;
+
+       for (Index = 0; error_table[Index].Desc; Index +=1) {
+               if (error_table[Index].Code == Status) {
+                       return error_table[Index].Desc;
+               }
+       }
+
+       return L"";
+}
+       
+
+void
+console_error(CHAR16 *err, EFI_STATUS status)
+{
+       CHAR16 **err_arr = (CHAR16 *[]){
+               L"ERROR",
+               L"",
+               0,
+               0,
+       };
+       CHAR16 str[512];
+
+       SPrint(str, sizeof(str), L"%s: (%d) %s", err, status, err_string(status));
+
+       err_arr[2] = str;
+
+       console_alertbox(err_arr);
+}
+
+void
+console_reset(void)
+{
+       SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+
+       uefi_call_wrapper(co->Reset, 2, co, TRUE);
+       /* set mode 0 - required to be 80x25 */
+       uefi_call_wrapper(co->SetMode, 2, co, 0);
+       uefi_call_wrapper(co->ClearScreen, 1, co);
+}
+
+UINT8 verbose;
+
+VOID
+setup_verbosity(VOID)
+{
+       EFI_STATUS status;
+       EFI_GUID guid = SHIM_LOCK_GUID;
+       UINT8 verbose_check;
+       UINTN verbose_check_size;
+
+       verbose_check_size = 1;
+       status = get_variable(L"SHIM_VERBOSE", (void *)&verbose_check,
+                                 &verbose_check_size, guid);
+       verbose = 0;
+       if (!EFI_ERROR(status))
+               verbose = verbose_check;
+}
+
+VOID setup_console (int text)
+{
+       EFI_STATUS status;
+       EFI_GUID console_control_guid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+       EFI_CONSOLE_CONTROL_PROTOCOL *concon;
+       static EFI_CONSOLE_CONTROL_SCREEN_MODE mode =
+                                       EfiConsoleControlScreenGraphics;
+       EFI_CONSOLE_CONTROL_SCREEN_MODE new_mode;
+
+       status = LibLocateProtocol(&console_control_guid, (VOID **)&concon);
+       if (status != EFI_SUCCESS)
+               return;
+
+       if (text) {
+               new_mode = EfiConsoleControlScreenText;
+
+               status = uefi_call_wrapper(concon->GetMode, 4, concon, &mode,
+                                               0, 0);
+               /* If that didn't work, assume it's graphics */
+               if (status != EFI_SUCCESS)
+                       mode = EfiConsoleControlScreenGraphics;
+       } else {
+               new_mode = mode;
+       }
+
+       uefi_call_wrapper(concon->SetMode, 2, concon, new_mode);
+}
diff --git a/lib/execute.c b/lib/execute.c
new file mode 100644 (file)
index 0000000..89328c6
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * --
+ *
+ * generate_path is a cut and paste from
+ *  
+ *   git://github.com/mjg59/shim.git
+ *
+ * Code Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (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 <efi.h>
+#include <efilib.h>
+
+#include <guid.h>
+#include <execute.h>
+
+EFI_STATUS
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16 **PathName)
+{
+       unsigned int pathlen;
+       EFI_STATUS efi_status = EFI_SUCCESS;
+       CHAR16 *devpathstr = DevicePathToStr(li->FilePath),
+               *found = NULL;
+       unsigned int i;
+
+       for (i = 0; i < StrLen(devpathstr); i++) {
+               if (devpathstr[i] == '/')
+                       devpathstr[i] = '\\';
+               if (devpathstr[i] == '\\')
+                       found = &devpathstr[i];
+       }
+       if (!found) {
+               pathlen = 0;
+       } else {
+               while (*(found - 1) == '\\')
+                       --found;
+               *found = '\0';
+               pathlen = StrLen(devpathstr);
+       }
+
+       if (name[0] != '\\')
+               pathlen++;
+
+       *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16));
+
+       if (!*PathName) {
+               Print(L"Failed to allocate path buffer\n");
+               efi_status = EFI_OUT_OF_RESOURCES;
+               goto error;
+       }
+
+       StrCpy(*PathName, devpathstr);
+
+       if (name[0] != '\\')
+               StrCat(*PathName, L"\\");
+       StrCat(*PathName, name);
+       
+       *path = FileDevicePath(li->DeviceHandle, *PathName);
+
+error:
+       FreePool(devpathstr);
+
+       return efi_status;
+}
+
+EFI_STATUS
+execute(EFI_HANDLE image, CHAR16 *name)
+{
+       EFI_STATUS status;
+       EFI_HANDLE h;
+       EFI_LOADED_IMAGE *li;
+       EFI_DEVICE_PATH *devpath;
+       CHAR16 *PathName;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
+                                  &IMAGE_PROTOCOL, (void **)&li);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       
+       status = generate_path(name, li, &devpath, &PathName);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
+                                  devpath, NULL, 0, &h);
+       if (status != EFI_SUCCESS)
+               goto out;
+       
+       status = uefi_call_wrapper(BS->StartImage, 3, h, NULL, NULL);
+       uefi_call_wrapper(BS->UnloadImage, 1, h);
+
+ out:
+       FreePool(PathName);
+       FreePool(devpath);
+       return status;
+}
diff --git a/lib/guid.c b/lib/guid.c
new file mode 100644 (file)
index 0000000..5f5a03f
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ */
+
+#include <guid.h>
+
+/* all the necessary guids */
+EFI_GUID GV_GUID = EFI_GLOBAL_VARIABLE;
+EFI_GUID SIG_DB = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 0x67, 0x65, 0x6f }};
+
+EFI_GUID X509_GUID =   { 0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} };
+EFI_GUID RSA2048_GUID = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} };
+EFI_GUID PKCS7_GUID = { 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} };
+EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL;
+EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL;
+EFI_GUID EFI_CERT_SHA1_GUID = { 0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd }};
+EFI_GUID EFI_CERT_SHA256_GUID  = { 0xc1c41626, 0x504c, 0x4092, { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 } };
+EFI_GUID MOK_OWNER = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } };
+EFI_GUID SECURITY2_PROTOCOL_GUID = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
diff --git a/lib/security_policy.c b/lib/security_policy.c
new file mode 100644 (file)
index 0000000..9af3a10
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * Install and remove a platform security2 override policy
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <guid.h>
+#include <variables.h>
+#include <simple_file.h>
+#include <errors.h>
+
+#if defined(OVERRIDE_SECURITY_POLICY)
+#include <security_policy.h>
+
+/*
+ * See the UEFI Platform Initialization manual (Vol2: DXE) for this
+ */
+struct _EFI_SECURITY2_PROTOCOL;
+struct _EFI_SECURITY_PROTOCOL;
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
+typedef EFI_DEVICE_PATH EFI_DEVICE_PATH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
+                       const EFI_SECURITY_PROTOCOL *This,
+                       UINT32 AuthenticationStatus,
+                       const EFI_DEVICE_PATH_PROTOCOL *File
+                                                                    );
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+                       const EFI_SECURITY2_PROTOCOL *This,
+                       const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+                       VOID *FileBuffer,
+                       UINTN FileSize,
+                       BOOLEAN BootPolicy
+                                                                    );
+
+struct _EFI_SECURITY2_PROTOCOL {
+       EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+struct _EFI_SECURITY_PROTOCOL {
+       EFI_SECURITY_FILE_AUTHENTICATION_STATE  FileAuthenticationState;
+};
+
+
+static UINT8 *security_policy_esl = NULL;
+static UINTN security_policy_esl_len;
+static SecurityHook extra_check = NULL;
+
+static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
+static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
+
+static EFI_STATUS thunk_security_policy_authentication(
+       const EFI_SECURITY_PROTOCOL *This,
+       UINT32 AuthenticationStatus,
+       const EFI_DEVICE_PATH_PROTOCOL *DevicePath
+                                                      ) 
+__attribute__((unused));
+
+static EFI_STATUS thunk_security2_policy_authentication(
+       const EFI_SECURITY2_PROTOCOL *This,
+       const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+       VOID *FileBuffer,
+       UINTN FileSize,
+       BOOLEAN BootPolicy
+                                                      ) 
+__attribute__((unused));
+
+static __attribute__((used)) EFI_STATUS
+security2_policy_authentication (
+       const EFI_SECURITY2_PROTOCOL *This,
+       const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+       VOID *FileBuffer,
+       UINTN FileSize,
+       BOOLEAN BootPolicy
+                                )
+{
+       EFI_STATUS status, auth;
+
+       /* Chain original security policy */
+
+       status = uefi_call_wrapper(es2fa, 5, This, DevicePath, FileBuffer,
+                                  FileSize, BootPolicy);
+
+       /* if OK, don't bother with MOK check */
+       if (status == EFI_SUCCESS)
+               return status;
+
+       if (extra_check)
+               auth = extra_check(FileBuffer, FileSize);
+       else
+               return EFI_SECURITY_VIOLATION;
+
+       if (auth == EFI_SECURITY_VIOLATION || auth == EFI_ACCESS_DENIED)
+               /* return previous status, which is the correct one
+                * for the platform: may be either EFI_ACCESS_DENIED
+                * or EFI_SECURITY_VIOLATION */
+               return status;
+
+       return auth;
+}
+
+static __attribute__((used)) EFI_STATUS
+security_policy_authentication (
+       const EFI_SECURITY_PROTOCOL *This,
+       UINT32 AuthenticationStatus,
+       const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst
+       )
+{
+       EFI_STATUS status, fail_status;
+       EFI_DEVICE_PATH *DevPath 
+               = DuplicateDevicePath((EFI_DEVICE_PATH *)DevicePathConst),
+               *OrigDevPath = DevPath;
+       EFI_HANDLE h;
+       EFI_FILE *f;
+       VOID *FileBuffer;
+       UINTN FileSize;
+       CHAR16* DevPathStr;
+
+       /* Chain original security policy */
+       status = uefi_call_wrapper(esfas, 3, This, AuthenticationStatus,
+                                  DevicePathConst);
+
+       /* if OK avoid checking MOK: It's a bit expensive to
+        * read the whole file in again (esfas already did this) */
+       if (status == EFI_SUCCESS)
+               goto out;
+
+       /* capture failure status: may be either EFI_ACCESS_DENIED or
+        * EFI_SECURITY_VIOLATION */
+       fail_status = status;
+
+       status = uefi_call_wrapper(BS->LocateDevicePath, 3,
+                                  &SIMPLE_FS_PROTOCOL, &DevPath, &h);
+       if (status != EFI_SUCCESS)
+               goto out;
+
+       DevPathStr = DevicePathToStr(DevPath);
+
+       status = simple_file_open_by_handle(h, DevPathStr, &f,
+                                           EFI_FILE_MODE_READ);
+       FreePool(DevPathStr);
+       if (status != EFI_SUCCESS)
+               goto out;
+
+       status = simple_file_read_all(f, &FileSize, &FileBuffer);
+       simple_file_close(f);
+       if (status != EFI_SUCCESS)
+               goto out;
+
+       if (extra_check)
+               status = extra_check(FileBuffer, FileSize);
+       else
+               status = EFI_SECURITY_VIOLATION;
+       FreePool(FileBuffer);
+
+       if (status == EFI_ACCESS_DENIED || status == EFI_SECURITY_VIOLATION)
+               /* return what the platform originally said */
+               status = fail_status;
+ out:
+       FreePool(OrigDevPath);
+       return status;
+}
+
+
+/* Nasty: ELF and EFI have different calling conventions.  Here is the map for
+ * calling ELF -> EFI
+ *
+ *   1) rdi -> rcx (32 saved)
+ *   2) rsi -> rdx (32 saved)
+ *   3) rdx -> r8 ( 32 saved)
+ *   4) rcx -> r9 (32 saved)
+ *   5) r8 -> 32(%rsp) (48 saved)
+ *   6) r9 -> 40(%rsp) (48 saved)
+ *   7) pad+0(%rsp) -> 48(%rsp) (64 saved)
+ *   8) pad+8(%rsp) -> 56(%rsp) (64 saved)
+ *   9) pad+16(%rsp) -> 64(%rsp) (80 saved)
+ *  10) pad+24(%rsp) -> 72(%rsp) (80 saved)
+ *  11) pad+32(%rsp) -> 80(%rsp) (96 saved)
+
+ *
+ * So for a five argument callback, the map is ignore the first two arguments
+ * and then map (EFI -> ELF) assuming pad = 0.
+ *
+ * ARG4  -> ARG1
+ * ARG3  -> ARG2
+ * ARG5  -> ARG3
+ * ARG6  -> ARG4
+ * ARG11 -> ARG5
+ *
+ * Calling conventions also differ over volatile and preserved registers in
+ * MS: RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered nonvolatile .
+ * In ELF: Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling
+ * function and the called function is required to preserve their values.
+ *
+ * This means when accepting a function callback from MS -> ELF, we have to do
+ * separate preservation on %rdi, %rsi before swizzling the arguments and
+ * handing off to the ELF function.
+ */
+
+asm (
+".type security2_policy_authentication,@function\n"
+"thunk_security2_policy_authentication:\n\t"
+       "mov    0x28(%rsp), %r10        # ARG5\n\t"
+       "push   %rdi\n\t"
+       "push   %rsi\n\t"
+       "mov    %r10, %rdi\n\t"
+       "subq   $8, %rsp        # space for storing stack pad\n\t"
+       "mov    $0x08, %rax\n\t"
+       "mov    $0x10, %r10\n\t"
+       "and    %rsp, %rax\n\t"
+       "cmovnz %rax, %r11\n\t"
+       "cmovz  %r10, %r11\n\t"
+       "subq   %r11, %rsp\n\t"
+       "addq   $8, %r11\n\t"
+       "mov    %r11, (%rsp)\n\t"
+"# five argument swizzle\n\t"
+       "mov    %rdi, %r10\n\t"
+       "mov    %rcx, %rdi\n\t"
+       "mov    %rdx, %rsi\n\t"
+       "mov    %r8, %rdx\n\t"
+       "mov    %r9, %rcx\n\t"
+       "mov    %r10, %r8\n\t"
+       "callq  security2_policy_authentication@PLT\n\t"
+       "mov    (%rsp), %r11\n\t"
+       "addq   %r11, %rsp\n\t"
+       "pop    %rsi\n\t"
+       "pop    %rdi\n\t"
+       "ret\n"
+);
+
+asm (
+".type security_policy_authentication,@function\n"
+"thunk_security_policy_authentication:\n\t"
+       "push   %rdi\n\t"
+       "push   %rsi\n\t"
+       "subq   $8, %rsp        # space for storing stack pad\n\t"
+       "mov    $0x08, %rax\n\t"
+       "mov    $0x10, %r10\n\t"
+       "and    %rsp, %rax\n\t"
+       "cmovnz %rax, %r11\n\t"
+       "cmovz  %r10, %r11\n\t"
+       "subq   %r11, %rsp\n\t"
+       "addq   $8, %r11\n\t"
+       "mov    %r11, (%rsp)\n\t"
+"# three argument swizzle\n\t"
+       "mov    %rcx, %rdi\n\t"
+       "mov    %rdx, %rsi\n\t"
+       "mov    %r8, %rdx\n\t"
+       "callq  security_policy_authentication@PLT\n\t"
+       "mov    (%rsp), %r11\n\t"
+       "addq   %r11, %rsp\n\t"
+       "pop    %rsi\n\t"
+       "pop    %rdi\n\t"
+       "ret\n"
+);
+
+EFI_STATUS
+security_policy_install(SecurityHook hook)
+{
+       EFI_SECURITY_PROTOCOL *security_protocol;
+       EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
+       EFI_STATUS status;
+
+       if (esfas)
+               /* Already Installed */
+               return EFI_ALREADY_STARTED;
+
+       /* Don't bother with status here.  The call is allowed
+        * to fail, since SECURITY2 was introduced in PI 1.2.1
+        * If it fails, use security2_protocol == NULL as indicator */
+       uefi_call_wrapper(BS->LocateProtocol, 3,
+                         &SECURITY2_PROTOCOL_GUID, NULL,
+                         &security2_protocol);
+
+       status = uefi_call_wrapper(BS->LocateProtocol, 3,
+                                  &SECURITY_PROTOCOL_GUID, NULL,
+                                  &security_protocol);
+       if (status != EFI_SUCCESS)
+               /* This one is mandatory, so there's a serious problem */
+               return status;
+
+       if (security2_protocol) {
+               es2fa = security2_protocol->FileAuthentication;
+               security2_protocol->FileAuthentication = 
+                       thunk_security2_policy_authentication;
+       }
+
+       esfas = security_protocol->FileAuthenticationState;
+       security_protocol->FileAuthenticationState =
+               thunk_security_policy_authentication;
+
+       if (hook)
+               extra_check = hook;
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+security_policy_uninstall(void)
+{
+       EFI_STATUS status;
+
+       if (esfas) {
+               EFI_SECURITY_PROTOCOL *security_protocol;
+
+               status = uefi_call_wrapper(BS->LocateProtocol, 3,
+                                          &SECURITY_PROTOCOL_GUID, NULL,
+                                          &security_protocol);
+
+               if (status != EFI_SUCCESS)
+                       return status;
+
+               security_protocol->FileAuthenticationState = esfas;
+               esfas = NULL;
+       } else {
+               /* nothing installed */
+               return EFI_NOT_STARTED;
+       }
+
+       if (es2fa) {
+               EFI_SECURITY2_PROTOCOL *security2_protocol;
+
+               status = uefi_call_wrapper(BS->LocateProtocol, 3,
+                                          &SECURITY2_PROTOCOL_GUID, NULL,
+                                          &security2_protocol);
+
+               if (status != EFI_SUCCESS)
+                       return status;
+
+               security2_protocol->FileAuthentication = es2fa;
+               es2fa = NULL;
+       }
+
+       if (extra_check)
+               extra_check = NULL;
+
+       return EFI_SUCCESS;
+}
+
+void
+security_protocol_set_hashes(unsigned char *esl, int len)
+{
+       security_policy_esl = esl;
+       security_policy_esl_len = len;
+}
+#endif /* OVERRIDE_SECURITY_POLICY */
diff --git a/lib/shell.c b/lib/shell.c
new file mode 100644 (file)
index 0000000..afd3952
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * misc shell helper functions
+ */
+#include <efi.h>
+#include <efilib.h>
+
+#include <shell.h>
+
+EFI_STATUS
+argsplit(EFI_HANDLE image, int *argc, CHAR16*** ARGV)
+{
+       unsigned int i, count = 1;
+       EFI_STATUS status;
+       EFI_LOADED_IMAGE *info;
+       CHAR16 *start;
+
+       *argc = 0;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info);
+       if (EFI_ERROR(status)) {
+               Print(L"Failed to get arguments\n");
+               return status;
+       }
+
+       for (i = 0; i < info->LoadOptionsSize; i += 2) {
+               CHAR16 *c = (CHAR16 *)(info->LoadOptions + i);
+               if (*c == L' ' && *(c+1) != '\0') {
+                       (*argc)++;
+               }
+       }
+
+       (*argc)++;              /* we counted spaces, so add one for initial */
+
+       *ARGV = AllocatePool(*argc * sizeof(**ARGV));
+       if (!*ARGV) {
+               return EFI_OUT_OF_RESOURCES;
+       }
+       (*ARGV)[0] = (CHAR16 *)info->LoadOptions;
+       for (i = 0; i < info->LoadOptionsSize; i += 2) {
+               CHAR16 *c = (CHAR16 *)(info->LoadOptions + i);
+               if (*c == L' ') {
+                       *c = L'\0';
+                       if (*(c + 1) == '\0')
+                               /* strip trailing space */
+                               break;
+                       start = c + 1;
+                       (*ARGV)[count++] = start;
+               }
+       }
+
+       return EFI_SUCCESS;
+}
+
diff --git a/lib/simple_file.c b/lib/simple_file.c
new file mode 100644 (file)
index 0000000..d345d87
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <console.h>
+#include <simple_file.h>
+#include <efiauthenticated.h>
+#include <execute.h>           /* for generate_path() */
+
+static EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static EFI_GUID FILE_INFO = EFI_FILE_INFO_ID;
+static EFI_GUID FS_INFO = EFI_FILE_SYSTEM_INFO_ID;
+
+EFI_STATUS
+simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UINT64 mode)
+{
+       EFI_STATUS efi_status;
+       EFI_FILE_IO_INTERFACE *drive;
+       EFI_FILE *root;
+
+       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
+                                      &SIMPLE_FS_PROTOCOL, (void **)&drive);
+
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"Unable to find simple file protocol (%d)\n", efi_status);
+               goto error;
+       }
+
+       efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"Failed to open drive volume (%d)\n", efi_status);
+               goto error;
+       }
+
+       efi_status = uefi_call_wrapper(root->Open, 5, root, file, name,
+                                      mode, 0);
+
+ error:
+       return efi_status;
+}
+
+EFI_STATUS
+simple_file_open(EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode)
+{
+       EFI_STATUS efi_status;
+       EFI_HANDLE device;
+       EFI_LOADED_IMAGE *li;
+       EFI_DEVICE_PATH *loadpath = NULL;
+       CHAR16 *PathName = NULL;
+
+       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
+                                      &IMAGE_PROTOCOL, (void **)&li);
+
+       if (efi_status != EFI_SUCCESS)
+               return simple_file_open_by_handle(image, name, file, mode);
+
+       efi_status = generate_path(name, li, &loadpath, &PathName);
+
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"Unable to generate load path for %s\n", name);
+               return efi_status;
+       }
+
+       device = li->DeviceHandle;
+
+       efi_status = simple_file_open_by_handle(device, PathName, file, mode);
+
+       FreePool(PathName);
+       FreePool(loadpath);
+
+       return efi_status;
+}
+
+EFI_STATUS
+simple_dir_read_all_by_handle(EFI_HANDLE image, EFI_FILE *file, CHAR16* name, EFI_FILE_INFO **entries,
+                   int *count)
+{
+       EFI_STATUS status;
+       char buf[4096];
+       UINTN size = sizeof(buf);
+       EFI_FILE_INFO *fi = (void *)buf;
+       
+       status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
+                                  &size, fi);
+       if (status != EFI_SUCCESS) {
+               Print(L"Failed to get file info\n");
+               goto out;
+       }
+       if ((fi->Attribute & EFI_FILE_DIRECTORY) == 0) {
+               Print(L"Not a directory %s\n", name);
+               status = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+       size = 0;
+       *count = 0;
+       for (;;) {
+               UINTN len = sizeof(buf);
+               status = uefi_call_wrapper(file->Read, 3, file, &len, buf);
+               if (status != EFI_SUCCESS || len == 0)
+                       break;
+               (*count)++;
+               size += len;
+       }
+       uefi_call_wrapper(file->SetPosition, 2, file, 0);
+
+       char *ptr = AllocatePool(size);
+       *entries = (EFI_FILE_INFO *)ptr;
+       if (!*entries)
+               return EFI_OUT_OF_RESOURCES;
+       int i;
+       for (i = 0; i < *count; i++) {
+               UINTN len = size;
+               uefi_call_wrapper(file->Read, 3, file, &len, ptr);
+               ptr += len;
+               size -= len;
+       }
+       status = EFI_SUCCESS;
+ out:
+       simple_file_close(file);
+       if (status != EFI_SUCCESS && *entries) {
+               FreePool(*entries);
+               *entries = NULL;
+       }
+       return status;
+}
+
+EFI_STATUS
+simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **entries,
+                   int *count)
+{
+       EFI_FILE *file;
+       EFI_STATUS status;
+
+       status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ);
+       if (status != EFI_SUCCESS) {
+               Print(L"failed to open file %s: %d\n", name, status);
+               return status;
+       }
+
+       return simple_dir_read_all_by_handle(image, file, name, entries, count);
+}
+
+EFI_STATUS
+simple_file_read_all(EFI_FILE *file, UINTN *size, void **buffer)
+{
+       EFI_STATUS efi_status;
+       EFI_FILE_INFO *fi;
+       char buf[1024];
+
+       *size = sizeof(buf);
+       fi = (void *)buf;
+       
+
+       efi_status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
+                                      size, fi);
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"Failed to get file info\n");
+               return efi_status;
+       }
+
+       *size = fi->FileSize;
+
+       *buffer = AllocatePool(*size);
+       if (!*buffer) {
+               Print(L"Failed to allocate buffer of size %d\n", *size);
+               return EFI_OUT_OF_RESOURCES;
+       }
+       efi_status = uefi_call_wrapper(file->Read, 3, file, size, *buffer);
+
+       return efi_status;
+}
+
+
+EFI_STATUS
+simple_file_write_all(EFI_FILE *file, UINTN size, void *buffer)
+{
+       EFI_STATUS efi_status;
+
+       efi_status = uefi_call_wrapper(file->Write, 3, file, &size, buffer);
+
+       return efi_status;
+}
+
+void
+simple_file_close(EFI_FILE *file)
+{
+       uefi_call_wrapper(file->Close, 1, file);
+}
+
+EFI_STATUS
+simple_volume_selector(CHAR16 **title, CHAR16 **selected, EFI_HANDLE *h)
+{
+       UINTN count, i;
+       EFI_HANDLE *vol_handles = NULL;
+       EFI_STATUS status;
+       CHAR16 **entries;
+       int val;
+
+       uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol,
+                         &SIMPLE_FS_PROTOCOL, NULL, &count, &vol_handles);
+
+       if (!count || !vol_handles)
+               return EFI_NOT_FOUND;
+
+       entries = AllocatePool(sizeof(CHAR16 *) * (count+1));
+       if (!entries)
+               return EFI_OUT_OF_RESOURCES;
+
+       for (i = 0; i < count; i++) {
+               char buf[4096];
+               UINTN size = sizeof(buf);
+               EFI_FILE_SYSTEM_INFO *fi = (void *)buf;
+               EFI_FILE *root;
+               CHAR16 *name;
+               EFI_FILE_IO_INTERFACE *drive;
+
+               status = uefi_call_wrapper(BS->HandleProtocol, 3,
+                                          vol_handles[i],
+                                          &SIMPLE_FS_PROTOCOL,
+                                          (void **)&drive);
+               if (status != EFI_SUCCESS || !drive)
+                       continue;
+
+               status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+               if (status != EFI_SUCCESS)
+                       continue;
+
+               status = uefi_call_wrapper(root->GetInfo, 4, root, &FS_INFO,
+                                          &size, fi);
+               if (status != EFI_SUCCESS)
+                       continue;
+
+               name = fi->VolumeLabel;
+               
+               if (!name || StrLen(name) == 0 || StrCmp(name, L" ") == 0) 
+                       name = DevicePathToStr(DevicePathFromHandle(vol_handles[i]));
+
+               entries[i] = AllocatePool((StrLen(name) + 2) * sizeof(CHAR16));
+               if (!entries[i])
+                       break;
+               StrCpy(entries[i], name);
+       }
+       entries[i] = NULL;
+
+       val = console_select(title, entries, 0);
+
+       if (val >= 0) {
+               *selected = AllocatePool((StrLen(entries[val]) + 1) * sizeof(CHAR16));
+               if (*selected) {
+                       StrCpy(*selected , entries[val]);
+               }
+               *h = vol_handles[val];
+       } else {
+               *selected = NULL;
+               *h = 0;
+       }
+
+       for (i = 0; i < count; i++) {
+               if (entries[i])
+                       FreePool(entries[i]);
+       }
+       FreePool(entries);
+       FreePool(vol_handles);
+
+       
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
+                 CHAR16 ***result, int *count, EFI_FILE_INFO **entries)
+{
+       EFI_STATUS status;
+       int tot, offs = StrLen(filter), i, c, filtercount = 1;
+       EFI_FILE_INFO *next;
+       void *ptr;
+       CHAR16 *newfilter = AllocatePool((StrLen(filter) + 1) * sizeof(CHAR16)),
+               **filterarr;
+
+       if (!newfilter)
+               return EFI_OUT_OF_RESOURCES;
+
+       /* just in case efi ever stops writeable strings */
+       StrCpy(newfilter, filter);
+
+       for (i = 0; i < offs; i++) {
+               if (filter[i] == '|')
+                       filtercount++;
+       }
+       filterarr = AllocatePool(filtercount * sizeof(void *));
+       if (!filterarr)
+               return EFI_OUT_OF_RESOURCES;
+       c = 0;
+       filterarr[c++] = newfilter;
+       for (i = 0; i < offs; i++) {
+               if (filter[i] == '|') {
+                       newfilter[i] = '\0';
+                       filterarr[c++] = &newfilter[i+1];
+               }
+       }
+
+       *count = 0;
+
+       status = simple_dir_read_all(image, name, entries, &tot);
+               
+       if (status != EFI_SUCCESS)
+               goto out;
+       ptr = next = *entries;
+
+       for (i = 0; i < tot; i++) {
+               int len = StrLen(next->FileName);
+
+               for (c = 0; c < filtercount; c++) {
+                       offs = StrLen(filterarr[c]);
+
+                       if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0
+                           || (next->Attribute & EFI_FILE_DIRECTORY)) {
+                               (*count)++;
+                               break;
+                       }
+               }
+               ptr += OFFSET_OF(EFI_FILE_INFO, FileName) + (len + 1)*sizeof(CHAR16);
+               next = ptr;
+       }
+       if (*count)
+               *result = AllocatePool(((*count) + 1) * sizeof(void *));
+       else
+               *result = AllocatePool(2 * sizeof(void *));
+
+       *count = 0;
+       ptr = next = *entries;
+
+       for (i = 0; i < tot; i++) {
+               int len = StrLen(next->FileName);
+
+               if (StrCmp(next->FileName, L".") == 0)
+                       /* ignore . directory */
+                       goto next;
+
+               if (next->Attribute & EFI_FILE_DIRECTORY) {
+                               (*result)[(*count)] = PoolPrint(L"%s/", next->FileName);
+                               if (!(*result)[(*count)]) {
+                                       Print(L"Failed to allocate buffer");
+                                       return EFI_OUT_OF_RESOURCES;
+                               }
+                               (*count)++;
+                               goto next;
+               }
+
+               for (c = 0; c < filtercount; c++) {
+                       offs = StrLen(filterarr[c]);
+
+                       if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0) {
+                               (*result)[(*count)] = StrDuplicate(next->FileName);
+                               if (!(*result)[(*count)]) {
+                                       Print(L"Failed to allocate buffer");
+                                       return EFI_OUT_OF_RESOURCES;
+                               }
+                               (*count)++;
+                       } else {
+                               continue;
+                       }
+                       break;
+               }
+
+       next:           
+               if (StrCmp(next->FileName, L"..") == 0) {
+                       /* place .. directory first */
+                       CHAR16 *tmp = (*result)[(*count) - 1];
+
+                       (*result)[(*count) - 1] = (*result)[0];
+                       (*result)[0] = tmp;
+               }
+
+               ptr += OFFSET_OF(EFI_FILE_INFO, FileName) + (len + 1)*sizeof(CHAR16);
+               next = ptr;
+       }
+       if (*count == 0) {
+               /* no entries at all ... can happen because top level dir has no . or .. */
+               (*result)[(*count)++] = L"./";
+       }
+       (*result)[*count] = NULL;
+       status = EFI_SUCCESS;
+
+ out:
+       if (status != EFI_SUCCESS) {
+               if (*entries)
+                       FreePool(*entries);
+               *entries = NULL;
+               if (*result)
+                       FreePool(*result);
+               *result = NULL;
+       }
+       return status;
+}
+
+static void
+free_entries(CHAR16 **entries, int count)
+{
+       int i;
+
+       for (i = 0; i<count; i++)
+               FreePool(entries[i]);
+}
+
+void
+simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
+                    CHAR16 *filter, CHAR16 **result)
+{
+       EFI_STATUS status;
+       CHAR16 **entries = NULL;
+       EFI_FILE_INFO *dmp;
+       int count, select, len;
+       CHAR16 *newname, *selected;
+
+       *result = NULL;
+       if (!name)
+               name = L"\\";
+       if (!filter)
+               filter = L"";
+       if (!*im) {
+               EFI_HANDLE h;
+               CHAR16 *volname;
+
+               simple_volume_selector(title, &volname, &h);
+               if (!volname)
+                       return;
+               FreePool(volname);
+               *im = h;
+       }
+
+       newname = AllocatePool((StrLen(name) + 1)*sizeof(CHAR16));
+       if (!newname)
+               return;
+
+       StrCpy(newname, name);
+       name = newname;
+
+ redo:
+       status = simple_dir_filter(*im, name, filter, &entries, &count, &dmp);
+
+       if (status != EFI_SUCCESS)
+               goto out_free_name;
+
+       select = console_select(title, entries, 0);
+       if (select < 0)
+               /* ESC key */
+               goto out_free;
+       selected = entries[select];
+       /* note that memory used by selected is valid until dmp is freed */
+       len = StrLen(selected);
+       if (selected[len - 1] == '/') {
+               CHAR16 *newname;
+
+               /* stay where we are */
+               if (StrCmp(selected, L"./") == 0) {
+                       free_entries(entries, count);
+                       FreePool(entries);
+                       entries = NULL;
+                       FreePool(dmp);
+                       goto redo;
+               } else if (StrCmp(selected, L"../") == 0) {
+                       int i;
+
+                       i = StrLen(name) - 1;
+
+
+                       for (i = StrLen(name); i > 0; --i) {
+                               if (name[i] == '\\')
+                                       break;
+                       }
+                       if (i == 0)
+                               i = 1;
+
+                       if (StrCmp(name, L"\\") != 0
+                           && StrCmp(&name[i], L"..") != 0) {
+                               name[i] = '\0';
+                               free_entries(entries, count);
+                               FreePool(entries);
+                               entries = NULL;
+                               FreePool(dmp);
+                               goto redo;
+                       }
+               }
+               newname = AllocatePool((StrLen(name) + len + 2)*sizeof(CHAR16));
+               if (!newname)
+                       goto out_free;
+               StrCpy(newname, name);
+                       
+               if (name[StrLen(name) - 1] != '\\')
+                       StrCat(newname, L"\\");
+               StrCat(newname, selected);
+               /* remove trailing / */
+               newname[StrLen(newname) - 1] = '\0';
+
+               free_entries(entries, count);
+               FreePool(entries);
+               entries = NULL;
+               FreePool(dmp);
+               FreePool(name);
+               name = newname;
+
+               goto redo;
+       }
+       *result = AllocatePool((StrLen(name) + len + 2)*sizeof(CHAR16));
+       if (*result) {
+               StrCpy(*result, name);
+               if (name[StrLen(name) - 1] != '\\')
+                       StrCat(*result, L"\\");
+               StrCat(*result, selected);
+       }
+
+ out_free:
+       FreePool(dmp);
+       if (entries) {
+               free_entries(entries, count);
+               FreePool(entries);
+       }
+ out_free_name:
+       FreePool(name);
+}
diff --git a/lib/variables.c b/lib/variables.c
new file mode 100644 (file)
index 0000000..59d7d05
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * Portions of this file are a direct cut and paste from Tianocore
+ * (http://tianocore.sf.net)
+ *
+ *  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+ *
+ * Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ * This program and the accompanying materials
+ * are licensed and made available under the terms and conditions of the BSD License
+ * which accompanies this distribution.  The full text of the license may be found 
+ * at
+ * http://opensource.org/licenses/bsd-license.php
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ * 
+ */
+#include <efi.h>
+#include <efilib.h>
+
+#include <efiauthenticated.h>
+
+#include <variables.h>
+#include <guid.h>
+#include <console.h>
+#include <errors.h>
+
+EFI_STATUS
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
+                   void **out, int *outlen)
+{
+       *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
+
+       *out = AllocateZeroPool(*outlen);
+       if (!*out)
+               return EFI_OUT_OF_RESOURCES;
+
+       EFI_SIGNATURE_LIST *sl = *out;
+
+       sl->SignatureHeaderSize = 0;
+       sl->SignatureType = *type;
+       sl->SignatureSize = cert_len + sizeof(EFI_GUID);
+       sl->SignatureListSize = *outlen;
+
+       EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST);
+
+       if (owner)
+               sd->SignatureOwner = *owner;
+
+       CopyMem(sd->SignatureData, cert, cert_len);
+
+       return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CreateTimeBasedPayload (
+  IN OUT UINTN            *DataSize,
+  IN OUT UINT8            **Data
+  )
+{
+  EFI_STATUS                       Status;
+  UINT8                            *NewData;
+  UINT8                            *Payload;
+  UINTN                            PayloadSize;
+  EFI_VARIABLE_AUTHENTICATION_2    *DescriptorData;
+  UINTN                            DescriptorSize;
+  EFI_TIME                         Time;
+  EFI_GUID efi_cert_type = EFI_CERT_TYPE_PKCS7_GUID;
+  
+  if (Data == NULL || DataSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  
+  //
+  // In Setup mode or Custom mode, the variable does not need to be signed but the 
+  // parameters to the SetVariable() call still need to be prepared as authenticated
+  // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
+  // data in it.
+  //
+  Payload     = *Data;
+  PayloadSize = *DataSize;
+  
+  DescriptorSize    = OFFSET_OF(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);
+  NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize);
+  if (NewData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  if ((Payload != NULL) && (PayloadSize != 0)) {
+    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
+  }
+
+  DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);
+
+  ZeroMem (&Time, sizeof (EFI_TIME));
+  Status = uefi_call_wrapper(RT->GetTime,2, &Time, NULL);
+  if (EFI_ERROR (Status)) {
+    FreePool(NewData);
+    return Status;
+  }
+  Time.Pad1       = 0;
+  Time.Nanosecond = 0;
+  Time.TimeZone   = 0;
+  Time.Daylight   = 0;
+  Time.Pad2       = 0;
+  CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));
+  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
+  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;
+  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
+  DescriptorData->AuthInfo.CertType =  efi_cert_type;
+  /* we're expecting an EFI signature list, so don't free the input since
+   * it might not be in a pool */
+#if 0
+  if (Payload != NULL) {
+    FreePool(Payload);
+  }
+#endif
+  
+  *DataSize = DescriptorSize + PayloadSize;
+  *Data     = NewData;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
+                 UINT32 options, int createtimebased)
+{
+       EFI_SIGNATURE_LIST *Cert;
+       UINTN DataSize;
+       EFI_STATUS efi_status;
+
+       /* Microsoft request: Bugs in some UEFI platforms mean that PK or any
+        * other secure variable can be updated or deleted programmatically,
+        * so prevent */
+       if (!variable_is_setupmode(1))
+               return EFI_SECURITY_VIOLATION;
+
+       if (createtimebased) {
+               int ds;
+               efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
+                                                (void **)&Cert, &ds);
+               if (efi_status != EFI_SUCCESS) {
+                       Print(L"Failed to create %s certificate %d\n", var, efi_status);
+                       return efi_status;
+               }
+
+               DataSize = ds;
+       } else {
+               /* we expect an efi signature list rather than creating it */
+               Cert = (EFI_SIGNATURE_LIST *)Data;
+               DataSize = len;
+       }
+       efi_status = CreateTimeBasedPayload(&DataSize, (UINT8 **)&Cert);
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"Failed to create time based payload %d\n", efi_status);
+               return efi_status;
+       }
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
+                                      EFI_VARIABLE_NON_VOLATILE
+                                      | EFI_VARIABLE_RUNTIME_ACCESS 
+                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                      | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
+                                      | options,
+                                      DataSize, Cert);
+
+       return efi_status;
+}
+
+UINT64
+GetOSIndications(void)
+{
+       UINT64 indications;
+       UINTN DataSize = sizeof(indications);
+       EFI_STATUS efi_status;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"OsIndicationsSupported", &GV_GUID, NULL, &DataSize, &indications);
+       if (efi_status != EFI_SUCCESS)
+               return 0;
+
+       return indications;
+}
+
+EFI_STATUS
+SETOSIndicationsAndReboot(UINT64 indications)
+{
+       UINTN DataSize = sizeof(indications);
+       EFI_STATUS efi_status;
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"OsIndications",
+                                      &GV_GUID,
+                                      EFI_VARIABLE_NON_VOLATILE
+                                      | EFI_VARIABLE_RUNTIME_ACCESS 
+                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                      DataSize, &indications);
+
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, NULL);
+       /* does not return */
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS
+get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
+                 UINT32 *attributes)
+{
+       EFI_STATUS efi_status;
+
+       *len = 0;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
+                                      NULL, len, NULL);
+       if (efi_status != EFI_BUFFER_TOO_SMALL)
+               return efi_status;
+
+       *data = AllocateZeroPool(*len);
+       if (!*data)
+               return EFI_OUT_OF_RESOURCES;
+       
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
+                                      attributes, len, *data);
+
+       if (efi_status != EFI_SUCCESS) {
+               FreePool(*data);
+               *data = NULL;
+       }
+       return efi_status;
+}
+
+EFI_STATUS
+get_variable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner)
+{
+       return get_variable_attr(var, data, len, owner, NULL);
+}
+
+EFI_STATUS
+find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen)
+{
+       EFI_SIGNATURE_LIST *CertList;
+
+       certlist_for_each_certentry(CertList, Data, DataSize, DataSize) {
+               if (CertList->SignatureSize != keylen + sizeof(EFI_GUID))
+                       continue;
+               EFI_SIGNATURE_DATA *Cert;
+
+               certentry_for_each_cert(Cert, CertList)
+                       if (CompareMem (Cert->SignatureData, key, keylen) == 0)
+                               return EFI_SUCCESS;
+       }
+       return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen)
+{
+       UINTN DataSize;
+       UINT8 *Data;
+       EFI_STATUS status;
+
+       status = get_variable(var, &Data, &DataSize, owner);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       status = find_in_esl(Data, DataSize, key, keylen);
+
+       FreePool(Data);
+
+       return status;
+}
+
+int
+variable_is_setupmode(int default_return)
+{
+       /* set to 1 because we return true if SetupMode doesn't exist */
+       UINT8 SetupMode = default_return;
+       UINTN DataSize = sizeof(SetupMode);
+       EFI_STATUS status;
+
+       status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL,
+                                  &DataSize, &SetupMode);
+       if (EFI_ERROR(status))
+               return default_return;
+
+       return SetupMode;
+}
+
+int
+variable_is_secureboot(void)
+{
+       /* return false if variable doesn't exist */
+       UINT8 SecureBoot = 0;
+       UINTN DataSize;
+       EFI_STATUS status;
+
+       DataSize = sizeof(SecureBoot);
+       status = uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", &GV_GUID, NULL,
+                                  &DataSize, &SecureBoot);
+       if (EFI_ERROR(status))
+               return 0;
+
+       return SecureBoot;
+}
+
+EFI_STATUS
+variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
+                    UINT8 hash[SHA256_DIGEST_SIZE])
+{
+       EFI_STATUS status;
+
+       if (find_in_variable_esl(var, owner, hash, SHA256_DIGEST_SIZE)
+           == EFI_SUCCESS)
+               /* hash already present */
+               return EFI_ALREADY_STARTED;
+
+       UINT8 sig[sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE];
+       EFI_SIGNATURE_LIST *l = (void *)sig;
+       EFI_SIGNATURE_DATA *d = (void *)sig + sizeof(EFI_SIGNATURE_LIST);
+       SetMem(sig, 0, sizeof(sig));
+       l->SignatureType = EFI_CERT_SHA256_GUID;
+       l->SignatureListSize = sizeof(sig);
+       l->SignatureSize = 16 +32; /* UEFI defined */
+       CopyMem(&d->SignatureData, hash, SHA256_DIGEST_SIZE);
+       d->SignatureOwner = MOK_OWNER;
+
+       if (CompareGuid(&owner, &SIG_DB) == 0)
+               status = SetSecureVariable(var, sig, sizeof(sig), owner,
+                                          EFI_VARIABLE_APPEND_WRITE, 0);
+       else
+               status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
+                                          EFI_VARIABLE_NON_VOLATILE
+                                          | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                          | EFI_VARIABLE_APPEND_WRITE,
+                                          sizeof(sig), sig);
+       return status;
+}
diff --git a/make-certs b/make-certs
new file mode 100755 (executable)
index 0000000..3e9293b
--- /dev/null
@@ -0,0 +1,554 @@
+#!/bin/bash -e
+#
+#  Generate a root CA cert for signing, and then a subject cert.
+#  Usage: make-certs.sh hostname [user[@domain]] [more ...]
+#  For testing only, probably still has some bugs in it.
+#
+
+DOMAIN=xn--u4h.net
+DAYS=365
+KEYTYPE=RSA
+KEYSIZE=2048
+DIGEST=SHA256
+CRLHOURS=24
+CRLDAYS=
+
+# Cleanup temporary files at exit.
+touch openssl.cnf
+newcertdir=`mktemp -d`
+cleanup() {
+       test -f openssl.cnf   && rm -f openssl.cnf
+       test -f ca.txt        && rm -f ca.txt
+       test -f ocsp.txt      && rm -f ocsp.txt
+       test -n "$newcertdir" && rm -fr "$newcertdir"
+}
+trap cleanup EXIT
+
+# The first argument is either a common name value or a flag indicating that
+# we're doing something other than issuing a cert.
+commonname="$1"
+refresh_crl=false
+revoke_cert=false
+ocsp_serve=false
+if test "x$commonname" = "x-refresh-crl" ; then
+       refresh_crl=true
+       commonname="$1"
+fi
+if test "x$commonname" = "x-refresh_crl" ; then
+       refresh_crl=true
+       commonname="$1"
+fi
+if test "x$commonname" = "x-revoke" ; then
+       revoke_cert=true
+       shift
+       commonname="$1"
+fi
+if test "x$commonname" = "x-ocsp" ; then
+       ocsp_serve=true
+       commonname="$1"
+fi
+if test "x$commonname" = x ; then
+       echo Usage: `basename $0` 'commonname' user'[@domain]' '[more [...]]'
+       echo Usage: `basename $0` -revoke 'commonname'
+       echo Usage: `basename $0` -ocsp
+       echo Usage: `basename $0` -refresh-crl
+       echo More:
+       echo -e \\tKey usage: "[sign|signing|encrypt|encryption|all]"
+       echo -e \\tAuthority Access Info OCSP responder: "ocsp:URI"
+       echo -e \\tCRL distribution point: "crl:URI"
+       echo -e \\tSubject Alternative Name:
+       echo -e \\t\\tHostname: "*"
+       echo -e \\t\\tIP address: w.x.y.z
+       echo -e \\t\\tEmail address: "*@*.com/edu/net/org/local"
+       echo -e \\t\\tKerberos principal name: "*@*.COM/EDU/NET/ORG/LOCAL"
+       echo -e \\tExtended key usage:
+       echo -e \\t\\t1....
+       echo -e \\t\\t2....
+       echo -e \\t\\tid-kp-server-auth \| tls-server
+       echo -e \\t\\tid-kp-client-auth \| tls-client
+       echo -e \\t\\tid-kp-email-protection \| email
+       echo -e \\t\\tid-ms-kp-sc-logon \| id-ms-sc-logon
+       echo -e \\t\\tid-pkinit-kp-client-auth \| id-pkinit-client
+       echo -e \\t\\tid-pkinit-kp-kdc \| id-pkinit-kdc
+       echo -e \\t\\tca \| CA
+       exit 1
+fi
+
+# Choose a user name part for email attributes.
+GIVENUSER=$2
+test x"$GIVENUSER" = x && GIVENUSER=$USER
+echo "$GIVENUSER" | grep -q @ || GIVENUSER="$GIVENUSER"@$DOMAIN
+DOMAIN=`echo "$GIVENUSER" | cut -f2- -d@`
+
+shift || true
+shift || true
+
+# Done already?
+done=:
+
+keygen() {
+       case "$KEYTYPE" in
+       DSA)
+               openssl dsaparam -out "$1".param $KEYSIZE
+               openssl gendsa "$1".param
+               ;;
+       RSA|*)
+               #openssl genrsa $KEYSIZE -passout pass:qweqwe
+               openssl genrsa $KEYSIZE
+               #openssl genrsa $KEYSIZE -nodes
+               ;;
+       esac
+}
+
+# Set some defaults.
+CA=FALSE
+if test -s ca.crldp.uri.txt ; then
+       crlval="`cat ca.crldp.uri.txt`"
+       crl="URI:$crlval"
+fi
+if test -s ca.ocsp.uri.txt ; then
+       aiaval="`cat ca.ocsp.uri.txt`"
+       aia="OCSP;URI:$aiaval"
+fi
+if test -s ca.domain.txt ; then
+       domval="`cat ca.domain.txt`"
+       if test -n "$domval" ; then
+               DOMAIN="$domval"
+       fi
+fi
+
+# Parse the arguments which indicate what sort of information we want.
+while test $# -gt 0 ; do
+       type=
+       value="$1"
+       case "$value" in
+       RSA|rsa)
+               KEYTYPE=RSA
+               ;;
+       DSA|dsa)
+               KEYTYPE=DSA
+               ;;
+       OCSP:*|ocsp:*)
+               aiaval=`echo "$value" | cut -f2- -d:`
+               aia="OCSP;URI:$aiaval"
+               ;;
+       CRL:*|crl:*)
+               crlval=`echo "$value" | cut -f2- -d:`
+               crl="URI:$crlval"
+               ;;
+       signing|sign)
+               keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature"
+               ;;
+       encryption|encrypt)
+               keyusage="${keyusage:+${keyusage},}keyEncipherment,dataEncipherment"
+               ;;
+       all)
+               keyusage="digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly"
+               ;;
+       ca|CA)
+               CA=TRUE
+               keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign"
+               ;;
+       1.*|2.*|id-*|tls-*|email|mail|codesign)
+               ekuval=`echo "$value" | tr '[A-Z]' '[a-z]' | sed 's,\-,,g'`
+               case "$ekuval" in
+               idkpserverauth|tlsserver) ekuval=1.3.6.1.5.5.7.3.1;;
+               idkpclientauth|tlsclient) ekuval=1.3.6.1.5.5.7.3.2;;
+               idkpemailprotection|email|mail) ekuval=1.3.6.1.5.5.7.3.4;;
+               idkpcodesign|codesign) ekuval=1.3.6.1.5.5.7.3.3;;
+               idmskpsclogon|idmssclogon) ekuval=1.3.6.1.4.1.311.20.2.2;;
+               idpkinitkpclientauth|idpkinitclient) ekuval=1.3.6.1.5.2.3.4;;
+               idpkinitkpkdc|idpkinitkdc) ekuval=1.3.6.1.5.2.3.5;;
+               esac
+               if test -z "$eku" ; then
+                       eku="$ekuval"
+               else
+                       eku="$eku,$ekuval"
+               fi
+               ;;
+       *@*.COM|*@*.EDU|*@*.NET|*@*.ORG|*@*.LOCAL)
+               luser=`echo "$value" | tr '[A-Z]' '[a-z]'`
+               if test "$luser" = "$value" ; then
+                       luser=
+               fi
+               type="otherName:1.3.6.1.5.2.2;SEQUENCE:$value,${luser:+otherName:1.3.6.1.4.1.311.20.2.3;UTF8:${luser},}otherName:1.3.6.1.4.1.311.20.2.3;UTF8"
+               unset luser
+               principals="$principals $value"
+               ;;
+       *@*.com|*@*.edu|*@*.net|*@*.org|*@*.local)            type=email;;
+       [0-9]*.[0-9]*.[0-9]*.[0-9]*)                          type=IP;;
+       *)                                                    type=DNS;;
+       esac
+       if test -n "$type" ; then
+               newvalue="${type}:$value"
+               if test -z "$altnames" ; then
+                       altnames="${newvalue}"
+               else
+                       altnames="${altnames},${newvalue}"
+               fi
+       fi
+       shift
+done
+
+# Build the configuration file, including bits on how to construct the CA
+# certificate, an OCSP responder certificate, and the issued certificate.
+cat > openssl.cnf <<- EOF
+[ca]
+default_ca = issuer
+
+[issuer]
+private_key = `pwd`/ca.key
+certificate = `pwd`/ca.crt
+database = `pwd`/ca.db
+serial = `pwd`/ca.srl
+default_md = $DIGEST
+new_certs_dir = $newcertdir
+policy = no_policy
+
+[no_policy]
+
+[req_oids]
+domainComponent = 0.9.2342.19200300.100.1.25
+
+[req_ca]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_ca_name
+default_md = $DIGEST
+subjectKeyIdentifier=hash
+
+[req_ca_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeCity
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+cat >> openssl.cnf <<- EOF
+#commonName = Test Certifying CA
+
+[v3_ca]
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always
+#authorityKeyIdentifier=keyid:always,issuer:always
+keyUsage=nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
+basicConstraints=critical,CA:TRUE
+nsComment="Testing CA Certificate"
+EOF
+if test -n "$aia" ; then
+       echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+       echo -n "$aiaval" > ca.ocsp.uri.txt
+fi
+if test -n "$crl" ; then
+       echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+       echo -n "$crlval" > ca.crldp.uri.txt
+fi
+echo "$DOMAIN" > ca.domain.txt
+cat >> openssl.cnf <<- EOF
+
+[req_ocsp]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_ocsp_name
+default_md = $DIGEST
+
+[req_ocsp_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeOrg
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+cat >> openssl.cnf <<- EOF
+#commonName = OCSP Signer for Test Certifying CA
+
+[v3_ocsp]
+subjectKeyIdentifier=hash
+#authorityKeyIdentifier=keyid:always,issuer:always
+authorityKeyIdentifier=keyid:always
+keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
+extendedKeyUsage=1.3.6.1.5.5.7.3.9
+#basicConstraints=CA:FALSE
+basicConstraints=CA:TRUE
+nsComment="Testing OCSP Certificate"
+1.3.6.1.5.5.7.48.1.5=ASN1:NULL
+EOF
+if test -n "$aia" ; then
+       echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+fi
+if test -n "$crl" ; then
+       echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+fi
+cat >> openssl.cnf <<- EOF
+
+[req_issued]
+prompt = no
+oid_section = req_oids
+distinguished_name = req_issued_name
+default_md = $DIGEST
+
+[req_issued_name]
+C=US
+#stateOrProvinceName=SomeState
+localityName=SomeCity
+O=SomeOrg
+EOF
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
+#mail = $GIVENUSER
+cat >> openssl.cnf <<- EOF
+commonName = $commonname
+
+[v3_issued]
+#certificatePolicies=2.5.29.32.0${eku:+,${eku}}
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid:always
+#authorityKeyIdentifier=keyid:always,issuer:always
+EOF
+if test -n "$aia" ; then
+       echo "authorityInfoAccess = ${aia}" >> openssl.cnf
+fi
+if test -n "$crl" ; then
+       echo "crlDistributionPoints = ${crl}" >> openssl.cnf
+fi
+if test -n "$keyusage" ; then
+       echo "keyUsage = critical,${keyusage}" >> openssl.cnf
+fi
+if test -n "$altnames" ; then
+       echo "subjectAltName = ${altnames}" >> openssl.cnf
+fi
+if test -n "$eku" ; then
+       echo "extendedKeyUsage = ${eku}" >> openssl.cnf
+       :
+fi
+if test "x$CA" = xTRUE ; then
+       echo "basicConstraints=critical,CA:TRUE" >> openssl.cnf
+       echo 'nsComment="Testing CA Certificate for '"$commonname"'"' >> openssl.cnf
+else
+       echo "basicConstraints=CA:FALSE" >> openssl.cnf
+       echo 'nsComment="Testing Certificate for '"$commonname"'"' >> openssl.cnf
+fi
+for value in $principals; do
+       user=`echo "$value" | cut -f1 -d@`
+       realm=`echo "$value" | cut -f2- -d@`
+       echo "" >> openssl.cnf
+       echo "[$value]" >> openssl.cnf
+       echo "realm=EXPLICIT:0,GeneralString:$realm" >> openssl.cnf
+       echo "kerberosname=EXPLICIT:1,SEQUENCE:krb5$user" >> openssl.cnf
+
+       echo "" >> openssl.cnf
+       echo "[krb5$user]" >> openssl.cnf
+       echo "nametype=EXPLICIT:0,INTEGER:1" >> openssl.cnf
+       echo "namelist=EXPLICIT:1,SEQUENCE:krb5basic$user" >> openssl.cnf
+
+       echo "[krb5basic$user]" >> openssl.cnf
+       count=0
+       for part in `echo "$user" | sed 's,/, ,g'` ; do
+               echo "$count.part=GeneralString:$part" >> openssl.cnf
+               count=`expr "$count" + 1`
+       done
+done
+
+# Create the data files for a new CA.
+if ! test -s ca.srl ; then
+       (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > ca.srl
+else
+       echo "You already have a ca.srl file; not replacing."
+fi
+if ! test -s ca.db ; then
+       touch ca.db
+else
+       echo "You already have a ca.db file; not replacing."
+fi
+if ! test -s ca.db.attr ; then
+       touch ca.db.attr
+else
+       echo "You already have a ca.db.attr file; not replacing."
+fi
+
+# If we need a CA key, generate one.
+if ! test -s ca.key ; then
+       umask=`umask -p`
+       umask 077
+       keygen ca > ca.key 2> /dev/null
+       $umask
+else
+       echo "You already have a ca.key file; not replacing."
+       done=echo
+fi
+
+# If we need a CA certificate, generate one.
+if ! test -s ca.crt ; then
+       sed -i -e 's,^\[req_ca\]$,\[req\],g' `pwd`/openssl.cnf
+       openssl req -config `pwd`/openssl.cnf -new -key ca.key > ca.csr 2> /dev/null -passin pass:shim
+       sed -i -e 's,^\[req\]$,\[req_ca\],g' `pwd`/openssl.cnf
+       openssl x509 -extfile `pwd`/openssl.cnf -CAserial ca.srl -signkey ca.key -extensions v3_ca -req -in ca.csr -days $DAYS -out ca.crt ; : 2> /dev/null
+       openssl x509 -noout -text -in ca.crt > ca.txt
+       cat ca.crt >> ca.txt
+       cat ca.txt > ca.crt
+       rm ca.txt
+       cat ca.crt > ca.chain.crt
+else
+       echo "You already have a ca.crt file; not replacing."
+       done=echo
+fi
+
+# If we need an OCSP key, generate one.
+if ! test -s ocsp.key ; then
+       umask=`umask -p`
+       umask 077
+       keygen ocsp > ocsp.key 2> /dev/null
+       $umask
+else
+       echo "You already have an ocsp.key file; not replacing."
+       done=echo
+fi
+
+# Generate the OCSP signing cert.  Set the X.509v3 basic constraints and EKU.
+if ! test -s ocsp.crt ; then
+       sed -i -e 's,^\[req_ocsp\]$,\[req\],g' `pwd`/openssl.cnf
+       openssl req -config `pwd`/openssl.cnf -new -key ocsp.key > ocsp.csr 2> /dev/null
+       sed -i -e 's,^\[req\]$,\[req_ocsp\],g' `pwd`/openssl.cnf
+       openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_ocsp -preserveDN -in ocsp.csr -days $DAYS -out ocsp.crt 2> /dev/null
+       openssl x509 -noout -text -in ocsp.crt > ocsp.txt
+       cat ocsp.crt >> ocsp.txt
+       cat ocsp.txt >  ocsp.crt
+       rm ocsp.txt
+else
+       echo "You already have an ocsp.crt file; not replacing."
+       done=echo
+fi
+
+# If we were told to revoke the certificate with the specified common name,
+# do so.
+if $revoke_cert ; then
+       openssl ca -config `pwd`/openssl.cnf -revoke "$commonname".crt
+fi
+
+# Always refresh the CRL.
+openssl ca -config `pwd`/openssl.cnf -gencrl ${CRLHOURS:+-crlhours ${CRLHOURS}} ${CRLDAYS:+-crldays ${CRLDAYS}} -out ca.crl.pem
+openssl crl -in ca.crl.pem -outform der -out ca.crl
+openssl crl -in ca.crl -inform der -noout -text > ca.crl.pem
+openssl crl -in ca.crl -inform der >> ca.crl.pem
+
+# If we were told to start up the mini OCSP server, do so.
+if $ocsp_serve ; then
+       openssl ocsp -text -index `pwd`/ca.db -CA `pwd`/ca.crt -rsigner `pwd`/ocsp.crt -rkey `pwd`/ocsp.key -rother `pwd`/ocsp.crt -port "`cut -f3 -d/ ca.ocsp.uri.txt | sed -r 's,(^[^:]*),0.0.0.0,g'`"
+       exit 0
+fi
+
+# If we're just here to do a revocation or refresh the CRL, we're done.
+if $revoke_cert || $refresh_crl ; then
+       exit 0
+fi
+
+# Create a new serial number and whatnot if this is a new sub-CA.
+if test "x$CA" = xTRUE ; then
+       if ! test -d "$commonname" ; then
+               mkdir "$commonname"
+       fi
+       if ! test -s "$commonname/ca.srl" ; then
+               (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > "$commonname/ca.srl"
+       else
+               echo "You already have a $commonname/ca.srl file; not replacing."
+       fi
+       if test -n "$aia" ; then
+               echo -n "$aiaval" > "$commonname/ca.ocsp.uri.txt"
+       fi
+       if test -n "$crl" ; then
+               echo -n "$crlval" > "$commonname/ca.crldp.uri.txt"
+       fi
+       echo "$DOMAIN" > "$commonname/ca.domain.txt"
+       touch "$commonname/ca.db" "$commonname/ca.db.attr"
+       cert="$commonname/ca.crt"
+       csr="$commonname/ca.csr"
+       key="$commonname/ca.key"
+       pem="$commonname/ca.pem"
+       pfx="$commonname/ca.p12"
+       ln -s ../`basename $0` "$commonname"/
+else
+       cert="$commonname.crt"
+       csr="$commonname.csr"
+       key="$commonname.key"
+       pem="$commonname.pem"
+       pfx="$commonname.p12"
+fi
+
+# Generate the subject's certificate.  Set the X.509v3 basic constraints.
+if ! test -s "$cert" ; then
+       # Generate another key, unless we have a key or CSR.
+       if ! test -s "$key" && ! test -s "$csr" ; then
+               umask=`umask -p`
+               umask 077
+               keygen "$commonname" > "$key" 2> /dev/null
+               $umask
+       else
+               echo "You already have a $key or $csr file; not replacing."
+               done=echo
+       fi
+
+       if ! test -s "$csr" ; then
+               sed -i -e 's,^\[req_issued\]$,\[req\],g' `pwd`/openssl.cnf
+               openssl req -config `pwd`/openssl.cnf -new -key "$key" > "$csr" 2> /dev/null
+               sed -i -e 's,^\[req\]$,\[req_issued\],g' `pwd`/openssl.cnf
+       fi
+       openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_issued -preserveDN -in "$csr" -days $DAYS -out "$cert" 2> /dev/null
+       openssl x509 -noout -text -in "$cert" > "$cert.txt"
+       cat "$cert" >> "$cert.txt"
+       cat "$cert.txt" > "$cert"
+       rm -f "$cert.txt"
+else
+       echo "You already have a $cert file; not replacing."
+       done=echo
+fi
+
+if test -s ca.chain.crt ; then
+       chain=ca.chain.crt
+else
+       chain=ca.crt
+fi
+if test "x$CA" = xTRUE ; then
+       cat "$chain" "$cert" > "$commonname/ca.chain.crt"
+fi
+
+# Create ca.pem and the subject's name.pem for the benefit of applications
+# which expect both the private key and the certificate in one file.
+umask=`umask -p`
+umask 077
+if ! test -s ca.pem ; then
+       cat ca.key ca.crt > ca.pem
+else
+       echo "You already have a ca.pem file; not replacing."
+       done=echo
+fi
+if ! test -s "$pem" ; then
+       cat "$key" "$cert" > "$pem"
+else
+       echo "You already have a $pem file; not replacing."
+       done=echo
+fi
+if ! test -s "$pfx" ; then
+       #openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:qweqwe
+       openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:
+else
+       echo "You already have a $pfx file; not replacing."
+       done=echo
+fi
+$umask
+$done
+
+echo CA certificate:
+openssl x509 -noout -issuer  -in ca.crt | sed s,=\ ,\ ,g
+openssl x509 -noout -subject -in ca.crt | sed s,=\ ,\ ,g
+echo
+echo End entity certificate:
+openssl x509 -noout -issuer  -in "$cert" | sed s,=\ ,\ ,g
+openssl x509 -noout -subject -in "$cert" | sed s,=\ ,\ ,g
+openssl x509 -noout -serial  -in "$cert" | sed s,=,\ ,g
+echo
+echo PKCS12 bag:
+openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:
+#openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:qweqwe
+echo
+echo Verifying:
+echo + openssl verify -CAfile "$chain" "$cert"
+openssl verify -CAfile "$chain" "$cert"
diff --git a/netboot.c b/netboot.c
new file mode 100644 (file)
index 0000000..1cc1a2b
--- /dev/null
+++ b/netboot.c
@@ -0,0 +1,346 @@
+/*
+ * netboot - trivial UEFI first-stage bootloader netboot support
+ *
+ * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#include <efi.h>
+#include <efilib.h>
+#include <string.h>
+#include "shim.h"
+#include "netboot.h"
+#include "str.h"
+
+#define ntohs(x) __builtin_bswap16(x)  /* supported both by GCC and clang */
+#define htons(x) ntohs(x)
+
+static EFI_PXE_BASE_CODE *pxe;
+static EFI_IP_ADDRESS tftp_addr;
+static CHAR8 *full_path;
+
+
+typedef struct {
+       UINT16 OpCode;
+       UINT16 Length;
+       UINT8 Data[1];
+} EFI_DHCP6_PACKET_OPTION;
+
+/*
+ * usingNetboot
+ * Returns TRUE if we identify a protocol that is enabled and Providing us with
+ * the needed information to fetch a grubx64.efi image
+ */
+BOOLEAN findNetboot(EFI_HANDLE device)
+{
+       EFI_STATUS status;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
+                                  &PxeBaseCodeProtocol, (VOID **)&pxe);
+       if (status != EFI_SUCCESS) {
+               pxe = NULL;
+               return FALSE;
+       }
+
+       if (!pxe || !pxe->Mode) {
+               pxe = NULL;
+               return FALSE;
+       }
+
+       if (!pxe->Mode->Started || !pxe->Mode->DhcpAckReceived) {
+               pxe = NULL;
+               return FALSE;
+       }
+
+       /*
+        * We've located a pxe protocol handle thats been started and has
+        * received an ACK, meaning its something we'll be able to get
+        * tftp server info out of
+        */
+       return TRUE;
+}
+
+static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
+{
+       void *optr = NULL, *end = NULL;
+       EFI_DHCP6_PACKET_OPTION *option = NULL;
+       CHAR8 *url = NULL;
+       UINT32 urllen = 0;
+
+       optr = pkt->DhcpOptions;
+       end = optr + sizeof(pkt->DhcpOptions);
+
+       for (;;) {
+               option = (EFI_DHCP6_PACKET_OPTION *)optr;
+
+               if (ntohs(option->OpCode) == 0)
+                       break;
+
+               if (ntohs(option->OpCode) == 59) {
+                       /* This is the bootfile url option */
+                       urllen = ntohs(option->Length);
+                       if ((void *)(option->Data + urllen) > end)
+                               break;
+                       url = AllocateZeroPool(urllen + 1);
+                       if (!url)
+                               break;
+                       memcpy(url, option->Data, urllen);
+                       return url;
+               }
+               optr += 4 + ntohs(option->Length);
+               if (optr + sizeof(EFI_DHCP6_PACKET_OPTION) > end)
+                       break;
+       }
+
+       return NULL;
+}
+
+static CHAR16 str2ns(CHAR8 *str)
+{
+        CHAR16 ret = 0;
+        CHAR8 v;
+        for(;*str;str++) {
+                if ('0' <= *str && *str <= '9')
+                        v = *str - '0';
+                else if ('A' <= *str && *str <= 'F')
+                        v = *str - 'A' + 10;
+                else if ('a' <= *str && *str <= 'f')
+                        v = *str - 'a' + 10;
+                else
+                        v = 0;
+                ret = (ret << 4) + v;
+        }
+        return htons(ret);
+}
+
+static CHAR8 *str2ip6(CHAR8 *str)
+{
+       UINT8 i = 0, j = 0, p = 0;
+       size_t len = 0, dotcount = 0;
+       enum { MAX_IP6_DOTS = 7 };
+       CHAR8 *a = NULL, *b = NULL, t = 0;
+       static UINT16 ip[8];
+
+       memset(ip, 0, sizeof(ip));
+
+       /* Count amount of ':' to prevent overflows.
+        * max. count = 7. Returns an invalid ip6 that
+        * can be checked against
+        */
+       for (a = str; *a != 0; ++a) {
+               if (*a == ':')
+                       ++dotcount;
+       }
+       if (dotcount > MAX_IP6_DOTS)
+               return (CHAR8 *)ip;
+
+       len = strlen(str);
+       a = b = str;
+       for (i = p = 0; i < len; i++, b++) {
+               if (*b != ':')
+                       continue;
+               *b = '\0';
+               ip[p++] = str2ns(a);
+               *b = ':';
+               a = b + 1;
+               if (b[1] == ':' )
+                       break;
+       }
+       a = b = (str + len);
+       for (j = len, p = 7; j > i; j--, a--) {
+               if (*a != ':')
+                       continue;
+               t = *b;
+               *b = '\0';
+               ip[p--] = str2ns(a+1);
+               *b = t;
+               b = a;
+       }
+       return (CHAR8 *)ip;
+}
+
+static BOOLEAN extract_tftp_info(CHAR8 *url)
+{
+       CHAR8 *start, *end;
+       CHAR8 ip6str[40];
+       CHAR8 ip6inv[16];
+       CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+
+       // to check against str2ip6() errors
+       memset(ip6inv, 0, sizeof(ip6inv));
+
+       if (strncmp((UINT8 *)url, (UINT8 *)"tftp://", 7)) {
+               Print(L"URLS MUST START WITH tftp://\n");
+               return FALSE;
+       }
+       start = url + 7;
+       if (*start != '[') {
+               Print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
+               return FALSE;
+       }
+
+       start++;
+       end = start;
+       while ((*end != '\0') && (*end != ']')) {
+               end++;
+               if (end - start >= (int)sizeof(ip6str)) {
+                       Print(L"TFTP URL includes malformed IPv6 address\n");
+                       return FALSE;
+               }
+       }
+       if (*end == '\0') {
+               Print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
+               return FALSE;
+       }
+       memset(ip6str, 0, sizeof(ip6str));
+       memcpy(ip6str, start, end - start);
+       end++;
+       memcpy(&tftp_addr.v6, str2ip6(ip6str), 16);
+       if (memcmp(&tftp_addr.v6, ip6inv, sizeof(ip6inv)) == 0)
+               return FALSE;
+       full_path = AllocateZeroPool(strlen(end)+strlen(template)+1);
+       if (!full_path)
+               return FALSE;
+       memcpy(full_path, end, strlen(end));
+       end = (CHAR8 *)strrchr((char *)full_path, '/');
+       if (!end)
+               end = (CHAR8 *)full_path;
+       memcpy(end, template, strlen(template));
+       end[strlen(template)] = '\0';
+
+       return TRUE;
+}
+
+static EFI_STATUS parseDhcp6()
+{
+       EFI_PXE_BASE_CODE_DHCPV6_PACKET *packet = (EFI_PXE_BASE_CODE_DHCPV6_PACKET *)&pxe->Mode->DhcpAck.Raw;
+       CHAR8 *bootfile_url;
+
+       bootfile_url = get_v6_bootfile_url(packet);
+       if (!bootfile_url)
+               return EFI_NOT_FOUND;
+       if (extract_tftp_info(bootfile_url) == FALSE) {
+               FreePool(bootfile_url);
+               return EFI_NOT_FOUND;
+       }
+       FreePool(bootfile_url);
+       return EFI_SUCCESS;
+}
+
+static EFI_STATUS parseDhcp4()
+{
+       CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+       INTN template_len = strlen(template) + 1;
+
+       INTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
+       INTN i;
+       UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
+
+       for (i = dir_len; i >= 0; i--) {
+               if (dir[i] == '/')
+                       break;
+       }
+       dir_len = (i >= 0) ? i + 1 : 0;
+
+       full_path = AllocateZeroPool(dir_len + template_len);
+
+       if (!full_path)
+               return EFI_OUT_OF_RESOURCES;
+
+       if (dir_len > 0) {
+               strncpya(full_path, dir, dir_len);
+               if (full_path[dir_len-1] == '/' && template[0] == '/')
+                       full_path[dir_len-1] = '\0';
+       }
+       if (dir_len == 0 && dir[0] != '/' && template[0] == '/')
+               template++;
+       strcata(full_path, template);
+       memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
+
+       return EFI_SUCCESS;
+}
+
+EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle)
+{
+
+       EFI_STATUS rc;
+
+       if (!pxe)
+               return EFI_NOT_READY;
+
+       memset((UINT8 *)&tftp_addr, 0, sizeof(tftp_addr));
+
+       /*
+        * If we've discovered an active pxe protocol figure out
+        * if its ipv4 or ipv6
+        */
+       if (pxe->Mode->UsingIpv6){
+               rc = parseDhcp6();
+       } else
+               rc = parseDhcp4();
+       return rc;
+}
+
+EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz)
+{
+       EFI_STATUS rc;
+       EFI_PXE_BASE_CODE_TFTP_OPCODE read = EFI_PXE_BASE_CODE_TFTP_READ_FILE;
+       BOOLEAN overwrite = FALSE;
+       BOOLEAN nobuffer = FALSE;
+       UINTN blksz = 512;
+
+       Print(L"Fetching Netboot Image\n");
+       if (*buffer == NULL) {
+               *buffer = AllocatePool(4096 * 1024);
+               if (!*buffer)
+                       return EFI_OUT_OF_RESOURCES; 
+               *bufsiz = 4096 * 1024;
+       }
+
+try_again:
+       rc = uefi_call_wrapper(pxe->Mtftp, 10, pxe, read, *buffer, overwrite,
+                               bufsiz, &blksz, &tftp_addr, full_path, NULL, nobuffer);
+
+       if (rc == EFI_BUFFER_TOO_SMALL) {
+               /* try again, doubling buf size */
+               *bufsiz *= 2;
+               FreePool(*buffer);
+               *buffer = AllocatePool(*bufsiz);
+               if (!*buffer)
+                       return EFI_OUT_OF_RESOURCES;
+               goto try_again;
+       }
+
+       if (rc != EFI_SUCCESS && *buffer) {
+               FreePool(*buffer);
+       }
+       return rc;
+}
diff --git a/netboot.h b/netboot.h
new file mode 100644 (file)
index 0000000..6417373
--- /dev/null
+++ b/netboot.h
@@ -0,0 +1,9 @@
+#ifndef _NETBOOT_H_
+#define _NETBOOT_H_
+
+extern BOOLEAN findNetboot(EFI_HANDLE image_handle);
+
+extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle);
+
+extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz);
+#endif
diff --git a/replacements.c b/replacements.c
new file mode 100644 (file)
index 0000000..01eda0e
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * shim - trivial UEFI first-stage bootloader
+ *
+ * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+/*   Chemical agents lend themselves to covert use in sabotage against
+ * which it is exceedingly difficult to visualize any really effective
+ * defense... I will not dwell upon this use of CBW because, as one
+ * pursues the possibilities of such covert uses, one discovers that the
+ * scenarios resemble that in which the components of a nuclear weapon
+ * are smuggled into New York City and assembled in the basement of the
+ * Empire State Building.
+ *   In other words, once the possibility is recognized to exist, about
+ * all that one can do is worry about it.
+ *   -- Dr. Ivan L Bennett, Jr., testifying before the Subcommittee on
+ *      National Security Policy and Scientific Developments, November 20,
+ *      1969.
+ */
+
+#include <efi.h>
+#include <efiapi.h>
+#include <efilib.h>
+#include "shim.h"
+#include "replacements.h"
+
+/* oh for fuck's sakes.*/
+#ifndef EFI_SECURITY_VIOLATION
+#define EFI_SECURITY_VIOLATION 26
+#endif
+
+static EFI_SYSTEM_TABLE *systab;
+
+static typeof(systab->BootServices->LoadImage) system_load_image;
+static typeof(systab->BootServices->StartImage) system_start_image;
+static typeof(systab->BootServices->Exit) system_exit;
+static typeof(systab->BootServices->ExitBootServices) system_exit_boot_services;
+
+static EFI_HANDLE last_loaded_image;
+
+void
+unhook_system_services(void)
+{
+       if (!systab)
+               return;
+
+       systab->BootServices->LoadImage = system_load_image;
+       systab->BootServices->StartImage = system_start_image;
+       systab->BootServices->ExitBootServices = system_exit_boot_services;
+}
+
+static EFI_STATUS EFIAPI
+load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
+       EFI_DEVICE_PATH *DevicePath, VOID *SourceBuffer,
+       UINTN SourceSize, EFI_HANDLE *ImageHandle)
+{
+       EFI_STATUS status;
+       unhook_system_services();
+
+       status = systab->BootServices->LoadImage(BootPolicy,
+                       ParentImageHandle, DevicePath,
+                       SourceBuffer, SourceSize, ImageHandle);
+       hook_system_services(systab);
+       if (EFI_ERROR(status))
+               last_loaded_image = NULL;
+       else
+               last_loaded_image = *ImageHandle;
+       return status;
+}
+
+static EFI_STATUS EFIAPI
+start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data)
+{
+       EFI_STATUS status;
+       unhook_system_services();
+
+       /* We have to uninstall shim's protocol here, because if we're
+        * On the fallback.efi path, then our call pathway is:
+        *
+        * shim->fallback->shim->grub
+        * ^               ^      ^
+        * |               |      \- gets protocol #0
+        * |               \- installs its protocol (#1)
+        * \- installs its protocol (#0)
+        * and if we haven't removed this, then grub will get the *first*
+        * shim's protocol, but it'll get the second shim's systab
+        * replacements.  So even though it will participate and verify
+        * the kernel, the systab never finds out.
+        */
+       if (image_handle == last_loaded_image) {
+               loader_is_participating = 1;
+               uninstall_shim_protocols();
+       }
+       status = systab->BootServices->StartImage(image_handle, exit_data_size, exit_data);
+       if (EFI_ERROR(status)) {
+               if (image_handle == last_loaded_image) {
+                       EFI_STATUS status2 = install_shim_protocols();
+
+                       if (EFI_ERROR(status2)) {
+                               Print(L"Something has gone seriously wrong: %d\n",
+                                       status2);
+                               Print(L"shim cannot continue, sorry.\n");
+                               systab->BootServices->Stall(5000000);
+                               systab->RuntimeServices->ResetSystem(
+                                       EfiResetShutdown,
+                                       EFI_SECURITY_VIOLATION, 0, NULL);
+                       }
+               }
+               hook_system_services(systab);
+               loader_is_participating = 0;
+       }
+       return status;
+}
+
+static EFI_STATUS EFIAPI
+exit_boot_services(EFI_HANDLE image_key, UINTN map_key)
+{
+       if (loader_is_participating || verification_method == VERIFIED_BY_HASH) {
+               unhook_system_services();
+               EFI_STATUS status;
+               status = systab->BootServices->ExitBootServices(image_key, map_key);
+               if (status != EFI_SUCCESS)
+                       hook_system_services(systab);
+               return status;
+       }
+
+       Print(L"Bootloader has not verified loaded image.\n");
+       Print(L"System is compromised.  halting.\n");
+       systab->BootServices->Stall(5000000);
+       systab->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION, 0, NULL);
+       return EFI_SECURITY_VIOLATION;
+}
+
+static EFI_STATUS EFIAPI
+do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus,
+       UINTN ExitDataSize, CHAR16 *ExitData)
+{
+       EFI_STATUS status;
+
+       shim_fini();
+
+       status = systab->BootServices->Exit(ImageHandle, ExitStatus,
+                                           ExitDataSize, ExitData);
+       if (EFI_ERROR(status)) {
+               EFI_STATUS status2 = shim_init();
+
+               if (EFI_ERROR(status2)) {
+                       Print(L"Something has gone seriously wrong: %r\n",
+                               status2);
+                       Print(L"shim cannot continue, sorry.\n");
+                       systab->BootServices->Stall(5000000);
+                       systab->RuntimeServices->ResetSystem(
+                               EfiResetShutdown,
+                               EFI_SECURITY_VIOLATION, 0, NULL);
+               }
+       }
+       return status;
+}
+
+void
+hook_system_services(EFI_SYSTEM_TABLE *local_systab)
+{
+       systab = local_systab;
+
+       /* We need to hook various calls to make this work... */
+
+       /* We need LoadImage() hooked so that fallback.c can load shim
+        * without having to fake LoadImage as well.  This allows it
+        * to call the system LoadImage(), and have us track the output
+        * and mark loader_is_participating in start_image.  This means
+        * anything added by fallback has to be verified by the system db,
+        * which we want to preserve anyway, since that's all launching
+        * through BDS gives us. */
+       system_load_image = systab->BootServices->LoadImage;
+       systab->BootServices->LoadImage = load_image;
+
+       /* we need StartImage() so that we can allow chain booting to an
+        * image trusted by the firmware */
+       system_start_image = systab->BootServices->StartImage;
+       systab->BootServices->StartImage = start_image;
+
+       /* we need to hook ExitBootServices() so a) we can enforce the policy
+        * and b) we can unwrap when we're done. */
+       system_exit_boot_services = systab->BootServices->ExitBootServices;
+       systab->BootServices->ExitBootServices = exit_boot_services;
+}
+
+void
+unhook_exit(void)
+{
+       systab->BootServices->Exit = system_exit;
+}
+
+void
+hook_exit(EFI_SYSTEM_TABLE *local_systab)
+{
+       systab = local_systab;
+
+       /* we need to hook Exit() so that we can allow users to quit the
+        * bootloader and still e.g. start a new one or run an internal
+        * shell. */
+       system_exit = systab->BootServices->Exit;
+       systab->BootServices->Exit = do_exit;
+}
diff --git a/replacements.h b/replacements.h
new file mode 100644 (file)
index 0000000..e38cded
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Red Hat, Inc <pjones@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (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 SHIM_REPLACEMENTS_H
+#define SHIM_REPLACEMENTS_H 1
+
+typedef enum {
+       VERIFIED_BY_NOTHING,
+       VERIFIED_BY_CERT,
+       VERIFIED_BY_HASH
+} verification_method_t;
+
+extern verification_method_t verification_method;
+extern int loader_is_participating;
+
+extern void hook_system_services(EFI_SYSTEM_TABLE *local_systab);
+extern void unhook_system_services(void);
+
+extern void hook_exit(EFI_SYSTEM_TABLE *local_systab);
+extern void unhook_exit(void);
+
+extern EFI_STATUS install_shim_protocols(void);
+extern void uninstall_shim_protocols(void);
+
+#endif /* SHIM_REPLACEMENTS_H */
diff --git a/shim.c b/shim.c
new file mode 100644 (file)
index 0000000..c69961b
--- /dev/null
+++ b/shim.c
@@ -0,0 +1,2740 @@
+/*
+ * shim - trivial UEFI first-stage bootloader
+ *
+ * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#include <efi.h>
+#include <efilib.h>
+#include <Library/BaseCryptLib.h>
+#include "PeImage.h"
+#include "shim.h"
+#include "netboot.h"
+#include "httpboot.h"
+#include "shim_cert.h"
+#include "replacements.h"
+#include "tpm.h"
+#include "ucs2.h"
+
+#include "guid.h"
+#include "variables.h"
+#include "efiauthenticated.h"
+#include "security_policy.h"
+#include "console.h"
+#include "version.h"
+
+#include <stdarg.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#define FALLBACK L"\\fb" EFI_ARCH L".efi"
+#define MOK_MANAGER L"\\mm" EFI_ARCH L".efi"
+
+#define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2"
+
+static EFI_SYSTEM_TABLE *systab;
+static EFI_HANDLE image_handle;
+static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
+
+static CHAR16 *second_stage;
+static void *load_options;
+static UINT32 load_options_size;
+static UINT8 in_protocol;
+
+#define perror(fmt, ...) ({                                            \
+               UINTN __perror_ret = 0;                                 \
+               if (!in_protocol)                                       \
+                       __perror_ret = Print((fmt), ##__VA_ARGS__);     \
+               __perror_ret;                                           \
+       })
+
+EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+
+/*
+ * The vendor certificate used for validating the second stage loader
+ */
+extern struct {
+       UINT32 vendor_cert_size;
+       UINT32 vendor_dbx_size;
+       UINT32 vendor_cert_offset;
+       UINT32 vendor_dbx_offset;
+} cert_table;
+
+UINT32 vendor_cert_size;
+UINT32 vendor_dbx_size;
+UINT8 *vendor_cert;
+UINT8 *vendor_dbx;
+
+/*
+ * indicator of how an image has been verified
+ */
+verification_method_t verification_method;
+int loader_is_participating;
+
+#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
+
+UINT8 user_insecure_mode;
+UINT8 ignore_db;
+
+typedef enum {
+       DATA_FOUND,
+       DATA_NOT_FOUND,
+       VAR_NOT_FOUND
+} CHECK_STATUS;
+
+typedef struct {
+       UINT32 MokSize;
+       UINT8 *Mok;
+} MokListNode;
+
+/*
+ * Perform basic bounds checking of the intra-image pointers
+ */
+static void *ImageAddress (void *image, unsigned int size, unsigned int address)
+{
+       if (address > size)
+               return NULL;
+
+       return image + address;
+}
+
+/* here's a chart:
+ *             i686    x86_64  aarch64
+ *  64-on-64:  nyet    yes     yes
+ *  64-on-32:  nyet    yes     nyet
+ *  32-on-32:  yes     yes     no
+ */
+static int
+allow_64_bit(void)
+{
+#if defined(__x86_64__) || defined(__aarch64__)
+       return 1;
+#elif defined(__i386__) || defined(__i686__)
+       /* Right now blindly assuming the kernel will correctly detect this
+        * and /halt the system/ if you're not really on a 64-bit cpu */
+       if (in_protocol)
+               return 1;
+       return 0;
+#else /* assuming everything else is 32-bit... */
+       return 0;
+#endif
+}
+
+static int
+allow_32_bit(void)
+{
+#if defined(__x86_64__)
+#if defined(ALLOW_32BIT_KERNEL_ON_X64)
+       if (in_protocol)
+               return 1;
+       return 0;
+#else
+       return 0;
+#endif
+#elif defined(__i386__) || defined(__i686__)
+       return 1;
+#elif defined(__arch64__)
+       return 0;
+#else /* assuming everything else is 32-bit... */
+       return 1;
+#endif
+}
+
+static int
+image_is_64_bit(EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr)
+{
+       /* .Magic is the same offset in all cases */
+       if (PEHdr->Pe32Plus.OptionalHeader.Magic
+                       == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+               return 1;
+       return 0;
+}
+
+static const UINT16 machine_type =
+#if defined(__x86_64__)
+       IMAGE_FILE_MACHINE_X64;
+#elif defined(__aarch64__)
+       IMAGE_FILE_MACHINE_ARM64;
+#elif defined(__arm__)
+       IMAGE_FILE_MACHINE_ARMTHUMB_MIXED;
+#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
+       IMAGE_FILE_MACHINE_I386;
+#elif defined(__ia64__)
+       IMAGE_FILE_MACHINE_IA64;
+#else
+#error this architecture is not supported by shim
+#endif
+
+static int
+image_is_loadable(EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr)
+{
+       /* If the machine type doesn't match the binary, bail, unless
+        * we're in an allowed 64-on-32 scenario */
+       if (PEHdr->Pe32.FileHeader.Machine != machine_type) {
+               if (!(machine_type == IMAGE_FILE_MACHINE_I386 &&
+                     PEHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64 &&
+                     allow_64_bit())) {
+                       return 0;
+               }
+       }
+
+       /* If it's not a header type we recognize at all, bail */
+       switch (PEHdr->Pe32Plus.OptionalHeader.Magic) {
+       case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+       case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+               break;
+       default:
+               return 0;
+       }
+
+       /* and now just check for general 64-vs-32 compatibility */
+       if (image_is_64_bit(PEHdr)) {
+               if (allow_64_bit())
+                       return 1;
+       } else {
+               if (allow_32_bit())
+                       return 1;
+       }
+       return 0;
+}
+
+/*
+ * Perform the actual relocation
+ */
+static EFI_STATUS relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
+                                EFI_IMAGE_SECTION_HEADER *Section,
+                                void *orig, void *data)
+{
+       EFI_IMAGE_BASE_RELOCATION *RelocBase, *RelocBaseEnd;
+       UINT64 Adjust;
+       UINT16 *Reloc, *RelocEnd;
+       char *Fixup, *FixupBase, *FixupData = NULL;
+       UINT16 *Fixup16;
+       UINT32 *Fixup32;
+       UINT64 *Fixup64;
+       int size = context->ImageSize;
+       void *ImageEnd = (char *)orig + size;
+       int n = 0;
+
+       if (image_is_64_bit(context->PEHdr))
+               context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)(unsigned long)data;
+       else
+               context->PEHdr->Pe32.OptionalHeader.ImageBase = (UINT32)(unsigned long)data;
+
+       /* Alright, so here's how this works:
+        *
+        * context->RelocDir gives us two things:
+        * - the VA the table of base relocation blocks are (maybe) to be
+        *   mapped at (RelocDir->VirtualAddress)
+        * - the virtual size (RelocDir->Size)
+        *
+        * The .reloc section (Section here) gives us some other things:
+        * - the name! kind of. (Section->Name)
+        * - the virtual size (Section->VirtualSize), which should be the same
+        *   as RelocDir->Size
+        * - the virtual address (Section->VirtualAddress)
+        * - the file section size (Section->SizeOfRawData), which is
+        *   a multiple of OptHdr->FileAlignment.  Only useful for image
+        *   validation, not really useful for iteration bounds.
+        * - the file address (Section->PointerToRawData)
+        * - a bunch of stuff we don't use that's 0 in our binaries usually
+        * - Flags (Section->Characteristics)
+        *
+        * and then the thing that's actually at the file address is an array
+        * of EFI_IMAGE_BASE_RELOCATION structs with some values packed behind
+        * them.  The SizeOfBlock field of this structure includes the
+        * structure itself, and adding it to that structure's address will
+        * yield the next entry in the array.
+        */
+       RelocBase = ImageAddress(orig, size, Section->PointerToRawData);
+       /* RelocBaseEnd here is the address of the first entry /past/ the
+        * table.  */
+       RelocBaseEnd = ImageAddress(orig, size, Section->PointerToRawData +
+                                               Section->Misc.VirtualSize);
+
+       if (!RelocBase && !RelocBaseEnd)
+               return EFI_SUCCESS;
+
+       if (!RelocBase || !RelocBaseEnd) {
+               perror(L"Reloc table overflows binary\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       Adjust = (UINTN)data - context->ImageAddress;
+
+       if (Adjust == 0)
+               return EFI_SUCCESS;
+
+       while (RelocBase < RelocBaseEnd) {
+               Reloc = (UINT16 *) ((char *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
+
+               if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > context->RelocDir->Size)) {
+                       perror(L"Reloc %d block size %d is invalid\n", n, RelocBase->SizeOfBlock);
+                       return EFI_UNSUPPORTED;
+               }
+
+               RelocEnd = (UINT16 *) ((char *) RelocBase + RelocBase->SizeOfBlock);
+               if ((void *)RelocEnd < orig || (void *)RelocEnd > ImageEnd) {
+                       perror(L"Reloc %d entry overflows binary\n", n);
+                       return EFI_UNSUPPORTED;
+               }
+
+               FixupBase = ImageAddress(data, size, RelocBase->VirtualAddress);
+               if (!FixupBase) {
+                       perror(L"Reloc %d Invalid fixupbase\n", n);
+                       return EFI_UNSUPPORTED;
+               }
+
+               while (Reloc < RelocEnd) {
+                       Fixup = FixupBase + (*Reloc & 0xFFF);
+                       switch ((*Reloc) >> 12) {
+                       case EFI_IMAGE_REL_BASED_ABSOLUTE:
+                               break;
+
+                       case EFI_IMAGE_REL_BASED_HIGH:
+                               Fixup16   = (UINT16 *) Fixup;
+                               *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
+                               if (FixupData != NULL) {
+                                       *(UINT16 *) FixupData = *Fixup16;
+                                       FixupData             = FixupData + sizeof (UINT16);
+                               }
+                               break;
+
+                       case EFI_IMAGE_REL_BASED_LOW:
+                               Fixup16   = (UINT16 *) Fixup;
+                               *Fixup16  = (UINT16) (*Fixup16 + (UINT16) Adjust);
+                               if (FixupData != NULL) {
+                                       *(UINT16 *) FixupData = *Fixup16;
+                                       FixupData             = FixupData + sizeof (UINT16);
+                               }
+                               break;
+
+                       case EFI_IMAGE_REL_BASED_HIGHLOW:
+                               Fixup32   = (UINT32 *) Fixup;
+                               *Fixup32  = *Fixup32 + (UINT32) Adjust;
+                               if (FixupData != NULL) {
+                                       FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT32));
+                                       *(UINT32 *)FixupData  = *Fixup32;
+                                       FixupData             = FixupData + sizeof (UINT32);
+                               }
+                               break;
+
+                       case EFI_IMAGE_REL_BASED_DIR64:
+                               Fixup64 = (UINT64 *) Fixup;
+                               *Fixup64 = *Fixup64 + (UINT64) Adjust;
+                               if (FixupData != NULL) {
+                                       FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));
+                                       *(UINT64 *)(FixupData) = *Fixup64;
+                                       FixupData = FixupData + sizeof(UINT64);
+                               }
+                               break;
+
+                       default:
+                               perror(L"Reloc %d Unknown relocation\n", n);
+                               return EFI_UNSUPPORTED;
+                       }
+                       Reloc += 1;
+               }
+               RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+               n++;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
+{
+       UINTN length;
+
+       if (!Cert || CertSize < 4)
+               return FALSE;
+
+       /*
+        * A DER encoding x509 certificate starts with SEQUENCE(0x30),
+        * the number of length bytes, and the number of value bytes.
+        * The size of a x509 certificate is usually between 127 bytes
+        * and 64KB. For convenience, assume the number of value bytes
+        * is 2, i.e. the second byte is 0x82.
+        */
+       if (Cert[0] != 0x30 || Cert[1] != 0x82)
+               return FALSE;
+
+       length = Cert[2]<<8 | Cert[3];
+       if (length != (CertSize - 4))
+               return FALSE;
+
+       return TRUE;
+}
+
+static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize)
+{
+       X509 *x509;
+       CONST UINT8 *Temp = Cert;
+       EXTENDED_KEY_USAGE *eku;
+       ASN1_OBJECT *module_signing;
+
+       module_signing = OBJ_nid2obj(OBJ_create(OID_EKU_MODSIGN, NULL, NULL));
+
+       x509 = d2i_X509 (NULL, &Temp, (long) CertSize);
+       if (x509 != NULL) {
+               eku = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
+
+               if (eku) {
+                       int i = 0;
+                       for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+                               ASN1_OBJECT *key_usage = sk_ASN1_OBJECT_value(eku, i);
+
+                               if (OBJ_cmp(module_signing, key_usage) == 0)
+                                       return FALSE;
+                       }
+                       EXTENDED_KEY_USAGE_free(eku);
+               }
+
+               X509_free(x509);
+       }
+
+       OBJ_cleanup();
+
+       return TRUE;
+}
+
+static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
+                                        UINTN dbsize,
+                                        WIN_CERTIFICATE_EFI_PKCS *data,
+                                        UINT8 *hash)
+{
+       EFI_SIGNATURE_DATA *Cert;
+       UINTN CertSize;
+       BOOLEAN IsFound = FALSE;
+       EFI_GUID CertType = X509_GUID;
+
+       while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+               if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
+                       Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+                       CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
+                       if (verify_x509(Cert->SignatureData, CertSize)) {
+                               if (verify_eku(Cert->SignatureData, CertSize)) {
+                                       IsFound = AuthenticodeVerify (data->CertData,
+                                                                     data->Hdr.dwLength - sizeof(data->Hdr),
+                                                                     Cert->SignatureData,
+                                                                     CertSize,
+                                                                     hash, SHA256_DIGEST_SIZE);
+                                       if (IsFound)
+                                               return DATA_FOUND;
+                               }
+                       } else if (verbose) {
+                               console_notify(L"Not a DER encoding x.509 Certificate");
+                       }
+               }
+
+               dbsize -= CertList->SignatureListSize;
+               CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+       }
+
+       return DATA_NOT_FOUND;
+}
+
+static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid,
+                                 WIN_CERTIFICATE_EFI_PKCS *data, UINT8 *hash)
+{
+       CHECK_STATUS rc;
+       EFI_STATUS efi_status;
+       EFI_SIGNATURE_LIST *CertList;
+       UINTN dbsize = 0;
+       UINT8 *db;
+
+       efi_status = get_variable(dbname, &db, &dbsize, guid);
+
+       if (efi_status != EFI_SUCCESS)
+               return VAR_NOT_FOUND;
+
+       CertList = (EFI_SIGNATURE_LIST *)db;
+
+       rc = check_db_cert_in_ram(CertList, dbsize, data, hash);
+
+       FreePool(db);
+
+       return rc;
+}
+
+/*
+ * Check a hash against an EFI_SIGNATURE_LIST in a buffer
+ */
+static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList,
+                                        UINTN dbsize, UINT8 *data,
+                                        int SignatureSize, EFI_GUID CertType)
+{
+       EFI_SIGNATURE_DATA *Cert;
+       UINTN CertCount, Index;
+       BOOLEAN IsFound = FALSE;
+
+       while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+               CertCount = (CertList->SignatureListSize -sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+               Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+               if (CompareGuid(&CertList->SignatureType, &CertType) == 0) {
+                       for (Index = 0; Index < CertCount; Index++) {
+                               if (CompareMem (Cert->SignatureData, data, SignatureSize) == 0) {
+                                       //
+                                       // Find the signature in database.
+                                       //
+                                       IsFound = TRUE;
+                                       break;
+                               }
+
+                               Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+                       }
+                       if (IsFound) {
+                               break;
+                       }
+               }
+
+               dbsize -= CertList->SignatureListSize;
+               CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+       }
+
+       if (IsFound)
+               return DATA_FOUND;
+
+       return DATA_NOT_FOUND;
+}
+
+/*
+ * Check a hash against an EFI_SIGNATURE_LIST in a UEFI variable
+ */
+static CHECK_STATUS check_db_hash(CHAR16 *dbname, EFI_GUID guid, UINT8 *data,
+                                 int SignatureSize, EFI_GUID CertType)
+{
+       EFI_STATUS efi_status;
+       EFI_SIGNATURE_LIST *CertList;
+       UINTN dbsize = 0;
+       UINT8 *db;
+
+       efi_status = get_variable(dbname, &db, &dbsize, guid);
+
+       if (efi_status != EFI_SUCCESS) {
+               return VAR_NOT_FOUND;
+       }
+
+       CertList = (EFI_SIGNATURE_LIST *)db;
+
+       CHECK_STATUS rc = check_db_hash_in_ram(CertList, dbsize, data,
+                                               SignatureSize, CertType);
+       FreePool(db);
+       return rc;
+
+}
+
+/*
+ * Check whether the binary signature or hash are present in dbx or the
+ * built-in blacklist
+ */
+static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert,
+                                  UINT8 *sha256hash, UINT8 *sha1hash)
+{
+       EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+       EFI_GUID shim_var = SHIM_LOCK_GUID;
+       EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_dbx;
+
+       if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha256hash,
+                                SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) ==
+                               DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+       if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha1hash,
+                                SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID) ==
+                               DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+       if (cert && check_db_cert_in_ram(dbx, vendor_dbx_size, cert,
+                                        sha256hash) == DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+
+       if (check_db_hash(L"dbx", secure_var, sha256hash, SHA256_DIGEST_SIZE,
+                         EFI_CERT_SHA256_GUID) == DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+       if (check_db_hash(L"dbx", secure_var, sha1hash, SHA1_DIGEST_SIZE,
+                         EFI_CERT_SHA1_GUID) == DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+       if (cert && check_db_cert(L"dbx", secure_var, cert, sha256hash) ==
+                               DATA_FOUND)
+               return EFI_ACCESS_DENIED;
+       if (check_db_hash(L"MokListX", shim_var, sha256hash, SHA256_DIGEST_SIZE,
+                         EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+               return EFI_ACCESS_DENIED;
+       }
+       if (cert && check_db_cert(L"MokListX", shim_var, cert, sha256hash) ==
+                               DATA_FOUND) {
+               return EFI_ACCESS_DENIED;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static void update_verification_method(verification_method_t method)
+{
+       if (verification_method == VERIFIED_BY_NOTHING)
+               verification_method = method;
+}
+
+/*
+ * Check whether the binary signature or hash are present in db or MokList
+ */
+static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
+                                  UINT8 *sha256hash, UINT8 *sha1hash)
+{
+       EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+       EFI_GUID shim_var = SHIM_LOCK_GUID;
+
+       if (!ignore_db) {
+               if (check_db_hash(L"db", secure_var, sha256hash, SHA256_DIGEST_SIZE,
+                                       EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+                       update_verification_method(VERIFIED_BY_HASH);
+                       return EFI_SUCCESS;
+               }
+               if (check_db_hash(L"db", secure_var, sha1hash, SHA1_DIGEST_SIZE,
+                                       EFI_CERT_SHA1_GUID) == DATA_FOUND) {
+                       verification_method = VERIFIED_BY_HASH;
+                       update_verification_method(VERIFIED_BY_HASH);
+                       return EFI_SUCCESS;
+               }
+               if (cert && check_db_cert(L"db", secure_var, cert, sha256hash)
+                                       == DATA_FOUND) {
+                       verification_method = VERIFIED_BY_CERT;
+                       update_verification_method(VERIFIED_BY_CERT);
+                       return EFI_SUCCESS;
+               }
+       }
+
+       if (check_db_hash(L"MokList", shim_var, sha256hash, SHA256_DIGEST_SIZE,
+                         EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+               verification_method = VERIFIED_BY_HASH;
+               update_verification_method(VERIFIED_BY_HASH);
+               return EFI_SUCCESS;
+       }
+       if (cert && check_db_cert(L"MokList", shim_var, cert, sha256hash) ==
+                               DATA_FOUND) {
+               verification_method = VERIFIED_BY_CERT;
+               update_verification_method(VERIFIED_BY_CERT);
+               return EFI_SUCCESS;
+       }
+
+       update_verification_method(VERIFIED_BY_NOTHING);
+       return EFI_ACCESS_DENIED;
+}
+
+/*
+ * Check whether we're in Secure Boot and user mode
+ */
+
+static BOOLEAN secure_mode (void)
+{
+       static int first = 1;
+       if (user_insecure_mode)
+               return FALSE;
+
+       if (variable_is_secureboot() != 1) {
+               if (verbose && !in_protocol && first)
+                       console_notify(L"Secure boot not enabled");
+               first = 0;
+               return FALSE;
+       }
+
+       /* If we /do/ have "SecureBoot", but /don't/ have "SetupMode",
+        * then the implementation is bad, but we assume that secure boot is
+        * enabled according to the status of "SecureBoot".  If we have both
+        * of them, then "SetupMode" may tell us additional data, and we need
+        * to consider it.
+        */
+       if (variable_is_setupmode(0) == 1) {
+               if (verbose && !in_protocol && first)
+                       console_notify(L"Platform is in setup mode");
+               first = 0;
+               return FALSE;
+       }
+
+       first = 0;
+       return TRUE;
+}
+
+#define check_size_line(data, datasize_in, hashbase, hashsize, l) ({   \
+       if ((unsigned long)hashbase >                                   \
+                       (unsigned long)data + datasize_in) {            \
+               perror(L"shim.c:%d Invalid hash base 0x%016x\n", l,     \
+                       hashbase);                                      \
+               goto done;                                              \
+       }                                                               \
+       if ((unsigned long)hashbase + hashsize >                        \
+                       (unsigned long)data + datasize_in) {            \
+               perror(L"shim.c:%d Invalid hash size 0x%016x\n", l,     \
+                       hashsize);                                      \
+               goto done;                                              \
+       }                                                               \
+})
+#define check_size(d,ds,h,hs) check_size_line(d,ds,h,hs,__LINE__)
+
+/*
+ * Calculate the SHA1 and SHA256 hashes of a binary
+ */
+
+static EFI_STATUS generate_hash (char *data, unsigned int datasize_in,
+                                PE_COFF_LOADER_IMAGE_CONTEXT *context,
+                                UINT8 *sha256hash, UINT8 *sha1hash)
+
+{
+       unsigned int sha256ctxsize, sha1ctxsize;
+       unsigned int size = datasize_in;
+       void *sha256ctx = NULL, *sha1ctx = NULL;
+       char *hashbase;
+       unsigned int hashsize;
+       unsigned int SumOfBytesHashed, SumOfSectionBytes;
+       unsigned int index, pos;
+       unsigned int datasize;
+       EFI_IMAGE_SECTION_HEADER  *Section;
+       EFI_IMAGE_SECTION_HEADER  *SectionHeader = NULL;
+       EFI_STATUS status = EFI_SUCCESS;
+       EFI_IMAGE_DOS_HEADER *DosHdr = (void *)data;
+       unsigned int PEHdr_offset = 0;
+
+       if (datasize_in < 0) {
+               perror(L"Invalid data size\n");
+               return EFI_INVALID_PARAMETER;
+       }
+       size = datasize = (unsigned int)datasize_in;
+
+       if (datasize <= sizeof (*DosHdr) ||
+           DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+               perror(L"Invalid signature\n");
+               return EFI_INVALID_PARAMETER;
+       }
+       PEHdr_offset = DosHdr->e_lfanew;
+
+       sha256ctxsize = Sha256GetContextSize();
+       sha256ctx = AllocatePool(sha256ctxsize);
+
+       sha1ctxsize = Sha1GetContextSize();
+       sha1ctx = AllocatePool(sha1ctxsize);
+
+       if (!sha256ctx || !sha1ctx) {
+               perror(L"Unable to allocate memory for hash context\n");
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       if (!Sha256Init(sha256ctx) || !Sha1Init(sha1ctx)) {
+               perror(L"Unable to initialise hash\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       /* Hash start to checksum */
+       hashbase = data;
+       hashsize = (char *)&context->PEHdr->Pe32.OptionalHeader.CheckSum -
+               hashbase;
+       check_size(data, datasize_in, hashbase, hashsize);
+
+       if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+           !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+               perror(L"Unable to generate hash\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       /* Hash post-checksum to start of certificate table */
+       hashbase = (char *)&context->PEHdr->Pe32.OptionalHeader.CheckSum +
+               sizeof (int);
+       hashsize = (char *)context->SecDir - hashbase;
+       check_size(data, datasize_in, hashbase, hashsize);
+
+       if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+           !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+               perror(L"Unable to generate hash\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       /* Hash end of certificate table to end of image header */
+       EFI_IMAGE_DATA_DIRECTORY *dd = context->SecDir + 1;
+       hashbase = (char *)dd;
+       hashsize = context->SizeOfHeaders - (unsigned long)((char *)dd - data);
+       if (hashsize > datasize_in) {
+               perror(L"Data Directory size %d is invalid\n", hashsize);
+               status = EFI_INVALID_PARAMETER;
+               goto done;
+       }
+       check_size(data, datasize_in, hashbase, hashsize);
+
+       if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+           !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+               perror(L"Unable to generate hash\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       /* Sort sections */
+       SumOfBytesHashed = context->SizeOfHeaders;
+
+       /* Validate section locations and sizes */
+       for (index = 0, SumOfSectionBytes = 0; index < context->PEHdr->Pe32.FileHeader.NumberOfSections; index++) {
+               EFI_IMAGE_SECTION_HEADER  *SectionPtr;
+
+               /* Validate SectionPtr is within image */
+               SectionPtr = ImageAddress(data, datasize,
+                       PEHdr_offset +
+                       sizeof (UINT32) +
+                       sizeof (EFI_IMAGE_FILE_HEADER) +
+                       context->PEHdr->Pe32.FileHeader.SizeOfOptionalHeader +
+                       (index * sizeof(*SectionPtr)));
+               if (!SectionPtr) {
+                       perror(L"Malformed section %d\n", index);
+                       status = EFI_INVALID_PARAMETER;
+                       goto done;
+               }
+               /* Validate section size is within image. */
+               if (SectionPtr->SizeOfRawData >
+                   datasize - SumOfBytesHashed - SumOfSectionBytes) {
+                       perror(L"Malformed section %d size\n", index);
+                       status = EFI_INVALID_PARAMETER;
+                       goto done;
+               }
+               SumOfSectionBytes += SectionPtr->SizeOfRawData;
+       }
+
+       SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * context->PEHdr->Pe32.FileHeader.NumberOfSections);
+       if (SectionHeader == NULL) {
+               perror(L"Unable to allocate section header\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+       /* Already validated above */
+       Section = ImageAddress(data, datasize,
+               PEHdr_offset +
+               sizeof (UINT32) +
+               sizeof (EFI_IMAGE_FILE_HEADER) +
+               context->PEHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+
+       /* Sort the section headers */
+       for (index = 0; index < context->PEHdr->Pe32.FileHeader.NumberOfSections; index++) {
+               pos = index;
+               while ((pos > 0) && (Section->PointerToRawData < SectionHeader[pos - 1].PointerToRawData)) {
+                       CopyMem (&SectionHeader[pos], &SectionHeader[pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));
+                       pos--;
+               }
+               CopyMem (&SectionHeader[pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));
+               Section += 1;
+       }
+
+       /* Hash the sections */
+       for (index = 0; index < context->PEHdr->Pe32.FileHeader.NumberOfSections; index++) {
+               Section = &SectionHeader[index];
+               if (Section->SizeOfRawData == 0) {
+                       continue;
+               }
+               hashbase  = ImageAddress(data, size, Section->PointerToRawData);
+
+               if (!hashbase) {
+                       perror(L"Malformed section header\n");
+                       status = EFI_INVALID_PARAMETER;
+                       goto done;
+               }
+
+               /* Verify hashsize within image. */
+               if (Section->SizeOfRawData >
+                   datasize - Section->PointerToRawData) {
+                       perror(L"Malformed section raw size %d\n", index);
+                       status = EFI_INVALID_PARAMETER;
+                       goto done;
+               }
+               hashsize  = (unsigned int) Section->SizeOfRawData;
+               check_size(data, datasize_in, hashbase, hashsize);
+
+               if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+                   !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+                       perror(L"Unable to generate hash\n");
+                       status = EFI_OUT_OF_RESOURCES;
+                       goto done;
+               }
+               SumOfBytesHashed += Section->SizeOfRawData;
+       }
+
+       /* Hash all remaining data */
+       if (datasize > SumOfBytesHashed) {
+               hashbase = data + SumOfBytesHashed;
+               hashsize = datasize - context->SecDir->Size - SumOfBytesHashed;
+               check_size(data, datasize_in, hashbase, hashsize);
+
+               if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+                   !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+                       perror(L"Unable to generate hash\n");
+                       status = EFI_OUT_OF_RESOURCES;
+                       goto done;
+               }
+       }
+
+       if (!(Sha256Final(sha256ctx, sha256hash)) ||
+           !(Sha1Final(sha1ctx, sha1hash))) {
+               perror(L"Unable to finalise hash\n");
+               status = EFI_OUT_OF_RESOURCES;
+               goto done;
+       }
+
+done:
+       if (SectionHeader)
+               FreePool(SectionHeader);
+       if (sha1ctx)
+               FreePool(sha1ctx);
+       if (sha256ctx)
+               FreePool(sha256ctx);
+
+       return status;
+}
+
+/*
+ * Ensure that the MOK database hasn't been set or modified from an OS
+ */
+static EFI_STATUS verify_mok (void) {
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS status = EFI_SUCCESS;
+       UINT8 *MokListData = NULL;
+       UINTN MokListDataSize = 0;
+       UINT32 attributes;
+
+       status = get_variable_attr(L"MokList", &MokListData, &MokListDataSize,
+                                  shim_lock_guid, &attributes);
+
+       if (!EFI_ERROR(status) && attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+               perror(L"MokList is compromised!\nErase all keys in MokList!\n");
+               if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
+                       perror(L"Failed to erase MokList\n");
+                        return EFI_ACCESS_DENIED;
+               }
+       }
+
+       if (MokListData)
+               FreePool(MokListData);
+
+       return EFI_SUCCESS;
+}
+
+/*
+ * Check that the signature is valid and matches the binary
+ */
+static EFI_STATUS verify_buffer (char *data, int datasize,
+                        PE_COFF_LOADER_IMAGE_CONTEXT *context)
+{
+       UINT8 sha256hash[SHA256_DIGEST_SIZE];
+       UINT8 sha1hash[SHA1_DIGEST_SIZE];
+       EFI_STATUS status = EFI_ACCESS_DENIED;
+       WIN_CERTIFICATE_EFI_PKCS *cert = NULL;
+       unsigned int size = datasize;
+
+       if (context->SecDir->Size != 0) {
+               if (context->SecDir->Size >= size) {
+                       perror(L"Certificate Database size is too large\n");
+                       return EFI_INVALID_PARAMETER;
+               }
+
+               cert = ImageAddress (data, size,
+                                    context->SecDir->VirtualAddress);
+
+               if (!cert) {
+                       perror(L"Certificate located outside the image\n");
+                       return EFI_INVALID_PARAMETER;
+               }
+
+               if (cert->Hdr.dwLength > context->SecDir->Size) {
+                       perror(L"Certificate list size is inconsistent with PE headers");
+                       return EFI_INVALID_PARAMETER;
+               }
+
+               if (cert->Hdr.wCertificateType !=
+                   WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
+                       perror(L"Unsupported certificate type %x\n",
+                               cert->Hdr.wCertificateType);
+                       return EFI_UNSUPPORTED;
+               }
+       }
+
+       status = generate_hash(data, datasize, context, sha256hash, sha1hash);
+       if (status != EFI_SUCCESS)
+               return status;
+
+       /*
+        * Check that the MOK database hasn't been modified
+        */
+       status = verify_mok();
+       if (status != EFI_SUCCESS)
+               return status;
+
+       /*
+        * Ensure that the binary isn't blacklisted
+        */
+       status = check_blacklist(cert, sha256hash, sha1hash);
+
+       if (status != EFI_SUCCESS) {
+               perror(L"Binary is blacklisted\n");
+               return status;
+       }
+
+       /*
+        * Check whether the binary is whitelisted in any of the firmware
+        * databases
+        */
+       status = check_whitelist(cert, sha256hash, sha1hash);
+       if (status == EFI_SUCCESS)
+               return status;
+
+       if (cert) {
+               /*
+                * Check against the shim build key
+                */
+               if (sizeof(shim_cert) &&
+                   AuthenticodeVerify(cert->CertData,
+                              cert->Hdr.dwLength - sizeof(cert->Hdr),
+                              shim_cert, sizeof(shim_cert), sha256hash,
+                              SHA256_DIGEST_SIZE)) {
+                       status = EFI_SUCCESS;
+                       return status;
+               }
+
+               /*
+                * And finally, check against shim's built-in key
+                */
+               if (vendor_cert_size &&
+                   AuthenticodeVerify(cert->CertData,
+                                      cert->Hdr.dwLength - sizeof(cert->Hdr),
+                                      vendor_cert, vendor_cert_size,
+                                      sha256hash, SHA256_DIGEST_SIZE)) {
+                       status = EFI_SUCCESS;
+                       return status;
+               }
+       }
+
+       status = EFI_ACCESS_DENIED;
+
+       return status;
+}
+
+/*
+ * Read the binary header and grab appropriate information from it
+ */
+static EFI_STATUS read_header(void *data, unsigned int datasize,
+                             PE_COFF_LOADER_IMAGE_CONTEXT *context)
+{
+       EFI_IMAGE_DOS_HEADER *DosHdr = data;
+       EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data;
+       unsigned long HeaderWithoutDataDir, SectionHeaderOffset, OptHeaderSize;
+       unsigned long FileAlignment = 0;
+
+       if (datasize < sizeof (PEHdr->Pe32)) {
+               perror(L"Invalid image\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
+               PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
+
+       if (!image_is_loadable(PEHdr)) {
+               perror(L"Platform does not support this image\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if (image_is_64_bit(PEHdr)) {
+               context->NumberOfRvaAndSizes = PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
+               context->SizeOfHeaders = PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
+               context->ImageSize = PEHdr->Pe32Plus.OptionalHeader.SizeOfImage;
+               context->SectionAlignment = PEHdr->Pe32Plus.OptionalHeader.SectionAlignment;
+               FileAlignment = PEHdr->Pe32Plus.OptionalHeader.FileAlignment;
+               OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);
+       } else {
+               context->NumberOfRvaAndSizes = PEHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes;
+               context->SizeOfHeaders = PEHdr->Pe32.OptionalHeader.SizeOfHeaders;
+               context->ImageSize = (UINT64)PEHdr->Pe32.OptionalHeader.SizeOfImage;
+               context->SectionAlignment = PEHdr->Pe32.OptionalHeader.SectionAlignment;
+               FileAlignment = PEHdr->Pe32.OptionalHeader.FileAlignment;
+               OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);
+       }
+
+       if (FileAlignment % 2 != 0) {
+               perror(L"File Alignment is invalid (%d)\n", FileAlignment);
+               return EFI_UNSUPPORTED;
+       }
+       if (FileAlignment == 0)
+               FileAlignment = 0x200;
+       if (context->SectionAlignment == 0)
+               context->SectionAlignment = PAGE_SIZE;
+       if (context->SectionAlignment < FileAlignment)
+               context->SectionAlignment = FileAlignment;
+
+       context->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections;
+
+       if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < context->NumberOfRvaAndSizes) {
+               perror(L"Image header too small\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       HeaderWithoutDataDir = OptHeaderSize
+                       - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
+       if (((UINT32)PEHdr->Pe32.FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
+                       context->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
+               perror(L"Image header overflows data directory\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       SectionHeaderOffset = DosHdr->e_lfanew
+                               + sizeof (UINT32)
+                               + sizeof (EFI_IMAGE_FILE_HEADER)
+                               + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader;
+       if (((UINT32)context->ImageSize - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
+                       <= context->NumberOfSections) {
+               perror(L"Image sections overflow image size\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if ((context->SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
+                       < (UINT32)context->NumberOfSections) {
+               perror(L"Image sections overflow section headers\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if ((((UINT8 *)PEHdr - (UINT8 *)data) + sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION)) > datasize) {
+               perror(L"Invalid image\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if (PEHdr->Te.Signature != EFI_IMAGE_NT_SIGNATURE) {
+               perror(L"Unsupported image type\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if (PEHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) {
+               perror(L"Unsupported image - Relocations have been stripped\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       context->PEHdr = PEHdr;
+
+       if (image_is_64_bit(PEHdr)) {
+               context->ImageAddress = PEHdr->Pe32Plus.OptionalHeader.ImageBase;
+               context->EntryPoint = PEHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint;
+               context->RelocDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+               context->SecDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+       } else {
+               context->ImageAddress = PEHdr->Pe32.OptionalHeader.ImageBase;
+               context->EntryPoint = PEHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
+               context->RelocDir = &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+               context->SecDir = &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+       }
+
+       context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
+
+       if (context->ImageSize < context->SizeOfHeaders) {
+               perror(L"Invalid image\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if ((unsigned long)((UINT8 *)context->SecDir - (UINT8 *)data) >
+           (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
+               perror(L"Invalid image\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       if (context->SecDir->VirtualAddress >= datasize) {
+               perror(L"Malformed security header\n");
+               return EFI_INVALID_PARAMETER;
+       }
+       return EFI_SUCCESS;
+}
+
+/*
+ * Once the image has been loaded it needs to be validated and relocated
+ */
+static EFI_STATUS handle_image (void *data, unsigned int datasize,
+                               EFI_LOADED_IMAGE *li)
+{
+       EFI_STATUS efi_status;
+       char *buffer;
+       int i;
+       EFI_IMAGE_SECTION_HEADER *Section;
+       char *base, *end;
+       PE_COFF_LOADER_IMAGE_CONTEXT context;
+       unsigned int alignment;
+       int found_entry_point = 0;
+
+       /*
+        * The binary header contains relevant context and section pointers
+        */
+       efi_status = read_header(data, datasize, &context);
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to read header: %r\n", efi_status);
+               return efi_status;
+       }
+
+       /*
+        * We only need to verify the binary if we're in secure mode
+        */
+       if (secure_mode ()) {
+               efi_status = verify_buffer(data, datasize, &context);
+
+               if (EFI_ERROR(efi_status)) {
+                       console_error(L"Verification failed", efi_status);
+                       return efi_status;
+               } else {
+                       if (verbose)
+                               console_notify(L"Verification succeeded");
+               }
+       }
+
+       /* The spec says, uselessly, of SectionAlignment:
+        * =====
+        * The alignment (in bytes) of sections when they are loaded into
+        * memory. It must be greater than or equal to FileAlignment. The
+        * default is the page size for the architecture.
+        * =====
+        * Which doesn't tell you whose responsibility it is to enforce the
+        * "default", or when.  It implies that the value in the field must
+        * be > FileAlignment (also poorly defined), but it appears visual
+        * studio will happily write 512 for FileAlignment (its default) and
+        * 0 for SectionAlignment, intending to imply PAGE_SIZE.
+        *
+        * We only support one page size, so if it's zero, nerf it to 4096.
+        */
+       alignment = context.SectionAlignment;
+       if (!alignment)
+               alignment = 4096;
+
+       buffer = AllocatePool(context.ImageSize + context.SectionAlignment);
+       buffer = ALIGN_POINTER(buffer, alignment);
+
+       if (!buffer) {
+               perror(L"Failed to allocate image buffer\n");
+               return EFI_OUT_OF_RESOURCES;
+       }
+
+       CopyMem(buffer, data, context.SizeOfHeaders);
+
+       entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint);
+       if (!entry_point) {
+               perror(L"Entry point is invalid\n");
+               FreePool(buffer);
+               return EFI_UNSUPPORTED;
+       }
+
+
+       char *RelocBase, *RelocBaseEnd;
+       /*
+        * These are relative virtual addresses, so we have to check them
+        * against the image size, not the data size.
+        */
+       RelocBase = ImageAddress(buffer, context.ImageSize,
+                                context.RelocDir->VirtualAddress);
+       /*
+        * RelocBaseEnd here is the address of the last byte of the table
+        */
+       RelocBaseEnd = ImageAddress(buffer, context.ImageSize,
+                                   context.RelocDir->VirtualAddress +
+                                   context.RelocDir->Size - 1);
+
+       EFI_IMAGE_SECTION_HEADER *RelocSection = NULL;
+
+       /*
+        * Copy the executable's sections to their desired offsets
+        */
+       Section = context.FirstSection;
+       for (i = 0; i < context.NumberOfSections; i++, Section++) {
+               base = ImageAddress (buffer, context.ImageSize,
+                                    Section->VirtualAddress);
+               end = ImageAddress (buffer, context.ImageSize,
+                                   Section->VirtualAddress
+                                    + Section->Misc.VirtualSize - 1);
+
+               if (end < base) {
+                       perror(L"Section %d has negative size\n", i);
+                       FreePool(buffer);
+                       return EFI_UNSUPPORTED;
+               }
+
+               if (Section->VirtualAddress <= context.EntryPoint &&
+                   (Section->VirtualAddress + Section->SizeOfRawData - 1)
+                   > context.EntryPoint)
+                       found_entry_point++;
+
+               /* We do want to process .reloc, but it's often marked
+                * discardable, so we don't want to memcpy it. */
+               if (CompareMem(Section->Name, ".reloc\0\0", 8) == 0) {
+                       if (RelocSection) {
+                               perror(L"Image has multiple relocation sections\n");
+                               return EFI_UNSUPPORTED;
+                       }
+                       /* If it has nonzero sizes, and our bounds check
+                        * made sense, and the VA and size match RelocDir's
+                        * versions, then we believe in this section table. */
+                       if (Section->SizeOfRawData &&
+                                       Section->Misc.VirtualSize &&
+                                       base && end &&
+                                       RelocBase == base &&
+                                       RelocBaseEnd == end) {
+                               RelocSection = Section;
+                       }
+               }
+
+               if (Section->Characteristics & EFI_IMAGE_SCN_MEM_DISCARDABLE) {
+                       continue;
+               }
+
+               if (!base) {
+                       perror(L"Section %d has invalid base address\n", i);
+                       return EFI_UNSUPPORTED;
+               }
+               if (!end) {
+                       perror(L"Section %d has zero size\n", i);
+                       return EFI_UNSUPPORTED;
+               }
+
+               if (!(Section->Characteristics & EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA) &&
+                   (Section->VirtualAddress < context.SizeOfHeaders ||
+                    Section->PointerToRawData < context.SizeOfHeaders)) {
+                       perror(L"Section %d is inside image headers\n", i);
+                       return EFI_UNSUPPORTED;
+               }
+
+               if (Section->Characteristics & EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
+                       ZeroMem(base, Section->Misc.VirtualSize);
+               } else {
+                       if (Section->PointerToRawData < context.SizeOfHeaders) {
+                               perror(L"Section %d is inside image headers\n", i);
+                               return EFI_UNSUPPORTED;
+                       }
+
+                       if (Section->SizeOfRawData > 0)
+                               CopyMem(base, data + Section->PointerToRawData,
+                                       Section->SizeOfRawData);
+
+                       if (Section->SizeOfRawData < Section->Misc.VirtualSize)
+                               ZeroMem(base + Section->SizeOfRawData,
+                                       Section->Misc.VirtualSize - Section->SizeOfRawData);
+               }
+       }
+
+       if (context.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+               perror(L"Image has no relocation entry\n");
+               FreePool(buffer);
+               return EFI_UNSUPPORTED;
+       }
+
+       if (context.RelocDir->Size && RelocSection) {
+               /*
+                * Run the relocation fixups
+                */
+               efi_status = relocate_coff(&context, RelocSection, data,
+                                          buffer);
+
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Relocation failed: %r\n", efi_status);
+                       FreePool(buffer);
+                       return efi_status;
+               }
+       }
+
+       /*
+        * grub needs to know its location and size in memory, so fix up
+        * the loaded image protocol values
+        */
+       li->ImageBase = buffer;
+       li->ImageSize = context.ImageSize;
+
+       /* Pass the load options to the second stage loader */
+       li->LoadOptions = load_options;
+       li->LoadOptionsSize = load_options_size;
+
+       if (!found_entry_point) {
+               perror(L"Entry point is not within sections\n");
+               return EFI_UNSUPPORTED;
+       }
+       if (found_entry_point > 1) {
+               perror(L"%d sections contain entry point\n");
+               return EFI_UNSUPPORTED;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static int
+should_use_fallback(EFI_HANDLE image_handle)
+{
+       EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
+       EFI_LOADED_IMAGE *li;
+       unsigned int pathlen = 0;
+       CHAR16 *bootpath = NULL;
+       EFI_FILE_IO_INTERFACE *fio = NULL;
+       EFI_FILE *vh = NULL;
+       EFI_FILE *fh = NULL;
+       EFI_STATUS rc;
+       int ret = 0;
+
+       rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+                                      &loaded_image_protocol, (void **)&li);
+       if (EFI_ERROR(rc)) {
+               perror(L"Could not get image for bootx64.efi: %r\n", rc);
+               return 0;
+       }
+
+       bootpath = DevicePathToStr(li->FilePath);
+
+       /* Check the beginning of the string and the end, to avoid
+        * caring about which arch this is. */
+       /* I really don't know why, but sometimes bootpath gives us
+        * L"\\EFI\\BOOT\\/BOOTX64.EFI".  So just handle that here...
+        */
+       if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) &&
+                       StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15) &&
+                       StrnCaseCmp(bootpath, L"EFI\\BOOT\\BOOT", 13) &&
+                       StrnCaseCmp(bootpath, L"EFI\\BOOT\\/BOOT", 14))
+               goto error;
+
+       pathlen = StrLen(bootpath);
+       if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI"))
+               goto error;
+
+       rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle,
+                              &FileSystemProtocol, (void **)&fio);
+       if (EFI_ERROR(rc)) {
+               perror(L"Could not get fio for li->DeviceHandle: %r\n", rc);
+               goto error;
+       }
+
+       rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &vh);
+       if (EFI_ERROR(rc)) {
+               perror(L"Could not open fio volume: %r\n", rc);
+               goto error;
+       }
+
+       rc = uefi_call_wrapper(vh->Open, 5, vh, &fh, L"\\EFI\\BOOT" FALLBACK,
+                              EFI_FILE_MODE_READ, 0);
+       if (EFI_ERROR(rc)) {
+               /* Do not print the error here - this is an acceptable case
+                * for removable media, where we genuinely don't want
+                * fallback.efi to exist.
+                * Print(L"Could not open \"\\EFI\\BOOT%s\": %d\n", FALLBACK,
+                *       rc);
+                */
+               goto error;
+       }
+
+       ret = 1;
+error:
+       if (fh)
+               uefi_call_wrapper(fh->Close, 1, fh);
+       if (vh)
+           uefi_call_wrapper(vh->Close, 1, vh);
+       if (bootpath)
+               FreePool(bootpath);
+
+       return ret;
+}
+
+/*
+ * Generate the path of an executable given shim's path and the name
+ * of the executable
+ */
+static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
+                               CHAR16 **PathName)
+{
+       EFI_DEVICE_PATH *devpath;
+       unsigned int i;
+       int j, last = -1;
+       unsigned int pathlen = 0;
+       EFI_STATUS efi_status = EFI_SUCCESS;
+       CHAR16 *bootpath;
+
+       /*
+        * Suuuuper lazy technique here, but check and see if this is a full
+        * path to something on the ESP.  Backwards compatibility demands
+        * that we don't just use \\, becuase we (not particularly brightly)
+        * used to require that the relative file path started with that.
+        *
+        * If it is a full path, don't try to merge it with the directory
+        * from our Loaded Image handle.
+        */
+       if (StrSize(ImagePath) > 5 && StrnCmp(ImagePath, L"\\EFI\\", 5) == 0) {
+               *PathName = StrDuplicate(ImagePath);
+               if (!*PathName) {
+                       perror(L"Failed to allocate path buffer\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+               return EFI_SUCCESS;
+       }
+
+       devpath = li->FilePath;
+
+       bootpath = DevicePathToStr(devpath);
+
+       pathlen = StrLen(bootpath);
+
+       /*
+        * DevicePathToStr() concatenates two nodes with '/'.
+        * Convert '/' to '\\'.
+        */
+       for (i = 0; i < pathlen; i++) {
+               if (bootpath[i] == '/')
+                       bootpath[i] = '\\';
+       }
+
+       for (i=pathlen; i>0; i--) {
+               if (bootpath[i] == '\\' && bootpath[i-1] == '\\')
+                       bootpath[i] = '/';
+               else if (last == -1 && bootpath[i] == '\\')
+                       last = i;
+       }
+
+       if (last == -1 && bootpath[0] == '\\')
+               last = 0;
+       bootpath[last+1] = '\0';
+
+       if (last > 0) {
+               for (i = 0, j = 0; bootpath[i] != '\0'; i++) {
+                       if (bootpath[i] != '/') {
+                               bootpath[j] = bootpath[i];
+                               j++;
+                       }
+               }
+               bootpath[j] = '\0';
+       }
+
+       while (*ImagePath == '\\')
+               ImagePath++;
+
+       *PathName = AllocatePool(StrSize(bootpath) + StrSize(ImagePath));
+
+       if (!*PathName) {
+               perror(L"Failed to allocate path buffer\n");
+               efi_status = EFI_OUT_OF_RESOURCES;
+               goto error;
+       }
+
+       *PathName[0] = '\0';
+       if (StrnCaseCmp(bootpath, ImagePath, StrLen(bootpath)))
+               StrCat(*PathName, bootpath);
+       StrCat(*PathName, ImagePath);
+
+error:
+       FreePool(bootpath);
+
+       return efi_status;
+}
+
+/*
+ * Open the second stage bootloader and read it into a buffer
+ */
+static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
+                             int *datasize, CHAR16 *PathName)
+{
+       EFI_GUID simple_file_system_protocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
+       EFI_GUID file_info_id = EFI_FILE_INFO_ID;
+       EFI_STATUS efi_status;
+       EFI_HANDLE device;
+       EFI_FILE_INFO *fileinfo = NULL;
+       EFI_FILE_IO_INTERFACE *drive;
+       EFI_FILE *root, *grub;
+       UINTN buffersize = sizeof(EFI_FILE_INFO);
+
+       device = li->DeviceHandle;
+
+       /*
+        * Open the device
+        */
+       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
+                                      &simple_file_system_protocol,
+                                      (void **)&drive);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to find fs: %r\n", efi_status);
+               goto error;
+       }
+
+       efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to open fs: %r\n", efi_status);
+               goto error;
+       }
+
+       /*
+        * And then open the file
+        */
+       efi_status = uefi_call_wrapper(root->Open, 5, root, &grub, PathName,
+                                      EFI_FILE_MODE_READ, 0);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to open %s - %r\n", PathName, efi_status);
+               goto error;
+       }
+
+       fileinfo = AllocatePool(buffersize);
+
+       if (!fileinfo) {
+               perror(L"Unable to allocate file info buffer\n");
+               efi_status = EFI_OUT_OF_RESOURCES;
+               goto error;
+       }
+
+       /*
+        * Find out how big the file is in order to allocate the storage
+        * buffer
+        */
+       efi_status = uefi_call_wrapper(grub->GetInfo, 4, grub, &file_info_id,
+                                      &buffersize, fileinfo);
+
+       if (efi_status == EFI_BUFFER_TOO_SMALL) {
+               FreePool(fileinfo);
+               fileinfo = AllocatePool(buffersize);
+               if (!fileinfo) {
+                       perror(L"Unable to allocate file info buffer\n");
+                       efi_status = EFI_OUT_OF_RESOURCES;
+                       goto error;
+               }
+               efi_status = uefi_call_wrapper(grub->GetInfo, 4, grub,
+                                              &file_info_id, &buffersize,
+                                              fileinfo);
+       }
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Unable to get file info: %r\n", efi_status);
+               goto error;
+       }
+
+       buffersize = fileinfo->FileSize;
+
+       *data = AllocatePool(buffersize);
+
+       if (!*data) {
+               perror(L"Unable to allocate file buffer\n");
+               efi_status = EFI_OUT_OF_RESOURCES;
+               goto error;
+       }
+
+       /*
+        * Perform the actual read
+        */
+       efi_status = uefi_call_wrapper(grub->Read, 3, grub, &buffersize,
+                                      *data);
+
+       if (efi_status == EFI_BUFFER_TOO_SMALL) {
+               FreePool(*data);
+               *data = AllocatePool(buffersize);
+               efi_status = uefi_call_wrapper(grub->Read, 3, grub,
+                                              &buffersize, *data);
+       }
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Unexpected return from initial read: %r, buffersize %x\n", efi_status, buffersize);
+               goto error;
+       }
+
+       *datasize = buffersize;
+
+       FreePool(fileinfo);
+
+       return EFI_SUCCESS;
+error:
+       if (*data) {
+               FreePool(*data);
+               *data = NULL;
+       }
+
+       if (fileinfo)
+               FreePool(fileinfo);
+       return efi_status;
+}
+
+/*
+ * Protocol entry point. If secure boot is enabled, verify that the provided
+ * buffer is signed with a trusted key.
+ */
+EFI_STATUS shim_verify (void *buffer, UINT32 size)
+{
+       EFI_STATUS status = EFI_SUCCESS;
+       PE_COFF_LOADER_IMAGE_CONTEXT context;
+
+       loader_is_participating = 1;
+       in_protocol = 1;
+
+       if (!secure_mode())
+               goto done;
+
+       status = read_header(buffer, size, &context);
+       if (status != EFI_SUCCESS)
+               goto done;
+
+       status = verify_buffer(buffer, size, &context);
+done:
+       in_protocol = 0;
+       return status;
+}
+
+static EFI_STATUS shim_hash (char *data, int datasize,
+                            PE_COFF_LOADER_IMAGE_CONTEXT *context,
+                            UINT8 *sha256hash, UINT8 *sha1hash)
+{
+       EFI_STATUS status;
+
+       in_protocol = 1;
+       status = generate_hash(data, datasize, context, sha256hash, sha1hash);
+       in_protocol = 0;
+
+       return status;
+}
+
+static EFI_STATUS shim_read_header(void *data, unsigned int datasize,
+                                  PE_COFF_LOADER_IMAGE_CONTEXT *context)
+{
+       EFI_STATUS status;
+
+       in_protocol = 1;
+       status = read_header(data, datasize, context);
+       in_protocol = 0;
+
+       return status;
+}
+
+/*
+ * Load and run an EFI executable
+ */
+EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
+{
+       EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
+       EFI_STATUS efi_status;
+       EFI_LOADED_IMAGE *li, li_bak;
+       CHAR16 *PathName = NULL;
+       void *sourcebuffer = NULL;
+       UINT64 sourcesize = 0;
+       void *data = NULL;
+       int datasize;
+
+       /*
+        * We need to refer to the loaded image protocol on the running
+        * binary in order to find our path
+        */
+       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+                                      &loaded_image_protocol, (void **)&li);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Unable to init protocol\n");
+               return efi_status;
+       }
+
+       /*
+        * Build a new path from the existing one plus the executable name
+        */
+       efi_status = generate_path(li, ImagePath, &PathName);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Unable to generate path %s: %r\n", ImagePath, efi_status);
+               goto done;
+       }
+
+       if (findNetboot(li->DeviceHandle)) {
+               efi_status = parseNetbootinfo(image_handle);
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Netboot parsing failed: %r\n", efi_status);
+                       return EFI_PROTOCOL_ERROR;
+               }
+               efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
+                                              &sourcesize);
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Unable to fetch TFTP image: %r\n", efi_status);
+                       return efi_status;
+               }
+               data = sourcebuffer;
+               datasize = sourcesize;
+#if  defined(ENABLE_HTTPBOOT)
+       } else if (find_httpboot(li->DeviceHandle)) {
+               efi_status = httpboot_fetch_buffer (image_handle, &sourcebuffer,
+                                                   &sourcesize);
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Unable to fetch HTTP image: %r\n", efi_status);
+                       return efi_status;
+               }
+               data = sourcebuffer;
+               datasize = sourcesize;
+#endif
+       } else {
+               /*
+                * Read the new executable off disk
+                */
+               efi_status = load_image(li, &data, &datasize, PathName);
+
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Failed to load image %s: %r\n", PathName, efi_status);
+                       goto done;
+               }
+       }
+
+       /* Measure the binary into the TPM */
+       tpm_log_event((EFI_PHYSICAL_ADDRESS)data, datasize, 9,
+                     (CHAR8 *)"Second stage bootloader");
+
+       /*
+        * We need to modify the loaded image protocol entry before running
+        * the new binary, so back it up
+        */
+       CopyMem(&li_bak, li, sizeof(li_bak));
+
+       /*
+        * Verify and, if appropriate, relocate and execute the executable
+        */
+       efi_status = handle_image(data, datasize, li);
+
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to load image: %r\n", efi_status);
+               CopyMem(li, &li_bak, sizeof(li_bak));
+               goto done;
+       }
+
+       loader_is_participating = 0;
+
+       /*
+        * The binary is trusted and relocated. Run it
+        */
+       efi_status = uefi_call_wrapper(entry_point, 2, image_handle, systab);
+
+       /*
+        * Restore our original loaded image values
+        */
+       CopyMem(li, &li_bak, sizeof(li_bak));
+done:
+       if (PathName)
+               FreePool(PathName);
+
+       if (data)
+               FreePool(data);
+
+       return efi_status;
+}
+
+/*
+ * Load and run grub. If that fails because grub isn't trusted, load and
+ * run MokManager.
+ */
+EFI_STATUS init_grub(EFI_HANDLE image_handle)
+{
+       EFI_STATUS efi_status;
+       int use_fb = should_use_fallback(image_handle);
+
+       efi_status = start_image(image_handle, use_fb ? FALLBACK :second_stage);
+
+       if (efi_status == EFI_SECURITY_VIOLATION) {
+               efi_status = start_image(image_handle, MOK_MANAGER);
+               if (efi_status != EFI_SUCCESS) {
+                       Print(L"start_image() returned %r\n", efi_status);
+                       uefi_call_wrapper(BS->Stall, 1, 2000000);
+                       return efi_status;
+               }
+
+               efi_status = start_image(image_handle,
+                                        use_fb ? FALLBACK : second_stage);
+       }
+
+       if (efi_status != EFI_SUCCESS) {
+               Print(L"start_image() returned %r\n", efi_status);
+               uefi_call_wrapper(BS->Stall, 1, 2000000);
+       }
+
+       return efi_status;
+}
+
+/*
+ * Measure some of the MOK variables into the TPM
+ */
+EFI_STATUS measure_mok()
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       UINT8 *Data = NULL;
+       UINTN DataSize = 0;
+
+       efi_status = get_variable(L"MokList", &Data, &DataSize, shim_lock_guid);
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       efi_status = tpm_log_event((EFI_PHYSICAL_ADDRESS)Data, DataSize, 14,
+                                  (CHAR8 *)"MokList");
+
+       FreePool(Data);
+
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       efi_status = get_variable(L"MokSBState", &Data, &DataSize,
+                                 shim_lock_guid);
+
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       efi_status = tpm_log_event((EFI_PHYSICAL_ADDRESS)Data, DataSize, 14,
+                                  (CHAR8 *)"MokSBState");
+
+       FreePool(Data);
+
+       return efi_status;
+}
+
+/*
+ * Copy the boot-services only MokList variable to the runtime-accessible
+ * MokListRT variable. It's not marked NV, so the OS can't modify it.
+ */
+EFI_STATUS mirror_mok_list()
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       UINT8 *Data = NULL;
+       UINTN DataSize = 0;
+       void *FullData = NULL;
+       UINTN FullDataSize = 0;
+       EFI_SIGNATURE_LIST *CertList = NULL;
+       EFI_SIGNATURE_DATA *CertData = NULL;
+       uint8_t *p = NULL;
+
+       efi_status = get_variable(L"MokList", &Data, &DataSize, shim_lock_guid);
+       if (efi_status != EFI_SUCCESS)
+               DataSize = 0;
+
+       if (vendor_cert_size) {
+               FullDataSize = DataSize
+                            + sizeof (*CertList)
+                            + sizeof (EFI_GUID)
+                            + vendor_cert_size
+                            ;
+               FullData = AllocatePool(FullDataSize);
+               if (!FullData) {
+                       perror(L"Failed to allocate space for MokListRT\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+               p = FullData;
+
+               if (efi_status == EFI_SUCCESS && DataSize > 0) {
+                       CopyMem(p, Data, DataSize);
+                       p += DataSize;
+               }
+               CertList = (EFI_SIGNATURE_LIST *)p;
+               p += sizeof (*CertList);
+               CertData = (EFI_SIGNATURE_DATA *)p;
+               p += sizeof (EFI_GUID);
+
+               CertList->SignatureType = EFI_CERT_X509_GUID;
+               CertList->SignatureListSize = vendor_cert_size
+                                             + sizeof (*CertList)
+                                             + sizeof (*CertData)
+                                             -1;
+               CertList->SignatureHeaderSize = 0;
+               CertList->SignatureSize = vendor_cert_size + sizeof (EFI_GUID);
+
+               CertData->SignatureOwner = SHIM_LOCK_GUID;
+               CopyMem(p, vendor_cert, vendor_cert_size);
+       } else {
+               FullDataSize = DataSize;
+               FullData = Data;
+       }
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokListRT",
+                                      &shim_lock_guid,
+                                      EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                      | EFI_VARIABLE_RUNTIME_ACCESS,
+                                      FullDataSize, FullData);
+       if (efi_status != EFI_SUCCESS) {
+               perror(L"Failed to set MokListRT: %r\n", efi_status);
+       }
+
+       return efi_status;
+}
+
+/*
+ * Copy the boot-services only MokListX variable to the runtime-accessible
+ * MokListXRT variable. It's not marked NV, so the OS can't modify it.
+ */
+EFI_STATUS mirror_mok_list_x()
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       UINT8 *Data = NULL;
+       UINTN DataSize = 0;
+
+       efi_status = get_variable(L"MokListX", &Data, &DataSize, shim_lock_guid);
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokListXRT",
+                                      &shim_lock_guid,
+                                      EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                      | EFI_VARIABLE_RUNTIME_ACCESS,
+                                      DataSize, Data);
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Failed to set MokListRT", efi_status);
+       }
+
+       return efi_status;
+}
+
+/*
+ * Copy the boot-services only MokSBState variable to the runtime-accessible
+ * MokSBStateRT variable. It's not marked NV, so the OS can't modify it.
+ */
+EFI_STATUS mirror_mok_sb_state()
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+       UINT8 *Data = NULL;
+       UINTN DataSize = 0;
+
+       efi_status = get_variable(L"MokSBState", &Data, &DataSize, shim_lock_guid);
+       if (efi_status != EFI_SUCCESS)
+               return efi_status;
+
+       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokSBStateRT",
+                                      &shim_lock_guid,
+                                      EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                      | EFI_VARIABLE_RUNTIME_ACCESS,
+                                      DataSize, Data);
+       if (efi_status != EFI_SUCCESS) {
+               console_error(L"Failed to set MokSBStateRT", efi_status);
+       }
+
+       return efi_status;
+}
+
+/*
+ * Check if a variable exists
+ */
+static BOOLEAN check_var(CHAR16 *varname)
+{
+       EFI_STATUS efi_status;
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       UINTN size = sizeof(UINT32);
+       UINT32 MokVar;
+       UINT32 attributes;
+
+       efi_status = uefi_call_wrapper(RT->GetVariable, 5, varname,
+                                      &shim_lock_guid, &attributes,
+                                      &size, (void *)&MokVar);
+
+       if (efi_status == EFI_SUCCESS || efi_status == EFI_BUFFER_TOO_SMALL)
+               return TRUE;
+
+       return FALSE;
+}
+
+/*
+ * If the OS has set any of these variables we need to drop into MOK and
+ * handle them appropriately
+ */
+EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
+{
+       EFI_STATUS efi_status;
+
+       if (check_var(L"MokNew") || check_var(L"MokSB") ||
+           check_var(L"MokPW") || check_var(L"MokAuth") ||
+           check_var(L"MokDel") || check_var(L"MokDB") ||
+           check_var(L"MokXNew") || check_var(L"MokXDel") ||
+           check_var(L"MokXAuth")) {
+               efi_status = start_image(image_handle, MOK_MANAGER);
+
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Failed to start MokManager: %r\n", efi_status);
+                       return efi_status;
+               }
+       }
+
+       return EFI_SUCCESS;
+}
+
+/*
+ * Verify that MokSBState is valid, and if appropriate set insecure mode
+ */
+static EFI_STATUS check_mok_sb (void)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS status = EFI_SUCCESS;
+       UINT8 MokSBState;
+       UINTN MokSBStateSize = sizeof(MokSBState);
+       UINT32 attributes;
+
+       user_insecure_mode = 0;
+       ignore_db = 0;
+
+       status = uefi_call_wrapper(RT->GetVariable, 5, L"MokSBState", &shim_lock_guid,
+                                  &attributes, &MokSBStateSize, &MokSBState);
+       if (status != EFI_SUCCESS)
+               return EFI_ACCESS_DENIED;
+
+       /*
+        * Delete and ignore the variable if it's been set from or could be
+        * modified by the OS
+        */
+       if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+               perror(L"MokSBState is compromised! Clearing it\n");
+               if (LibDeleteVariable(L"MokSBState", &shim_lock_guid) != EFI_SUCCESS) {
+                       perror(L"Failed to erase MokSBState\n");
+               }
+               status = EFI_ACCESS_DENIED;
+       } else {
+               if (MokSBState == 1) {
+                       user_insecure_mode = 1;
+               }
+       }
+
+       return status;
+}
+
+/*
+ * Verify that MokDBState is valid, and if appropriate set ignore db mode
+ */
+
+static EFI_STATUS check_mok_db (void)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS status = EFI_SUCCESS;
+       UINT8 MokDBState;
+       UINTN MokDBStateSize = sizeof(MokDBState);
+       UINT32 attributes;
+
+       status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDBState", &shim_lock_guid,
+                                  &attributes, &MokDBStateSize, &MokDBState);
+       if (status != EFI_SUCCESS)
+               return EFI_ACCESS_DENIED;
+
+       ignore_db = 0;
+
+       /*
+        * Delete and ignore the variable if it's been set from or could be
+        * modified by the OS
+        */
+       if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+               perror(L"MokDBState is compromised! Clearing it\n");
+               if (LibDeleteVariable(L"MokDBState", &shim_lock_guid) != EFI_SUCCESS) {
+                       perror(L"Failed to erase MokDBState\n");
+               }
+               status = EFI_ACCESS_DENIED;
+       } else {
+               if (MokDBState == 1) {
+                       ignore_db = 1;
+               }
+       }
+
+       return status;
+}
+
+static EFI_STATUS mok_ignore_db()
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status = EFI_SUCCESS;
+       UINT8 Data = 1;
+       UINTN DataSize = sizeof(UINT8);
+
+       check_mok_db();
+
+       if (ignore_db) {
+               efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokIgnoreDB",
+                               &shim_lock_guid,
+                               EFI_VARIABLE_BOOTSERVICE_ACCESS
+                               | EFI_VARIABLE_RUNTIME_ACCESS,
+                               DataSize, (void *)&Data);
+               if (efi_status != EFI_SUCCESS) {
+                       perror(L"Failed to set MokIgnoreDB: %r\n", efi_status);
+               }
+       }
+
+       return efi_status;
+
+}
+
+EFI_GUID bds_guid = { 0x8108ac4e, 0x9f11, 0x4d59, { 0x85, 0x0e, 0xe2, 0x1a, 0x52, 0x2c, 0x59, 0xb2 } };
+
+static inline EFI_STATUS
+get_load_option_optional_data(UINT8 *data, UINTN data_size,
+                             UINT8 **od, UINTN *ods)
+{
+       /*
+        * If it's not at least Attributes + FilePathListLength +
+        * Description=L"" + 0x7fff0400 (EndEntrireDevicePath), it can't
+        * be valid.
+        */
+       if (data_size < (sizeof(UINT32) + sizeof(UINT16) + 2 + 4))
+               return EFI_INVALID_PARAMETER;
+
+       UINT8 *cur = data + sizeof(UINT32);
+       UINT16 fplistlen = *(UINT16 *)cur;
+       /*
+        * If there's not enough space for the file path list and the
+        * smallest possible description (L""), it's not valid.
+        */
+       if (fplistlen > data_size - (sizeof(UINT32) + 2 + 4))
+               return EFI_INVALID_PARAMETER;
+
+       cur += sizeof(UINT16);
+       UINTN limit = data_size - (cur - data) - fplistlen;
+       UINTN i;
+       for (i = 0; i < limit ; i++) {
+               /* If the description isn't valid UCS2-LE, it's not valid. */
+               if (i % 2 != 0) {
+                       if (cur[i] != 0)
+                               return EFI_INVALID_PARAMETER;
+               } else if (cur[i] == 0) {
+                       /* we've found the end */
+                       i++;
+                       if (i >= limit || cur[i] != 0)
+                               return EFI_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       i++;
+       if (i > limit)
+               return EFI_INVALID_PARAMETER;
+
+       /*
+        * If i is limit, we know the rest of this is the FilePathList and
+        * there's no optional data.  So just bail now.
+        */
+       if (i == limit) {
+               *od = NULL;
+               *ods = 0;
+               return EFI_SUCCESS;
+       }
+
+       cur += i;
+       limit -= i;
+       limit += fplistlen;
+       i = 0;
+       while (limit - i >= 4) {
+               struct {
+                       UINT8 type;
+                       UINT8 subtype;
+                       UINT16 len;
+               } dp = {
+                       .type = cur[i],
+                       .subtype = cur[i+1],
+                       /*
+                        * it's a little endian UINT16, but we're not
+                        * guaranteed alignment is sane, so we can't just
+                        * typecast it directly.
+                        */
+                       .len = (cur[i+3] << 8) | cur[i+2],
+               };
+
+               /*
+                * We haven't found an EndEntire, so this has to be a valid
+                * EFI_DEVICE_PATH in order for the data to be valid.  That
+                * means it has to fit, and it can't be smaller than 4 bytes.
+                */
+               if (dp.len < 4 || dp.len > limit)
+                       return EFI_INVALID_PARAMETER;
+
+               /*
+                * see if this is an EndEntire node...
+                */
+               if (dp.type == 0x7f && dp.subtype == 0xff) {
+                       /*
+                        * if we've found the EndEntire node, it must be 4
+                        * bytes
+                        */
+                       if (dp.len != 4)
+                               return EFI_INVALID_PARAMETER;
+
+                       i += dp.len;
+                       break;
+               }
+
+               /*
+                * It's just some random DP node; skip it.
+                */
+               i += dp.len;
+       }
+       if (i != fplistlen)
+               return EFI_INVALID_PARAMETER;
+
+       /*
+        * if there's any space left, it's "optional data"
+        */
+       *od = cur + i;
+       *ods = limit - i;
+       return EFI_SUCCESS;
+}
+
+/*
+ * Check the load options to specify the second stage loader
+ */
+EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
+{
+       EFI_STATUS status;
+       EFI_LOADED_IMAGE *li;
+       CHAR16 *start = NULL;
+       int remaining_size = 0;
+       CHAR16 *loader_str = NULL;
+       UINTN loader_len = 0;
+       unsigned int i;
+
+       second_stage = DEFAULT_LOADER;
+       load_options = NULL;
+       load_options_size = 0;
+
+       status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+                                  &LoadedImageProtocol, (void **) &li);
+       if (status != EFI_SUCCESS) {
+               perror (L"Failed to get load options: %r\n", status);
+               return status;
+       }
+
+       /* So, load options are a giant pain in the ass.  If we're invoked
+        * from the EFI shell, we get something like this:
+
+00000000  5c 00 45 00 36 00 49 00  5c 00 66 00 65 00 64 00  |\.E.F.I.\.f.e.d.|
+00000010  6f 00 72 00 61 00 5c 00  73 00 68 00 69 00 6d 00  |o.r.a.\.s.h.i.m.|
+00000020  78 00 36 00 34 00 2e 00  64 00 66 00 69 00 20 00  |x.6.4...e.f.i. .|
+00000030  5c 00 45 00 46 00 49 00  5c 00 66 00 65 00 64 00  |\.E.F.I.\.f.e.d.|
+00000040  6f 00 72 00 61 00 5c 00  66 00 77 00 75 00 70 00  |o.r.a.\.f.w.u.p.|
+00000050  64 00 61 00 74 00 65 00  2e 00 65 00 66 00 20 00  |d.a.t.e.e.f.i. .|
+00000060  00 00 66 00 73 00 30 00  3a 00 5c 00 00 00        |..f.s.0.:.\...|
+
+       *
+       * which is just some paths rammed together separated by a UCS-2 NUL.
+       * But if we're invoked from BDS, we get something more like:
+       *
+
+00000000  01 00 00 00 62 00 4c 00  69 00 6e 00 75 00 78 00  |....b.L.i.n.u.x.|
+00000010  20 00 46 00 69 00 72 00  6d 00 77 00 61 00 72 00  | .F.i.r.m.w.a.r.|
+00000020  65 00 20 00 55 00 70 00  64 00 61 00 74 00 65 00  |e. .U.p.d.a.t.e.|
+00000030  72 00 00 00 40 01 2a 00  01 00 00 00 00 08 00 00  |r.....*.........|
+00000040  00 00 00 00 00 40 06 00  00 00 00 00 1a 9e 55 bf  |.....@........U.|
+00000050  04 57 f2 4f b4 4a ed 26  4a 40 6a 94 02 02 04 04  |.W.O.:.&J@j.....|
+00000060  34 00 5c 00 45 00 46 00  49 00 5c 00 66 00 65 00  |4.\.E.F.I.f.e.d.|
+00000070  64 00 6f 00 72 00 61 00  5c 00 73 00 68 00 69 00  |o.r.a.\.s.h.i.m.|
+00000080  6d 00 78 00 36 00 34 00  2e 00 65 00 66 00 69 00  |x.6.4...e.f.i...|
+00000090  00 00 7f ff 40 00 20 00  5c 00 66 00 77 00 75 00  |...... .\.f.w.u.|
+000000a0  70 00 78 00 36 00 34 00  2e 00 65 00 66 00 69 00  |p.x.6.4...e.f.i.|
+000000b0  00 00                                             |..|
+
+       *
+       * which is clearly an EFI_LOAD_OPTION filled in halfway reasonably.
+       * In short, the UEFI shell is still a useless piece of junk.
+       *
+       * But then on some versions of BDS, we get:
+
+00000000  5c 00 66 00 77 00 75 00  70 00 78 00 36 00 34 00  |\.f.w.u.p.x.6.4.|
+00000010  2e 00 65 00 66 00 69 00  00 00                    |..e.f.i...|
+0000001a
+
+       * which as you can see is one perfectly normal UCS2-EL string
+       * containing the load option from the Boot#### variable.
+       *
+       * We also sometimes find a guid or partial guid at the end, because
+       * BDS will add that, but we ignore that here.
+       */
+
+       /*
+        * In either case, we've got to have at least a UCS2 NUL...
+        */
+       if (li->LoadOptionsSize < 2)
+               return EFI_BAD_BUFFER_SIZE;
+
+       /*
+        * Some awesome versions of BDS will add entries for Linux.  On top
+        * of that, some versions of BDS will "tag" any Boot#### entries they
+        * create by putting a GUID at the very end of the optional data in
+        * the EFI_LOAD_OPTIONS, thus screwing things up for everybody who
+        * tries to actually *use* the optional data for anything.  Why they
+        * did this instead of adding a flag to the spec to /say/ it's
+        * created by BDS, I do not know.  For shame.
+        *
+        * Anyway, just nerf that out from the start.  It's always just
+        * garbage at the end.
+        */
+       if (li->LoadOptionsSize > 16) {
+               if (CompareGuid((EFI_GUID *)(li->LoadOptions
+                                            + (li->LoadOptionsSize - 16)),
+                               &bds_guid) == 0)
+                       li->LoadOptionsSize -= 16;
+       }
+
+       /*
+        * Check and see if this is just a list of strings.  If it's an
+        * EFI_LOAD_OPTION, it'll be 0, since we know EndEntire device path
+        * won't pass muster as UCS2-LE.
+        *
+        * If there are 3 strings, we're launched from the shell most likely,
+        * But we actually only care about the second one.
+        */
+       UINTN strings = count_ucs2_strings(li->LoadOptions,
+                                          li->LoadOptionsSize);
+       /*
+        * If it's not string data, try it as an EFI_LOAD_OPTION.
+        */
+       if (strings == 0) {
+               /*
+                * We at least didn't find /enough/ strings.  See if it works
+                * as an EFI_LOAD_OPTION.
+                */
+               status = get_load_option_optional_data(li->LoadOptions,
+                                                      li->LoadOptionsSize,
+                                                      (UINT8 **)&start,
+                                                      &loader_len);
+               if (status != EFI_SUCCESS)
+                       return EFI_SUCCESS;
+
+               remaining_size = 0;
+       } else if (strings >= 2) {
+               /*
+                * UEFI shell copies the whole line of the command into
+                * LoadOptions.  We ignore the string before the first L' ',
+                * i.e. the name of this program.
+                * Counting by two bytes is safe, because we know the size is
+                * compatible with a UCS2-LE string.
+                */
+               UINT8 *cur = li->LoadOptions;
+               for (i = 0; i < li->LoadOptionsSize - 2; i += 2) {
+                       CHAR16 c = (cur[i+1] << 8) | cur[i];
+                       if (c == L' ') {
+                               start = (CHAR16 *)&cur[i+2];
+                               remaining_size = li->LoadOptionsSize - i - 2;
+                               break;
+                       }
+               }
+
+               if (!start || remaining_size <= 0 || start[0] == L'\0')
+                       return EFI_SUCCESS;
+
+               for (i = 0; start[i] != '\0'; i++) {
+                       if (start[i] == L' ')
+                               start[i] = L'\0';
+                       if (start[i] == L'\0') {
+                               loader_len = 2 * i + 2;
+                               break;
+                       }
+               }
+               if (loader_len)
+                       remaining_size -= loader_len;
+       } else {
+               /* only find one string */
+               start = li->LoadOptions;
+               loader_len = li->LoadOptionsSize;
+       }
+
+       /*
+        * Just to be sure all that math is right...
+        */
+       if (loader_len % 2 != 0)
+               return EFI_INVALID_PARAMETER;
+
+       strings = count_ucs2_strings((UINT8 *)start, loader_len);
+       if (strings < 1)
+               return EFI_SUCCESS;
+
+       /*
+        * Set up the name of the alternative loader and the LoadOptions for
+        * the loader
+        */
+       if (loader_len > 0) {
+               loader_str = AllocatePool(loader_len);
+               if (!loader_str) {
+                       perror(L"Failed to allocate loader string\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+
+               for (i = 0; i < loader_len / 2; i++)
+                       loader_str[i] = start[i];
+               loader_str[loader_len/2-1] = L'\0';
+
+               second_stage = loader_str;
+               load_options = remaining_size ? start + loader_len : NULL;
+               load_options_size = remaining_size;
+       }
+
+       return EFI_SUCCESS;
+}
+
+static SHIM_LOCK shim_lock_interface;
+static EFI_HANDLE shim_lock_handle;
+
+EFI_STATUS
+install_shim_protocols(void)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+       EFI_STATUS efi_status;
+
+       if (!secure_mode())
+               return EFI_SUCCESS;
+
+       /*
+        * Install the protocol
+        */
+       efi_status = uefi_call_wrapper(BS->InstallProtocolInterface, 4,
+                         &shim_lock_handle, &shim_lock_guid,
+                         EFI_NATIVE_INTERFACE, &shim_lock_interface);
+       if (EFI_ERROR(efi_status)) {
+               console_error(L"Could not install security protocol",
+                             efi_status);
+               return efi_status;
+       }
+
+#if defined(OVERRIDE_SECURITY_POLICY)
+       /*
+        * Install the security protocol hook
+        */
+       security_policy_install(shim_verify);
+#endif
+
+       return EFI_SUCCESS;
+}
+
+void
+uninstall_shim_protocols(void)
+{
+       EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+
+       if (!secure_mode())
+               return;
+
+#if defined(OVERRIDE_SECURITY_POLICY)
+       /*
+        * Clean up the security protocol hook
+        */
+       security_policy_uninstall();
+#endif
+
+       /*
+        * If we're back here then clean everything up before exiting
+        */
+       uefi_call_wrapper(BS->UninstallProtocolInterface, 3, shim_lock_handle,
+                         &shim_lock_guid, &shim_lock_interface);
+}
+
+EFI_STATUS
+shim_init(void)
+{
+       EFI_STATUS status = EFI_SUCCESS;
+       setup_console(1);
+       setup_verbosity();
+       dprinta(shim_version);
+
+       /* Set the second stage loader */
+       set_second_stage (image_handle);
+
+       if (secure_mode()) {
+               if (vendor_cert_size || vendor_dbx_size) {
+                       /*
+                        * If shim includes its own certificates then ensure
+                        * that anything it boots has performed some
+                        * validation of the next image.
+                        */
+                       hook_system_services(systab);
+                       loader_is_participating = 0;
+               }
+
+               hook_exit(systab);
+
+               status = install_shim_protocols();
+       }
+       return status;
+}
+
+void
+shim_fini(void)
+{
+       if (secure_mode()) {
+               /*
+                * Remove our protocols
+                */
+               uninstall_shim_protocols();
+
+               /*
+                * Remove our hooks from system services.
+                */
+               unhook_system_services();
+               unhook_exit();
+       }
+
+       /*
+        * Free the space allocated for the alternative 2nd stage loader
+        */
+       if (load_options_size > 0 && second_stage)
+               FreePool(second_stage);
+
+       setup_console(0);
+}
+
+extern EFI_STATUS
+efi_main(EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab);
+
+static void
+__attribute__((__optimize__("0")))
+debug_hook(void)
+{
+       EFI_GUID guid = SHIM_LOCK_GUID;
+       UINT8 *data = NULL;
+       UINTN dataSize = 0;
+       EFI_STATUS efi_status;
+       volatile register UINTN x = 0;
+       extern char _text, _data;
+
+       if (x)
+               return;
+
+       efi_status = get_variable(L"SHIM_DEBUG", &data, &dataSize, guid);
+       if (EFI_ERROR(efi_status)) {
+               return;
+       }
+
+       Print(L"add-symbol-file "DEBUGDIR
+             L"shim" EFI_ARCH L".efi.debug 0x%08x -s .data 0x%08x\n", &_text,
+             &_data);
+
+       Print(L"Pausing for debugger attachment.\n");
+       Print(L"To disable this, remove the EFI variable SHIM_DEBUG-%g .\n",
+             &guid);
+       x = 1;
+       while (x++) {
+               /* Make this so it can't /totally/ DoS us. */
+#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
+               if (x > 4294967294ULL)
+                       break;
+               __asm__ __volatile__("pause");
+#elif defined(__aarch64__)
+               if (x > 1000)
+                       break;
+               __asm__ __volatile__("wfi");
+#else
+               if (x > 12000)
+                       break;
+               uefi_call_wrapper(BS->Stall, 1, 5000);
+#endif
+       }
+       x = 1;
+}
+
+EFI_STATUS
+efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
+{
+       EFI_STATUS efi_status;
+
+       verification_method = VERIFIED_BY_NOTHING;
+
+       vendor_cert_size = cert_table.vendor_cert_size;
+       vendor_dbx_size = cert_table.vendor_dbx_size;
+       vendor_cert = (UINT8 *)&cert_table + cert_table.vendor_cert_offset;
+       vendor_dbx = (UINT8 *)&cert_table + cert_table.vendor_dbx_offset;
+
+       /*
+        * Set up the shim lock protocol so that grub and MokManager can
+        * call back in and use shim functions
+        */
+       shim_lock_interface.Verify = shim_verify;
+       shim_lock_interface.Hash = shim_hash;
+       shim_lock_interface.Context = shim_read_header;
+
+       systab = passed_systab;
+       image_handle = passed_image_handle;
+
+       /*
+        * Ensure that gnu-efi functions are available
+        */
+       InitializeLib(image_handle, systab);
+
+       /*
+        * if SHIM_DEBUG is set, wait for a debugger to attach.
+        */
+       debug_hook();
+
+       /*
+        * Measure the MOK variables
+        */
+       efi_status = measure_mok();
+       if (efi_status != EFI_SUCCESS && efi_status != EFI_NOT_FOUND) {
+               Print(L"Something has gone seriously wrong: %r\n", efi_status);
+               Print(L"Shim was unable to measure state into the TPM\n");
+               systab->BootServices->Stall(5000000);
+               systab->RuntimeServices->ResetSystem(EfiResetShutdown,
+                                                    EFI_SECURITY_VIOLATION,
+                                                    0, NULL);
+       }
+
+       /*
+        * Check whether the user has configured the system to run in
+        * insecure mode
+        */
+       check_mok_sb();
+
+       efi_status = shim_init();
+       if (EFI_ERROR(efi_status)) {
+               Print(L"Something has gone seriously wrong: %r\n", efi_status);
+               Print(L"shim cannot continue, sorry.\n");
+               uefi_call_wrapper(BS->Stall, 1, 5000000);
+               uefi_call_wrapper(systab->RuntimeServices->ResetSystem, 4,
+                                 EfiResetShutdown, EFI_SECURITY_VIOLATION,
+                                 0, NULL);
+       }
+
+       /*
+        * Tell the user that we're in insecure mode if necessary
+        */
+       if (user_insecure_mode) {
+               Print(L"Booting in insecure mode\n");
+               uefi_call_wrapper(BS->Stall, 1, 2000000);
+       }
+
+       /*
+        * Enter MokManager if necessary
+        */
+       efi_status = check_mok_request(image_handle);
+
+       /*
+        * Copy the MOK list to a runtime variable so the kernel can
+        * make use of it
+        */
+       efi_status = mirror_mok_list();
+
+       efi_status = mirror_mok_list_x();
+
+       /*
+        * Copy the MOK SB State to a runtime variable so the kernel can
+        * make use of it
+        */
+       efi_status = mirror_mok_sb_state();
+
+       /*
+        * Create the runtime MokIgnoreDB variable so the kernel can
+        * make use of it
+        */
+       efi_status = mok_ignore_db();
+
+       /*
+        * Hand over control to the second stage bootloader
+        */
+       efi_status = init_grub(image_handle);
+
+       shim_fini();
+       return efi_status;
+}
diff --git a/shim.h b/shim.h
new file mode 100644 (file)
index 0000000..52cbfeb
--- /dev/null
+++ b/shim.h
@@ -0,0 +1,39 @@
+#include "PeImage.h"
+
+extern EFI_GUID SHIM_LOCK_GUID;
+
+INTERFACE_DECL(_SHIM_LOCK);
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_VERIFY) (
+       IN VOID *buffer,
+       IN UINT32 size
+       );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_HASH) (
+       IN char *data,
+       IN int datasize,
+       PE_COFF_LOADER_IMAGE_CONTEXT *context,
+       UINT8 *sha256hash,
+       UINT8 *sha1hash
+       );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_CONTEXT) (
+       IN VOID *data,
+       IN unsigned int datasize,
+       PE_COFF_LOADER_IMAGE_CONTEXT *context
+       );
+
+typedef struct _SHIM_LOCK {
+       EFI_SHIM_LOCK_VERIFY Verify;
+       EFI_SHIM_LOCK_HASH Hash;
+       EFI_SHIM_LOCK_CONTEXT Context;
+} SHIM_LOCK;
+
+extern EFI_STATUS shim_init(void);
+extern void shim_fini(void);
diff --git a/testplan.txt b/testplan.txt
new file mode 100644 (file)
index 0000000..0b0569e
--- /dev/null
@@ -0,0 +1,87 @@
+How to test a new shim build for RHEL/fedora:
+
+1) build pesign-test-app, and sign it with the appropriate key
+2) build shim with the appropriate key built in
+3) install pesign-test-app and shim-unsigned on the test machine
+4) make a lockdown.efi for "Red Hat Test Certificate" and put it in \EFI\test
+   mkdir /boot/efi/EFI/test/
+   wget http://pjones.fedorapeople.org/shim/LockDown-rhtest.efi
+   mv LockDown-rhtest.efi /boot/efi/EFI/test/lockdown.efi
+5) sign shim with RHTC and put it in \EFI\test:
+   pesign -i /usr/share/shim/shim.efi -o /boot/efi/EFI/test/shim.efi \
+        -s -c "Red Hat Test Certificate"
+6) put pesign-test-app-signed.efi in \EFI\test as grubx64.efi
+   cp /usr/share/pesign-test-app-0.4/pesign-test-app-signed.efi \
+       /boot/efi/EFI/test/grubx64.efi
+7) sign a copy of grubx64.efi with RHTC and iput it in \EFI\test\ .  Also
+   leave an unsigned copy there:
+    pesign -i /boot/efi/EFI/redhat/grubx64.efi \
+       -o /boot/efi/EFI/test/grubx64-unsigned.efi \
+       -r -u 0
+    pesign -i /boot/efi/EFI/test/grubx64-unsigned.efi \
+       -o /boot/efi/EFI/test/grub.efi \
+       -s -c "Red Hat Test Certificate"
+8) sign a copy of mokmanager with RHTC and put it in \EFI\test:
+    pesign -i /usr/share/shim/MokManager.efi \
+       -o /boot/efi/EFI/test/MokManager.efi -s \
+       -c "Red Hat Test Certificate"
+9) copy grub.cfg to our test directory:
+    cp /boot/efi/EFI/redhat/grub.cfg /boot/efi/EFI/test/grub.cfg
+10) *move* \EFI\redhat\BOOT.CSV to \EFI\test 
+    rm -rf /boot/efi/EFI/BOOT/
+    mkdir /boot/efi/EFI/BOOT/
+    mv /boot/efi/EFI/redhat/BOOT.CSV /boot/efi/EFI/test/BOOT.CSV
+11) sign a copy of fallback.efi and put it in \EFI\BOOT\fallback.efi
+    pesign -i /usr/share/shim/fallback.efi \
+       -o /boot/efi/EFI/BOOT/fallback.efi \
+       -s -c "Red Hat Test Certificate"
+12) put shim.efi there as well
+    cp /boot/efi/EFI/test/shim.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
+13) enroll the current kernel's certificate with mokutil:
+    # this should be a /different/ cert than the one signing pesign-test-app.
+    # for instance use a RHEL cert for p-t-a and a fedora cert+kernel here.
+    mokutil --import ~/fedora-ca.cer
+14) put machine in setup mode
+15) boot to the UEFI shell
+16) run lockdown.efi from #4:
+    fs0:\EFI\test\lockdown.efi
+17) enable secure boot verification
+18) verify it can't run other binaries:
+    fs0:\EFI\test\grubx64.efi
+    result should be an error, probably similar to:
+    "fs0:\...\grubx64.efi is not recognized as an internal or external command"
+19) in the EFI shell, run fs0:\EFI\test\shim.efi
+20) you should see MokManager.  Enroll the certificate you added in #13, and
+    the system will reboot.
+21) reboot to the UEFI shell and run fs0:\EFI\test\shim.efi
+    result: "This is a test application that should be completely safe."
+  If you get the expected result, shim can run things signed by its internal
+  key ring.  Check a box someplace that says it can do that.
+22) from the EFI shell, copy grub to grubx64.efi:
+    cp \EFI\test\grub.efi \EFI\test\grubx64.efi
+23) in the EFI shell, run fs0:\EFI\test\shim.efi
+    result: this should start grub, which will let you boot a kernel
+  If grub starts, it means shim can run things signed by a key in the system's
+  db.  Check a box someplace that says it can do that.
+  If the kernel boots, it means shim can run things from Mok.  Check a box
+  someplace that says it can do that.
+24) remove all boot entries and the BootOrder variable:
+    [root@uefi ~]# cd /sys/firmware/efi/efivars/
+    [root@uefi efivars]# rm -vf Boot[0123456789]* BootOrder-*
+    removed ‘Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c’
+    removed ‘Boot0001-8be4df61-93ca-11d2-aa0d-00e098032b8c’
+    removed ‘Boot0002-8be4df61-93ca-11d2-aa0d-00e098032b8c’
+    removed ‘Boot2001-8be4df61-93ca-11d2-aa0d-00e098032b8c’
+    removed ‘BootOrder-8be4df61-93ca-11d2-aa0d-00e098032b8c’
+    [root@uefi efivars]# 
+25) reboot
+26) the system should run \EFI\BOOT\BOOTX64.EFI .  If it doesn't, you may just
+    have an old machine.  In that case, go to the EFI shell and run:
+    fs0:\EFI\BOOT\BOOTX64.EFI
+  If this works, you should see a bit of output very quickly and then the same
+  thing as #24.  This means shim recognized it was in \EFI\BOOT and ran
+  fallback.efi, which worked.
+27) copy the unsigned grub into place and reboot:
+  cp /boot/efi/EFI/test/grubx64-unsigned.efi /boot/efi/EFI/test/grubx64.efi
+28) reboot again.
+    result: shim should refuse to load grub.
diff --git a/tpm.c b/tpm.c
new file mode 100644 (file)
index 0000000..71bcf9b
--- /dev/null
+++ b/tpm.c
@@ -0,0 +1,127 @@
+#include <efi.h>
+#include <efilib.h>
+#include <string.h>
+
+#include "tpm.h"
+
+extern UINT8 in_protocol;
+
+#define perror(fmt, ...) ({                                             \
+                       UINTN __perror_ret = 0;                               \
+                       if (!in_protocol)                                     \
+                               __perror_ret = Print((fmt), ##__VA_ARGS__);   \
+                       __perror_ret;                                         \
+               })
+
+
+EFI_GUID tpm_guid = EFI_TPM_GUID;
+EFI_GUID tpm2_guid = EFI_TPM2_GUID;
+
+static BOOLEAN tpm_present(efi_tpm_protocol_t *tpm)
+{
+       EFI_STATUS status;
+       TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
+       UINT32 flags;
+       EFI_PHYSICAL_ADDRESS eventlog, lastevent;
+
+       caps.Size = (UINT8)sizeof(caps);
+       status = uefi_call_wrapper(tpm->status_check, 5, tpm, &caps, &flags,
+                                  &eventlog, &lastevent);
+
+       if (status != EFI_SUCCESS || caps.TPMDeactivatedFlag
+           || !caps.TPMPresentFlag)
+               return FALSE;
+
+       return TRUE;
+}
+
+static BOOLEAN tpm2_present(efi_tpm2_protocol_t *tpm)
+{
+       EFI_STATUS status;
+       EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
+       EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *caps_1_0;
+
+       caps.Size = (UINT8)sizeof(caps);
+
+       status = uefi_call_wrapper(tpm->get_capability, 2, tpm, &caps);
+
+       if (status != EFI_SUCCESS)
+               return FALSE;
+
+       if (caps.StructureVersion.Major == 1 &&
+           caps.StructureVersion.Minor == 0) {
+               caps_1_0 = (EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *)&caps;
+               if (caps_1_0->TPMPresentFlag)
+                       return TRUE;
+       } else {
+               if (caps.TPMPresentFlag)
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
+EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
+                        const CHAR8 *description)
+{
+       EFI_STATUS status;
+       efi_tpm_protocol_t *tpm;
+       efi_tpm2_protocol_t *tpm2;
+
+       status = LibLocateProtocol(&tpm2_guid, (VOID **)&tpm2);
+       /* TPM 2.0 */
+       if (status == EFI_SUCCESS) {
+               EFI_TCG2_EVENT *event;
+
+               if (!tpm2_present(tpm2))
+                       return EFI_SUCCESS;
+
+               event = AllocatePool(sizeof(*event) + strlen(description) + 1);
+               if (!event) {
+                       perror(L"Unable to allocate event structure\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+
+               event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
+               event->Header.HeaderVersion = 1;
+               event->Header.PCRIndex = pcr;
+               event->Header.EventType = 0x0d;
+               event->Size = sizeof(*event) - sizeof(event->Event) + strlen(description) + 1;
+               memcpy(event->Event, description, strlen(description) + 1);
+               status = uefi_call_wrapper(tpm2->hash_log_extend_event, 5, tpm2,
+                                          0, buf, (UINT64) size, event);
+               FreePool(event);
+               return status;
+       } else {
+               TCG_PCR_EVENT *event;
+               UINT32 algorithm, eventnum = 0;
+               EFI_PHYSICAL_ADDRESS lastevent;
+
+               status = LibLocateProtocol(&tpm_guid, (VOID **)&tpm);
+
+               if (status != EFI_SUCCESS)
+                       return EFI_SUCCESS;
+
+               if (!tpm_present(tpm))
+                       return EFI_SUCCESS;
+
+               event = AllocatePool(sizeof(*event) + strlen(description) + 1);
+
+               if (!event) {
+                       perror(L"Unable to allocate event structure\n");
+                       return EFI_OUT_OF_RESOURCES;
+               }
+
+               event->PCRIndex = pcr;
+               event->EventType = 0x0d;
+               event->EventSize = strlen(description) + 1;
+               algorithm = 0x00000004;
+               status = uefi_call_wrapper(tpm->log_extend_event, 7, tpm, buf,
+                                          (UINT64)size, algorithm, event,
+                                          &eventnum, &lastevent);
+               FreePool(event);
+               return status;
+       }
+
+       return EFI_SUCCESS;
+}
diff --git a/tpm.h b/tpm.h
new file mode 100644 (file)
index 0000000..2c21b26
--- /dev/null
+++ b/tpm.h
@@ -0,0 +1,145 @@
+#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd }};
+#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }};
+
+EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
+                        const CHAR8 *description);
+
+typedef struct {
+  uint8_t Major;
+  uint8_t Minor;
+  uint8_t RevMajor;
+  uint8_t RevMinor;
+} TCG_VERSION;
+
+typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY {
+  uint8_t          Size;                /// Size of this structure.
+  TCG_VERSION    StructureVersion;
+  TCG_VERSION    ProtocolSpecVersion;
+  uint8_t          HashAlgorithmBitmap; /// Hash algorithms .
+  char        TPMPresentFlag;      /// 00h = TPM not present.
+  char        TPMDeactivatedFlag;  /// 01h = TPM currently deactivated.
+} TCG_EFI_BOOT_SERVICE_CAPABILITY;
+
+typedef struct _TCG_PCR_EVENT {
+  uint32_t PCRIndex;
+  uint32_t EventType;
+  uint8_t digest[20];
+  uint32_t EventSize;
+  uint8_t  Event[1];
+} TCG_PCR_EVENT;
+
+struct efi_tpm_protocol
+{
+  EFI_STATUS (EFIAPI *status_check) (struct efi_tpm_protocol *this,
+                                    TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
+                                    uint32_t *TCGFeatureFlags,
+                                    EFI_PHYSICAL_ADDRESS *EventLogLocation,
+                                    EFI_PHYSICAL_ADDRESS *EventLogLastEntry);
+  EFI_STATUS (EFIAPI *hash_all) (struct efi_tpm_protocol *this,
+                                uint8_t *HashData,
+                                uint64_t HashLen,
+                                uint32_t AlgorithmId,
+                                uint64_t *HashedDataLen,
+                                uint8_t **HashedDataResult);
+  EFI_STATUS (EFIAPI *log_event) (struct efi_tpm_protocol *this,
+                                 TCG_PCR_EVENT *TCGLogData,
+                                 uint32_t *EventNumber,
+                                 uint32_t Flags);
+  EFI_STATUS (EFIAPI *pass_through_to_tpm) (struct efi_tpm_protocol *this,
+                                           uint32_t TpmInputParameterBlockSize,
+                                           uint8_t *TpmInputParameterBlock,
+                                           uint32_t TpmOutputParameterBlockSize,
+                                           uint8_t *TpmOutputParameterBlock);
+  EFI_STATUS (EFIAPI *log_extend_event) (struct efi_tpm_protocol *this,
+                                        EFI_PHYSICAL_ADDRESS HashData,
+                                        uint64_t HashDataLen,
+                                        uint32_t AlgorithmId,
+                                        TCG_PCR_EVENT *TCGLogData,
+                                        uint32_t *EventNumber,
+                                        EFI_PHYSICAL_ADDRESS *EventLogLastEntry);
+};
+
+typedef struct efi_tpm_protocol efi_tpm_protocol_t;
+
+typedef uint32_t EFI_TCG2_EVENT_LOG_BITMAP;
+typedef uint32_t EFI_TCG2_EVENT_LOG_FORMAT;
+typedef uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP;
+
+typedef struct tdEFI_TCG2_VERSION {
+  uint8_t Major;
+  uint8_t Minor;
+} __attribute__ ((packed)) EFI_TCG2_VERSION;
+
+typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 {
+  uint8_t Size;
+  EFI_TCG2_VERSION StructureVersion;
+  EFI_TCG2_VERSION ProtocolVersion;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
+  EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
+  BOOLEAN TPMPresentFlag;
+  uint16_t MaxCommandSize;
+  uint16_t MaxResponseSize;
+  uint32_t ManufacturerID;
+  uint32_t NumberOfPcrBanks;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
+} EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0;
+
+typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
+  uint8_t Size;
+  EFI_TCG2_VERSION StructureVersion;
+  EFI_TCG2_VERSION ProtocolVersion;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
+  EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
+  BOOLEAN TPMPresentFlag;
+  uint16_t MaxCommandSize;
+  uint16_t MaxResponseSize;
+  uint32_t ManufacturerID;
+  uint32_t NumberOfPcrBanks;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
+} __attribute__ ((packed))  EFI_TCG2_BOOT_SERVICE_CAPABILITY;
+
+typedef uint32_t TCG_PCRINDEX;
+typedef uint32_t TCG_EVENTTYPE;
+
+typedef struct tdEFI_TCG2_EVENT_HEADER {
+  uint32_t HeaderSize;
+  uint16_t HeaderVersion;
+  TCG_PCRINDEX PCRIndex;
+  TCG_EVENTTYPE EventType;
+} __attribute__ ((packed)) EFI_TCG2_EVENT_HEADER;
+
+typedef struct tdEFI_TCG2_EVENT {
+  uint32_t Size;
+  EFI_TCG2_EVENT_HEADER Header;
+  uint8_t Event[1];
+} __attribute__ ((packed)) EFI_TCG2_EVENT;
+
+struct efi_tpm2_protocol
+{
+  EFI_STATUS (EFIAPI *get_capability) (struct efi_tpm2_protocol *this,
+                                      EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability);
+  EFI_STATUS (EFIAPI *get_event_log) (struct efi_tpm2_protocol *this,
+                                     EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
+                                     EFI_PHYSICAL_ADDRESS *EventLogLocation,
+                                     EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
+                                     BOOLEAN *EventLogTruncated);
+  EFI_STATUS (EFIAPI *hash_log_extend_event) (struct efi_tpm2_protocol *this,
+                                             uint64_t Flags,
+                                             EFI_PHYSICAL_ADDRESS DataToHash,
+                                             uint64_t DataToHashLen,
+                                             EFI_TCG2_EVENT *EfiTcgEvent);
+  EFI_STATUS (EFIAPI *submit_command) (struct efi_tpm2_protocol *this,
+                                      uint32_t InputParameterBlockSize,
+                                      uint8_t *InputParameterBlock,
+                                      uint32_t OutputParameterBlockSize,
+                                      uint8_t *OutputParameterBlock);
+  EFI_STATUS (EFIAPI *get_active_pcr_blanks) (struct efi_tpm2_protocol *this,
+                                             uint32_t *ActivePcrBanks);
+  EFI_STATUS (EFIAPI *set_active_pcr_banks) (struct efi_tpm2_protocol *this,
+                                            uint32_t ActivePcrBanks);
+  EFI_STATUS (EFIAPI *get_result_of_set_active_pcr_banks) (struct efi_tpm2_protocol *this,
+                                                          uint32_t *OperationPresent,
+                                                          uint32_t *Response);
+};
+
+typedef struct efi_tpm2_protocol efi_tpm2_protocol_t;
diff --git a/ucs2.h b/ucs2.h
new file mode 100644 (file)
index 0000000..010d096
--- /dev/null
+++ b/ucs2.h
@@ -0,0 +1,119 @@
+/*
+ * shim - trivial UEFI first-stage bootloader
+ *
+ * Copyright 2013 Red Hat, Inc <pjones@redhat.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#ifndef SHIM_UCS2_H
+#define SHIM_UCS2_H
+
+static inline INTN
+__attribute__((unused))
+StrCaseCmp(CHAR16 *s0, CHAR16 *s1)
+{
+       CHAR16 c0, c1;
+       while (1) {
+               if (*s0 == L'\0' || *s1 == L'\0')
+                       return *s1 - *s0;
+               c0 = (*s0 >= L'a' && *s0 <= L'z') ? *s0 - 32 : *s0;
+               c1 = (*s1 >= L'a' && *s1 <= L'z') ? *s1 - 32 : *s1;
+               if (c0 != c1)
+                       return c1 - c0;
+               s0++;
+               s1++;
+       }
+       return 0;
+}
+
+static inline INTN
+__attribute__((unused))
+StrnCaseCmp(CHAR16 *s0, CHAR16 *s1, int n)
+{
+       CHAR16 c0, c1;
+       int x = 0;
+       while (n > x++) {
+               if (*s0 == L'\0' || *s1 == L'\0')
+                       return *s1 - *s0;
+               c0 = (*s0 >= L'a' && *s0 <= L'z') ? *s0 - 32 : *s0;
+               c1 = (*s1 >= L'a' && *s1 <= L'z') ? *s1 - 32 : *s1;
+               if (c0 != c1)
+                       return c1 - c0;
+               s0++;
+               s1++;
+       }
+       return 0;
+}
+
+static inline UINTN
+__attribute__((unused))
+StrCSpn(const CHAR16 *s, const CHAR16 *reject)
+{
+       UINTN ret;
+
+       for (ret = 0; s[ret] != L'\0'; ret++) {
+               int i;
+               for (i = 0; reject[i] != L'\0'; i++) {
+                       if (reject[i] == s[ret])
+                               return ret;
+               }
+       }
+       return ret;
+}
+
+static inline UINTN
+__attribute__((__unused__))
+count_ucs2_strings(UINT8 *data, UINTN data_size)
+{
+       UINTN pos = 0;
+       UINTN last_nul_pos = 0;
+       UINTN num_nuls = 0;
+       UINTN i;
+
+       if (data_size % 2 != 0)
+               return 0;
+
+       for (i = pos; i < data_size; i++) {
+               if (i % 2 != 0) {
+                       if (data[i] != 0)
+                               return 0;
+               } else if (data[i] == 0) {
+                       last_nul_pos = i;
+                       num_nuls++;
+               }
+               pos = i;
+       }
+       if (num_nuls > 0 && last_nul_pos != pos - 1)
+               return 0;
+       return num_nuls;
+}
+
+#endif /* SHIM_UCS2_H */
diff --git a/version.c.in b/version.c.in
new file mode 100644 (file)
index 0000000..9e71970
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include "version.h"
+
+CHAR8 shim_version[] = 
+       "UEFI SHIM\n"
+       "$Version: @@VERSION@@ $\n"
+       "$BuildMachine: @@UNAME@@ $\n"
+       "$Commit: @@COMMIT@@ $\n";
diff --git a/version.h b/version.h
new file mode 100644 (file)
index 0000000..7fb3d81
--- /dev/null
+++ b/version.h
@@ -0,0 +1,8 @@
+#ifndef _SHIM_VERSION_H
+#define _SHIM_VERSION_H 1
+
+#include <efi.h>
+
+extern CHAR8 shim_version[];
+
+#endif /* SHIM_VERSION_H */