Fri Sep 19 05:53:49 2008 UTC ()
Pull in some things missed in a previous update.


(wrstuden)
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/Makefile
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_asn1.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_att.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_cd.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_dd.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_enc.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_env.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_err.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_ess.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_io.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_lcl.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_lib.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_sd.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/cms/cms_smime.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/Makefile
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed_cbc.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed_cfb.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed_ecb.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed_locl.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/seed/seed_ofb.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/Makefile
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_asn1.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_conf.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_err.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_lib.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_req_print.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_req_utils.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_rsp_print.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_rsp_sign.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_rsp_utils.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_rsp_verify.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/ts/ts_verify_ctx.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/Makefile
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/whrlpool.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/wp_block.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/wp_dgst.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/wp_locl.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/wp_test.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/asm/wp-mmx.pl
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/crypto/whrlpool/asm/wp-x86_64.pl
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cacert.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cakey.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_ddec.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_dec.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_denc.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_enc.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_uncomp.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/cms_ver.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/comp.txt
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/encr.txt
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/sign.txt
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/signer.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/cms/signer2.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/cacert.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/cakey.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/encr.txt
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/sign.txt
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/signer.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/signer2.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/smdec.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/smenc.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/smsign.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/demos/smime/smsign2.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/Makefile
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/README.gost
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/e_gost_err.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/e_gost_err.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/e_gost_err.proto
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost.ec
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost2001.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost2001_keyx.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost2001_keyx.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost89.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost89.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost94_keyx.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_ameth.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_asn1.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_crypt.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_ctl.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_eng.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_keywrap.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_keywrap.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_lcl.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_md.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_params.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_params.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_pmeth.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gost_sign.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gosthash.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gosthash.h
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/engines/ccgost/gostsum.c
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smdsa1.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smdsa2.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smdsa3.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smdsap.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smroot.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smrsa1.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smrsa2.pem
diff -r0 -r1.1.1.1.4.2 src/crypto/dist/openssl/test/smime-certs/smrsa3.pem

File Added: src/crypto/dist/openssl/crypto/cms/Attic/Makefile
#
# OpenSSL/crypto/cms/Makefile
#

DIR=	cms
TOP=	../..
CC=	cc
INCLUDES= -I.. -I$(TOP) -I../../include
CFLAG=-g
MAKEFILE=	Makefile
AR=		ar r

CFLAGS= $(INCLUDES) $(CFLAG)

GENERAL=Makefile
TEST=
APPS=

LIB=$(TOP)/libcrypto.a
LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
	cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c
LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
	cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o

SRC= $(LIBSRC)

EXHEADER=  cms.h
HEADER=	cms_lcl.h $(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)

top:
	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)

test:

all:	lib

lib:	$(LIBOBJ)
	$(AR) $(LIB) $(LIBOBJ)
	$(RANLIB) $(LIB) || echo Never mind.
	@touch lib

files:
	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

links:
	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)

install:
	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
	do  \
	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
	done;

tags:
	ctags $(SRC)

tests:

lint:
	lint -DLINT $(INCLUDES) $(SRC)>fluff

depend:
	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)

dclean:
	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
	mv -f Makefile.new $(MAKEFILE)

clean:
	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff

# DO NOT DELETE THIS LINE -- make depend depends on it.

cms_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
cms_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cms_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_asn1.o: ../../include/openssl/opensslconf.h
cms_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_asn1.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cms_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_asn1.o: cms.h cms_asn1.c cms_lcl.h
cms_att.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
cms_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cms_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cms_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_att.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cms_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_att.o: cms.h cms_att.c cms_lcl.h
cms_cd.o: ../../e_os.h ../../include/openssl/asn1.h
cms_cd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_cd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_cd.o: ../../include/openssl/comp.h ../../include/openssl/conf.h
cms_cd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cms_cd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cms_cd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cms_cd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_cd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_cd.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
cms_cd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
cms_cd.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
cms_cd.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_cd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_cd.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
cms_cd.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_cd.c cms_lcl.h
cms_dd.o: ../../e_os.h ../../include/openssl/asn1.h
cms_dd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_dd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_dd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_dd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_dd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_dd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_dd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_dd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cms_dd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_dd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_dd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cms_dd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_dd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_dd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_dd.o: ../cryptlib.h cms_dd.c cms_lcl.h
cms_enc.o: ../../e_os.h ../../include/openssl/asn1.h
cms_enc.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_enc.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_enc.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cms_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_enc.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
cms_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
cms_enc.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_enc.c cms_lcl.h
cms_env.o: ../../e_os.h ../../include/openssl/aes.h
cms_env.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
cms_env.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cms_env.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
cms_env.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cms_env.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cms_env.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cms_env.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_env.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_env.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
cms_env.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
cms_env.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
cms_env.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
cms_env.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_env.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_env.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_env.o: ../asn1/asn1_locl.h ../cryptlib.h cms_env.c cms_lcl.h
cms_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
cms_err.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cms_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cms_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cms_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
cms_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
cms_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
cms_err.o: cms_err.c
cms_ess.o: ../../e_os.h ../../include/openssl/asn1.h
cms_ess.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_ess.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_ess.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_ess.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_ess.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_ess.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_ess.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_ess.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cms_ess.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_ess.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_ess.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
cms_ess.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_ess.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_ess.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
cms_ess.o: ../../include/openssl/x509v3.h ../cryptlib.h cms_ess.c cms_lcl.h
cms_io.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
cms_io.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cms_io.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cms_io.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cms_io.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cms_io.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_io.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_io.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
cms_io.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
cms_io.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
cms_io.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_io.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_io.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
cms_io.o: cms_io.c cms_lcl.h
cms_lib.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
cms_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cms_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cms_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cms_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cms_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cms_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cms_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
cms_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
cms_lib.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
cms_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
cms_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
cms_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
cms_lib.o: cms_lcl.h cms_lib.c
cms_sd.o: ../../e_os.h ../../include/openssl/asn1.h
cms_sd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_sd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_sd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_sd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_sd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_sd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_sd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_sd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cms_sd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_sd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
cms_sd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cms_sd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_sd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_sd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_sd.o: ../asn1/asn1_locl.h ../cryptlib.h cms_lcl.h cms_sd.c
cms_smime.o: ../../e_os.h ../../include/openssl/asn1.h
cms_smime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
cms_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
cms_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
cms_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
cms_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
cms_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cms_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cms_smime.o: ../../include/openssl/objects.h
cms_smime.o: ../../include/openssl/opensslconf.h
cms_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cms_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cms_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cms_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cms_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cms_smime.o: ../cryptlib.h cms_lcl.h cms_smime.c

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms.h
/* 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;

DECLARE_STACK_OF(CMS_SignerInfo)
DECLARE_STACK_OF(GENERAL_NAMES)
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_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

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);

STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
int CMS_RecipientInfo_type(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_decrypt(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);
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);
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

/* 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_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_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_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_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_SET0_KEY		 144
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145
#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_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_TRANSPORT				 124
#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_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_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_VERIFICATION_FAILURE			 158
#define CMS_R_WRAP_ERROR				 159

#ifdef  __cplusplus
}
#endif
#endif

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_asn1.c
/* crypto/cms/cms_asn1.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include "cms.h"
#include "cms_lcl.h"


ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)

ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
	ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
	ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)

ASN1_CHOICE(CMS_CertificateChoices) = {
	ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
	ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
	ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
	ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
	ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
} ASN1_CHOICE_END(CMS_CertificateChoices)

ASN1_CHOICE(CMS_SignerIdentifier) = {
	ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
	ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
} ASN1_CHOICE_END(CMS_SignerIdentifier)

ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
	ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
	ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)

/* Minor tweak to operation: free up signer key, cert */
static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
							void *exarg)
	{
	if(operation == ASN1_OP_FREE_POST)
		{
		CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
		if (si->pkey)
			EVP_PKEY_free(si->pkey);
		if (si->signer)
			X509_free(si->signer);
		}
	return 1;
	}

ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
	ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
	ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
	ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
	ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)

ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
	ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
	ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)

ASN1_CHOICE(CMS_RevocationInfoChoice) = {
	ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
	ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
} ASN1_CHOICE_END(CMS_RevocationInfoChoice)

ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
	ASN1_SIMPLE(CMS_SignedData, version, LONG),
	ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
	ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
	ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
	ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
	ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)

ASN1_SEQUENCE(CMS_OriginatorInfo) = {
	ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
	ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1)
} ASN1_SEQUENCE_END(CMS_OriginatorInfo)

ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
	ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)

ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)

ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
	ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
	ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)

ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
	ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
	ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
	ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)

ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)

ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = {
	ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
	ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey)

ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)

ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)

ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = {
	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
	ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
	ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
	ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo)

ASN1_SEQUENCE(CMS_KEKIdentifier) = {
	ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
	ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
	ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
} ASN1_SEQUENCE_END(CMS_KEKIdentifier)

ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
	ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
	ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
	ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)

ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
	ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
	ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
	ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)

ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)

/* Free up RecipientInfo additional data */
static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
							void *exarg)
	{
	if(operation == ASN1_OP_FREE_PRE)
		{
		CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
		if (ri->type == CMS_RECIPINFO_TRANS)
			{
			CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
			if (ktri->pkey)
				EVP_PKEY_free(ktri->pkey);
			if (ktri->recip)
				X509_free(ktri->recip);
			}
		else if (ri->type == CMS_RECIPINFO_KEK)
			{
			CMS_KEKRecipientInfo *kekri = ri->d.kekri;
			if (kekri->key)
				{
				OPENSSL_cleanse(kekri->key, kekri->keylen);
				OPENSSL_free(kekri->key);
				}
			}
		}
	return 1;
	}

ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
	ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
	ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
	ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
	ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
	ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)

ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
	ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
	ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
	ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
	ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
	ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)

ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
	ASN1_SIMPLE(CMS_DigestedData, version, LONG),
	ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
	ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)

ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
	ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
	ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
	ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)

ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
	ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
	ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
	ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
	ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
	ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
	ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
	ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)

ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
	ASN1_SIMPLE(CMS_CompressedData, version, LONG),
	ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
	ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)

/* This is the ANY DEFINED BY table for the top level ContentInfo structure */

ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);

ASN1_ADB(CMS_ContentInfo) = {
	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
	ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
	ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);

/* CMS streaming support */
static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
							void *exarg)
	{
	ASN1_STREAM_ARG *sarg = exarg;
	CMS_ContentInfo *cms = NULL;
	if (pval)
		cms = (CMS_ContentInfo *)*pval;
	else
		return 1;
	switch(operation)
		{

		case ASN1_OP_STREAM_PRE:
		if (CMS_stream(&sarg->boundary, cms) <= 0)
			return 0;
		case ASN1_OP_DETACHED_PRE:
		sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
		if (!sarg->ndef_bio)
			return 0;
		break;

		case ASN1_OP_STREAM_POST:
		case ASN1_OP_DETACHED_POST:
		if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
			return 0;
		break;

		}
	return 1;
	}

ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
	ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
	ASN1_ADB_OBJECT(CMS_ContentInfo)
} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)

/* Specials for signed attributes */

/* When signing attributes we want to reorder them to match the sorted
 * encoding.
 */

ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = 
	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
ASN1_ITEM_TEMPLATE_END(CMS_Attributes_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(CMS_Attributes_Verify) = 
	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
				V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)



ASN1_CHOICE(CMS_ReceiptsFrom) = {
  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
} ASN1_CHOICE_END(CMS_ReceiptsFrom)

ASN1_SEQUENCE(CMS_ReceiptRequest) = {
  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
} ASN1_SEQUENCE_END(CMS_ReceiptRequest)

ASN1_SEQUENCE(CMS_Receipt) = {
  ASN1_SIMPLE(CMS_Receipt, version, LONG),
  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CMS_Receipt)


File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_att.c
/* crypto/cms/cms_att.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include "cms.h"
#include "cms_lcl.h"

/* CMS SignedData Attribute utilities */

int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
{
	return X509at_get_attr_count(si->signedAttrs);
}

int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
			  int lastpos)
{
	return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
}

int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
			  int lastpos)
{
	return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
}

X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
{
	return X509at_get_attr(si->signedAttrs, loc);
}

X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
{
	return X509at_delete_attr(si->signedAttrs, loc);
}

int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
{
	if(X509at_add1_attr(&si->signedAttrs, attr)) return 1;
	return 0;
}

int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
			const ASN1_OBJECT *obj, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj,
				type, bytes, len)) return 1;
	return 0;
}

int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
			int nid, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_NID(&si->signedAttrs, nid,
				type, bytes, len)) return 1;
	return 0;
}

int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
			const char *attrname, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname,
				type, bytes, len)) return 1;
	return 0;
}

void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
					int lastpos, int type)
{
	return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
}

int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
{
	return X509at_get_attr_count(si->unsignedAttrs);
}

int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
			  int lastpos)
{
	return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
}

int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
			  int lastpos)
{
	return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
}

X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
{
	return X509at_get_attr(si->unsignedAttrs, loc);
}

X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
{
	return X509at_delete_attr(si->unsignedAttrs, loc);
}

int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
{
	if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1;
	return 0;
}

int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
			const ASN1_OBJECT *obj, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj,
				type, bytes, len)) return 1;
	return 0;
}

int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
			int nid, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid,
				type, bytes, len)) return 1;
	return 0;
}

int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
			const char *attrname, int type,
			const void *bytes, int len)
{
	if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
				type, bytes, len)) return 1;
	return 0;
}

void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
					int lastpos, int type)
{
	return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
}

/* Specific attribute cases */

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_cd.c
/* crypto/cms/cms_cd.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/bio.h>
#include <openssl/comp.h>
#include "cms_lcl.h"

DECLARE_ASN1_ITEM(CMS_CompressedData)

#ifdef ZLIB

/* CMS CompressedData Utilities */

CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
	{
	CMS_ContentInfo *cms;
	CMS_CompressedData *cd;
	/* Will need something cleverer if there is ever more than one
	 * compression algorithm or parameters have some meaning...
	 */
	if (comp_nid != NID_zlib_compression)
		{
		CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
		return NULL;
		}
	cms = CMS_ContentInfo_new();
	if (!cms)
		return NULL;

	cd = M_ASN1_new_of(CMS_CompressedData);

	if (!cd)
		goto err;

	cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
	cms->d.compressedData = cd;

	cd->version = 0;

	X509_ALGOR_set0(cd->compressionAlgorithm,
			OBJ_nid2obj(NID_zlib_compression),
			V_ASN1_UNDEF, NULL);

	cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);

	return cms;

	err:

	if (cms)
		CMS_ContentInfo_free(cms);

	return NULL;
	}

BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
	{
	CMS_CompressedData *cd;
	ASN1_OBJECT *compoid;
	if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData)
		{
		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
				CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
		return NULL;
		}
	cd = cms->d.compressedData;
	X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
	if (OBJ_obj2nid(compoid) != NID_zlib_compression)
		{
		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
		return NULL;
		}
	return BIO_new(BIO_f_zlib());
	}

#endif

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_dd.c
/* crypto/cms/cms_dd.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"

DECLARE_ASN1_ITEM(CMS_DigestedData)

/* CMS DigestedData Utilities */

CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
	{
	CMS_ContentInfo *cms;
	CMS_DigestedData *dd;
	cms = CMS_ContentInfo_new();
	if (!cms)
		return NULL;

	dd = M_ASN1_new_of(CMS_DigestedData);

	if (!dd)
		goto err;

	cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
	cms->d.digestedData = dd;

	dd->version = 0;
	dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);

	cms_DigestAlgorithm_set(dd->digestAlgorithm, md);

	return cms;

	err:

	if (cms)
		CMS_ContentInfo_free(cms);

	return NULL;
	}

BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
	{
	CMS_DigestedData *dd;
	dd = cms->d.digestedData;
	return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
	}

int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
	{
	EVP_MD_CTX mctx;
	unsigned char md[EVP_MAX_MD_SIZE];
	unsigned int mdlen;
	int r = 0;
	CMS_DigestedData *dd;
	EVP_MD_CTX_init(&mctx);

	dd = cms->d.digestedData;

	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
		goto err;

	if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
		goto err;

	if (verify)
		{
		if (mdlen != (unsigned int)dd->digest->length)
			{
			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
				CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
			goto err;
			}

		if (memcmp(md, dd->digest->data, mdlen))
			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
				CMS_R_VERIFICATION_FAILURE);
		else
			r = 1;
		}
	else
		{
		if (!ASN1_STRING_set(dd->digest, md, mdlen))
			goto err;
		r = 1;
		}

	err:
	EVP_MD_CTX_cleanup(&mctx);

	return r;

	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_enc.c
/* crypto/cms/cms_enc.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/rand.h>
#include "cms_lcl.h"

/* CMS EncryptedData Utilities */

DECLARE_ASN1_ITEM(CMS_EncryptedData)

/* Return BIO based on EncryptedContentInfo and key */

BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
	{
	BIO *b;
	EVP_CIPHER_CTX *ctx;
	const EVP_CIPHER *ciph;
	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;

	int ok = 0;

	int enc, keep_key = 0;

	enc = ec->cipher ? 1 : 0;

	b = BIO_new(BIO_f_cipher());
	if (!b)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
		return NULL;
		}

	BIO_get_cipher_ctx(b, &ctx);

	if (enc)
		{
		ciph = ec->cipher;
		/* If not keeping key set cipher to NULL so subsequent calls
		 * decrypt.
		 */
		if (ec->key)
			ec->cipher = NULL;
		}
	else
		{
		ciph = EVP_get_cipherbyobj(calg->algorithm);

		if (!ciph)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							CMS_R_UNKNOWN_CIPHER);
			goto err;
			}
		}

	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_INITIALISATION_ERROR);
		goto err;
		}

	if (enc)
		{
		int ivlen;
		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
		/* Generate a random IV if we need one */
		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
		if (ivlen > 0)
			{
			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
				goto err;
			piv = iv;
			}
		}
	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
		goto err;
		}


	if (enc && !ec->key)
		{
		/* Generate random key */
		if (!ec->keylen)
			ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
		ec->key = OPENSSL_malloc(ec->keylen);
		if (!ec->key)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0)
			goto err;
		keep_key = 1;
		}
	else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx))
		{
		/* If necessary set key length */
		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_INVALID_KEY_LENGTH);
			goto err;
			}
		}

	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_INITIALISATION_ERROR);
		goto err;
		}

	if (piv)
		{
		calg->parameter = ASN1_TYPE_new();
		if (!calg->parameter)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
			goto err;
			}
		}
	ok = 1;

	err:
	if (ec->key && !keep_key)
		{
		OPENSSL_cleanse(ec->key, ec->keylen);
		OPENSSL_free(ec->key);
		ec->key = NULL;
		}
	if (ok)
		return b;
	BIO_free(b);
	return NULL;
	}

int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
				const EVP_CIPHER *cipher,
				const unsigned char *key, size_t keylen)
	{
	ec->cipher = cipher;
	if (key)
		{
		ec->key = OPENSSL_malloc(keylen);
		if (!ec->key)
			return 0;
		memcpy(ec->key, key, keylen);
		}
	ec->keylen = keylen;
	if (cipher)
		ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
	return 1;
	}

int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
				const unsigned char *key, size_t keylen)
	{
	CMS_EncryptedContentInfo *ec;
	if (!key || !keylen)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
		return 0;
		}
	if (ciph)
		{
		cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
		if (!cms->d.encryptedData)
			{
			CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
				ERR_R_MALLOC_FAILURE);
			return 0;
			}
		cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
		cms->d.encryptedData->version = 0;
		}
	else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
						CMS_R_NOT_ENCRYPTED_DATA);
		return 0;
		}
	ec = cms->d.encryptedData->encryptedContentInfo;
	return cms_EncryptedContent_init(ec, ciph, key, keylen);
	}

BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
	{
	CMS_EncryptedData *enc = cms->d.encryptedData;
	if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
		enc->version = 2;
	return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_env.c
/* crypto/cms/cms_env.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include "cms_lcl.h"
#include "asn1_locl.h"

/* CMS EnvelopedData Utilities */

DECLARE_ASN1_ITEM(CMS_EnvelopedData)
DECLARE_ASN1_ITEM(CMS_RecipientInfo)
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)

DECLARE_STACK_OF(CMS_RecipientInfo)

static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
	{
	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
		{
		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
		return NULL;
		}
	return cms->d.envelopedData;
	}

static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
	{
	if (cms->d.other == NULL)
		{
		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
		if (!cms->d.envelopedData)
			{
			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
							ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		cms->d.envelopedData->version = 0;
		cms->d.envelopedData->encryptedContentInfo->contentType =
						OBJ_nid2obj(NID_pkcs7_data);
		ASN1_OBJECT_free(cms->contentType);
		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
		return cms->d.envelopedData;
		}
	return cms_get0_enveloped(cms);
	}

STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
	{
	CMS_EnvelopedData *env;
	env = cms_get0_enveloped(cms);
	if (!env)
		return NULL;
	return env->recipientInfos;
	}

int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
	{
	return ri->type;
	}

CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
	{
	CMS_ContentInfo *cms;
	CMS_EnvelopedData *env;
	cms = CMS_ContentInfo_new();
	if (!cms)
		goto merr;
	env = cms_enveloped_data_init(cms);
	if (!env)
		goto merr;
	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
					cipher, NULL, 0))
		goto merr;
	return cms;
	merr:
	if (cms)
		CMS_ContentInfo_free(cms);
	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
	return NULL;
	}

/* Key Transport Recipient Info (KTRI) routines */

/* Add a recipient certificate. For now only handle key transport.
 * If we ever handle key agreement will need updating.
 */

CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
					X509 *recip, unsigned int flags)
	{
	CMS_RecipientInfo *ri = NULL;
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EnvelopedData *env;
	EVP_PKEY *pk = NULL;
	int i, type;
	env = cms_get0_enveloped(cms);
	if (!env)
		goto err;

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	/* Initialize and add key transport recipient info */

	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
	if (!ri->d.ktri)
		goto merr;
	ri->type = CMS_RECIPINFO_TRANS;

	ktri = ri->d.ktri;

	X509_check_purpose(recip, -1, -1);
	pk = X509_get_pubkey(recip);
	if (!pk)
		{
		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_ERROR_GETTING_PUBLIC_KEY);
		goto err;
		}
	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
	ktri->pkey = pk;
	ktri->recip = recip;

	if (flags & CMS_USE_KEYID)
		{
		ktri->version = 2;
		type = CMS_RECIPINFO_KEYIDENTIFIER;
		}
	else
		{
		ktri->version = 0;
		type = CMS_RECIPINFO_ISSUER_SERIAL;
		}

	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
	 * same structure.
	 */

	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
		goto err;

	if (pk->ameth && pk->ameth->pkey_ctrl)
		{
		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
						0, ri);
		if (i == -2)
			{
			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
			goto err;
			}
		if (i <= 0)
			{
			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_CTRL_FAILURE);
			goto err;
			}
		}

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;

	return ri;

	merr:
	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
	err:
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	return NULL;

	}

int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
					EVP_PKEY **pk, X509 **recip,
					X509_ALGOR **palg)
	{
	CMS_KeyTransRecipientInfo *ktri;
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}

	ktri = ri->d.ktri;

	if (pk)
		*pk = ktri->pkey;
	if (recip)
		*recip = ktri->recip;
	if (palg)
		*palg = ktri->keyEncryptionAlgorithm;
	return 1;
	}

int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	CMS_KeyTransRecipientInfo *ktri;
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ktri = ri->d.ktri;

	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
							keyid, issuer, sno);
	}

int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
	{
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
			CMS_R_NOT_KEY_TRANSPORT);
		return -2;
		}
	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
	}

int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
	{
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ri->d.ktri->pkey = pkey;
	return 1;
	}

/* Encrypt content key in key transport recipient info */

static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EncryptedContentInfo *ec;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;

	int ret = 0;

	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ktri = ri->d.ktri;
	ec = cms->d.envelopedData->encryptedContentInfo;

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_encrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
	ek = NULL;

	ret = 1;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (ek)
		OPENSSL_free(ek);
	return ret;

	}

/* Decrypt content key from KTRI */

static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
							CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;
	int ret = 0;

	if (ktri->pkey == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
			CMS_R_NO_PRIVATE_KEY);
		return 0;
		}

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_decrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
		goto err;
		}

	ret = 1;

	cms->d.envelopedData->encryptedContentInfo->key = ek;
	cms->d.envelopedData->encryptedContentInfo->keylen = eklen;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (!ret && ek)
		OPENSSL_free(ek);

	return ret;
	}

/* Key Encrypted Key (KEK) RecipientInfo routines */

int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
					const unsigned char *id, size_t idlen)
	{
	ASN1_OCTET_STRING tmp_os;
	CMS_KEKRecipientInfo *kekri;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
		return -2;
		}
	kekri = ri->d.kekri;
	tmp_os.type = V_ASN1_OCTET_STRING;
	tmp_os.flags = 0;
	tmp_os.data = (unsigned char *)id;
	tmp_os.length = (int)idlen;
	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
	}

/* For now hard code AES key wrap info */

static size_t aes_wrap_keylen(int nid)
	{
	switch (nid)
		{
		case NID_id_aes128_wrap:
		return 16;

		case NID_id_aes192_wrap:
		return  24;

		case NID_id_aes256_wrap:
		return  32;

		default:
		return 0;
		}
	}

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)
	{
	CMS_RecipientInfo *ri = NULL;
	CMS_EnvelopedData *env;
	CMS_KEKRecipientInfo *kekri;
	env = cms_get0_enveloped(cms);
	if (!env)
		goto err;

	if (nid == NID_undef)
		{
		switch (keylen)
			{
			case 16:
			nid = NID_id_aes128_wrap;
			break;

			case  24:
			nid = NID_id_aes192_wrap;
			break;

			case  32:
			nid = NID_id_aes256_wrap;
			break;

			default:
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
						CMS_R_INVALID_KEY_LENGTH);
			goto err;
			}

		}
	else
		{

		size_t exp_keylen = aes_wrap_keylen(nid);

		if (!exp_keylen)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
			goto err;
			}

		if (keylen != exp_keylen)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
					CMS_R_INVALID_KEY_LENGTH);
			goto err;
			}

		}

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
	if (!ri->d.kekri)
		goto merr;
	ri->type = CMS_RECIPINFO_KEK;

	kekri = ri->d.kekri;

	if (otherTypeId)
		{
		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
		if (kekri->kekid->other == NULL)
			goto merr;
		}

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;


	/* After this point no calls can fail */

	kekri->version = 4;

	kekri->key = key;
	kekri->keylen = keylen;

	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);

	kekri->kekid->date = date;

	if (kekri->kekid->other)
		{
		kekri->kekid->other->keyAttrId = otherTypeId;
		kekri->kekid->other->keyAttr = otherType;
		}

	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);

	return ri;

	merr:
	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
	err:
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	return NULL;

	}

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)
	{
	CMS_KEKIdentifier *rkid;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
		return 0;
		}
	rkid =  ri->d.kekri->kekid;
	if (palg)
		*palg = ri->d.kekri->keyEncryptionAlgorithm;
	if (pid)
		*pid = rkid->keyIdentifier;
	if (pdate)
		*pdate = rkid->date;
	if (potherid)
		{
		if (rkid->other)
			*potherid = rkid->other->keyAttrId;
		else
			*potherid = NULL;
		}
	if (pothertype)
		{
		if (rkid->other)
			*pothertype = rkid->other->keyAttr;
		else
			*pothertype = NULL;
		}
	return 1;
	}

int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
				unsigned char *key, size_t keylen)
	{
	CMS_KEKRecipientInfo *kekri;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
		return 0;
		}

	kekri = ri->d.kekri;
	kekri->key = key;
	kekri->keylen = keylen;
	return 1;
	}


/* Encrypt content key in KEK recipient info */

static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_EncryptedContentInfo *ec;
	CMS_KEKRecipientInfo *kekri;
	AES_KEY actx;
	unsigned char *wkey = NULL;
	int wkeylen;
	int r = 0;

	ec = cms->d.envelopedData->encryptedContentInfo;

	kekri = ri->d.kekri;

	if (!kekri->key)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
		return 0;
		}

	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
						CMS_R_ERROR_SETTING_KEY);
		goto err;
		}

	wkey = OPENSSL_malloc(ec->keylen + 8);

	if (!wkey)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
						ERR_R_MALLOC_FAILURE);
		goto err;
		}

	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);

	if (wkeylen <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
		goto err;
		}

	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);

	r = 1;

	err:

	if (!r && wkey)
		OPENSSL_free(wkey);
	OPENSSL_cleanse(&actx, sizeof(actx));

	return r;

	}

/* Decrypt content key in KEK recipient info */

static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_EncryptedContentInfo *ec;
	CMS_KEKRecipientInfo *kekri;
	AES_KEY actx;
	unsigned char *ukey = NULL;
	int ukeylen;
	int r = 0, wrap_nid;

	ec = cms->d.envelopedData->encryptedContentInfo;

	kekri = ri->d.kekri;

	if (!kekri->key)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
		return 0;
		}

	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
			CMS_R_INVALID_KEY_LENGTH);
		return 0;
		}

	/* If encrypted key length is invalid don't bother */

	if (kekri->encryptedKey->length < 16)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
		goto err;
		}

	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
						CMS_R_ERROR_SETTING_KEY);
		goto err;
		}

	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);

	if (!ukey)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
						ERR_R_MALLOC_FAILURE);
		goto err;
		}

	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
					kekri->encryptedKey->data,
					kekri->encryptedKey->length);

	if (ukeylen <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
							CMS_R_UNWRAP_ERROR);
		goto err;
		}

	ec->key = ukey;
	ec->keylen = ukeylen;

	r = 1;

	err:

	if (!r && ukey)
		OPENSSL_free(ukey);
	OPENSSL_cleanse(&actx, sizeof(actx));

	return r;

	}

int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
	{
	switch(ri->type)
		{
		case CMS_RECIPINFO_TRANS:
		return cms_RecipientInfo_ktri_decrypt(cms, ri);

		case CMS_RECIPINFO_KEK:
		return cms_RecipientInfo_kekri_decrypt(cms, ri);

		default:
		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
		return 0;
		}
	}

BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
	{
	CMS_EncryptedContentInfo *ec;
	STACK_OF(CMS_RecipientInfo) *rinfos;
	CMS_RecipientInfo *ri;
	int i, r, ok = 0;
	BIO *ret;

	/* Get BIO first to set up key */

	ec = cms->d.envelopedData->encryptedContentInfo;
	ret = cms_EncryptedContent_init_bio(ec);

	/* If error or no cipher end of processing */

	if (!ret || !ec->cipher)
		return ret;

	/* Now encrypt content key according to each RecipientInfo type */

	rinfos = cms->d.envelopedData->recipientInfos;

	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
		{
		ri = sk_CMS_RecipientInfo_value(rinfos, i);

		switch (ri->type)
			{
			case CMS_RECIPINFO_TRANS:
			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
			break;

			case CMS_RECIPINFO_KEK:
			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
			break;

			default:
			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
			goto err;
			}

		if (r <= 0)
			{
			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
				CMS_R_ERROR_SETTING_RECIPIENTINFO);
			goto err;
			}
		}

	ok = 1;

	err:
	ec->cipher = NULL;
	if (ec->key)
		{
		OPENSSL_cleanse(ec->key, ec->keylen);
		OPENSSL_free(ec->key);
		ec->key = NULL;
		ec->keylen = 0;
		}
	if (ok)
		return ret;
	BIO_free(ret);
	return NULL;

	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_err.c
/* crypto/cms/cms_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/cms.h>

/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR

#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)

static ERR_STRING_DATA CMS_str_functs[]=
	{
{ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"},
{ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"},
{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"},
{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"},
{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"},
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"},
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME),	"CMS_ADD1_SIGNINGTIME"},
{ERR_FUNC(CMS_F_CMS_COMPRESS),	"CMS_compress"},
{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE),	"cms_CompressedData_create"},
{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),	"cms_CompressedData_init_bio"},
{ERR_FUNC(CMS_F_CMS_COPY_CONTENT),	"CMS_COPY_CONTENT"},
{ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST),	"CMS_COPY_MESSAGEDIGEST"},
{ERR_FUNC(CMS_F_CMS_DATA),	"CMS_data"},
{ERR_FUNC(CMS_F_CMS_DATAFINAL),	"CMS_dataFinal"},
{ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"},
{ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"},
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"},
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"},
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"},
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"},
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL),	"cms_DigestedData_do_final"},
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY),	"CMS_digest_verify"},
{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT),	"cms_encode_Receipt"},
{ERR_FUNC(CMS_F_CMS_ENCRYPT),	"CMS_encrypt"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),	"cms_EncryptedContent_init_bio"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT),	"CMS_EncryptedData_decrypt"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT),	"CMS_EncryptedData_encrypt"},
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),	"CMS_EncryptedData_set1_key"},
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE),	"CMS_EnvelopedData_create"},
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),	"cms_EnvelopedData_init_bio"},
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT),	"CMS_ENVELOPED_DATA_INIT"},
{ERR_FUNC(CMS_F_CMS_FINAL),	"CMS_final"},
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"},
{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"},
{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"CMS_GET0_ENVELOPED"},
{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"},
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"},
{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"},
{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),	"CMS_ReceiptRequest_create0"},
{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),	"cms_Receipt_verify"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),	"CMS_RecipientInfo_decrypt"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),	"CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),	"CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),	"CMS_RecipientInfo_kekri_get0_id"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),	"CMS_RecipientInfo_kekri_id_cmp"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),	"CMS_RecipientInfo_ktri_cert_cmp"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),	"CMS_RECIPIENTINFO_KTRI_DECRYPT"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"},
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"},
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"},
{ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"},
{ERR_FUNC(CMS_F_CMS_SIGN),	"CMS_sign"},
{ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT),	"CMS_SIGNED_DATA_INIT"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),	"CMS_SIGNERINFO_CONTENT_SIGN"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN),	"CMS_SignerInfo_sign"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY),	"CMS_SignerInfo_verify"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),	"CMS_SIGNERINFO_VERIFY_CERT"},
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),	"CMS_SignerInfo_verify_content"},
{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT),	"CMS_sign_receipt"},
{ERR_FUNC(CMS_F_CMS_STREAM),	"CMS_stream"},
{ERR_FUNC(CMS_F_CMS_UNCOMPRESS),	"CMS_uncompress"},
{ERR_FUNC(CMS_F_CMS_VERIFY),	"CMS_verify"},
{0,NULL}
	};

static ERR_STRING_DATA CMS_str_reasons[]=
	{
{ERR_REASON(CMS_R_ADD_SIGNER_ERROR)      ,"add signer error"},
{ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),"certificate already present"},
{ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"},
{ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR)   ,"cms datafinal error"},
{ERR_REASON(CMS_R_CMS_LIB)               ,"cms lib"},
{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
{ERR_REASON(CMS_R_CONTENT_NOT_FOUND)     ,"content not found"},
{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
{ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR)  ,"content verify error"},
{ERR_REASON(CMS_R_CTRL_ERROR)            ,"ctrl error"},
{ERR_REASON(CMS_R_CTRL_FAILURE)          ,"ctrl failure"},
{ERR_REASON(CMS_R_DECRYPT_ERROR)         ,"decrypt error"},
{ERR_REASON(CMS_R_DIGEST_ERROR)          ,"digest error"},
{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
{ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"},
{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
{ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"},
{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR)    ,"msgsigdigest error"},
{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
{ERR_REASON(CMS_R_NEED_ONE_SIGNER)       ,"need one signer"},
{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT)  ,"not a signed receipt"},
{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"},
{ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"},
{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"},
{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
{ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"},
{ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"},
{ERR_REASON(CMS_R_NO_CONTENT_TYPE)       ,"no content type"},
{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
{ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
{ERR_REASON(CMS_R_NO_KEY_OR_CERT)        ,"no key or cert"},
{ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
{ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"},
{ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},
{ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"},
{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"},
{ERR_REASON(CMS_R_NO_SIGNERS)            ,"no signers"},
{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR)  ,"receipt decode error"},
{ERR_REASON(CMS_R_RECIPIENT_ERROR)       ,"recipient error"},
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
{ERR_REASON(CMS_R_SIGNFINAL_ERROR)       ,"signfinal error"},
{ERR_REASON(CMS_R_SMIME_TEXT_ERROR)      ,"smime text error"},
{ERR_REASON(CMS_R_STORE_INIT_ERROR)      ,"store init error"},
{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
{ERR_REASON(CMS_R_TYPE_NOT_DATA)         ,"type not data"},
{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
{ERR_REASON(CMS_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
{ERR_REASON(CMS_R_UNKNOWN_ID)            ,"unknown id"},
{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
{ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"},
{ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"},
{ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"},
{ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"},
{0,NULL}
	};

#endif

void ERR_load_CMS_strings(void)
	{
#ifndef OPENSSL_NO_ERR

	if (ERR_func_error_string(CMS_str_functs[0].error) == NULL)
		{
		ERR_load_strings(0,CMS_str_functs);
		ERR_load_strings(0,CMS_str_reasons);
		}
#endif
	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_ess.c
/* crypto/cms/cms_ess.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"

DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
DECLARE_ASN1_ITEM(CMS_Receipt)

IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)

/* ESS services: for now just Signed Receipt related */

int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
	{
	ASN1_STRING *str;
	CMS_ReceiptRequest *rr = NULL;
	if (prr)
		*prr = NULL;
	str = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
					-3, V_ASN1_SEQUENCE);
	if (!str)
		return 0;

	rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
	if (!rr)
		return -1;
	if (prr)
		*prr = rr;
	else
		CMS_ReceiptRequest_free(rr);
	return 1;
	}

CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
				int allorfirst,
				STACK_OF(GENERAL_NAMES) *receiptList,
				STACK_OF(GENERAL_NAMES) *receiptsTo)
	{
	CMS_ReceiptRequest *rr = NULL;

	rr = CMS_ReceiptRequest_new();
	if (!rr)
		goto merr;
	if (id)
		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
	else
		{
		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
			goto merr;
		if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 
					<= 0)
			goto err;
		}

	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
	rr->receiptsTo = receiptsTo;

	if (receiptList)
		{
		rr->receiptsFrom->type = 1;
		rr->receiptsFrom->d.receiptList = receiptList;
		}
	else
		{
		rr->receiptsFrom->type = 0;
		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
		}

	return rr;

	merr:
	CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);

	return NULL;
	
	}

int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
	{
	unsigned char *rrder = NULL;
	int rrderlen, r = 0;

	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
	if (rrderlen < 0)
		goto merr;

	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
					V_ASN1_SEQUENCE, rrder, rrderlen))
		goto merr;

	r = 1;

	merr:
	if (!r)
		CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);

	if (rrder)
		OPENSSL_free(rrder);

	return r;
	
	}

void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
					ASN1_STRING **pcid,
					int *pallorfirst,
					STACK_OF(GENERAL_NAMES) **plist,
					STACK_OF(GENERAL_NAMES) **prto)
	{
	if (pcid)
		*pcid = rr->signedContentIdentifier;
	if (rr->receiptsFrom->type == 0)
		{
		if (pallorfirst)
			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
		if (plist)
			*plist = NULL;
		}
	else
		{
		if (pallorfirst)
			*pallorfirst = -1;
		if (plist)
			*plist = rr->receiptsFrom->d.receiptList;
		}
	if (prto)
		*prto = rr->receiptsTo;
	}

/* Digest a SignerInfo structure for msgSigDigest attribute processing */

static int cms_msgSigDigest(CMS_SignerInfo *si,
				unsigned char *dig, unsigned int *diglen)
	{
	const EVP_MD *md;
	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
	if (md == NULL)
		return 0;
	if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
						si->signedAttrs, dig, diglen))
		return 0;
	return 1;
	}

/* Add a msgSigDigest attribute to a SignerInfo */

int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
	{
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int diglen;
	if (!cms_msgSigDigest(src, dig, &diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
		return 0;
		}
	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
					V_ASN1_OCTET_STRING, dig, diglen))
		{
		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	return 1;
	}

/* Verify signed receipt after it has already passed normal CMS verify */

int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
	{
	int r = 0, i;
	CMS_ReceiptRequest *rr = NULL;
	CMS_Receipt *rct = NULL;
	STACK_OF(CMS_SignerInfo) *sis, *osis;
	CMS_SignerInfo *si, *osi = NULL;
	ASN1_OCTET_STRING *msig, **pcont;
	ASN1_OBJECT *octype;
	unsigned char dig[EVP_MAX_MD_SIZE];
	unsigned int diglen;

	/* Get SignerInfos, also checks SignedData content type */
	osis = CMS_get0_SignerInfos(req_cms);
	sis = CMS_get0_SignerInfos(cms);
	if (!osis || !sis)
		goto err;

	if (sk_CMS_SignerInfo_num(sis) != 1)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
		goto err;
		}

	/* Check receipt content type */
	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
		goto err;
		}

	/* Extract and decode receipt content */
	pcont = CMS_get0_content(cms);
	if (!pcont || !*pcont)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
		goto err;
		}

	rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));

	if (!rct)	
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
		goto err;
		}

	/* Locate original request */

	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
		{
		osi = sk_CMS_SignerInfo_value(osis, i);
		if (!ASN1_STRING_cmp(osi->signature,
					rct->originatorSignatureValue))
			break;
		}

	if (i == sk_CMS_SignerInfo_num(osis))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
		goto err;
		}

	si = sk_CMS_SignerInfo_value(sis, 0);

	/* Get msgSigDigest value and compare */

	msig = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
					-3, V_ASN1_OCTET_STRING);

	if (!msig)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
		goto err;
		}

	if (!cms_msgSigDigest(osi, dig, &diglen))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
		goto err;
		}

	if (diglen != (unsigned int)msig->length)
			{
			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
				CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
			goto err;
			}

	if (memcmp(dig, msig->data, diglen))
			{
			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
				CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
			goto err;
			}

	/* Compare content types */

	octype = CMS_signed_get0_data_by_OBJ(osi,
				OBJ_nid2obj(NID_pkcs9_contentType),
					-3, V_ASN1_OBJECT);
	if (!octype)
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
		goto err;
		}

	/* Compare details in receipt request */

	if (OBJ_cmp(octype, rct->contentType))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
		goto err;
		}

	/* Get original receipt request details */

	if (!CMS_get1_ReceiptRequest(osi, &rr))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
		goto err;
		}

	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
					rct->signedContentIdentifier))
		{
		CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
					CMS_R_CONTENTIDENTIFIER_MISMATCH);
		goto err;
		}

	r = 1;

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);
	if (rct)
		M_ASN1_free_of(rct, CMS_Receipt);

	return r;

	}

/* Encode a Receipt into an OCTET STRING read for including into content of
 * a SignedData ContentInfo.
 */

ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
	{
	CMS_Receipt rct;
	CMS_ReceiptRequest *rr = NULL;
	ASN1_OBJECT *ctype;
	ASN1_OCTET_STRING *os = NULL;

	/* Get original receipt request */

	/* Get original receipt request details */

	if (!CMS_get1_ReceiptRequest(si, &rr))
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
		goto err;
		}

	/* Get original content type */

	ctype = CMS_signed_get0_data_by_OBJ(si,
				OBJ_nid2obj(NID_pkcs9_contentType),
					-3, V_ASN1_OBJECT);
	if (!ctype)
		{
		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
		goto err;
		}

	rct.version = 1;
	rct.contentType = ctype;
	rct.signedContentIdentifier = rr->signedContentIdentifier;
	rct.originatorSignatureValue = si->signature;

	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);

	err:
	if (rr)
		CMS_ReceiptRequest_free(rr);

	return os;

	}



File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_io.c
/* crypto/cms/cms_io.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/asn1t.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include "cms.h"
#include "cms_lcl.h"

int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
	{
	ASN1_OCTET_STRING **pos;
	pos = CMS_get0_content(cms);
	if (!pos)
		return 0;
	if (!*pos)
		*pos = ASN1_OCTET_STRING_new();
	if (*pos)
		{
		(*pos)->flags |= ASN1_STRING_FLAG_NDEF;
		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
		*boundary = &(*pos)->data;
		return 1;
		}
	CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
	return 0;
	}

CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
	{
	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
	}

int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
	{
	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
	}

IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)

BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) 
	{
	return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
				ASN1_ITEM_rptr(CMS_ContentInfo));
	}

/* CMS wrappers round generalised stream and MIME routines */

int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
	{
	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
					ASN1_ITEM_rptr(CMS_ContentInfo));
	}

int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
	{
	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags,
					"CMS",
					ASN1_ITEM_rptr(CMS_ContentInfo));
	}

int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
	{
	STACK_OF(X509_ALGOR) *mdalgs;
	int ctype_nid = OBJ_obj2nid(cms->contentType);
	int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
	if (ctype_nid == NID_pkcs7_signed)
		mdalgs = cms->d.signedData->digestAlgorithms;
	else
		mdalgs = NULL;

	return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
					ctype_nid, econt_nid, mdalgs,
					ASN1_ITEM_rptr(CMS_ContentInfo));	
	}

CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
	{
	return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
					ASN1_ITEM_rptr(CMS_ContentInfo));
	}


File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_lcl.h
/* crypto/cms/cms_lcl.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_LCL_H
#define HEADER_CMS_LCL_H

#ifdef __cplusplus
extern "C" {
#endif

#include <openssl/x509.h>

/* Cryptographic message syntax (CMS) structures: taken
 * from RFC3852
 */

/* Forward references */

typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
typedef struct CMS_SignedData_st CMS_SignedData;
typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
typedef struct CMS_DigestedData_st CMS_DigestedData;
typedef struct CMS_EncryptedData_st CMS_EncryptedData;
typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
typedef struct CMS_CompressedData_st CMS_CompressedData;
typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;

struct CMS_ContentInfo_st
	{
	ASN1_OBJECT *contentType;
	union	{
		ASN1_OCTET_STRING *data;
		CMS_SignedData *signedData;
		CMS_EnvelopedData *envelopedData;
		CMS_DigestedData *digestedData;
		CMS_EncryptedData *encryptedData;
		CMS_AuthenticatedData *authenticatedData;
		CMS_CompressedData *compressedData;
		ASN1_TYPE *other;
		/* Other types ... */
		void *otherData;
		} d;
	};

struct CMS_SignedData_st
	{
	long version;
	STACK_OF(X509_ALGOR) *digestAlgorithms;
	CMS_EncapsulatedContentInfo *encapContentInfo;
	STACK_OF(CMS_CertificateChoices) *certificates;
	STACK_OF(CMS_RevocationInfoChoice) *crls;
	STACK_OF(CMS_SignerInfo) *signerInfos;
	};
 
struct CMS_EncapsulatedContentInfo_st
	{
	ASN1_OBJECT *eContentType;
	ASN1_OCTET_STRING *eContent;
	/* Set to 1 if incomplete structure only part set up */
	int partial;
	};

struct CMS_SignerInfo_st
	{
	long version;
	CMS_SignerIdentifier *sid;
	X509_ALGOR *digestAlgorithm;
	STACK_OF(X509_ATTRIBUTE) *signedAttrs;
	X509_ALGOR *signatureAlgorithm;
	ASN1_OCTET_STRING *signature;
	STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
	/* Signing certificate and key */
	X509 *signer;
	EVP_PKEY *pkey;
	};

struct CMS_SignerIdentifier_st
	{
	int type;
	union	{
		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
		ASN1_OCTET_STRING *subjectKeyIdentifier;
		} d;
	};

struct CMS_EnvelopedData_st
	{
	long version;
	CMS_OriginatorInfo *originatorInfo;
	STACK_OF(CMS_RecipientInfo) *recipientInfos;
	CMS_EncryptedContentInfo *encryptedContentInfo;
	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
	};

struct CMS_OriginatorInfo_st
	{
	STACK_OF(CMS_CertificateChoices) *certificates;
	STACK_OF(CMS_RevocationInfoChoice) *crls;
	};

struct CMS_EncryptedContentInfo_st
	{
	ASN1_OBJECT *contentType;
	X509_ALGOR *contentEncryptionAlgorithm;
	ASN1_OCTET_STRING *encryptedContent;
	/* Content encryption algorithm and key */
	const EVP_CIPHER *cipher;
	unsigned char *key;
	size_t keylen;
	};

struct CMS_RecipientInfo_st
	{
 	int type;
 	union	{
  	 	CMS_KeyTransRecipientInfo *ktri;
   		CMS_KeyAgreeRecipientInfo *kari;
   		CMS_KEKRecipientInfo *kekri;
		CMS_PasswordRecipientInfo *pwri;
		CMS_OtherRecipientInfo *ori;
		} d;
	};

typedef CMS_SignerIdentifier CMS_RecipientIdentifier;

struct CMS_KeyTransRecipientInfo_st
	{
	long version;
	CMS_RecipientIdentifier *rid;
	X509_ALGOR *keyEncryptionAlgorithm;
	ASN1_OCTET_STRING *encryptedKey;
	/* Recipient Key and cert */
	X509 *recip;
	EVP_PKEY *pkey;
	};

struct CMS_KeyAgreeRecipientInfo_st
	{
	long version;
	CMS_OriginatorIdentifierOrKey *originator;
	ASN1_OCTET_STRING *ukm;
 	X509_ALGOR *keyEncryptionAlgorithm;
	STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
	};

struct CMS_OriginatorIdentifierOrKey_st
	{
	int type;
	union	{
		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
		ASN1_OCTET_STRING *subjectKeyIdentifier;
		CMS_OriginatorPublicKey *originatorKey;
		} d;
	};

struct CMS_OriginatorPublicKey_st
	{
	X509_ALGOR *algorithm;
	ASN1_BIT_STRING *publicKey;
	};

struct CMS_RecipientEncryptedKey_st
	{
 	CMS_KeyAgreeRecipientIdentifier *rid;
 	ASN1_OCTET_STRING *encryptedKey;
	};

struct CMS_KeyAgreeRecipientIdentifier_st
	{
	int type;
	union	{
		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
		CMS_RecipientKeyIdentifier *rKeyId;
		} d;
	};

struct CMS_RecipientKeyIdentifier_st
	{
 	ASN1_OCTET_STRING *subjectKeyIdentifier;
 	ASN1_GENERALIZEDTIME *date;
 	CMS_OtherKeyAttribute *other;
	};

struct CMS_KEKRecipientInfo_st
	{
 	long version;
 	CMS_KEKIdentifier *kekid;
 	X509_ALGOR *keyEncryptionAlgorithm;
 	ASN1_OCTET_STRING *encryptedKey;
	/* Extra info: symmetric key to use */
	unsigned char *key;
	size_t keylen;
	};

struct CMS_KEKIdentifier_st
	{
 	ASN1_OCTET_STRING *keyIdentifier;
 	ASN1_GENERALIZEDTIME *date;
 	CMS_OtherKeyAttribute *other;
	};

struct CMS_PasswordRecipientInfo_st
	{
 	long version;
 	X509_ALGOR *keyDerivationAlgorithm;
 	X509_ALGOR *keyEncryptionAlgorithm;
 	ASN1_OCTET_STRING *encryptedKey;
	};

struct CMS_OtherRecipientInfo_st
	{
 	ASN1_OBJECT *oriType;
 	ASN1_TYPE *oriValue;
	};

struct CMS_DigestedData_st
	{
	long version;
	X509_ALGOR *digestAlgorithm;
	CMS_EncapsulatedContentInfo *encapContentInfo;
	ASN1_OCTET_STRING *digest;
	};

struct CMS_EncryptedData_st
	{
	long version;
	CMS_EncryptedContentInfo *encryptedContentInfo;
	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
	};

struct CMS_AuthenticatedData_st
	{
	long version;
	CMS_OriginatorInfo *originatorInfo;
	STACK_OF(CMS_RecipientInfo) *recipientInfos;
	X509_ALGOR *macAlgorithm;
	X509_ALGOR *digestAlgorithm;
	CMS_EncapsulatedContentInfo *encapContentInfo;
	STACK_OF(X509_ATTRIBUTE) *authAttrs;
	ASN1_OCTET_STRING *mac;
	STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
	};

struct CMS_CompressedData_st
	{
	long version;
	X509_ALGOR *compressionAlgorithm;
	STACK_OF(CMS_RecipientInfo) *recipientInfos;
	CMS_EncapsulatedContentInfo *encapContentInfo;
	};

struct CMS_RevocationInfoChoice_st
	{
	int type;
	union	{
		X509_CRL *crl;
		CMS_OtherRevocationInfoFormat *other;
		} d;
	};

#define CMS_REVCHOICE_CRL		0
#define CMS_REVCHOICE_OTHER		1

struct CMS_OtherRevocationInfoFormat_st
	{
	ASN1_OBJECT *otherRevInfoFormat;
 	ASN1_TYPE *otherRevInfo;
	};

struct CMS_CertificateChoices
	{
	int type;
		union {
		X509 *certificate;
		ASN1_STRING *extendedCertificate;	/* Obsolete */
		ASN1_STRING *v1AttrCert;	/* Left encoded for now */
		ASN1_STRING *v2AttrCert;	/* Left encoded for now */
		CMS_OtherCertificateFormat *other;
		} d;
	};

#define CMS_CERTCHOICE_CERT		0
#define CMS_CERTCHOICE_EXCERT		1
#define CMS_CERTCHOICE_V1ACERT		2
#define CMS_CERTCHOICE_V2ACERT		3
#define CMS_CERTCHOICE_OTHER		4

struct CMS_OtherCertificateFormat_st
	{
	ASN1_OBJECT *otherCertFormat;
 	ASN1_TYPE *otherCert;
	};

/* This is also defined in pkcs7.h but we duplicate it
 * to allow the CMS code to be independent of PKCS#7
 */

struct CMS_IssuerAndSerialNumber_st
	{
	X509_NAME *issuer;
	ASN1_INTEGER *serialNumber;
	};

struct CMS_OtherKeyAttribute_st
	{
	ASN1_OBJECT *keyAttrId;
 	ASN1_TYPE *keyAttr;
	};

/* ESS structures */

#ifdef HEADER_X509V3_H

struct CMS_ReceiptRequest_st
	{
	ASN1_OCTET_STRING *signedContentIdentifier;
	CMS_ReceiptsFrom *receiptsFrom;
	STACK_OF(GENERAL_NAMES) *receiptsTo;
	};


struct CMS_ReceiptsFrom_st
	{
	int type;
	union
		{
		long allOrFirstTier;
		STACK_OF(GENERAL_NAMES) *receiptList;
		} d;
	};
#endif

struct CMS_Receipt_st
	{
	long version;
	ASN1_OBJECT *contentType;
	ASN1_OCTET_STRING *signedContentIdentifier;
	ASN1_OCTET_STRING *originatorSignatureValue;
	};

DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
DECLARE_ASN1_ITEM(CMS_SignerInfo)
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)

#define CMS_SIGNERINFO_ISSUER_SERIAL	0
#define CMS_SIGNERINFO_KEYIDENTIFIER	1

#define CMS_RECIPINFO_ISSUER_SERIAL	0
#define CMS_RECIPINFO_KEYIDENTIFIER	1

BIO *cms_content_bio(CMS_ContentInfo *cms);

CMS_ContentInfo *cms_Data_create(void);

CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);

BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno);
int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);

CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);

void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
					X509_ALGOR *mdalg);

BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
				const EVP_CIPHER *cipher,
				const unsigned char *key, size_t keylen);

int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);

BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
	
#ifdef  __cplusplus
}
#endif
#endif

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_lib.c
/* crypto/cms/cms_lib.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/asn1t.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include "cms.h"
#include "cms_lcl.h"

IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)

DECLARE_ASN1_ITEM(CMS_CertificateChoices)
DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
DECLARE_STACK_OF(CMS_CertificateChoices)
DECLARE_STACK_OF(CMS_RevocationInfoChoice)

const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
	{
	return cms->contentType;
	}

CMS_ContentInfo *cms_Data_create(void)
	{
	CMS_ContentInfo *cms;
	cms = CMS_ContentInfo_new();
	if (cms)
		{
		cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
		/* Never detached */
		CMS_set_detached(cms, 0);
		}
	return cms;
	}

BIO *cms_content_bio(CMS_ContentInfo *cms)
	{
	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
	if (!pos)
		return NULL;
	/* If content detached data goes nowhere: create NULL BIO */
	if (!*pos)
		return BIO_new(BIO_s_null());
	/* If content not detached and created return memory BIO
	 */
	if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
		return BIO_new(BIO_s_mem());
	/* Else content was read in: return read only BIO for it */
	return BIO_new_mem_buf((*pos)->data, (*pos)->length);
	}

BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
	{
	BIO *cmsbio, *cont;
	if (icont)
		cont = icont;
	else
		cont = cms_content_bio(cms);
	if (!cont)
		{
		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
		return NULL;
		}
	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_data:
		return cont;

		case NID_pkcs7_signed:
		cmsbio = cms_SignedData_init_bio(cms);
		break;

		case NID_pkcs7_digest:
		cmsbio = cms_DigestedData_init_bio(cms);
		break;
#ifdef ZLIB
		case NID_id_smime_ct_compressedData:
		cmsbio = cms_CompressedData_init_bio(cms);
		break;
#endif

		case NID_pkcs7_encrypted:
		cmsbio = cms_EncryptedData_init_bio(cms);
		break;

		case NID_pkcs7_enveloped:
		cmsbio = cms_EnvelopedData_init_bio(cms);
		break;

		default:
		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
		return NULL;
		}

	if (cmsbio)
		return BIO_push(cmsbio, cont);

	if (!icont)
		BIO_free(cont);
	return NULL;

	}

int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
	{
	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
	if (!pos)
		return 0;
	/* If ebmedded content find memory BIO and set content */
	if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
		{
		BIO *mbio;
		unsigned char *cont;
		long contlen;
		mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
		if (!mbio)
			{
			CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
			return 0;
			}
		contlen = BIO_get_mem_data(mbio, &cont);
		/* Set bio as read only so its content can't be clobbered */
		BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(mbio, 0);
		ASN1_STRING_set0(*pos, cont, contlen);
		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
		}

	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_data:
		case NID_pkcs7_enveloped:
		case NID_pkcs7_encrypted:
		case NID_id_smime_ct_compressedData:
		/* Nothing to do */
		return 1;

		case NID_pkcs7_signed:
		return cms_SignedData_final(cms, cmsbio);

		case NID_pkcs7_digest:
		return cms_DigestedData_do_final(cms, cmsbio, 0);

		default:
		CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
		return 0;
		}
	}

/* Return an OCTET STRING pointer to content. This allows it to
 * be accessed or set later.
 */

ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
	{
	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_data:
		return &cms->d.data;

		case NID_pkcs7_signed:
		return &cms->d.signedData->encapContentInfo->eContent;

		case NID_pkcs7_enveloped:
		return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;

		case NID_pkcs7_digest:
		return &cms->d.digestedData->encapContentInfo->eContent;

		case NID_pkcs7_encrypted:
		return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;

		case NID_id_smime_ct_authData:
		return &cms->d.authenticatedData->encapContentInfo->eContent;

		case NID_id_smime_ct_compressedData:
		return &cms->d.compressedData->encapContentInfo->eContent;

		default:
		if (cms->d.other->type == V_ASN1_OCTET_STRING)
			return &cms->d.other->value.octet_string;
		CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
		return NULL;

		}
	}

/* Return an ASN1_OBJECT pointer to content type. This allows it to
 * be accessed or set later.
 */

static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
	{
	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_signed:
		return &cms->d.signedData->encapContentInfo->eContentType;

		case NID_pkcs7_enveloped:
		return &cms->d.envelopedData->encryptedContentInfo->contentType;

		case NID_pkcs7_digest:
		return &cms->d.digestedData->encapContentInfo->eContentType;

		case NID_pkcs7_encrypted:
		return &cms->d.encryptedData->encryptedContentInfo->contentType;

		case NID_id_smime_ct_authData:
		return &cms->d.authenticatedData->encapContentInfo->eContentType;

		case NID_id_smime_ct_compressedData:
		return &cms->d.compressedData->encapContentInfo->eContentType;

		default:
		CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
					CMS_R_UNSUPPORTED_CONTENT_TYPE);
		return NULL;

		}
	}

const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
	{
	ASN1_OBJECT **petype;
	petype = cms_get0_econtent_type(cms);
	if (petype)
		return *petype;
	return NULL;
	}

int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
	{
	ASN1_OBJECT **petype, *etype;
	petype = cms_get0_econtent_type(cms);
	if (!petype)
		return 0;
	if (!oid)
		return 1;
	etype = OBJ_dup(oid);
	if (!etype)
		return 0;
	ASN1_OBJECT_free(*petype);
	*petype = etype;
	return 1;
	}

int CMS_is_detached(CMS_ContentInfo *cms)
	{
	ASN1_OCTET_STRING **pos;
	pos = CMS_get0_content(cms);
	if (!pos)
		return -1;
	if (*pos)
		return 0;
	return 1;
	}

int CMS_set_detached(CMS_ContentInfo *cms, int detached)
	{
	ASN1_OCTET_STRING **pos;
	pos = CMS_get0_content(cms);
	if (!pos)
		return 0;
	if (detached)
		{
		if (*pos)
			{
			ASN1_OCTET_STRING_free(*pos);
			*pos = NULL;
			}
		return 1;
		}
	if (!*pos)
		*pos = ASN1_OCTET_STRING_new();
	if (*pos)
		{
		/* NB: special flag to show content is created and not
		 * read in.
		 */
		(*pos)->flags |= ASN1_STRING_FLAG_CONT;
		return 1;
		}
	CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
	return 0;
	}

/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */

void cms_DigestAlgorithm_set(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);

	}

/* Create a digest BIO from an X509_ALGOR structure */

BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
	{
	BIO *mdbio = NULL;
	ASN1_OBJECT *digestoid;
	const EVP_MD *digest;
	X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
	digest = EVP_get_digestbyobj(digestoid);
	if (!digest)
		{
		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
				CMS_R_UNKNOWN_DIGEST_ALGORIHM);
		goto err;	
		}
	mdbio = BIO_new(BIO_f_md());
	if (!mdbio || !BIO_set_md(mdbio, digest))
		{
		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
				CMS_R_MD_BIO_INIT_ERROR);
		goto err;	
		}
	return mdbio;
	err:
	if (mdbio)
		BIO_free(mdbio);
	return NULL;
	}

/* Locate a message digest content from a BIO chain based on SignerInfo */

int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
					X509_ALGOR *mdalg)
	{
	int nid;
	ASN1_OBJECT *mdoid;
	X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
	nid = OBJ_obj2nid(mdoid);
	/* Look for digest type to match signature */
	for (;;)
		{
		EVP_MD_CTX *mtmp;
		chain = BIO_find_type(chain, BIO_TYPE_MD);
		if (chain == NULL)
			{
			CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
						CMS_R_NO_MATCHING_DIGEST);
			return 0;
			}
		BIO_get_md_ctx(chain, &mtmp);
		if (EVP_MD_CTX_type(mtmp) == nid)
			{
			EVP_MD_CTX_copy_ex(mctx, mtmp);
			return 1;
			}
		chain = BIO_next(chain);
		}
	}

static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
	{
	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_signed:
		return &cms->d.signedData->certificates;

		case NID_pkcs7_enveloped:
		return &cms->d.envelopedData->originatorInfo->certificates;

		default:
		CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
					CMS_R_UNSUPPORTED_CONTENT_TYPE);
		return NULL;

		}
	}

CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
	{
	STACK_OF(CMS_CertificateChoices) **pcerts;
	CMS_CertificateChoices *cch;
	pcerts = cms_get0_certificate_choices(cms);
	if (!pcerts)
		return NULL;
	if (!*pcerts)
		*pcerts = sk_CMS_CertificateChoices_new_null();
	if (!*pcerts)
		return NULL;
	cch = M_ASN1_new_of(CMS_CertificateChoices);
	if (!cch)
		return NULL;
	if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
		{
		M_ASN1_free_of(cch, CMS_CertificateChoices);
		return NULL;
		}
	return cch;
	}

int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
	{
	CMS_CertificateChoices *cch;
	STACK_OF(CMS_CertificateChoices) **pcerts;
	int i;
	pcerts = cms_get0_certificate_choices(cms);
	if (!pcerts)
		return 0;
	if (!pcerts)
		return 0;
	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
		{
		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
		if (cch->type == CMS_CERTCHOICE_CERT)
			{
			if (!X509_cmp(cch->d.certificate, cert))
				{
				CMSerr(CMS_F_CMS_ADD0_CERT, 
					CMS_R_CERTIFICATE_ALREADY_PRESENT);
				return 0;
				}
			}
		}
	cch = CMS_add0_CertificateChoices(cms);
	if (!cch)
		return 0;
	cch->type = CMS_CERTCHOICE_CERT;
	cch->d.certificate = cert;
	return 1;
	}

int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
	{
	int r;
	r = CMS_add0_cert(cms, cert);
	if (r > 0)
		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
	return r;
	}

static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
	{
	switch (OBJ_obj2nid(cms->contentType))
		{

		case NID_pkcs7_signed:
		return &cms->d.signedData->crls;

		case NID_pkcs7_enveloped:
		return &cms->d.envelopedData->originatorInfo->crls;

		default:
		CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
					CMS_R_UNSUPPORTED_CONTENT_TYPE);
		return NULL;

		}
	}

CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
	{
	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
	CMS_RevocationInfoChoice *rch;
	pcrls = cms_get0_revocation_choices(cms);
	if (!pcrls)
		return NULL;
	if (!*pcrls)
		*pcrls = sk_CMS_RevocationInfoChoice_new_null();
	if (!*pcrls)
		return NULL;
	rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
	if (!rch)
		return NULL;
	if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
		{
		M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
		return NULL;
		}
	return rch;
	}

int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
	{
	CMS_RevocationInfoChoice *rch;
	rch = CMS_add0_RevocationInfoChoice(cms);
	if (!rch)
		return 0;
	rch->type = CMS_REVCHOICE_CRL;
	rch->d.crl = crl;
	return 1;
	}

int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
	{
	int r;
	r = CMS_add0_crl(cms, crl);
	if (r > 0)
		CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
	return r;
	}

STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
	{
	STACK_OF(X509) *certs = NULL;
	CMS_CertificateChoices *cch;
	STACK_OF(CMS_CertificateChoices) **pcerts;
	int i;
	pcerts = cms_get0_certificate_choices(cms);
	if (!pcerts)
		return NULL;
	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
		{
		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
		if (cch->type == 0)
			{
			if (!certs)
				{
				certs = sk_X509_new_null();
				if (!certs)
					return NULL;
				}
			if (!sk_X509_push(certs, cch->d.certificate))
				{
				sk_X509_pop_free(certs, X509_free);
				return NULL;
				}
			CRYPTO_add(&cch->d.certificate->references,
						1, CRYPTO_LOCK_X509);
			}
		}
	return certs;

	}

STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
	{
	STACK_OF(X509_CRL) *crls = NULL;
	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
	CMS_RevocationInfoChoice *rch;
	int i;
	pcrls = cms_get0_revocation_choices(cms);
	if (!pcrls)
		return NULL;
	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
		{
		rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
		if (rch->type == 0)
			{
			if (!crls)
				{
				crls = sk_X509_CRL_new_null();
				if (!crls)
					return NULL;
				}
			if (!sk_X509_CRL_push(crls, rch->d.crl))
				{
				sk_X509_CRL_pop_free(crls, X509_CRL_free);
				return NULL;
				}
			CRYPTO_add(&rch->d.crl->references,
						1, CRYPTO_LOCK_X509_CRL);
			}
		}
	return crls;
	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_sd.c
/* crypto/cms/cms_sd.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/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"
#include "asn1_locl.h"

/* CMS SignedData Utilities */

DECLARE_ASN1_ITEM(CMS_SignedData)

static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
	{
	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
		{
		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
		return NULL;
		}
	return cms->d.signedData;
	}

static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
	{
	if (cms->d.other == NULL)
		{
		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
		if (!cms->d.signedData)
			{
			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		cms->d.signedData->version = 1;
		cms->d.signedData->encapContentInfo->eContentType =
						OBJ_nid2obj(NID_pkcs7_data);
		cms->d.signedData->encapContentInfo->partial = 1;
		ASN1_OBJECT_free(cms->contentType);
		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
		return cms->d.signedData;
		}
	return cms_get0_signed(cms);
	}

/* Just initialize SignedData e.g. for certs only structure */

int CMS_SignedData_init(CMS_ContentInfo *cms)
	{
	if (cms_signed_data_init(cms))
		return 1;
	else
		return 0;
	}

/* Check structures and fixup version numbers (if necessary) */

static void cms_sd_set_version(CMS_SignedData *sd)
	{
	int i;
	CMS_CertificateChoices *cch;
	CMS_RevocationInfoChoice *rch;
	CMS_SignerInfo *si;

	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
		{
		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
		if (cch->type == CMS_CERTCHOICE_OTHER)
			{
			if (sd->version < 5)
				sd->version = 5;
			}
		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
			{
			if (sd->version < 4)
				sd->version = 4;
			}
		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
			{
			if (sd->version < 3)
				sd->version = 3;
			}
		}

	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
		{
		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
		if (rch->type == CMS_REVCHOICE_OTHER)
			{
			if (sd->version < 5)
				sd->version = 5;
			}
		}

	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
			&& (sd->version < 3))
		sd->version = 3;

	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
			{
			if (si->version < 3)
				si->version = 3;
			if (sd->version < 3)
				sd->version = 3;
			}
		else
			sd->version = 1;
		}

	if (sd->version < 1)
		sd->version = 1;

	}
	
/* Copy an existing messageDigest value */

static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
	{
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *sitmp;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		ASN1_OCTET_STRING *messageDigest;
		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
		if (sitmp == si)
			continue;
		if (CMS_signed_get_attr_count(sitmp) < 0)
			continue;
		if (OBJ_cmp(si->digestAlgorithm->algorithm,
				sitmp->digestAlgorithm->algorithm))
			continue;
		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
					OBJ_nid2obj(NID_pkcs9_messageDigest),
					-3, V_ASN1_OCTET_STRING);
		if (!messageDigest)
			{
			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
			return 0;
			}

		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
						V_ASN1_OCTET_STRING,
						messageDigest, -1))
			return 1;
		else
			return 0;
		}
		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
		return 0;
	}

int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
	{
	switch(type)
		{
		case CMS_SIGNERINFO_ISSUER_SERIAL:
		sid->d.issuerAndSerialNumber =
			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
		if (!sid->d.issuerAndSerialNumber)
			goto merr;
		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
					X509_get_issuer_name(cert)))
			goto merr;
		if (!ASN1_STRING_copy(
			sid->d.issuerAndSerialNumber->serialNumber,
				X509_get_serialNumber(cert)))
			goto merr;
		break;

		case CMS_SIGNERINFO_KEYIDENTIFIER:
		if (!cert->skid)
			{
			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
					CMS_R_CERTIFICATE_HAS_NO_KEYID);
			return 0;
			}
		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
		if (!sid->d.subjectKeyIdentifier)
			goto merr;
		break;

		default:
		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
		return 0;
		}

	sid->type = type;

	return 1;

	merr:
	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
	return 0;

	}

int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
		{
		if (issuer)
			*issuer = sid->d.issuerAndSerialNumber->issuer;
		if (sno)
			*sno = sid->d.issuerAndSerialNumber->serialNumber;
		}
	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
		{
		if (keyid)
			*keyid = sid->d.subjectKeyIdentifier;
		}
	else
		return 0;
	return 1;
	}

int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
	{
	int ret;
	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
		{
		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
					X509_get_issuer_name(cert));
		if (ret)
			return ret;
		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
					X509_get_serialNumber(cert));
		}
	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
		{
		X509_check_purpose(cert, -1, -1);
		if (!cert->skid)
			return -1;
		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
							cert->skid);
		}
	else
		return -1;
	}

CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
			unsigned int flags)
	{
	CMS_SignedData *sd;
	CMS_SignerInfo *si = NULL;
	X509_ALGOR *alg;
	int i, type;
	if(!X509_check_private_key(signer, pk))
		{
		CMSerr(CMS_F_CMS_ADD1_SIGNER,
			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
                return NULL;
		}
	sd = cms_signed_data_init(cms);
	if (!sd)
		goto err;
	si = M_ASN1_new_of(CMS_SignerInfo);
	if (!si)
		goto merr;
	X509_check_purpose(signer, -1, -1);

	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);

	si->pkey = pk;
	si->signer = signer;

	if (flags & CMS_USE_KEYID)
		{
		si->version = 3;
		if (sd->version < 3)
			sd->version = 3;
		type = CMS_SIGNERINFO_KEYIDENTIFIER;
		}
	else
		{
		type = CMS_SIGNERINFO_ISSUER_SERIAL;
		si->version = 1;
		}

	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
		goto err;

	if (md == NULL)
		{
		int def_nid;
		if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
			goto err;
		md = EVP_get_digestbynid(def_nid);
		if (md == NULL)
			{
			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
			goto err;
			}
		}

	if (!md)
		{
		CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
		goto err;
		}

	cms_DigestAlgorithm_set(si->digestAlgorithm, md);

	/* See if digest is present in digestAlgorithms */
	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
		{
		ASN1_OBJECT *aoid;
		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
			break;
		}

	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
		{
		alg = X509_ALGOR_new();
		if (!alg)
			goto merr;
		cms_DigestAlgorithm_set(alg, md);
		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
			{
			X509_ALGOR_free(alg);
			goto merr;
			}
		}

	if (pk->ameth && pk->ameth->pkey_ctrl)
		{
		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
						0, si);
		if (i == -2)
			{
			CMSerr(CMS_F_CMS_ADD1_SIGNER,
				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
			goto err;
			}
		if (i <= 0)
			{
			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
			goto err;
			}
		}

	if (!(flags & CMS_NOATTR))
		{
		/* Initialialize signed attributes strutucture so other
		 * attributes such as signing time etc are added later
		 * even if we add none here.
		 */
		if (!si->signedAttrs)
			{
			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
			if (!si->signedAttrs)
				goto merr;
			}

		if (!(flags & CMS_NOSMIMECAP))
			{
			STACK_OF(X509_ALGOR) *smcap = NULL;
			i = CMS_add_standard_smimecap(&smcap);
			if (i)
				i = CMS_add_smimecap(si, smcap);
			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
			if (!i)
				goto merr;
			}
		if (flags & CMS_REUSE_DIGEST)
			{
			if (!cms_copy_messageDigest(cms, si))
				goto err;
			if (!(flags & CMS_PARTIAL) &&
					!CMS_SignerInfo_sign(si))
				goto err;
			}
		}

	if (!(flags & CMS_NOCERTS))
		{
		/* NB ignore -1 return for duplicate cert */
		if (!CMS_add1_cert(cms, signer))
			goto merr;
		}

	if (!sd->signerInfos)
		sd->signerInfos = sk_CMS_SignerInfo_new_null();
	if (!sd->signerInfos ||
		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
		goto merr;

	return si;

	merr:
	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
	err:
	if (si)
		M_ASN1_free_of(si, CMS_SignerInfo);
	return NULL;

	}

static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
	{
	ASN1_TIME *tt;
	int r = 0;
	if (t)
		tt = t;
	else
		tt = X509_gmtime_adj(NULL, 0);

	if (!tt)
		goto merr;

	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
						tt->type, tt, -1) <= 0)
		goto merr;

	r = 1;

	merr:

	if (!t)
		ASN1_TIME_free(tt);

	if (!r)
		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);

	return r;

	}

STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
	{
	CMS_SignedData *sd;
	sd = cms_get0_signed(cms);
	if (!sd)
		return NULL;
	return sd->signerInfos;
	}

STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
	{
	STACK_OF(X509) *signers = NULL;
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *si;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sinfos, i);
		if (si->signer)
			{
			if (!signers)
				{
				signers = sk_X509_new_null();
				if (!signers)
					return NULL;
				}
			if (!sk_X509_push(signers, si->signer))
				{
				sk_X509_free(signers);
				return NULL;
				}
			}
		}
	return signers;
	}

void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
	{
	if (signer)
		{
		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
		if (si->pkey)
			EVP_PKEY_free(si->pkey);
		si->pkey = X509_get_pubkey(signer);
		}
	if (si->signer)
		X509_free(si->signer);
	si->signer = signer;
	}

int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
	}

int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
	{
	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
	}

int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
				unsigned int flags)
	{
	CMS_SignedData *sd;
	CMS_SignerInfo *si;
	CMS_CertificateChoices *cch;
	STACK_OF(CMS_CertificateChoices) *certs;
	X509 *x;
	int i, j;
	int ret = 0;
	sd = cms_get0_signed(cms);
	if (!sd)
		return -1;
	certs = sd->certificates;
	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
		if (si->signer)
			continue;

		for (j = 0; j < sk_X509_num(scerts); j++)
			{
			x = sk_X509_value(scerts, j);
			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
				{
				CMS_SignerInfo_set1_signer_cert(si, x);
				ret++;
				break;
				}
			}

		if (si->signer || (flags & CMS_NOINTERN))
			continue;

		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
			{
			cch = sk_CMS_CertificateChoices_value(certs, j);
			if (cch->type != 0)
				continue;
			x = cch->d.certificate;
			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
				{
				CMS_SignerInfo_set1_signer_cert(si, x);
				ret++;
				break;
				}
			}
		}
	return ret;
	}

void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
					X509_ALGOR **pdig, X509_ALGOR **psig)
	{
	if (pk)
		*pk = si->pkey;
	if (signer)
		*signer = si->signer;
	if (pdig)
		*pdig = si->digestAlgorithm;
	if (psig)
		*psig = si->signatureAlgorithm;
	}

static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
					CMS_SignerInfo *si, BIO *chain)
	{
	EVP_MD_CTX mctx;
	int r = 0;
	EVP_MD_CTX_init(&mctx);


	if (!si->pkey)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
		return 0;
		}

	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
		goto err;

	/* If any signed attributes calculate and add messageDigest attribute */

	if (CMS_signed_get_attr_count(si) >= 0)
		{
		ASN1_OBJECT *ctype =
			cms->d.signedData->encapContentInfo->eContentType; 
		unsigned char md[EVP_MAX_MD_SIZE];
		unsigned int mdlen;
		EVP_DigestFinal_ex(&mctx, md, &mdlen);
		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
						V_ASN1_OCTET_STRING,
						md, mdlen))
			goto err;
		/* Copy content type across */
		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
					V_ASN1_OBJECT, ctype, -1) <= 0)
			goto err;
		if (!CMS_SignerInfo_sign(si))
			goto err;
		}
	else
		{
		unsigned char *sig;
		unsigned int siglen;
		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
		if (!sig)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
					ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
					CMS_R_SIGNFINAL_ERROR);
			OPENSSL_free(sig);
			goto err;
			}
		ASN1_STRING_set0(si->signature, sig, siglen);
		}

	r = 1;

	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;

	}

int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
	{
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *si;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sinfos, i);
		if (!cms_SignerInfo_content_sign(cms, si, chain))
			return 0;
		}
	cms->d.signedData->encapContentInfo->partial = 0;
	return 1;
	}

int CMS_SignerInfo_sign(CMS_SignerInfo *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->digestAlgorithm->algorithm);
	if (md == NULL)
		return 0;

	EVP_MD_CTX_init(&mctx);

	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
		{
		if (!cms_add1_signingTime(si, NULL))
			goto err;
		}

	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_CMS_SIGN, 0, si) <= 0)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
		goto err;
		}

	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
				ASN1_ITEM_rptr(CMS_Attributes_Sign));
	if(!abuf)
		goto err;
	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
		goto err;
	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
		goto err;
	OPENSSL_free(abuf);
	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_CMS_SIGN, 1, si) <= 0)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
		goto err;
		}

	EVP_MD_CTX_cleanup(&mctx);

	ASN1_STRING_set0(si->signature, abuf, siglen);

	return 1;

	err:
	if (abuf)
		OPENSSL_free(abuf);
	EVP_MD_CTX_cleanup(&mctx);
	return 0;

	}

int CMS_SignerInfo_verify(CMS_SignerInfo *si)
	{
	EVP_MD_CTX mctx;
	EVP_PKEY_CTX *pctx;
	unsigned char *abuf = NULL;
	int alen, r = -1;
	const EVP_MD *md = NULL;

	if (!si->pkey)
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
		return -1;
		}

	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
	if (md == NULL)
		return -1;
	EVP_MD_CTX_init(&mctx);
	if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
		goto err;

	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
				ASN1_ITEM_rptr(CMS_Attributes_Verify));
	if(!abuf)
		goto err;
	r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
	OPENSSL_free(abuf);
	if (r <= 0)
		{
		r = -1;
		goto err;
		}
	r = EVP_DigestVerifyFinal(&mctx,
			si->signature->data, si->signature->length);
	if (!r)
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;
	}

/* Create a chain of digest BIOs from a CMS ContentInfo */

BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
	{
	int i;
	CMS_SignedData *sd;
	BIO *chain = NULL;
	sd = cms_get0_signed(cms);
	if (!sd)
		return NULL;
	if (cms->d.signedData->encapContentInfo->partial)
		cms_sd_set_version(sd);
	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
		{
		X509_ALGOR *digestAlgorithm;
		BIO *mdbio;
		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
		if (!mdbio)
			goto err;	
		if (chain)
			 BIO_push(chain, mdbio);
		else
			chain = mdbio;
		}
	return chain;
	err:
	if (chain)
		BIO_free_all(chain);
	return NULL;
	}

int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
	{
	ASN1_OCTET_STRING *os = NULL;
	EVP_MD_CTX mctx;
	int r = -1;
	EVP_MD_CTX_init(&mctx);
	/* If we have any signed attributes look for messageDigest value */
	if (CMS_signed_get_attr_count(si) >= 0)
		{
		os = CMS_signed_get0_data_by_OBJ(si,
					OBJ_nid2obj(NID_pkcs9_messageDigest),
					-3, V_ASN1_OCTET_STRING);
		if (!os)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
			goto err;
			}
		}

	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
		goto err;

	/* If messageDigest found compare it */

	if (os)
		{
		unsigned char mval[EVP_MAX_MD_SIZE];
		unsigned int mlen;
		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
			goto err;
			}
		if (mlen != (unsigned int)os->length)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
			goto err;
			}

		if (memcmp(mval, os->data, mlen))
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_VERIFICATION_FAILURE);
			r = 0;
			}
		else
			r = 1;
		}
	else
		{
		r = EVP_VerifyFinal(&mctx, si->signature->data,
					si->signature->length, si->pkey);
		if (r <= 0)
			{
			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
				CMS_R_VERIFICATION_FAILURE);
			r = 0;
			}
		}

	err:
	EVP_MD_CTX_cleanup(&mctx);
	return r;

	}

int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
	{
	unsigned char *smder = NULL;
	int smderlen, r;
	smderlen = i2d_X509_ALGORS(algs, &smder);
	if (smderlen <= 0)
		return 0;
	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
					V_ASN1_SEQUENCE, smder, smderlen);
	OPENSSL_free(smder);
	return r;
	}

int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
				int algnid, int keysize)
	{
	X509_ALGOR *alg;
	ASN1_INTEGER *key = NULL;
	if (keysize > 0)
		{
		key = ASN1_INTEGER_new();
		if (!key || !ASN1_INTEGER_set(key, keysize))
			return 0;
		}
	alg = X509_ALGOR_new();
	if (!alg)
		{
		if (key)
			ASN1_INTEGER_free(key);
		return 0;
		}
		
	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
	if (!*algs)
		*algs = sk_X509_ALGOR_new_null();
	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
		{
		X509_ALGOR_free(alg);
		return 0;
		}
	return 1;
	}

/* Check to see if a cipher exists and if so add S/MIME capabilities */

static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
	{
	if (EVP_get_cipherbynid(nid))
		return CMS_add_simple_smimecap(sk, nid, arg);
	return 1;
	}

static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
	{
	if (EVP_get_digestbynid(nid))
		return CMS_add_simple_smimecap(sk, nid, arg);
	return 1;
	}

int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
	{
	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
		|| !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
		|| !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
		return 0;
	return 1;
	}

File Added: src/crypto/dist/openssl/crypto/cms/Attic/cms_smime.c
/* crypto/cms/cms_smime.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/asn1t.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"

static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
	{
	unsigned char buf[4096];
	int r = 0, i;
	BIO *tmpout = NULL;

	if (out == NULL)
		tmpout = BIO_new(BIO_s_null());
	else if (flags & CMS_TEXT)
		tmpout = BIO_new(BIO_s_mem());
	else
		tmpout = out;

	if(!tmpout)
		{
		CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	/* Read all content through chain to process digest, decrypt etc */
	for (;;)
	{
		i=BIO_read(in,buf,sizeof(buf));
		if (i <= 0)
			{
			if (BIO_method_type(in) == BIO_TYPE_CIPHER)
				{
				if (!BIO_get_cipher_status(in))
					goto err;
				}
			break;
			}
				
		if (tmpout)
			BIO_write(tmpout, buf, i);
	}

	if(flags & CMS_TEXT)
		{
		if(!SMIME_text(tmpout, out))
			{
			CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
			goto err;
			}
		}

	r = 1;

	err:
	if (tmpout && (tmpout != out))
		BIO_free(tmpout);
	return r;

	}

static int check_content(CMS_ContentInfo *cms)
	{
	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
	if (!pos || !*pos)
		{
		CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
		return 0;
		}
	return 1;
	}

static void do_free_upto(BIO *f, BIO *upto)
	{
	if (upto)
		{
		BIO *tbio;
		do 
			{
			tbio = BIO_pop(f);
			BIO_free(f);
			f = tbio;
			}
		while (f != upto);
		}
	else
		BIO_free_all(f);
	}

int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
	{
	BIO *cont;
	int r;
	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
		{
		CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
		return 0;
		}
	cont = CMS_dataInit(cms, NULL);
	if (!cont)
		return 0;
	r = cms_copy_content(out, cont, flags);
	BIO_free_all(cont);
	return r;
	}

CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
	{
	CMS_ContentInfo *cms;
	cms = cms_Data_create();
	if (!cms)
		return NULL;

	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
		return cms;

	CMS_ContentInfo_free(cms);

	return NULL;
	}

int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
							unsigned int flags)
	{
	BIO *cont;
	int r;
	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
		{
		CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
		return 0;
		}

	if (!dcont && !check_content(cms))
		return 0;

	cont = CMS_dataInit(cms, dcont);
	if (!cont)
		return 0;
	r = cms_copy_content(out, cont, flags);
	if (r)
		r = cms_DigestedData_do_final(cms, cont, 1);
	do_free_upto(cont, dcont);
	return r;
	}

CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
					unsigned int flags)
	{
	CMS_ContentInfo *cms;
	if (!md)
		md = EVP_sha1();
	cms = cms_DigestedData_create(md);
	if (!cms)
		return NULL;

	if(!(flags & CMS_DETACHED))
		CMS_set_detached(cms, 0);

	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
		return cms;

	CMS_ContentInfo_free(cms);
	return NULL;
	}

int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
				const unsigned char *key, size_t keylen,
				BIO *dcont, BIO *out, unsigned int flags)
	{
	BIO *cont;
	int r;
	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
					CMS_R_TYPE_NOT_ENCRYPTED_DATA);
		return 0;
		}

	if (!dcont && !check_content(cms))
		return 0;

	if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
		return 0;
	cont = CMS_dataInit(cms, dcont);
	if (!cont)
		return 0;
	r = cms_copy_content(out, cont, flags);
	do_free_upto(cont, dcont);
	return r;
	}

CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
					const unsigned char *key, size_t keylen,
					unsigned int flags)
	{
	CMS_ContentInfo *cms;
	if (!cipher)
		{
		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
		return NULL;
		}
	cms = CMS_ContentInfo_new();
	if (!cms)
		return NULL;
	if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
		return NULL;

	if(!(flags & CMS_DETACHED))
		CMS_set_detached(cms, 0);

	if ((flags & (CMS_STREAM|CMS_PARTIAL))
		|| CMS_final(cms, in, NULL, flags))
		return cms;

	CMS_ContentInfo_free(cms);
	return NULL;
	}

static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
					X509_STORE *store,
					STACK_OF(X509) *certs,
					STACK_OF(X509_CRL) *crls,
					unsigned int flags)
	{
	X509_STORE_CTX ctx;
	X509 *signer;
	int i, j, r = 0;
	CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
	if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
		{
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
						CMS_R_STORE_INIT_ERROR);
		goto err;
		}
	X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_SMIME_SIGN);
	if (crls)
		X509_STORE_CTX_set0_crls(&ctx, crls);

	i = X509_verify_cert(&ctx);
	if (i <= 0)
		{
		j = X509_STORE_CTX_get_error(&ctx);
		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
						CMS_R_CERTIFICATE_VERIFY_ERROR);
		ERR_add_error_data(2, "Verify error:",
					 X509_verify_cert_error_string(j));
		goto err;
		}
	r = 1;
	err:
	X509_STORE_CTX_cleanup(&ctx);
	return r;

	}

int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
	{
	CMS_SignerInfo *si;
	STACK_OF(CMS_SignerInfo) *sinfos;
	STACK_OF(X509) *cms_certs = NULL;
	STACK_OF(X509_CRL) *crls = NULL;
	X509 *signer;
	int i, scount = 0, ret = 0;
	BIO *cmsbio = NULL, *tmpin = NULL;

	if (!dcont && !check_content(cms))
		return 0;

	/* Attempt to find all signer certificates */

	sinfos = CMS_get0_SignerInfos(cms);

	if (sk_CMS_SignerInfo_num(sinfos) <= 0)
		{
		CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
		goto err;
		}

	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		si = sk_CMS_SignerInfo_value(sinfos, i);
		CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
		if (signer)
			scount++;
		}

	if (scount != sk_CMS_SignerInfo_num(sinfos))
		scount += CMS_set1_signers_certs(cms, certs, flags);

	if (scount != sk_CMS_SignerInfo_num(sinfos))
		{
		CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
		goto err;
		}

	/* Attempt to verify all signers certs */

	if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
		{
		cms_certs = CMS_get1_certs(cms);
		if (!(flags & CMS_NOCRL))
			crls = CMS_get1_crls(cms);
		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
			{
			si = sk_CMS_SignerInfo_value(sinfos, i);
			if (!cms_signerinfo_verify_cert(si, store,
							cms_certs, crls, flags))
				goto err;
			}
		}

	/* Attempt to verify all SignerInfo signed attribute signatures */

	if (!(flags & CMS_NO_ATTR_VERIFY))
		{
		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
			{
			si = sk_CMS_SignerInfo_value(sinfos, i);
			if (CMS_signed_get_attr_count(si) < 0)
				continue;
			if (CMS_SignerInfo_verify(si) <= 0)
				goto err;
			}
		}

	/* 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 (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
		{
		char *ptr;
		long len;
		len = BIO_get_mem_data(dcont, &ptr);
		tmpin = BIO_new_mem_buf(ptr, len);
		if (tmpin == NULL)
			{
			CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
			return 0;
			}
		}
	else
		tmpin = dcont;
		

	cmsbio=CMS_dataInit(cms, tmpin);
	if (!cmsbio)
		goto err;

	if (!cms_copy_content(out, cmsbio, flags))
		goto err;

	if (!(flags & CMS_NO_CONTENT_VERIFY))
		{
		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
			{
			si = sk_CMS_SignerInfo_value(sinfos, i);
			if (!CMS_SignerInfo_verify_content(si, cmsbio))
				{
				CMSerr(CMS_F_CMS_VERIFY,
					CMS_R_CONTENT_VERIFY_ERROR);
				goto err;
				}
			}
		}

	ret = 1;

	err:
	
	if (dcont && (tmpin == dcont))
		do_free_upto(cmsbio, dcont);
	else
		BIO_free_all(cmsbio);

	if (cms_certs)
		sk_X509_pop_free(cms_certs, X509_free);
	if (crls)
		sk_X509_CRL_pop_free(crls, X509_CRL_free);

	return ret;
	}

int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
			STACK_OF(X509) *certs,
			X509_STORE *store, unsigned int flags)
	{
	int r;
	flags &= ~(CMS_DETACHED|CMS_TEXT);
	r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
	if (r <= 0)
		return r;
	return cms_Receipt_verify(rcms, ocms);
	}

CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
						BIO *data, unsigned int flags)
	{
	CMS_ContentInfo *cms;
	int i;

	cms = CMS_ContentInfo_new();
	if (!cms || !CMS_SignedData_init(cms))
		goto merr;

	if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
		{
		CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
		goto err;
		}

	for (i = 0; i < sk_X509_num(certs); i++)
		{
		X509 *x = sk_X509_value(certs, i);
		if (!CMS_add1_cert(cms, x))
			goto merr;
		}

	if(!(flags & CMS_DETACHED))
		CMS_set_detached(cms, 0);

	if ((flags & (CMS_STREAM|CMS_PARTIAL))
		|| CMS_final(cms, data, NULL, flags))
		return cms;
	else
		goto err;

	merr:
	CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);

	err:
	if (cms)
		CMS_ContentInfo_free(cms);
	return NULL;
	}

CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
					X509 *signcert, EVP_PKEY *pkey,
					STACK_OF(X509) *certs,
					unsigned int flags)
	{
	CMS_SignerInfo *rct_si;
	CMS_ContentInfo *cms = NULL;
	ASN1_OCTET_STRING **pos, *os;
	BIO *rct_cont = NULL;
	int r = 0;

	flags &= ~(CMS_STREAM|CMS_TEXT);
	/* Not really detached but avoids content being allocated */
	flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
	if (!pkey || !signcert)
		{
		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
		return NULL;
		}

	/* Initialize signed data */

	cms = CMS_sign(NULL, NULL, certs, NULL, flags);
	if (!cms)
		goto err;

	/* Set inner content type to signed receipt */
	if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
		goto err;

	rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
	if (!rct_si)
		{
		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
		goto err;
		}

	os = cms_encode_Receipt(si);

	if (!os)
		goto err;

	/* Set content to digest */
	rct_cont = BIO_new_mem_buf(os->data, os->length);
	if (!rct_cont)
		goto err;

	/* Add msgSigDigest attribute */

	if (!cms_msgSigDigest_add1(rct_si, si))
		goto err;

	/* Finalize structure */
	if (!CMS_final(cms, rct_cont, NULL, flags))
		goto err;

	/* Set embedded content */
	pos = CMS_get0_content(cms);
	*pos = os;

	r = 1;

	err:
	if (rct_cont)
		BIO_free(rct_cont);
	if (r)
		return cms;
	CMS_ContentInfo_free(cms);
	return NULL;

	}

CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
				const EVP_CIPHER *cipher, unsigned int flags)
	{
	CMS_ContentInfo *cms;
	int i;
	X509 *recip;
	cms = CMS_EnvelopedData_create(cipher);
	if (!cms)
		goto merr;
	for (i = 0; i < sk_X509_num(certs); i++)
		{
		recip = sk_X509_value(certs, i);
		if (!CMS_add1_recipient_cert(cms, recip, flags))
			{
			CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
			goto err;
			}
		}

	if(!(flags & CMS_DETACHED))
		CMS_set_detached(cms, 0);

	if ((flags & (CMS_STREAM|CMS_PARTIAL))
		|| CMS_final(cms, data, NULL, flags))
		return cms;
	else
		goto err;

	merr:
	CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
	err:
	if (cms)
		CMS_ContentInfo_free(cms);
	return NULL;
	}

int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
	{
	STACK_OF(CMS_RecipientInfo) *ris;
	CMS_RecipientInfo *ri;
	int i, r;
	ris = CMS_get0_RecipientInfos(cms);
	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
		{
		ri = sk_CMS_RecipientInfo_value(ris, i);
		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
				continue;
		/* If we have a cert try matching RecipientInfo
		 * otherwise try them all.
		 */
		if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
			{
			CMS_RecipientInfo_set0_pkey(ri, pk);
			r = CMS_RecipientInfo_decrypt(cms, ri);
			CMS_RecipientInfo_set0_pkey(ri, NULL);
			if (r > 0)
				return 1;
			if (cert)
				{
				CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
						CMS_R_DECRYPT_ERROR);
				return 0;
				}
			ERR_clear_error();
			}
		}

	CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
	return 0;

	}

int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
				unsigned char *key, size_t keylen,
				unsigned char *id, size_t idlen)
	{
	STACK_OF(CMS_RecipientInfo) *ris;
	CMS_RecipientInfo *ri;
	int i, r;
	ris = CMS_get0_RecipientInfos(cms);
	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
		{
		ri = sk_CMS_RecipientInfo_value(ris, i);
		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
				continue;

		/* If we have an id try matching RecipientInfo
		 * otherwise try them all.
		 */
		if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
			{
			CMS_RecipientInfo_set0_key(ri, key, keylen);
			r = CMS_RecipientInfo_decrypt(cms, ri);
			CMS_RecipientInfo_set0_key(ri, NULL, 0);
			if (r > 0)
				return 1;
			if (id)
				{
				CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
						CMS_R_DECRYPT_ERROR);
				return 0;
				}
			ERR_clear_error();
			}
		}

	CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
	return 0;

	}
	
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
				BIO *dcont, BIO *out,
				unsigned int flags)
	{
	int r;
	BIO *cont;
	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
		{
		CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
		return 0;
		}
	if (!dcont && !check_content(cms))
		return 0;
	if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
		return 0;

	cont = CMS_dataInit(cms, dcont);
	if (!cont)
		return 0;
	r = cms_copy_content(out, cont, flags);
	do_free_upto(cont, dcont);
	return r;
	}

int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
	{
	BIO *cmsbio;
	int ret = 0;
	if (!(cmsbio = CMS_dataInit(cms, dcont)))
		{
		CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
		return 0;
		}

	SMIME_crlf_copy(data, cmsbio, flags);

	(void)BIO_flush(cmsbio);


        if (!CMS_dataFinal(cms, cmsbio))
		{
		CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
		goto err;
		}

	ret = 1;

	err:
	do_free_upto(cmsbio, dcont);

	return ret;

	}

#ifdef ZLIB

int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
							unsigned int flags)
	{
	BIO *cont;
	int r;
	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
		{
		CMSerr(CMS_F_CMS_UNCOMPRESS,
					CMS_R_TYPE_NOT_COMPRESSED_DATA);
		return 0;
		}

	if (!dcont && !check_content(cms))
		return 0;

	cont = CMS_dataInit(cms, dcont);
	if (!cont)
		return 0;
	r = cms_copy_content(out, cont, flags);
	do_free_upto(cont, dcont);
	return r;
	}

CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
	{
	CMS_ContentInfo *cms;
	if (comp_nid <= 0)
		comp_nid = NID_zlib_compression;
	cms = cms_CompressedData_create(comp_nid);
	if (!cms)
		return NULL;

	if(!(flags & CMS_DETACHED))
		CMS_set_detached(cms, 0);

	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
		return cms;

	CMS_ContentInfo_free(cms);
	return NULL;
	}

#else

int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
							unsigned int flags)
	{
	CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
	return 0;
	}

CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
	{
	CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
	return NULL;
	}

#endif

File Added: src/crypto/dist/openssl/crypto/seed/Attic/Makefile
#
# crypto/seed/Makefile
#

DIR=	seed
TOP=	../..
CC=	cc
CPP=	$(CC) -E
INCLUDES=
CFLAG=-g
MAKEFILE=	Makefile
AR=		ar r

CFLAGS= $(INCLUDES) $(CFLAG)

GENERAL=Makefile
TEST=
APPS=

LIB=$(TOP)/libcrypto.a
LIBSRC=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
LIBOBJ=seed.o seed_ecb.o seed_cbc.o seed_cfb.o seed_ofb.o

SRC= $(LIBSRC)

EXHEADER= seed.h
HEADER= seed_locl.h $(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)

top:
	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)

all:	lib

lib:	$(LIBOBJ)
	$(AR) $(LIB) $(LIBOBJ)
	$(RANLIB) $(LIB) || echo Never mind.
	@touch lib

files:
	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

links:
	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)

install:
	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
	do  \
	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
	done;

tags:
	ctags $(SRC)

tests:

lint:
	lint -DLINT $(INCLUDES) $(SRC)>fluff

depend:
	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)

dclean:
	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
	mv -f Makefile.new $(MAKEFILE)

clean:
	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff

# DO NOT DELETE THIS LINE -- make depend depends on it.

seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
seed.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
seed.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
seed.o: ../../include/openssl/seed.h ../../include/openssl/stack.h
seed.o: ../../include/openssl/symhacks.h seed.c seed_locl.h
seed_cbc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
seed_cbc.o: ../../include/openssl/opensslconf.h
seed_cbc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
seed_cbc.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
seed_cbc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
seed_cbc.o: seed_cbc.c seed_locl.h
seed_cfb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
seed_cfb.o: ../../include/openssl/opensslconf.h
seed_cfb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
seed_cfb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
seed_cfb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
seed_cfb.o: seed_cfb.c seed_locl.h
seed_ecb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
seed_ecb.o: ../../include/openssl/opensslconf.h
seed_ecb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
seed_ecb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
seed_ecb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
seed_ecb.o: seed_ecb.c
seed_ofb.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
seed_ofb.o: ../../include/openssl/opensslconf.h
seed_ofb.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
seed_ofb.o: ../../include/openssl/safestack.h ../../include/openssl/seed.h
seed_ofb.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
seed_ofb.o: seed_locl.h seed_ofb.c

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed.c
/*
 * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Neither the name of author nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#ifndef OPENSSL_NO_SEED

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <memory.h>
#endif

#include <openssl/seed.h>
#include "seed_locl.h"

static const seed_word SS[4][256] = {	{
	0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
	0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
	0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
	0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
	0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
	0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
	0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
	0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
	0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
	0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
	0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
	0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
	0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
	0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
	0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
	0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
	0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
	0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
	0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038,
	0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
	0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
	0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
	0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
	0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
	0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
	0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
	0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
	0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
	0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
	0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
	0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330,
	0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
},	{
	0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
	0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
	0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
	0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
	0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
	0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
	0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
	0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
	0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
	0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
	0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
	0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
	0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
	0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171,
	0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
	0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
	0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
	0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
	0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
	0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
	0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
	0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
	0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
	0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
	0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
	0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
	0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
	0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
	0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
	0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
	0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
	0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
},	{
	0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
	0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
	0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
	0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
	0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
	0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
	0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
	0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
	0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
	0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
	0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
	0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
	0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
	0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
	0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
	0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
	0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
	0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
	0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808,
	0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
	0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
	0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
	0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
	0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
	0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
	0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
	0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
	0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
	0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
	0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
	0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303,
	0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
},	{
	0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
	0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
	0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
	0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
	0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
	0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
	0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
	0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
	0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
	0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
	0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
	0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
	0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
	0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031,
	0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
	0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
	0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
	0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
	0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
	0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
	0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
	0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
	0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
	0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
	0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
	0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
	0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
	0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
	0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
	0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
	0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
	0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
}	};

/* key schedule constants - golden ratio */
#define KC0     0x9e3779b9
#define KC1     0x3c6ef373
#define KC2     0x78dde6e6
#define KC3     0xf1bbcdcc
#define KC4     0xe3779b99
#define KC5     0xc6ef3733
#define KC6     0x8dde6e67
#define KC7     0x1bbcdccf
#define KC8     0x3779b99e
#define KC9     0x6ef3733c
#define KC10    0xdde6e678
#define KC11    0xbbcdccf1
#define KC12    0x779b99e3
#define KC13    0xef3733c6
#define KC14    0xde6e678d
#define KC15    0xbcdccf1b


void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks)
{
	seed_word x1, x2, x3, x4;
	seed_word t0, t1;

	char2word(rawkey   , x1);
	char2word(rawkey+4 , x2);
	char2word(rawkey+8 , x3);
	char2word(rawkey+12, x4);

	t0 = (x1 + x3 - KC0) & 0xffffffff;
	t1 = (x2 - x4 + KC0) & 0xffffffff;                     KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);      KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);      KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);      KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);      KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);      KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);      KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);      KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);      KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);      KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);     KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);     KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);     KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);     KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
	KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);     KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
	KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);     KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
}

void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
{
	seed_word x1, x2, x3, x4;
	seed_word t0, t1;

	char2word(s,    x1);
	char2word(s+4,  x2);
	char2word(s+8,  x3);
	char2word(s+12, x4);
	
	E_SEED(t0, t1, x1, x2, x3, x4, 0);
	E_SEED(t0, t1, x3, x4, x1, x2, 2);
	E_SEED(t0, t1, x1, x2, x3, x4, 4);
	E_SEED(t0, t1, x3, x4, x1, x2, 6);
	E_SEED(t0, t1, x1, x2, x3, x4, 8);
	E_SEED(t0, t1, x3, x4, x1, x2, 10);
	E_SEED(t0, t1, x1, x2, x3, x4, 12);
	E_SEED(t0, t1, x3, x4, x1, x2, 14);
	E_SEED(t0, t1, x1, x2, x3, x4, 16);
	E_SEED(t0, t1, x3, x4, x1, x2, 18);
	E_SEED(t0, t1, x1, x2, x3, x4, 20);
	E_SEED(t0, t1, x3, x4, x1, x2, 22);
	E_SEED(t0, t1, x1, x2, x3, x4, 24);
	E_SEED(t0, t1, x3, x4, x1, x2, 26);
	E_SEED(t0, t1, x1, x2, x3, x4, 28);
	E_SEED(t0, t1, x3, x4, x1, x2, 30);

	word2char(x3, d);
	word2char(x4, d+4);
	word2char(x1, d+8);
	word2char(x2, d+12);
}

void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks)
{
	seed_word x1, x2, x3, x4;
	seed_word t0, t1;

	char2word(s,    x1);
	char2word(s+4,  x2);
	char2word(s+8,  x3);
	char2word(s+12, x4);
	
	E_SEED(t0, t1, x1, x2, x3, x4, 30);
	E_SEED(t0, t1, x3, x4, x1, x2, 28);
	E_SEED(t0, t1, x1, x2, x3, x4, 26);
	E_SEED(t0, t1, x3, x4, x1, x2, 24);
	E_SEED(t0, t1, x1, x2, x3, x4, 22);
	E_SEED(t0, t1, x3, x4, x1, x2, 20);
	E_SEED(t0, t1, x1, x2, x3, x4, 18);
	E_SEED(t0, t1, x3, x4, x1, x2, 16);
	E_SEED(t0, t1, x1, x2, x3, x4, 14);
	E_SEED(t0, t1, x3, x4, x1, x2, 12);
	E_SEED(t0, t1, x1, x2, x3, x4, 10);
	E_SEED(t0, t1, x3, x4, x1, x2, 8);
	E_SEED(t0, t1, x1, x2, x3, x4, 6);
	E_SEED(t0, t1, x3, x4, x1, x2, 4);
	E_SEED(t0, t1, x1, x2, x3, x4, 2);
	E_SEED(t0, t1, x3, x4, x1, x2, 0);

	word2char(x3, d);
	word2char(x4, d+4);
	word2char(x1, d+8);
	word2char(x2, d+12);
}

#endif /* OPENSSL_NO_SEED */

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed.h
/*
 * 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

#ifdef AES_LONG /* look whether we need 'long' to get 32 bits */
# ifndef SEED_LONG
#  define SEED_LONG 1
# endif
#endif

#if !defined(NO_SYS_TYPES_H)
# include <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;


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 */

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed_cbc.c
/* crypto/seed/seed_cbc.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */

#include "seed_locl.h"
#include <string.h>

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)
	{
	size_t n;
	unsigned char tmp[SEED_BLOCK_SIZE];
	const unsigned char *iv = ivec;

	if (enc)
		{
		while (len >= SEED_BLOCK_SIZE)
			{
			for (n = 0; n < SEED_BLOCK_SIZE; ++n)
				out[n] = in[n] ^ iv[n];
			SEED_encrypt(out, out, ks);
			iv = out;
			len -= SEED_BLOCK_SIZE;
			in  += SEED_BLOCK_SIZE;
			out += SEED_BLOCK_SIZE;
			}
		if (len)
			{
			for (n = 0; n < len; ++n)
				out[n] = in[n] ^ iv[n];
			for (n = len; n < SEED_BLOCK_SIZE; ++n)
				out[n] = iv[n];
			SEED_encrypt(out, out, ks);
			iv = out;
			}
		memcpy(ivec, iv, SEED_BLOCK_SIZE);
		}
	else if (in != out) /* decrypt */
		{
		while (len >= SEED_BLOCK_SIZE)
			{
			SEED_decrypt(in, out, ks);
			for (n = 0; n < SEED_BLOCK_SIZE; ++n)
				out[n] ^= iv[n];
			iv = in;
			len -= SEED_BLOCK_SIZE;
			in  += SEED_BLOCK_SIZE;
			out += SEED_BLOCK_SIZE;
			}
		if (len)
			{
			SEED_decrypt(in, tmp, ks);
			for (n = 0; n < len; ++n)
				out[n] = tmp[n] ^ iv[n];
			iv = in;
			}
		memcpy(ivec, iv, SEED_BLOCK_SIZE);
		}
	else /* decrypt, overlap */
		{
		while (len >= SEED_BLOCK_SIZE)
			{
			memcpy(tmp, in, SEED_BLOCK_SIZE);
			SEED_decrypt(in, out, ks);
			for (n = 0; n < SEED_BLOCK_SIZE; ++n)
				out[n] ^= ivec[n];
			memcpy(ivec, tmp, SEED_BLOCK_SIZE);
			len -= SEED_BLOCK_SIZE;
			in  += SEED_BLOCK_SIZE;
			out += SEED_BLOCK_SIZE;
			}
		if (len)
			{
			memcpy(tmp, in, SEED_BLOCK_SIZE);
			SEED_decrypt(tmp, tmp, ks);
			for (n = 0; n < len; ++n)
				out[n] = tmp[n] ^ ivec[n];
			memcpy(ivec, tmp, SEED_BLOCK_SIZE);
			}
		}
	}

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed_cfb.c
/* crypto/seed/seed_cfb.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include "seed_locl.h"
#include <string.h>

void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
                         size_t len, const SEED_KEY_SCHEDULE *ks,
                         unsigned char ivec[SEED_BLOCK_SIZE], int *num, int enc)
	{
	int n;
	unsigned char c;

	n = *num;

	if (enc)
		{
		while (len--)
			{
			if (n == 0)
				SEED_encrypt(ivec, ivec, ks);
			ivec[n] = *(out++) = *(in++) ^ ivec[n];
			n = (n+1) % SEED_BLOCK_SIZE;
			}
		}
	else
		{
		while (len--)
			{
			if (n == 0)
				SEED_encrypt(ivec, ivec, ks);
			c = *(in);
			*(out++) = *(in++) ^ ivec[n];
			ivec[n] = c;
			n = (n+1) % SEED_BLOCK_SIZE;
			}
		}

	*num = n;
	}

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed_ecb.c
/* crypto/seed/seed_ecb.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
 * 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.
 * ====================================================================
 *
 */

#include <openssl/seed.h>

void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, const SEED_KEY_SCHEDULE *ks, int enc) 
	{
	if (enc)
		SEED_encrypt(in, out, ks);
	else
		SEED_decrypt(in, out, ks);
	}

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed_locl.h
/*
 * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.  
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Neither the name of author nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#ifndef HEADER_SEED_LOCL_H
#define HEADER_SEED_LOCL_H

#include "openssl/e_os2.h"
#include <openssl/seed.h>


#ifdef SEED_LONG /* need 32-bit type */
typedef unsigned long seed_word;
#else
typedef unsigned int seed_word;
#endif


#ifdef  __cplusplus
extern "C" {
#endif

#define G_FUNC(v)       \
        SS[0][(unsigned char)      (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
        SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff]

#define char2word(c, i)  \
        (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3]))

#define word2char(l, c)  \
        *((c)+0) = (unsigned char)((l)>>24) & 0xff; \
        *((c)+1) = (unsigned char)((l)>>16) & 0xff; \
        *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \
        *((c)+3) = (unsigned char)((l))     & 0xff

#define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC)  \
        (T0) = (X3);                                     \
        (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff;    \
        (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff;    \
        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;    \
        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff

#define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC)  \
        (T0) = (X1);                                     \
        (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff;    \
        (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff;    \
        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;     \
        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff

#define KEYUPDATE_TEMP(T0, T1, K)   \
        (K)[0] = G_FUNC((T0));      \
        (K)[1] = G_FUNC((T1))

#define XOR_SEEDBLOCK(DST, SRC)      \
        ((DST))[0] ^= ((SRC))[0];    \
        ((DST))[1] ^= ((SRC))[1];    \
        ((DST))[2] ^= ((SRC))[2];    \
        ((DST))[3] ^= ((SRC))[3]

#define MOV_SEEDBLOCK(DST, SRC)      \
        ((DST))[0] = ((SRC))[0];     \
        ((DST))[1] = ((SRC))[1];     \
        ((DST))[2] = ((SRC))[2];     \
        ((DST))[3] = ((SRC))[3]

# define CHAR2WORD(C, I)              \
        char2word((C),    (I)[0]);    \
        char2word((C+4),  (I)[1]);    \
        char2word((C+8),  (I)[2]);    \
        char2word((C+12), (I)[3])

# define WORD2CHAR(I, C)              \
        word2char((I)[0], (C));       \
        word2char((I)[1], (C+4));     \
        word2char((I)[2], (C+8));     \
        word2char((I)[3], (C+12))

# define E_SEED(T0, T1, X1, X2, X3, X4, rbase)   \
        (T0) = (X3) ^ (ks->data)[(rbase)];       \
        (T1) = (X4) ^ (ks->data)[(rbase)+1];     \
        (T1) ^= (T0);                            \
        (T1) = G_FUNC((T1));                     \
        (T0) = ((T0) + (T1)) & 0xffffffff;       \
        (T0) = G_FUNC((T0));                     \
        (T1) = ((T1) + (T0)) & 0xffffffff;       \
        (T1) = G_FUNC((T1));                     \
        (T0) = ((T0) + (T1)) & 0xffffffff;       \
        (X1) ^= (T0);                            \
        (X2) ^= (T1)

#ifdef  __cplusplus
}
#endif

#endif /* HEADER_SEED_LOCL_H */

File Added: src/crypto/dist/openssl/crypto/seed/Attic/seed_ofb.c
/* crypto/seed/seed_ofb.c -*- mode:C; c-file-style: "eay" -*- */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include "seed_locl.h"
#include <string.h>

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)
	{
	int n;

	n = *num;
	
	while (len--)
		{
		if (n == 0)
			SEED_encrypt(ivec, ivec, ks);
		*(out++) = *(in++) ^ ivec[n];
		n = (n+1) % SEED_BLOCK_SIZE;
		}

	*num = n;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/Makefile
#
# SSLeay/crypto/ts/Makefile
#

DIR=	ts
TOP=	../..
CC=	cc
INCLUDES= -I.. -I../../include
CFLAG = -g
INSTALL_PREFIX=
OPENSSLDIR=     /usr/local/ssl
INSTALLTOP=/usr/local/ssl
MAKEDEPPROG=	makedepend
MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
MAKEFILE=	Makefile
AR=		ar r

PEX_LIBS=
EX_LIBS=
 
CFLAGS= $(INCLUDES) $(CFLAG)

GENERAL= Makefile
TEST=
APPS=

LIB=$(TOP)/libcrypto.a
LIBSRC=	ts_err.c ts_req_utils.c ts_req_print.c ts_rsp_utils.c ts_rsp_print.c \
	ts_rsp_sign.c ts_rsp_verify.c ts_verify_ctx.c ts_lib.c ts_conf.c \
	ts_asn1.c
LIBOBJ= ts_err.o ts_req_utils.o ts_req_print.o ts_rsp_utils.o ts_rsp_print.o \
	ts_rsp_sign.o ts_rsp_verify.o ts_verify_ctx.o ts_lib.o ts_conf.o \
	ts_asn1.o

SRC= $(LIBSRC)

EXHEADER= ts.h
HEADER=	$(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)

top:
	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)

test:

all:	lib

lib:	$(LIBOBJ)
	$(AR) $(LIB) $(LIBOBJ)
	$(RANLIB) $(LIB) || echo Never mind.
	@touch lib

files:
	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

links:
	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)

install:
	@for i in $(EXHEADER) ; \
	do  \
	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
	done;

tags:
	ctags $(SRC)

lint:
	lint -DLINT $(INCLUDES) $(SRC)>fluff

depend:
	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(LIBSRC)

dclean:
	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
	mv -f Makefile.new $(MAKEFILE)

clean:
	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify

# DO NOT DELETE THIS LINE -- make depend depends on it.

ts_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
ts_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_asn1.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
ts_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ts_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
ts_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
ts_asn1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ts_asn1.o: ../../include/openssl/ts.h ../../include/openssl/x509.h
ts_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
ts_asn1.o: ts_asn1.c
ts_conf.o: ../../e_os.h ../../include/openssl/asn1.h
ts_conf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_conf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_conf.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_conf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
ts_conf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
ts_conf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ts_conf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
ts_conf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
ts_conf.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
ts_conf.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_conf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_conf.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_conf.c
ts_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ts_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
ts_err.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
ts_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
ts_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
ts_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
ts_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
ts_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ts_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
ts_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_err.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_err.o: ../../include/openssl/x509v3.h ts_err.c
ts_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
ts_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
ts_lib.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
ts_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ts_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
ts_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
ts_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ts_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ts.h ts_lib.c
ts_req_print.o: ../../e_os.h ../../include/openssl/asn1.h
ts_req_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ts_req_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
ts_req_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
ts_req_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
ts_req_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
ts_req_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
ts_req_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
ts_req_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ts_req_print.o: ../../include/openssl/opensslconf.h
ts_req_print.o: ../../include/openssl/opensslv.h
ts_req_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_req_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_req_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_req_print.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_req_print.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_req_print.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_print.c
ts_req_utils.o: ../../e_os.h ../../include/openssl/asn1.h
ts_req_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_req_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_req_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_req_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_req_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_req_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_req_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_req_utils.o: ../../include/openssl/objects.h
ts_req_utils.o: ../../include/openssl/opensslconf.h
ts_req_utils.o: ../../include/openssl/opensslv.h
ts_req_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_req_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_req_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_req_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_req_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_req_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_req_utils.c
ts_rsp_print.o: ../../e_os.h ../../include/openssl/asn1.h
ts_rsp_print.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ts_rsp_print.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
ts_rsp_print.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
ts_rsp_print.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
ts_rsp_print.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
ts_rsp_print.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
ts_rsp_print.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
ts_rsp_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
ts_rsp_print.o: ../../include/openssl/opensslconf.h
ts_rsp_print.o: ../../include/openssl/opensslv.h
ts_rsp_print.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_rsp_print.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_rsp_print.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_rsp_print.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
ts_rsp_print.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
ts_rsp_print.o: ../cryptlib.h ts.h ts_rsp_print.c
ts_rsp_sign.o: ../../e_os.h ../../include/openssl/asn1.h
ts_rsp_sign.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_rsp_sign.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_rsp_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_rsp_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_rsp_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_rsp_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_rsp_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_rsp_sign.o: ../../include/openssl/objects.h
ts_rsp_sign.o: ../../include/openssl/opensslconf.h
ts_rsp_sign.o: ../../include/openssl/opensslv.h
ts_rsp_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_rsp_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_rsp_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_rsp_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_rsp_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_rsp_sign.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_sign.c
ts_rsp_utils.o: ../../e_os.h ../../include/openssl/asn1.h
ts_rsp_utils.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_rsp_utils.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_rsp_utils.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_rsp_utils.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_rsp_utils.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_rsp_utils.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_rsp_utils.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_rsp_utils.o: ../../include/openssl/objects.h
ts_rsp_utils.o: ../../include/openssl/opensslconf.h
ts_rsp_utils.o: ../../include/openssl/opensslv.h
ts_rsp_utils.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_rsp_utils.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_rsp_utils.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_rsp_utils.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_rsp_utils.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_rsp_utils.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_utils.c
ts_rsp_verify.o: ../../e_os.h ../../include/openssl/asn1.h
ts_rsp_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_rsp_verify.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_rsp_verify.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_rsp_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_rsp_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_rsp_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_rsp_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_rsp_verify.o: ../../include/openssl/objects.h
ts_rsp_verify.o: ../../include/openssl/opensslconf.h
ts_rsp_verify.o: ../../include/openssl/opensslv.h
ts_rsp_verify.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_rsp_verify.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_rsp_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_rsp_verify.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_rsp_verify.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_rsp_verify.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_rsp_verify.c
ts_verify_ctx.o: ../../e_os.h ../../include/openssl/asn1.h
ts_verify_ctx.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
ts_verify_ctx.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
ts_verify_ctx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
ts_verify_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ts_verify_ctx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
ts_verify_ctx.o: ../../include/openssl/err.h ../../include/openssl/evp.h
ts_verify_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ts_verify_ctx.o: ../../include/openssl/objects.h
ts_verify_ctx.o: ../../include/openssl/opensslconf.h
ts_verify_ctx.o: ../../include/openssl/opensslv.h
ts_verify_ctx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
ts_verify_ctx.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
ts_verify_ctx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
ts_verify_ctx.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
ts_verify_ctx.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
ts_verify_ctx.o: ../../include/openssl/x509v3.h ../cryptlib.h ts_verify_ctx.c

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts.h
/* 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

#include <openssl/evp.h>


#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);

TS_REQ	*d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
int	i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
TS_REQ	*d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
int	i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);

TS_MSG_IMPRINT	*TS_MSG_IMPRINT_new(void);
void		TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
int		i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
				    const unsigned char **pp, long length);

TS_MSG_IMPRINT	*TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);

TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
int		i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
TS_MSG_IMPRINT	*d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
int		i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);

TS_RESP	*TS_RESP_new(void);
void	TS_RESP_free(TS_RESP *a);
int	i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
TS_RESP	*d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
TS_RESP	*TS_RESP_dup(TS_RESP *a);

TS_RESP	*d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
int	i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
TS_RESP	*d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
int	i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);

TS_STATUS_INFO	*TS_STATUS_INFO_new(void);
void		TS_STATUS_INFO_free(TS_STATUS_INFO *a);
int		i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
TS_STATUS_INFO	*d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, 
				    const unsigned char **pp, long length);
TS_STATUS_INFO	*TS_STATUS_INFO_dup(TS_STATUS_INFO *a);

TS_TST_INFO	*TS_TST_INFO_new(void);
void		TS_TST_INFO_free(TS_TST_INFO *a);
int		i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
TS_TST_INFO	*d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
				    long length);
TS_TST_INFO	*TS_TST_INFO_dup(TS_TST_INFO *a);

TS_TST_INFO	*d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
int		i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
TS_TST_INFO	*d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
int		i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);

TS_ACCURACY	*TS_ACCURACY_new(void);
void		TS_ACCURACY_free(TS_ACCURACY *a);
int		i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
TS_ACCURACY	*d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
				    long length);
TS_ACCURACY	*TS_ACCURACY_dup(TS_ACCURACY *a);

ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
void		  ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
int		  i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a,
					unsigned char **pp);
ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
					 const unsigned char **pp, long length);
ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);

ESS_CERT_ID	*ESS_CERT_ID_new(void);
void		ESS_CERT_ID_free(ESS_CERT_ID *a);
int		i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
ESS_CERT_ID	*d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
				 long length);
ESS_CERT_ID	*ESS_CERT_ID_dup(ESS_CERT_ID *a);

ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
void		 ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
int		 i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, 
				      unsigned char **pp);
ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
				       const unsigned char **pp, long length);
ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);

void ERR_load_TS_strings(void);

int TS_REQ_set_version(TS_REQ *a, long version);
long TS_REQ_get_version(const TS_REQ *a);

int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);

int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);

int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);

int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);

int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);

int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
int TS_REQ_get_cert_req(const TS_REQ *a);

STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
void TS_REQ_ext_free(TS_REQ *a);
int TS_REQ_get_ext_count(TS_REQ *a);
int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);

/* Function declarations for TS_REQ defined in ts/ts_req_print.c */

int TS_REQ_print_bio(BIO *bio, TS_REQ *a);

/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */

int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);

/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
PKCS7 *TS_RESP_get_token(TS_RESP *a);
TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);

int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
long TS_TST_INFO_get_version(const TS_TST_INFO *a);

int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);

int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);

int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);

int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);

int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);

int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);

int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);

int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);

int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);

int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);

int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);

STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
void TS_TST_INFO_ext_free(TS_TST_INFO *a);
int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);

/* Declarations related to response generation, defined in ts/ts_resp_sign.c. */

/* Optional flags for response generation. */

/* Don't include the TSA name in response. */
#define	TS_TSA_NAME		0x01

/* Set ordering to true in response. */
#define	TS_ORDERING		0x02

/*
 * Include the signer certificate and the other specified certificates in
 * the ESS signing certificate attribute beside the PKCS7 signed data.
 * Only the signer certificates is included by default.
 */
#define	TS_ESS_CERT_ID_CHAIN	0x04

/* Forward declaration. */
struct TS_resp_ctx;

/* This must return a unique number less than 160 bits long. */
typedef ASN1_INTEGER *(*TS_serial_cb)(struct TS_resp_ctx *, void *);

/* This must return the seconds and microseconds since Jan 1, 1970 in
   the sec and usec variables allocated by the caller. 
   Return non-zero for success and zero for failure. */
typedef	int (*TS_time_cb)(struct TS_resp_ctx *, void *, long *sec, long *usec);

/* This must process the given extension.
 * It can modify the TS_TST_INFO object of the context.
 * Return values: !0 (processed), 0 (error, it must set the 
 * status info/failure info of the response).
 */
typedef	int (*TS_extension_cb)(struct TS_resp_ctx *, X509_EXTENSION *, void *);

typedef struct TS_resp_ctx
	{
	X509		*signer_cert;
	EVP_PKEY	*signer_key;
	STACK_OF(X509)	*certs;	/* Certs to include in signed data. */
	STACK_OF(ASN1_OBJECT)	*policies;	/* Acceptable policies. */
	ASN1_OBJECT	*default_policy; /* It may appear in policies, too. */
	STACK_OF(EVP_MD)	*mds;	/* Acceptable message digests. */
	ASN1_INTEGER	*seconds;	/* accuracy, 0 means not specified. */
	ASN1_INTEGER	*millis;	/* accuracy, 0 means not specified. */
	ASN1_INTEGER	*micros;	/* accuracy, 0 means not specified. */
	unsigned	clock_precision_digits; /* fraction of seconds in
						   time stamp token. */
	unsigned	flags;		/* Optional info, see values above. */

	/* Callback functions. */
	TS_serial_cb serial_cb;
	void *serial_cb_data;	/* User data for serial_cb. */
	
	TS_time_cb time_cb;
	void *time_cb_data;	/* User data for time_cb. */
	
	TS_extension_cb extension_cb;
	void *extension_cb_data;	/* User data for extension_cb. */

	/* These members are used only while creating the response. */
	TS_REQ		*request;
	TS_RESP		*response;
	TS_TST_INFO	*tst_info;
	} TS_RESP_CTX;

DECLARE_STACK_OF(EVP_MD)
DECLARE_ASN1_SET_OF(EVP_MD)

/* Creates a response context that can be used for generating responses. */
TS_RESP_CTX *TS_RESP_CTX_new(void);
void TS_RESP_CTX_free(TS_RESP_CTX *ctx);

/* This parameter must be set. */
int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);

/* This parameter must be set. */
int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);

/* This parameter must be set. */
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);

/* No additional certs are included in the response by default. */
int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);

/* Adds a new acceptable policy, only the default policy 
   is accepted by default. */
int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);

/* Adds a new acceptable message digest. Note that no message digests 
   are accepted by default. The md argument is shared with the caller. */
int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);

/* Accuracy is not included by default. */
int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
			     int secs, int millis, int micros);

/* Clock precision digits, i.e. the number of decimal digits: 
   '0' means sec, '3' msec, '6' usec, and so on. Default is 0. */ 
int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
					   unsigned clock_precision_digits);
/* At most we accept usec precision. */	
#define TS_MAX_CLOCK_PRECISION_DIGITS	6

/* No flags are set by default. */
void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);

/* Default callback always returns a constant. */
void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);

/* Default callback uses the gettimeofday() and gmtime() system calls. */
void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);

/* Default callback rejects all extensions. The extension callback is called 
 * when the TS_TST_INFO object is already set up and not signed yet. */
/* FIXME: extension handling is not tested yet. */
void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
				  TS_extension_cb cb, void *data);

/* The following methods can be used in the callbacks. */
int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
				int status, const char *text);

/* Sets the status info only if it is still TS_STATUS_GRANTED. */
int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
				     int status, const char *text);

int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);

/* The get methods below can be used in the extension callback. */
TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);

TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);

/* 
 * Creates the signed TS_TST_INFO and puts it in TS_RESP.
 * In case of errors it sets the status info properly.
 * Returns NULL only in case of memory allocation/fatal error.
 */
TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);

/*
 * Declarations related to response verification,
 * they are defined in ts/ts_resp_verify.c.
 */

int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
			     X509_STORE *store, X509 **signer_out);

/* Context structure for the generic verify method. */

/* Verify the signer's certificate and the signature of the response. */
#define	TS_VFY_SIGNATURE	(1u << 0)
/* Verify the version number of the response. */
#define	TS_VFY_VERSION		(1u << 1)
/* Verify if the policy supplied by the user matches the policy of the TSA. */
#define	TS_VFY_POLICY		(1u << 2)
/* Verify the message imprint provided by the user. This flag should not be
   specified with TS_VFY_DATA. */
#define	TS_VFY_IMPRINT		(1u << 3)
/* Verify the message imprint computed by the verify method from the user
   provided data and the MD algorithm of the response. This flag should not be
   specified with TS_VFY_IMPRINT. */
#define	TS_VFY_DATA		(1u << 4)
/* Verify the nonce value. */
#define	TS_VFY_NONCE		(1u << 5)
/* Verify if the TSA name field matches the signer certificate. */
#define	TS_VFY_SIGNER		(1u << 6)
/* Verify if the TSA name field equals to the user provided name. */
#define	TS_VFY_TSA_NAME		(1u << 7)

/* You can use the following convenience constants. */
#define	TS_VFY_ALL_IMPRINT	(TS_VFY_SIGNATURE	\
				 | TS_VFY_VERSION	\
				 | TS_VFY_POLICY	\
				 | TS_VFY_IMPRINT	\
				 | TS_VFY_NONCE		\
				 | TS_VFY_SIGNER	\
				 | TS_VFY_TSA_NAME)
#define	TS_VFY_ALL_DATA		(TS_VFY_SIGNATURE	\
				 | TS_VFY_VERSION	\
				 | TS_VFY_POLICY	\
				 | TS_VFY_DATA		\
				 | TS_VFY_NONCE		\
				 | TS_VFY_SIGNER	\
				 | TS_VFY_TSA_NAME)

typedef struct TS_verify_ctx
	{
	/* Set this to the union of TS_VFY_... flags you want to carry out. */
	unsigned	flags;

	/* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
	X509_STORE	*store;
	STACK_OF(X509)	*certs;

	/* Must be set only with TS_VFY_POLICY. */
	ASN1_OBJECT	*policy;

	/* Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, 
	   the algorithm from the response is used. */
	X509_ALGOR	*md_alg;
	unsigned char	*imprint;
	unsigned	imprint_len;

	/* Must be set only with TS_VFY_DATA. */
	BIO		*data;

	/* Must be set only with TS_VFY_TSA_NAME. */
	ASN1_INTEGER	*nonce;

	/* Must be set only with TS_VFY_TSA_NAME. */
	GENERAL_NAME	*tsa_name;
	} TS_VERIFY_CTX;

int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);

/*
 * Declarations related to response verification context,
 * they are defined in ts/ts_verify_ctx.c.
 */

/* Set all fields to zero. */
TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);

/* 
 * If ctx is NULL, it allocates and returns a new object, otherwise
 * it returns ctx. It initialises all the members as follows:
 * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
 * certs = NULL
 * store = NULL
 * policy = policy from the request or NULL if absent (in this case
 *	TS_VFY_POLICY is cleared from flags as well)
 * md_alg = MD algorithm from request
 * imprint, imprint_len = imprint from request
 * data = NULL
 * nonce, nonce_len = nonce from the request or NULL if absent (in this case
 * 	TS_VFY_NONCE is cleared from flags as well)
 * tsa_name = NULL
 * Important: after calling this method TS_VFY_SIGNATURE should be added!
 */
TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);

/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */

int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);

/* Common utility functions defined in ts/ts_lib.c */

int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);

/* Function declarations for handling configuration options,
   defined in ts/ts_conf.c */

X509 *TS_CONF_load_cert(const char *file);
STACK_OF(X509) *TS_CONF_load_certs(const char *file);
EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
		       TS_RESP_CTX *ctx);
int TS_CONF_set_crypto_device(CONF *conf, const char *section,
			      const char *device);
int TS_CONF_set_default_engine(const char *name);
int TS_CONF_set_signer_cert(CONF *conf, const char *section,
			    const char *cert, TS_RESP_CTX *ctx);
int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
		      TS_RESP_CTX *ctx);
int TS_CONF_set_signer_key(CONF *conf, const char *section,
			   const char *key, const char *pass, TS_RESP_CTX *ctx);
int TS_CONF_set_def_policy(CONF *conf, const char *section,
			   const char *policy, TS_RESP_CTX *ctx);
int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
				       TS_RESP_CTX *ctx);
int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
				  TS_RESP_CTX *ctx);

/* -------------------------------------------------- */
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_TS_strings(void);

/* Error codes for the TS functions. */

/* Function codes. */
#define TS_F_D2I_TS_RESP				 147
#define TS_F_DEF_SERIAL_CB				 110
#define TS_F_DEF_TIME_CB				 111
#define TS_F_ESS_ADD_SIGNING_CERT			 112
#define TS_F_ESS_CERT_ID_NEW_INIT			 113
#define TS_F_ESS_SIGNING_CERT_NEW_INIT			 114
#define TS_F_INT_TS_RESP_VERIFY_TOKEN			 149
#define TS_F_PKCS7_TO_TS_TST_INFO			 148
#define TS_F_TS_ACCURACY_SET_MICROS			 115
#define TS_F_TS_ACCURACY_SET_MILLIS			 116
#define TS_F_TS_ACCURACY_SET_SECONDS			 117
#define TS_F_TS_CHECK_IMPRINTS				 100
#define TS_F_TS_CHECK_NONCES				 101
#define TS_F_TS_CHECK_POLICY				 102
#define TS_F_TS_CHECK_SIGNING_CERTS			 103
#define TS_F_TS_CHECK_STATUS_INFO			 104
#define TS_F_TS_COMPUTE_IMPRINT				 145
#define TS_F_TS_CONF_SET_DEFAULT_ENGINE			 146
#define TS_F_TS_GET_STATUS_TEXT				 105
#define TS_F_TS_MSG_IMPRINT_SET_ALGO			 118
#define TS_F_TS_REQ_SET_MSG_IMPRINT			 119
#define TS_F_TS_REQ_SET_NONCE				 120
#define TS_F_TS_REQ_SET_POLICY_ID			 121
#define TS_F_TS_RESP_CREATE_RESPONSE			 122
#define TS_F_TS_RESP_CREATE_TST_INFO			 123
#define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO		 124
#define TS_F_TS_RESP_CTX_ADD_MD				 125
#define TS_F_TS_RESP_CTX_ADD_POLICY			 126
#define TS_F_TS_RESP_CTX_NEW				 127
#define TS_F_TS_RESP_CTX_SET_ACCURACY			 128
#define TS_F_TS_RESP_CTX_SET_CERTS			 129
#define TS_F_TS_RESP_CTX_SET_DEF_POLICY			 130
#define TS_F_TS_RESP_CTX_SET_SIGNER_CERT		 131
#define TS_F_TS_RESP_CTX_SET_STATUS_INFO		 132
#define TS_F_TS_RESP_GET_POLICY				 133
#define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION		 134
#define TS_F_TS_RESP_SET_STATUS_INFO			 135
#define TS_F_TS_RESP_SET_TST_INFO			 150
#define TS_F_TS_RESP_SIGN				 136
#define TS_F_TS_RESP_VERIFY_SIGNATURE			 106
#define TS_F_TS_RESP_VERIFY_TOKEN			 107
#define TS_F_TS_TST_INFO_SET_ACCURACY			 137
#define TS_F_TS_TST_INFO_SET_MSG_IMPRINT		 138
#define TS_F_TS_TST_INFO_SET_NONCE			 139
#define TS_F_TS_TST_INFO_SET_POLICY_ID			 140
#define TS_F_TS_TST_INFO_SET_SERIAL			 141
#define TS_F_TS_TST_INFO_SET_TIME			 142
#define TS_F_TS_TST_INFO_SET_TSA			 143
#define TS_F_TS_VERIFY					 108
#define TS_F_TS_VERIFY_CERT				 109
#define TS_F_TS_VERIFY_CTX_NEW				 144

/* Reason codes. */
#define TS_R_BAD_PKCS7_TYPE				 132
#define TS_R_BAD_TYPE					 133
#define TS_R_CERTIFICATE_VERIFY_ERROR			 100
#define TS_R_COULD_NOT_SET_ENGINE			 127
#define TS_R_COULD_NOT_SET_TIME				 115
#define TS_R_D2I_TS_RESP_INT_FAILED			 128
#define TS_R_DETACHED_CONTENT				 134
#define TS_R_ESS_ADD_SIGNING_CERT_ERROR			 116
#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR		 101
#define TS_R_INVALID_NULL_POINTER			 102
#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE		 117
#define TS_R_MESSAGE_IMPRINT_MISMATCH			 103
#define TS_R_NONCE_MISMATCH				 104
#define TS_R_NONCE_NOT_RETURNED				 105
#define TS_R_NO_CONTENT					 106
#define TS_R_NO_TIME_STAMP_TOKEN			 107
#define TS_R_PKCS7_ADD_SIGNATURE_ERROR			 118
#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR		 119
#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED		 129
#define TS_R_POLICY_MISMATCH				 108
#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 120
#define TS_R_RESPONSE_SETUP_ERROR			 121
#define TS_R_SIGNATURE_FAILURE				 109
#define TS_R_THERE_MUST_BE_ONE_SIGNER			 110
#define TS_R_TIME_SYSCALL_ERROR				 122
#define TS_R_TOKEN_NOT_PRESENT				 130
#define TS_R_TOKEN_PRESENT				 131
#define TS_R_TSA_NAME_MISMATCH				 111
#define TS_R_TSA_UNTRUSTED				 112
#define TS_R_TST_INFO_SETUP_ERROR			 123
#define TS_R_TS_DATASIGN				 124
#define TS_R_UNACCEPTABLE_POLICY			 125
#define TS_R_UNSUPPORTED_MD_ALGORITHM			 126
#define TS_R_UNSUPPORTED_VERSION			 113
#define TS_R_WRONG_CONTENT_TYPE				 114

#ifdef  __cplusplus
}
#endif
#endif

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_asn1.c
/* crypto/ts/ts_asn1.c */
/* Written by Nils Larsch for the OpenSSL project 2004.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <openssl/ts.h>
#include <openssl/err.h>
#include <openssl/asn1t.h>

ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
	ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
	ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(TS_MSG_IMPRINT)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
#ifndef OPENSSL_NO_BIO
TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
	{
	return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, bp, a);
	}

int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
{
	return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
}
#endif
#ifndef OPENSSL_NO_FP_API
TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
	{
	return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, d2i_TS_MSG_IMPRINT, fp, a);
	}

int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
	{
	return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
	}
#endif

ASN1_SEQUENCE(TS_REQ) = {
	ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
	ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
	ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
	ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
	ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
	ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
} ASN1_SEQUENCE_END(TS_REQ)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
#ifndef OPENSSL_NO_BIO
TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
	{
	return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
	}

int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
	{
	return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
	}
#endif
#ifndef OPENSSL_NO_FP_API
TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
	{
	return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
	}

int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
	{
	return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
	}
#endif

ASN1_SEQUENCE(TS_ACCURACY) = {
	ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
	ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
	ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
} ASN1_SEQUENCE_END(TS_ACCURACY)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)

ASN1_SEQUENCE(TS_TST_INFO) = {
	ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
	ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
	ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
	ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
	ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
	ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
	ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
	ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
	ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
	ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
} ASN1_SEQUENCE_END(TS_TST_INFO)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
#ifndef OPENSSL_NO_BIO
TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
	{
	return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, a);
	}

int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
	{
	return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
	}
#endif
#ifndef OPENSSL_NO_FP_API
TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
	{
	return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, a);
	}

int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
	{
	return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
	}
#endif

ASN1_SEQUENCE(TS_STATUS_INFO) = {
	ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
	ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
	ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(TS_STATUS_INFO)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)

static int ts_resp_set_tst_info(TS_RESP *a)
{
	long    status;

	status = ASN1_INTEGER_get(a->status_info->status);

	if (a->token) {
		if (status != 0 && status != 1) {
			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
			return 0;
		}
		if (a->tst_info != NULL)
			TS_TST_INFO_free(a->tst_info);
		a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
		if (!a->tst_info) {
			TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
			return 0;
		}
	} else if (status == 0 || status == 1) {
		TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
		return 0;
	}

	return 1;
}

static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
	void *exarg)
{
	TS_RESP *ts_resp = (TS_RESP *)*pval;
	if (op == ASN1_OP_NEW_POST) {
		ts_resp->tst_info = NULL;
	} else if (op == ASN1_OP_FREE_POST) {
		if (ts_resp->tst_info != NULL)
			TS_TST_INFO_free(ts_resp->tst_info);
	} else if (op == ASN1_OP_D2I_POST) {
		if (ts_resp_set_tst_info(ts_resp) == 0)
			return 0;
	}
	return 1;
}

ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
	ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
	ASN1_OPT(TS_RESP, token, PKCS7),
} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)

IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
#ifndef OPENSSL_NO_BIO
TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
	{
	return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
	}

int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
	{
	return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
	}
#endif
#ifndef OPENSSL_NO_FP_API
TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
	{
	return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
	}

int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
	{
	return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
	}
#endif

ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
	ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
	ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)

IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)

ASN1_SEQUENCE(ESS_CERT_ID) = {
	ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
	ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
} ASN1_SEQUENCE_END(ESS_CERT_ID)

IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)

ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
	ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
	ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
} ASN1_SEQUENCE_END(ESS_SIGNING_CERT)

IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)

/* Getting encapsulated TS_TST_INFO object from PKCS7. */
TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
{
	PKCS7_SIGNED *pkcs7_signed;
	PKCS7 *enveloped;
	ASN1_TYPE *tst_info_wrapper;
	ASN1_OCTET_STRING *tst_info_der;
	const unsigned char *p;

	if (!PKCS7_type_is_signed(token))
		{
		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
		return NULL;
		}

	/* Content must be present. */
	if (PKCS7_get_detached(token))
		{
		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
		return NULL;
		}

	/* We have a signed data with content. */
	pkcs7_signed = token->d.sign;
	enveloped = pkcs7_signed->contents;
	if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo)
		{
		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
		return NULL;
		}

	/* We have a DER encoded TST_INFO as the signed data. */
	tst_info_wrapper = enveloped->d.other;
	if (tst_info_wrapper->type != V_ASN1_OCTET_STRING)
		{
		TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
		return NULL;
		}

	/* We have the correct ASN1_OCTET_STRING type. */
	tst_info_der = tst_info_wrapper->value.octet_string;
	/* At last, decode the TST_INFO. */
	p = tst_info_der->data;
	return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_conf.c
/* crypto/ts/ts_conf.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <string.h>

#include <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/pem.h>
#include <openssl/engine.h>
#include <openssl/ts.h>

/* Macro definitions for the configuration file. */

#define	BASE_SECTION			"tsa"
#define	ENV_DEFAULT_TSA			"default_tsa"
#define	ENV_SERIAL			"serial"
#define ENV_CRYPTO_DEVICE		"crypto_device"
#define	ENV_SIGNER_CERT			"signer_cert"
#define	ENV_CERTS			"certs"
#define	ENV_SIGNER_KEY			"signer_key"
#define	ENV_DEFAULT_POLICY		"default_policy"
#define	ENV_OTHER_POLICIES		"other_policies"
#define	ENV_DIGESTS			"digests"
#define	ENV_ACCURACY			"accuracy"
#define	ENV_ORDERING			"ordering"
#define	ENV_TSA_NAME			"tsa_name"
#define	ENV_ESS_CERT_ID_CHAIN		"ess_cert_id_chain"
#define	ENV_VALUE_SECS			"secs"
#define	ENV_VALUE_MILLISECS		"millisecs"
#define	ENV_VALUE_MICROSECS		"microsecs"
#define	ENV_CLOCK_PRECISION_DIGITS	"clock_precision_digits" 
#define	ENV_VALUE_YES			"yes"
#define	ENV_VALUE_NO			"no"

/* Function definitions for certificate and key loading. */

X509 *TS_CONF_load_cert(const char *file)
	{
	BIO *cert = NULL;
	X509 *x = NULL;

	if ((cert = BIO_new_file(file, "r")) == NULL) goto end;
	x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
end:
	if (x == NULL)
		fprintf(stderr, "unable to load certificate: %s\n", file);
	BIO_free(cert);
	return x;
	}

STACK_OF(X509) *TS_CONF_load_certs(const char *file)
	{
	BIO *certs = NULL;
	STACK_OF(X509) *othercerts = NULL;
	STACK_OF(X509_INFO) *allcerts = NULL;
	int i;

	if (!(certs = BIO_new_file(file, "r"))) goto end;

	if (!(othercerts = sk_X509_new_null())) goto end;
	allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
	for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
		{
		X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
		if (xi->x509)
			{
			sk_X509_push(othercerts, xi->x509);
			xi->x509 = NULL;
			}
		}
end:
	if (othercerts == NULL)
		fprintf(stderr, "unable to load certificates: %s\n", file);
	sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
	BIO_free(certs);
	return othercerts;
	}

EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
	{
	BIO *key = NULL;
	EVP_PKEY *pkey = NULL;

	if (!(key = BIO_new_file(file, "r"))) goto end;
	pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *) pass);
 end:
	if (pkey == NULL)
		fprintf(stderr, "unable to load private key: %s\n", file);
	BIO_free(key);
	return pkey;
	}

/* Function definitions for handling configuration options. */

static void TS_CONF_lookup_fail(const char *name, const char *tag)
	{
	fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag);
	}

static void TS_CONF_invalid(const char *name, const char *tag)
	{
	fprintf(stderr, "invalid variable value for %s::%s\n", name, tag);
	}

const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
	{
	if (!section)
		{
		section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
		if (!section)
			TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
		}
	return section;
	}

int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
		       TS_RESP_CTX *ctx)
	{
	int ret = 0;
	char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
	if (!serial)
		{
		TS_CONF_lookup_fail(section, ENV_SERIAL);
		goto err;
		}
	TS_RESP_CTX_set_serial_cb(ctx, cb, serial);

	ret = 1;
 err:
	return ret;
	}

int TS_CONF_set_crypto_device(CONF *conf, const char *section,
			      const char *device)
	{
	int ret = 0;
	
	if (!device)
		device = NCONF_get_string(conf, section,
					  ENV_CRYPTO_DEVICE);

	if (device && !TS_CONF_set_default_engine(device))
		{
		TS_CONF_invalid(section, ENV_CRYPTO_DEVICE);
		goto err;
		}
	ret = 1;
 err:
	return ret;
	}

int TS_CONF_set_default_engine(const char *name)
	{
	ENGINE *e = NULL;
	int ret = 0;

	/* Leave the default if builtin specified. */
	if (strcmp(name, "builtin") == 0) return 1;

	if (!(e = ENGINE_by_id(name))) goto err;
	/* Enable the use of the NCipher HSM for forked children. */
	if (strcmp(name, "chil") == 0) 
		ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
	/* All the operations are going to be carried out by the engine. */
	if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) goto err;
	ret = 1;
 err:
	if (!ret)
		{
		TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, 
		      TS_R_COULD_NOT_SET_ENGINE);
		ERR_add_error_data(2, "engine:", name);
		}
	if (e) ENGINE_free(e);
	return ret;
	}

int TS_CONF_set_signer_cert(CONF *conf, const char *section,
			    const char *cert, TS_RESP_CTX *ctx)
	{
	int ret = 0;
	X509 *cert_obj = NULL;
	if (!cert) 
		cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
	if (!cert)
		{
		TS_CONF_lookup_fail(section, ENV_SIGNER_CERT);
		goto err;
		}
	if (!(cert_obj = TS_CONF_load_cert(cert)))
		goto err;
	if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
		goto err;

	ret = 1;
 err:
	X509_free(cert_obj);
	return ret;
	}

int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
		      TS_RESP_CTX *ctx)
	{
	int ret = 0;
	STACK_OF(X509) *certs_obj = NULL;
	if (!certs) 
		certs = NCONF_get_string(conf, section, ENV_CERTS);
	/* Certificate chain is optional. */
	if (!certs) goto end;
	if (!(certs_obj = TS_CONF_load_certs(certs))) goto err;
	if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) goto err;
 end:
	ret = 1;
 err:
	sk_X509_pop_free(certs_obj, X509_free);
	return ret;
	}

int TS_CONF_set_signer_key(CONF *conf, const char *section,
			   const char *key, const char *pass,
			   TS_RESP_CTX *ctx)
	{
	int ret = 0;
	EVP_PKEY *key_obj = NULL;
	if (!key) 
		key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
	if (!key)
		{
		TS_CONF_lookup_fail(section, ENV_SIGNER_KEY);
		goto err;
		}
	if (!(key_obj = TS_CONF_load_key(key, pass))) goto err;
	if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) goto err;

	ret = 1;
 err:
	EVP_PKEY_free(key_obj);
	return ret;
	}

int TS_CONF_set_def_policy(CONF *conf, const char *section,
			   const char *policy, TS_RESP_CTX *ctx)
	{
	int ret = 0;
	ASN1_OBJECT *policy_obj = NULL;
	if (!policy) 
		policy = NCONF_get_string(conf, section, 
					  ENV_DEFAULT_POLICY);
	if (!policy)
		{
		TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
		goto err;
		}
	if (!(policy_obj = OBJ_txt2obj(policy, 0)))
		{
		TS_CONF_invalid(section, ENV_DEFAULT_POLICY);
		goto err;
		}
	if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
		goto err;

	ret = 1;
 err:
	ASN1_OBJECT_free(policy_obj);
	return ret;
	}

int TS_CONF_set_policies(CONF *conf, const char *section,
			 TS_RESP_CTX *ctx)
	{
	int ret = 0;
	int i;
	STACK_OF(CONF_VALUE) *list = NULL;
	char *policies = NCONF_get_string(conf, section, 
					  ENV_OTHER_POLICIES);
	/* If no other policy is specified, that's fine. */
	if (policies && !(list = X509V3_parse_list(policies)))
		{
		TS_CONF_invalid(section, ENV_OTHER_POLICIES);
		goto err;
		}
	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
		{
		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
		const char *extval = val->value ? val->value : val->name;
		ASN1_OBJECT *objtmp;
		if (!(objtmp = OBJ_txt2obj(extval, 0)))
			{
			TS_CONF_invalid(section, ENV_OTHER_POLICIES);
			goto err;
			}
		if (!TS_RESP_CTX_add_policy(ctx, objtmp))
			goto err;
		ASN1_OBJECT_free(objtmp);
		}

	ret = 1;
 err:
	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
	return ret;
	}

int TS_CONF_set_digests(CONF *conf, const char *section,
			TS_RESP_CTX *ctx)
	{
	int ret = 0;
	int i;
	STACK_OF(CONF_VALUE) *list = NULL;
	char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
	if (!digests)
		{
		TS_CONF_lookup_fail(section, ENV_DIGESTS);
		goto err;
		}
	if (!(list = X509V3_parse_list(digests)))
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	if (sk_CONF_VALUE_num(list) == 0)
		{
		TS_CONF_invalid(section, ENV_DIGESTS);
		goto err;
		}
	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
		{
		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
		const char *extval = val->value ? val->value : val->name;
		const EVP_MD *md;
		if (!(md = EVP_get_digestbyname(extval)))
			{
			TS_CONF_invalid(section, ENV_DIGESTS);
			goto err;
			}
		if (!TS_RESP_CTX_add_md(ctx, md))
			goto err;
		}

	ret = 1;
 err:
	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
	return ret;
	}

int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
	{
	int ret = 0;
	int i;
	int secs = 0, millis = 0, micros = 0;
	STACK_OF(CONF_VALUE) *list = NULL;
	char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);

	if (accuracy && !(list = X509V3_parse_list(accuracy)))
		{
		TS_CONF_invalid(section, ENV_ACCURACY);
		goto err;
		}
	for (i = 0; i < sk_CONF_VALUE_num(list); ++i)
		{
		CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
		if (strcmp(val->name, ENV_VALUE_SECS) == 0) 
			{
			if (val->value) secs = atoi(val->value);
			}
		else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0)
			{
			if (val->value) millis = atoi(val->value);
			}
		else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0)
			{
			if (val->value) micros = atoi(val->value);
			}
		else
			{
			TS_CONF_invalid(section, ENV_ACCURACY);
			goto err;
			}
		}
	if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
		goto err;

	ret = 1;
 err:
	sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
	return ret;
	}

int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
				       TS_RESP_CTX *ctx)
	{
	int ret = 0;
	long digits = 0;
	
	/* If not specified, set the default value to 0, i.e. sec  precision */
	if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
				&digits))
		digits = 0;
	if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS)
		{
		TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
		goto err;
		}

	if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
		goto err;

	return 1;
 err:
	return ret;
	}

static int TS_CONF_add_flag(CONF *conf, const char *section, const char *field,
			    int flag, TS_RESP_CTX *ctx)
	{
	/* Default is false. */
	const char *value = NCONF_get_string(conf, section, field);
	if (value)
		{
		if (strcmp(value, ENV_VALUE_YES) == 0)
			TS_RESP_CTX_add_flags(ctx, flag);
		else if (strcmp(value, ENV_VALUE_NO) != 0)
			{
			TS_CONF_invalid(section, field);
			return 0;
			}
		}

	return 1;
	}

int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
	{
	return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
	}

int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
	{
	return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
	}

int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
				  TS_RESP_CTX *ctx)
	{
	return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, 
				TS_ESS_CERT_ID_CHAIN, ctx);
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_err.c
/* crypto/ts/ts_err.c */
/* ====================================================================
 * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/* NOTE: this file was auto generated by the mkerr.pl script: any changes
 * made to it will be overwritten when the script next updates this file,
 * only reason strings will be preserved.
 */

#include <stdio.h>
#include <openssl/err.h>
#include <openssl/ts.h>

/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR

#define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)

static ERR_STRING_DATA TS_str_functs[]=
	{
{ERR_FUNC(TS_F_D2I_TS_RESP),	"d2i_TS_RESP"},
{ERR_FUNC(TS_F_DEF_SERIAL_CB),	"DEF_SERIAL_CB"},
{ERR_FUNC(TS_F_DEF_TIME_CB),	"DEF_TIME_CB"},
{ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT),	"ESS_ADD_SIGNING_CERT"},
{ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT),	"ESS_CERT_ID_NEW_INIT"},
{ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT),	"ESS_SIGNING_CERT_NEW_INIT"},
{ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN),	"INT_TS_RESP_VERIFY_TOKEN"},
{ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO),	"PKCS7_to_TS_TST_INFO"},
{ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS),	"TS_ACCURACY_set_micros"},
{ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS),	"TS_ACCURACY_set_millis"},
{ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS),	"TS_ACCURACY_set_seconds"},
{ERR_FUNC(TS_F_TS_CHECK_IMPRINTS),	"TS_CHECK_IMPRINTS"},
{ERR_FUNC(TS_F_TS_CHECK_NONCES),	"TS_CHECK_NONCES"},
{ERR_FUNC(TS_F_TS_CHECK_POLICY),	"TS_CHECK_POLICY"},
{ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS),	"TS_CHECK_SIGNING_CERTS"},
{ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO),	"TS_CHECK_STATUS_INFO"},
{ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT),	"TS_COMPUTE_IMPRINT"},
{ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE),	"TS_CONF_set_default_engine"},
{ERR_FUNC(TS_F_TS_GET_STATUS_TEXT),	"TS_GET_STATUS_TEXT"},
{ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO),	"TS_MSG_IMPRINT_set_algo"},
{ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT),	"TS_REQ_set_msg_imprint"},
{ERR_FUNC(TS_F_TS_REQ_SET_NONCE),	"TS_REQ_set_nonce"},
{ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID),	"TS_REQ_set_policy_id"},
{ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE),	"TS_RESP_create_response"},
{ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO),	"TS_RESP_CREATE_TST_INFO"},
{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),	"TS_RESP_CTX_add_failure_info"},
{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD),	"TS_RESP_CTX_add_md"},
{ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY),	"TS_RESP_CTX_add_policy"},
{ERR_FUNC(TS_F_TS_RESP_CTX_NEW),	"TS_RESP_CTX_new"},
{ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY),	"TS_RESP_CTX_set_accuracy"},
{ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS),	"TS_RESP_CTX_set_certs"},
{ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY),	"TS_RESP_CTX_set_def_policy"},
{ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),	"TS_RESP_CTX_set_signer_cert"},
{ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),	"TS_RESP_CTX_set_status_info"},
{ERR_FUNC(TS_F_TS_RESP_GET_POLICY),	"TS_RESP_GET_POLICY"},
{ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),	"TS_RESP_SET_GENTIME_WITH_PRECISION"},
{ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO),	"TS_RESP_set_status_info"},
{ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO),	"TS_RESP_set_tst_info"},
{ERR_FUNC(TS_F_TS_RESP_SIGN),	"TS_RESP_SIGN"},
{ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE),	"TS_RESP_verify_signature"},
{ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN),	"TS_RESP_verify_token"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY),	"TS_TST_INFO_set_accuracy"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),	"TS_TST_INFO_set_msg_imprint"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE),	"TS_TST_INFO_set_nonce"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID),	"TS_TST_INFO_set_policy_id"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL),	"TS_TST_INFO_set_serial"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME),	"TS_TST_INFO_set_time"},
{ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA),	"TS_TST_INFO_set_tsa"},
{ERR_FUNC(TS_F_TS_VERIFY),	"TS_VERIFY"},
{ERR_FUNC(TS_F_TS_VERIFY_CERT),	"TS_VERIFY_CERT"},
{ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW),	"TS_VERIFY_CTX_new"},
{0,NULL}
	};

static ERR_STRING_DATA TS_str_reasons[]=
	{
{ERR_REASON(TS_R_BAD_PKCS7_TYPE)         ,"bad pkcs7 type"},
{ERR_REASON(TS_R_BAD_TYPE)               ,"bad type"},
{ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
{ERR_REASON(TS_R_COULD_NOT_SET_ENGINE)   ,"could not set engine"},
{ERR_REASON(TS_R_COULD_NOT_SET_TIME)     ,"could not set time"},
{ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED) ,"d2i ts resp int failed"},
{ERR_REASON(TS_R_DETACHED_CONTENT)       ,"detached content"},
{ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),"ess add signing cert error"},
{ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),"ess signing certificate error"},
{ERR_REASON(TS_R_INVALID_NULL_POINTER)   ,"invalid null pointer"},
{ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),"invalid signer certificate purpose"},
{ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH),"message imprint mismatch"},
{ERR_REASON(TS_R_NONCE_MISMATCH)         ,"nonce mismatch"},
{ERR_REASON(TS_R_NONCE_NOT_RETURNED)     ,"nonce not returned"},
{ERR_REASON(TS_R_NO_CONTENT)             ,"no content"},
{ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN)    ,"no time stamp token"},
{ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
{ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),"pkcs7 add signed attr error"},
{ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),"pkcs7 to ts tst info failed"},
{ERR_REASON(TS_R_POLICY_MISMATCH)        ,"policy mismatch"},
{ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
{ERR_REASON(TS_R_RESPONSE_SETUP_ERROR)   ,"response setup error"},
{ERR_REASON(TS_R_SIGNATURE_FAILURE)      ,"signature failure"},
{ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER),"there must be one signer"},
{ERR_REASON(TS_R_TIME_SYSCALL_ERROR)     ,"time syscall error"},
{ERR_REASON(TS_R_TOKEN_NOT_PRESENT)      ,"token not present"},
{ERR_REASON(TS_R_TOKEN_PRESENT)          ,"token present"},
{ERR_REASON(TS_R_TSA_NAME_MISMATCH)      ,"tsa name mismatch"},
{ERR_REASON(TS_R_TSA_UNTRUSTED)          ,"tsa untrusted"},
{ERR_REASON(TS_R_TST_INFO_SETUP_ERROR)   ,"tst info setup error"},
{ERR_REASON(TS_R_TS_DATASIGN)            ,"ts datasign"},
{ERR_REASON(TS_R_UNACCEPTABLE_POLICY)    ,"unacceptable policy"},
{ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM),"unsupported md algorithm"},
{ERR_REASON(TS_R_UNSUPPORTED_VERSION)    ,"unsupported version"},
{ERR_REASON(TS_R_WRONG_CONTENT_TYPE)     ,"wrong content type"},
{0,NULL}
	};

#endif

void ERR_load_TS_strings(void)
	{
#ifndef OPENSSL_NO_ERR

	if (ERR_func_error_string(TS_str_functs[0].error) == NULL)
		{
		ERR_load_strings(0,TS_str_functs);
		ERR_load_strings(0,TS_str_reasons);
		}
#endif
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_lib.c
/* crypto/ts/ts_lib.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
#include "ts.h"

/* Local function declarations. */

/* Function definitions. */

int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
	{
	BIGNUM num_bn;
	int result = 0;
	char *hex;

	BN_init(&num_bn);
	ASN1_INTEGER_to_BN(num, &num_bn);
	if ((hex = BN_bn2hex(&num_bn))) 
		{
		result = BIO_write(bio, "0x", 2) > 0;
		result = result && BIO_write(bio, hex, strlen(hex)) > 0;
		OPENSSL_free(hex);
		}
	BN_free(&num_bn);

	return result;
	}

int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
	{
	char obj_txt[128];

	int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
	BIO_write(bio, obj_txt, len);
	BIO_write(bio, "\n", 1);

	return 1;
	}

int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
	{
	int i, critical, n;
	X509_EXTENSION *ex;
	ASN1_OBJECT *obj;

	BIO_printf(bio, "Extensions:\n");
	n = X509v3_get_ext_count(extensions);
	for (i = 0; i < n; i++)
		{
		ex = X509v3_get_ext(extensions, i);
		obj = X509_EXTENSION_get_object(ex);
		i2a_ASN1_OBJECT(bio, obj);
		critical = X509_EXTENSION_get_critical(ex);
		BIO_printf(bio, ": %s\n", critical ? "critical" : "");
		if (!X509V3_EXT_print(bio, ex, 0, 4))
			{
			BIO_printf(bio, "%4s", "");
			M_ASN1_OCTET_STRING_print(bio, ex->value);
			}
		BIO_write(bio, "\n", 1);
		}

	return 1;
	}

int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
	{
	int i = OBJ_obj2nid(alg->algorithm);
	return BIO_printf(bio, "Hash Algorithm: %s\n",
		(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
	}

int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
	{
	const ASN1_OCTET_STRING *msg;

	TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));

	BIO_printf(bio, "Message data:\n");
	msg = TS_MSG_IMPRINT_get_msg(a);
	BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), 
			M_ASN1_STRING_length(msg), 4);

	return 1;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_req_print.c
/* crypto/ts/ts_req_print.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
#include <openssl/ts.h>

/* Function definitions. */

int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
	{
	int v;
	ASN1_OBJECT *policy_id;
	const ASN1_INTEGER *nonce;

	if (a == NULL) return 0;

	v = TS_REQ_get_version(a);
	BIO_printf(bio, "Version: %d\n", v);

	TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a));

	BIO_printf(bio, "Policy OID: ");
	policy_id = TS_REQ_get_policy_id(a);
	if (policy_id == NULL)
		BIO_printf(bio, "unspecified\n");
	else	
		TS_OBJ_print_bio(bio, policy_id);

	BIO_printf(bio, "Nonce: ");
	nonce = TS_REQ_get_nonce(a);
	if (nonce == NULL)
		BIO_printf(bio, "unspecified");
	else
		TS_ASN1_INTEGER_print_bio(bio, nonce);
	BIO_write(bio, "\n", 1);

	BIO_printf(bio, "Certificate required: %s\n", 
		   TS_REQ_get_cert_req(a) ? "yes" : "no");

	TS_ext_print_bio(bio, TS_REQ_get_exts(a));

	return 1;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_req_utils.c
/* crypto/ts/ts_req_utils.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include <openssl/ts.h>

int TS_REQ_set_version(TS_REQ *a, long version)
	{
	return ASN1_INTEGER_set(a->version, version);
	}

long TS_REQ_get_version(const TS_REQ *a)
	{
	return ASN1_INTEGER_get(a->version);
	}

int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
	{
	TS_MSG_IMPRINT *new_msg_imprint;

	if (a->msg_imprint == msg_imprint)
		return 1;
	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
	if (new_msg_imprint == NULL)
		{
		TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	TS_MSG_IMPRINT_free(a->msg_imprint);
	a->msg_imprint = new_msg_imprint;
	return 1;
	}

TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
	{
	return a->msg_imprint;
	}

int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
	{
	X509_ALGOR *new_alg;

	if (a->hash_algo == alg)
		return 1;
	new_alg = X509_ALGOR_dup(alg);
	if (new_alg == NULL)
		{
		TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	X509_ALGOR_free(a->hash_algo);
	a->hash_algo = new_alg;
	return 1;
	}

X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
	{
	return a->hash_algo;
	}

int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
	{
	return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
	}

ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
	{
	return a->hashed_msg;
	}

int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy)
	{
	ASN1_OBJECT *new_policy;

	if (a->policy_id == policy)
		return 1;
	new_policy = OBJ_dup(policy);
	if (new_policy == NULL)
		{
		TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_OBJECT_free(a->policy_id);
	a->policy_id = new_policy;
	return 1;
	}

ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
	{
	return a->policy_id;
	}

int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
	{
	ASN1_INTEGER *new_nonce;

	if (a->nonce == nonce)
		return 1;
	new_nonce = ASN1_INTEGER_dup(nonce);
	if (new_nonce == NULL)
		{
		TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_INTEGER_free(a->nonce);
	a->nonce = new_nonce;
	return 1;
	}

const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
	{
	return a->nonce;
	}

int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
	{
	a->cert_req = cert_req ? 0xFF : 0x00;
	return 1;
	}

int TS_REQ_get_cert_req(const TS_REQ *a)
	{
	return a->cert_req ? 1 : 0;
	}

STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
	{
	return a->extensions;
	}

void TS_REQ_ext_free(TS_REQ *a)
	{
	if (!a) return;
	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
	a->extensions = NULL;
	}

int TS_REQ_get_ext_count(TS_REQ *a)
	{
	return X509v3_get_ext_count(a->extensions);
	}

int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
	{
	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
	}

int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos)
	{
	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
	}

int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
	{
	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
	}

X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
	{
	return X509v3_get_ext(a->extensions,loc);
	}

X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
	{
	return X509v3_delete_ext(a->extensions,loc);
	}

int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
	{
	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
	}

void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
	{
	return X509V3_get_d2i(a->extensions, nid, crit, idx);
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_rsp_print.c
/* crypto/ts/ts_resp_print.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
#include "ts.h"

struct status_map_st
	{
	int bit;
	const char *text;
	};

/* Local function declarations. */

static int TS_status_map_print(BIO *bio, struct status_map_st *a,
			       ASN1_BIT_STRING *v);
static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);

/* Function definitions. */

int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
	{
	TS_TST_INFO *tst_info;

	BIO_printf(bio, "Status info:\n");
	TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a));

	BIO_printf(bio, "\nTST info:\n");
	tst_info = TS_RESP_get_tst_info(a);
	if (tst_info != NULL)
		TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a));
	else
		BIO_printf(bio, "Not included.\n");
		
	return 1;
	}

int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
	{
	static const char *status_map[] =
		{
		"Granted.",
		"Granted with modifications.",
		"Rejected.",
		"Waiting.",
		"Revocation warning.",
		"Revoked."
		};
	static struct status_map_st failure_map[] =
		{
		{ TS_INFO_BAD_ALG,
		"unrecognized or unsupported algorithm identifier" },
		{ TS_INFO_BAD_REQUEST,
		"transaction not permitted or supported" },
		{ TS_INFO_BAD_DATA_FORMAT,
		"the data submitted has the wrong format" },
		{ TS_INFO_TIME_NOT_AVAILABLE,
		"the TSA's time source is not available" },
		{ TS_INFO_UNACCEPTED_POLICY,
		"the requested TSA policy is not supported by the TSA" },
		{ TS_INFO_UNACCEPTED_EXTENSION,
		"the requested extension is not supported by the TSA" },
		{ TS_INFO_ADD_INFO_NOT_AVAILABLE,
		"the additional information requested could not be understood "
		"or is not available" },
		{ TS_INFO_SYSTEM_FAILURE,
		"the request cannot be handled due to system failure" },
		{ -1, NULL }
		};
	long status;
	int i, lines = 0;

	/* Printing status code. */
	BIO_printf(bio, "Status: ");
	status = ASN1_INTEGER_get(a->status);
	if (0 <= status && status < (long)(sizeof(status_map)/sizeof(status_map[0])))
		BIO_printf(bio, "%s\n", status_map[status]);
	else
		BIO_printf(bio, "out of bounds\n");
	
	/* Printing status description. */
	BIO_printf(bio, "Status description: ");
	for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i)
		{
		if (i > 0)
			BIO_puts(bio, "\t");
		ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i),
				     0);
		BIO_puts(bio, "\n");
		}
	if (i == 0)
		BIO_printf(bio, "unspecified\n");

	/* Printing failure information. */
	BIO_printf(bio, "Failure info: ");
	if (a->failure_info != NULL)
		lines = TS_status_map_print(bio, failure_map,
					    a->failure_info);
	if (lines == 0)
		BIO_printf(bio, "unspecified");
	BIO_printf(bio, "\n");

	return 1;
	}

static int TS_status_map_print(BIO *bio, struct status_map_st *a,
			       ASN1_BIT_STRING *v)
	{
	int lines = 0;

	for (; a->bit >= 0; ++a)
		{
		if (ASN1_BIT_STRING_get_bit(v, a->bit))
			{
			if (++lines > 1)
				BIO_printf(bio, ", ");
			BIO_printf(bio, "%s", a->text);
			}
		}

	return lines;
	}

int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
	{
	int v;
	ASN1_OBJECT *policy_id;
	const ASN1_INTEGER *serial;
	const ASN1_GENERALIZEDTIME *gtime;
	TS_ACCURACY *accuracy;
	const ASN1_INTEGER *nonce;
	GENERAL_NAME *tsa_name;

	if (a == NULL) return 0;

	/* Print version. */
	v = TS_TST_INFO_get_version(a);
	BIO_printf(bio, "Version: %d\n", v);

	/* Print policy id. */
	BIO_printf(bio, "Policy OID: ");
	policy_id = TS_TST_INFO_get_policy_id(a);
	TS_OBJ_print_bio(bio, policy_id);

	/* Print message imprint. */
	TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a));

	/* Print serial number. */
	BIO_printf(bio, "Serial number: ");
	serial = TS_TST_INFO_get_serial(a);
	if (serial == NULL)
		BIO_printf(bio, "unspecified");
	else
		TS_ASN1_INTEGER_print_bio(bio, serial);
	BIO_write(bio, "\n", 1);

	/* Print time stamp. */
	BIO_printf(bio, "Time stamp: ");
	gtime = TS_TST_INFO_get_time(a);
	ASN1_GENERALIZEDTIME_print(bio, gtime);
	BIO_write(bio, "\n", 1);

	/* Print accuracy. */
	BIO_printf(bio, "Accuracy: ");
	accuracy = TS_TST_INFO_get_accuracy(a);
	if (accuracy == NULL)
		BIO_printf(bio, "unspecified");
	else
		TS_ACCURACY_print_bio(bio, accuracy);
	BIO_write(bio, "\n", 1);

	/* Print ordering. */
	BIO_printf(bio, "Ordering: %s\n", 
		   TS_TST_INFO_get_ordering(a) ? "yes" : "no");

	/* Print nonce. */
	BIO_printf(bio, "Nonce: ");
	nonce = TS_TST_INFO_get_nonce(a);
	if (nonce == NULL)
		BIO_printf(bio, "unspecified");
	else
		TS_ASN1_INTEGER_print_bio(bio, nonce);
	BIO_write(bio, "\n", 1);

	/* Print TSA name. */
	BIO_printf(bio, "TSA: ");
	tsa_name = TS_TST_INFO_get_tsa(a);
	if (tsa_name == NULL)
		BIO_printf(bio, "unspecified");
	else
		{
		STACK_OF(CONF_VALUE) *nval;
		if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL)))
			X509V3_EXT_val_prn(bio, nval, 0, 0);
		sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
		}
	BIO_write(bio, "\n", 1);

	/* Print extensions. */
	TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a));

	return 1;
	}

static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy)
	{
	const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy);
	const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy);
	const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy);

	if (seconds != NULL)
		TS_ASN1_INTEGER_print_bio(bio, seconds);
	else
		BIO_printf(bio, "unspecified");
	BIO_printf(bio, " seconds, ");
	if (millis != NULL)
		TS_ASN1_INTEGER_print_bio(bio, millis);
	else
		BIO_printf(bio, "unspecified");
	BIO_printf(bio, " millis, ");
	if (micros != NULL)
		TS_ASN1_INTEGER_print_bio(bio, micros);
	else
		BIO_printf(bio, "unspecified");
	BIO_printf(bio, " micros");

	return 1;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_rsp_sign.c
/* crypto/ts/ts_resp_sign.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include "cryptlib.h"

#if defined(OPENSSL_SYS_UNIX)
#include <sys/time.h>
#endif

#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>

/* Private function declarations. */

static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);

static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
static int TS_RESP_check_request(TS_RESP_CTX *ctx);
static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, 
					    ASN1_OBJECT *policy);
static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
static int TS_RESP_sign(TS_RESP_CTX *ctx);

static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
						   STACK_OF(X509) *certs);
static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
static int TS_TST_INFO_content_new(PKCS7 *p7);
static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);

static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
	ASN1_GENERALIZEDTIME *, long, long, unsigned);

/* Default callbacks for response generation. */

static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
	{
	ASN1_INTEGER *serial = ASN1_INTEGER_new();
	if (!serial) goto err;
	if (!ASN1_INTEGER_set(serial, 1)) goto err;
	return serial;
 err:
	TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
				    "Error during serial number generation.");
	return NULL;
	}

#if defined(OPENSSL_SYS_UNIX)

/* Use the gettimeofday function call. */
static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
		       long *sec, long *usec)
	{
	struct timeval tv;
	if (gettimeofday(&tv, NULL) != 0) 
		{
		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Time is not available.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
		return 0;
		}
	/* Return time to caller. */
	*sec = tv.tv_sec;
	*usec = tv.tv_usec;

	return 1;
	}

#else

/* Use the time function call that provides only seconds precision. */
static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
		       long *sec, long *usec)
	{
	time_t t;
	if (time(&t) == (time_t) -1)
		{
		TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Time is not available.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
		return 0;
		}
	/* Return time to caller, only second precision. */
	*sec = (long) t;
	*usec = 0;

	return 1;
	}

#endif

static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
			    void *data)
	{
	/* No extensions are processed here. */
	TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
				    "Unsupported extension.");
	TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
	return 0;
	}

/* TS_RESP_CTX management functions. */

TS_RESP_CTX *TS_RESP_CTX_new()
	{
	TS_RESP_CTX *ctx;

	if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX))))
		{
		TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	memset(ctx, 0, sizeof(TS_RESP_CTX));

	/* Setting default callbacks. */
	ctx->serial_cb = def_serial_cb;
	ctx->time_cb = def_time_cb;
	ctx->extension_cb = def_extension_cb;

	return ctx;
	}

void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
	{
	if (!ctx) return;

	X509_free(ctx->signer_cert);
	EVP_PKEY_free(ctx->signer_key);
	sk_X509_pop_free(ctx->certs, X509_free);
	sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
	ASN1_OBJECT_free(ctx->default_policy);
	sk_EVP_MD_free(ctx->mds);	/* No EVP_MD_free method exists. */
	ASN1_INTEGER_free(ctx->seconds);
	ASN1_INTEGER_free(ctx->millis);
	ASN1_INTEGER_free(ctx->micros);
	OPENSSL_free(ctx);
	}

int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
	{
	if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1)
		{
		TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 
		      TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
		return 0;
		}
	if (ctx->signer_cert) X509_free(ctx->signer_cert);
	ctx->signer_cert = signer;
	CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
	return 1;
	}

int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
	{
	if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key);
	ctx->signer_key = key;
	CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);

	return 1;
	}

int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
	{
	if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
	if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err;
	return 1;
 err:
	TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
	return 0;
	}

int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
	{
	int i;

	if (ctx->certs)
		{
		sk_X509_pop_free(ctx->certs, X509_free);
		ctx->certs = NULL;
		}
	if (!certs) return 1;
	if (!(ctx->certs = sk_X509_dup(certs))) 
		{
		TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	for (i = 0; i < sk_X509_num(ctx->certs); ++i)
		{
		X509 *cert = sk_X509_value(ctx->certs, i);
		CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509);
		}

	return 1;
	}

int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
	{
	ASN1_OBJECT *copy = NULL;

	/* Create new policy stack if necessary. */
	if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) 
		goto err;
	if (!(copy = OBJ_dup(policy))) goto err;
	if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err;

	return 1;
 err:
	TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
	ASN1_OBJECT_free(copy);
	return 0;
	}

int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
	{
	/* Create new md stack if necessary. */
	if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) 
		goto err;
	/* Add the shared md, no copy needed. */
	if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err;

	return 1;
 err:
	TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
	return 0;
	}

#define TS_RESP_CTX_accuracy_free(ctx)		\
	ASN1_INTEGER_free(ctx->seconds);	\
	ctx->seconds = NULL;			\
	ASN1_INTEGER_free(ctx->millis);		\
	ctx->millis = NULL;			\
	ASN1_INTEGER_free(ctx->micros);		\
	ctx->micros = NULL;

int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, 
			     int secs, int millis, int micros)
	{

	TS_RESP_CTX_accuracy_free(ctx);
	if (secs && (!(ctx->seconds = ASN1_INTEGER_new())
		     || !ASN1_INTEGER_set(ctx->seconds, secs)))
		goto err;
	if (millis && (!(ctx->millis = ASN1_INTEGER_new())
		       || !ASN1_INTEGER_set(ctx->millis, millis)))
		goto err;
	if (micros && (!(ctx->micros = ASN1_INTEGER_new())
		       || !ASN1_INTEGER_set(ctx->micros, micros)))
		goto err;

	return 1;
 err:
	TS_RESP_CTX_accuracy_free(ctx);
	TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
	return 0;
	}

void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
	{
	ctx->flags |= flags;
	}

void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
	{
	ctx->serial_cb = cb;
	ctx->serial_cb_data = data;
	}

void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
	{
	ctx->time_cb = cb;
	ctx->time_cb_data = data;
	}

void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
				  TS_extension_cb cb, void *data)
	{
	ctx->extension_cb = cb;
	ctx->extension_cb_data = data;
	}

int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
				int status, const char *text)
	{
	TS_STATUS_INFO *si = NULL;
	ASN1_UTF8STRING *utf8_text = NULL;
	int ret = 0;

	if (!(si = TS_STATUS_INFO_new())) goto err;
	if (!ASN1_INTEGER_set(si->status, status)) goto err;
	if (text)
		{
		if (!(utf8_text = ASN1_UTF8STRING_new())
		    || !ASN1_STRING_set(utf8_text, text, strlen(text)))
			goto err;
		if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
			goto err;
		if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err;
		utf8_text = NULL;	/* Ownership is lost. */
		}
	if (!TS_RESP_set_status_info(ctx->response, si)) goto err;
	ret = 1;
 err:
	if (!ret)
		TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
	TS_STATUS_INFO_free(si);
	ASN1_UTF8STRING_free(utf8_text);
	return ret;
	}

int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
				     int status, const char *text)
	{
	int ret = 1;
	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);

	if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED)
		{
		/* Status has not been set, set it now. */
		ret = TS_RESP_CTX_set_status_info(ctx, status, text);
		}
	return ret;
	}

int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
	{
	TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
	if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
		goto err;
	if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
		goto err;
	return 1;
 err:
	TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
	return 0;
	}

TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
	{
	return ctx->request;
	}

TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
	{
	return ctx->tst_info;
	}

int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
       {
       if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
	       return 0;
       ctx->clock_precision_digits = precision;
       return 1;
       }

/* Main entry method of the response generation. */
TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
	{
	ASN1_OBJECT *policy;
	TS_RESP *response;
	int result = 0;

	TS_RESP_CTX_init(ctx);

	/* Creating the response object. */
	if (!(ctx->response = TS_RESP_new())) 
		{
		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
		goto end;
		}

	/* Parsing DER request. */
	if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
		{
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Bad request format or "
					    "system error.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
		goto end;
		}

	/* Setting default status info. */
	if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
		goto end;

	/* Checking the request format. */
	if (!TS_RESP_check_request(ctx)) goto end;

	/* Checking acceptable policies. */
	if (!(policy = TS_RESP_get_policy(ctx))) goto end;

	/* Creating the TS_TST_INFO object. */
	if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
		goto end;

	/* Processing extensions. */
	if (!TS_RESP_process_extensions(ctx)) goto end;

	/* Generating the signature. */
	if (!TS_RESP_sign(ctx)) goto end;

	/* Everything was successful. */
	result = 1;
 end:
	if (!result)
		{
		TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
		if (ctx->response != NULL)
			{
			if (TS_RESP_CTX_set_status_info_cond(ctx,
				TS_STATUS_REJECTION, "Error during response "
				"generation.") == 0)
				{
				TS_RESP_free(ctx->response);
				ctx->response = NULL;
				}
			}
		}
	response = ctx->response;
	ctx->response = NULL;	/* Ownership will be returned to caller. */
	TS_RESP_CTX_cleanup(ctx);
	return response;
	}

/* Initializes the variable part of the context. */
static void TS_RESP_CTX_init(TS_RESP_CTX *ctx)
	{
	ctx->request = NULL;
	ctx->response = NULL;
	ctx->tst_info = NULL;
	}

/* Cleans up the variable part of the context. */
static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
	{
	TS_REQ_free(ctx->request);
	ctx->request = NULL;
	TS_RESP_free(ctx->response);
	ctx->response = NULL;
	TS_TST_INFO_free(ctx->tst_info);
	ctx->tst_info = NULL;
	}

/* Checks the format and content of the request. */
static int TS_RESP_check_request(TS_RESP_CTX *ctx)
	{
	TS_REQ *request = ctx->request;
	TS_MSG_IMPRINT *msg_imprint;
	X509_ALGOR *md_alg;
	int md_alg_id;
	const ASN1_OCTET_STRING *digest;
	EVP_MD *md = NULL;
	int i;

	/* Checking request version. */
	if (TS_REQ_get_version(request) != 1)
		{
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Bad request version.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
		return 0;
		}

	/* Checking message digest algorithm. */
	msg_imprint = TS_REQ_get_msg_imprint(request);
	md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
	md_alg_id = OBJ_obj2nid(md_alg->algorithm);
	for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i)
		{
		EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
		if (md_alg_id == EVP_MD_type(current_md))
			md = current_md;
		}
	if (!md)
		{
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Message digest algorithm is "
					    "not supported.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
		return 0;
		}

	/* No message digest takes parameter. */
	if (md_alg->parameter 
	    && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL)
		{
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Superfluous message digest "
					    "parameter.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
		return 0;
		}
	/* Checking message digest size. */
	digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
	if (digest->length != EVP_MD_size(md))
		{
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Bad message digest.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
		return 0;
		}

	return 1;
	}

/* Returns the TSA policy based on the requested and acceptable policies. */
static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx)
	{
	ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
	ASN1_OBJECT *policy = NULL;
	int i;

	if (ctx->default_policy == NULL)
		{
		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
		return NULL;
		}
	/* Return the default policy if none is requested or the default is
	   requested. */
	if (!requested || !OBJ_cmp(requested, ctx->default_policy))
		policy = ctx->default_policy;

	/* Check if the policy is acceptable. */
	for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i)
		{
		ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
		if (!OBJ_cmp(requested, current))
			policy = current;
		}
	if (!policy)
		{
		TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
					    "Requested policy is not "
					    "supported.");
		TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
		}
	return policy;
	}

/* Creates the TS_TST_INFO object based on the settings of the context. */
static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
					    ASN1_OBJECT *policy)
	{
	int result = 0;
	TS_TST_INFO *tst_info = NULL;
	ASN1_INTEGER *serial = NULL;
	ASN1_GENERALIZEDTIME *asn1_time = NULL;
	long sec, usec;
	TS_ACCURACY *accuracy = NULL;
	const ASN1_INTEGER *nonce;
	GENERAL_NAME *tsa_name = NULL;

	if (!(tst_info = TS_TST_INFO_new())) goto end;
	if (!TS_TST_INFO_set_version(tst_info, 1)) goto end;
	if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end;
	if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
		goto end;
	if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data))
	    || !TS_TST_INFO_set_serial(tst_info, serial))
		goto end;
	if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec)
            || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, 
					sec, usec, 
					ctx->clock_precision_digits))
	    || !TS_TST_INFO_set_time(tst_info, asn1_time))
		goto end;

	/* Setting accuracy if needed. */
	if ((ctx->seconds || ctx->millis || ctx->micros) 
	    && !(accuracy = TS_ACCURACY_new()))
		goto end;

	if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
		goto end;
	if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
		goto end;
	if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
		goto end;
	if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) 
		goto end;

	/* Setting ordering. */
	if ((ctx->flags & TS_ORDERING) 
	    && !TS_TST_INFO_set_ordering(tst_info, 1))
		goto end;
	
	/* Setting nonce if needed. */
	if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL
	    && !TS_TST_INFO_set_nonce(tst_info, nonce))
		goto end;

	/* Setting TSA name to subject of signer certificate. */
	if (ctx->flags & TS_TSA_NAME)
		{
		if (!(tsa_name = GENERAL_NAME_new())) goto end;
		tsa_name->type = GEN_DIRNAME;
		tsa_name->d.dirn = 
			X509_NAME_dup(ctx->signer_cert->cert_info->subject);
		if (!tsa_name->d.dirn) goto end;
		if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end;
		}

	result = 1;
 end:
	if (!result)
		{
		TS_TST_INFO_free(tst_info);
		tst_info = NULL;
		TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
						 "Error during TSTInfo "
						 "generation.");
		}
	GENERAL_NAME_free(tsa_name);
	TS_ACCURACY_free(accuracy);
	ASN1_GENERALIZEDTIME_free(asn1_time);
	ASN1_INTEGER_free(serial);
	
	return tst_info;
	}

/* Processing the extensions of the request. */
static int TS_RESP_process_extensions(TS_RESP_CTX *ctx)
	{
	STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
	int i;
	int ok = 1;

	for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i)
		{
		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
		/* XXXXX The last argument was previously
		   (void *)ctx->extension_cb, but ISO C doesn't permit
		   converting a function pointer to void *.  For lack of
		   better information, I'm placing a NULL there instead.
		   The callback can pick its own address out from the ctx
		   anyway...
		*/
		ok = (*ctx->extension_cb)(ctx, ext, NULL);
		}

	return ok;
	}

/* Functions for signing the TS_TST_INFO structure of the context. */
static int TS_RESP_sign(TS_RESP_CTX *ctx)
	{
	int ret = 0;
	PKCS7 *p7 = NULL;
	PKCS7_SIGNER_INFO *si;
	STACK_OF(X509) *certs;	/* Certificates to include in sc. */
	ESS_SIGNING_CERT *sc = NULL;
	ASN1_OBJECT *oid;
	BIO *p7bio = NULL;
	int i;

	/* Check if signcert and pkey match. */
	if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
		TSerr(TS_F_TS_RESP_SIGN, 
		      TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
                goto err;
	}

	/* Create a new PKCS7 signed object. */
	if (!(p7 = PKCS7_new())) {
		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err;

	/* Force SignedData version to be 3 instead of the default 1. */
	if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err;

	/* Add signer certificate and optional certificate chain. */
	if (TS_REQ_get_cert_req(ctx->request))
		{
		PKCS7_add_certificate(p7, ctx->signer_cert);
		if (ctx->certs)
			{
			for(i = 0; i < sk_X509_num(ctx->certs); ++i) 
				{
				X509 *cert = sk_X509_value(ctx->certs, i);
				PKCS7_add_certificate(p7, cert);
				}
			}
		}

	/* Add a new signer info. */
    	if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, 
				       ctx->signer_key, EVP_sha1())))
		{
		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
		goto err;
		}

	/* Add content type signed attribute to the signer info. */
	oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
					V_ASN1_OBJECT, oid))
		{
		TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
		goto err;
		}

	/* Create the ESS SigningCertificate attribute which contains 
	   the signer certificate id and optionally the certificate chain. */
	certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
	if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
		goto err;

	/* Add SigningCertificate signed attribute to the signer info. */
	if (!ESS_add_signing_cert(si, sc))
		{
		TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
		goto err;
		}	

	/* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
	if (!TS_TST_INFO_content_new(p7)) goto err;

	/* Add the DER encoded tst_info to the PKCS7 structure. */
	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
		TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	/* Convert tst_info to DER. */
	if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info))
		{
		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
		goto err;
		}

	/* Create the signature and add it to the signer info. */
        if (!PKCS7_dataFinal(p7, p7bio))
		{
		TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
		goto err;
		}

	/* Set new PKCS7 and TST_INFO objects. */
	TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
	p7 = NULL;		/* Ownership is lost. */
	ctx->tst_info = NULL;	/* Ownership is lost. */

	ret = 1;
 err:
	if (!ret)
		TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
						 "Error during signature "
						 "generation.");
	BIO_free_all(p7bio);
	ESS_SIGNING_CERT_free(sc);
	PKCS7_free(p7);
	return ret;
	}

static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
						   STACK_OF(X509) *certs)
	{
	ESS_CERT_ID *cid;
	ESS_SIGNING_CERT *sc = NULL;
	int i;

	/* Creating the ESS_CERT_ID stack. */
	if (!(sc = ESS_SIGNING_CERT_new())) goto err;
	if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
		goto err;

	/* Adding the signing certificate id. */
	if (!(cid = ESS_CERT_ID_new_init(signcert, 0))
	    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
		goto err;
	/* Adding the certificate chain ids. */
	for (i = 0; i < sk_X509_num(certs); ++i)
		{
		X509 *cert = sk_X509_value(certs, i);
		if (!(cid = ESS_CERT_ID_new_init(cert, 1))
		    || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
			goto err;
		}

	return sc;
err:
	ESS_SIGNING_CERT_free(sc);
	TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
	return NULL;
	}

static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
	{
	ESS_CERT_ID *cid = NULL;
	GENERAL_NAME *name = NULL;
	
	/* Recompute SHA1 hash of certificate if necessary (side effect). */
	X509_check_purpose(cert, -1, 0);

	if (!(cid = ESS_CERT_ID_new())) goto err;
	if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
				   sizeof(cert->sha1_hash)))
		goto err;

	/* Setting the issuer/serial if requested. */
	if (issuer_needed)
		{
		/* Creating issuer/serial structure. */
		if (!cid->issuer_serial
		    && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
			goto err;
		/* Creating general name from the certificate issuer. */
		if (!(name = GENERAL_NAME_new())) goto err;
		name->type = GEN_DIRNAME;
		if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) 
			goto err;
		if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 
			goto err;
		name = NULL;	/* Ownership is lost. */
		/* Setting the serial number. */
		ASN1_INTEGER_free(cid->issuer_serial->serial);
		if (!(cid->issuer_serial->serial = 
		      ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
			goto err;
		}

	return cid;
err:
	GENERAL_NAME_free(name);
	ESS_CERT_ID_free(cid);
	TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
	return NULL;
	}

static int TS_TST_INFO_content_new(PKCS7 *p7)
	{
	PKCS7 *ret = NULL;
	ASN1_OCTET_STRING *octet_string = NULL;

	/* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
	if (!(ret = PKCS7_new())) goto err;
	if (!(ret->d.other = ASN1_TYPE_new())) goto err;
	ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
	if (!(octet_string = ASN1_OCTET_STRING_new())) goto err;
	ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
	octet_string = NULL;

	/* Add encapsulated content to signed PKCS7 structure. */
	if (!PKCS7_set_content(p7, ret)) goto err;

	return 1;
 err:
	ASN1_OCTET_STRING_free(octet_string);
	PKCS7_free(ret);
	return 0;
	}

static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
	{
	ASN1_STRING *seq = NULL;
	unsigned char *p, *pp = NULL;
	int len;

	len = i2d_ESS_SIGNING_CERT(sc, NULL);
	if (!(pp = (unsigned char *) OPENSSL_malloc(len)))
		{
		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p = pp;
	i2d_ESS_SIGNING_CERT(sc, &p);
	if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
		{
		TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	OPENSSL_free(pp); pp = NULL;
	return PKCS7_add_signed_attribute(si, 
					  NID_id_smime_aa_signingCertificate,
					  V_ASN1_SEQUENCE, seq);
 err:
	ASN1_STRING_free(seq);
	OPENSSL_free(pp);

	return 0;
	}


static ASN1_GENERALIZEDTIME *
TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, 
				   long sec, long usec, unsigned precision)
	{
	time_t time_sec = (time_t) sec;
	struct tm *tm = NULL;	
	char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
	char *p = genTime_str;
	char *p_end = genTime_str + sizeof(genTime_str);

	if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
		goto err;

	
	if (!(tm = gmtime(&time_sec)))
		goto err;

	/* 
	 * Put "genTime_str" in GeneralizedTime format.  We work around the 
	 * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST 
	 * NOT include fractional seconds") and OpenSSL related functions to 
	 * meet the rfc3161 requirement: "GeneralizedTime syntax can include 
	 * fraction-of-second details". 
	 */                   
	p += BIO_snprintf(p, p_end - p,
			  "%04d%02d%02d%02d%02d%02d",
			  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
			  tm->tm_hour, tm->tm_min, tm->tm_sec);
	if (precision > 0)
	{
		/* Add fraction of seconds (leave space for dot and null). */
		BIO_snprintf(p, 2 + precision, ".%ld", usec);
		/* We cannot use the snprintf return value, 
		   because it might have been truncated. */
		p += strlen(p);

		/* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
		   the following restrictions for a DER-encoding, which OpenSSL
		   (specifically ASN1_GENERALIZEDTIME_check() function) doesn't 
		   support:
		   "The encoding MUST terminate with a "Z" (which means "Zulu" 
		   time). The decimal point element, if present, MUST be the 
		   point option ".". The fractional-seconds elements, 
		   if present, MUST omit all trailing 0's; 
		   if the elements correspond to 0, they MUST be wholly
		   omitted, and the decimal point element also MUST be
		   omitted." */
		/* Remove trailing zeros. The dot guarantees the exit
		   condition of this loop even if all the digits are zero. */
		while (*--p == '0')
			/* empty */;
		/* p points to either the dot or the last non-zero digit. */
		if (*p != '.') ++p;
		}
	/* Add the trailing Z and the terminating null. */
	*p++ = 'Z';
	*p++ = '\0';

	/* Now call OpenSSL to check and set our genTime value */
	if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
		goto err;
	if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str))
		{
		ASN1_GENERALIZEDTIME_free(asn1_time);
		goto err;
		}

	return asn1_time;
 err:
	TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
	return NULL;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_rsp_utils.c
/* crypto/ts/ts_resp_utils.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>

/* Function definitions. */

int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
	{
	TS_STATUS_INFO *new_status_info;

	if (a->status_info == status_info)
		return 1;
	new_status_info = TS_STATUS_INFO_dup(status_info);
	if (new_status_info == NULL)
		{
		TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	TS_STATUS_INFO_free(a->status_info);
	a->status_info = new_status_info;

	return 1;
	}

TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
	{
	return a->status_info;
	}

/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
	{
	/* Set new PKCS7 and TST_INFO objects. */
	PKCS7_free(a->token);
	a->token = p7;
	TS_TST_INFO_free(a->tst_info);
	a->tst_info = tst_info;
	}

PKCS7 *TS_RESP_get_token(TS_RESP *a)
	{
	return a->token;
	}

TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
	{
	return a->tst_info;
	}

int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
	{
	return ASN1_INTEGER_set(a->version, version);
	}

long TS_TST_INFO_get_version(const TS_TST_INFO *a)
	{
	return ASN1_INTEGER_get(a->version);
	}

int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
	{
	ASN1_OBJECT *new_policy;

	if (a->policy_id == policy)
		return 1;
	new_policy = OBJ_dup(policy);
	if (new_policy == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_OBJECT_free(a->policy_id);
	a->policy_id = new_policy;
	return 1;
	}

ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
	{
	return a->policy_id;
	}

int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
	{
	TS_MSG_IMPRINT *new_msg_imprint;

	if (a->msg_imprint == msg_imprint)
		return 1;
	new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
	if (new_msg_imprint == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	TS_MSG_IMPRINT_free(a->msg_imprint);
	a->msg_imprint = new_msg_imprint;
	return 1;
	}

TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
	{
	return a->msg_imprint;
	}

int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
	{
	ASN1_INTEGER *new_serial;

	if (a->serial == serial)
		return 1;
	new_serial = ASN1_INTEGER_dup(serial);
	if (new_serial == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_INTEGER_free(a->serial);
	a->serial = new_serial;
	return 1;
	}

const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
	{
	return a->serial;
	}

int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
	{
	ASN1_GENERALIZEDTIME *new_time;

	if (a->time == gtime)
		return 1;
	new_time = M_ASN1_GENERALIZEDTIME_dup(gtime);
	if (new_time == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_GENERALIZEDTIME_free(a->time);
	a->time = new_time;
	return 1;
	}

const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
	{
	return a->time;
	}

int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
	{
	TS_ACCURACY *new_accuracy;

	if (a->accuracy == accuracy)
		return 1;
	new_accuracy = TS_ACCURACY_dup(accuracy);
	if (new_accuracy == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	TS_ACCURACY_free(a->accuracy);
	a->accuracy = new_accuracy;
	return 1;
	}

TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
	{
	return a->accuracy;
	}

int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
	{
	ASN1_INTEGER *new_seconds;

	if (a->seconds == seconds)
		return 1;
	new_seconds = ASN1_INTEGER_dup(seconds);
	if (new_seconds == NULL)
		{
		TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_INTEGER_free(a->seconds);
	a->seconds = new_seconds;
	return 1;
	}

const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
	{
	return a->seconds;
	}

int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
	{
	ASN1_INTEGER *new_millis = NULL;

	if (a->millis == millis)
		return 1;
	if (millis != NULL)
		{
		new_millis = ASN1_INTEGER_dup(millis);
		if (new_millis == NULL)
			{
			TSerr(TS_F_TS_ACCURACY_SET_MILLIS, 
			      ERR_R_MALLOC_FAILURE);
			return 0;
			}
		}
	ASN1_INTEGER_free(a->millis);
	a->millis = new_millis;
	return 1;
	}

const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
	{
	return a->millis;
	}

int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
	{
	ASN1_INTEGER *new_micros = NULL;

	if (a->micros == micros)
		return 1;
	if (micros != NULL)
		{
		new_micros = ASN1_INTEGER_dup(micros);
		if (new_micros == NULL)
			{
			TSerr(TS_F_TS_ACCURACY_SET_MICROS, 
			      ERR_R_MALLOC_FAILURE);
			return 0;
			}
		}
	ASN1_INTEGER_free(a->micros);
	a->micros = new_micros;
	return 1;
	}

const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
	{
	return a->micros;
	}

int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
	{
	a->ordering = ordering ? 0xFF : 0x00;
	return 1;
	}

int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
	{
	return a->ordering ? 1 : 0;
	}

int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
	{
	ASN1_INTEGER *new_nonce;

	if (a->nonce == nonce)
		return 1;
	new_nonce = ASN1_INTEGER_dup(nonce);
	if (new_nonce == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	ASN1_INTEGER_free(a->nonce);
	a->nonce = new_nonce;
	return 1;
	}

const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
	{
	return a->nonce;
	}

int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
	{
	GENERAL_NAME *new_tsa;

	if (a->tsa == tsa)
		return 1;
	new_tsa = GENERAL_NAME_dup(tsa);
	if (new_tsa == NULL)
		{
		TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	GENERAL_NAME_free(a->tsa);
	a->tsa = new_tsa;
	return 1;
	}

GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
	{
	return a->tsa;
	}

STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
	{
	return a->extensions;
	}

void TS_TST_INFO_ext_free(TS_TST_INFO *a)
	{
	if (!a) return;
	sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
	a->extensions = NULL;
	}

int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
	{
	return X509v3_get_ext_count(a->extensions);
	}

int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
	{
	return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
	}

int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos)
	{
	return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
	}

int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
	{
	return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
	}

X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
	{
	return X509v3_get_ext(a->extensions,loc);
	}

X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
	{
	return X509v3_delete_ext(a->extensions,loc);
	}

int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
	{
	return X509v3_add_ext(&a->extensions,ex,loc) != NULL;
	}

void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
	{
	return X509V3_get_d2i(a->extensions, nid, crit, idx);
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_rsp_verify.c
/* crypto/ts/ts_resp_verify.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/ts.h>
#include <openssl/pkcs7.h>

/* Private function declarations. */

static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
			  X509 *signer, STACK_OF(X509) **chain);
static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
				 PKCS7 *token, TS_TST_INFO *tst_info);
static int TS_check_status_info(TS_RESP *response);
static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
			      X509_ALGOR **md_alg, 
			      unsigned char **imprint, unsigned *imprint_len);
static int TS_check_imprints(X509_ALGOR *algor_a, 
			     unsigned char *imprint_a, unsigned len_a,
			     TS_TST_INFO *tst_info);
static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);

/*
 * Local mapping between response codes and descriptions.
 * Don't forget to change TS_STATUS_BUF_SIZE when modifying 
 * the elements of this array.
 */
static const char *TS_status_text[] =
	{ "granted",
	  "grantedWithMods",
	  "rejection",
	  "waiting",
	  "revocationWarning",
	  "revocationNotification" };

#define TS_STATUS_TEXT_SIZE	(sizeof(TS_status_text)/sizeof(*TS_status_text))

/*
 * This must be greater or equal to the sum of the strings in TS_status_text
 * plus the number of its elements.
 */
#define TS_STATUS_BUF_SIZE	256

static struct
	{
	int code;
	const char *text;
	} TS_failure_info[] =
		{ { TS_INFO_BAD_ALG, "badAlg" },
		  { TS_INFO_BAD_REQUEST, "badRequest" },
		  { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
		  { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
		  { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
		  { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
		  { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
		  { TS_INFO_SYSTEM_FAILURE, "systemFailure" } };

#define TS_FAILURE_INFO_SIZE	(sizeof(TS_failure_info) / \
				sizeof(*TS_failure_info))

/* Functions for verifying a signed TS_TST_INFO structure. */

/*
 * This function carries out the following tasks:
 *	- Checks if there is one and only one signer.
 *	- Search for the signing certificate in 'certs' and in the response.
 *	- Check the extended key usage and key usage fields of the signer
 *	certificate (done by the path validation).
 *	- Build and validate the certificate path.
 *	- Check if the certificate path meets the requirements of the
 *	SigningCertificate ESS signed attribute.
 *	- Verify the signature value.
 *	- Returns the signer certificate in 'signer', if 'signer' is not NULL.
 */
int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
			     X509_STORE *store, X509 **signer_out)
	{
	STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
	PKCS7_SIGNER_INFO *si;
	STACK_OF(X509) *signers = NULL;
	X509	*signer;
	STACK_OF(X509) *chain = NULL;
	char	buf[4096];
	int	i, j = 0, ret = 0;
	BIO	*p7bio = NULL;

	/* Some sanity checks first. */
	if (!token)
		{
		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
		goto err;
		}

	/* Check for the correct content type */
	if(!PKCS7_type_is_signed(token))
		{
		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
		goto err;
		}

	/* Check if there is one and only one signer. */
	sinfos = PKCS7_get_signer_info(token);
	if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1)
		{
		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
		      TS_R_THERE_MUST_BE_ONE_SIGNER);
		goto err;
		}
	si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);

	/* Check for no content: no data to verify signature. */
	if (PKCS7_get_detached(token))
		{
		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
		goto err;
		}
	
	/* Get hold of the signer certificate, search only internal
	   certificates if it was requested. */
	signers = PKCS7_get0_signers(token, certs, 0);
	if (!signers || sk_X509_num(signers) != 1) goto err;
	signer = sk_X509_value(signers, 0);

	/* Now verify the certificate. */
	if (!TS_verify_cert(store, certs, signer, &chain)) goto err;

	/* Check if the signer certificate is consistent with the
	   ESS extension. */
	if (!TS_check_signing_certs(si, chain)) goto err;

	/* Creating the message digest. */
	p7bio = PKCS7_dataInit(token, NULL);

	/* We now have to 'read' from p7bio to calculate digests etc. */
	while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0);

	/* Verifying the signature. */
	j = PKCS7_signatureVerify(p7bio, token, si, signer);
	if (j <= 0)
		{
		TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
		goto err;
		}

	/* Return the signer certificate if needed. */
	if (signer_out)
		{
		*signer_out = signer;
		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
		}

	ret = 1;

 err:
	BIO_free_all(p7bio);
	sk_X509_pop_free(chain, X509_free);
	sk_X509_free(signers);

	return ret;
	}

/*
 * The certificate chain is returned in chain. Caller is responsible for
 * freeing the vector.
 */
static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
			  X509 *signer, STACK_OF(X509) **chain)
	{
	X509_STORE_CTX	cert_ctx;
	int i;
	int ret = 1;

	/* chain is an out argument. */
	*chain = NULL;
	X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
	X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
	i = X509_verify_cert(&cert_ctx);
	if (i <= 0)
		{
		int j = X509_STORE_CTX_get_error(&cert_ctx);
		TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
		ERR_add_error_data(2, "Verify error:",
				   X509_verify_cert_error_string(j));
		ret = 0;
		}
	else
		{
		/* Get a copy of the certificate chain. */
		*chain = X509_STORE_CTX_get1_chain(&cert_ctx);
		}

	X509_STORE_CTX_cleanup(&cert_ctx);

	return ret;
	}

static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
	{
	ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
	STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
	X509 *cert;
	int i = 0;
	int ret = 0;

	if (!ss) goto err;
	cert_ids = ss->cert_ids;
	/* The signer certificate must be the first in cert_ids. */
	cert = sk_X509_value(chain, 0);
	if (TS_find_cert(cert_ids, cert) != 0) goto err;
	
	/* Check the other certificates of the chain if there are more
	   than one certificate ids in cert_ids. */
	if (sk_ESS_CERT_ID_num(cert_ids) > 1)
		{
		/* All the certificates of the chain must be in cert_ids. */
		for (i = 1; i < sk_X509_num(chain); ++i)
			{
			cert = sk_X509_value(chain, i);
			if (TS_find_cert(cert_ids, cert) < 0) goto err;
			}
		}
	ret = 1;
 err:
	if (!ret)
		TSerr(TS_F_TS_CHECK_SIGNING_CERTS, 
		      TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
	ESS_SIGNING_CERT_free(ss);
	return ret;
	}

static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
	{
	ASN1_TYPE *attr;
	const unsigned char *p;
	attr = PKCS7_get_signed_attribute(si, 
					  NID_id_smime_aa_signingCertificate);
	if (!attr) return NULL;
	p = attr->value.sequence->data;
	return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
	}

/* Returns < 0 if certificate is not found, certificate index otherwise. */
static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
	{
	int i;

	if (!cert_ids || !cert) return -1;

	/* Recompute SHA1 hash of certificate if necessary (side effect). */
	X509_check_purpose(cert, -1, 0);

	/* Look for cert in the cert_ids vector. */
	for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i)
		{
		ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);

		/* Check the SHA-1 hash first. */
		if (cid->hash->length == sizeof(cert->sha1_hash)
		    && !memcmp(cid->hash->data, cert->sha1_hash,
			       sizeof(cert->sha1_hash)))
			{
			/* Check the issuer/serial as well if specified. */
			ESS_ISSUER_SERIAL *is = cid->issuer_serial;
			if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
				return i;
			}
		}
	
	return -1;
	}

static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
	{
	GENERAL_NAME *issuer;

	if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1;

	/* Check the issuer first. It must be a directory name. */
	issuer = sk_GENERAL_NAME_value(is->issuer, 0);
	if (issuer->type != GEN_DIRNAME 
	    || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
		return -1;

	/* Check the serial number, too. */
	if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
		return -1;

	return 0;
	}

/*
 * Verifies whether 'response' contains a valid response with regards 
 * to the settings of the context:
 *	- Gives an error message if the TS_TST_INFO is not present.
 *	- Calls _TS_RESP_verify_token to verify the token content.
 */
int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
	{
	PKCS7 *token = TS_RESP_get_token(response);
	TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
	int ret = 0;

	/* Check if we have a successful TS_TST_INFO object in place. */
	if (!TS_check_status_info(response)) goto err;

	/* Check the contents of the time stamp token. */
	if (!int_TS_RESP_verify_token(ctx, token, tst_info))
		goto err;

	ret = 1;
 err:
	return ret;
	}

/*
 * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
 * calls the internal int_TS_RESP_verify_token function for verifying it.
 */
int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
	{
	TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
	int ret = 0;
	if (tst_info)
		{
		ret = int_TS_RESP_verify_token(ctx, token, tst_info);
		TS_TST_INFO_free(tst_info);
		}
	return ret;
	}

/*
 * Verifies whether the 'token' contains a valid time stamp token 
 * with regards to the settings of the context. Only those checks are
 * carried out that are specified in the context:
 *	- Verifies the signature of the TS_TST_INFO.
 *	- Checks the version number of the response.
 *	- Check if the requested and returned policies math.
 *	- Check if the message imprints are the same.
 *	- Check if the nonces are the same.
 *	- Check if the TSA name matches the signer.
 *	- Check if the TSA name is the expected TSA.
 */
static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 
				 PKCS7 *token, TS_TST_INFO *tst_info)
	{
	X509 *signer = NULL;
	GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
	X509_ALGOR *md_alg = NULL;
	unsigned char *imprint = NULL;
	unsigned imprint_len = 0;
	int ret = 0;

	/* Verify the signature. */
	if ((ctx->flags & TS_VFY_SIGNATURE)
	    && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
					 &signer))
		goto err;
	
	/* Check version number of response. */
	if ((ctx->flags & TS_VFY_VERSION)
	    && TS_TST_INFO_get_version(tst_info) != 1)
		{
		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
		goto err;
		}

	/* Check policies. */
	if ((ctx->flags & TS_VFY_POLICY)
	    && !TS_check_policy(ctx->policy, tst_info))
		goto err;
	
	/* Check message imprints. */
	if ((ctx->flags & TS_VFY_IMPRINT)
	    && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
				  tst_info)) 
		goto err;

	/* Compute and check message imprints. */
	if ((ctx->flags & TS_VFY_DATA)
	    && (!TS_compute_imprint(ctx->data, tst_info,
				    &md_alg, &imprint, &imprint_len)
	    || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
		goto err;

	/* Check nonces. */
	if ((ctx->flags & TS_VFY_NONCE)
	    && !TS_check_nonces(ctx->nonce, tst_info))
		goto err;

	/* Check whether TSA name and signer certificate match. */
	if ((ctx->flags & TS_VFY_SIGNER)
	    && tsa_name && !TS_check_signer_name(tsa_name, signer))
		{
		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
		goto err;
		}

	/* Check whether the TSA is the expected one. */
	if ((ctx->flags & TS_VFY_TSA_NAME)
	    && !TS_check_signer_name(ctx->tsa_name, signer))
		{
		TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
		goto err;
		}

	ret = 1;
 err:
	X509_free(signer);
	X509_ALGOR_free(md_alg);
	OPENSSL_free(imprint);
	return ret;
	}

static int TS_check_status_info(TS_RESP *response)
	{
	TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
	long status = ASN1_INTEGER_get(info->status);
	const char *status_text = NULL;
	char *embedded_status_text = NULL;
	char failure_text[TS_STATUS_BUF_SIZE] = "";

	/* Check if everything went fine. */
	if (status == 0 || status == 1) return 1;

	/* There was an error, get the description in status_text. */
	if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
		status_text = TS_status_text[status];
	else
		status_text = "unknown code";

	/* Set the embedded_status_text to the returned description. */
	if (sk_ASN1_UTF8STRING_num(info->text) > 0
	    && !(embedded_status_text = TS_get_status_text(info->text)))
		return 0;
	
	/* Filling in failure_text with the failure information. */
	if (info->failure_info)
		{
		int i;
		int first = 1;
		for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i)
			{
			if (ASN1_BIT_STRING_get_bit(info->failure_info,
						    TS_failure_info[i].code))
				{
				if (!first)
					strcpy(failure_text, ",");
				else
					first = 0;
				strcat(failure_text, TS_failure_info[i].text);
				}
			}
		}
	if (failure_text[0] == '\0')
		strcpy(failure_text, "unspecified");

	/* Making up the error string. */
	TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
	ERR_add_error_data(6,
			   "status code: ", status_text,
			   ", status text: ", embedded_status_text ? 
			   embedded_status_text : "unspecified",
			   ", failure codes: ", failure_text);
	OPENSSL_free(embedded_status_text);

	return 0;
	}

static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
	{
	int i;
	unsigned int length = 0;
	char *result = NULL;
	char *p;

	/* Determine length first. */
	for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i)
		{
		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
		length += ASN1_STRING_length(current);
		length += 1;	/* separator character */
		}
	/* Allocate memory (closing '\0' included). */
	if (!(result = OPENSSL_malloc(length)))
		{
		TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	/* Concatenate the descriptions. */
	for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i)
		{
		ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
		length = ASN1_STRING_length(current);
		if (i > 0) *p++ = '/';
		strncpy(p, (const char *)ASN1_STRING_data(current), length);
		p += length;
		}
	/* We do have space for this, too. */
	*p = '\0';
	
	return result;
	}

static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
	{
	ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);

	if (OBJ_cmp(req_oid, resp_oid) != 0)
		{
		TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
		return 0;
		}

	return 1;
	}

static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
			      X509_ALGOR **md_alg, 
			      unsigned char **imprint, unsigned *imprint_len)
	{
	TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
	X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
	const EVP_MD *md;
	EVP_MD_CTX md_ctx;
	unsigned char buffer[4096];
	int length;

	*md_alg = NULL;
	*imprint = NULL;

	/* Return the MD algorithm of the response. */
	if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err;

	/* Getting the MD object. */
	if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm)))
		{
		TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
		goto err;
		}

	/* Compute message digest. */
	*imprint_len = EVP_MD_size(md);
	if (!(*imprint = OPENSSL_malloc(*imprint_len))) 
		{
		TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	EVP_DigestInit(&md_ctx, md);
	while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
		{
		EVP_DigestUpdate(&md_ctx, buffer, length);
		}
	EVP_DigestFinal(&md_ctx, *imprint, NULL);

	return 1;
 err:
	X509_ALGOR_free(*md_alg);
	OPENSSL_free(*imprint);
	*imprint_len = 0;
	return 0;
	}

static int TS_check_imprints(X509_ALGOR *algor_a, 
			     unsigned char *imprint_a, unsigned len_a,
			     TS_TST_INFO *tst_info)
	{
	TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
	X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
	int ret = 0;

	/* algor_a is optional. */
	if (algor_a)
		{
		/* Compare algorithm OIDs. */
		if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err;

		/* The parameter must be NULL in both. */
		if ((algor_a->parameter 
		     && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
		    || (algor_b->parameter
			&& ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
			goto err;
		}

	/* Compare octet strings. */
	ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
		memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
 err:
	if (!ret)
		TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
	return ret;
	}

static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
	{
	const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);

	/* Error if nonce is missing. */
	if (!b)
		{
		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
		return 0;
		}

	/* No error if a nonce is returned without being requested. */
	if (ASN1_INTEGER_cmp(a, b) != 0)
		{
		TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
		return 0;
		}

	return 1;
	}

/* Check if the specified TSA name matches either the subject
   or one of the subject alternative names of the TSA certificate. */
static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
	{
	STACK_OF(GENERAL_NAME) *gen_names = NULL;
	int idx = -1;
	int found = 0;

	/* Check the subject name first. */
	if (tsa_name->type == GEN_DIRNAME 
	    && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
		return 1;

	/* Check all the alternative names. */
	gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
				     NULL, &idx);
	while (gen_names != NULL
	       && !(found = TS_find_name(gen_names, tsa_name) >= 0))
		{
		/* Get the next subject alternative name,
		   although there should be no more than one. */
		GENERAL_NAMES_free(gen_names);
		gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
					     NULL, &idx);
		}
	if (gen_names) GENERAL_NAMES_free(gen_names);
	
	return found;
	}

/* Returns 1 if name is in gen_names, 0 otherwise. */
static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
	{
	int i, found;
	for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
	     ++i)
		{
		GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
		found = GENERAL_NAME_cmp(current, name) == 0;
		}
	return found ? i - 1 : -1;
	}

File Added: src/crypto/dist/openssl/crypto/ts/Attic/ts_verify_ctx.c
/* crypto/ts/ts_verify_ctx.c */
/* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
 * project 2003.
 */
/* ====================================================================
 * 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 <assert.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/ts.h>

TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
	{
	TS_VERIFY_CTX *ctx = 
		(TS_VERIFY_CTX *) OPENSSL_malloc(sizeof(TS_VERIFY_CTX));
	if (ctx)
		memset(ctx, 0, sizeof(TS_VERIFY_CTX));
	else
		TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
	return ctx;
	}

void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
	{
	assert(ctx != NULL);
	memset(ctx, 0, sizeof(TS_VERIFY_CTX));
	}

void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
	{
	if (!ctx) return;

	TS_VERIFY_CTX_cleanup(ctx);
	OPENSSL_free(ctx);
	}

void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
	{
	if (!ctx) return;

	X509_STORE_free(ctx->store);
	sk_X509_pop_free(ctx->certs, X509_free);

	ASN1_OBJECT_free(ctx->policy);

	X509_ALGOR_free(ctx->md_alg);
	OPENSSL_free(ctx->imprint);
	
	BIO_free_all(ctx->data);

	ASN1_INTEGER_free(ctx->nonce);

	GENERAL_NAME_free(ctx->tsa_name);

	TS_VERIFY_CTX_init(ctx);
	}

TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
	{
	TS_VERIFY_CTX *ret = ctx;
	ASN1_OBJECT *policy;
	TS_MSG_IMPRINT *imprint;
	X509_ALGOR *md_alg;
	ASN1_OCTET_STRING *msg;
	const ASN1_INTEGER *nonce;

	assert(req != NULL);
	if (ret)
		TS_VERIFY_CTX_cleanup(ret);
	else
		if (!(ret = TS_VERIFY_CTX_new())) return NULL;

	/* Setting flags. */
	ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);

	/* Setting policy. */
	if ((policy = TS_REQ_get_policy_id(req)) != NULL)
		{
		if (!(ret->policy = OBJ_dup(policy))) goto err;
		}
	else
		ret->flags &= ~TS_VFY_POLICY;

	/* Setting md_alg, imprint and imprint_len. */
	imprint = TS_REQ_get_msg_imprint(req);
	md_alg = TS_MSG_IMPRINT_get_algo(imprint);
	if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) goto err;
	msg = TS_MSG_IMPRINT_get_msg(imprint);
	ret->imprint_len = ASN1_STRING_length(msg);
	if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) goto err;
	memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);

	/* Setting nonce. */
	if ((nonce = TS_REQ_get_nonce(req)) != NULL)
		{
		if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) goto err;
		}
	else
		ret->flags &= ~TS_VFY_NONCE;

	return ret;
 err:
	if (ctx)
		TS_VERIFY_CTX_cleanup(ctx);
	else
		TS_VERIFY_CTX_free(ret);
	return NULL;
	}

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/Makefile
#
# crypto/whrlpool/Makefile
#

DIR=	whrlpool
TOP=	../..
CC=	cc
CPP=	$(CC) -E
INCLUDES=
CFLAG=-g
MAKEFILE=	Makefile
AR=		ar r

WP_ASM_OBJ=wp_block.o

CFLAGS= $(INCLUDES) $(CFLAG)
ASFLAGS= $(INCLUDES) $(ASFLAG)
AFLAGS= $(ASFLAGS)

GENERAL=Makefile
TEST=wp_test.c
APPS=

LIB=$(TOP)/libcrypto.a
LIBSRC=wp_dgst.c wp_block.c
LIBOBJ=wp_dgst.o $(WP_ASM_OBJ)

SRC= $(LIBSRC)

EXHEADER= whrlpool.h
HEADER= wp_locl.h $(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)

top:
	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)

all:	lib

lib:	$(LIBOBJ)
	$(AR) $(LIB) $(LIBOBJ)
	$(RANLIB) $(LIB) || echo Never mind.
	@touch lib

wp-mmx.s:	asm/wp-mmx.pl ../perlasm/x86asm.pl
	$(PERL) asm/wp-mmx.pl $(PERLASM_SCHEME) $(CFLAGS) $(PROCESSOR) > $@

wp-x86_64.s: asm/wp-x86_64.pl
	$(PERL) asm/wp-x86_64.pl $@

$(LIBOBJ): $(LIBSRC)

files:
	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

links:
	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)

install:
	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
	do  \
	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
	done;

tags:
	ctags $(SRC)

tests:

lint:
	lint -DLINT $(INCLUDES) $(SRC)>fluff

depend:
	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)

dclean:
	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
	mv -f Makefile.new $(MAKEFILE)

clean:
	rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff

# DO NOT DELETE THIS LINE -- make depend depends on it.

wp_block.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
wp_block.o: ../../include/openssl/whrlpool.h wp_block.c wp_locl.h
wp_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
wp_dgst.o: ../../include/openssl/whrlpool.h wp_dgst.c wp_locl.h

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/whrlpool.h
#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
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

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/wp_block.c
/**
 * The Whirlpool hashing function.
 *
 * <P>
 * <b>References</b>
 *
 * <P>
 * The Whirlpool algorithm was developed by
 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
 *
 * See
 *      P.S.L.M. Barreto, V. Rijmen,
 *      ``The Whirlpool hashing function,''
 *      NESSIE submission, 2000 (tweaked version, 2001),
 *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
 *
 * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
 * Vincent Rijmen. Lookup "reference implementations" on
 * <http://planeta.terra.com.br/informatica/paulobarreto/>
 *
 * =============================================================================
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "wp_locl.h"
#include <string.h>

typedef unsigned char		u8;
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32)
typedef unsigned __int64	u64;
#elif defined(__arch64__)
typedef unsigned long		u64;
#else
typedef unsigned long long	u64;
#endif

#define ROUNDS	10

#define STRICT_ALIGNMENT
#if defined(__i386) || defined(__i386__) || \
    defined(__x86_64) || defined(__x86_64__) || \
    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)
/* Well, formally there're couple of other architectures, which permit
 * unaligned loads, specifically those not crossing cache lines, IA-64
 * and PowerPC... */
#  undef STRICT_ALIGNMENT
#endif

#undef SMALL_REGISTER_BANK
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
#  define SMALL_REGISTER_BANK
#  if defined(WHIRLPOOL_ASM)
#    ifndef OPENSSL_SMALL_FOOTPRINT
#      define OPENSSL_SMALL_FOOTPRINT	/* it appears that for elder non-MMX
					   CPUs this is actually faster! */
#    endif
#    define GO_FOR_MMX(ctx,inp,num)	do {			\
	extern unsigned long OPENSSL_ia32cap_P;			\
	void whirlpool_block_mmx(void *,const void *,size_t);	\
	if (!(OPENSSL_ia32cap_P & (1<<23)))	break;		\
        whirlpool_block_mmx(ctx->H.c,inp,num);	return;		\
					} while (0)
#  endif
#endif

#undef ROTATE
#if defined(_MSC_VER)
#  if defined(_WIN64)	/* applies to both IA-64 and AMD64 */
#    pragma intrinsic(_rotl64)
#    define ROTATE(a,n)	_rotl64((a),n)
#  endif
#elif defined(__GNUC__) && __GNUC__>=2
#  if defined(__x86_64) || defined(__x86_64__)
#    if defined(L_ENDIAN)
#      define ROTATE(a,n)	({ u64 ret; asm ("rolq %1,%0"	\
				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
#    elif defined(B_ENDIAN)
       /* Most will argue that x86_64 is always little-endian. Well,
        * yes, but then we have stratus.com who has modified gcc to
	* "emulate" big-endian on x86. Is there evidence that they
	* [or somebody else] won't do same for x86_64? Naturally no.
	* And this line is waiting ready for that brave soul:-) */
#      define ROTATE(a,n)	({ u64 ret; asm ("rorq %1,%0"	\
				   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
#    endif
#  elif defined(__ia64) || defined(__ia64__)
#    if defined(L_ENDIAN)
#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
				   : "=r"(ret) : "r"(a),"M"(64-(n))); ret; })
#    elif defined(B_ENDIAN)
#      define ROTATE(a,n)	({ u64 ret; asm ("shrp %0=%1,%1,%2"	\
				   : "=r"(ret) : "r"(a),"M"(n)); ret; })
#    endif
#  endif
#endif

#if defined(OPENSSL_SMALL_FOOTPRINT)
#  if !defined(ROTATE)
#    if defined(L_ENDIAN)	/* little-endians have to rotate left */
#      define ROTATE(i,n)	((i)<<(n) ^ (i)>>(64-n))
#    elif defined(B_ENDIAN)	/* big-endians have to rotate right */
#      define ROTATE(i,n)	((i)>>(n) ^ (i)<<(64-n))
#    endif
#  endif
#  if defined(ROTATE) && !defined(STRICT_ALIGNMENT)
#    define STRICT_ALIGNMENT	/* ensure smallest table size */
#  endif
#endif

/*
 * Table size depends on STRICT_ALIGNMENT and whether or not endian-
 * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not
 * defined, which is normally the case on x86[_64] CPUs, the table is
 * 4KB large unconditionally. Otherwise if ROTATE is defined, the
 * table is 2KB large, and otherwise - 16KB. 2KB table requires a
 * whole bunch of additional rotations, but I'm willing to "trade,"
 * because 16KB table certainly trashes L1 cache. I wish all CPUs
 * could handle unaligned load as 4KB table doesn't trash the cache,
 * nor does it require additional rotations.
 */
/*
 * Note that every Cn macro expands as two loads: one byte load and
 * one quadword load. One can argue that that many single-byte loads
 * is too excessive, as one could load a quadword and "milk" it for
 * eight 8-bit values instead. Well, yes, but in order to do so *and*
 * avoid excessive loads you have to accomodate a handful of 64-bit
 * values in the register bank and issue a bunch of shifts and mask.
 * It's a tradeoff: loads vs. shift and mask in big register bank[!].
 * On most CPUs eight single-byte loads are faster and I let other
 * ones to depend on smart compiler to fold byte loads if beneficial.
 * Hand-coded assembler would be another alternative:-)
 */
#ifdef STRICT_ALIGNMENT
#  if defined(ROTATE)
#    define N	1
#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7
#    define C0(K,i)	(Cx.q[K.c[(i)*8+0]])
#    define C1(K,i)	ROTATE(Cx.q[K.c[(i)*8+1]],8)
#    define C2(K,i)	ROTATE(Cx.q[K.c[(i)*8+2]],16)
#    define C3(K,i)	ROTATE(Cx.q[K.c[(i)*8+3]],24)
#    define C4(K,i)	ROTATE(Cx.q[K.c[(i)*8+4]],32)
#    define C5(K,i)	ROTATE(Cx.q[K.c[(i)*8+5]],40)
#    define C6(K,i)	ROTATE(Cx.q[K.c[(i)*8+6]],48)
#    define C7(K,i)	ROTATE(Cx.q[K.c[(i)*8+7]],56)
#  else
#    define N	8
#    define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
					c7,c0,c1,c2,c3,c4,c5,c6, \
					c6,c7,c0,c1,c2,c3,c4,c5, \
					c5,c6,c7,c0,c1,c2,c3,c4, \
					c4,c5,c6,c7,c0,c1,c2,c3, \
					c3,c4,c5,c6,c7,c0,c1,c2, \
					c2,c3,c4,c5,c6,c7,c0,c1, \
					c1,c2,c3,c4,c5,c6,c7,c0
#    define C0(K,i)	(Cx.q[0+8*K.c[(i)*8+0]])
#    define C1(K,i)	(Cx.q[1+8*K.c[(i)*8+1]])
#    define C2(K,i)	(Cx.q[2+8*K.c[(i)*8+2]])
#    define C3(K,i)	(Cx.q[3+8*K.c[(i)*8+3]])
#    define C4(K,i)	(Cx.q[4+8*K.c[(i)*8+4]])
#    define C5(K,i)	(Cx.q[5+8*K.c[(i)*8+5]])
#    define C6(K,i)	(Cx.q[6+8*K.c[(i)*8+6]])
#    define C7(K,i)	(Cx.q[7+8*K.c[(i)*8+7]])
#  endif
#else
#  define N	2
#  define LL(c0,c1,c2,c3,c4,c5,c6,c7)	c0,c1,c2,c3,c4,c5,c6,c7, \
					c0,c1,c2,c3,c4,c5,c6,c7
#  define C0(K,i)	(((u64*)(Cx.c+0))[2*K.c[(i)*8+0]])
#  define C1(K,i)	(((u64*)(Cx.c+7))[2*K.c[(i)*8+1]])
#  define C2(K,i)	(((u64*)(Cx.c+6))[2*K.c[(i)*8+2]])
#  define C3(K,i)	(((u64*)(Cx.c+5))[2*K.c[(i)*8+3]])
#  define C4(K,i)	(((u64*)(Cx.c+4))[2*K.c[(i)*8+4]])
#  define C5(K,i)	(((u64*)(Cx.c+3))[2*K.c[(i)*8+5]])
#  define C6(K,i)	(((u64*)(Cx.c+2))[2*K.c[(i)*8+6]])
#  define C7(K,i)	(((u64*)(Cx.c+1))[2*K.c[(i)*8+7]])
#endif

static const
union	{
	u8	c[(256*N+ROUNDS)*sizeof(u64)];
	u64	q[(256*N+ROUNDS)];
	} Cx = { {
	/* Note endian-neutral representation:-) */
	LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8),
	LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26),
	LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8),
	LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb),
	LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb),
	LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11),
	LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09),
	LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d),
	LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b),
	LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff),
	LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c),
	LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e),
	LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96),
	LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30),
	LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d),
	LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8),
	LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47),
	LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35),
	LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37),
	LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a),
	LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2),
	LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c),
	LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84),
	LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80),
	LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5),
	LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3),
	LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21),
	LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c),
	LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43),
	LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29),
	LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d),
	LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5),
	LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd),
	LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8),
	LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92),
	LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e),
	LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13),
	LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23),
	LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20),
	LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44),
	LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2),
	LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf),
	LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c),
	LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a),
	LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50),
	LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9),
	LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14),
	LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9),
	LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c),
	LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f),
	LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90),
	LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07),
	LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd),
	LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3),
	LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d),
	LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78),
	LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97),
	LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02),
	LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73),
	LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7),
	LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6),
	LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2),
	LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49),
	LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56),
	LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70),
	LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd),
	LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb),
	LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71),
	LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b),
	LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf),
	LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45),
	LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a),
	LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4),
	LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58),
	LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e),
	LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f),
	LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac),
	LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0),
	LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef),
	LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6),
	LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c),
	LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12),
	LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93),
	LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde),
	LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6),
	LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1),
	LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b),
	LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f),
	LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31),
	LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8),
	LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9),
	LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc),
	LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e),
	LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b),
	LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf),
	LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59),
	LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2),
	LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77),
	LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33),
	LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4),
	LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27),
	LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb),
	LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89),
	LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32),
	LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54),
	LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d),
	LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64),
	LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d),
	LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d),
	LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f),
	LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca),
	LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7),
	LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d),
	LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce),
	LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f),
	LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f),
	LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63),
	LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a),
	LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc),
	LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82),
	LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a),
	LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48),
	LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95),
	LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf),
	LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d),
	LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0),
	LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91),
	LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8),
	LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b),
	LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
	LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9),
	LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e),
	LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1),
	LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6),
	LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28),
	LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3),
	LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74),
	LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe),
	LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d),
	LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea),
	LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57),
	LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38),
	LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad),
	LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4),
	LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda),
	LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7),
	LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb),
	LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9),
	LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a),
	LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03),
	LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a),
	LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e),
	LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60),
	LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc),
	LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46),
	LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f),
	LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76),
	LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa),
	LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36),
	LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae),
	LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b),
	LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85),
	LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e),
	LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7),
	LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55),
	LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a),
	LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81),
	LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52),
	LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62),
	LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3),
	LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10),
	LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab),
	LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0),
	LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5),
	LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec),
	LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16),
	LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94),
	LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f),
	LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5),
	LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98),
	LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17),
	LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4),
	LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1),
	LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e),
	LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42),
	LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34),
	LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08),
	LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee),
	LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61),
	LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1),
	LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f),
	LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24),
	LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3),
	LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25),
	LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22),
	LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65),
	LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79),
	LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69),
	LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9),
	LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19),
	LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe),
	LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a),
	LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0),
	LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99),
	LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83),
	LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04),
	LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66),
	LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0),
	LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1),
	LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd),
	LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40),
	LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c),
	LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18),
	LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b),
	LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51),
	LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05),
	LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c),
	LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39),
	LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa),
	LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b),
	LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc),
	LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e),
	LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0),
	LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88),
	LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67),
	LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a),
	LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87),
	LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1),
	LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72),
	LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53),
	LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01),
	LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b),
	LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4),
	LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3),
	LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15),
	LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c),
	LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5),
	LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5),
	LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4),
	LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba),
	LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6),
	LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7),
	LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06),
	LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41),
	LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7),
	LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f),
	LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e),
	LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6),
	LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2),
	LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68),
	LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c),
	LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed),
	LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75),
	LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86),
	LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b),
	LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2),
#define RC	(&(Cx.q[256*N]))
	0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f,	/* rc[ROUNDS] */
	0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52,
	0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35,
	0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57,
	0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda,
	0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85,
	0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67,
	0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8,
	0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e,
	0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33
	}
};

void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n)
	{
	int	r;
	const u8 *p=inp;
	union	{ u64 q[8]; u8 c[64]; } S,K,*H=(void *)ctx->H.q;

#ifdef GO_FOR_MMX
	GO_FOR_MMX(ctx,inp,n);
#endif
							do {
#ifdef OPENSSL_SMALL_FOOTPRINT
	u64	L[8];
	int	i;

	for (i=0;i<64;i++)	S.c[i] = (K.c[i] = H->c[i]) ^ p[i];
	for (r=0;r<ROUNDS;r++)
		{
		for (i=0;i<8;i++)
			{
			L[i]  = i ? 0 : RC[r];
			L[i] ^=	C0(K,i)       ^ C1(K,(i-1)&7) ^
				C2(K,(i-2)&7) ^ C3(K,(i-3)&7) ^
				C4(K,(i-4)&7) ^ C5(K,(i-5)&7) ^
				C6(K,(i-6)&7) ^ C7(K,(i-7)&7);
			}
		memcpy (K.q,L,64);
		for (i=0;i<8;i++)
			{
			L[i] ^= C0(S,i)       ^ C1(S,(i-1)&7) ^
				C2(S,(i-2)&7) ^ C3(S,(i-3)&7) ^
				C4(S,(i-4)&7) ^ C5(S,(i-5)&7) ^
				C6(S,(i-6)&7) ^ C7(S,(i-7)&7);
			}
		memcpy (S.q,L,64);
		}
	for (i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
#else
	u64	L0,L1,L2,L3,L4,L5,L6,L7;

#ifdef STRICT_ALIGNMENT
	if ((size_t)p & 7)
		{
		memcpy (S.c,p,64);
		S.q[0] ^= (K.q[0] = H->q[0]);
		S.q[1] ^= (K.q[1] = H->q[1]);
		S.q[2] ^= (K.q[2] = H->q[2]);
		S.q[3] ^= (K.q[3] = H->q[3]);
		S.q[4] ^= (K.q[4] = H->q[4]);
		S.q[5] ^= (K.q[5] = H->q[5]);
		S.q[6] ^= (K.q[6] = H->q[6]);
		S.q[7] ^= (K.q[7] = H->q[7]);
		}
	else
#endif
		{
		const u64 *pa = (const u64*)p;
		S.q[0] = (K.q[0] = H->q[0]) ^ pa[0];
		S.q[1] = (K.q[1] = H->q[1]) ^ pa[1];
		S.q[2] = (K.q[2] = H->q[2]) ^ pa[2];
		S.q[3] = (K.q[3] = H->q[3]) ^ pa[3];
		S.q[4] = (K.q[4] = H->q[4]) ^ pa[4];
		S.q[5] = (K.q[5] = H->q[5]) ^ pa[5];
		S.q[6] = (K.q[6] = H->q[6]) ^ pa[6];
		S.q[7] = (K.q[7] = H->q[7]) ^ pa[7];
		}

	for(r=0;r<ROUNDS;r++)
		{
#ifdef SMALL_REGISTER_BANK
		L0 =	C0(K,0) ^ C1(K,7) ^ C2(K,6) ^ C3(K,5) ^
			C4(K,4) ^ C5(K,3) ^ C6(K,2) ^ C7(K,1) ^ RC[r];
		L1 =	C0(K,1) ^ C1(K,0) ^ C2(K,7) ^ C3(K,6) ^
			C4(K,5) ^ C5(K,4) ^ C6(K,3) ^ C7(K,2);
		L2 =	C0(K,2) ^ C1(K,1) ^ C2(K,0) ^ C3(K,7) ^
			C4(K,6) ^ C5(K,5) ^ C6(K,4) ^ C7(K,3);
		L3 =	C0(K,3) ^ C1(K,2) ^ C2(K,1) ^ C3(K,0) ^
			C4(K,7) ^ C5(K,6) ^ C6(K,5) ^ C7(K,4);
		L4 =	C0(K,4) ^ C1(K,3) ^ C2(K,2) ^ C3(K,1) ^
			C4(K,0) ^ C5(K,7) ^ C6(K,6) ^ C7(K,5);
		L5 =	C0(K,5) ^ C1(K,4) ^ C2(K,3) ^ C3(K,2) ^
			C4(K,1) ^ C5(K,0) ^ C6(K,7) ^ C7(K,6);
		L6 =	C0(K,6) ^ C1(K,5) ^ C2(K,4) ^ C3(K,3) ^
			C4(K,2) ^ C5(K,1) ^ C6(K,0) ^ C7(K,7);
		L7 =	C0(K,7) ^ C1(K,6) ^ C2(K,5) ^ C3(K,4) ^
			C4(K,3) ^ C5(K,2) ^ C6(K,1) ^ C7(K,0);

		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;

		L0 ^=	C0(S,0) ^ C1(S,7) ^ C2(S,6) ^ C3(S,5) ^
			C4(S,4) ^ C5(S,3) ^ C6(S,2) ^ C7(S,1);
		L1 ^=	C0(S,1) ^ C1(S,0) ^ C2(S,7) ^ C3(S,6) ^
			C4(S,5) ^ C5(S,4) ^ C6(S,3) ^ C7(S,2);
		L2 ^=	C0(S,2) ^ C1(S,1) ^ C2(S,0) ^ C3(S,7) ^
			C4(S,6) ^ C5(S,5) ^ C6(S,4) ^ C7(S,3);
		L3 ^=	C0(S,3) ^ C1(S,2) ^ C2(S,1) ^ C3(S,0) ^
			C4(S,7) ^ C5(S,6) ^ C6(S,5) ^ C7(S,4);
		L4 ^=	C0(S,4) ^ C1(S,3) ^ C2(S,2) ^ C3(S,1) ^
			C4(S,0) ^ C5(S,7) ^ C6(S,6) ^ C7(S,5);
		L5 ^=	C0(S,5) ^ C1(S,4) ^ C2(S,3) ^ C3(S,2) ^
			C4(S,1) ^ C5(S,0) ^ C6(S,7) ^ C7(S,6);
		L6 ^=	C0(S,6) ^ C1(S,5) ^ C2(S,4) ^ C3(S,3) ^
			C4(S,2) ^ C5(S,1) ^ C6(S,0) ^ C7(S,7);
		L7 ^=	C0(S,7) ^ C1(S,6) ^ C2(S,5) ^ C3(S,4) ^
			C4(S,3) ^ C5(S,2) ^ C6(S,1) ^ C7(S,0);

		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
#else
		L0  = C0(K,0); L1  = C1(K,0); L2  = C2(K,0); L3  = C3(K,0);
		L4  = C4(K,0); L5  = C5(K,0); L6  = C6(K,0); L7  = C7(K,0);
		L0 ^= RC[r];

		L1 ^= C0(K,1); L2 ^= C1(K,1); L3 ^= C2(K,1); L4 ^= C3(K,1);
		L5 ^= C4(K,1); L6 ^= C5(K,1); L7 ^= C6(K,1); L0 ^= C7(K,1);

		L2 ^= C0(K,2); L3 ^= C1(K,2); L4 ^= C2(K,2); L5 ^= C3(K,2);
		L6 ^= C4(K,2); L7 ^= C5(K,2); L0 ^= C6(K,2); L1 ^= C7(K,2);

		L3 ^= C0(K,3); L4 ^= C1(K,3); L5 ^= C2(K,3); L6 ^= C3(K,3);
		L7 ^= C4(K,3); L0 ^= C5(K,3); L1 ^= C6(K,3); L2 ^= C7(K,3);

		L4 ^= C0(K,4); L5 ^= C1(K,4); L6 ^= C2(K,4); L7 ^= C3(K,4);
		L0 ^= C4(K,4); L1 ^= C5(K,4); L2 ^= C6(K,4); L3 ^= C7(K,4);

		L5 ^= C0(K,5); L6 ^= C1(K,5); L7 ^= C2(K,5); L0 ^= C3(K,5);
		L1 ^= C4(K,5); L2 ^= C5(K,5); L3 ^= C6(K,5); L4 ^= C7(K,5);

		L6 ^= C0(K,6); L7 ^= C1(K,6); L0 ^= C2(K,6); L1 ^= C3(K,6);
		L2 ^= C4(K,6); L3 ^= C5(K,6); L4 ^= C6(K,6); L5 ^= C7(K,6);

		L7 ^= C0(K,7); L0 ^= C1(K,7); L1 ^= C2(K,7); L2 ^= C3(K,7);
		L3 ^= C4(K,7); L4 ^= C5(K,7); L5 ^= C6(K,7); L6 ^= C7(K,7);

		K.q[0] = L0; K.q[1] = L1; K.q[2] = L2; K.q[3] = L3;
		K.q[4] = L4; K.q[5] = L5; K.q[6] = L6; K.q[7] = L7;

		L0 ^= C0(S,0); L1 ^= C1(S,0); L2 ^= C2(S,0); L3 ^= C3(S,0);
		L4 ^= C4(S,0); L5 ^= C5(S,0); L6 ^= C6(S,0); L7 ^= C7(S,0);

		L1 ^= C0(S,1); L2 ^= C1(S,1); L3 ^= C2(S,1); L4 ^= C3(S,1);
		L5 ^= C4(S,1); L6 ^= C5(S,1); L7 ^= C6(S,1); L0 ^= C7(S,1);

		L2 ^= C0(S,2); L3 ^= C1(S,2); L4 ^= C2(S,2); L5 ^= C3(S,2);
		L6 ^= C4(S,2); L7 ^= C5(S,2); L0 ^= C6(S,2); L1 ^= C7(S,2);

		L3 ^= C0(S,3); L4 ^= C1(S,3); L5 ^= C2(S,3); L6 ^= C3(S,3);
		L7 ^= C4(S,3); L0 ^= C5(S,3); L1 ^= C6(S,3); L2 ^= C7(S,3);

		L4 ^= C0(S,4); L5 ^= C1(S,4); L6 ^= C2(S,4); L7 ^= C3(S,4);
		L0 ^= C4(S,4); L1 ^= C5(S,4); L2 ^= C6(S,4); L3 ^= C7(S,4);

		L5 ^= C0(S,5); L6 ^= C1(S,5); L7 ^= C2(S,5); L0 ^= C3(S,5);
		L1 ^= C4(S,5); L2 ^= C5(S,5); L3 ^= C6(S,5); L4 ^= C7(S,5);

		L6 ^= C0(S,6); L7 ^= C1(S,6); L0 ^= C2(S,6); L1 ^= C3(S,6);
		L2 ^= C4(S,6); L3 ^= C5(S,6); L4 ^= C6(S,6); L5 ^= C7(S,6);

		L7 ^= C0(S,7); L0 ^= C1(S,7); L1 ^= C2(S,7); L2 ^= C3(S,7);
		L3 ^= C4(S,7); L4 ^= C5(S,7); L5 ^= C6(S,7); L6 ^= C7(S,7);

		S.q[0] = L0; S.q[1] = L1; S.q[2] = L2; S.q[3] = L3;
		S.q[4] = L4; S.q[5] = L5; S.q[6] = L6; S.q[7] = L7;
#endif
		}

#ifdef STRICT_ALIGNMENT
	if ((size_t)p & 7)
		{
		int i;
		for(i=0;i<64;i++)	H->c[i] ^= S.c[i] ^ p[i];
		}
	else
#endif
		{
		const u64 *pa=(const u64 *)p;
		H->q[0] ^= S.q[0] ^ pa[0];
		H->q[1] ^= S.q[1] ^ pa[1];
		H->q[2] ^= S.q[2] ^ pa[2];
		H->q[3] ^= S.q[3] ^ pa[3];
		H->q[4] ^= S.q[4] ^ pa[4];
		H->q[5] ^= S.q[5] ^ pa[5];
		H->q[6] ^= S.q[6] ^ pa[6];
		H->q[7] ^= S.q[7] ^ pa[7];
		}
#endif
							p += 64;
							} while(--n);
	}

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/wp_dgst.c
/**
 * The Whirlpool hashing function.
 *
 * <P>
 * <b>References</b>
 *
 * <P>
 * The Whirlpool algorithm was developed by
 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
 *
 * See
 *      P.S.L.M. Barreto, V. Rijmen,
 *      ``The Whirlpool hashing function,''
 *      NESSIE submission, 2000 (tweaked version, 2001),
 *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
 *
 * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
 * Vincent Rijmen. Lookup "reference implementations" on
 * <http://planeta.terra.com.br/informatica/paulobarreto/>
 *
 * =============================================================================
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * OpenSSL-specific implementation notes.
 *
 * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
 * number of *bytes* as input length argument. Bit-oriented routine
 * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
 * does not have one-stroke counterpart.
 *
 * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
 * to serve WHIRLPOOL_Update. This is done for performance.
 *
 * Unlike authors' reference implementation, block processing
 * routine whirlpool_block is designed to operate on multi-block
 * input. This is done for perfomance.
 */

#include "wp_locl.h"
#include <string.h>

int WHIRLPOOL_Init	(WHIRLPOOL_CTX *c)
	{
	memset (c,0,sizeof(*c));
	return(1);
	}

int WHIRLPOOL_Update	(WHIRLPOOL_CTX *c,const void *_inp,size_t bytes)
	{
	/* Well, largest suitable chunk size actually is
	 * (1<<(sizeof(size_t)*8-3))-64, but below number
	 * is large enough for not to care about excessive
	 * calls to WHIRLPOOL_BitUpdate... */
	size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4);
	const unsigned char *inp = _inp;

	while (bytes>=chunk)
		{
		WHIRLPOOL_BitUpdate(c,inp,chunk*8);
		bytes -= chunk;
		inp   += chunk;
		}
	if (bytes)
		WHIRLPOOL_BitUpdate(c,inp,bytes*8);

	return(1);
	}

void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits)
	{
	size_t		n;
	unsigned int	bitoff = c->bitoff,
			bitrem = bitoff%8,
			inpgap = (8-(unsigned int)bits%8)&7;
	const unsigned char *inp=_inp;

	/* This 256-bit increment procedure relies on the size_t
	 * being natural size of CPU register, so that we don't
	 * have to mask the value in order to detect overflows. */
	c->bitlen[0] += bits;
	if (c->bitlen[0] < bits)	/* overflow */
		{
		n = 1;
		do  { 	c->bitlen[n]++;
		    } while(c->bitlen[n]==0
		   	    && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t)));
		}

#ifndef OPENSSL_SMALL_FOOTPRINT
	reconsider:
	if (inpgap==0 && bitrem==0)	/* byte-oriented loop */
		{
		while (bits)
			{
			if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK))
				{
				whirlpool_block(c,inp,n);
				inp  += n*WHIRLPOOL_BBLOCK/8;
				bits %= WHIRLPOOL_BBLOCK;
				}
			else
				{
				unsigned int byteoff = bitoff/8;

				bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */
				if (bits >= bitrem)
					{
					bits -= bitrem;
					bitrem /= 8;
					memcpy(c->data+byteoff,inp,bitrem);
					inp  += bitrem;
					whirlpool_block(c,c->data,1);
					bitoff = 0;
					}
				else
					{
					memcpy(c->data+byteoff,inp,bits/8);
					bitoff += bits;
					bits = 0;
					}
				c->bitoff = bitoff;
				}
			}
		}
	else				/* bit-oriented loop */
#endif
		{
		/*
			   inp
			   |
			   +-------+-------+-------
			      |||||||||||||||||||||
			   +-------+-------+-------
		+-------+-------+-------+-------+-------
		||||||||||||||				c->data
		+-------+-------+-------+-------+-------
			|
			c->bitoff/8
		*/
		while (bits)
			{
			unsigned int	byteoff	= bitoff/8;
			unsigned char	b;

#ifndef OPENSSL_SMALL_FOOTPRINT
			if (bitrem==inpgap)
				{
				c->data[byteoff++] |= inp[0] & (0xff>>inpgap);
				inpgap = 8-inpgap;
				bitoff += inpgap;  bitrem = 0;	/* bitoff%8 */
				bits   -= inpgap;  inpgap = 0;	/* bits%8   */
				inp++;
				if (bitoff==WHIRLPOOL_BBLOCK)
					{
					whirlpool_block(c,c->data,1);
					bitoff = 0;
					}
				c->bitoff = bitoff;
				goto reconsider;
				}
			else
#endif
			if (bits>=8)
				{
				b  = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap)));
				b &= 0xff;
				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
				else		c->data[byteoff++]  = b;
				bitoff += 8;
				bits   -= 8;
				inp++;
				if (bitoff>=WHIRLPOOL_BBLOCK)
					{
					whirlpool_block(c,c->data,1);
					byteoff  = 0;
					bitoff  %= WHIRLPOOL_BBLOCK;
					}
				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
				}
			else	/* remaining less than 8 bits */
				{
				b = (inp[0]<<inpgap)&0xff;
				if (bitrem)	c->data[byteoff++] |= b>>bitrem;
				else		c->data[byteoff++]  = b;
				bitoff += bits;
				if (bitoff==WHIRLPOOL_BBLOCK)
					{
					whirlpool_block(c,c->data,1);
					byteoff  = 0;
			        	bitoff  %= WHIRLPOOL_BBLOCK;
					}
				if (bitrem)	c->data[byteoff] = b<<(8-bitrem);
				bits = 0;
				}
			c->bitoff = bitoff;
			}
		}
	}

int WHIRLPOOL_Final	(unsigned char *md,WHIRLPOOL_CTX *c)
	{
	unsigned int	bitoff  = c->bitoff,
			byteoff = bitoff/8;
	size_t		i,j,v;
	unsigned char  *p;

	bitoff %= 8;
	if (bitoff)	c->data[byteoff] |= 0x80>>bitoff;
	else		c->data[byteoff]  = 0x80;
	byteoff++;

	/* pad with zeros */
	if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
		{
		if (byteoff<WHIRLPOOL_BBLOCK/8)
			memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff);
		whirlpool_block(c,c->data,1);
		byteoff = 0;
		}
	if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
		memset(&c->data[byteoff],0,
			(WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff);
	/* smash 256-bit c->bitlen in big-endian order */
	p = &c->data[WHIRLPOOL_BBLOCK/8-1];	/* last byte in c->data */
	for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++)
		for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8)
			*p-- = (unsigned char)(v&0xff);

	whirlpool_block(c,c->data,1);

	if (md)	{
		memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH);
		memset(c,0,sizeof(*c));
		return(1);
		}
	return(0);
	}

unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md)
	{
	WHIRLPOOL_CTX ctx;
	static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];

	if (md == NULL) md=m;
	WHIRLPOOL_Init(&ctx);
	WHIRLPOOL_Update(&ctx,inp,bytes);
	WHIRLPOOL_Final(md,&ctx);
	return(md);
	}

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/wp_locl.h
#include <openssl/whrlpool.h>

void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t);

File Added: src/crypto/dist/openssl/crypto/whrlpool/Attic/wp_test.c
/* ====================================================================
 * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
 * ====================================================================
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <openssl/whrlpool.h>
#include <openssl/crypto.h>

#if defined(OPENSSL_NO_WHIRLPOOL)
int main(int argc, char *argv[])
{
    printf("No Whirlpool support\n");
    return(0);
}
#else

/* ISO/IEC 10118-3 test vector set */
unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = {
	0x19,0xFA,0x61,0xD7,0x55,0x22,0xA4,0x66,
	0x9B,0x44,0xE3,0x9C,0x1D,0x2E,0x17,0x26,
	0xC5,0x30,0x23,0x21,0x30,0xD4,0x07,0xF8,
	0x9A,0xFE,0xE0,0x96,0x49,0x97,0xF7,0xA7,
	0x3E,0x83,0xBE,0x69,0x8B,0x28,0x8F,0xEB,
	0xCF,0x88,0xE3,0xE0,0x3C,0x4F,0x07,0x57,
	0xEA,0x89,0x64,0xE5,0x9B,0x63,0xD9,0x37,
	0x08,0xB1,0x38,0xCC,0x42,0xA6,0x6E,0xB3 };

unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = {
	0x8A,0xCA,0x26,0x02,0x79,0x2A,0xEC,0x6F,
	0x11,0xA6,0x72,0x06,0x53,0x1F,0xB7,0xD7,
	0xF0,0xDF,0xF5,0x94,0x13,0x14,0x5E,0x69,
	0x73,0xC4,0x50,0x01,0xD0,0x08,0x7B,0x42,
	0xD1,0x1B,0xC6,0x45,0x41,0x3A,0xEF,0xF6,
	0x3A,0x42,0x39,0x1A,0x39,0x14,0x5A,0x59,
	0x1A,0x92,0x20,0x0D,0x56,0x01,0x95,0xE5,
	0x3B,0x47,0x85,0x84,0xFD,0xAE,0x23,0x1A };

unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = {
	0x4E,0x24,0x48,0xA4,0xC6,0xF4,0x86,0xBB,
	0x16,0xB6,0x56,0x2C,0x73,0xB4,0x02,0x0B,
	0xF3,0x04,0x3E,0x3A,0x73,0x1B,0xCE,0x72,
	0x1A,0xE1,0xB3,0x03,0xD9,0x7E,0x6D,0x4C,
	0x71,0x81,0xEE,0xBD,0xB6,0xC5,0x7E,0x27,
	0x7D,0x0E,0x34,0x95,0x71,0x14,0xCB,0xD6,
	0xC7,0x97,0xFC,0x9D,0x95,0xD8,0xB5,0x82,
	0xD2,0x25,0x29,0x20,0x76,0xD4,0xEE,0xF5 };

unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = {
	0x37,0x8C,0x84,0xA4,0x12,0x6E,0x2D,0xC6,
	0xE5,0x6D,0xCC,0x74,0x58,0x37,0x7A,0xAC,
	0x83,0x8D,0x00,0x03,0x22,0x30,0xF5,0x3C,
	0xE1,0xF5,0x70,0x0C,0x0F,0xFB,0x4D,0x3B,
	0x84,0x21,0x55,0x76,0x59,0xEF,0x55,0xC1,
	0x06,0xB4,0xB5,0x2A,0xC5,0xA4,0xAA,0xA6,
	0x92,0xED,0x92,0x00,0x52,0x83,0x8F,0x33,
	0x62,0xE8,0x6D,0xBD,0x37,0xA8,0x90,0x3E };

unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = {
	0xF1,0xD7,0x54,0x66,0x26,0x36,0xFF,0xE9,
	0x2C,0x82,0xEB,0xB9,0x21,0x2A,0x48,0x4A,
	0x8D,0x38,0x63,0x1E,0xAD,0x42,0x38,0xF5,
	0x44,0x2E,0xE1,0x3B,0x80,0x54,0xE4,0x1B,
	0x08,0xBF,0x2A,0x92,0x51,0xC3,0x0B,0x6A,
	0x0B,0x8A,0xAE,0x86,0x17,0x7A,0xB4,0xA6,
	0xF6,0x8F,0x67,0x3E,0x72,0x07,0x86,0x5D,
	0x5D,0x98,0x19,0xA3,0xDB,0xA4,0xEB,0x3B };

unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = {
	0xDC,0x37,0xE0,0x08,0xCF,0x9E,0xE6,0x9B,
	0xF1,0x1F,0x00,0xED,0x9A,0xBA,0x26,0x90,
	0x1D,0xD7,0xC2,0x8C,0xDE,0xC0,0x66,0xCC,
	0x6A,0xF4,0x2E,0x40,0xF8,0x2F,0x3A,0x1E,
	0x08,0xEB,0xA2,0x66,0x29,0x12,0x9D,0x8F,
	0xB7,0xCB,0x57,0x21,0x1B,0x92,0x81,0xA6,
	0x55,0x17,0xCC,0x87,0x9D,0x7B,0x96,0x21,
	0x42,0xC6,0x5F,0x5A,0x7A,0xF0,0x14,0x67 };

unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = {
	0x46,0x6E,0xF1,0x8B,0xAB,0xB0,0x15,0x4D,
	0x25,0xB9,0xD3,0x8A,0x64,0x14,0xF5,0xC0,
	0x87,0x84,0x37,0x2B,0xCC,0xB2,0x04,0xD6,
	0x54,0x9C,0x4A,0xFA,0xDB,0x60,0x14,0x29,
	0x4D,0x5B,0xD8,0xDF,0x2A,0x6C,0x44,0xE5,
	0x38,0xCD,0x04,0x7B,0x26,0x81,0xA5,0x1A,
	0x2C,0x60,0x48,0x1E,0x88,0xC5,0xA2,0x0B,
	0x2C,0x2A,0x80,0xCF,0x3A,0x9A,0x08,0x3B };

unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = {
	0x2A,0x98,0x7E,0xA4,0x0F,0x91,0x70,0x61,
	0xF5,0xD6,0xF0,0xA0,0xE4,0x64,0x4F,0x48,
	0x8A,0x7A,0x5A,0x52,0xDE,0xEE,0x65,0x62,
	0x07,0xC5,0x62,0xF9,0x88,0xE9,0x5C,0x69,
	0x16,0xBD,0xC8,0x03,0x1B,0xC5,0xBE,0x1B,
	0x7B,0x94,0x76,0x39,0xFE,0x05,0x0B,0x56,
	0x93,0x9B,0xAA,0xA0,0xAD,0xFF,0x9A,0xE6,
	0x74,0x5B,0x7B,0x18,0x1C,0x3B,0xE3,0xFD };

unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = {
	0x0C,0x99,0x00,0x5B,0xEB,0x57,0xEF,0xF5,
	0x0A,0x7C,0xF0,0x05,0x56,0x0D,0xDF,0x5D,
	0x29,0x05,0x7F,0xD8,0x6B,0x20,0xBF,0xD6,
	0x2D,0xEC,0xA0,0xF1,0xCC,0xEA,0x4A,0xF5,
	0x1F,0xC1,0x54,0x90,0xED,0xDC,0x47,0xAF,
	0x32,0xBB,0x2B,0x66,0xC3,0x4F,0xF9,0xAD,
	0x8C,0x60,0x08,0xAD,0x67,0x7F,0x77,0x12,
	0x69,0x53,0xB2,0x26,0xE4,0xED,0x8B,0x01 };

int main (int argc,char *argv[])
{ unsigned char md[WHIRLPOOL_DIGEST_LENGTH];
  int		i;
  WHIRLPOOL_CTX	ctx;

#ifdef OPENSSL_IA32_SSE2
    /* Alternative to this is to call OpenSSL_add_all_algorithms...
     * The below code is retained exclusively for debugging purposes. */
    { char      *env;

	if ((env=getenv("OPENSSL_ia32cap")))
	    OPENSSL_ia32cap = strtoul (env,NULL,0);
    }
#endif

    fprintf(stdout,"Testing Whirlpool ");

    WHIRLPOOL("",0,md);
    if (memcmp(md,iso_test_1,sizeof(iso_test_1)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 1 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL("a",1,md);
    if (memcmp(md,iso_test_2,sizeof(iso_test_2)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 2 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL("abc",3,md);
    if (memcmp(md,iso_test_3,sizeof(iso_test_3)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 3 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL("message digest",14,md);
    if (memcmp(md,iso_test_4,sizeof(iso_test_4)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 4 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL("abcdefghijklmnopqrstuvwxyz",26,md);
    if (memcmp(md,iso_test_5,sizeof(iso_test_5)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 5 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL(	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz"
		"0123456789",62,md);
    if (memcmp(md,iso_test_6,sizeof(iso_test_6)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 6 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL(	"1234567890""1234567890""1234567890""1234567890"
		"1234567890""1234567890""1234567890""1234567890",80,md);
    if (memcmp(md,iso_test_7,sizeof(iso_test_7)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 7 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk",32,md);
    if (memcmp(md,iso_test_8,sizeof(iso_test_8)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 8 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);
 
    WHIRLPOOL_Init (&ctx);
    for (i=0;i<1000000;i+=288)
	WHIRLPOOL_Update (&ctx,	"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa"
				"aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa",
				(1000000-i)<288?1000000-i:288);
    WHIRLPOOL_Final (md,&ctx);
    if (memcmp(md,iso_test_9,sizeof(iso_test_9)))
    {   fflush(stdout);
	fprintf(stderr,"\nTEST 9 of 9 failed.\n");
	return 1;
    }
    else
	fprintf(stdout,"."); fflush(stdout);

    fprintf(stdout," passed.\n"); fflush(stdout);

  return 0;
}
#endif

File Added: src/crypto/dist/openssl/crypto/whrlpool/asm/Attic/wp-mmx.pl
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
# project. Rights for redistribution and usage in source and binary
# forms are granted according to the OpenSSL license.
# ====================================================================
#
# whirlpool_block_mmx implementation.
#
*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results
# in 16KB large table, which is tough on L1 cache, but eliminates
# unaligned references to it. Value of 2 results in 4KB table, but
# 7/8 of references to it are unaligned. AMD cores seem to be
# allergic to the latter, while Intel ones - to former [see the
# table]. I stick to value of 2 for two reasons: 1. smaller table
# minimizes cache trashing and thus mitigates the hazard of side-
# channel leakage similar to AES cache-timing one; 2. performance
# gap among different µ-archs is smaller.
#
# Performance table lists rounded amounts of CPU cycles spent by
# whirlpool_block_mmx routine on single 64 byte input block, i.e.
# smaller is better and asymptotic throughput can be estimated by
# multiplying 64 by CPU clock frequency and dividing by relevant
# value from the given table:
#
#		$SCALE=2/8	icc8	gcc3	
# Intel P4	3200/4600	4600(*)	6400
# Intel PIII	2900/3000	4900	5400
# AMD K[78]	2500/1800	9900	8200(**)
#
# (*)	I've sketched even non-MMX assembler, but for the record
#	I've failed to beat the Intel compiler on P4, without using
#	MMX that is...
# (**)	... on AMD on the other hand non-MMX assembler was observed
#	to perform significantly better, but I figured this MMX
#	implementation is even faster anyway, so why bother? As for
#	pre-MMX AMD core[s], the improvement coefficient is more
#	than likely to vary anyway and I don't know how. But the
#	least I know is that gcc-generated code compiled with
#	-DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for
#	details] and optimized for Pentium was observed to perform
#	*better* on Pentium 100 than unrolled non-MMX assembler
#	loop... So we just say that I don't know if maintaining
#	non-MMX implementation would actually pay off, but till
#	opposite is proved "unlikely" is assumed.

$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
push(@INC,"${dir}","${dir}../../perlasm");
require "x86asm.pl";

&asm_init($ARGV[0],"wp-mmx.pl");

sub L()  { &data_byte(@_); }
sub LL()
{	if	($SCALE==2)	{ &data_byte(@_); &data_byte(@_); }
	elsif	($SCALE==8)	{ for ($i=0;$i<8;$i++) {
					&data_byte(@_);
					unshift(@_,pop(@_));
				  }
				}
	else			{ die "unvalid SCALE value"; }
}

sub scale()
{	if	($SCALE==2)	{ &lea(@_[0],&DWP(0,@_[1],@_[1])); }
	elsif	($SCALE==8)	{ &lea(@_[0],&DWP(0,"",@_[1],8));  }
	else			{ die "unvalid SCALE value";       }
}

sub row()
{	if	($SCALE==2)	{ ((8-shift)&7); }
	elsif	($SCALE==8)	{ (8*shift);     }
	else			{ die "unvalid SCALE value"; }
}

$tbl="ebp";
@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7");

&function_begin_B("whirlpool_block_mmx");
	&push	("ebp");
	&push	("ebx");
	&push	("esi");
	&push	("edi");

	&mov	("esi",&wparam(0));		# hash value
	&mov	("edi",&wparam(1));		# input data stream
	&mov	("ebp",&wparam(2));		# number of chunks in input

	&mov	("eax","esp");			# copy stack pointer
	&sub	("esp",128+20);			# allocate frame
	&and	("esp",-64);			# align for cache-line

	&lea	("ebx",&DWP(128,"esp"));
	&mov	(&DWP(0,"ebx"),"esi");		# save parameter block
	&mov	(&DWP(4,"ebx"),"edi");
	&mov	(&DWP(8,"ebx"),"ebp");
	&mov	(&DWP(16,"ebx"),"eax");		# saved stack pointer

	&call	(&label("pic_point"));
&set_label("pic_point");
	&blindpop($tbl);
	&lea	($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl));

	&xor	("ecx","ecx");
	&xor	("edx","edx");

	for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); }    # L=H
&set_label("outerloop");
	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L

	&xor	("esi","esi");
	&mov	(&DWP(12,"ebx"),"esi");		# zero round counter

&set_label("round",16);
	&movq	(@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8));	# rc[r]
	&mov	("eax",&DWP(0,"esp"));
	&mov	("ebx",&DWP(4,"esp"));
for($i=0;$i<8;$i++) {
    my $func = ($i==0)? movq : pxor;
	&movb	(&LB("ecx"),&LB("eax"));
	&movb	(&LB("edx"),&HB("eax"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&shr	("eax",16);
	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
	&$func	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("eax"));
	&movb	(&LB("edx"),&HB("eax"));
	&mov	("eax",&DWP(($i+1)*8,"esp"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&$func	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
	&$func	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("ebx"));
	&movb	(&LB("edx"),&HB("ebx"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&shr	("ebx",16);
	&$func	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
	&$func	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("ebx"));
	&movb	(&LB("edx"),&HB("ebx"));
	&mov	("ebx",&DWP(($i+1)*8+4,"esp"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&$func	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
	&$func	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
    push(@mm,shift(@mm));
}

	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L

for($i=0;$i<8;$i++) {
	&movb	(&LB("ecx"),&LB("eax"));
	&movb	(&LB("edx"),&HB("eax"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&shr	("eax",16);
	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
	&pxor	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("eax"));
	&movb	(&LB("edx"),&HB("eax"));
	&mov	("eax",&DWP(64+($i+1)*8,"esp"))		if ($i<7);
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&pxor	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
	&pxor	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("ebx"));
	&movb	(&LB("edx"),&HB("ebx"));
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&shr	("ebx",16);
	&pxor	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
	&pxor	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
	&movb	(&LB("ecx"),&LB("ebx"));
	&movb	(&LB("edx"),&HB("ebx"));
	&mov	("ebx",&DWP(64+($i+1)*8+4,"esp"))	if ($i<7);
	&scale	("esi","ecx");
	&scale	("edi","edx");
	&pxor	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
	&pxor	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
    push(@mm,shift(@mm));
}
	&lea	("ebx",&DWP(128,"esp"));
	&mov	("esi",&DWP(12,"ebx"));		# pull round counter
	&add	("esi",1);
	&cmp	("esi",10);
	&je	(&label("roundsdone"));

	&mov	(&DWP(12,"ebx"),"esi");		# update round counter
	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
	&jmp	(&label("round"));

&set_label("roundsdone",16);
	&mov	("esi",&DWP(0,"ebx"));		# reload argument block
	&mov	("edi",&DWP(4,"ebx"));
	&mov	("eax",&DWP(8,"ebx"));

	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); }    # L^=H
	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); }    # H=L

	&lea	("edi",&DWP(64,"edi"));		# inp+=64
	&sub	("eax",1);			# num--
	&jz	(&label("alldone"));
	&mov	(&DWP(4,"ebx"),"edi");		# update argument block
	&mov	(&DWP(8,"ebx"),"eax");
	&jmp	(&label("outerloop"));

&set_label("alldone");
	&emms	();
	&mov	("esp",&DWP(16,"ebx"));		# restore saved stack pointer
	&pop	("edi");
	&pop	("esi");
	&pop	("ebx");
	&pop	("ebp");
	&ret	();

&align(64);
&set_label("table");
	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);

	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);

&function_end_B("whirlpool_block_mmx");
&asm_finish(); 

File Added: src/crypto/dist/openssl/crypto/whrlpool/asm/Attic/wp-x86_64.pl
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
# project. Rights for redistribution and usage in source and binary
# forms are granted according to the OpenSSL license.
# ====================================================================
#
# whirlpool_block for x86_64.
#
# 2500 cycles per 64-byte input block on AMD64, which is *identical*
# to 32-bit MMX version executed on same CPU. So why did I bother?
# Well, it's faster than gcc 3.3.2 generated code by over 50%, and
# over 80% faster than PathScale 1.4, an "ambitious" commercial
# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio
# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the
# first example when they fail to generate more optimal code, when
# I believe they had *all* chances to...
#
# Note that register and stack frame layout are virtually identical
# to 32-bit MMX version, except that %r8-15 are used instead of
# %mm0-8. You can even notice that K[i] and S[i] are loaded to
# %eax:%ebx as pair of 32-bit values and not as single 64-bit one.
# This is done in order to avoid 64-bit shift penalties on Intel
# EM64T core. Speaking of which! I bet it's possible to improve
# Opteron performance by compressing the table to 2KB and replacing
# unaligned references with complementary rotations [which would
# incidentally replace lea instructions], but it would definitely
# just "kill" EM64T, because it has only 1 shifter/rotator [against
# 3 on Opteron] and which is *unacceptably* slow with 64-bit
# operand.

$output=shift;

$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";

open STDOUT,"| $^X $xlate $output";

sub L() { $code.=".byte	".join(',',@_)."\n"; }
sub LL(){ $code.=".byte	".join(',',@_).",".join(',',@_)."\n"; }

@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15");

$func="whirlpool_block";
$table=".Ltable";

$code=<<___;
.text

.globl	$func
.type	$func,\@function,3
.align	16
$func:
	push	%rbx
	push	%rbp
	push	%r12
	push	%r13
	push	%r14
	push	%r15

	mov	%rsp,%rax
	sub	\$128+40,%rsp
	and	\$-64,%rsp

	lea	128(%rsp),%rbx
	mov	%rdi,0(%rbx)		# save parameter block
	mov	%rsi,8(%rbx)
	mov	%rdx,16(%rbx)
	mov	%rax,32(%rbx)		# saved stack pointer

	.picmeup %rbp
	lea	$table-.(%rbp),%rbp

	xor	%rcx,%rcx
	xor	%rdx,%rdx
___
for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; }	# L=H
$code.=".Louterloop:\n";
for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
$code.=<<___;
	xor	%rsi,%rsi
	mov	%rsi,24(%rbx)		# zero round counter
.align	16
.Lround:
	mov	4096(%rbp,%rsi,8),@mm[0]	# rc[r]
	mov	0(%rsp),%eax
	mov	4(%rsp),%ebx
___
for($i=0;$i<8;$i++) {
    my $func = ($i==0)? "mov" : "xor";
    $code.=<<___;
	mov	%al,%cl
	mov	%ah,%dl
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	shr	\$16,%eax
	xor	0(%rbp,%rsi,8),@mm[0]
	$func	7(%rbp,%rdi,8),@mm[1]
	mov	%al,%cl
	mov	%ah,%dl
	mov	$i*8+8(%rsp),%eax		# ($i+1)*8
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	$func	6(%rbp,%rsi,8),@mm[2]
	$func	5(%rbp,%rdi,8),@mm[3]
	mov	%bl,%cl
	mov	%bh,%dl
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	shr	\$16,%ebx
	$func	4(%rbp,%rsi,8),@mm[4]
	$func	3(%rbp,%rdi,8),@mm[5]
	mov	%bl,%cl
	mov	%bh,%dl
	mov	$i*8+8+4(%rsp),%ebx		# ($i+1)*8+4
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	$func	2(%rbp,%rsi,8),@mm[6]
	$func	1(%rbp,%rdi,8),@mm[7]
___
    push(@mm,shift(@mm));
}
for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
for($i=0;$i<8;$i++) {
    $code.=<<___;
	mov	%al,%cl
	mov	%ah,%dl
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	shr	\$16,%eax
	xor	0(%rbp,%rsi,8),@mm[0]
	xor	7(%rbp,%rdi,8),@mm[1]
	mov	%al,%cl
	mov	%ah,%dl
	`"mov	64+$i*8+8(%rsp),%eax"	if($i<7);`	# 64+($i+1)*8
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	xor	6(%rbp,%rsi,8),@mm[2]
	xor	5(%rbp,%rdi,8),@mm[3]
	mov	%bl,%cl
	mov	%bh,%dl
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	shr	\$16,%ebx
	xor	4(%rbp,%rsi,8),@mm[4]
	xor	3(%rbp,%rdi,8),@mm[5]
	mov	%bl,%cl
	mov	%bh,%dl
	`"mov	64+$i*8+8+4(%rsp),%ebx"	if($i<7);`	# 64+($i+1)*8+4
	lea	(%rcx,%rcx),%rsi
	lea	(%rdx,%rdx),%rdi
	xor	2(%rbp,%rsi,8),@mm[6]
	xor	1(%rbp,%rdi,8),@mm[7]
___
    push(@mm,shift(@mm));
}
$code.=<<___;
	lea	128(%rsp),%rbx
	mov	24(%rbx),%rsi		# pull round counter
	add	\$1,%rsi
	cmp	\$10,%rsi
	je	.Lroundsdone

	mov	%rsi,24(%rbx)		# update round counter
___
for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
$code.=<<___;
	jmp	.Lround
.align	16
.Lroundsdone:
	mov	0(%rbx),%rdi		# reload argument block
	mov	8(%rbx),%rsi
	mov	16(%rbx),%rax
___
for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; }	# L^=H
for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; }	# H=L
$code.=<<___;
	lea	64(%rsi),%rsi		# inp+=64
	sub	\$1,%rax		# num--
	jz	.Lalldone
	mov	%rsi,8(%rbx)		# update parameter block
	mov	%rax,16(%rbx)
	jmp	.Louterloop
.Lalldone:
	mov	32(%rbx),%rsp		# restore saved pointer
	pop	%r15
	pop	%r14
	pop	%r13
	pop	%r12
	pop	%rbp
	pop	%rbx
	ret
.size	$func,.-$func

.align	64
.type	$table,\@object
$table:
___
	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);

	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);

$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
close STDOUT;

File Added: src/crypto/dist/openssl/demos/cms/Attic/cacert.pem
-----BEGIN CERTIFICATE-----
MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/demos/cms/Attic/cakey.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
+VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_ddec.c
/* S/MIME detached data decrypt example: rarely done but
 * should the need arise this is an example....
 */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL, *dcont = NULL;
	X509 *rcert = NULL;
	EVP_PKEY *rkey = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate and private key */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	if (!rcert || !rkey)
		goto err;

	/* Open PEM file containing enveloped data */

	in = BIO_new_file("smencr.pem", "r");

	if (!in)
		goto err;

	/* Parse PEM content */
	cms = PEM_read_bio_CMS(in, NULL, 0, NULL);

	if (!cms)
		goto err;

	/* Open file containing detached content */
	dcont = BIO_new_file("smencr.out", "rb");

	if (!in)
		goto err;

	out = BIO_new_file("encrout.txt", "w");
	if (!out)
		goto err;

	/* Decrypt S/MIME message */
	if (!CMS_decrypt(cms, rkey, rcert, dcont, out, 0))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Decrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);
	if (rcert)
		X509_free(rcert);
	if (rkey)
		EVP_PKEY_free(rkey);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);
	if (dcont)
		BIO_free(dcont);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_dec.c
/* Simple S/MIME decryption example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *rcert = NULL;
	EVP_PKEY *rkey = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate and private key */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	if (!rcert || !rkey)
		goto err;

	/* Open S/MIME message to decrypt */

	in = BIO_new_file("smencr.txt", "r");

	if (!in)
		goto err;

	/* Parse message */
	cms = SMIME_read_CMS(in, NULL);

	if (!cms)
		goto err;

	out = BIO_new_file("decout.txt", "w");
	if (!out)
		goto err;

	/* Decrypt S/MIME message */
	if (!CMS_decrypt(cms, rkey, rcert, out, NULL, 0))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Decrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);
	if (rcert)
		X509_free(rcert);
	if (rkey)
		EVP_PKEY_free(rkey);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_denc.c
/* S/MIME detached data encrypt example: rarely done but
 * should the need arise this is an example....
 */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL, *dout = NULL;
	X509 *rcert = NULL;
	STACK_OF(X509) *recips = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	int flags = CMS_STREAM|CMS_DETACHED;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	if (!rcert)
		goto err;

	/* Create recipient STACK and add recipient cert to it */
	recips = sk_X509_new_null();

	if (!recips || !sk_X509_push(recips, rcert))
		goto err;

	/* sk_X509_pop_free will free up recipient STACK and its contents
	 * so set rcert to NULL so it isn't freed up twice.
	 */
	rcert = NULL;

	/* Open content being encrypted */

	in = BIO_new_file("encr.txt", "r");

	dout = BIO_new_file("smencr.out", "wb");

	if (!in)
		goto err;

	/* encrypt content */
	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);

	if (!cms)
		goto err;

	out = BIO_new_file("smencr.pem", "w");
	if (!out)
		goto err;

	if (!CMS_final(cms, in, dout, flags))
		goto err;

	/* Write out CMS structure without content */
	if (!PEM_write_bio_CMS(out, cms))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Encrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);
	if (rcert)
		X509_free(rcert);
	if (recips)
		sk_X509_pop_free(recips, X509_free);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (dout)
		BIO_free(dout);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_enc.c
/* Simple S/MIME encrypt example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *rcert = NULL;
	STACK_OF(X509) *recips = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	/*
	 * On OpenSSL 0.9.9 only:
	 * for streaming set CMS_STREAM
	 */
	int flags = CMS_STREAM;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	if (!rcert)
		goto err;

	/* Create recipient STACK and add recipient cert to it */
	recips = sk_X509_new_null();

	if (!recips || !sk_X509_push(recips, rcert))
		goto err;

	/* sk_X509_pop_free will free up recipient STACK and its contents
	 * so set rcert to NULL so it isn't freed up twice.
	 */
	rcert = NULL;

	/* Open content being encrypted */

	in = BIO_new_file("encr.txt", "r");

	if (!in)
		goto err;

	/* encrypt content */
	cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags);

	if (!cms)
		goto err;

	out = BIO_new_file("smencr.txt", "w");
	if (!out)
		goto err;

	/* Write out S/MIME message */
	if (!SMIME_write_CMS(out, cms, in, flags))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Encrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);
	if (rcert)
		X509_free(rcert);
	if (recips)
		sk_X509_pop_free(recips, X509_free);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_uncomp.c
/* Simple S/MIME uncompression example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL;
	CMS_ContentInfo *cms = NULL;
	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Open compressed content */

	in = BIO_new_file("smcomp.txt", "r");

	if (!in)
		goto err;

	/* Sign content */
	cms = SMIME_read_CMS(in, NULL);

	if (!cms)
		goto err;

	out = BIO_new_file("smuncomp.txt", "w");
	if (!out)
		goto err;

	/* Uncompress S/MIME message */
	if (!CMS_uncompress(cms, out, NULL, 0))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Uncompressing Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/cms_ver.c
/* Simple S/MIME verification example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
	X509_STORE *st = NULL;
	X509 *cacert = NULL;
	CMS_ContentInfo *cms = NULL;

	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Set up trusted CA certificate store */

	st = X509_STORE_new();

	/* Read in signer certificate and private key */
	tbio = BIO_new_file("cacert.pem", "r");

	if (!tbio)
		goto err;

	cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	if (!cacert)
		goto err;

	if (!X509_STORE_add_cert(st, cacert))
		goto err;

	/* Open content being signed */

	in = BIO_new_file("smout.txt", "r");

	if (!in)
		goto err;

	/* Sign content */
	cms = SMIME_read_CMS(in, &cont);

	if (!cms)
		goto err;

	/* File to output verified content to */
	out = BIO_new_file("smver.txt", "w");
	if (!out)
		goto err;

	if (!CMS_verify(cms, NULL, st, cont, out, 0))
		{
		fprintf(stderr, "Verification Failure\n");
		goto err;
		}

	fprintf(stderr, "Verification Successful\n");

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Verifying Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (cms)
		CMS_ContentInfo_free(cms);

	if (cacert)
		X509_free(cacert);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/cms/Attic/comp.txt
Content-type: text/plain

Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed
Some Text To be Compressed

File Added: src/crypto/dist/openssl/demos/cms/Attic/encr.txt
Content-type: text/plain

Sample OpenSSL Data for CMS encryption

File Added: src/crypto/dist/openssl/demos/cms/Attic/sign.txt
Content-type: text/plain

Test OpenSSL CMS Signed Content

File Added: src/crypto/dist/openssl/demos/cms/Attic/signer.pem
-----BEGIN CERTIFICATE-----
MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
+Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
lDiQlgX0JtmLgA==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/cms/Attic/signer2.pem
-----BEGIN CERTIFICATE-----
MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
2aX6rl2JEuJ5Yg==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/smime/Attic/cacert.pem
-----BEGIN CERTIFICATE-----
MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3
WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD
aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN
RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz
i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR
ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT
jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx
CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B
SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD
VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB
ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc
G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo
u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF
1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw==
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/demos/smime/Attic/cakey.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd
c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3
dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB
AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5
HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs
tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS
rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18
9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u
jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is
uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU
+VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP
wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW
8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg==
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/smime/Attic/encr.txt
Content-type: text/plain

Sample OpenSSL Data for PKCS#7 encryption

File Added: src/crypto/dist/openssl/demos/smime/Attic/sign.txt
Content-type: text/plain

Test OpenSSL Signed Content

File Added: src/crypto/dist/openssl/demos/smime/Attic/signer.pem
-----BEGIN CERTIFICATE-----
MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3
WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl
bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz
jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L
ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y
gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX
MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn
+Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv
lDiQlgX0JtmLgA==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm
1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH
Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB
AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG
mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o
wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx
04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55
qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc
YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY
sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4
4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid
7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5
xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw=
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/smime/Attic/signer2.pem
-----BEGIN CERTIFICATE-----
MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV
BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv
dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0
WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT
TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl
bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ
jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW
ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW
GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7
2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X
h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4
aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR
2aX6rl2JEuJ5Yg==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM
nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f
nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB
AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF
6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2
CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf
m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX
2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr
upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4
ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL
SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk
gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX
pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A=
-----END RSA PRIVATE KEY-----

File Added: src/crypto/dist/openssl/demos/smime/Attic/smdec.c
/* Simple S/MIME signing example */
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *rcert = NULL;
	EVP_PKEY *rkey = NULL;
	PKCS7 *p7 = NULL;
	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate and private key */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	if (!rcert || !rkey)
		goto err;

	/* Open content being signed */

	in = BIO_new_file("smencr.txt", "r");

	if (!in)
		goto err;

	/* Sign content */
	p7 = SMIME_read_PKCS7(in, NULL);

	if (!p7)
		goto err;

	out = BIO_new_file("encrout.txt", "w");
	if (!out)
		goto err;

	/* Decrypt S/MIME message */
	if (!PKCS7_decrypt(p7, rkey, rcert, out, 0))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Signing Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (p7)
		PKCS7_free(p7);
	if (rcert)
		X509_free(rcert);
	if (rkey)
		EVP_PKEY_free(rkey);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}





File Added: src/crypto/dist/openssl/demos/smime/Attic/smenc.c
/* Simple S/MIME encrypt example */
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *rcert = NULL;
	STACK_OF(X509) *recips = NULL;
	PKCS7 *p7 = NULL;
	int ret = 1;

	/*
	 * On OpenSSL 0.9.9 only:
	 * for streaming set PKCS7_STREAM
	 */
	int flags = PKCS7_STREAM;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in recipient certificate */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	if (!rcert)
		goto err;

	/* Create recipient STACK and add recipient cert to it */
	recips = sk_X509_new_null();

	if (!recips || !sk_X509_push(recips, rcert))
		goto err;

	/* sk_X509_pop_free will free up recipient STACK and its contents
	 * so set rcert to NULL so it isn't freed up twice.
	 */
	rcert = NULL;

	/* Open content being encrypted */

	in = BIO_new_file("encr.txt", "r");

	if (!in)
		goto err;

	/* encrypt content */
	p7 = PKCS7_encrypt(recips, in, EVP_des_ede3_cbc(), flags);

	if (!p7)
		goto err;

	out = BIO_new_file("smencr.txt", "w");
	if (!out)
		goto err;

	/* Write out S/MIME message */
	if (!SMIME_write_PKCS7(out, p7, in, flags))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Encrypting Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (p7)
		PKCS7_free(p7);
	if (rcert)
		X509_free(rcert);
	if (recips)
		sk_X509_pop_free(recips, X509_free);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/smime/Attic/smsign.c
/* Simple S/MIME signing example */
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *scert = NULL;
	EVP_PKEY *skey = NULL;
	PKCS7 *p7 = NULL;
	int ret = 1;

	/* For simple S/MIME signing use PKCS7_DETACHED.
	 * On OpenSSL 0.9.9 only:
	 * for streaming detached set PKCS7_DETACHED|PKCS7_STREAM
	 * for streaming non-detached set PKCS7_STREAM
	 */
	int flags = PKCS7_DETACHED|PKCS7_STREAM;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Read in signer certificate and private key */
	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	if (!scert || !skey)
		goto err;

	/* Open content being signed */

	in = BIO_new_file("sign.txt", "r");

	if (!in)
		goto err;

	/* Sign content */
	p7 = PKCS7_sign(scert, skey, NULL, in, flags);

	if (!p7)
		goto err;

	out = BIO_new_file("smout.txt", "w");
	if (!out)
		goto err;

	if (!(flags & PKCS7_STREAM))
		BIO_reset(in);

	/* Write out S/MIME message */
	if (!SMIME_write_PKCS7(out, p7, in, flags))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Signing Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (p7)
		PKCS7_free(p7);
	if (scert)
		X509_free(scert);
	if (skey)
		EVP_PKEY_free(skey);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}

File Added: src/crypto/dist/openssl/demos/smime/Attic/smsign2.c
/* S/MIME signing example: 2 signers. OpenSSL 0.9.9 only */
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/err.h>

int main(int argc, char **argv)
	{
	BIO *in = NULL, *out = NULL, *tbio = NULL;
	X509 *scert = NULL, *scert2 = NULL;
	EVP_PKEY *skey = NULL, *skey2 = NULL;
	PKCS7 *p7 = NULL;
	int ret = 1;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	tbio = BIO_new_file("signer.pem", "r");

	if (!tbio)
		goto err;

	scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	BIO_free(tbio);

	tbio = BIO_new_file("signer2.pem", "r");

	if (!tbio)
		goto err;

	scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL);

	BIO_reset(tbio);

	skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

	if (!scert2 || !skey2)
		goto err;

	in = BIO_new_file("sign.txt", "r");

	if (!in)
		goto err;

	p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM|PKCS7_PARTIAL);

	if (!p7)
		goto err;

	/* Add each signer in turn */

	if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0))
		goto err;

	if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0))
		goto err;

	out = BIO_new_file("smout.txt", "w");
	if (!out)
		goto err;

	/* NB: content included and finalized by SMIME_write_PKCS7 */

	if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM))
		goto err;

	ret = 0;

	err:

	if (ret)
		{
		fprintf(stderr, "Error Signing Data\n");
		ERR_print_errors_fp(stderr);
		}

	if (p7)
		PKCS7_free(p7);

	if (scert)
		X509_free(scert);
	if (skey)
		EVP_PKEY_free(skey);

	if (scert2)
		X509_free(scert2);
	if (skey)
		EVP_PKEY_free(skey2);

	if (in)
		BIO_free(in);
	if (out)
		BIO_free(out);
	if (tbio)
		BIO_free(tbio);

	return ret;

	}





File Added: src/crypto/dist/openssl/engines/ccgost/Attic/Makefile
DIR=ccgost
TOP=../..
CC=cc
INCLUDES= -I../../include
CFLAG=-g
MAKEFILE= Makefile
AR= ar r
CFLAGS= $(INCLUDES) $(CFLAG)
LIB=$(TOP)/libcrypto.a

LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c

LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o

SRC=$(LIBSRC)

LIBNAME=gost

top: 
	(cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all)

all: lib

tags:
	ctags $(SRC)

errors:
	$(PERL) ../../util/mkerr.pl -conf gost.ec -nostatic -write $(SRC)

lib: $(LIBOBJ)
	if [ -n "$(SHARED_LIBS)" ]; then \
		$(MAKE) -f $(TOP)/Makefile.shared -e \
			LIBNAME=$(LIBNAME) \
			LIBEXTRAS='$(LIBOBJ)' \
			LIBDEPS='-L$(TOP) -lcrypto' \
			link_o.$(SHLIB_TARGET); \
	else \
		$(AR) $(LIB) $(LIBOBJ); \
	fi
	@touch lib

install:
	[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
	if [ -n "$(SHARED_LIBS)" ]; then \
		set -e; \
		echo installing $(LIBNAME); \
		pfx=lib; \
		if [ "$(PLATFORM)" != "Cygwin" ]; then \
			case "$(CFLAGS)" in \
			*DSO_BEOS*) sfx=".so";; \
			*DSO_DLFCN*) sfx=".so";; \
			*DSO_DL*) sfx=".sl";; \
			*DSO_WIN32*) sfx="eay32.dll"; pfx=;; \
			*) sfx=".bad";; \
			esac; \
			cp $${pfx}$(LIBNAME)$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$${pfx}$(LIBNAME)$$sfx.new; \
		else \
			sfx="so"; \
			cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$${pfx}$(LIBNAME)$$sfx.new; \
		fi; \
		chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$${pfx}$(LIBNAME)$$sfx.new; \
		mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$${pfx}$(LIBNAME)$$sfx; \
	fi

links:

tests:

depend:
	@if [ -z "$(THIS)" ]; then \
	    $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
	else \
	    $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
	fi

files:



lint:
	lint -DLINT $(INCLUDES) $(SRC)>fluff

dclean:
	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
	mv -f Makefile.new $(MAKEFILE)

clean:
	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll

# DO NOT DELETE THIS LINE -- make depend depends on it.

gost2001.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost2001.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost2001.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost2001.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost2001.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost2001.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost2001.o: ../../include/openssl/err.h ../../include/openssl/evp.h
gost2001.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost2001.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
gost2001.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost2001.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
gost2001.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
gost2001.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
gost2001.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
gost2001.o: e_gost_err.h gost2001.c gost89.h gost_lcl.h gost_params.h
gost2001.o: gosthash.h
gost2001_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost2001_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost2001_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost2001_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost2001_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost2001_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost2001_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
gost2001_keyx.o: ../../include/openssl/obj_mac.h
gost2001_keyx.o: ../../include/openssl/objects.h
gost2001_keyx.o: ../../include/openssl/opensslconf.h
gost2001_keyx.o: ../../include/openssl/opensslv.h
gost2001_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
gost2001_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
gost2001_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost2001_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost2001_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost2001_keyx.c
gost2001_keyx.o: gost2001_keyx.h gost89.h gost_keywrap.h gost_lcl.h gosthash.h
gost89.o: gost89.c gost89.h
gost94_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost94_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost94_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost94_keyx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
gost94_keyx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
gost94_keyx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
gost94_keyx.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
gost94_keyx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost94_keyx.o: ../../include/openssl/objects.h
gost94_keyx.o: ../../include/openssl/opensslconf.h
gost94_keyx.o: ../../include/openssl/opensslv.h
gost94_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
gost94_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
gost94_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost94_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost94_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
gost94_keyx.o: gost94_keyx.c gost_keywrap.h gost_lcl.h gosthash.h
gost_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_ameth.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
gost_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_ameth.o: ../../include/openssl/objects.h
gost_ameth.o: ../../include/openssl/opensslconf.h
gost_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
gost_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost_ameth.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h
gost_ameth.o: gost_ameth.c gost_lcl.h gost_params.h gosthash.h
gost_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
gost_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_asn1.o: ../../include/openssl/opensslconf.h
gost_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
gost_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost_asn1.o: ../../include/openssl/x509_vfy.h gost89.h gost_asn1.c gost_lcl.h
gost_asn1.o: gosthash.h
gost_crypt.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_crypt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_crypt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_crypt.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_crypt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_crypt.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_crypt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
gost_crypt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_crypt.o: ../../include/openssl/opensslconf.h
gost_crypt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_crypt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
gost_crypt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
gost_crypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
gost_crypt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
gost_crypt.o: e_gost_err.h gost89.h gost_crypt.c gost_lcl.h gosthash.h
gost_ctl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_ctl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_ctl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_ctl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_ctl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_ctl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_ctl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
gost_ctl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_ctl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
gost_ctl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_ctl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
gost_ctl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost_ctl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost_ctl.o: ../../include/openssl/x509_vfy.h gost89.h gost_ctl.c gost_lcl.h
gost_ctl.o: gosthash.h
gost_eng.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_eng.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_eng.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_eng.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
gost_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
gost_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
gost_eng.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost_eng.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost_eng.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h gost_eng.c
gost_eng.o: gost_lcl.h gosthash.h
gost_keywrap.o: gost89.h gost_keywrap.c gost_keywrap.h
gost_md.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_md.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_md.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_md.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_md.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
gost_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
gost_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
gost_md.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
gost_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
gost_md.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
gost_md.o: e_gost_err.h gost89.h gost_lcl.h gost_md.c gosthash.h
gost_params.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
gost_params.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
gost_params.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_params.o: ../../include/openssl/opensslconf.h
gost_params.o: ../../include/openssl/opensslv.h
gost_params.o: ../../include/openssl/ossl_typ.h
gost_params.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
gost_params.o: ../../include/openssl/symhacks.h gost_params.c gost_params.h
gost_pmeth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
gost_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
gost_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
gost_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
gost_pmeth.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
gost_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_pmeth.o: ../../include/openssl/objects.h
gost_pmeth.o: ../../include/openssl/opensslconf.h
gost_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
gost_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
gost_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
gost_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
gost_pmeth.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_pmeth.c
gost_pmeth.o: gosthash.h
gost_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
gost_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
gost_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
gost_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
gost_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
gost_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
gost_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
gost_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
gost_sign.o: ../../include/openssl/opensslconf.h
gost_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
gost_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
gost_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
gost_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_sign.c
gost_sign.o: gosthash.h
gosthash.o: gost89.h gosthash.c gosthash.h

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/README.gost
GOST ENGINE

This engine provides implementation of Russian cryptography standard.
This is also an example of adding new cryptoalgorithms into OpenSSL
without changing its core. If OpenSSL is compiled with dynamic engine
support, new algorithms can be added even without recompilation of
OpenSSL and applications which use it.

ALGORITHMS SUPPORTED

GOST R 34.10-94 and GOST R 34.10-2001 - digital signature algorithms.
   Also support key exchange based on public keys. See RFC 4357 for
   details of VKO key exchange algorithm. These algorithms use
   256 bit private keys. Public keys are 1024 bit for 94 and 512 bit for
   2001 (which is elliptic-curve based). Key exchange algorithms
   (VKO R 34.10) are supported on these keys too.
   
GOST R 34.11-94  Message digest algorithm. 256-bit hash value

GOST 28147-89 - Symmetric cipher  with 256-bit key. Various modes are
   defined in the standard, but only CFB and CNT modes are implemented
   in the engine. To make statistical analysis more difficult, key
   meshing is supported (see RFC 4357).

GOST 28147-89 MAC mode. Message authentication code. While most MAC
    algorithms  out there are based on hash functions using HMAC
	algorithm, this algoritm is based on symmetric cipher. 
	It has 256-bit symmetric key and only 32 bits of MAC value
	(while HMAC has same key size and value size). 

	It is implemented as combination of EVP_PKEY type and EVP_MD type.

USAGE OF THESE ALGORITHMS

This engine is designed to allow usage of this algorithms in the
high-level openssl functions, such as PKI, S/MIME and TLS.

See RFC 4490 for S/MIME with GOST algorithms and RFC 4491 for PKI.
TLS support is implemented according IETF
draft-chudov-cryptopro-cptls-03.txt and is compatible with
CryptoPro CSP 3.0 and 3.6 as well as with MagPro CSP. 
GOST ciphersuites implemented in CryptoPro CSP 2.0 are not supported
because they use ciphersuite numbers used now by AES ciphersuites.

To use the engine you have to load it via openssl configuration
file. Applications should read openssl configuration file or provide
their own means to load engines. Also, applications which operate with
private keys, should use generic EVP_PKEY API instead of using RSA or
other algorithm-specific API.

CONFIGURATION FILE

Configuration file should include following statement in the global
section, i.e. before first bracketed section header (see config(5) for details)

   openssl_conf = openssl_def

where openssl_def is name of the section in configuration file which
describes global defaults.

This section should contain following statement:

   [openssl_def]
   engines = engine_section

which points to the section which describes list of the engines to be
loaded. This section should contain:

	[engine_section]
	gost = gost_section

And section which describes configuration of the engine should contain

	[gost_section]
	engine_id = gost
	dynamic_path = /usr/lib/ssl/engines/libgost.so
	default_algorithms = ALL
	crypt_params = id-Gost28147-89-CryptoPro-A-ParamSet

Where engine_id parameter specifies name of engine (should be "gost").
dynamic_path is a location of the loadable shared library implementing the
engine. If the engine is compiled statically or is located in the OpenSSL
engines directory, this line can be omitted. But as of October 2007 there is
some bug in OpenSSL engine initialization code which prevents engine from
correct initialization if it is loaded without explicit dynamic_path.
default_algorithms parameter specifies that all algorithms, provided by
engine, should be used.

The crypt_params parameter is engine-specific. It allows the user to choose
between different parameter sets of symmetric cipher algorithm. RFC 4357
specifies several parameters for the GOST 28147-89 algorithm, but OpenSSL
doesn't provide user interface to choose one when encrypting. So use engine
configuration parameter instead.

Value of this parameter can be either short name, defined in OpenSSL
obj_dat.h header file or numeric representation of OID, defined in RFC
4357. 

USAGE WITH COMMAND LINE openssl UTILITY

1. Generation of private key

	openssl genpkey -algorithm gost2001 -pkeyopt paramset:A -out seckey.pem

  Use -algorithm option to specify algorithm.
  Use -pkeyopt option to pass paramset to algorithm. The following paramsets
  are supported by 
  	gost94: 0,A,B,C,D,XA,XB,XC
	gost2001: 0,A,B,C,XA,XB
  You can also use numeric representation of OID as to destinate
  paramset.

  Paramsets starting with X are intended to use for key exchange keys.
  Paramsets without X are for digital signature keys.

  Paramset for both algorithms 0 is the test paramset which should be used
  only for test purposes.

There are no algorithm-specific things with generation of certificate
request once you have a private key.

2. S/MIME operations

If you want to send encrypted mail using GOST algorithms, don't forget
to specify -gost89 as encryption algorithm for OpenSSL smime command.
While OpenSSL is clever enough to find out that GOST R 34.11-94 digest
must be used for digital signing with GOST private key, it have no way
to derive symmetric encryption algorithm from key exchange keys.

3. TLS operations

OpenSSL supports all four ciphersuites defined in the IETF draft.
Once you've loaded GOST key and certificate into your TLS server,
ciphersuites which use GOST 28147-89 encryption are enabled.

Ciphersuites with NULL encryption should be enabled explicitely if
needed.

GOST2001-GOST89-GOST89 Uses GOST R 34.10-2001 for auth and key exchange
		GOST 28147-89 for encryption and GOST 28147-89 MAC
GOST94-GOST89-GOST89 Uses GOST R 34.10-94 for auth and key exchange
		GOST 28147-89 for encryption and GOST 28147-89 MAC
GOST2001-NULL-GOST94 Uses GOST R 34.10-2001 for auth and key exchange,
        no encryption and HMAC, based on GOST R 34.11-94
GOST94-NULL-GOST94 Uses GOST R 34.10-94 for auth and key exchange,
        no encryption and HMAC, based on GOST R 34.11-94

Gost 94 and gost 2001 keys can be used simultaneously in the TLS server.
RSA, DSA and EC keys can be used simultaneously with GOST keys, if
server implementation supports loading more than two private
key/certificate pairs. In this case ciphersuites which use any of loaded
keys would be supported and clients can negotiate ones they wish.

This allows creation of TLS servers which use GOST ciphersuites for
Russian clients and RSA/DSA ciphersuites for foreign clients.

4. Calculation of digests and symmetric encryption
 OpenSSL provides specific commands (like sha1, aes etc) for calculation
 of digests and symmetric encryption. Since such commands cannot be
 added dynamically, no such commands are provided for GOST algorithms.
 Use generic commands 'dgst' and 'enc'.

 Calculation of GOST R 34.11-94 message digest

 openssl dgst -md_gost94 datafile

 Note that GOST R 34.11-94 specifies that digest value should be
 interpreted as little-endian number, but OpenSSL outputs just hex dump
 of digest value.

 So, to obtain correct digest value, such as produced by gostsum utility
 included in the engine distribution, bytes of output should be
 reversed.
 
 Calculation of HMAC based on GOST R 34.11-94

 openssl dgst -md_gost94 -mac hmac -macopt key:<32 bytes of key> datafile
  
  (or use hexkey if key contain NUL bytes)
 Calculation of GOST 28147 MAC

 openssl dgst -mac gost-mac -macopt key:<32 bytes of key> datafile

 Note absense of an option that specifies digest algorithm. gost-mac
 algorithm supports only one digest (which is actually part of
 implementation of this mac) and OpenSSL is clever enough to find out
 this.

 Encryption with GOST 28147 CFB mode
 openssl enc -gost89 -out encrypted-file -in plain-text-file -k <passphrase>  
 Encryption with GOST 28147 CNT mode
 openssl enc -gost89-cnt -out encrypted-file -in plain-text-file -k <passphrase>


5. Encrypting private keys and PKCS12

To produce PKCS12 files compatible with MagPro CSP, you need to use
GOST algorithm for encryption of PKCS12 file and also GOST R 34.11-94
hash to derive key from password.

openssl pksc12 -export -inkey gost.pem -in gost_cert.pem -keypbe gost89\
   -certpbe gost89 -macalg md_gost94
 
 

PROGRAMMING INTERFACES DETAILS

Applications never should access engine directly. They only use provided
EVP_PKEY API. But there are some details, which should be taken into
account.

EVP provides two kinds of API for key exchange:

1. EVP_PKEY_encrypt/EVP_PKEY_decrypt functions, intended to use with
	RSA-like public key encryption algorithms

2. EVP_PKEY_derive, intended to use with Diffie-Hellman-like shared key
computing algorithms.

Although VKO R 34.10 algorithms, described in the RFC 4357 are
definitely second case, engine provides BOTH API for GOST R 34.10 keys.

EVP_PKEY_derive just invokes appropriate VKO algorithm and computes
256 bit shared key. VKO R 34.10-2001 requires 64 bits of random user key
material (UKM). This UKM should be transmitted to other party, so it is
not generated inside derive function.

It should be set by EVP_PKEY_CTX_ctrl function using
EVP_PKEY_CTRL_SET_IV command after call of EVP_PKEY_derive_init, but
before EVP_PKEY_derive.
	unsigned char ukm[8];
	RAND_bytes(ukm,8);
   EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, 8, ukm)

EVP_PKEY_encrypt encrypts provided session key with VKO shared key and
packs it into GOST key transport structure, described in the RFC 4490.

It typically uses ephemeral key pair to compute shared key and packs its
public part along with encrypted key. So, for most cases use of 
EVP_PKEY_encrypt/EVP_PKEY_decrypt with GOST keys is almost same as with
RSA.

However, if peerkey field in the EVP_PKEY_CTX structure is set (using
EVP_PKEY_derive_set_peerkey function) to EVP_PKEY structure which has private
key and uses same parameters as the public key from which this EVP_PKEY_CTX is
created, EVP_PKEY_encrypt will use this private key to compute shared key and
set ephemeral key in the GOST_key_transport structure to NULL. In this case
pkey and peerkey fields in the EVP_PKEY_CTX are used upside-down.

If EVP_PKEY_decrypt encounters GOST_key_transport structure with NULL
public key field, it tries to use peerkey field from the context to
compute shared key. In this case peerkey field should really contain
peer public key.

Encrypt operation supports EVP_PKEY_CTRL_SET_IV operation as well.
It can be used when some specific restriction on UKM are imposed by
higher level protocol. For instance, description of GOST ciphersuites
requires UKM to be derived from shared secret. 

If UKM is not set by this control command, encrypt operation would
generate random UKM.


This sources include implementation of GOST 28147-89 and GOST R 34.11-94
which are completely indepentent from OpenSSL and can be used separately
(files gost89.c, gost89.h, gosthash.c, gosthash.h) Utility gostsum (file
gostsum.c) is provided as example of such separate usage. This is
program, simular to md5sum and sha1sum utilities, but calculates GOST R
34.11-94 hash.

Makefile doesn't include rule for compiling gostsum.
Use command

$(CC) -o gostsum gostsum.c gost89.c gosthash.c
where $(CC) is name of your C compiler.

Implementations of GOST R 34.10-xx, including VKO algorithms heavily
depends on OpenSSL BIGNUM and Elliptic Curve libraries.



File Added: src/crypto/dist/openssl/engines/ccgost/Attic/e_gost_err.c
/* e_gost_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 "e_gost_err.h"

/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR

#define ERR_FUNC(func) ERR_PACK(0,func,0)
#define ERR_REASON(reason) ERR_PACK(0,0,reason)

static ERR_STRING_DATA GOST_str_functs[]=
	{
{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS),	"DECODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS),	"ENCODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS),	"FILL_GOST2001_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS),	"FILL_GOST94_PARAMS"},
{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS),	"GET_ENCRYPTION_PARAMS"},
{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC),	"GOST2001_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST2001_DO_SIGN),	"GOST2001_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY),	"GOST2001_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST2001_KEYGEN),	"GOST2001_KEYGEN"},
{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS),	"GOST89_GET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS),	"GOST89_SET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC),	"GOST94_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST_CIPHER_CTL),	"GOST_CIPHER_CTL"},
{ERR_FUNC(GOST_F_GOST_DO_SIGN),	"GOST_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST_DO_VERIFY),	"GOST_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST_IMIT_CTRL),	"GOST_IMIT_CTRL"},
{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE),	"GOST_IMIT_UPDATE"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST01),	"PARAM_COPY_GOST01"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST94),	"PARAM_COPY_GOST94"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT),	"PKEY_GOST01CP_DECRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT),	"PKEY_GOST01CP_ENCRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN),	"PKEY_GOST01CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE),	"PKEY_GOST2001_DERIVE"},
{ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT),	"PKEY_GOST94CP_DECRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT),	"PKEY_GOST94CP_ENCRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN),	"PKEY_GOST94CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL),	"PKEY_GOST_CTRL"},
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR),	"PKEY_GOST_CTRL01_STR"},
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR),	"PKEY_GOST_CTRL94_STR"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL),	"PKEY_GOST_MAC_CTRL"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR),	"PKEY_GOST_MAC_CTRL_STR"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN),	"PKEY_GOST_MAC_KEYGEN"},
{ERR_FUNC(GOST_F_PRINT_GOST_01),	"PRINT_GOST_01"},
{ERR_FUNC(GOST_F_PRIV_DECODE_GOST),	"PRIV_DECODE_GOST"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST01),	"PUB_DECODE_GOST01"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST94),	"PUB_DECODE_GOST94"},
{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01),	"PUB_ENCODE_GOST01"},
{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE),	"UNPACK_CC_SIGNATURE"},
{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE),	"UNPACK_CP_SIGNATURE"},
{0,NULL}
	};

static ERR_STRING_DATA GOST_str_reasons[]=
	{
{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"},
{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"},
{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE)  ,"invalid digest type"},
{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"},
{ERR_REASON(GOST_R_INVALID_IV_LENGTH)    ,"invalid iv length"},
{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
{ERR_REASON(GOST_R_INVALID_PARAMSET)     ,"invalid paramset"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
{ERR_REASON(GOST_R_MAC_KEY_NOT_SET)      ,"mac key not set"},
{ERR_REASON(GOST_R_MALLOC_FAILURE)       ,"malloc failure"},
{ERR_REASON(GOST_R_NO_MEMORY)            ,"no memory"},
{ERR_REASON(GOST_R_NO_PARAMETERS_SET)    ,"no parameters set"},
{ERR_REASON(GOST_R_NO_PEER_KEY)          ,"no peer key"},
{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"},
{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
{ERR_REASON(GOST_R_SIGNATURE_MISMATCH)   ,"signature mismatch"},
{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
{ERR_REASON(GOST_R_UKM_NOT_SET)          ,"ukm not set"},
{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"},
{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
{0,NULL}
	};

#endif

#ifdef GOST_LIB_NAME
static ERR_STRING_DATA GOST_lib_name[]=
        {
{0	,GOST_LIB_NAME},
{0,NULL}
	};
#endif


static int GOST_lib_error_code=0;
static int GOST_error_init=1;

void ERR_load_GOST_strings(void)
	{
	if (GOST_lib_error_code == 0)
		GOST_lib_error_code=ERR_get_next_error_library();

	if (GOST_error_init)
		{
		GOST_error_init=0;
#ifndef OPENSSL_NO_ERR
		ERR_load_strings(GOST_lib_error_code,GOST_str_functs);
		ERR_load_strings(GOST_lib_error_code,GOST_str_reasons);
#endif

#ifdef GOST_LIB_NAME
		GOST_lib_name->error = ERR_PACK(GOST_lib_error_code,0,0);
		ERR_load_strings(0,GOST_lib_name);
#endif
		}
	}

void ERR_unload_GOST_strings(void)
	{
	if (GOST_error_init == 0)
		{
#ifndef OPENSSL_NO_ERR
		ERR_unload_strings(GOST_lib_error_code,GOST_str_functs);
		ERR_unload_strings(GOST_lib_error_code,GOST_str_reasons);
#endif

#ifdef GOST_LIB_NAME
		ERR_unload_strings(0,GOST_lib_name);
#endif
		GOST_error_init=1;
		}
	}

void ERR_GOST_error(int function, int reason, char *file, int line)
	{
	if (GOST_lib_error_code == 0)
		GOST_lib_error_code=ERR_get_next_error_library();
	ERR_PUT_error(GOST_lib_error_code,function,reason,file,line);
	}

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/e_gost_err.h
/* ====================================================================
 * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_GOST_ERR_H
#define HEADER_GOST_ERR_H

#ifdef  __cplusplus
extern "C" {
#endif

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_GOST_strings(void);
void ERR_unload_GOST_strings(void);
void ERR_GOST_error(int function, int reason, char *file, int line);
#define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__)

/* Error codes for the GOST functions. */

/* Function codes. */
#define GOST_F_DECODE_GOST_ALGOR_PARAMS			 99
#define GOST_F_ENCODE_GOST_ALGOR_PARAMS			 100
#define GOST_F_FILL_GOST2001_PARAMS			 101
#define GOST_F_FILL_GOST94_PARAMS			 102
#define GOST_F_GET_ENCRYPTION_PARAMS			 103
#define GOST_F_GOST2001_COMPUTE_PUBLIC			 104
#define GOST_F_GOST2001_DO_SIGN				 105
#define GOST_F_GOST2001_DO_VERIFY			 106
#define GOST_F_GOST2001_KEYGEN				 107
#define GOST_F_GOST89_GET_ASN1_PARAMETERS		 108
#define GOST_F_GOST89_SET_ASN1_PARAMETERS		 109
#define GOST_F_GOST94_COMPUTE_PUBLIC			 110
#define GOST_F_GOST_CIPHER_CTL				 111
#define GOST_F_GOST_DO_SIGN				 112
#define GOST_F_GOST_DO_VERIFY				 113
#define GOST_F_GOST_IMIT_CTRL				 114
#define GOST_F_GOST_IMIT_UPDATE				 115
#define GOST_F_PARAM_COPY_GOST01			 116
#define GOST_F_PARAM_COPY_GOST94			 117
#define GOST_F_PKEY_GOST01CP_DECRYPT			 118
#define GOST_F_PKEY_GOST01CP_ENCRYPT			 119
#define GOST_F_PKEY_GOST01CP_KEYGEN			 120
#define GOST_F_PKEY_GOST2001_DERIVE			 121
#define GOST_F_PKEY_GOST94CP_DECRYPT			 122
#define GOST_F_PKEY_GOST94CP_ENCRYPT			 123
#define GOST_F_PKEY_GOST94CP_KEYGEN			 124
#define GOST_F_PKEY_GOST_CTRL				 125
#define GOST_F_PKEY_GOST_CTRL01_STR			 126
#define GOST_F_PKEY_GOST_CTRL94_STR			 127
#define GOST_F_PKEY_GOST_MAC_CTRL			 128
#define GOST_F_PKEY_GOST_MAC_CTRL_STR			 129
#define GOST_F_PKEY_GOST_MAC_KEYGEN			 130
#define GOST_F_PRINT_GOST_01				 131
#define GOST_F_PRIV_DECODE_GOST				 132
#define GOST_F_PUB_DECODE_GOST01			 133
#define GOST_F_PUB_DECODE_GOST94			 134
#define GOST_F_PUB_ENCODE_GOST01			 135
#define GOST_F_UNPACK_CC_SIGNATURE			 136
#define GOST_F_UNPACK_CP_SIGNATURE			 137

/* Reason codes. */
#define GOST_R_BAD_KEY_PARAMETERS_FORMAT		 99
#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT		 100
#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY		 101
#define GOST_R_ERROR_COMPUTING_SHARED_KEY		 102
#define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO		 103
#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO		 104
#define GOST_R_INCOMPATIBLE_ALGORITHMS			 105
#define GOST_R_INVALID_CIPHER_PARAMS			 106
#define GOST_R_INVALID_CIPHER_PARAM_OID			 107
#define GOST_R_INVALID_DIGEST_TYPE			 108
#define GOST_R_INVALID_GOST94_PARMSET			 109
#define GOST_R_INVALID_IV_LENGTH			 110
#define GOST_R_INVALID_MAC_KEY_LENGTH			 111
#define GOST_R_INVALID_PARAMSET				 112
#define GOST_R_KEY_IS_NOT_INITALIZED			 113
#define GOST_R_KEY_IS_NOT_INITIALIZED			 114
#define GOST_R_KEY_PARAMETERS_MISSING			 115
#define GOST_R_MAC_KEY_NOT_SET				 116
#define GOST_R_MALLOC_FAILURE				 117
#define GOST_R_NO_MEMORY				 118
#define GOST_R_NO_PARAMETERS_SET			 119
#define GOST_R_NO_PEER_KEY				 120
#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR	 121
#define GOST_R_PUBLIC_KEY_UNDEFINED			 122
#define GOST_R_RANDOM_GENERATOR_ERROR			 123
#define GOST_R_RANDOM_GENERATOR_FAILURE			 124
#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED		 125
#define GOST_R_SIGNATURE_MISMATCH			 126
#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q		 127
#define GOST_R_UKM_NOT_SET				 128
#define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND		 129
#define GOST_R_UNSUPPORTED_PARAMETER_SET		 130

#ifdef  __cplusplus
}
#endif
#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/e_gost_err.proto
/* ====================================================================
 * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_GOST_ERR_H
#define HEADER_GOST_ERR_H

#define GOST_LIB_NAME "GOST engine"
#ifdef __cplusplus
 extern "C" {
#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost.ec
L GOST 			e_gost_err.h			e_gost_err.c
L NONE    		asymm.h    			NONE
L NONE    		md.h    			NONE
L NONE    		crypt.h    			NONE
L NONE			gostkeyx.h			NONE

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost2001.c
/**********************************************************************
 *                          gost2001.c                                *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *          Implementation of GOST R 34.10-2001      				  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include "gost_lcl.h"
#include "gost_params.h"
#include <string.h>
#include <openssl/rand.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include "e_gost_err.h"
#ifdef DEBUG_SIGN
extern 
void dump_signature(const char *message,const unsigned char *buffer,size_t len);
void dump_dsa_sig(const char *message, DSA_SIG *sig);
#else

#define dump_signature(a,b,c)
#define dump_dsa_sig(a,b)
#endif

/*
 * Fills EC_KEY structure hidden in the app_data field of DSA structure
 * with parameter information, extracted from parameter array in
 * params.c file.
 *
 * Also fils DSA->q field with copy of EC_GROUP order field to make
 * DSA_size function work
 */ 
int fill_GOST2001_params(EC_KEY *eckey, int nid)
	{
	R3410_2001_params *params = R3410_2001_paramset;
	EC_GROUP *grp=NULL;
	BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
	EC_POINT *P=NULL;
	BN_CTX *ctx=BN_CTX_new();
	int ok=0;
	
	BN_CTX_start(ctx);
	p=BN_CTX_get(ctx);
	a=BN_CTX_get(ctx);
	b=BN_CTX_get(ctx);
	x=BN_CTX_get(ctx);
	y=BN_CTX_get(ctx);
	q=BN_CTX_get(ctx);
	while (params->nid!=NID_undef && params->nid != nid) params++;
	if (params->nid == NID_undef)
		{
		GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
		goto err;
		}	
	BN_hex2bn(&p,params->p);
	BN_hex2bn(&a,params->a);
	BN_hex2bn(&b,params->b);
	
	grp = EC_GROUP_new_curve_GFp(p,a,b,ctx);

	P = EC_POINT_new(grp);

	BN_hex2bn(&x,params->x);
	BN_hex2bn(&y,params->y);
	EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx);
	BN_hex2bn(&q,params->q);
#ifdef DEBUG_KEYS
	fprintf(stderr,"Set params index %d oid %s\nq=",
		(params-R3410_2001_paramset),OBJ_nid2sn(params->nid));
	BN_print_fp(stderr,q);
	fprintf(stderr,"\n");
#endif	

	EC_GROUP_set_generator(grp,P,q,NULL);
	EC_GROUP_set_curve_name(grp,params->nid);

	EC_KEY_set_group(eckey,grp);
	ok=1;
	err:
	EC_POINT_free(P);
	EC_GROUP_free(grp);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return ok;
	}	


/*
 * Computes gost2001 signature as DSA_SIG structure 
 *
 *
 */ 
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
	{
	DSA_SIG *newsig = NULL;
	BIGNUM *md = hashsum2bn(dgst);
	BIGNUM *order = NULL;
	const EC_GROUP *group;
	const BIGNUM *priv_key;
	BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
	EC_POINT *C=NULL;
	BN_CTX *ctx = BN_CTX_new();	
	BN_CTX_start(ctx);
	OPENSSL_assert(dlen==32);
	newsig=DSA_SIG_new();
	if (!newsig) 
		{
		GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
		goto err;
		}	
	group = EC_KEY_get0_group(eckey);
	order=BN_CTX_get(ctx);
	EC_GROUP_get_order(group,order,ctx);
	priv_key = EC_KEY_get0_private_key(eckey);
	e = BN_CTX_get(ctx);
	BN_mod(e,md,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"digest as bignum=");
	BN_print_fp(stderr,md);
	fprintf(stderr,"\ndigest mod q=");
	BN_print_fp(stderr,e);
	fprintf(stderr,"\n");
#endif		
	if (BN_is_zero(e))
		{
		BN_one(e);
		}   
	k =BN_CTX_get(ctx);
	C=EC_POINT_new(group);
	do 
		{
		do 
			{
			if (!BN_rand_range(k,order)) 
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!X) X=BN_CTX_get(ctx);
			if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!r) r=BN_CTX_get(ctx);
			BN_nnmod(r,X,order,ctx);
			}
		while (BN_is_zero(r));
		/* s =  (r*priv_key+k*e) mod order */
		if (!tmp) tmp = BN_CTX_get(ctx);
		BN_mod_mul(tmp,priv_key,r,order,ctx);
		if (!tmp2) tmp2 = BN_CTX_get(ctx);
		BN_mod_mul(tmp2,k,e,order,ctx);
		if (!s) s=BN_CTX_get(ctx);
		BN_mod_add(s,tmp,tmp2,order,ctx);
		}
	while (BN_is_zero(s));	

	newsig->s=BN_dup(s);
	newsig->r=BN_dup(r);
	err:			
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	EC_POINT_free(C);
	BN_free(md);
	return newsig;
	}
/*
 * Verifies gost 2001 signature
 *
 */ 
int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
	DSA_SIG *sig, EC_KEY *ec)
	{
	BN_CTX *ctx=BN_CTX_new();
	const EC_GROUP *group = EC_KEY_get0_group(ec);
	BIGNUM *order;
	BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
	BIGNUM *X=NULL,*tmp=NULL;
	EC_POINT *C = NULL;
	const EC_POINT *pub_key=NULL;
	int ok=0;

	BN_CTX_start(ctx);
	order = BN_CTX_get(ctx);
	e = BN_CTX_get(ctx);
	z1 = BN_CTX_get(ctx);
	z2 = BN_CTX_get(ctx);
	tmp = BN_CTX_get(ctx);
	X= BN_CTX_get(ctx);	
	R=BN_CTX_get(ctx);
	v=BN_CTX_get(ctx);
	
	EC_GROUP_get_order(group,order,ctx);
	pub_key = EC_KEY_get0_public_key(ec);
	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
		(BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) 
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
		goto err;

		}
	md = hashsum2bn(dgst);

	BN_mod(e,md,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"digest as bignum: ");
	BN_print_fp(stderr,md);
	fprintf(stderr,"\ndigest mod q: ");
	BN_print_fp(stderr,e);
#endif	
	if (BN_is_zero(e)) BN_one(e);
	v=BN_mod_inverse(v,e,order,ctx);
	BN_mod_mul(z1,sig->s,v,order,ctx);
	BN_sub(tmp,order,sig->r);
	BN_mod_mul(z2,tmp,v,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"\nInverted digest value: ");
	BN_print_fp(stderr,v);
	fprintf(stderr,"\nz1: ");
	BN_print_fp(stderr,z1);
	fprintf(stderr,"\nz2: ");
	BN_print_fp(stderr,z2);
#endif	
	C = EC_POINT_new(group);
	if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) 
		{	
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
		goto err;
		}	
	if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) 
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
		goto err;
		}
	BN_mod(R,X,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"\nX=");
	BN_print_fp(stderr,X);
	fprintf(stderr,"\nX mod q=");
	BN_print_fp(stderr,R);
	fprintf(stderr,"\n");
#endif	
	if (BN_cmp(R,sig->r)!=0)
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
		}
	else
		{
		ok = 1;
		}
	err:
	EC_POINT_free(C);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	BN_free(md);
	return ok;
	}
/*
 * Computes GOST R 34.10-2001 public key
 *
 *
 */ 
int gost2001_compute_public(EC_KEY *ec) 
	{
	const EC_GROUP *group = EC_KEY_get0_group(ec);
	EC_POINT *pub_key=NULL;
	const BIGNUM *priv_key=NULL;
	BN_CTX *ctx=NULL;
	int ok=0;

	if (!group)
		{
		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
		return 0;
		}	
	ctx=BN_CTX_new();
	BN_CTX_start(ctx);
	if (!(priv_key=EC_KEY_get0_private_key(ec))) 
		{
		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
		goto err;
		}	

	pub_key = EC_POINT_new(group);
	if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx)) 
		{
		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
		goto err;
		}	
	if (!EC_KEY_set_public_key(ec,pub_key))
		{
		GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
		goto err;
		}	
	ok = 256;
	err:
	BN_CTX_end(ctx);
	EC_POINT_free(pub_key);
	BN_CTX_free(ctx);
	return ok;
	}
/*
 * 
 * Generates GOST R 34.10-2001 keypair
 *
 *
 */ 
int gost2001_keygen(EC_KEY *ec)
	{
	BIGNUM *order = BN_new(),*d=BN_new();
	const EC_GROUP *group = EC_KEY_get0_group(ec);
	EC_GROUP_get_order(group,order,NULL);
	
	do 
		{
		if (!BN_rand_range(d,order)) 
			{
			GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
			BN_free(d);
			BN_free(order);
			return 0;
			}	
		}
	while (BN_is_zero(d));
	EC_KEY_set_private_key(ec,d);
	BN_free(d);
	BN_free(order);
	return gost2001_compute_public(ec);
	}


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost2001_keyx.c
/**********************************************************************
 *                          gost_keyx.c                               *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *   VK0 34.10-2001 key exchange and GOST R 34.10-2001                *
 *   based PKCS7/SMIME support                                        *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <string.h>
#include <openssl/objects.h>
#include "gost89.h"
#include "gosthash.h"
#include "e_gost_err.h"
#include "gost_keywrap.h"
#include "gost_lcl.h"
#include "gost2001_keyx.h"



/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,const EC_POINT *pub_key,EC_KEY *priv_key,const unsigned char *ukm)
	{
	unsigned char ukm_be[8],databuf[64],hashbuf[64];
	BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
	const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
	EC_POINT *pnt=EC_POINT_new(EC_KEY_get0_group(priv_key));
	int i;
	gost_hash_ctx hash_ctx;
	BN_CTX *ctx = BN_CTX_new();

	for (i=0;i<8;i++)
		{
		ukm_be[7-i]=ukm[i];
		}
	BN_CTX_start(ctx);
	UKM=getbnfrombuf(ukm_be,8);
	p=BN_CTX_get(ctx);
	order = BN_CTX_get(ctx);
	X=BN_CTX_get(ctx);
	Y=BN_CTX_get(ctx);
	EC_GROUP_get_order(EC_KEY_get0_group(priv_key),order,ctx);
	BN_mod_mul(p,key,UKM,order,ctx);	
	EC_POINT_mul(EC_KEY_get0_group(priv_key),pnt,NULL,pub_key,p,ctx);
	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key),
		pnt,X,Y,ctx);
	/*Serialize elliptic curve point same way as we do it when saving
	 * key */
	store_bignum(Y,databuf,32);
	store_bignum(X,databuf+32,32);
 	/* And reverse byte order of whole buffer */
	for (i=0;i<64;i++)
		{
		hashbuf[63-i]=databuf[i];
		}
	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
	start_hash(&hash_ctx);
	hash_block(&hash_ctx,hashbuf,64);
	finish_hash(&hash_ctx,shared_key);
	done_gost_hash_ctx(&hash_ctx);
	BN_free(UKM);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	EC_POINT_free(pnt);
	return 32;
	}


/*
 * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001
 * algorithm
 */
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
	/* Public key of peer in the ctx field peerkey
	 * Our private key in the ctx pkey
	 * ukm is in the algorithm specific context data
	 */
	EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
	EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	
	if (!data->shared_ukm) {
		GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
		return 0;
	}	

	if (key == NULL) {
		*keylen = 32;
		return 32;
	}	
	
	*keylen=VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
		(EC_KEY *)EVP_PKEY_get0(my_key),data->shared_ukm);
	return 1;	
}




/*  
 * EVP_PKEY_METHOD callback encrypt  
 * Implementation of GOST2001 key transport, cryptocom variation 
 */
/* Generates ephemeral key based on pubk algorithm
 * computes shared key using VKO and returns filled up
 * GOST_KEY_TRANSPORT structure
 */

/*  
 * EVP_PKEY_METHOD callback encrypt  
 * Implementation of GOST2001 key transport, cryptopo variation 
 */

int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) 
	{
	GOST_KEY_TRANSPORT *gkt=NULL; 
	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
	const struct gost_cipher_info *param=get_encryption_params(NULL);
	unsigned char ukm[8], shared_key[32], crypted_key[44];
	int ret=0;
	int key_is_ephemeral=1;
	gost_ctx cctx;
	EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
	if (data->shared_ukm) 
		{
		memcpy(ukm, data->shared_ukm,8);
		} 
	else if (out) 
		{
		
		if (RAND_bytes(ukm,8)<=0)
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
				GOST_R_RANDOM_GENERATOR_FAILURE);
			return 0;
			}	
		}	
	/* Check for private key in the peer_key of context */	
	if (sec_key) 
		{
		key_is_ephemeral=0;
		if (!gost_get0_priv_key(sec_key)) 
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
			goto err;
			}	
		} 
	else 
		{
		key_is_ephemeral=1;
		if (out) 
			{
			sec_key = EVP_PKEY_new();
			EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
			EVP_PKEY_copy_parameters(sec_key,pubk);
			if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) 
				{
				goto err;
				}	
			}
		}
	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
		{
		param= gost_cipher_list+1;
		}	
    if (out) 
		{
		VKO_compute_key(shared_key,32,EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),EVP_PKEY_get0(sec_key),ukm);
		gost_init(&cctx,param->sblock);	
		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
		}
	gkt = GOST_KEY_TRANSPORT_new();
	if (!gkt)
		{
		goto err;
		}	
	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
			ukm,8))
		{
		goto err;
		}	
	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
		{
		goto err;
		}
	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
		{
		goto err;
		}
	if (key_is_ephemeral) {	
		if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
					GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
			goto err;
			}	
	}		
	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
	GOST_KEY_TRANSPORT_free(gkt);
	return ret;	
	err:		
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}
/*  
 * EVP_PKEY_METHOD callback decrypt  
 * Implementation of GOST2001 key transport, cryptopo variation 
 */
int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len)
	{
	const unsigned char *p = in;
	EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
	GOST_KEY_TRANSPORT *gkt = NULL;
	int ret=0;	
	unsigned char wrappedKey[44];
	unsigned char sharedKey[32];
	gost_ctx ctx;
	const struct gost_cipher_info *param=NULL;
	EVP_PKEY *eph_key=NULL;

	if (!key)
		{
		*key_len = 32;
		return 1;
		}	
	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
		in_len);
	if (!gkt)
		{
		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
		return -1;
		}	
    
	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
	if (!eph_key) {
		eph_key = EVP_PKEY_CTX_get0_peerkey(pctx);
		if (! eph_key) {
			GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
				GOST_R_NO_PEER_KEY);
			goto err;
		}
		/* Increment reference count of peer key */
		CRYPTO_add(&(eph_key->references),1 ,CRYPTO_LOCK_EVP_PKEY);
	}	
		
	param = get_encryption_params(gkt->key_agreement_info->cipher);
	gost_init(&ctx,param->sblock);	
	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
	OPENSSL_assert(gkt->key_info->imit->length==4);
	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
	VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(eph_key)),
		EVP_PKEY_get0(priv),wrappedKey);
	if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key))
		{
		GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
			GOST_R_ERROR_COMPUTING_SHARED_KEY);
		goto err;
		}	
				
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	ret=1;
err:	
	return ret;
	}

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost2001_keyx.h
GOST_KEY_TRANSPORT *
make_rfc4490_keytransport_2001(EVP_PKEY *pubk, BIGNUM *eph_key,
                               const unsigned char *key, size_t keylen,
                               unsigned char *ukm, size_t ukm_len);

int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,
                                    GOST_KEY_TRANSPORT *gkt,
                                    unsigned char *key_buf,
                                    int key_buf_len) ;


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost89.c
/**********************************************************************
 *                        gost89.c                                    *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *          Implementation of GOST 28147-89 encryption algorithm      *
 *            No OpenSSL libraries required to compile and use        *
 *                              this code                             *
 **********************************************************************/ 
#include <string.h>
#include "gost89.h"
/* Substitution blocks from RFC 4357 
   
   Note: our implementation of gost 28147-89 algorithm 
   uses S-box matrix rotated 90 degrees counterclockwise, relative to 
   examples given in RFC.
  

*/

/* Substitution blocks from test examples for GOST R 34.11-94*/
gost_subst_block GostR3411_94_TestParamSet = {
	{0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC},
	{0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC},
	{0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE},
	{0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2},
	{0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3},
	{0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
	{0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9},
	{0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3}
	};  
/* Substitution blocks for hash function 1.2.643.2.9.1.6.1  */
gost_subst_block GostR3411_94_CryptoProParamSet= {
	{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
	{0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
	{0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
	{0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
	{0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
	{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
	{0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
	{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
	} ;

/* Test paramset from GOST 28147 */
gost_subst_block Gost28147_TestParamSet =
	{
	{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
	{0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
	{0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
	{0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
	{0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
	{0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
	{0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
	{0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
	};




/* 1.2.643.2.2.31.1 */
gost_subst_block Gost28147_CryptoProParamSetA= {
	{0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
	{0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
	{0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
	{0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
	{0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
	{0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
	{0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
	{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
	};
/* 1.2.643.2.2.31.2 */
gost_subst_block Gost28147_CryptoProParamSetB= 
	{
	{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
	{0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
	{0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
	{0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
	{0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
	{0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
	{0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
	{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
	};
/* 1.2.643.2.2.31.3 */
gost_subst_block Gost28147_CryptoProParamSetC= 
	{
	{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
	{0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
	{0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
	{0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
	{0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
	{0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
	{0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
	{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
	};

/* 1.2.643.2.2.31.4 */ 
gost_subst_block Gost28147_CryptoProParamSetD=
	{
	{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
	{0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
	{0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
	{0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
	{0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
	{0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
	{0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
	{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
	};


const byte CryptoProKeyMeshingKey[]={
	0x69, 0x00, 0x72, 0x22,   0x64, 0xC9, 0x04, 0x23,
    0x8D, 0x3A, 0xDB, 0x96,   0x46, 0xE9, 0x2A, 0xC4,
    0x18, 0xFE, 0xAC, 0x94,   0x00, 0xED, 0x07, 0x12,
    0xC0, 0x86, 0xDC, 0xC2,   0xEF, 0x4C, 0xA9, 0x2B
	};	
/* Initialization of gost_ctx subst blocks*/
static void kboxinit(gost_ctx *c, const gost_subst_block *b)
	{ 
	int i; 
	
	for (i = 0; i < 256; i++)
		{
		c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24;
		c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16;
		c->k43[i] = (b->k4[i>>4] <<4  | b->k3 [i &15])<<8;
		c->k21[i] = b->k2[i>>4] <<4  | b->k1 [i &15];

		}
	}

/* Part of GOST 28147 algorithm moved into separate function */
static word32 f(gost_ctx *c,word32 x) 
	{
	x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| 
		c->k43[x>> 8 & 255] | c->k21[x & 255]; 
	/* Rotate left 11 bits */ 
	return x<<11 | x>>(32-11);
	}
/* Low-level encryption routine - encrypts one 64 bit block*/
void gostcrypt(gost_ctx *c, const byte *in, byte *out)
	{ 
	register word32 n1, n2; /* As named in the GOST */ 
	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
	/* Instead of swapping halves, swap names each round */ 
 	 
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
  
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
                               
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
                               
	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
 
	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24); 
	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
	} 
/* Low-level decryption routine. Decrypts one 64-bit block */
void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
	{ 
	register word32 n1, n2; /* As named in the GOST */ 
	n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); 
	n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); 
	
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
	
	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
	
	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
	
	n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
	n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
	n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
	n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);

	out[0] = (byte)(n2&0xff);  out[1] = (byte)((n2>>8)&0xff);
	out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
	out[4] = (byte)(n1&0xff);  out[5] = (byte)((n1>>8)&0xff);
	out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
	} 

/* Encrypts several blocks in ECB mode */
void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
	{ 
	int i; 
	for(i=0;i<blocks;i++)
		{ 
		gostcrypt(c,clear,cipher); 
		clear+=8;
		cipher+=8;
		}
	}
/* Decrypts several blocks in ECB mode */
void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
	{ 
	int i; 
	for(i=0;i<blocks;i++)
		{ 
		gostdecrypt(c,cipher,clear); 
		clear+=8; 
		cipher+=8;
		}
	}

/* Encrypts several full blocks in CFB mode using 8byte IV */
void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks)
	{
	byte cur_iv[8];
	byte gamma[8];
	int i,j;
	const byte *in;
	byte *out;
	memcpy(cur_iv,iv,8);
	for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8)
		{
		gostcrypt(ctx,cur_iv,gamma);
		for (j=0;j<8;j++)
			{
			cur_iv[j]=out[j]=in[j]^gamma[j];
			}
		}	
	}	
/* Decrypts several full blocks in CFB mode using 8byte IV */
void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,  int blocks)
	{
	byte cur_iv[8];
	byte gamma[8];
	int i,j;
	const byte *in;
	byte *out;
	memcpy(cur_iv,iv,8);
	for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8)
		{
		gostcrypt(ctx,cur_iv,gamma);
		for (j=0;j<8;j++)
			{
			out[j]=(cur_iv[j]=in[j])^gamma[j];
			}
		}	
	}	

/* Encrypts one block using specified key */
void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock) 
	{
	gost_key(c,key);
	gostcrypt(c,inblock,outblock);
	}

/* Set 256 bit  key into context */
void gost_key(gost_ctx *c, const byte *k) 
	{ 
	int i,j; 
	for(i=0,j=0;i<8;i++,j+=4)
		{
		c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
		}		
	} 

/* Retrieve 256-bit key from context */
void gost_get_key(gost_ctx *c, byte *k) 
	{
	int i,j; 
	for(i=0,j=0;i<8;i++,j+=4)
		{
		k[j]=(byte)(c->k[i]& 0xFF);
		k[j+1]=(byte)((c->k[i]>>8 )&0xFF);
		k[j+2]=(byte)((c->k[i]>>16) &0xFF);
		k[j+3]=(byte)((c->k[i]>>24) &0xFF);
		}		
	}

/* Initalize context. Provides default value for subst_block */
void gost_init(gost_ctx *c, const gost_subst_block *b)
	{ 	
	if(!b)
		{
		b=&GostR3411_94_TestParamSet;
		}	
	kboxinit(c,b); 
	}

/* Cleans up key from context */
void gost_destroy(gost_ctx *c)
	{ 
	int i; for(i=0;i<8;i++) c->k[i]=0; 
	} 

/* Compute GOST 28147 mac block 
 * 
 * Parameters
 *   gost_ctx *c - context initalized with substitution blocks and key
 *   buffer - 8-byte mac state buffer
 *   block 8-byte block to process.
 * */
void mac_block(gost_ctx *c,byte *buffer,const  byte *block)
	{
	register word32 n1, n2; /* As named in the GOST */ 
	int i;
	for (i=0; i<8; i++)
		{
		buffer[i]^=block[i];
		}	  
	n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); 
	n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); 
	/* Instead of swapping halves, swap names each round */ 
 	 
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); 
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); 
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); 
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); 
  
	n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
	n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
	n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
	n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);

	buffer[0] = (byte)(n1&0xff);  buffer[1] = (byte)((n1>>8)&0xff);
	buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24);
	buffer[4] = (byte)(n2&0xff);  buffer[5] = (byte)((n2>>8)&0xff);
	buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24);
	}

/* Get mac with specified number of bits from MAC state buffer */
void get_mac(byte *buffer,int nbits,byte *out)
	{
	int nbytes= nbits >> 3;
	int rembits = nbits & 7;
	int mask =rembits?((1<rembits)-1):0;
	int i;
	for (i=0;i<nbytes;i++) out[i]=buffer[i];
	if (rembits) out[i]=buffer[i]&mask;
	}	

/* Compute mac of specified length (in bits) from data. 
 * Context should be initialized with key and subst blocks */
int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
	unsigned int data_len,unsigned char *mac) 
	{
	byte buffer[8]={0,0,0,0,0,0,0,0};
	byte buf2[8];
	unsigned int i;
	for (i=0;i+8<=data_len;i+=8) 
		mac_block(ctx,buffer,data+i);
	if (i<data_len)
		{
		memset(buf2,0,8);
		memcpy(buf2,data+i,data_len-i);
		mac_block(ctx,buffer,buf2);
		}	
	get_mac(buffer,mac_len,mac);
	return 1;
	}

/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data,
	unsigned int data_len,unsigned char *mac) 
	{
	byte buffer[8];
	byte buf2[8];
	unsigned int i;
	memcpy (buffer,iv,8);
	for (i=0;i+8<=data_len;i+=8) 
		mac_block(ctx,buffer,data+i);
	if (i<data_len)
		{
		memset(buf2,0,8);
		memcpy(buf2,data+i,data_len-i);
		mac_block(ctx,buffer,buf2);
		}	
	get_mac(buffer,mac_len,mac);
	return 1;
	}

/* Implements key meshing algorithm by modifing ctx and IV in place */
void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv)
	{
	unsigned char newkey[32],newiv[8];
	/* Set static keymeshing key */
	/* "Decrypt" key with keymeshing key */
	gost_dec(ctx,CryptoProKeyMeshingKey,newkey,4);
	/* set new key */
	gost_key(ctx,newkey);
	/* Encrypt iv with new key */
	gostcrypt(ctx,iv,newiv);
	memcpy(iv,newiv,8);
	}

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost89.h
/**********************************************************************
 *                        gost89.h                                    *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *     This file is distributed under the same license as OpenSSL     *
 *                                                                    *
 *          Declarations for GOST 28147-89 encryption algorithm       *
 *            No OpenSSL libraries required to compile and use        *
 *                       this code                                    *
 **********************************************************************/            
#ifndef GOST89_H
#define GOST89_H

/* Typedef for unsigned 32-bit integer */
#if __LONG_MAX__ > 2147483647L 
typedef unsigned int u4; 
#else 
typedef unsigned long u4; 
#endif 
/* Typedef for unsigned 8-bit integer */
typedef unsigned char byte; 

/* Internal representation of GOST substitution blocks */
typedef struct {
		byte k8[16];
		byte k7[16];
		byte k6[16];
		byte k5[16];
		byte k4[16];
		byte k3[16];
		byte k2[16];
		byte k1[16];
} gost_subst_block;		


/* Cipher context includes key and preprocessed  substitution block */
typedef struct { 
		u4 k[8]; 
		/* Constant s-boxes -- set up in gost_init(). */ 
		u4 k87[256],k65[256],k43[256],k21[256]; 
} gost_ctx; 
/* Note: encrypt and decrypt expect full blocks--padding blocks is 
         caller's responsibility. All bulk encryption is done in 
		 ECB mode by these calls. Other modes may be added easily 
		 enough.                                            */
/* Encrypt several full blocks in ECB mode */
void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks); 
/* Decrypt several full blocks in ECB mode */
void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks); 
/* Encrypts several full blocks in CFB mode using 8byte IV */
void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher,int  blocks);
/* Decrypts several full blocks in CFB mode using 8byte IV */
void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,int  blocks);

/* Encrypt one  block */
void gostcrypt(gost_ctx *c, const byte *in, byte *out);
/* Decrypt one  block */
void gostdecrypt(gost_ctx *c, const byte *in,byte *out);
/* Set key into context */
void gost_key(gost_ctx *ctx, const byte *key); 
/* Get key from context */
void gost_get_key(gost_ctx *ctx, byte *key);
/* Set S-blocks into context */
void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block); 
/* Clean up context */
void gost_destroy(gost_ctx *ctx);
/* Intermediate function used for calculate hash */
void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock);
/* Compute MAC of given length in bits from data */
int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data,
		unsigned int data_len,unsigned char *hmac) ;
/* Compute MAC of given length in bits from data, using non-zero 8-byte
 * IV (non-standard, for use in CryptoPro key transport only */
int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data,
		unsigned int data_len,unsigned char *hmac) ;
/* Perform one step of MAC calculation like gostcrypt */
void mac_block(gost_ctx *c,byte *buffer,const  byte *block); 
/* Extracts MAC value from mac state buffer */
void get_mac(byte *buffer,int nbits,byte *out);
/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/
void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv);
/* Parameter sets specified in RFC 4357 */
extern gost_subst_block GostR3411_94_TestParamSet;
extern gost_subst_block GostR3411_94_CryptoProParamSet;
extern gost_subst_block Gost28147_TestParamSet;
extern gost_subst_block Gost28147_CryptoProParamSetA;
extern gost_subst_block Gost28147_CryptoProParamSetB;
extern gost_subst_block Gost28147_CryptoProParamSetC;
extern gost_subst_block Gost28147_CryptoProParamSetD;
extern const byte CryptoProKeyMeshingKey[]; 
#if __LONG_MAX__ > 2147483647L 
typedef unsigned int word32; 
#else 
typedef unsigned long word32; 
#endif 

#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost94_keyx.c
/**********************************************************************
 *                             gost94_keyx.c                          *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *     Implements generation and parsing of GOST_KEY_TRANSPORT for    *
 *     			GOST R 34.10-94 algorithms                            *
 *																	  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include <openssl/dh.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/objects.h>

#include "gost89.h"
#include "gosthash.h"
#include "e_gost_err.h"
#include "gost_keywrap.h"
#include "gost_lcl.h"
/* Common functions for both 94 and 2001 key exchange schemes */
/* Implementation of the Diffi-Hellman key agreement scheme based on
 * GOST-94 keys */

/* Computes Diffie-Hellman key and stores it into buffer in
 * little-endian byte order as expected by both versions of GOST 94
 * algorigthm
 */
static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) 
	{
	unsigned char be_key[128];
	int i,key_size;
	key_size=DH_compute_key(be_key,pub_key,dh);
	if (!key_size) return 0;
	memset(pair_key,0,128);
	for (i=0;i<key_size;i++)
		{
		pair_key[i]=be_key[key_size-1-i];
		}
	return key_size;	
	}	

/*
 * Computes 256 bit Key exchange key as specified in RFC 4357 
 */
static int make_cp_exchange_key(BIGNUM *priv_key,EVP_PKEY *pubk, unsigned char *shared_key)
	{
	unsigned char dh_key [128];
	int ret;
	gost_hash_ctx hash_ctx;
	DH *dh = DH_new();
	
	memset(dh_key,0,128);
	dh->g = BN_dup(pubk->pkey.dsa->g);
	dh->p = BN_dup(pubk->pkey.dsa->p);
	dh->priv_key = BN_dup(priv_key);
	ret=compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ;
	DH_free(dh);
	if (!ret)	return 0;
	init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
	start_hash(&hash_ctx);
	hash_block(&hash_ctx,dh_key,128);
	finish_hash(&hash_ctx,shared_key);
	done_gost_hash_ctx(&hash_ctx);
	return 1;
	}

/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */

int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen)
	{
		EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
		EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
		*keylen = 32;
		if (key == NULL) return 1;

		return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
	}

/* EVP_PKEY_METHOD callback encrypt for
 * GOST R 34.10-94 cryptopro modification
 */


int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) 
	{
	GOST_KEY_TRANSPORT *gkt=NULL;
	unsigned char shared_key[32], ukm[8],crypted_key[44];
	const struct gost_cipher_info *param=get_encryption_params(NULL);
	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	int size=-1;
	gost_ctx cctx;
	int key_is_ephemeral=1;
	EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);

	/* Do not use vizir cipher parameters with cryptopro */
	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
		{
		param= gost_cipher_list+1;
		}	

	if (mykey) 
		{
		/* If key already set, it is not ephemeral */
		key_is_ephemeral=0;
		if (!gost_get0_priv_key(mykey)) 
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
			goto err;
			}	
		} 
	else 
		{
		/* Otherwise generate ephemeral key */
		key_is_ephemeral = 1;
		if (out) 
			{
			mykey = EVP_PKEY_new();
			EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new());
			EVP_PKEY_copy_parameters(mykey,pubk);
			if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) 
				{
				goto err;
				}	
			}
		}	
	if (out)
		make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key);
	if (data->shared_ukm) 
		{
		memcpy(ukm,data->shared_ukm,8);
		}
	else if (out) 
		{	
		if (RAND_bytes(ukm,8)<=0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
					GOST_R_RANDOM_GENERATOR_FAILURE);
			goto err;
			}	
		}
		
	if (out) {
		gost_init(&cctx,param->sblock);
		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
	}	
	gkt = GOST_KEY_TRANSPORT_new();
	if (!gkt)
		{
		goto memerr;
		}	
	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
			ukm,8))
		{
		goto memerr;
		}	
	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
		{
		goto memerr;
		}
	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
		{
		goto memerr;
		}
	if (key_is_ephemeral) {	
	if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk))
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
		goto err;
		}
		if (out) EVP_PKEY_free(mykey);
	}	
	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
	*outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL);
	if (!size)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
		size=-1;
		}
	GOST_KEY_TRANSPORT_free(gkt);
	return 1;	
	memerr:
		if (key_is_ephemeral) {
			EVP_PKEY_free(mykey);
		}	
	GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
		GOST_R_MALLOC_FAILURE);
	err:		
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}

	
/* EVP_PLEY_METHOD callback decrypt for
 * GOST R 34.10-94 cryptopro modification
 */
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
	const unsigned char *p = in;
	GOST_KEY_TRANSPORT *gkt = NULL;
	unsigned char wrappedKey[44];
	unsigned char sharedKey[32];
	gost_ctx cctx;
	const struct gost_cipher_info *param=NULL;
	EVP_PKEY *eph_key=NULL;
	EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); 
	
	if (!key)
		{
		*key_len = 32;
		return 1;
		}	
	
	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
		in_len);
	if (!gkt)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
		return 0;
		}	
	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
	/* No ephemeral key in the structure. Check peer key in the context
	 */
	if (!eph_key) {
		eph_key = EVP_PKEY_CTX_get0_peerkey(ctx);
		if (! eph_key) {
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_NO_PEER_KEY);
			goto err;
		}
		/* Increment reference count of peer key */
		CRYPTO_add(&(eph_key->references),1 ,CRYPTO_LOCK_EVP_PKEY);
	}	


	param = get_encryption_params(gkt->key_agreement_info->cipher);
	gost_init(&cctx,param->sblock);	
	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
	memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
	memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
	OPENSSL_assert(gkt->key_info->imit->length==4);
	memcpy(wrappedKey+40,gkt->key_info->imit->data,4);	
	make_cp_exchange_key(gost_get0_priv_key(priv),eph_key,sharedKey);
	if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
			GOST_R_ERROR_COMPUTING_SHARED_KEY);
		goto err;
		}	
				
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return 1;
err:
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}	


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_ameth.c
/**********************************************************************
 *                          gost_ameth.c                              *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *       Implementation of RFC 4490/4491 ASN1 method                  *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include "gost_params.h"
#include "gost_lcl.h"
#include "e_gost_err.h"

int gost94_nid_by_params(DSA *p) 
	{
	R3410_params *gost_params;
	BIGNUM *q=BN_new();
	for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) 
		{
		BN_dec2bn(&q,gost_params->q);
		if (!BN_cmp(q,p->q)) 
			{
			BN_free(q);
			return gost_params->nid;
			}
		}	
	BN_free(q);
	return NID_undef;
	}

static ASN1_STRING  *encode_gost_algor_params(const EVP_PKEY *key)
	{
	ASN1_STRING *params = ASN1_STRING_new();
	GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
	int pkey_param_nid = NID_undef;
	int cipher_param_nid = NID_undef;
	if (!params || !gkp) 
		{
		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
			ERR_R_MALLOC_FAILURE);
		ASN1_STRING_free(params);
		params = NULL;
		goto err;
		}	
	switch (EVP_PKEY_base_id(key)) 
		{
		case NID_id_GostR3410_2001:
			pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key)));
			cipher_param_nid = get_encryption_params(NULL)->nid;
			break;
		case NID_id_GostR3410_94:
			pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
			if (pkey_param_nid == NID_undef) 
				{
				GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
					GOST_R_INVALID_GOST94_PARMSET);
				ASN1_STRING_free(params);
				params=NULL;
				goto err;
				}	
			cipher_param_nid = get_encryption_params(NULL)->nid;
			break;
		}	
	gkp->key_params = OBJ_nid2obj(pkey_param_nid);
	gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
	/*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/
	params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
	if (params->length <=0 ) 
		{
		GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
			ERR_R_MALLOC_FAILURE);
		ASN1_STRING_free(params);
		params = NULL;
		goto err;
		}
	params ->type = V_ASN1_SEQUENCE;
	err:
	GOST_KEY_PARAMS_free(gkp);
	return params;
	}

/* Parses GOST algorithm parameters from X509_ALGOR and
 * modifies pkey setting NID and parameters
 */
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) 
	{
	ASN1_OBJECT *palg_obj =NULL;
	int ptype = V_ASN1_UNDEF;
	int pkey_nid = NID_undef,param_nid = NID_undef;
        void *_pval;
	ASN1_STRING *pval = NULL;
	const unsigned char  *p;
	GOST_KEY_PARAMS *gkp = NULL;

	X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
        pval = _pval;
	if (ptype != V_ASN1_SEQUENCE) 
		{
		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
			GOST_R_BAD_KEY_PARAMETERS_FORMAT);
		return 0;
		}	
	p=pval->data;
	pkey_nid = OBJ_obj2nid(palg_obj);

	gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
	if (!gkp) 
		{
		GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
			GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
		return 0;
		}	
	param_nid = OBJ_obj2nid(gkp->key_params);
	GOST_KEY_PARAMS_free(gkp);
	EVP_PKEY_set_type(pkey,pkey_nid);
	switch (pkey_nid) 
		{
		case NID_id_GostR3410_94:
		{
		DSA *dsa= EVP_PKEY_get0(pkey);
		if (!dsa) 
			{
			dsa = DSA_new();
			if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
			}
		if (!fill_GOST94_params(dsa,param_nid)) return 0;
		break;
		}
		case NID_id_GostR3410_2001:
		{
		EC_KEY *ec = EVP_PKEY_get0(pkey);
		if (!ec) 
			{
			ec = EC_KEY_new();
			if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0;
			}
		if (!fill_GOST2001_params(ec,param_nid)) return 0;
		}
		}

	return 1;
	}

static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) 
	{
	switch (EVP_PKEY_base_id(pkey)) 
		{
		case NID_id_GostR3410_94:
		{
		DSA *dsa = EVP_PKEY_get0(pkey);
		if (!dsa) 
			{
			dsa = DSA_new();
			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
			}	
		dsa->priv_key = BN_dup(priv);
		if (!EVP_PKEY_missing_parameters(pkey)) 
			gost94_compute_public(dsa);
		break;
		}	
		case NID_id_GostR3410_2001:
		{
		EC_KEY *ec = EVP_PKEY_get0(pkey);
		if (!ec) 
			{
			ec = EC_KEY_new();
			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
			}	
		if (!EC_KEY_set_private_key(ec,priv)) return 0;
		if (!EVP_PKEY_missing_parameters(pkey)) 
			gost2001_compute_public(ec);
		break;
		}
		}
	return 1;		
	}
BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) 
	{
	switch (EVP_PKEY_base_id(pkey)) 
		{
		case NID_id_GostR3410_94:
		{
		DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
		if (!dsa) 
			{
			return NULL;
			}	
		if (!dsa->priv_key) return NULL;
		return dsa->priv_key;
		break;
		}	
		case NID_id_GostR3410_2001:
		{
		EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
		const BIGNUM* priv;
		if (!ec) 
			{
			return NULL;
			}	
		if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
		return (BIGNUM *)priv;
		break;
		}
		}
	return NULL;		
	}

static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
	long arg1, void *arg2)
	{
	switch (op)
		{
		case ASN1_PKEY_CTRL_PKCS7_SIGN:
			if (arg1 == 0) 
				{
				X509_ALGOR *alg1 = NULL, *alg2 = NULL;
				int nid = EVP_PKEY_base_id(pkey);
				PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2, 
					NULL, &alg1, &alg2);
				X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
					V_ASN1_NULL, 0);
				if (nid == NID_undef) 
					{
					return (-1);
					}
				X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
				}
			return 1;
		case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
			if (arg1 == 0)
				{
				X509_ALGOR *alg;
				ASN1_STRING * params = encode_gost_algor_params(pkey);
				if (!params) 
					{
					return -1;
					}
				PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
				X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
					V_ASN1_SEQUENCE, params);
				}
			return 1;
		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
			*(int *)arg2 = NID_id_GostR3411_94;
			return 2;
		}
	
	return -2;
	}
/*----------------------- free functions * ------------------------------*/
static void pkey_free_gost94(EVP_PKEY *key) 
	{
	if (key->pkey.dsa) 
		{
		DSA_free(key->pkey.dsa);
		}
	}

static void pkey_free_gost01(EVP_PKEY *key) 
	{
	if (key->pkey.ec) 
		{
		EC_KEY_free(key->pkey.ec);
		}
	}	

/* ------------------ private key functions  -----------------------------*/
static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) 
	{
	const unsigned char *pkey_buf = NULL,*p=NULL;
	int priv_len = 0;
	BIGNUM *pk_num=NULL;
	int ret =0;
	X509_ALGOR *palg =NULL;
	ASN1_OBJECT *palg_obj = NULL;
	ASN1_INTEGER *priv_key=NULL;

	if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) 
		return 0;
	p = pkey_buf;
	if (!decode_gost_algor_params(pk,palg)) 
		{
		return 0;
		}
	if (V_ASN1_OCTET_STRING == *p) 
		{
		/* New format - Little endian octet string */
		unsigned char rev_buf[32];
		int i;
		ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len);
		if (!s||s->length !=32) 
			{
			GOSTerr(GOST_F_PRIV_DECODE_GOST,
				EVP_R_DECODE_ERROR);
			return 0;	
			}
		for (i=0;i<32;i++)
			{
			rev_buf[31-i]=s->data[i];
			}
		ASN1_STRING_free(s);
		pk_num = getbnfrombuf(rev_buf,32);
		} 
	else
		{
		priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
		if (!priv_key) return 0;
		ret= ((pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
		ASN1_INTEGER_free(priv_key);
		if (!ret)
			{
			GOSTerr(GOST_F_PRIV_DECODE_GOST,
				EVP_R_DECODE_ERROR);
			return 0;	
			}
		}

	ret= gost_set_priv_key(pk,pk_num);
	BN_free(pk_num);
	return ret;
	}

/* ----------------------------------------------------------------------*/
static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
	{
	ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
	ASN1_STRING *params = encode_gost_algor_params(pk);
	unsigned char *priv_buf = NULL;
	int priv_len;

	ASN1_INTEGER *asn1key=NULL;
	if (!params) 
		{
		return 0;
		}
	asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL);
	priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf);
	ASN1_INTEGER_free(asn1key);
	return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
		priv_buf,priv_len);
	}
/* --------- printing keys --------------------------------*/
static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx, int type) 
	{
	int param_nid = NID_undef;

	if (type == 2) 
		{
		BIGNUM *key;

		if (!BIO_indent(out,indent,128)) return 0;
		BIO_printf(out,"Private key: ");
		key = gost_get0_priv_key(pkey);
		if (!key) 
			BIO_printf(out,"<undefined>");
		else 
			BN_print(out,key);
		BIO_printf(out,"\n");
		}
	if (type >= 1)
		{
		BIGNUM *pubkey;
		
		pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
		BIO_indent(out,indent,128);
		BIO_printf(out,"Public key: ");
		BN_print(out,pubkey);
		BIO_printf(out,"\n");
	}	

	param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
	BIO_indent(out,indent,128);
	BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid));
	return 1;
}

static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx) 
	{
	return print_gost_94(out, pkey, indent, pctx,0);
	}

static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx)
	{
	return print_gost_94(out,pkey, indent, pctx,1);
	}
static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx) 
	{
	return print_gost_94(out,pkey,indent,pctx,2);
	}

static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx, int type)
	{
	int param_nid = NID_undef;
	if (type == 2) 
		{
		BIGNUM *key;

		if (!BIO_indent(out,indent,128)) return 0;
		BIO_printf(out,"Private key: ");
		key = gost_get0_priv_key(pkey);
		if (!key) 
			BIO_printf(out,"<undefined)");
		else 
			BN_print(out,key);
		BIO_printf(out,"\n");
		}
	if (type >=1) 
		{
		BN_CTX *ctx = BN_CTX_new();
		BIGNUM *X,*Y;
		const EC_POINT *pubkey;
		const EC_GROUP *group;
		BN_CTX_start(ctx);
		X= BN_CTX_get(ctx);
		Y=BN_CTX_get(ctx);
		if (!ctx) 
			{
			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE);
			return 0;
			}
		pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
		group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
		if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx)) 
			{
			GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB);
			BN_CTX_free(ctx);
			return 0;
			}
		if (!BIO_indent(out,indent,128)) return 0;
		BIO_printf(out,"Public key:\n");
		if (!BIO_indent(out,indent+3,128)) return 0;
		BIO_printf(out,"X:");
		BN_print(out,X);
		BIO_printf(out,"\n");
		BIO_indent(out,indent+3,128);
		BIO_printf(out,"Y:");
		BN_print(out,Y);
		BIO_printf(out,"\n");
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}

	param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
	if (!BIO_indent(out,indent,128)) return 0;
	BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid));
	return 1;
}
static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx) 
	{	
	return print_gost_01(out,pkey,indent,pctx,0);
	}
static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx)
	{
	return print_gost_01(out,pkey, indent, pctx,1);
	}
static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent,
	ASN1_PCTX *pctx) 
	{
	return print_gost_01(out,pkey,indent,pctx,2);
	}
/* ---------------------------------------------------------------------*/
static int param_missing_gost94(const EVP_PKEY *pk) 
	{
	const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
	if (!dsa) return 1;
	if (!dsa->q) return 1;
	return 0;
	}

static int param_missing_gost01(const EVP_PKEY *pk) 
	{
	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
	if (!ec) return 1;
	if (!EC_KEY_get0_group(ec)) return 1;
	return 0;
	}

static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) 
	{
	const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
	DSA *dto = EVP_PKEY_get0(to);
	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST94,
			GOST_R_INCOMPATIBLE_ALGORITHMS);
		return 0;
		}	
	if (!dfrom) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST94,
			GOST_R_KEY_PARAMETERS_MISSING);
		return 0;
		}	
	if (!dto) 
		{
		dto = DSA_new();
		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto);
		}	
#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);	
	COPYBIGNUM(dto,dfrom,p)
		COPYBIGNUM(dto,dfrom,q)
		COPYBIGNUM(dto,dfrom,g)

		if (dto->priv_key) 
			gost94_compute_public(dto);
	return 1;	
	}
static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 
	{
	EC_KEY *eto = EVP_PKEY_get0(to);
	const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
			GOST_R_INCOMPATIBLE_ALGORITHMS);
		return 0;
		}	
	if (!efrom) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
			GOST_R_KEY_PARAMETERS_MISSING);
		return 0;
		}	
	if (!eto) 
		{
		eto = EC_KEY_new();
		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
		}	
	EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
	if (EC_KEY_get0_private_key(eto)) 
		{
		gost2001_compute_public(eto);
		}
	return 1;
	}

static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) 
	{
	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
	if (!BN_cmp(da->q,db->q)) return 1;
	return 0;
	}

static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) 
	{
	if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))==
		EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b)))) 
		{
		return 1;
		}
	return 0;

	}

/* ---------- Public key functions * --------------------------------------*/
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
	{
	X509_ALGOR *palg = NULL;
	const unsigned char *pubkey_buf = NULL;
	unsigned char *databuf;
	ASN1_OBJECT *palgobj = NULL;
	int pub_len,i,j;
	DSA *dsa;
	ASN1_OCTET_STRING *octet= NULL;

	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
			&palg, pub)) return 0;
	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
	if (!decode_gost_algor_params(pk,palg)) return 0;
	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
	if (!octet) 
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
		return 0;
		}	
	databuf = OPENSSL_malloc(octet->length);
	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
		{
		databuf[j]=octet->data[i];
		}	
	dsa = EVP_PKEY_get0(pk);
	dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL);
	ASN1_OCTET_STRING_free(octet);
	OPENSSL_free(databuf);
	return 1;

	}

static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
	{
	ASN1_OBJECT *algobj = NULL;
	ASN1_OCTET_STRING *octet = NULL;
	void *pval = NULL;
	unsigned char *buf=NULL,*databuf,*sptr;
	int i,j,data_len,ret=0;

	int ptype = V_ASN1_UNDEF;
	DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
	if (pk->save_parameters) 
		{
		ASN1_STRING *params = encode_gost_algor_params(pk);
		pval = params;
		ptype = V_ASN1_SEQUENCE;
		}	
	data_len = BN_num_bytes(dsa->pub_key);
	databuf = OPENSSL_malloc(data_len);
	BN_bn2bin(dsa->pub_key,databuf);
	octet = ASN1_OCTET_STRING_new();
	ASN1_STRING_set(octet,NULL,data_len);
	sptr = ASN1_STRING_data(octet);
	for (i=0,j=data_len-1; i< data_len;i++,j--)
		{
		sptr[i]=databuf[j];
		}
	OPENSSL_free(databuf);
	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
	ASN1_BIT_STRING_free(octet);
	if (ret <0)  return 0;
	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
	}

static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
	{
	X509_ALGOR *palg = NULL;
	const unsigned char *pubkey_buf = NULL;
	unsigned char *databuf;
	ASN1_OBJECT *palgobj = NULL;
	int pub_len,i,j;
	EC_POINT *pub_key;
	BIGNUM *X,*Y;
	ASN1_OCTET_STRING *octet= NULL;
	int len;
	const EC_GROUP *group;

	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
			&palg, pub)) return 0;
	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
	if (!decode_gost_algor_params(pk,palg)) return 0;
	group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
	if (!octet) 
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
		return 0;
		}	
	databuf = OPENSSL_malloc(octet->length);
	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
		{
		databuf[j]=octet->data[i];
		}
	len=octet->length/2;
	ASN1_OCTET_STRING_free(octet);	
	
	Y= getbnfrombuf(databuf,len);
	X= getbnfrombuf(databuf+len,len);
	OPENSSL_free(databuf);
	pub_key = EC_POINT_new(group);
	if (!EC_POINT_set_affine_coordinates_GFp(group
			,pub_key,X,Y,NULL))
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,
			ERR_R_EC_LIB);
		EC_POINT_free(pub_key);
		BN_free(X);
		BN_free(Y);
		return 0;
		}	
	BN_free(X);
	BN_free(Y);
	if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key))
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,
			ERR_R_EC_LIB);
		EC_POINT_free(pub_key);
		return 0;
		}	
	EC_POINT_free(pub_key);
	return 1;

	}

static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
	{
	ASN1_OBJECT *algobj = NULL;
	ASN1_OCTET_STRING *octet = NULL;
	void *pval = NULL;
	unsigned char *buf=NULL,*databuf,*sptr;
	int i,j,data_len,ret=0;
	const EC_POINT *pub_key;
	BIGNUM *X,*Y,*order;
	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
	int ptype = V_ASN1_UNDEF;

	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
	if (pk->save_parameters) 
		{
		ASN1_STRING *params = encode_gost_algor_params(pk);
		pval = params;
		ptype = V_ASN1_SEQUENCE;
		}
	order = BN_new();
	EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
	pub_key=EC_KEY_get0_public_key(ec);
	if (!pub_key) 
		{
		GOSTerr(GOST_F_PUB_ENCODE_GOST01,
			GOST_R_PUBLIC_KEY_UNDEFINED);
		return 0;
		}	
	X=BN_new();
	Y=BN_new();
	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
		pub_key,X,Y,NULL);
	data_len = 2*BN_num_bytes(order);
	BN_free(order);
	databuf = OPENSSL_malloc(data_len);
	memset(databuf,0,data_len);
	
	store_bignum(X,databuf+data_len/2,data_len/2);
	store_bignum(Y,databuf,data_len/2);

	BN_free(X);
	BN_free(Y);
	octet = ASN1_OCTET_STRING_new();
	ASN1_STRING_set(octet,NULL,data_len);
	sptr=ASN1_STRING_data(octet);
    for (i=0,j=data_len-1;i<data_len;i++,j--) 
		{
        sptr[i]=databuf[j];
		}
    OPENSSL_free(databuf);
	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
	ASN1_BIT_STRING_free(octet);
	if (ret <0)  return 0;
	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
	}

static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
	{
	const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
	const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
	if (da && db && da->pub_key && db->pub_key
		&& !BN_cmp(da->pub_key,db->pub_key)) 
		{
		return 1;
		}		
	return 0;
	}

static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
	{
	const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
	const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
	const EC_POINT *ka,*kb;
	int ret=0;
	if (!ea || !eb) return 0;
	ka = EC_KEY_get0_public_key(ea);
	kb = EC_KEY_get0_public_key(eb);
	if (!ka || !kb) return 0;
	ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
	return ret;
	}




static int pkey_size_gost(const EVP_PKEY *pk)
	{
	return 64;
	}

static int pkey_bits_gost(const EVP_PKEY *pk)
	{
	return 256;
	}
/*------------------------ ASN1 METHOD for GOST MAC  -------------------*/
static void  mackey_free_gost(EVP_PKEY *pk)
	{
		if (pk->pkey.ptr) {
			OPENSSL_free(pk->pkey.ptr);
		}	
	}
static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
	switch (op)
		{
		case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
			*(int *)arg2 = NID_undef;
			return 2;
		}
	return -2;
}	
/* ----------------------------------------------------------------------*/
int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) 
	{
	*ameth =	EVP_PKEY_asn1_new(nid, 
		ASN1_PKEY_SIGPARAM_NULL, pemstr, info); 
	if (!*ameth) return 0;
	switch (nid) 
		{
		case NID_id_GostR3410_94:
			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
			EVP_PKEY_asn1_set_private (*ameth, 
				priv_decode_gost, priv_encode_gost, 
				priv_print_gost94);

			EVP_PKEY_asn1_set_param (*ameth, 0, 0,
				param_missing_gost94, param_copy_gost94, 
				param_cmp_gost94,param_print_gost94 );
			EVP_PKEY_asn1_set_public (*ameth,
				pub_decode_gost94, pub_encode_gost94,
				pub_cmp_gost94, pub_print_gost94,
				pkey_size_gost, pkey_bits_gost);
	
			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
			break;
		case NID_id_GostR3410_2001:
			EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01);
			EVP_PKEY_asn1_set_private (*ameth, 
				priv_decode_gost, priv_encode_gost, 
				priv_print_gost01);

			EVP_PKEY_asn1_set_param (*ameth, 0, 0,
				param_missing_gost01, param_copy_gost01, 
				param_cmp_gost01, param_print_gost01);
			EVP_PKEY_asn1_set_public (*ameth,
				pub_decode_gost01, pub_encode_gost01,
				pub_cmp_gost01, pub_print_gost01,
				pkey_size_gost, pkey_bits_gost);
	
			EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
			break;
		case NID_id_Gost28147_89_MAC:
			EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
			EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost);	
			break;
		}		
	return 1;
	}

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_asn1.c
/**********************************************************************
 *                          gost_keytrans.c                           *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *   ASN1 structure definition for GOST key transport                 *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "gost_lcl.h"

ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
	ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
	ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT)

IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)

ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = {
	ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
	ASN1_SIMPLE(GOST_KEY_INFO, imit,          ASN1_OCTET_STRING)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)

IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO)

ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = {
	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
	ASN1_IMP(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
	ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)

IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)

ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = {
	ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
	ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
	ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)

IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS)

ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = {
	ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
	ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)

IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)

ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /*FIXME incomplete*/
	ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)

IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_crypt.c
/**********************************************************************
 *                          gost_crypt.c                              *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *       OpenSSL interface to GOST 28147-89 cipher functions          *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include "gost89.h"
#include <openssl/rand.h>
#include "e_gost_err.h"
#include "gost_lcl.h"
static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 
	const unsigned char *iv, int enc);
static int	gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
	const unsigned char *iv, int enc);
/* Handles block of data in CFB mode */			
static int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
	const unsigned char *in, unsigned int inl);
/* Handles block of data in CNT mode */			
static int	gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
	const unsigned char *in, unsigned int inl);
/* Cleanup function */			
static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
/* set/get cipher parameters */
static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
/* Control function */
static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);

EVP_CIPHER cipher_gost = 
	{
	NID_id_Gost28147_89,
	1,/*block_size*/
	32,/*key_size*/
	8,/*iv_len - ñèíõðîïîñûëêà*/
	EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
	gost_cipher_init,
	gost_cipher_do_cfb,
	gost_cipher_cleanup,
	sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
	gost89_set_asn1_parameters,
	gost89_get_asn1_parameters,
	gost_cipher_ctl,
	NULL,
	};

EVP_CIPHER cipher_gost_cpacnt = 
	{
	NID_gost89_cnt,
	1,/*block_size*/
	32,/*key_size*/
	8,/*iv_len - ñèíõðîïîñûëêà*/
	EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
	EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
	gost_cipher_init_cpa,
	gost_cipher_do_cnt,
	gost_cipher_cleanup,
	sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
	gost89_set_asn1_parameters,
	gost89_get_asn1_parameters,
	gost_cipher_ctl,
	NULL,
	};

/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
/* Init functions which set specific parameters */
static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
/* process block of data */
static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
/* Return computed value */
static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md);
/* Copies context */
static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
static int gost_imit_cleanup(EVP_MD_CTX *ctx);
/* Control function, knows how to set MAC key.*/
static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);

EVP_MD imit_gost_cpa =
	{
	NID_id_Gost28147_89_MAC,
	NID_undef,
	4,
	0,
	gost_imit_init_cpa,
	gost_imit_update,
	gost_imit_final,
	gost_imit_copy,
	gost_imit_cleanup,
	NULL,
	NULL,
	{0,0,0,0,0},
	8,
	sizeof(struct ossl_gost_imit_ctx), 
	gost_imit_ctrl
	};

/* 
 * Correspondence between gost parameter OIDs and substitution blocks
 * NID field is filed by register_gost_NID function in engine.c
 * upon engine initialization
 */

struct gost_cipher_info gost_cipher_list[]=
	{
/* NID */  /* Subst block */          /* Key meshing*/
/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
	{NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
	{NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
	{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
	{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
	{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
	{NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1},
	{NID_undef,NULL,0}
	};	

/*  get encryption parameters from crypto network settings
	FIXME For now we use environment var CRYPT_PARAMS as place to 
	store these settings. Actually, it is better to use engine control   command, read from configuration file to set them */
const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
	{
	int nid;
	struct gost_cipher_info *param;
	if (!obj)
		{
		const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
		if (!params || !strlen(params)) 
			return &gost_cipher_list[0];

		nid = OBJ_txt2nid(params);
		if (nid == NID_undef)
			{
			GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
				GOST_R_INVALID_CIPHER_PARAM_OID);
			return NULL;
			}	
		}
	else
		{
		nid= OBJ_obj2nid(obj);
		}
	for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; 
		 param++);
	if (!param->sblock)
		{
		GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
		return NULL;
		}	
	return param;
	}

/* Sets cipher param from paramset NID. */
static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
	{
	const struct gost_cipher_info *param;
	param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
	if (!param) return 0;
	
	c->paramNID = param->nid;
	c->key_meshing=param->key_meshing;
	c->count=0;
	gost_init(&(c->cctx), param->sblock);
	return 1;
	}

/* Initializes EVP_CIPHER_CTX by paramset NID */
static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
	const unsigned char *iv, int enc, int paramNID,int mode)
	{
	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
	if (ctx->app_data == NULL)
		{
		if (!gost_cipher_set_param(c,paramNID)) return 0;
		ctx->app_data = ctx->cipher_data;
		}
	if (key) gost_key(&(c->cctx),key);
	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
	return 1;
	}	

static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
	const unsigned char *iv, int enc)
	{
	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
	c->key_meshing=1;
	c->count=0;
	if(key) gost_key(&(c->cctx),key);
	if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
	memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
	return 1;
	}

/* Initializes EVP_CIPHER_CTX with default values */
int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
	const unsigned char *iv, int enc)
	{
	return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
	}	
/* Wrapper around gostcrypt function from gost89.c which perform
 * key meshing when nesseccary 
 */
static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
	{
	struct ossl_gost_cipher_ctx *c = ctx;
	if (c->count&&c->key_meshing && c->count%1024==0)
		{
		cryptopro_key_meshing(&(c->cctx),iv);
		}	
	gostcrypt(&(c->cctx),iv,buf);
	c->count+=8;
	}

static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
	{
	struct ossl_gost_cipher_ctx *c = ctx;
	word32 g,go;
	unsigned char buf1[8];
	if (c->count && c->key_meshing && c->count %1024 ==0)
		{
		cryptopro_key_meshing(&(c->cctx),iv);
		}
	if (c->count==0)
		{
		gostcrypt(&(c->cctx),iv,buf1);
		}
	else
		{
		memcpy(buf1,iv,8);
		}	
	g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
	g += 0x01010101;
	buf1[0]=(unsigned char)(g&0xff);
	buf1[1]=(unsigned char)((g>>8)&0xff);
	buf1[2]=(unsigned char)((g>>16)&0xff);
	buf1[3]=(unsigned char)((g>>24)&0xff);
	g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24);
	go = g;
	g += 0x01010104;
	if (go > g)      /*  overflow*/
		g++;
	buf1[4]=(unsigned char)(g&0xff);
	buf1[5]=(unsigned char)((g>>8)&0xff);
	buf1[6]=(unsigned char)((g>>16)&0xff);
	buf1[7]=(unsigned char)((g>>24)&0xff);
	memcpy(iv,buf1,8);
	gostcrypt(&(c->cctx),buf1,buf);
	c->count +=8;
	}

/* GOST encryption in CFB mode */
int	gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
	const unsigned char *in, unsigned int inl)
	{
	const unsigned char *in_ptr=in;
	unsigned char *out_ptr=out;
	unsigned int i=0;
	unsigned int j=0;
/* process partial block if any */
	if (ctx->num) 
		{
		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
			{
			if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
			*out_ptr=ctx->buf[j]^(*in_ptr);
			if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
			}	
		if (j==8)
			{
			memcpy(ctx->iv,ctx->buf+8,8);
			ctx->num=0;
			}
		else
			{
			ctx->num=j;
			return 1;
			}	
		}	

	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
		{
		/*block cipher current iv */
		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
		/*xor next block of input text with it and output it*/
		/*output this block */
		if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
		for (j=0;j<8;j++)
			{
			out_ptr[j]=ctx->buf[j]^in_ptr[j];
			}	
		/* Encrypt */
		/* Next iv is next block of cipher text*/
		if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
		}
/* Process rest of buffer */
	if (i<inl)
		{
		gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
		if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
		for (j=0;i<inl;j++,i++)
			{
			out_ptr[j]=ctx->buf[j]^in_ptr[j];
			}			
		ctx->num = j;
		if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
		}
	else
		{
		ctx->num = 0;
		}	
	return 1;
	}

static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
	const unsigned char *in, unsigned int inl)
	{
	const unsigned char *in_ptr=in;
	unsigned char *out_ptr=out;
	unsigned int i=0;
	unsigned int j;
/* process partial block if any */
	if (ctx->num) 
		{
		for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) 
			{
			*out_ptr=ctx->buf[j]^(*in_ptr);
			}	
		if (j==8)
			{
			ctx->num=0;
			}
		else
			{
			ctx->num=j;
			return 1;
			}	
		}	

	for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
		{
		/*block cipher current iv */
		/* Encrypt */
		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
		/*xor next block of input text with it and output it*/
		/*output this block */
		for (j=0;j<8;j++)
			{
			out_ptr[j]=ctx->buf[j]^in_ptr[j];
			}	
		}
/* Process rest of buffer */
	if (i<inl)
		{
		gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
		for (j=0;i<inl;j++,i++)
			{
			out_ptr[j]=ctx->buf[j]^in_ptr[j];
			}			
		ctx->num = j;
		}
	else
		{
		ctx->num = 0;
		}	
	return 1;
	}

/* Cleaning up of EVP_CIPHER_CTX */
int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) 
	{
	gost_destroy((gost_ctx *)ctx->cipher_data);
	ctx->app_data = NULL;
	return 1;
	}	

/* Control function for gost cipher */
int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
	{
	switch (type)
		{
		case EVP_CTRL_RAND_KEY:
		{
		if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
			{
			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
			return -1;
			}
		break;
		}
		default:
			GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
			return -1;
		}
	return 1;
	}

/* Set cipher parameters from ASN1 structure */
int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
	{
	int len=0;
	unsigned char *buf=NULL;
	unsigned char *p=NULL;
	struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
	GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
	ASN1_OCTET_STRING *os = NULL;
	if (!gcp)
		{
		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
		return 0;
		}
	if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
		{
		GOST_CIPHER_PARAMS_free(gcp);
		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
		return 0;
		}
	ASN1_OBJECT_free(gcp->enc_param_set);
	gcp->enc_param_set = OBJ_nid2obj(c->paramNID);

	len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
	p = buf = (unsigned char*)OPENSSL_malloc(len);
	if (!buf)
		{
		GOST_CIPHER_PARAMS_free(gcp);
		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
		return 0;
		}
	i2d_GOST_CIPHER_PARAMS(gcp, &p);
	GOST_CIPHER_PARAMS_free(gcp);

	os = ASN1_OCTET_STRING_new();

	if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
		{
		OPENSSL_free(buf);
		GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
		return 0;
		}
	OPENSSL_free(buf);

	ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
	return 1;
	}

/* Store parameters into ASN1 structure */
int  gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
	{
	int ret = -1;
	int len; 
	GOST_CIPHER_PARAMS *gcp = NULL;
	unsigned char *p = params->value.sequence->data;
	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
		{
		return ret;
		}

	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
		params->value.sequence->length);

	len = gcp->iv->length;
	if (len != ctx->cipher->iv_len)
		{
		GOST_CIPHER_PARAMS_free(gcp);
		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
			GOST_R_INVALID_IV_LENGTH);
		return -1;
		}
	if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
		{
		GOST_CIPHER_PARAMS_free(gcp);
		return -1;
		}
	memcpy(ctx->oiv, gcp->iv->data, len);

	GOST_CIPHER_PARAMS_free(gcp);

	return 1;
	}


int gost_imit_init_cpa(EVP_MD_CTX *ctx)
	{
	struct ossl_gost_imit_ctx *c = ctx->md_data;
	memset(c->buffer,0,16);
	c->count = 0;
	c->bytes_left=0;
	c->key_meshing=1;
	gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
	return 1;
	}

static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
	{
	unsigned char buffer[8];
	/* We are using local buffer for iv because CryptoPro doesn't 
	 * interpret internal state of MAC algorithm as iv during keymeshing
	 * (but does initialize internal state from iv in key transport
	 */
	if (c->key_meshing&& c->count && c->count %1024 ==0)
		{
		cryptopro_key_meshing(&(c->cctx),buffer);
		}
	mac_block(&(c->cctx),c->buffer,data);
	c->count +=8;
	}

int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
	{
	struct ossl_gost_imit_ctx *c = ctx->md_data;
	const unsigned char *p = data;
	size_t bytes = count,i;
	if (!(c->key_set)) {
		GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
		return 0;
	}
	if (c->bytes_left)
		{
		for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
			{
			c->partial_block[i]=*p;
			}
		if (i==8)
			{
			mac_block_mesh(c,c->partial_block);
			}
		else
			{
			c->bytes_left = i;
			return 1;
			}		
		}	
	while (bytes>8)
		{
		mac_block_mesh(c,p);
		p+=8;
		bytes-=8;
		}
	if (bytes>0)
		{
		memcpy(c->partial_block,p,bytes);
		}	
	c->bytes_left=bytes;
	return 1;
	}

int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
	{
	struct ossl_gost_imit_ctx *c = ctx->md_data;
	if (!c->key_set) return 0;
	if (c->bytes_left)
		{
		int i;
		for (i=c->bytes_left;i<8;i++)
			{
			c->partial_block[i]=0;
			}
		mac_block_mesh(c,c->partial_block);
		}
	get_mac(c->buffer,32,md);
	return 1;
	}

int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
	{
	switch (type)
		{
		case EVP_MD_CTRL_KEY_LEN:
			*((unsigned int*)(ptr)) = 32;
			return 1;
		case EVP_MD_CTRL_SET_KEY:
		{
		if (arg!=32) {
			GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
			return 0;
		}

		gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr)	;
		((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
		return 1;

		}
		default:
			return 0;
		}		
	}

int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
	{
	memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
	return 1;
	}

/* Clean up imit ctx */
int gost_imit_cleanup(EVP_MD_CTX *ctx)
	{
	memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
	return 1;
	}


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_ctl.c
/**********************************************************************
 *                        gost_ctl.c                                  *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *       This file is distributed under the same license as OpenSSL   *
 *                                                                    *
 *        Implementation of control commands for GOST engine          *
 *            OpenSSL 0.9.9 libraries required                        *
 **********************************************************************/            
#include <stdlib.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/buffer.h>
#include "gost_lcl.h"

static char *gost_params[GOST_PARAM_MAX+1]={NULL};
static const char *gost_envnames[]={"CRYPT_PARAMS"};
const ENGINE_CMD_DEFN gost_cmds[]=
	{
/*	{ GOST_CTRL_RNG,
	"RNG",
	"Type of random number generator to use",
	ENGINE_CMD_FLAG_STRING
	},
	{ GOST_CTRL_RNG_PARAMS,
	"RNG_PARAMS",
	"Parameter for random number generator",
	ENGINE_CMD_FLAG_STRING
	},
*/	  { GOST_CTRL_CRYPT_PARAMS,
		"CRYPT_PARAMS",
		"OID of default GOST 28147-89 parameters",
		ENGINE_CMD_FLAG_STRING
			},
{0,NULL,NULL,0}
	};

void gost_param_free() 
{
	int i;
	for (i=0;i<=GOST_PARAM_MAX;i++) 
		if (gost_params[i]!=NULL) 
			{
			OPENSSL_free(gost_params[i]);
			gost_params[i]=NULL;
			}
		
}

int gost_control_func(ENGINE *e,int cmd,long i, void *p, void (*f)(void))
	{
	int param = cmd-ENGINE_CMD_BASE;
	int ret=0;
	if (param <0 || param >GOST_PARAM_MAX) return -1;
	ret=gost_set_default_param(param,p);
	return ret;
	}

const char *get_gost_engine_param(int param) 
	{
	char *tmp;
	if (param <0 || param >GOST_PARAM_MAX) return NULL;
	if (gost_params[param]!=NULL) 
		{
		return gost_params[param];
		}
	tmp = getenv(gost_envnames[param]);
	if (tmp) 
		{
		if (gost_params[param]) OPENSSL_free(gost_params[param]);
		gost_params[param] = BUF_strdup(tmp);
		return gost_params[param];
		}	
	return NULL;
	}	

int gost_set_default_param(int param, const char *value) 
	{
	const char *tmp;
	if (param <0 || param >GOST_PARAM_MAX) return 0;
	tmp = getenv(gost_envnames[param]);
	/* if there is value in the environment, use it, else -passed string * */
	if (!tmp) tmp=value;
	if (gost_params[param]) OPENSSL_free(gost_params[param]);
	gost_params[param] = BUF_strdup(tmp);

	return 1;
	}	

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_eng.c
/**********************************************************************
 *                          gost_eng.c                                *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *              Main file of GOST engine                              *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/obj_mac.h>
#include "e_gost_err.h"
#include "gost_lcl.h"
static const char *engine_gost_id = "gost";
static const char *engine_gost_name = "Reference implementation of GOST engine";

/* Symmetric cipher and digest function registrar */

static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
	const int **nids, int nid);

static int gost_digests(ENGINE *e, const EVP_MD **digest,
	const int **nids, int ind);

static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
	const int **nids, int nid);

static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
	const int **nids, int nid);

static int gost_cipher_nids[] =
    {NID_id_Gost28147_89, NID_gost89_cnt,0};

static int gost_digest_nids[] =
	{NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};

static int gost_pkey_meth_nids[] = 
	{NID_id_GostR3410_94,
	 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};

static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
	 *pmeth_GostR3410_2001 = NULL,
	*pmeth_Gost28147_MAC = NULL;

static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
	*ameth_GostR3410_2001 = NULL,
	*ameth_Gost28147_MAC = NULL;


static int gost_engine_init(ENGINE *e)
	{ 
	return 1;
	}

static int gost_engine_finish(ENGINE *e)
	{ 
	return 1;
	}

static int gost_engine_destroy(ENGINE *e)
	{ 
	gost_param_free();
	return 1;
	}

static int bind_gost (ENGINE *e,const char *id) 
	{
	int ret = 0;
	if (id && strcmp(id, engine_gost_id)) return 0;

	if (!ENGINE_set_id(e, engine_gost_id)) 
		{
		printf("ENGINE_set_id failed\n"); 
		goto end;
		}	
	if (!ENGINE_set_name(e, engine_gost_name)) 
		{
		printf("ENGINE_set_name failed\n");
		goto end;
		}	
	if (!ENGINE_set_digests(e, gost_digests)) 
		{
		printf("ENGINE_set_digests failed\n");
		goto end;
		}	
	if (! ENGINE_set_ciphers(e, gost_ciphers)) 
		{
		printf("ENGINE_set_ciphers failed\n");
		goto end;
		}	
	if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 
		{
		printf("ENGINE_set_pkey_meths failed\n");
		goto end;
		}	
	if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) 
		{
		printf("ENGINE_set_pkey_asn1_meths failed\n");
		goto end;
		}	
	/* Control function and commands */
	if (!ENGINE_set_cmd_defns(e,gost_cmds)) 
		{
		fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
		goto end;
		}	
	if (!ENGINE_set_ctrl_function(e,gost_control_func)) 
		{
		fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
		goto end;
		}	
	if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
		|| ! ENGINE_set_init_function(e,gost_engine_init)
		|| ! ENGINE_set_finish_function(e,gost_engine_finish))
		{
		goto end;
		}

	if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
	if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
	if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
		"GOST-MAC", "GOST 28147-89 MAC")) goto end;

	if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
	if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
	if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
		goto end;
	if ( ! ENGINE_register_ciphers(e)
		|| ! ENGINE_register_digests(e)
		|| ! ENGINE_register_pkey_meths(e)
		/* These two actually should go in LIST_ADD command */
		|| ! EVP_add_cipher(&cipher_gost)
		|| ! EVP_add_cipher(&cipher_gost_cpacnt)
		|| ! EVP_add_digest(&digest_gost)
		|| ! EVP_add_digest(&imit_gost_cpa)
		)
		{
		goto end;
		}

	ERR_load_GOST_strings();
	ret = 1;
	end:
	return ret;
	}	

#ifndef OPENSSL_NO_DYNAMIC_ENGINE
IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
IMPLEMENT_DYNAMIC_CHECK_FN()
#endif  /* ndef OPENSSL_NO_DYNAMIC_ENGINE */

static int gost_digests(ENGINE *e, const EVP_MD **digest,
	const int **nids, int nid)
	{ 
	int ok =1 ;
	if (!digest) 
		{
		*nids = gost_digest_nids;
		return 2; 
		}
	/*printf("Digest no %d requested\n",nid);*/
	if(nid == NID_id_GostR3411_94) 
		{
		*digest = &digest_gost;
		}
	else if (nid == NID_id_Gost28147_89_MAC) 
		{
		*digest = &imit_gost_cpa;
		}
	else
		{
		ok =0;
		*digest = NULL;
		}
	return ok;
	}	
	
static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
	const int **nids, int nid) 
	{
	int ok = 1;
	if (!cipher) 
		{
		*nids = gost_cipher_nids;
		return 2; /* two ciphers are supported */
		}

	if(nid == NID_id_Gost28147_89) 
		{
		*cipher = &cipher_gost;
		}
	else if  (nid == NID_gost89_cnt) 
		{
		*cipher = &cipher_gost_cpacnt;
		}
	else	
		{
		ok = 0;
		*cipher = NULL;
		}
	return ok;
	}	

static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
	const int **nids, int nid)
	{
	if (!pmeth) 
		{
		*nids = gost_pkey_meth_nids;
		return 3;
		}

	switch (nid) 
		{
		case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
		case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
		case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
		default:;
		}
	
	*pmeth = NULL;
	return 0;
	}

static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
	const int **nids, int nid)
	{
	if (!ameth) 
		{
		*nids = gost_pkey_meth_nids;
		return 3;
		}
	switch (nid) 
		{
		case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
		case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
		case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
	
		default:;
		}
	
	*ameth = NULL;
	return 0;
	}

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
static ENGINE *engine_gost(void)
	{	
	ENGINE *ret = ENGINE_new();
	if (!ret)
		return NULL;
	if (!bind_gost(ret,engine_gost_id)) 
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}
	
void ENGINE_load_gost(void)
	{
	ENGINE *toadd =engine_gost();
	if (!toadd) return;
	ENGINE_add(toadd);
	ENGINE_free(toadd);
	ERR_clear_error();
	}
#endif	


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_keywrap.c
/**********************************************************************
 *                          keywrap.c                                 *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 * Implementation of CryptoPro key wrap algorithm, as defined in      *
 *               RFC 4357 p 6.3 and 6.4                               *
 *                  Doesn't need OpenSSL                              *
 **********************************************************************/
#include <string.h>
#include "gost89.h"
#include "gost_keywrap.h"

/* Diversifies key using random UserKey Material
 * Implements RFC 4357 p 6.5 key diversification algorithm 
 * 
 * inputKey - 32byte key to be diversified
 * ukm - 8byte user key material
 * outputKey - 32byte buffer to store diversified key 
 *
 */
void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
	{

	u4 k,s1,s2;
	int i,j,mask;
	unsigned char S[8];
	memcpy(outputKey,inputKey,32);
	for (i=0;i<8;i++) 
		{
		/* Make array of integers from key */
		/* Compute IV S*/
		s1=0,s2=0;
		for (j=0,mask=1;j<8;j++,mask<<=1) 
			{
			k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
				(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
			if (mask & ukm[i]) 
				{
				s1+=k;
				}
			else 
				{
				s2+=k;
				}
			}
		S[0]=(unsigned char)(s1&0xff);
		S[1]=(unsigned char)((s1>>8)&0xff);
		S[2]=(unsigned char)((s1>>16)&0xff);
		S[3]=(unsigned char)((s1>>24)&0xff); 
		S[4]=(unsigned char)(s2&0xff);
		S[5]=(unsigned char)((s2>>8)&0xff);
		S[6]=(unsigned char)((s2>>16)&0xff);
		S[7]=(unsigned char)((s2>>24)&0xff); 
		gost_key(ctx,outputKey);
		gost_enc_cfb(ctx,S,outputKey,outputKey,4);
		}
	}	
	

/*
 * Wraps key using RFC 4357 6.3
 * ctx - gost encryption context, initialized with some S-boxes 
 * keyExchangeKey (KEK) 32-byte (256-bit) shared key
 * ukm - 8 byte (64 bit) user key material, 
 * sessionKey - 32-byte (256-bit) key to be wrapped
 * wrappedKey - 44-byte buffer to store wrapped key
 */ 

int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
	const	unsigned char *sessionKey, unsigned char *wrappedKey) 
	{
	unsigned char kek_ukm[32];
	keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
	gost_key(ctx,kek_ukm);
	memcpy(wrappedKey,ukm,8);
	gost_enc(ctx,sessionKey,wrappedKey+8,4);
	gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
	return 1;
	}
/*
 * Unwraps key using RFC 4357 6.4
 * ctx - gost encryption context, initialized with some S-boxes 
 * keyExchangeKey 32-byte shared key
 * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
 * 32 byte  encrypted key and 4 byte MAC  
 * 
 * sessionKEy - 32byte buffer to store sessionKey in
 * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
 */ 

int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
	const unsigned char *wrappedKey, unsigned char *sessionKey) 
	{
	unsigned char kek_ukm[32],cek_mac[4];
	keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey 
		/* First 8 bytes of wrapped Key is ukm */
		,kek_ukm);
	gost_key(ctx,kek_ukm);
	gost_dec(ctx,wrappedKey+8,sessionKey,4);
	gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
	if (memcmp(cek_mac,wrappedKey+40,4)) 
		{
		return 0;
		}		
	return 1;		
	}	



File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_keywrap.h
/**********************************************************************
 *                         gost_keywrap.h                             *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *       This file is distributed under the same license as OpenSSL   *
 *                                                                    *
 * Implementation of CryptoPro key wrap algorithm, as defined in      *
 * RFC 4357 p 6.3 and 6.4                                             *
 * Doesn't need OpenSSL                                               *
 **********************************************************************/
#ifndef GOST_KEYWRAP_H
#define GOST_KEYWRAP_H
#include <string.h>
#include "gost89.h"
/* Diversifies key using random UserKey Material
 * Implements RFC 4357 p 6.5 key diversification algorithm 
 * 
 * inputKey - 32byte key to be diversified
 * ukm - 8byte user key material
 * outputKey - 32byte buffer to store diversified key 
 *
 */
void keyDiversifyCryptoPro(gost_ctx *ctx,
	const unsigned char *inputKey, 
	const unsigned char *ukm, 
	unsigned char *outputKey);
/*
 * Wraps key using RFC 4357 6.3
 * ctx - gost encryption context, initialized with some S-boxes 
 * keyExchangeKey (KEK) 32-byte (256-bit) shared key
 * ukm - 8 byte (64 bit) user key material, 
 * sessionKey - 32-byte (256-bit) key to be wrapped
 * wrappedKey - 44-byte buffer to store wrapped key
 */ 

int keyWrapCryptoPro(gost_ctx *ctx,
	const unsigned char *keyExchangeKey, 
	const unsigned char *ukm,
	const	unsigned char *sessionKey, 
	unsigned char *wrappedKey) ;
/*
 * Unwraps key using RFC 4357 6.4
 * ctx - gost encryption context, initialized with some S-boxes 
 * keyExchangeKey 32-byte shared key
 * wrappedKey  44 byte key to be unwrapped (concatenation of 8-byte UKM,
 * 32 byte  encrypted key and 4 byte MAC  
 * 
 * sessionKEy - 32byte buffer to store sessionKey in
 * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
 */ 


int keyUnwrapCryptoPro(gost_ctx *ctx,
	const unsigned char *keyExchangeKey,
	const unsigned char *wrappedKey, 
	unsigned char *sessionKey) ;
#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_lcl.h
#ifndef GOST_TOOLS_H
#define GOST_TOOLS_H
/**********************************************************************
 *                        gost_lcl.h                                  *
 *             Copyright (c) 2006 Cryptocom LTD                       *
 *       This file is distributed under the same license as OpenSSL   *
 *                                                                    *
 *         Internal declarations  used in GOST engine                *
 *         OpenSSL 0.9.9 libraries required to compile and use        *
 *                              this code                             *
 **********************************************************************/ 
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/dsa.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/engine.h>
#include <openssl/ec.h>
#include "gost89.h"
#include "gosthash.h"
/* Control commands */
#define GOST_PARAM_CRYPT_PARAMS 0
#define GOST_PARAM_MAX 0
#define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS)

	extern const ENGINE_CMD_DEFN gost_cmds[];
	int gost_control_func(ENGINE *e,int cmd, long i, void *p, void (*f)(void));
	const char *get_gost_engine_param(int param);	
	int gost_set_default_param(int param, const char *value); 
	void gost_param_free(void);

/* method registration */

	int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info);
	int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags);

/* Gost-specific pmeth control-function parameters */
/* For GOST R34.10 parameters */
#define param_ctrl_string "paramset"
#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1)
/* For GOST 28147 MAC */
#define key_ctrl_string "key"
#define hexkey_ctrl_string "hexkey"
#define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3)
/* Pmeth internal representation */
	struct gost_pmeth_data {
   	    int sign_param_nid; /* Should be set whenever parameters are filled */
		EVP_MD *md;
		unsigned char *shared_ukm;
	};

	struct gost_mac_pmeth_data {
		int key_set;
		EVP_MD *md;
		unsigned char key[32];
	}	;
/* GOST-specific ASN1 structures */


typedef struct {
	ASN1_OCTET_STRING *encrypted_key;
	ASN1_OCTET_STRING *imit;
} GOST_KEY_INFO;

DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO)

typedef struct {
	ASN1_OBJECT *cipher;
	X509_PUBKEY *ephem_key;
	ASN1_OCTET_STRING *eph_iv;
} GOST_KEY_AGREEMENT_INFO;

DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
	
typedef struct {
	GOST_KEY_INFO *key_info;
	GOST_KEY_AGREEMENT_INFO *key_agreement_info;
} GOST_KEY_TRANSPORT;

DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)

typedef struct { /* FIXME incomplete */
	GOST_KEY_TRANSPORT *gkt;
} GOST_CLIENT_KEY_EXCHANGE_PARAMS;

DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
typedef struct {
	ASN1_OBJECT *key_params;
	ASN1_OBJECT *hash_params;
	ASN1_OBJECT *cipher_params;
} GOST_KEY_PARAMS;

DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS)

typedef struct {
	ASN1_OCTET_STRING *iv;
	ASN1_OBJECT *enc_param_set;
} GOST_CIPHER_PARAMS; 

DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
/*============== Message digest  and cipher related structures  ==========*/
	 /* Structure used as EVP_MD_CTX-md_data. 
	  * It allows to avoid storing in the md-data pointers to
	  * dynamically allocated memory.
	  *
	  * I cannot invent better way to avoid memory leaks, because
	  * openssl insist on invoking Init on Final-ed digests, and there
	  * is no reliable way to find out whether pointer in the passed
	  * md_data is valid or not.
	  * */
struct ossl_gost_digest_ctx {
	gost_hash_ctx dctx;
	gost_ctx cctx;
};	
/* EVP_MD structure for GOST R 34.11 */
extern EVP_MD digest_gost;
/* EVP_MD structure for GOST 28147 in MAC mode */
extern EVP_MD imit_gost_cpa;
/* Cipher context used for EVP_CIPHER operation */
struct ossl_gost_cipher_ctx {
	int paramNID;
	off_t count;
	int key_meshing;
	gost_ctx cctx;
};	
/* Structure to map parameter NID to S-block */
struct gost_cipher_info {
	int nid;
	gost_subst_block *sblock;
	int key_meshing;
};
/* Context for MAC */
struct ossl_gost_imit_ctx {
	gost_ctx cctx;
	unsigned char buffer[8];
	unsigned char partial_block[8];
	off_t count;
	int key_meshing;
	int bytes_left;
	int key_set;
};	
/* Table which maps parameter NID to S-blocks */
extern struct gost_cipher_info gost_cipher_list[];
/* Find encryption params from ASN1_OBJECT */
const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj);
/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */
extern EVP_CIPHER cipher_gost;
extern EVP_CIPHER cipher_gost_cpacnt;
#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3)
#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4)
/* EVP_PKEY_METHOD key encryption callbacks */
/* From gost94_keyx.c */
int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );

int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
/* From gost2001_keyx.c */
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len );

int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
/* derive functions */
/* From gost2001_keyx.c */
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
/* From gost94_keyx.c */
int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
/* Internal functions for signature algorithms */
int fill_GOST94_params(DSA *dsa,int nid);
int fill_GOST2001_params(EC_KEY *eckey, int nid);
int gost_sign_keygen(DSA *dsa) ;
int gost2001_keygen(EC_KEY *ec) ;

DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) ;
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey);

int gost_do_verify(const unsigned char *dgst, int dgst_len,
		DSA_SIG *sig, DSA *dsa) ;
int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
			DSA_SIG *sig, EC_KEY *ec);
int gost2001_compute_public(EC_KEY *ec) ;
int gost94_compute_public(DSA *dsa) ;
/*============== miscellaneous functions============================= */
/* from gost_sign.c */
/* Convert GOST R 34.11 hash sum to bignum according to standard */
BIGNUM *hashsum2bn(const unsigned char *dgst) ;
/* Store bignum in byte array of given length, prepending by zeros
 * if nesseccary */
int store_bignum(BIGNUM *bn, unsigned char *buf,int len);
/* Read bignum, which can have few MSB all-zeros    from buffer*/ 
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len);
/* Pack GOST R 34.10 signature according to CryptoPro rules */
int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen); 
/* Unpack GOST R 34.10 signature according to CryptoPro rules */
DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) ;
/* from ameth.c */
/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001  keys*/
/* Returns pointer into EVP_PKEY structure */
BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) ;
/* Find NID by GOST 94 parameters */
int gost94_nid_by_params(DSA *p) ;


#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_md.c
/**********************************************************************
 *                          md_gost.c                                 *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *       OpenSSL interface to GOST R 34.11-94 hash functions          *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include "gost_lcl.h"
#include "gosthash.h"
#include "e_gost_err.h"

/* implementation of GOST 34.11 hash function See gost_md.c*/
static int gost_digest_init(EVP_MD_CTX *ctx);
static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
static int gost_digest_cleanup(EVP_MD_CTX *ctx);

EVP_MD digest_gost=  
	{
	NID_id_GostR3411_94,
	NID_undef,
	32,
	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
	gost_digest_init,
	gost_digest_update,
	gost_digest_final,
	gost_digest_copy,
	gost_digest_cleanup,
	NULL,
	NULL,
	{NID_undef,NID_undef,0,0,0},
	32,
	sizeof(struct ossl_gost_digest_ctx ),
	NULL
	};

int gost_digest_init(EVP_MD_CTX *ctx) 
	{
	struct ossl_gost_digest_ctx *c = ctx->md_data;
	memset(&(c->dctx),0,sizeof(gost_hash_ctx));
	gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
	c->dctx.cipher_ctx= &(c->cctx);
	return 1;
	}

int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) 
	{
	return hash_block((gost_hash_ctx *)ctx->md_data,data,count);	
	}

int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
	{
	return finish_hash((gost_hash_ctx *)ctx->md_data,md);
	
	}

int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) 
	{
	struct ossl_gost_digest_ctx *md_ctx=to->md_data;
	if (to->md_data && from->md_data) {
		memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
		md_ctx->dctx.cipher_ctx=&(md_ctx->cctx);
	}
	return 1;
	}		

int gost_digest_cleanup(EVP_MD_CTX *ctx) 
	{
	if (ctx->md_data)
	memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
	return 1;
	}	

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_params.c
/**********************************************************************
 *                        params.c                                    *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357    *
 *         OpenSSL 0.9.9 libraries required to compile and use        *
 *                              this code                             *
 **********************************************************************/ 
#include "gost_params.h"
#include <openssl/objects.h>
/* Parameters of GOST 34.10 */

R3410_params R3410_paramset[]={
/* Paramset A */
{NID_id_GostR3410_94_CryptoPro_A_ParamSet,
"100997906755055304772081815535925224869"
"8410825720534578748235158755771479905292727772441528526992987964833"
"5669968284202797289605274717317548059048560713474685214192868091256"
"1502802222185647539190902656116367847270145019066794290930185446216"
"3997308722217328898303231940973554032134009725883228768509467406639"
"62",
"127021248288932417465907042777176443525"
"7876535089165358128175072657050312609850984974231883334834011809259"
"9999512098893413065920561499672425412104927434935707492031276956145"
"1689224110579311248812610229678534638401693520013288995000362260684"
"2227508135323070045173416336850045410625869714168836867788425378203"
"83",
"683631961449557007844441656118272528951"
"02170888761442055095051287550314083023"},
{NID_id_GostR3410_94_CryptoPro_B_ParamSet,
"429418261486158041438734477379555023926"
"7234596860714306679811299408947123142002706038521669956384871995765"
"7284814898909770759462613437669456364882730370838934791080835932647"
"9767786019153434744009610342313166725786869204821949328786333602033"
"8479709268434224762105576023501613261478065276102850944540333865234"
"1",
"139454871199115825601409655107690713107"
"0417070599280317977580014543757653577229840941243685222882398330391"
"1468164807668823692122073732267216074074777170091113455043205380464"
"7694904686120113087816240740184800477047157336662926249423571248823"
"9685422217536601433914856808405203368594584948031873412885804895251"
"63",
"79885141663410976897627118935756323747307951916507639758300472692338873533959"
},
{NID_id_GostR3410_94_CryptoPro_C_ParamSet,
"816552717970881016017893191415300348226"
"2544051353358162468249467681876621283478212884286545844013955142622"
"2087723485023722868022275009502224827866201744494021697716482008353"
"6398202298024892620480898699335508064332313529725332208819456895108"
"5155178100221003459370588291073071186553005962149936840737128710832"
"3",
"110624679233511963040518952417017040248"
"5862954819831383774196396298584395948970608956170224210628525560327"
"8638246716655439297654402921844747893079518669992827880792192992701"
"1428546551433875806377110443534293554066712653034996277099320715774"
"3542287621283671843703709141350171945045805050291770503634517804938"
"01",
"113468861199819350564868233378875198043"
"267947776488510997961231672532899549103"
},
{NID_id_GostR3410_94_CryptoPro_D_ParamSet,
"756976611021707301782128757801610628085"
"5283803109571158829574281419208532589041660017017859858216341400371"
"4687551412794400562878935266630754392677014598582103365983119173924"
"4732511225464712252386803315902707727668715343476086350472025298282"
"7271461690125050616858238384366331089777463541013033926723743254833"
"7",
"905457649621929965904290958774625315611"
"3056083907389766971404812524422262512556054474620855996091570786713"
"5849550236741915584185990627801066465809510095784713989819413820871"
"5964648914493053407920737078890520482730623038837767710173664838239"
"8574828787891286471201460474326612697849693665518073864436497893214"
"9",
"108988435796353506912374591498972192620"
"190487557619582334771735390599299211593"
},

{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
"1335318132727206734338595199483190012179423759678474868994823595993"
"6964252873471246159040332773182141032801252925387191478859899310331"
"0567744136196364803064721377826656898686468463277710150809401182608"
"7702016153249904683329312949209127762411378780302243557466062839716"
"59376426832674269780880061631528163475887",
"14201174159756348119636828602231808974327613839524373876287257344192"
"74593935127189736311660784676003608489466235676257952827747192122419"
"29071046134208380636394084512691828894000571524625445295769349356752"
"72895683154177544176313938445719175509684710784659566254794231229333"
"8483924514339614727760681880609734239",
"91771529896554605945588149018382750217296858393520724172743325725474"
"374979801"
},
{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
"8890864727828423151699995801875757891031463338652579140051973659"
"3048131440685857067369829407947744496306656291505503608252399443"
"7900272386749145996230867832228661977543992816745254823298629859"
"8753575466286051738837854736167685769017780335804511440773337196"
"2538423532919394477873664752824509986617878992443177",
"1028946126624994859676552074360530315217970499989304888248413244"
"8474923022758470167998871003604670704877377286176171227694098633"
"1539089568784129110109512690503345393869871295783467257264868341"
"7200196629860561193666752429682367397084815179752036423595736533"
"68957392061769855284593965042530895046088067160269433",
"9109671391802626916582318050603555673628769498182593088388796888"
"5281641595199"
},
{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
"4430618464297584182473135030809859326863990650118941756995270074"
"8609973181426950235239623239110557450826919295792878938752101867"
"7047181623251027516953100431855964837602657827828194249605561893"
"6965865325513137194483136247773653468410118796740709840825496997"
"9375560722345106704721086025979309968763193072908334",
"1246996366993477513607147265794064436203408861395055989217248455"
"7299870737698999651480662364723992859320868822848751165438350943"
"3276647222625940615560580450040947211826027729977563540237169063"
"0448079715771649447778447000597419032457722226253269698374446528"
"35352729304393746106576383349151001715930924115499549",
"6787876137336591234380295020065682527118129468050147943114675429"
"4748422492761"
},


{NID_undef,NULL, NULL, NULL}
};
	
R3410_2001_params R3410_2001_paramset[]={
	/* default_cc_sign01_param 1.2.643.2.9.1.8.1 */
	{NID_id_GostR3410_2001_ParamSet_cc,
	/* A */	
	"C0000000000000000000000000000000000000000000000000000000000003c4",
	/* B */
	"2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c",
	/* P */
	"C0000000000000000000000000000000000000000000000000000000000003C7",
	/* Q */
	"5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85",
	/* X */
	"2",
	/* Y */
	"a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"
	},
	/* 1.2.643.2.2.35.0 */
	{NID_id_GostR3410_2001_TestParamSet,
	"7",
	"5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E",
	"8000000000000000000000000000000000000000000000000000000000000431",
	"8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
	"2",
	"08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"
	},
	/*1.2.643.2.2.35.1*/
	{NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
	"a6",
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
	"1",
	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
	},
	/*1.2.643.2.2.35.2*/
	{NID_id_GostR3410_2001_CryptoPro_B_ParamSet,	
	"8000000000000000000000000000000000000000000000000000000000000C96",
	"3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B",
	"8000000000000000000000000000000000000000000000000000000000000C99",
	"800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
	"1",	
	"3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"
	},
	/*1.2.643.2.2.35.3*/
	{NID_id_GostR3410_2001_CryptoPro_C_ParamSet,
	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
	"805a",
	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
	"0",
	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
	},
	/*1.2.643.2.2.36.0*/
	{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
	"a6",
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
	"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
	"1",
	"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
	},
	/*1.2.643.2.2.36.1*/
	{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,
	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
	"805a",
	"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
	"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
	"0",
	"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
	},
	{ 0,NULL,NULL,NULL,NULL,NULL,NULL
	}
};

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_params.h
/**********************************************************************
 *                        gost_params.h                               *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *       This file is distributed under the same license as OpenSSL   *
 *                                                                    *
 *       Declaration of structures used to represent  GOST R 34.10    *
 * 	               parameter sets, defined in RFC 4357                *
 *         OpenSSL 0.9.9 libraries required to compile and use        *
 *                              this code                             *
 **********************************************************************/ 
#ifndef GOST_PARAMSET_H
#define GOST_PARAMSET_H
typedef struct R3410 {
		int nid;
		char *a;
		char *p;
		char *q;
} R3410_params;

extern R3410_params R3410_paramset[];

typedef struct R3410_2001 {
		int nid;
		char *a;
		char *b;
		char *p;
		char *q;
		char *x;
		char *y;
} R3410_2001_params;

extern R3410_2001_params R3410_2001_paramset[];

#endif

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_pmeth.c
/**********************************************************************
 *                          gost_pmeth.c                              *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *   Implementation of RFC 4357 (GOST R 34.10) Publick key method     *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/ec.h>
#include <openssl/x509v3.h> /*For string_to_hex */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gost_params.h"
#include "gost_lcl.h"
#include "e_gost_err.h"
/*-------init, cleanup, copy - uniform for all algs  ---------------*/
/* Allocates new gost_pmeth_data structure and assigns it as data */
static int pkey_gost_init(EVP_PKEY_CTX *ctx)
	{
	struct gost_pmeth_data *data;
	data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
	if (!data) return 0;
	memset(data,0,sizeof(struct gost_pmeth_data));
	EVP_PKEY_CTX_set_data(ctx,data);
	return 1;
	}

/* Copies contents of gost_pmeth_data structure */
static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
	{
	struct gost_pmeth_data *dst_data,*src_data;
	if (!pkey_gost_init(dst))
		{
		return 0;
		}
	src_data = EVP_PKEY_CTX_get_data(src);
	dst_data = EVP_PKEY_CTX_get_data(dst);
	*dst_data = *src_data;
	if (src_data -> shared_ukm) {
		dst_data->shared_ukm=NULL;
	}	
	return 1;
	}

/* Frees up gost_pmeth_data structure */
static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx)
	{
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	if (data->shared_ukm) OPENSSL_free(data->shared_ukm);
	OPENSSL_free(data);
	}	

/* --------------------- control functions  ------------------------------*/
static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
	{
	struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
	switch (type)
		{
		case EVP_PKEY_CTRL_MD:
		{
		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94)
			{
			GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
			return 0;
			}
		pctx->md = (EVP_MD *)p2;
		return 1;
		}
		break;

		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
			return 1;

		case EVP_PKEY_CTRL_GOST_PARAMSET:
			pctx->sign_param_nid = (int)p1;
			return 1;
		case EVP_PKEY_CTRL_SET_IV:
			pctx->shared_ukm=OPENSSL_malloc((int)p1);
			memcpy(pctx->shared_ukm,p2,(int) p1);
			return 1;
			
		}
	return -2;
	}


static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
	int param_nid=0;
	if(!strcmp(type, param_ctrl_string))
		{
		if (!value)
			{
			return 0;
			}
		if (strlen(value) == 1)
			{
			switch(toupper(value[0]))
				{
				case 'A':
					param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet;
					break;
				case 'D':
					param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet;
					break;
				default:
					return 0;
					break;
				}
			}
		else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
			{
			switch (toupper(value[1]))
				{
				case 'A':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet;
					break;
				default:
					return 0;
					break;
				}
			}
		else
			{
			R3410_params *p = R3410_paramset;
			param_nid = OBJ_txt2nid(value);
			if (param_nid == NID_undef)
				{
				return 0;
				}
			for (;p->nid != NID_undef;p++)
				{
				if (p->nid == param_nid) break;
				}
			if (p->nid == NID_undef)
				{
				GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
					GOST_R_INVALID_PARAMSET);
				return 0;
				}
			}

		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
			param_nid, NULL);
		}
	return -2;
	}

static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
	int param_nid=0;
	if(!strcmp(type, param_ctrl_string))
		{
		if (!value)
			{
			return 0;
			}
		if (strlen(value) == 1)
			{
			switch(toupper(value[0]))
				{
				case 'A':
					param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
					break;	
				case 'B':
					param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet;
					break;
				case 'C':
					param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet;
					break;
				case '0':
					param_nid = NID_id_GostR3410_2001_TestParamSet;
					break;
				default:
					return 0;
					break;
				}
			}
		else if ((strlen(value) == 2) && (toupper(value[0]) == 'X'))
			{
			switch (toupper(value[1]))
				{
				case 'A':
					param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
					break;
				case 'B':
					param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet;
					break;
				default:
					return 0;
					break;
				}
			}
		else
			{
			R3410_2001_params *p = R3410_2001_paramset;
			param_nid = OBJ_txt2nid(value);
			if (param_nid == NID_undef)
				{
				return 0;
				}
			for (;p->nid != NID_undef;p++)
				{
				if (p->nid == param_nid) break;
				}
			if (p->nid == NID_undef)
				{
				GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
					GOST_R_INVALID_PARAMSET);
				return 0;
				}
			}

		return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
			param_nid, NULL);
		}
	return -2;
	}

/* --------------------- key generation  --------------------------------*/


/* Generates Gost_R3410_94_cp key */
static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	DSA *dsa=NULL;
	if (data->sign_param_nid == NID_undef)
		{
			GOSTerr(GOST_F_PKEY_GOST94CP_KEYGEN,
				GOST_R_NO_PARAMETERS_SET);
			return 0;
		}
	dsa = DSA_new();
	if (!fill_GOST94_params(dsa,data->sign_param_nid))
		{
		DSA_free(dsa);
		return 0;
		}
	gost_sign_keygen(dsa);
	EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa);
	return 1;
	}

/* Generates GOST_R3410 2001 key and assigns it using specified type */
static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	EC_KEY *ec=NULL;
	if (data->sign_param_nid == NID_undef)
		{
			GOSTerr(GOST_F_PKEY_GOST01CP_KEYGEN,
				GOST_R_NO_PARAMETERS_SET);
			return 0;
		}
	ec = EC_KEY_new();
	if (!fill_GOST2001_params(ec,data->sign_param_nid))
		{
		EC_KEY_free(ec);
		return 0;
		}
	gost2001_keygen(ec);

	EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec);
	return 1;
	}



/* ----------- sign callbacks --------------------------------------*/

static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
	const unsigned char *tbs, size_t tbs_len)
	{
	DSA_SIG *unpacked_sig=NULL;
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
	if (!siglen) return 0;
	if (!sig)
		{
		*siglen= 64; /* better to check size of pkey->pkey.dsa-q */
		return 1;
		}	
	unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
	if (!unpacked_sig)
		{
		return 0;
		}
	return pack_sign_cp(unpacked_sig,32,sig,siglen);
	}

static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
	const unsigned char *tbs, size_t tbs_len)
	{
	DSA_SIG *unpacked_sig=NULL;
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
	if (!siglen) return 0;
	if (!sig)
		{
		*siglen= 64; /* better to check size of curve order*/
		return 1;
		}	
	unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
	if (!unpacked_sig)
		{
		return 0;
		}
	return pack_sign_cp(unpacked_sig,32,sig,siglen);
	}

/* ------------------- verify callbacks ---------------------------*/

static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
	{
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
	if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
	}


static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
	{
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
#ifdef DEBUG_SIGN	
	fprintf(stderr,"R=");
	BN_print_fp(stderr,s->r);
	fprintf(stderr,"\nS=");
	BN_print_fp(stderr,s->s);
	fprintf(stderr,"\n");
#endif	
	if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
	}

/* ------------- encrypt init -------------------------------------*/
/* Generates ephermeral key */
static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
	{
	return 1;
	}
/* --------------- Derive init ------------------------------------*/
static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
{
	return 1;
}
/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/
static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
	{
	struct gost_mac_pmeth_data *data;
	data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data));
	if (!data) return 0;
	memset(data,0,sizeof(struct gost_mac_pmeth_data));
	EVP_PKEY_CTX_set_data(ctx,data);
	return 1;
	}	
static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx)
	{
	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
	OPENSSL_free(data);
	}	
static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
	{
	struct gost_mac_pmeth_data *dst_data,*src_data;
	if (!pkey_gost_mac_init(dst))
		{
		return 0;
		}
	src_data = EVP_PKEY_CTX_get_data(src);
	dst_data = EVP_PKEY_CTX_get_data(dst);
	*dst_data = *src_data;
	return 1;
	}
	
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
	{
	struct gost_mac_pmeth_data *data =
(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);

	switch (type)
		{
		case EVP_PKEY_CTRL_MD:
		{
		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
			{
			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
			return 0;
			}
		data->md = (EVP_MD *)p2;
		return 1;
		}
		break;

		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
			return 1;
		case EVP_PKEY_CTRL_SET_MAC_KEY:
			if (p1 != 32) 
				{
				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
					GOST_R_INVALID_MAC_KEY_LENGTH);
				return 0;
				}

			memcpy(data->key,p2,32);
			data->key_set = 1;
			return 1;
		case EVP_PKEY_CTRL_DIGESTINIT:
			{ 
			EVP_MD_CTX *mctx = p2;
			void *key;
			if (!data->key_set)
				{ 
				EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
				if (!pkey) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				key = EVP_PKEY_get0(pkey);
				if (!key) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				} else {
				key = &(data->key);
				}
			return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
			}  
		}	
	return -2;
	}
static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
	const char *type, const char *value)
	{
	if (!strcmp(type, key_ctrl_string)) 
		{
		if (strlen(value)!=32) 
			{
			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
				GOST_R_INVALID_MAC_KEY_LENGTH);
			return 0;	
			}
		return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
			32,(char *)value);
		}
	if (!strcmp(type, hexkey_ctrl_string)) 
		{
			long keylen; int ret;
			unsigned char *keybuf=string_to_hex(value,&keylen);
			if (keylen != 32) 
				{
				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
					GOST_R_INVALID_MAC_KEY_LENGTH);
				return 0;	
				}
			ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY,
				32,keybuf);
			OPENSSL_free(keybuf);
			return ret;
	
		}
	return -2;
	}	

static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
		struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
		unsigned char *keydata;
		if (!data->key_set) 
		{
			GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET);
			return 0;
		}
		keydata = OPENSSL_malloc(32);
		memcpy(keydata,data->key,32);
		EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata);
		return 1;
	}

static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
	{
	return 1;
}

static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
	{
		unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(int)!=sizeof(size_t)*/
		int ret;
		if (!sig) 
			{
			*siglen = 4;
			return 1;
			}
		ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen);
		*siglen = tmpsiglen;
		return ret;
	}
/* ----------------------------------------------------------------*/
int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags)
	{
	*pmeth = EVP_PKEY_meth_new(id, flags);
	if (!*pmeth) return 0;

	switch (id)
		{
		case NID_id_GostR3410_94:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str);
			EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen);
			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign);
			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify);
			EVP_PKEY_meth_set_encrypt(*pmeth,
				pkey_gost_encrypt_init, pkey_GOST94cp_encrypt);
			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt);
			EVP_PKEY_meth_set_derive(*pmeth,
				pkey_gost_derive_init, pkey_gost94_derive);
			break;
		case NID_id_GostR3410_2001:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str);
			EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign);
			EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify);

			EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen);

			EVP_PKEY_meth_set_encrypt(*pmeth,
				pkey_gost_encrypt_init, pkey_GOST01cp_encrypt);
			EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt);
			EVP_PKEY_meth_set_derive(*pmeth,
				pkey_gost_derive_init, pkey_gost2001_derive);
			break;
		case NID_id_Gost28147_89_MAC:
			EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);
			EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx);
			EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen);
			EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init);
			EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup);
			EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy);
			return 1;
		default: /*Unsupported method*/
			return 0;
		}
	EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);
	EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup);

	EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy);
	/*FIXME derive etc...*/
	
	return 1;
	}


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gost_sign.c
/**********************************************************************
 *                          gost_sign.c                               *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *       Implementation of GOST R 34.10-94 signature algoritgthm      *
 *       for OpenSSL                                                  *
 *          Requires OpenSSL 0.9.9 for compilation                    *
 **********************************************************************/
#include <string.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>

#include "gost_params.h"
#include "gost_lcl.h"
#include "e_gost_err.h"

#ifdef DEBUG_SIGN
void dump_signature(const char *message,const unsigned char *buffer,size_t len)
	{
	size_t i;
	fprintf(stderr,"signature %s Length=%d",message,len);
	for (i=0; i<len; i++)
		{
		if (i% 16 ==0) fputc('\n',stderr);
		fprintf (stderr," %02x",buffer[i]);
		}
	fprintf(stderr,"\nEnd of signature\n");
	}

void dump_dsa_sig(const char *message, DSA_SIG *sig)
	{
	fprintf(stderr,"%s\nR=",message);
	BN_print_fp(stderr,sig->r);
	fprintf(stderr,"\nS=");
	BN_print_fp(stderr,sig->s);
	fprintf(stderr,"\n");
	}

#else

#define dump_signature(a,b,c)
#define dump_dsa_sig(a,b)
#endif

/*
 * Computes signature and returns it as DSA_SIG structure
 */
DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
	{
	BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
	DSA_SIG *newsig = DSA_SIG_new();
	BIGNUM *md = hashsum2bn(dgst);
	/* check if H(M) mod q is zero */
	BN_CTX *ctx=BN_CTX_new();
	BN_CTX_start(ctx);
	if (!newsig)
		{
		GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
		goto err;
		}	
	tmp=BN_CTX_get(ctx);
	k = BN_CTX_get(ctx);
	tmp2 = BN_CTX_get(ctx);
	BN_mod(tmp,md,dsa->q,ctx);
	if (BN_is_zero(tmp))
		{
		BN_one(md);
		}	
	do
		{
		do
			{
			/*Generate random number k less than q*/
			BN_rand_range(k,dsa->q);
			/* generate r = (a^x mod p) mod q */
			BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
			if (!(newsig->r)) newsig->r=BN_new();
			BN_mod(newsig->r,tmp,dsa->q,ctx);
			}
		while (BN_is_zero(newsig->r));
		/* generate s = (xr + k(Hm)) mod q */
		BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
		BN_mod_mul(tmp2,k,md,dsa->q,ctx);
		if (!newsig->s) newsig->s=BN_new();
		BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
		}
	while (BN_is_zero(newsig->s));		
	err:
	BN_free(md);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return newsig;
	}	


/*
 * Packs signature according to Cryptocom rules
 * and frees up DSA_SIG structure
 */
/*
int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
	{
	*siglen = 2*order;
	memset(sig,0,*siglen);
	store_bignum(s->r, sig,order);
	store_bignum(s->s, sig + order,order);
	dump_signature("serialized",sig,*siglen);
	DSA_SIG_free(s);
	return 1;
	}
*/
/*
 * Packs signature according to Cryptopro rules
 * and frees up DSA_SIG structure
 */
int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
	{
	*siglen = 2*order;
	memset(sig,0,*siglen);
	store_bignum(s->s, sig, order);
	store_bignum(s->r, sig+order,order);
	dump_signature("serialized",sig,*siglen);
	DSA_SIG_free(s);
	return 1;
	}

/*
 * Verifies signature passed as DSA_SIG structure
 *
 */

int gost_do_verify(const unsigned char *dgst, int dgst_len,
	DSA_SIG *sig, DSA *dsa)
	{
	BIGNUM *md, *tmp=NULL;
	BIGNUM *q2=NULL;
	BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
	BIGNUM *tmp2=NULL,*tmp3=NULL;
	int ok;
	BN_CTX *ctx = BN_CTX_new();

	BN_CTX_start(ctx);
	if (BN_cmp(sig->s,dsa->q)>=1||
		BN_cmp(sig->r,dsa->q)>=1)
		{
		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
		return 0;
		}
	md=hashsum2bn(dgst);
	
	tmp=BN_CTX_get(ctx);
	v=BN_CTX_get(ctx);
	q2=BN_CTX_get(ctx);
	z1=BN_CTX_get(ctx);
	z2=BN_CTX_get(ctx);
	tmp2=BN_CTX_get(ctx);
	tmp3=BN_CTX_get(ctx);
	u = BN_CTX_get(ctx);
	
	BN_mod(tmp,md,dsa->q,ctx);
	if (BN_is_zero(tmp))
		{
		BN_one(md);
		}
	BN_copy(q2,dsa->q);
	BN_sub_word(q2,2);
	BN_mod_exp(v,md,q2,dsa->q,ctx);
	BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
	BN_sub(tmp,dsa->q,sig->r);
	BN_mod_mul(z2,tmp,v,dsa->p,ctx);
	BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
	BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
	BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
	BN_mod(u,tmp3,dsa->q,ctx);
	ok= BN_cmp(u,sig->r);
	
	BN_free(md);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	if (ok!=0)
		{
		GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
		}	
	return (ok==0);
	}

/*
 * Computes public keys for GOST R 34.10-94 algorithm
 *
 */
int gost94_compute_public(DSA *dsa)
	{
	/* Now fill algorithm parameters with correct values */
	BN_CTX *ctx = BN_CTX_new();
	if (!dsa->g)
		{
		GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
		return 0;
		}	
	/* Compute public key  y = a^x mod p */
	dsa->pub_key=BN_new();
	BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
	BN_CTX_free(ctx);
	return 1;
	}

/*
 * Fill GOST 94 params, searching them in R3410_paramset array
 * by nid of paramset
 *
 */
int fill_GOST94_params(DSA *dsa,int nid)
	{
	R3410_params *params=R3410_paramset;
	while (params->nid!=NID_undef && params->nid !=nid) params++;
	if (params->nid == NID_undef)
		{
		GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
		return 0;
		}	
#define dump_signature(a,b,c)
	if (dsa->p) { BN_free(dsa->p); }
	dsa->p=NULL;
	BN_dec2bn(&(dsa->p),params->p);
	if (dsa->q) { BN_free(dsa->q); }
	dsa->q=NULL;
	BN_dec2bn(&(dsa->q),params->q);
	if (dsa->g) { BN_free(dsa->g); }
	dsa->g=NULL;
	BN_dec2bn(&(dsa->g),params->a);
	return 1;
	}	

/*
 *  Generate GOST R 34.10-94 keypair
 *
 *
 */
int gost_sign_keygen(DSA *dsa)
	{
	dsa->priv_key = BN_new();
	BN_rand_range(dsa->priv_key,dsa->q);
	return gost94_compute_public( dsa);
	}

/* Unpack signature according to cryptocom rules  */
/*
DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
	{
	DSA_SIG *s;
	s = DSA_SIG_new();
	if (s == NULL)
		{
		GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
		return(NULL);
		}
	s->r = getbnfrombuf(sig, siglen/2);
	s->s = getbnfrombuf(sig + siglen/2, siglen/2);
	return s;
	}
*/
/* Unpack signature according to cryptopro rules  */
DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
	{
	DSA_SIG *s;

	s = DSA_SIG_new();
	if (s == NULL)
		{
		GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
		return NULL;
		}
	s->s = getbnfrombuf(sig , siglen/2);
	s->r = getbnfrombuf(sig + siglen/2, siglen/2);
	return s;
	}

/* Convert little-endian byte array into bignum */
BIGNUM *hashsum2bn(const unsigned char *dgst)
	{
	unsigned char buf[32];
	int i;
	for (i=0;i<32;i++)
		{
		buf[31-i]=dgst[i];
		}
	return getbnfrombuf(buf,32);
	}

/* Convert byte buffer to bignum, skipping leading zeros*/
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
	{
	while (*buf==0&&len>0)
		{
		buf++; len--;
		}
	if (len)
		{
		return BN_bin2bn(buf,len,NULL);
		}
	else
		{
		BIGNUM *b=BN_new();
		BN_zero(b);
		return b;
		}
	}

/* Pack bignum into byte buffer of given size, filling all leading bytes
 * by zeros */
int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
	{
	int bytes = BN_num_bytes(bn);
	if (bytes>len) return 0;
	memset(buf,0,len);
	BN_bn2bin(bn,buf+len-bytes);
	return 1;
	}	

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gosthash.c
/**********************************************************************
 *                          gosthash.c                                *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *    Implementation of GOST R 34.11-94 hash function                 *
 *       uses on gost89.c and gost89.h Doesn't need OpenSSL           *
 **********************************************************************/
#include <string.h>

#include "gost89.h"
#include "gosthash.h"


/* Use OPENSSL_malloc for memory allocation if compiled with 
 * -DOPENSSL_BUILD, and libc malloc otherwise
 */
#ifndef MYALLOC
# ifdef OPENSSL_BUILD
#  include <openssl/crypto.h>
#  define MYALLOC(size) OPENSSL_malloc(size)
#  define MYFREE(ptr) OPENSSL_free(ptr)
# else
#  define MYALLOC(size) malloc(size)
#  define MYFREE(ptr) free(ptr)
# endif
#endif
/* Following functions are various bit meshing routines used in
 * GOST R 34.11-94 algorithms */
static void swap_bytes (byte *w, byte *k) 
	{
	int i,j;
	for (i=0;i<4;i++)	
		for (j=0;j<8;j++) 
			k[i+4*j]=w[8*i+j];

	}

/* was A_A */
static void circle_xor8 (const byte *w, byte *k) 
	{
	byte buf[8];
	int i;
	memcpy(buf,w,8);
	memcpy(k,w+8,24);
	for(i=0;i<8;i++) 
		k[i+24]=buf[i]^k[i];
	}

/* was R_R */
static void transform_3 (byte *data) 
	{
	unsigned short int acc;
	acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
		((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
	memmove(data,data+2,30);
	data[30]=acc&0xff;
	data[31]=acc>>8;
	}

/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
static int add_blocks(int n,byte *left, const byte *right) 
	{
	int i;
	int carry=0;
	int sum;
	for (i=0;i<n;i++) 
		{
	   	sum=(int)left[i]+(int)right[i]+carry;
		left[i]=sum & 0xff;
		carry=sum>>8;
		}
	return carry;
	} 

/* Xor two sequences of bytes */
static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
	{
	size_t i;
	for (i=0;i<len;i++) result[i]=a[i]^b[i];
	}	

/* 
 * 	Calculate H(i+1) = Hash(Hi,Mi) 
 * 	Where H and M are 32 bytes long
 */
static int hash_step(gost_ctx *c,byte *H,const byte *M) 
	{
	static byte U[32],W[32],V[32],S[32],Key[32];
	int i;
	/* Compute first key */
	xor_blocks(W,H,M,32);
	swap_bytes(W,Key);
	/* Encrypt first 8 bytes of H with first key*/
	gost_enc_with_key(c,Key,H,S);
	/* Compute second key*/
	circle_xor8(H,U);
	circle_xor8(M,V);
	circle_xor8(V,V);
	xor_blocks(W,U,V,32);
	swap_bytes(W,Key);
	/* encrypt second 8 bytes of H with second key*/
	gost_enc_with_key(c,Key,H+8,S+8);
	/* compute third key */
	circle_xor8(U,U);
	U[31]=~U[31]; U[29]=~U[29]; U[28]=~U[28]; U[24]=~U[24];
	U[23]=~U[23]; U[20]=~U[20]; U[18]=~U[18]; U[17]=~U[17];
	U[14]=~U[14]; U[12]=~U[12]; U[10]=~U[10]; U[ 8]=~U[ 8];
	U[ 7]=~U[ 7]; U[ 5]=~U[ 5]; U[ 3]=~U[ 3]; U[ 1]=~U[ 1];
	circle_xor8(V,V);
	circle_xor8(V,V);
	xor_blocks(W,U,V,32);
	swap_bytes(W,Key);
	/* encrypt third 8 bytes of H with third key*/
	gost_enc_with_key(c,Key,H+16,S+16);
	/* Compute fourth key */
	circle_xor8(U,U);
	circle_xor8(V,V);
	circle_xor8(V,V);
	xor_blocks(W,U,V,32);
	swap_bytes(W,Key);
	/* Encrypt last 8 bytes with fourth key */
	gost_enc_with_key(c,Key,H+24,S+24);
	for (i=0;i<12;i++) 
		transform_3(S);
	xor_blocks(S,S,M,32);
	transform_3(S);
	xor_blocks(S,S,H,32);
	for (i=0;i<61;i++) 
		transform_3(S);
	memcpy(H,S,32);
	return 1;
	}

/* Initialize gost_hash ctx - cleans up temporary structures and
 * set up substitution blocks
 */
int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
	{	
	memset(ctx,0,sizeof(gost_hash_ctx));
	ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
	if (!ctx->cipher_ctx)
		{
		return 0;
		}		
	gost_init(ctx->cipher_ctx,subst_block);
	return 1;
	}

/*
 * Free cipher CTX if it is dynamically allocated. Do not use
 * if cipher ctx is statically allocated as in OpenSSL implementation of
 * GOST hash algroritm
 *
 */ 
void done_gost_hash_ctx(gost_hash_ctx *ctx) 
	{
	/* No need to use gost_destroy, because cipher keys are not really
	 * secret when hashing */
	MYFREE(ctx->cipher_ctx);
	}

/*
 * reset state of hash context to begin hashing new message
 */
int start_hash(gost_hash_ctx *ctx)
	{
	if (!ctx->cipher_ctx) return 0;
	memset(&(ctx->H),0,32);
	memset(&(ctx->S),0,32);
	ctx->len = 0L;
	ctx->left=0;
	return 1;
	}

/*
 * Hash block of arbitrary length
 *
 *
 */
int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
	{
	const byte *curptr=block;
	const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
	if (ctx->left)
		{
		/*There are some bytes from previous step*/
		unsigned int add_bytes = 32-ctx->left;
		if (add_bytes>length)
			{
			add_bytes = length;
			}	
		memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
		ctx->left+=add_bytes;
		if (ctx->left<32)
			{
			return 1;
			}	
		curptr=block+add_bytes;
		hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
		add_blocks(32,ctx->S,ctx->remainder);
		ctx->len+=32;
		ctx->left=0;
		}
	while (curptr<=barrier)
		{	
		hash_step(ctx->cipher_ctx,ctx->H,curptr);
			
		add_blocks(32,ctx->S,curptr);
		ctx->len+=32;
		curptr+=32;
		}	
	if (curptr!=block+length)
		{
		ctx->left=block+length-curptr;
		memcpy(ctx->remainder,curptr,ctx->left);
		}	
	return 1;	
	}

/*
 * Compute hash value from current state of ctx
 * state of hash ctx becomes invalid and cannot be used for further
 * hashing.
 */ 
int finish_hash(gost_hash_ctx *ctx,byte *hashval)
	{
	byte buf[32];
	byte H[32];
	byte S[32];
	ghosthash_len fin_len=ctx->len;
	byte *bptr;
	memcpy(H,ctx->H,32);
	memcpy(S,ctx->S,32);
	if (ctx->left)
		{
		memset(buf,0,32);
		memcpy(buf,ctx->remainder,ctx->left);
		hash_step(ctx->cipher_ctx,H,buf);
		add_blocks(32,S,buf);
		fin_len+=ctx->left;
		}
	memset(buf,0,32);
	bptr=buf;
	fin_len<<=3; /* Hash length in BITS!!*/
	while(fin_len>0)
		{
		*(bptr++)=(byte)(fin_len&0xFF);
		fin_len>>=8;
		};
	hash_step(ctx->cipher_ctx,H,buf);
	hash_step(ctx->cipher_ctx,H,S);
	memcpy(hashval,H,32);
	return 1;
	}


File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gosthash.h
/**********************************************************************
 *                          gosthash.h                                *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *       This file is distributed under the same license as OpenSSL   *
 *                                                                    *
 *    Declaration of GOST R 34.11-94 hash functions                   *
 *       uses  and gost89.h Doesn't need OpenSSL                      *
 **********************************************************************/
#ifndef GOSTHASH_H
#define GOSTHASH_H
#include "gost89.h"
#include <stdlib.h>

#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
typedef __int64 ghosthash_len;
#elif defined(__arch64__)
typedef long ghosthash_len;
#else
typedef long long ghosthash_len;
#endif

typedef struct gost_hash_ctx {
		ghosthash_len len;
		gost_ctx *cipher_ctx;
		int left;
		byte H[32];
		byte S[32];
		byte remainder[32];
} gost_hash_ctx;		


/* Initalizes gost hash ctx, including creation of gost cipher ctx */

int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block);
void done_gost_hash_ctx(gost_hash_ctx *ctx);

/* Cleans up all fields, except cipher ctx preparing ctx for computing
 * of new hash value */
int start_hash(gost_hash_ctx *ctx);

/* Hashes block of data */
int hash_block(gost_hash_ctx *ctx, const byte *block, size_t length);

/* Finalizes computation of hash  and fills buffer (which should be at
 * least 32 bytes long) with value of computed hash. */
int finish_hash(gost_hash_ctx *ctx, byte *hashval);

#endif	

File Added: src/crypto/dist/openssl/engines/ccgost/Attic/gostsum.c
/**********************************************************************
 *                        gostsum.c                                   *
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 *         This file is distributed under the same license as OpenSSL *
 *                                                                    *
 *        Almost drop-in replacement for md5sum and sha1sum           *
 *          which computes GOST R 34.11-94 hashsum instead            *
 *                                                                    *
 **********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <string.h>
#include "gosthash.h"
#define BUF_SIZE 262144
int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode);
int hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
int get_line(FILE *f,char *hash,char *filename);
void help()
	{
	fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
		"\t-c check message digests (default is generate)\n"
		"\t-v verbose, print file names when checking\n"
		"\t-b read files in binary mode\n"
		"\t-t use test GOST paramset (default is CryptoPro paramset)\n"
		"The input for -c should be the list of message digests and file names\n"
		"that is printed on stdout by this program when it generates digests.\n");
	exit(3);
	}

#ifndef O_BINARY
#define O_BINARY 0
#endif

int main(int argc,char **argv)
	{
	int c,i;
	int verbose=0;
	int errors=0;
	int open_mode = O_RDONLY;
	gost_subst_block *b=  &GostR3411_94_CryptoProParamSet;
	FILE *check_file = NULL;
	gost_hash_ctx ctx;
	
	while( (c=getopt(argc,argv,"bc::tv"))!=-1)
		{
		switch (c)
			{
			case 'v': verbose=1; break;
			case 't': b= &GostR3411_94_TestParamSet; break;
			case 'b': open_mode |= O_BINARY; break;
			case 'c':
				if (optarg)
					{
					check_file = fopen(optarg,"r");
					if (!check_file)
						{
						perror(optarg);
						exit(2);
						}
					}
				else
					{
				  	check_file= stdin;
					}
				break;
			default:
				fprintf(stderr,"invalid option %c",optopt);
				help();
			}
		}
	init_gost_hash_ctx(&ctx,b);
	if (check_file)
		{
		char inhash[65],calcsum[65],filename[PATH_MAX];
		int failcount=0,count=0;;
		if (check_file==stdin && optind<argc)
			{
			check_file=fopen(argv[optind],"r");
			if (!check_file)
				{	
				perror(argv[optind]);
				exit(2);
				}
			}	
		while (get_line(check_file,inhash,filename))
			{
			if (!hash_file(&ctx,filename,calcsum,open_mode))
				{
				exit (2);
				}	
			count++;
			if (!strncmp(calcsum,inhash,65))
				{
				if (verbose)
					{
					fprintf(stderr,"%s\tOK\n",filename);
					}
				}
			else
				{
				if (verbose)
					{
					fprintf(stderr,"%s\tFAILED\n",filename);
					}
				else
					{
					fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
						argv[0],filename);
					}
				failcount++;
				}
			}	
		if (verbose && failcount)
			{
			fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
				argv[0],failcount,count);
			}
		exit (failcount?1:0);
		}
	if (optind==argc)
		{
		char sum[65];
		if (!hash_stream(&ctx,fileno(stdin),sum))
			{
			perror("stdin");
			exit(1);
			}	
		printf("%s -\n",sum);
		exit(0);
		}	
	for (i=optind;i<argc;i++)
		{
		char sum[65];
		if (!hash_file(&ctx,argv[i],sum,open_mode))
			{
			errors++;
			}
		else
			{	
			printf("%s %s\n",sum,argv[i]);
			}
		}	
	exit(errors?1:0);	
	}

int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode)
	{
	int fd;
	if ((fd=open(filename,mode))<0)
		{
		perror(filename);
		return 0;
		}
	if (!hash_stream(ctx,fd,sum))
		{
		perror(filename);
		return 0;
		}	
	close(fd);
	return 1;
	}

int hash_stream(gost_hash_ctx *ctx,int fd, char *sum)
	{
	unsigned char buffer[BUF_SIZE];
	ssize_t bytes;
	int i;
	start_hash(ctx);
	while ((bytes=read(fd,buffer,BUF_SIZE))>0)
		{
		hash_block(ctx,buffer,bytes);
		}
	if (bytes<0)
		{
		return 0;
		}	
	finish_hash(ctx,buffer);
	for (i=0;i<32;i++)
		{
		sprintf(sum+2*i,"%02x",buffer[31-i]);
		}
	return 1;
	}	
	
int get_line(FILE *f,char *hash,char *filename)
	{
	int i;
	if (fread(hash,1,64,f)<64) return 0;
	hash[64]=0;
	for (i=0;i<64;i++)
		{
		if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F'
				&& hash[i]<'a')||hash[i]>'f')
			{
			fprintf(stderr,"Not a hash value '%s'\n",hash);
			return 0;
			}
		}	
	if (fgetc(f)!=' ')
		{
		fprintf(stderr,"Malformed input line\n");
		return 0;
		}
	i=strlen(fgets(filename,PATH_MAX,f));
	while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
	return 1;
	}	

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smdsa1.pem
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
9fMUZq1v0ePD4Wo0Xkxo
-----END DSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
7WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
4Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smdsa2.pem
-----BEGIN DSA PRIVATE KEY-----
MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
Nf8SimTZYB0/CKje6M5ufA==
-----END DSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
6WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
6Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smdsa3.pem
-----BEGIN DSA PRIVATE KEY-----
MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
Y+XZd0Sv69CatDIRYWvaIA==
-----END DSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smdsap.pem
-----BEGIN DSA PARAMETERS-----
MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
Qw5z
-----END DSA PARAMETERS-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smroot.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
9Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
1tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
3Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
3ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
0J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
9HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
81XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smrsa1.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
9cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw==
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smrsa2.pem
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
59i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
+rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
6rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
00obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw==
-----END CERTIFICATE-----

File Added: src/crypto/dist/openssl/test/smime-certs/Attic/smrsa3.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
9XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
-----END CERTIFICATE-----