diff options
Diffstat (limited to 'openssl/crypto/x509')
27 files changed, 9836 insertions, 0 deletions
diff --git a/openssl/crypto/x509/Makefile b/openssl/crypto/x509/Makefile new file mode 100644 index 000000000..464752b15 --- /dev/null +++ b/openssl/crypto/x509/Makefile @@ -0,0 +1,417 @@ +# +# OpenSSL/crypto/x509/Makefile +# + +DIR= x509 +TOP= ../.. +CC= cc +INCLUDES= -I.. -I$(TOP) -I../../include +CFLAG=-g +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile README +TEST= +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \ + x509_obj.c x509_req.c x509spki.c x509_vfy.c \ + x509_set.c x509cset.c x509rset.c x509_err.c \ + x509name.c x509_v3.c x509_ext.c x509_att.c \ + x509type.c x509_lu.c x_all.c x509_txt.c \ + x509_trs.c by_file.c by_dir.c x509_vpm.c +LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \ + x509_obj.o x509_req.o x509spki.o x509_vfy.o \ + x509_set.o x509cset.o x509rset.o x509_err.o \ + x509name.o x509_v3.o x509_ext.o x509_att.o \ + x509type.o x509_lu.o x_all.o x509_txt.o \ + x509_trs.o by_file.o by_dir.o x509_vpm.o + +SRC= $(LIBSRC) + +EXHEADER= x509.h x509_vfy.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(ARX) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(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. + +by_dir.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h +by_dir.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +by_dir.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +by_dir.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +by_dir.o: ../../include/openssl/err.h ../../include/openssl/evp.h +by_dir.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +by_dir.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +by_dir.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +by_dir.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +by_dir.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +by_dir.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +by_dir.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +by_dir.o: ../cryptlib.h by_dir.c +by_file.o: ../../e_os.h ../../include/openssl/asn1.h +by_file.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +by_file.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +by_file.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +by_file.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +by_file.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +by_file.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +by_file.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +by_file.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +by_file.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h +by_file.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +by_file.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +by_file.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +by_file.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_file.c +x509_att.o: ../../e_os.h ../../include/openssl/asn1.h +x509_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_att.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_att.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_att.o: ../../include/openssl/opensslconf.h +x509_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_att.o: ../cryptlib.h x509_att.c +x509_cmp.o: ../../e_os.h ../../include/openssl/asn1.h +x509_cmp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_cmp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_cmp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_cmp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_cmp.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_cmp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_cmp.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_cmp.o: ../../include/openssl/opensslconf.h +x509_cmp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_cmp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_cmp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_cmp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_cmp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_cmp.o: ../cryptlib.h x509_cmp.c +x509_d2.o: ../../e_os.h ../../include/openssl/asn1.h +x509_d2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_d2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509_d2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509_d2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509_d2.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509_d2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509_d2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509_d2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_d2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_d2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_d2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_d2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_d2.c +x509_def.o: ../../e_os.h ../../include/openssl/asn1.h +x509_def.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_def.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509_def.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509_def.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509_def.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509_def.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509_def.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_def.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_def.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_def.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_def.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_def.c +x509_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +x509_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +x509_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_err.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_err.o: ../../include/openssl/opensslconf.h +x509_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_err.o: ../../include/openssl/x509_vfy.h x509_err.c +x509_ext.o: ../../e_os.h ../../include/openssl/asn1.h +x509_ext.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_ext.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_ext.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_ext.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_ext.o: ../../include/openssl/opensslconf.h +x509_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_ext.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_ext.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_ext.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_ext.o: ../cryptlib.h x509_ext.c +x509_lu.o: ../../e_os.h ../../include/openssl/asn1.h +x509_lu.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_lu.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_lu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_lu.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_lu.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_lu.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_lu.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_lu.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +x509_lu.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +x509_lu.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +x509_lu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +x509_lu.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +x509_lu.o: ../../include/openssl/x509v3.h ../cryptlib.h x509_lu.c +x509_obj.o: ../../e_os.h ../../include/openssl/asn1.h +x509_obj.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_obj.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509_obj.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509_obj.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509_obj.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509_obj.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509_obj.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509_obj.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_obj.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_obj.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_obj.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_obj.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_obj.c +x509_r2x.o: ../../e_os.h ../../include/openssl/asn1.h +x509_r2x.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +x509_r2x.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +x509_r2x.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_r2x.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_r2x.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_r2x.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_r2x.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_r2x.o: ../../include/openssl/opensslconf.h +x509_r2x.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_r2x.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_r2x.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_r2x.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_r2x.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_r2x.c +x509_req.o: ../../e_os.h ../../include/openssl/asn1.h +x509_req.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +x509_req.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +x509_req.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_req.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_req.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_req.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_req.o: ../../include/openssl/opensslconf.h +x509_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_req.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h +x509_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_req.c +x509_set.o: ../../e_os.h ../../include/openssl/asn1.h +x509_set.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_set.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509_set.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509_set.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509_set.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509_set.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509_set.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_set.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_set.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_set.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_set.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_set.c +x509_trs.o: ../../e_os.h ../../include/openssl/asn1.h +x509_trs.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_trs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_trs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_trs.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_trs.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_trs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_trs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_trs.o: ../../include/openssl/opensslconf.h +x509_trs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_trs.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_trs.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_trs.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_trs.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_trs.o: ../cryptlib.h x509_trs.c +x509_txt.o: ../../e_os.h ../../include/openssl/asn1.h +x509_txt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_txt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509_txt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509_txt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509_txt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509_txt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509_txt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509_txt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_txt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_txt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_txt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_txt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_txt.c +x509_v3.o: ../../e_os.h ../../include/openssl/asn1.h +x509_v3.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_v3.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_v3.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_v3.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_v3.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_v3.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_v3.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_v3.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +x509_v3.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +x509_v3.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +x509_v3.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +x509_v3.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +x509_v3.o: ../../include/openssl/x509v3.h ../cryptlib.h x509_v3.c +x509_vfy.o: ../../e_os.h ../../include/openssl/asn1.h +x509_vfy.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_vfy.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_vfy.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_vfy.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_vfy.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_vfy.o: ../../include/openssl/opensslconf.h +x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_vfy.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_vfy.o: ../cryptlib.h x509_vfy.c +x509_vpm.o: ../../e_os.h ../../include/openssl/asn1.h +x509_vpm.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509_vpm.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +x509_vpm.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +x509_vpm.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +x509_vpm.o: ../../include/openssl/err.h ../../include/openssl/evp.h +x509_vpm.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +x509_vpm.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +x509_vpm.o: ../../include/openssl/opensslconf.h +x509_vpm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509_vpm.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509_vpm.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509_vpm.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509_vpm.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +x509_vpm.o: ../cryptlib.h x509_vpm.c +x509cset.o: ../../e_os.h ../../include/openssl/asn1.h +x509cset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509cset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509cset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509cset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509cset.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509cset.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509cset.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509cset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509cset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509cset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509cset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509cset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509cset.c +x509name.o: ../../e_os.h ../../include/openssl/asn1.h +x509name.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509name.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509name.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509name.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509name.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509name.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509name.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509name.c +x509rset.o: ../../e_os.h ../../include/openssl/asn1.h +x509rset.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509rset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509rset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509rset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509rset.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509rset.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509rset.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509rset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509rset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509rset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509rset.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509rset.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509rset.c +x509spki.o: ../../e_os.h ../../include/openssl/asn1.h +x509spki.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509spki.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509spki.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509spki.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509spki.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509spki.c +x509type.o: ../../e_os.h ../../include/openssl/asn1.h +x509type.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +x509type.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +x509type.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x509type.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x509type.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x509type.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x509type.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x509type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x509type.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +x509type.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +x509type.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +x509type.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509type.c +x_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h +x_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +x_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +x_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +x_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +x_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +x_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +x_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +x_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +x_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h +x_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +x_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +x_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +x_all.o: ../cryptlib.h x_all.c diff --git a/openssl/crypto/x509/by_dir.c b/openssl/crypto/x509/by_dir.c new file mode 100644 index 000000000..341e0ba6a --- /dev/null +++ b/openssl/crypto/x509/by_dir.c @@ -0,0 +1,386 @@ +/* crypto/x509/by_dir.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include <errno.h> + +#include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef MAC_OS_pre_X +# include <stat.h> +#else +# include <sys/stat.h> +#endif + +#include <openssl/lhash.h> +#include <openssl/x509.h> + +#ifdef _WIN32 +#define stat _stat +#endif + +typedef struct lookup_dir_st + { + BUF_MEM *buffer; + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; + } BY_DIR; + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx,const char *dir,int type); +static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name, + X509_OBJECT *ret); +X509_LOOKUP_METHOD x509_dir_lookup= + { + "Load certs from files in a directory", + new_dir, /* new */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + }; + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) + { + return(&x509_dir_lookup); + } + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) + { + int ret=0; + BY_DIR *ld; + char *dir = NULL; + + ld=(BY_DIR *)ctx->method_data; + + switch (cmd) + { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) + { + dir=(char *)Getenv(X509_get_default_cert_dir_env()); + if (dir) + ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); + else + ret=add_cert_dir(ld,X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) + { + X509err(X509_F_DIR_CTRL,X509_R_LOADING_CERT_DIR); + } + } + else + ret=add_cert_dir(ld,argp,(int)argl); + break; + } + return(ret); + } + +static int new_dir(X509_LOOKUP *lu) + { + BY_DIR *a; + + if ((a=(BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) + return(0); + if ((a->buffer=BUF_MEM_new()) == NULL) + { + OPENSSL_free(a); + return(0); + } + a->num_dirs=0; + a->dirs=NULL; + a->dirs_type=NULL; + a->num_dirs_alloced=0; + lu->method_data=(char *)a; + return(1); + } + +static void free_dir(X509_LOOKUP *lu) + { + BY_DIR *a; + int i; + + a=(BY_DIR *)lu->method_data; + for (i=0; i<a->num_dirs; i++) + if (a->dirs[i] != NULL) OPENSSL_free(a->dirs[i]); + if (a->dirs != NULL) OPENSSL_free(a->dirs); + if (a->dirs_type != NULL) OPENSSL_free(a->dirs_type); + if (a->buffer != NULL) BUF_MEM_free(a->buffer); + OPENSSL_free(a); + } + +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) + { + int j,len; + int *ip; + const char *s,*ss,*p; + char **pp; + + if (dir == NULL || !*dir) + { + X509err(X509_F_ADD_CERT_DIR,X509_R_INVALID_DIRECTORY); + return 0; + } + + s=dir; + p=s; + for (;;p++) + { + if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) + { + ss=s; + s=p+1; + len=(int)(p-ss); + if (len == 0) continue; + for (j=0; j<ctx->num_dirs; j++) + if (strlen(ctx->dirs[j]) == (size_t)len && + strncmp(ctx->dirs[j],ss,(unsigned int)len) == 0) + break; + if (j<ctx->num_dirs) + continue; + if (ctx->num_dirs_alloced < (ctx->num_dirs+1)) + { + ctx->num_dirs_alloced+=10; + pp=(char **)OPENSSL_malloc(ctx->num_dirs_alloced* + sizeof(char *)); + ip=(int *)OPENSSL_malloc(ctx->num_dirs_alloced* + sizeof(int)); + if ((pp == NULL) || (ip == NULL)) + { + X509err(X509_F_ADD_CERT_DIR,ERR_R_MALLOC_FAILURE); + return(0); + } + memcpy(pp,ctx->dirs,(ctx->num_dirs_alloced-10)* + sizeof(char *)); + memcpy(ip,ctx->dirs_type,(ctx->num_dirs_alloced-10)* + sizeof(int)); + if (ctx->dirs != NULL) + OPENSSL_free(ctx->dirs); + if (ctx->dirs_type != NULL) + OPENSSL_free(ctx->dirs_type); + ctx->dirs=pp; + ctx->dirs_type=ip; + } + ctx->dirs_type[ctx->num_dirs]=type; + ctx->dirs[ctx->num_dirs]=(char *)OPENSSL_malloc((unsigned int)len+1); + if (ctx->dirs[ctx->num_dirs] == NULL) return(0); + strncpy(ctx->dirs[ctx->num_dirs],ss,(unsigned int)len); + ctx->dirs[ctx->num_dirs][len]='\0'; + ctx->num_dirs++; + } + if (*p == '\0') break; + } + return(1); + } + +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) + { + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok=0; + int i,j,k; + unsigned long h; + BUF_MEM *b=NULL; + struct stat st; + X509_OBJECT stmp,*tmp; + const char *postfix=""; + + if (name == NULL) return(0); + + stmp.type=type; + if (type == X509_LU_X509) + { + data.x509.st_x509.cert_info= &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject=name; + stmp.data.x509= &data.x509.st_x509; + postfix=""; + } + else if (type == X509_LU_CRL) + { + data.crl.st_crl.crl= &data.crl.st_crl_info; + data.crl.st_crl_info.issuer=name; + stmp.data.crl= &data.crl.st_crl; + postfix="r"; + } + else + { + X509err(X509_F_GET_CERT_BY_SUBJECT,X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b=BUF_MEM_new()) == NULL) + { + X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_BUF_LIB); + goto finish; + } + + ctx=(BY_DIR *)xl->method_data; + + h=X509_NAME_hash(name); + for (i=0; i<ctx->num_dirs; i++) + { + j=strlen(ctx->dirs[i])+1+8+6+1+1; + if (!BUF_MEM_grow(b,j)) + { + X509err(X509_F_GET_CERT_BY_SUBJECT,ERR_R_MALLOC_FAILURE); + goto finish; + } + k=0; + for (;;) + { + char c = '/'; +#ifdef OPENSSL_SYS_VMS + c = ctx->dirs[i][strlen(ctx->dirs[i])-1]; + if (c != ':' && c != '>' && c != ']') + { + /* If no separator is present, we assume the + directory specifier is a logical name, and + add a colon. We really should use better + VMS routines for merging things like this, + but this will do for now... + -- Richard Levitte */ + c = ':'; + } + else + { + c = '\0'; + } +#endif + if (c == '\0') + { + /* This is special. When c == '\0', no + directory separator should be added. */ + BIO_snprintf(b->data,b->max, + "%s%08lx.%s%d",ctx->dirs[i],h, + postfix,k); + } + else + { + BIO_snprintf(b->data,b->max, + "%s%c%08lx.%s%d",ctx->dirs[i],c,h, + postfix,k); + } + k++; + if (stat(b->data,&st) < 0) + break; + /* found one. */ + if (type == X509_LU_X509) + { + if ((X509_load_cert_file(xl,b->data, + ctx->dirs_type[i])) == 0) + break; + } + else if (type == X509_LU_CRL) + { + if ((X509_load_crl_file(xl,b->data, + ctx->dirs_type[i])) == 0) + break; + } + /* else case will caught higher up */ + } + + /* we have added it to the cache so now pull + * it out again */ + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + j = sk_X509_OBJECT_find(xl->store_ctx->objs,&stmp); + if(j != -1) tmp=sk_X509_OBJECT_value(xl->store_ctx->objs,j); + else tmp = NULL; + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + + if (tmp != NULL) + { + ok=1; + ret->type=tmp->type; + memcpy(&ret->data,&tmp->data,sizeof(ret->data)); + /* If we were going to up the reference count, + * we would need to do it on a perl 'type' + * basis */ + /* CRYPTO_add(&tmp->data.x509->references,1, + CRYPTO_LOCK_X509);*/ + goto finish; + } + } +finish: + if (b != NULL) BUF_MEM_free(b); + return(ok); + } + diff --git a/openssl/crypto/x509/by_file.c b/openssl/crypto/x509/by_file.c new file mode 100644 index 000000000..a5e0d4aef --- /dev/null +++ b/openssl/crypto/x509/by_file.c @@ -0,0 +1,300 @@ +/* crypto/x509/by_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include <errno.h> + +#include "cryptlib.h" +#include <openssl/lhash.h> +#include <openssl/buffer.h> +#include <openssl/x509.h> +#include <openssl/pem.h> + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +X509_LOOKUP_METHOD x509_file_lookup= + { + "Load file into cache", + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_file_ctrl, /* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + }; + +X509_LOOKUP_METHOD *X509_LOOKUP_file(void) + { + return(&x509_file_lookup); + } + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret) + { + int ok=0; + char *file; + + switch (cmd) + { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) + { + file = (char *)Getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx,file, + X509_FILETYPE_PEM) != 0); + + else + ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + + if (!ok) + { + X509err(X509_F_BY_FILE_CTRL,X509_R_LOADING_DEFAULTS); + } + } + else + { + if(argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx,argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx,argp,(int)argl) != 0); + } + break; + } + return(ok); + } + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) + { + int ret=0; + BIO *in=NULL; + int i,count=0; + X509 *x=NULL; + + if (file == NULL) return(1); + in=BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in,file) <= 0)) + { + X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) + { + for (;;) + { + x=PEM_read_bio_X509_AUX(in,NULL,NULL,NULL); + if (x == NULL) + { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) + { + ERR_clear_error(); + break; + } + else + { + X509err(X509_F_X509_LOAD_CERT_FILE, + ERR_R_PEM_LIB); + goto err; + } + } + i=X509_STORE_add_cert(ctx->store_ctx,x); + if (!i) goto err; + count++; + X509_free(x); + x=NULL; + } + ret=count; + } + else if (type == X509_FILETYPE_ASN1) + { + x=d2i_X509_bio(in,NULL); + if (x == NULL) + { + X509err(X509_F_X509_LOAD_CERT_FILE,ERR_R_ASN1_LIB); + goto err; + } + i=X509_STORE_add_cert(ctx->store_ctx,x); + if (!i) goto err; + ret=i; + } + else + { + X509err(X509_F_X509_LOAD_CERT_FILE,X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + if (x != NULL) X509_free(x); + if (in != NULL) BIO_free(in); + return(ret); + } + +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) + { + int ret=0; + BIO *in=NULL; + int i,count=0; + X509_CRL *x=NULL; + + if (file == NULL) return(1); + in=BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in,file) <= 0)) + { + X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) + { + for (;;) + { + x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); + if (x == NULL) + { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) + { + ERR_clear_error(); + break; + } + else + { + X509err(X509_F_X509_LOAD_CRL_FILE, + ERR_R_PEM_LIB); + goto err; + } + } + i=X509_STORE_add_crl(ctx->store_ctx,x); + if (!i) goto err; + count++; + X509_CRL_free(x); + x=NULL; + } + ret=count; + } + else if (type == X509_FILETYPE_ASN1) + { + x=d2i_X509_CRL_bio(in,NULL); + if (x == NULL) + { + X509err(X509_F_X509_LOAD_CRL_FILE,ERR_R_ASN1_LIB); + goto err; + } + i=X509_STORE_add_crl(ctx->store_ctx,x); + if (!i) goto err; + ret=i; + } + else + { + X509err(X509_F_X509_LOAD_CRL_FILE,X509_R_BAD_X509_FILETYPE); + goto err; + } +err: + if (x != NULL) X509_CRL_free(x); + if (in != NULL) BIO_free(in); + return(ret); + } + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + int i, count = 0; + if(type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if(!in) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if(!inf) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB); + return 0; + } + for(i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if(itmp->x509) { + X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + count++; + } + if(itmp->crl) { + X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + count++; + } + } + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + + +#endif /* OPENSSL_NO_STDIO */ + diff --git a/openssl/crypto/x509/x509.h b/openssl/crypto/x509/x509.h new file mode 100644 index 000000000..e71b5257e --- /dev/null +++ b/openssl/crypto/x509/x509.h @@ -0,0 +1,1355 @@ +/* crypto/x509/x509.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +#define HEADER_X509_H + +#include <openssl/e_os2.h> +#include <openssl/symhacks.h> +#ifndef OPENSSL_NO_BUFFER +#include <openssl/buffer.h> +#endif +#ifndef OPENSSL_NO_EVP +#include <openssl/evp.h> +#endif +#ifndef OPENSSL_NO_BIO +#include <openssl/bio.h> +#endif +#include <openssl/stack.h> +#include <openssl/asn1.h> +#include <openssl/safestack.h> + +#ifndef OPENSSL_NO_EC +#include <openssl/ec.h> +#endif + +#ifndef OPENSSL_NO_ECDSA +#include <openssl/ecdsa.h> +#endif + +#ifndef OPENSSL_NO_ECDH +#include <openssl/ecdh.h> +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#ifndef OPENSSL_NO_DSA +#include <openssl/dsa.h> +#endif +#ifndef OPENSSL_NO_DH +#include <openssl/dh.h> +#endif +#endif + +#ifndef OPENSSL_NO_SHA +#include <openssl/sha.h> +#endif +#include <openssl/ossl_typ.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +#undef X509_NAME +#undef X509_CERT_PAIR +#endif + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st + { + int nid; + int (*a2i)(void); + int (*i2a)(void); + } X509_OBJECTS; + +struct X509_algor_st + { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } /* X509_ALGOR */; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st + { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; + } X509_VAL; + +typedef struct X509_pubkey_st + { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; + } X509_PUBKEY; + +typedef struct X509_sig_st + { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; + } X509_SIG; + +typedef struct X509_name_entry_st + { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ + } X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st + { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +#ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +#else + char *bytes; +#endif + unsigned long hash; /* Keep the hash around for lookups */ + } /* X509_NAME */; + +DECLARE_STACK_OF(X509_NAME) + +#define X509_EX_V_NETSCAPE_HACK 0x8000 +#define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st + { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; + } X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st + { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is wrong) */ + union { + char *ptr; +/* 0 */ STACK_OF(ASN1_TYPE) *set; +/* 1 */ ASN1_TYPE *single; + } value; + } X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + + +typedef struct X509_req_info_st + { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + } X509_REQ_INFO; + +typedef struct X509_req_st + { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + } X509_REQ; + +typedef struct x509_cinf_st + { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + } X509_CINF; + +/* This stuff is certificate "auxiliary info" + * it contains details which are useful in certificate + * stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st + { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ + } X509_CERT_AUX; + +struct x509_st + { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + struct AUTHORITY_KEYID_st *akid; + X509_POLICY_CACHE *policy_cache; +#ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +#endif +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + X509_CERT_AUX *aux; + } /* X509 */; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */ + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 + +/* Keep these up to date! */ +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 7 + + +/* trust_flags values */ +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +#define X509_FLAG_COMPAT 0 +#define X509_FLAG_NO_HEADER 1L +#define X509_FLAG_NO_VERSION (1L << 1) +#define X509_FLAG_NO_SERIAL (1L << 2) +#define X509_FLAG_NO_SIGNAME (1L << 3) +#define X509_FLAG_NO_ISSUER (1L << 4) +#define X509_FLAG_NO_VALIDITY (1L << 5) +#define X509_FLAG_NO_SUBJECT (1L << 6) +#define X509_FLAG_NO_PUBKEY (1L << 7) +#define X509_FLAG_NO_EXTENSIONS (1L << 8) +#define X509_FLAG_NO_SIGDUMP (1L << 9) +#define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +#define XN_FLAG_SEP_MASK (0xf << 16) + +#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */ +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */ +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */ +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */ +#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */ + +#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */ + +/* How the field name is shown */ + +#define XN_FLAG_FN_MASK (0x3 << 21) + +#define XN_FLAG_FN_SN 0 /* Object short name */ +#define XN_FLAG_FN_LN (1 << 21) /* Object long name */ +#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */ +#define XN_FLAG_FN_NONE (3 << 21) /* No field names */ + +#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */ + +/* This determines if we dump fields we don't recognise: + * RFC2253 requires this. + */ + +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */ + +/* Complete set of RFC2253 flags */ + +#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +typedef struct X509_revoked_st + { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + int sequence; /* load sequence */ + } X509_REVOKED; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st + { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; + } X509_CRL_INFO; + +struct X509_crl_st + { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + } /* X509_CRL */; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st + { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + + int references; + } X509_PKEY; + +#ifndef OPENSSL_NO_EVP +typedef struct X509_info_st + { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + int references; + } X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +#endif + +/* The next 2 structures and their 8 routines were sent to me by + * Pat Richard <patr@x509.com> and are used to manipulate + * Netscapes spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st + { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ + } NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st + { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; + } NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence + { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; + } NETSCAPE_CERT_SEQUENCE; + +/* Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { +ASN1_OCTET_STRING *salt; +ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { +X509_ALGOR *keyfunc; +X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +ASN1_TYPE *salt; /* Usually OCTET STRING but could be anything */ +ASN1_INTEGER *iter; +ASN1_INTEGER *keylength; +X509_ALGOR *prf; +} PBKDF2PARAM; + + +/* PKCS#8 private key info structure */ + +typedef struct pkcs8_priv_key_info_st + { + int broken; /* Flag for various broken formats */ +#define PKCS8_OK 0 +#define PKCS8_NO_OCTET 1 +#define PKCS8_EMBEDDED_PARAM 2 +#define PKCS8_NS_DB 3 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + STACK_OF(X509_ATTRIBUTE) *attributes; + } PKCS8_PRIV_KEY_INFO; + +#ifdef __cplusplus +} +#endif + +#include <openssl/x509_vfy.h> +#include <openssl/pkcs7.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SSLEAY_MACROS +#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\ + a->signature,(char *)a->cert_info,r) +#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \ + a->sig_alg,a->signature,(char *)a->req_info,r) +#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \ + a->sig_alg, a->signature,(char *)a->crl,r) + +#define X509_sign(x,pkey,md) \ + ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \ + x->sig_alg, x->signature, (char *)x->cert_info,pkey,md) +#define X509_REQ_sign(x,pkey,md) \ + ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \ + x->signature, (char *)x->req_info,pkey,md) +#define X509_CRL_sign(x,pkey,md) \ + ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \ + x->signature, (char *)x->crl,pkey,md) +#define NETSCAPE_SPKI_sign(x,pkey,md) \ + ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \ + x->signature, (char *)x->spkac,pkey,md) + +#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \ + (char *(*)())d2i_X509,(char *)x509) +#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\ + (int (*)())i2d_X509_ATTRIBUTE, \ + (char *(*)())d2i_X509_ATTRIBUTE,(char *)xa) +#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \ + (int (*)())i2d_X509_EXTENSION, \ + (char *(*)())d2i_X509_EXTENSION,(char *)ex) +#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \ + (char *(*)())d2i_X509, (fp),(unsigned char **)(x509)) +#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509) +#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \ + (char *(*)())d2i_X509, (bp),(unsigned char **)(x509)) +#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509) + +#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \ + (char *(*)())d2i_X509_CRL,(char *)crl) +#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \ + X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\ + (unsigned char **)(crl)) +#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\ + (unsigned char *)crl) +#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \ + X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\ + (unsigned char **)(crl)) +#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\ + (unsigned char *)crl) + +#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \ + (char *(*)())d2i_PKCS7,(char *)p7) +#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \ + PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\ + (unsigned char **)(p7)) +#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\ + (unsigned char *)p7) +#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \ + PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\ + (unsigned char **)(p7)) +#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\ + (unsigned char *)p7) + +#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \ + (char *(*)())d2i_X509_REQ,(char *)req) +#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\ + X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\ + (unsigned char **)(req)) +#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\ + (unsigned char *)req) +#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\ + X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\ + (unsigned char **)(req)) +#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\ + (unsigned char *)req) + +#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \ + (char *(*)())d2i_RSAPublicKey,(char *)rsa) +#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \ + (char *(*)())d2i_RSAPrivateKey,(char *)rsa) + +#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\ + RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \ + (unsigned char **)(rsa)) +#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \ + (unsigned char *)rsa) +#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\ + RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \ + (unsigned char **)(rsa)) +#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \ + (unsigned char *)rsa) + +#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\ + RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \ + (unsigned char **)(rsa)) +#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \ + (unsigned char *)rsa) +#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\ + RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \ + (unsigned char **)(rsa)) +#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \ + (unsigned char *)rsa) + +#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\ + DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \ + (unsigned char **)(dsa)) +#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \ + (unsigned char *)dsa) +#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\ + DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \ + (unsigned char **)(dsa)) +#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \ + (unsigned char *)dsa) + +#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\ + EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \ + (unsigned char **)(ecdsa)) +#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \ + (unsigned char *)ecdsa) +#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\ + EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \ + (unsigned char **)(ecdsa)) +#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \ + (unsigned char *)ecdsa) + +#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\ + (char *(*)())d2i_X509_ALGOR,(char *)xn) + +#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \ + (char *(*)())d2i_X509_NAME,(char *)xn) +#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \ + (int (*)())i2d_X509_NAME_ENTRY, \ + (char *(*)())d2i_X509_NAME_ENTRY,\ + (char *)ne) + +#define X509_digest(data,type,md,len) \ + ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len) +#define X509_NAME_digest(data,type,md,len) \ + ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len) +#ifndef PKCS7_ISSUER_AND_SERIAL_digest +#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \ + ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\ + (char *)data,md,len) +#endif +#endif + +#define X509_EXT_PACK_UNKNOWN 1 +#define X509_EXT_PACK_STRING 2 + +#define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +#define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +#define X509_extract_key(x) X509_get_pubkey(x) /*****/ +#define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +#define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +#define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +#define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +#define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +#define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +#define X509_CRL_get_issuer(x) ((x)->crl->issuer) +#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +/* This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */ +#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + + +const char *X509_verify_cert_error_string(long n); + +#ifndef SSLEAY_MACROS +#ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +#ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp,X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +#endif + +#ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp,X509 **x509); +int i2d_X509_bio(BIO *bp,X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +#endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +#endif /* !SSLEAY_MACROS */ + +int X509_cmp_time(ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(ASN1_TIME *s); +ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char * X509_get_default_cert_area(void ); +const char * X509_get_default_cert_dir(void ); +const char * X509_get_default_cert_file(void ); +const char * X509_get_default_cert_dir_env(void ); +const char * X509_get_default_cert_file_env(void ); +const char * X509_get_default_private_dir(void ); + +X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, + STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp); +EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp); +RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp); +DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); +#endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a,unsigned char **pp); +X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char * X509_alias_get0(X509 *x, int *len); +unsigned char * X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); + +X509_PKEY * X509_PKEY_new(void ); +void X509_PKEY_free(X509_PKEY *a); +int i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp); +X509_PKEY * d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +#ifndef OPENSSL_NO_EVP +X509_INFO * X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data, + unsigned char *md,unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data,EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey, const EVP_MD *type); +#endif + +int X509_set_version(X509 *x,long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER * X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY * X509_get_pubkey(X509 *x); +ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */); + +int X509_REQ_set_version(X509_REQ *x,long version); +int X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int * X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +#ifndef OPENSSL_NO_FP_API +int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print_fp(FILE *bp,X509 *x); +int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); +#endif + +#ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); +int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print(BIO *bp,X509 *x); +int X509_ocspid_print(BIO *bp,X509 *x); +int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp,X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +int X509_REQ_print(BIO *bp,X509_REQ *req); +#endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf,int len); + +/* NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. */ +int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type,unsigned char *bytes, int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type,const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj,int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, + const char *attrname, int type, + const unsigned char *bytes, int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, + int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST * X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +#define X509_F_ADD_CERT_DIR 100 +#define X509_F_BY_FILE_CTRL 101 +#define X509_F_CHECK_POLICY 145 +#define X509_F_DIR_CTRL 102 +#define X509_F_GET_CERT_BY_SUBJECT 103 +#define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +#define X509_F_X509AT_ADD1_ATTR 135 +#define X509_F_X509V3_ADD_EXT 104 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +#define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +#define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +#define X509_F_X509_CHECK_PRIVATE_KEY 128 +#define X509_F_X509_CRL_PRINT_FP 147 +#define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +#define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +#define X509_F_X509_LOAD_CERT_CRL_FILE 132 +#define X509_F_X509_LOAD_CERT_FILE 111 +#define X509_F_X509_LOAD_CRL_FILE 112 +#define X509_F_X509_NAME_ADD_ENTRY 113 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +#define X509_F_X509_NAME_ONELINE 116 +#define X509_F_X509_NAME_PRINT 117 +#define X509_F_X509_PRINT_EX_FP 118 +#define X509_F_X509_PUBKEY_GET 119 +#define X509_F_X509_PUBKEY_SET 120 +#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +#define X509_F_X509_REQ_PRINT_EX 121 +#define X509_F_X509_REQ_PRINT_FP 122 +#define X509_F_X509_REQ_TO_X509 123 +#define X509_F_X509_STORE_ADD_CERT 124 +#define X509_F_X509_STORE_ADD_CRL 125 +#define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +#define X509_F_X509_STORE_CTX_INIT 143 +#define X509_F_X509_STORE_CTX_NEW 142 +#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +#define X509_F_X509_TO_X509_REQ 126 +#define X509_F_X509_TRUST_ADD 133 +#define X509_F_X509_TRUST_SET 141 +#define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +#define X509_R_BAD_X509_FILETYPE 100 +#define X509_R_BASE64_DECODE_ERROR 118 +#define X509_R_CANT_CHECK_DH_KEY 114 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +#define X509_R_ERR_ASN1_LIB 102 +#define X509_R_INVALID_DIRECTORY 113 +#define X509_R_INVALID_FIELD_NAME 119 +#define X509_R_INVALID_TRUST 123 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 103 +#define X509_R_LOADING_DEFAULTS 104 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +#define X509_R_SHOULD_RETRY 106 +#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +#define X509_R_UNKNOWN_KEY_TYPE 117 +#define X509_R_UNKNOWN_NID 109 +#define X509_R_UNKNOWN_PURPOSE_ID 121 +#define X509_R_UNKNOWN_TRUST_ID 120 +#define X509_R_UNSUPPORTED_ALGORITHM 111 +#define X509_R_WRONG_LOOKUP_TYPE 112 +#define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/openssl/crypto/x509/x509_att.c b/openssl/crypto/x509/x509_att.c new file mode 100644 index 000000000..98460e892 --- /dev/null +++ b/openssl/crypto/x509/x509_att.c @@ -0,0 +1,359 @@ +/* crypto/x509/x509_att.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <openssl/stack.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} + +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos) +{ + ASN1_OBJECT *obj; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) return(-2); + return(X509at_get_attr_by_OBJ(x,obj,lastpos)); +} + +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, + int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) return(-1); + lastpos++; + if (lastpos < 0) + lastpos=0; + n=sk_X509_ATTRIBUTE_num(sk); + for ( ; lastpos < n; lastpos++) + { + ex=sk_X509_ATTRIBUTE_value(sk,lastpos); + if (OBJ_cmp(ex->object,obj) == 0) + return(lastpos); + } + return(-1); +} + +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x,loc); +} + +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return(NULL); + ret=sk_X509_ATTRIBUTE_delete(x,loc); + return(ret); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr=NULL; + STACK_OF(X509_ATTRIBUTE) *sk=NULL; + + if (x == NULL) + { + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) + { + if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } + else + sk= *x; + + if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk,new_attr)) + goto err; + if (*x == NULL) + *x=sk; + return(sk); +err: + X509err(X509_F_X509AT_ADD1_ATTR,ERR_R_MALLOC_FAILURE); +err2: + if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr); + if (sk != NULL) sk_X509_ATTRIBUTE_free(sk); + return(NULL); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if(!attr) return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if(!attr) return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if(!attr) return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type) +{ + int i; + X509_ATTRIBUTE *at; + i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) + return NULL; + if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + return NULL; + at = X509at_get_attr(x, i); + if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + return NULL; + return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *ret; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) + { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID); + return(NULL); + } + ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len); + if (ret == NULL) ASN1_OBJECT_free(obj); + return(ret); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) + { + if ((ret=X509_ATTRIBUTE_new()) == NULL) + { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE); + return(NULL); + } + } + else + ret= *attr; + + if (!X509_ATTRIBUTE_set1_object(ret,obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) *attr=ret; + return(ret); +err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return(NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len) + { + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj=OBJ_txt2obj(atrname, 0); + if (obj == NULL) + { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", atrname); + return(NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len); + ASN1_OBJECT_free(obj); + return nattr; + } + +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return(0); + ASN1_OBJECT_free(attr->object); + attr->object=OBJ_dup(obj); + return(1); +} + +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len) +{ + ASN1_TYPE *ttmp; + ASN1_STRING *stmp = NULL; + int atype = 0; + if (!attr) return 0; + if(attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if(!stmp) { + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1){ + if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err; + if(!ASN1_STRING_set(stmp, data, len)) goto err; + atype = attrtype; + } + if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; + attr->single = 0; + /* This is a bit naughty because the attribute should really have + * at least one value but some types use and zero length SET and + * require this. + */ + if (attrtype == 0) + return 1; + if(!(ttmp = ASN1_TYPE_new())) goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) + { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } + else + ASN1_TYPE_set(ttmp, atype, stmp); + if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err; + return 1; + err: + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + return 0; +} + +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) +{ + if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set); + if(attr->value.single) return 1; + return 0; +} + +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) return(NULL); + return(attr->object); +} + +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data) +{ + ASN1_TYPE *ttmp; + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if(!ttmp) return NULL; + if(atrtype != ASN1_TYPE_get(ttmp)){ + X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); + return NULL; + } + return ttmp->value.ptr; +} + +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) return(NULL); + if(idx >= X509_ATTRIBUTE_count(attr)) return NULL; + if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx); + else return attr->value.single; +} diff --git a/openssl/crypto/x509/x509_cmp.c b/openssl/crypto/x509/x509_cmp.c new file mode 100644 index 000000000..2faf92514 --- /dev/null +++ b/openssl/crypto/x509/x509_cmp.c @@ -0,0 +1,432 @@ +/* crypto/x509/x509_cmp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <ctype.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) + { + int i; + X509_CINF *ai,*bi; + + ai=a->cert_info; + bi=b->cert_info; + i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber); + if (i) return(i); + return(X509_NAME_cmp(ai->issuer,bi->issuer)); + } + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_and_serial_hash(X509 *a) + { + unsigned long ret=0; + EVP_MD_CTX ctx; + unsigned char md[16]; + char *f; + + EVP_MD_CTX_init(&ctx); + f=X509_NAME_oneline(a->cert_info->issuer,NULL,0); + ret=strlen(f); + EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); + EVP_DigestUpdate(&ctx,(unsigned char *)f,ret); + OPENSSL_free(f); + EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data, + (unsigned long)a->cert_info->serialNumber->length); + EVP_DigestFinal_ex(&ctx,&(md[0]),NULL); + ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| + ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) + )&0xffffffffL; + EVP_MD_CTX_cleanup(&ctx); + return(ret); + } +#endif + +int X509_issuer_name_cmp(const X509 *a, const X509 *b) + { + return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer)); + } + +int X509_subject_name_cmp(const X509 *a, const X509 *b) + { + return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject)); + } + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) + { + return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer)); + } + +X509_NAME *X509_get_issuer_name(X509 *a) + { + return(a->cert_info->issuer); + } + +unsigned long X509_issuer_name_hash(X509 *x) + { + return(X509_NAME_hash(x->cert_info->issuer)); + } + +X509_NAME *X509_get_subject_name(X509 *a) + { + return(a->cert_info->subject); + } + +ASN1_INTEGER *X509_get_serialNumber(X509 *a) + { + return(a->cert_info->serialNumber); + } + +unsigned long X509_subject_name_hash(X509 *x) + { + return(X509_NAME_hash(x->cert_info->subject)); + } + +#ifndef OPENSSL_NO_SHA +/* Compare two certificates: they must be identical for + * this to work. NB: Although "cmp" operations are generally + * prototyped to take "const" arguments (eg. for use in + * STACKs), the way X509 handling is - these operations may + * involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point + * where the "depth-first" constification tree has to halt + * with an evil cast. + */ +int X509_cmp(const X509 *a, const X509 *b) +{ + /* ensure hash is valid */ + X509_check_purpose((X509 *)a, -1, 0); + X509_check_purpose((X509 *)b, -1, 0); + + return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); +} +#endif + + +/* Case insensitive string comparision */ +static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + if (a->length != b->length) + return (a->length - b->length); + + for (i=0; i<a->length; i++) + { + int ca, cb; + + ca = tolower(a->data[i]); + cb = tolower(b->data[i]); + + if (ca != cb) + return(ca-cb); + } + return 0; +} + +/* Case insensitive string comparision with space normalization + * Space normalization - ignore leading, trailing spaces, + * multiple spaces between characters are replaced by single space + */ +static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + unsigned char *pa = NULL, *pb = NULL; + int la, lb; + + la = a->length; + lb = b->length; + pa = a->data; + pb = b->data; + + /* skip leading spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + + /* skip trailing spaces */ + while (la > 0 && isspace(pa[la-1])) + la--; + while (lb > 0 && isspace(pb[lb-1])) + lb--; + + /* compare strings with space normalization */ + while (la > 0 && lb > 0) + { + int ca, cb; + + /* compare character */ + ca = tolower(*pa); + cb = tolower(*pb); + if (ca != cb) + return (ca - cb); + + pa++; pb++; + la--; lb--; + + if (la <= 0 || lb <= 0) + break; + + /* is white space next character ? */ + if (isspace(*pa) && isspace(*pb)) + { + /* skip remaining white spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + } + } + if (la > 0 || lb > 0) + return la - lb; + + return 0; +} + +static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b) + { + int j; + j = a->length - b->length; + if (j) + return j; + return memcmp(a->data, b->data, a->length); + } + +#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING) + +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) + { + int i,j; + X509_NAME_ENTRY *na,*nb; + + unsigned long nabit, nbbit; + + j = sk_X509_NAME_ENTRY_num(a->entries) + - sk_X509_NAME_ENTRY_num(b->entries); + if (j) + return j; + for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) + { + na=sk_X509_NAME_ENTRY_value(a->entries,i); + nb=sk_X509_NAME_ENTRY_value(b->entries,i); + j=na->value->type-nb->value->type; + if (j) + { + nabit = ASN1_tag2bit(na->value->type); + nbbit = ASN1_tag2bit(nb->value->type); + if (!(nabit & STR_TYPE_CMP) || + !(nbbit & STR_TYPE_CMP)) + return j; + if (!asn1_string_memcmp(na->value, nb->value)) + j = 0; + } + else if (na->value->type == V_ASN1_PRINTABLESTRING) + j=nocase_spacenorm_cmp(na->value, nb->value); + else if (na->value->type == V_ASN1_IA5STRING + && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) + j=nocase_cmp(na->value, nb->value); + else + j = asn1_string_memcmp(na->value, nb->value); + if (j) return(j); + j=na->set-nb->set; + if (j) return(j); + } + + /* We will check the object types after checking the values + * since the values will more often be different than the object + * types. */ + for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) + { + na=sk_X509_NAME_ENTRY_value(a->entries,i); + nb=sk_X509_NAME_ENTRY_value(b->entries,i); + j=OBJ_cmp(na->object,nb->object); + if (j) return(j); + } + return(0); + } + +#ifndef OPENSSL_NO_MD5 +/* I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. */ +unsigned long X509_NAME_hash(X509_NAME *x) + { + unsigned long ret=0; + unsigned char md[16]; + EVP_MD_CTX md_ctx; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x,NULL); + EVP_MD_CTX_init(&md_ctx); + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL); + EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length); + EVP_DigestFinal_ex(&md_ctx,md,NULL); + EVP_MD_CTX_cleanup(&md_ctx); + + ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)| + ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L) + )&0xffffffffL; + return(ret); + } +#endif + +/* Search a stack of X509 for a match */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) + { + int i; + X509_CINF cinf; + X509 x,*x509=NULL; + + if(!sk) return NULL; + + x.cert_info= &cinf; + cinf.serialNumber=serial; + cinf.issuer=name; + + for (i=0; i<sk_X509_num(sk); i++) + { + x509=sk_X509_value(sk,i); + if (X509_issuer_and_serial_cmp(x509,&x) == 0) + return(x509); + } + return(NULL); + } + +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) + { + X509 *x509; + int i; + + for (i=0; i<sk_X509_num(sk); i++) + { + x509=sk_X509_value(sk,i); + if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0) + return(x509); + } + return(NULL); + } + +EVP_PKEY *X509_get_pubkey(X509 *x) + { + if ((x == NULL) || (x->cert_info == NULL)) + return(NULL); + return(X509_PUBKEY_get(x->cert_info->key)); + } + +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) + { + if(!x) return NULL; + return x->cert_info->key->public_key; + } + +int X509_check_private_key(X509 *x, EVP_PKEY *k) + { + EVP_PKEY *xk=NULL; + int ok=0; + + xk=X509_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) + { + case 1: + ok=1; + break; + case 0: + X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) + { + X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) + { + /* No idea */ + X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return(ok); + } diff --git a/openssl/crypto/x509/x509_d2.c b/openssl/crypto/x509/x509_d2.c new file mode 100644 index 000000000..51410cfd1 --- /dev/null +++ b/openssl/crypto/x509/x509_d2.c @@ -0,0 +1,107 @@ +/* crypto/x509/x509_d2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/crypto.h> +#include <openssl/x509.h> + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_set_default_paths(X509_STORE *ctx) + { + X509_LOOKUP *lookup; + + lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file()); + if (lookup == NULL) return(0); + X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); + + lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir()); + if (lookup == NULL) return(0); + X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return(1); + } + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) + { + X509_LOOKUP *lookup; + + if (file != NULL) + { + lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_file()); + if (lookup == NULL) return(0); + if (X509_LOOKUP_load_file(lookup,file,X509_FILETYPE_PEM) != 1) + return(0); + } + if (path != NULL) + { + lookup=X509_STORE_add_lookup(ctx,X509_LOOKUP_hash_dir()); + if (lookup == NULL) return(0); + if (X509_LOOKUP_add_dir(lookup,path,X509_FILETYPE_PEM) != 1) + return(0); + } + if ((path == NULL) && (file == NULL)) + return(0); + return(1); + } + +#endif diff --git a/openssl/crypto/x509/x509_def.c b/openssl/crypto/x509/x509_def.c new file mode 100644 index 000000000..e0ac151a7 --- /dev/null +++ b/openssl/crypto/x509/x509_def.c @@ -0,0 +1,81 @@ +/* crypto/x509/x509_def.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/crypto.h> +#include <openssl/x509.h> + +const char *X509_get_default_private_dir(void) + { return(X509_PRIVATE_DIR); } + +const char *X509_get_default_cert_area(void) + { return(X509_CERT_AREA); } + +const char *X509_get_default_cert_dir(void) + { return(X509_CERT_DIR); } + +const char *X509_get_default_cert_file(void) + { return(X509_CERT_FILE); } + +const char *X509_get_default_cert_dir_env(void) + { return(X509_CERT_DIR_EVP); } + +const char *X509_get_default_cert_file_env(void) + { return(X509_CERT_FILE_EVP); } + diff --git a/openssl/crypto/x509/x509_err.c b/openssl/crypto/x509/x509_err.c new file mode 100644 index 000000000..fb377292d --- /dev/null +++ b/openssl/crypto/x509/x509_err.c @@ -0,0 +1,161 @@ +/* crypto/x509/x509_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include <stdio.h> +#include <openssl/err.h> +#include <openssl/x509.h> + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) + +static ERR_STRING_DATA X509_str_functs[]= + { +{ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, +{ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, +{ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, +{ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, +{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, +{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, +{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, +{ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, +{ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), "X509_ATTRIBUTE_create_by_NID"}, +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), "X509_ATTRIBUTE_create_by_OBJ"}, +{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), "X509_ATTRIBUTE_create_by_txt"}, +{ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, +{ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, +{ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, +{ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, +{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), "X509_EXTENSION_create_by_NID"}, +{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), "X509_EXTENSION_create_by_OBJ"}, +{ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), "X509_get_pubkey_parameters"}, +{ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, +{ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, +{ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, +{ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, +{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), "X509_NAME_ENTRY_create_by_NID"}, +{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), "X509_NAME_ENTRY_create_by_txt"}, +{ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), "X509_NAME_ENTRY_set_object"}, +{ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, +{ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, +{ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, +{ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"}, +{ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, +{ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), "X509_REQ_check_private_key"}, +{ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, +{ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, +{ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, +{ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, +{ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, +{ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), "X509_STORE_CTX_get1_issuer"}, +{ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, +{ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, +{ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), "X509_STORE_CTX_purpose_inherit"}, +{ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, +{ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, +{ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, +{ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, +{0,NULL} + }; + +static ERR_STRING_DATA X509_str_reasons[]= + { +{ERR_REASON(X509_R_BAD_X509_FILETYPE) ,"bad x509 filetype"}, +{ERR_REASON(X509_R_BASE64_DECODE_ERROR) ,"base64 decode error"}, +{ERR_REASON(X509_R_CANT_CHECK_DH_KEY) ,"cant check dh key"}, +{ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),"cert already in hash table"}, +{ERR_REASON(X509_R_ERR_ASN1_LIB) ,"err asn1 lib"}, +{ERR_REASON(X509_R_INVALID_DIRECTORY) ,"invalid directory"}, +{ERR_REASON(X509_R_INVALID_FIELD_NAME) ,"invalid field name"}, +{ERR_REASON(X509_R_INVALID_TRUST) ,"invalid trust"}, +{ERR_REASON(X509_R_KEY_TYPE_MISMATCH) ,"key type mismatch"}, +{ERR_REASON(X509_R_KEY_VALUES_MISMATCH) ,"key values mismatch"}, +{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"}, +{ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"}, +{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"}, +{ERR_REASON(X509_R_SHOULD_RETRY) ,"should retry"}, +{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"}, +{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"}, +{ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) ,"unknown key type"}, +{ERR_REASON(X509_R_UNKNOWN_NID) ,"unknown nid"}, +{ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) ,"unknown purpose id"}, +{ERR_REASON(X509_R_UNKNOWN_TRUST_ID) ,"unknown trust id"}, +{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM),"unsupported algorithm"}, +{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) ,"wrong lookup type"}, +{ERR_REASON(X509_R_WRONG_TYPE) ,"wrong type"}, +{0,NULL} + }; + +#endif + +void ERR_load_X509_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(X509_str_functs[0].error) == NULL) + { + ERR_load_strings(0,X509_str_functs); + ERR_load_strings(0,X509_str_reasons); + } +#endif + } diff --git a/openssl/crypto/x509/x509_ext.c b/openssl/crypto/x509/x509_ext.c new file mode 100644 index 000000000..e7fdacb5e --- /dev/null +++ b/openssl/crypto/x509/x509_ext.c @@ -0,0 +1,210 @@ +/* crypto/x509/x509_ext.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <openssl/stack.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + + +int X509_CRL_get_ext_count(X509_CRL *x) + { + return(X509v3_get_ext_count(x->crl->extensions)); + } + +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->crl->extensions,nid,lastpos)); + } + +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->crl->extensions,obj,lastpos)); + } + +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->crl->extensions,crit,lastpos)); + } + +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc) + { + return(X509v3_get_ext(x->crl->extensions,loc)); + } + +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) + { + return(X509v3_delete_ext(x->crl->extensions,loc)); + } + +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); +} + +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} + +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->crl->extensions),ex,loc) != NULL); + } + +int X509_get_ext_count(X509 *x) + { + return(X509v3_get_ext_count(x->cert_info->extensions)); + } + +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->cert_info->extensions,nid,lastpos)); + } + +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->cert_info->extensions,obj,lastpos)); + } + +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->cert_info->extensions,crit,lastpos)); + } + +X509_EXTENSION *X509_get_ext(X509 *x, int loc) + { + return(X509v3_get_ext(x->cert_info->extensions,loc)); + } + +X509_EXTENSION *X509_delete_ext(X509 *x, int loc) + { + return(X509v3_delete_ext(x->cert_info->extensions,loc)); + } + +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->cert_info->extensions),ex,loc) != NULL); + } + +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); +} + +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} + +int X509_REVOKED_get_ext_count(X509_REVOKED *x) + { + return(X509v3_get_ext_count(x->extensions)); + } + +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->extensions,nid,lastpos)); + } + +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->extensions,obj,lastpos)); + } + +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->extensions,crit,lastpos)); + } + +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc) + { + return(X509v3_get_ext(x->extensions,loc)); + } + +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) + { + return(X509v3_delete_ext(x->extensions,loc)); + } + +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->extensions),ex,loc) != NULL); + } + +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->extensions, nid, crit, idx); +} + +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} + +IMPLEMENT_STACK_OF(X509_EXTENSION) +IMPLEMENT_ASN1_SET_OF(X509_EXTENSION) diff --git a/openssl/crypto/x509/x509_lu.c b/openssl/crypto/x509/x509_lu.c new file mode 100644 index 000000000..cd2cfb6d8 --- /dev/null +++ b/openssl/crypto/x509/x509_lu.c @@ -0,0 +1,567 @@ +/* crypto/x509/x509_lu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/lhash.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) + { + X509_LOOKUP *ret; + + ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) return NULL; + + ret->init=0; + ret->skip=0; + ret->method=method; + ret->method_data=NULL; + ret->store_ctx=NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) + { + OPENSSL_free(ret); + return NULL; + } + return ret; + } + +void X509_LOOKUP_free(X509_LOOKUP *ctx) + { + if (ctx == NULL) return; + if ( (ctx->method != NULL) && + (ctx->method->free != NULL)) + ctx->method->free(ctx); + OPENSSL_free(ctx); + } + +int X509_LOOKUP_init(X509_LOOKUP *ctx) + { + if (ctx->method == NULL) return 0; + if (ctx->method->init != NULL) + return ctx->method->init(ctx); + else + return 1; + } + +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) + { + if (ctx->method == NULL) return 0; + if (ctx->method->shutdown != NULL) + return ctx->method->shutdown(ctx); + else + return 1; + } + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) + { + if (ctx->method == NULL) return -1; + if (ctx->method->ctrl != NULL) + return ctx->method->ctrl(ctx,cmd,argc,argl,ret); + else + return 1; + } + +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) + { + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) + return X509_LU_FAIL; + if (ctx->skip) return 0; + return ctx->method->get_by_subject(ctx,type,name,ret); + } + +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret) + { + if ((ctx->method == NULL) || + (ctx->method->get_by_issuer_serial == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret); + } + +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret) + { + if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret); + } + +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret) + { + if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_alias(ctx,type,str,len,ret); + } + + +static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) + { + int ret; + + ret=((*a)->type - (*b)->type); + if (ret) return ret; + switch ((*a)->type) + { + case X509_LU_X509: + ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509); + break; + case X509_LU_CRL: + ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl); + break; + default: + /* abort(); */ + return 0; + } + return ret; + } + +X509_STORE *X509_STORE_new(void) + { + X509_STORE *ret; + + if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) + return NULL; + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + ret->cache=1; + ret->get_cert_methods=sk_X509_LOOKUP_new_null(); + ret->verify=0; + ret->verify_cb=0; + + if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) + return NULL; + + ret->get_issuer = 0; + ret->check_issued = 0; + ret->check_revocation = 0; + ret->get_crl = 0; + ret->check_crl = 0; + ret->cert_crl = 0; + ret->cleanup = 0; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data); + ret->references=1; + return ret; + } + +static void cleanup(X509_OBJECT *a) + { + if (a->type == X509_LU_X509) + { + X509_free(a->data.x509); + } + else if (a->type == X509_LU_CRL) + { + X509_CRL_free(a->data.crl); + } + else + { + /* abort(); */ + } + + OPENSSL_free(a); + } + +void X509_STORE_free(X509_STORE *vfy) + { + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + sk=vfy->get_cert_methods; + for (i=0; i<sk_X509_LOOKUP_num(sk); i++) + { + lu=sk_X509_LOOKUP_value(sk,i); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); + if (vfy->param) + X509_VERIFY_PARAM_free(vfy->param); + OPENSSL_free(vfy); + } + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) + { + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk=v->get_cert_methods; + for (i=0; i<sk_X509_LOOKUP_num(sk); i++) + { + lu=sk_X509_LOOKUP_value(sk,i); + if (m == lu->method) + { + return lu; + } + } + /* a new one */ + lu=X509_LOOKUP_new(m); + if (lu == NULL) + return NULL; + else + { + lu->store_ctx=v; + if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) + return lu; + else + { + X509_LOOKUP_free(lu); + return NULL; + } + } + } + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret) + { + X509_STORE *ctx=vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp,*tmp; + int i,j; + + tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); + + if (tmp == NULL) + { + for (i=vs->current_method; i<sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) + { + lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i); + j=X509_LOOKUP_by_subject(lu,type,name,&stmp); + if (j < 0) + { + vs->current_method=j; + return j; + } + else if (j) + { + tmp= &stmp; + break; + } + } + vs->current_method=0; + if (tmp == NULL) + return 0; + } + +/* if (ret->data.ptr != NULL) + X509_OBJECT_free_contents(ret); */ + + ret->type=tmp->type; + ret->data.ptr=tmp->data.ptr; + + X509_OBJECT_up_ref_count(ret); + + return 1; + } + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) + { + X509_OBJECT *obj; + int ret=1; + + if (x == NULL) return 0; + obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) + { + X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type=X509_LU_X509; + obj->data.x509=x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) + { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret=0; + } + else sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; + } + +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) + { + X509_OBJECT *obj; + int ret=1; + + if (x == NULL) return 0; + obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) + { + X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type=X509_LU_CRL; + obj->data.crl=x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) + { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret=0; + } + else sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; + } + +void X509_OBJECT_up_ref_count(X509_OBJECT *a) + { + switch (a->type) + { + case X509_LU_X509: + CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509); + break; + case X509_LU_CRL: + CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL); + break; + } + } + +void X509_OBJECT_free_contents(X509_OBJECT *a) + { + switch (a->type) + { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } + } + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) + { + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + + stmp.type=type; + switch (type) + { + case X509_LU_X509: + stmp.data.x509= &x509_s; + x509_s.cert_info= &cinf_s; + cinf_s.subject=name; + break; + case X509_LU_CRL: + stmp.data.crl= &crl_s; + crl_s.crl= &crl_info_s; + crl_info_s.issuer=name; + break; + default: + /* abort(); */ + return -1; + } + + return sk_X509_OBJECT_find(h,&stmp); + } + +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) +{ + int idx; + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx==-1) return NULL; + return sk_X509_OBJECT_value(h, idx); +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) +{ + int idx, i; + X509_OBJECT *obj; + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) return NULL; + if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) + { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) + return NULL; + if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } + return NULL; +} + + +/* Try to get issuer certificate from store. Due to limitations + * of the API this can only retrieve a single certificate matching + * a given subject name. However it will fill the cache with all + * matching certificates, so we can examine the cache for all + * matches. + * + * Return values are: + * 1 lookup successful. + * 0 certificate not found. + * -1 some other error. + */ + + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int i, ok, idx; + xn=X509_get_issuer_name(x); + ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); + if (ok != X509_LU_X509) + { + if (ok == X509_LU_RETRY) + { + X509_OBJECT_free_contents(&obj); + X509err(X509_F_X509_STORE_CTX_GET1_ISSUER,X509_R_SHOULD_RETRY); + return -1; + } + else if (ok != X509_LU_FAIL) + { + X509_OBJECT_free_contents(&obj); + /* not good :-(, break anyway */ + return -1; + } + return 0; + } + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, obj.data.x509)) + { + *issuer = obj.data.x509; + return 1; + } + X509_OBJECT_free_contents(&obj); + /* Else find index of first matching cert */ + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + /* This shouldn't normally happen since we already have one match */ + if (idx == -1) return 0; + + /* Look through all matching certificates for a suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) + { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* See if we've ran out of matches */ + if (pobj->type != X509_LU_X509) return 0; + if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0; + if (ctx->check_issued(ctx, x, pobj->data.x509)) + { + *issuer = pobj->data.x509; + X509_OBJECT_up_ref_count(pobj); + return 1; + } + } + return 0; +} + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) + { + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); + } + +int X509_STORE_set_depth(X509_STORE *ctx, int depth) + { + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; + } + +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) + { + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); + } + +int X509_STORE_set_trust(X509_STORE *ctx, int trust) + { + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); + } + +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) + { + return X509_VERIFY_PARAM_set1(ctx->param, param); + } + +IMPLEMENT_STACK_OF(X509_LOOKUP) +IMPLEMENT_STACK_OF(X509_OBJECT) diff --git a/openssl/crypto/x509/x509_obj.c b/openssl/crypto/x509/x509_obj.c new file mode 100644 index 000000000..1e718f76e --- /dev/null +++ b/openssl/crypto/x509/x509_obj.c @@ -0,0 +1,226 @@ +/* crypto/x509/x509_obj.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/lhash.h> +#include <openssl/objects.h> +#include <openssl/x509.h> +#include <openssl/buffer.h> + +char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) + { + X509_NAME_ENTRY *ne; +int i; + int n,lold,l,l1,l2,num,j,type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b=NULL; + static char hex[17]="0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; +#ifdef CHARSET_EBCDIC + char ebcdic_buf[1024]; +#endif + + if (buf == NULL) + { + if ((b=BUF_MEM_new()) == NULL) goto err; + if (!BUF_MEM_grow(b,200)) goto err; + b->data[0]='\0'; + len=200; + } + if (a == NULL) + { + if(b) + { + buf=b->data; + OPENSSL_free(b); + } + strncpy(buf,"NO X509_NAME",len); + buf[len-1]='\0'; + return buf; + } + + len--; /* space for '\0' */ + l=0; + for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++) + { + ne=sk_X509_NAME_ENTRY_value(a->entries,i); + n=OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL)) + { + i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object); + s=tmp_buf; + } + l1=strlen(s); + + type=ne->value->type; + num=ne->value->length; + q=ne->value->data; +#ifdef CHARSET_EBCDIC + if (type == V_ASN1_GENERALSTRING || + type == V_ASN1_VISIBLESTRING || + type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_TELETEXSTRING || + type == V_ASN1_VISIBLESTRING || + type == V_ASN1_IA5STRING) { + ascii2ebcdic(ebcdic_buf, q, + (num > sizeof ebcdic_buf) + ? sizeof ebcdic_buf : num); + q=ebcdic_buf; + } +#endif + + if ((type == V_ASN1_GENERALSTRING) && ((num%4) == 0)) + { + gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=0; + for (j=0; j<num; j++) + if (q[j] != 0) gs_doit[j&3]=1; + + if (gs_doit[0]|gs_doit[1]|gs_doit[2]) + gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1; + else + { + gs_doit[0]=gs_doit[1]=gs_doit[2]=0; + gs_doit[3]=1; + } + } + else + gs_doit[0]=gs_doit[1]=gs_doit[2]=gs_doit[3]=1; + + for (l2=j=0; j<num; j++) + { + if (!gs_doit[j&3]) continue; + l2++; +#ifndef CHARSET_EBCDIC + if ((q[j] < ' ') || (q[j] > '~')) l2+=3; +#else + if ((os_toascii[q[j]] < os_toascii[' ']) || + (os_toascii[q[j]] > os_toascii['~'])) l2+=3; +#endif + } + + lold=l; + l+=1+l1+1+l2; + if (b != NULL) + { + if (!BUF_MEM_grow(b,l+1)) goto err; + p= &(b->data[lold]); + } + else if (l > len) + { + break; + } + else + p= &(buf[lold]); + *(p++)='/'; + memcpy(p,s,(unsigned int)l1); p+=l1; + *(p++)='='; + +#ifndef CHARSET_EBCDIC /* q was assigned above already. */ + q=ne->value->data; +#endif + + for (j=0; j<num; j++) + { + if (!gs_doit[j&3]) continue; +#ifndef CHARSET_EBCDIC + n=q[j]; + if ((n < ' ') || (n > '~')) + { + *(p++)='\\'; + *(p++)='x'; + *(p++)=hex[(n>>4)&0x0f]; + *(p++)=hex[n&0x0f]; + } + else + *(p++)=n; +#else + n=os_toascii[q[j]]; + if ((n < os_toascii[' ']) || + (n > os_toascii['~'])) + { + *(p++)='\\'; + *(p++)='x'; + *(p++)=hex[(n>>4)&0x0f]; + *(p++)=hex[n&0x0f]; + } + else + *(p++)=q[j]; +#endif + } + *p='\0'; + } + if (b != NULL) + { + p=b->data; + OPENSSL_free(b); + } + else + p=buf; + if (i == 0) + *p = '\0'; + return(p); +err: + X509err(X509_F_X509_NAME_ONELINE,ERR_R_MALLOC_FAILURE); + if (b != NULL) BUF_MEM_free(b); + return(NULL); + } + diff --git a/openssl/crypto/x509/x509_r2x.c b/openssl/crypto/x509/x509_r2x.c new file mode 100644 index 000000000..254a14693 --- /dev/null +++ b/openssl/crypto/x509/x509_r2x.c @@ -0,0 +1,114 @@ +/* crypto/x509/x509_r2x.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/asn1.h> +#include <openssl/x509.h> +#include <openssl/objects.h> +#include <openssl/buffer.h> + +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) + { + X509 *ret=NULL; + X509_CINF *xi=NULL; + X509_NAME *xn; + + if ((ret=X509_new()) == NULL) + { + X509err(X509_F_X509_REQ_TO_X509,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* duplicate the request */ + xi=ret->cert_info; + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) + { + if ((xi->version=M_ASN1_INTEGER_new()) == NULL) goto err; + if (!ASN1_INTEGER_set(xi->version,2)) goto err; +/* xi->extensions=ri->attributes; <- bad, should not ever be done + ri->attributes=NULL; */ + } + + xn=X509_REQ_get_subject_name(r); + if (X509_set_subject_name(ret,X509_NAME_dup(xn)) == 0) + goto err; + if (X509_set_issuer_name(ret,X509_NAME_dup(xn)) == 0) + goto err; + + if (X509_gmtime_adj(xi->validity->notBefore,0) == NULL) + goto err; + if (X509_gmtime_adj(xi->validity->notAfter,(long)60*60*24*days) == NULL) + goto err; + + X509_set_pubkey(ret,X509_REQ_get_pubkey(r)); + + if (!X509_sign(ret,pkey,EVP_md5())) + goto err; + if (0) + { +err: + X509_free(ret); + ret=NULL; + } + return(ret); + } + diff --git a/openssl/crypto/x509/x509_req.c b/openssl/crypto/x509/x509_req.c new file mode 100644 index 000000000..3872e1fb6 --- /dev/null +++ b/openssl/crypto/x509/x509_req.c @@ -0,0 +1,324 @@ +/* crypto/x509/x509_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/asn1.h> +#include <openssl/x509.h> +#include <openssl/objects.h> +#include <openssl/buffer.h> +#include <openssl/pem.h> + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) + { + X509_REQ *ret; + X509_REQ_INFO *ri; + int i; + EVP_PKEY *pktmp; + + ret=X509_REQ_new(); + if (ret == NULL) + { + X509err(X509_F_X509_TO_X509_REQ,ERR_R_MALLOC_FAILURE); + goto err; + } + + ri=ret->req_info; + + ri->version->length=1; + ri->version->data=(unsigned char *)OPENSSL_malloc(1); + if (ri->version->data == NULL) goto err; + ri->version->data[0]=0; /* version == 0 */ + + if (!X509_REQ_set_subject_name(ret,X509_get_subject_name(x))) + goto err; + + pktmp = X509_get_pubkey(x); + i=X509_REQ_set_pubkey(ret,pktmp); + EVP_PKEY_free(pktmp); + if (!i) goto err; + + if (pkey != NULL) + { + if (!X509_REQ_sign(ret,pkey,md)) + goto err; + } + return(ret); +err: + X509_REQ_free(ret); + return(NULL); + } + +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) + { + if ((req == NULL) || (req->req_info == NULL)) + return(NULL); + return(X509_PUBKEY_get(req->req_info->pubkey)); + } + +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) + { + EVP_PKEY *xk=NULL; + int ok=0; + + xk=X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) + { + case 1: + ok=1; + break; + case 0: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) + { + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) + { + /* No idea */ + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return(ok); + } + +/* It seems several organisations had the same idea of including a list of + * extensions in a certificate request. There are at least two OIDs that are + * used and there may be more: so the list is configurable. + */ + +static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef}; + +static int *ext_nids = ext_nid_list; + +int X509_REQ_extension_nid(int req_nid) +{ + int i, nid; + for(i = 0; ; i++) { + nid = ext_nids[i]; + if(nid == NID_undef) return 0; + else if (req_nid == nid) return 1; + } +} + +int *X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void X509_REQ_set_extension_nids(int *nids) +{ + ext_nids = nids; +} + +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) + { + X509_ATTRIBUTE *attr; + ASN1_TYPE *ext = NULL; + int idx, *pnid; + const unsigned char *p; + + if ((req == NULL) || (req->req_info == NULL) || !ext_nids) + return(NULL); + for (pnid = ext_nids; *pnid != NID_undef; pnid++) + { + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); + if (idx == -1) + continue; + attr = X509_REQ_get_attr(req, idx); + if(attr->single) ext = attr->value.single; + else if(sk_ASN1_TYPE_num(attr->value.set)) + ext = sk_ASN1_TYPE_value(attr->value.set, 0); + break; + } + if(!ext || (ext->type != V_ASN1_SEQUENCE)) + return NULL; + p = ext->value.sequence->data; + return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p, + ext->value.sequence->length, + d2i_X509_EXTENSION, X509_EXTENSION_free, + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); +} + +/* Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non standard one. + */ + +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid) +{ + unsigned char *p = NULL, *q; + long len; + ASN1_TYPE *at = NULL; + X509_ATTRIBUTE *attr = NULL; + if(!(at = ASN1_TYPE_new()) || + !(at->value.sequence = ASN1_STRING_new())) goto err; + + at->type = V_ASN1_SEQUENCE; + /* Generate encoding of extensions */ + len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION, + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); + if(!(p = OPENSSL_malloc(len))) goto err; + q = p; + i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION, + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); + at->value.sequence->data = p; + p = NULL; + at->value.sequence->length = len; + if(!(attr = X509_ATTRIBUTE_new())) goto err; + if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; + if(!sk_ASN1_TYPE_push(attr->value.set, at)) goto err; + at = NULL; + attr->single = 0; + attr->object = OBJ_nid2obj(nid); + if (!req->req_info->attributes) + { + if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) + goto err; + } + if(!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) goto err; + return 1; + err: + if(p) OPENSSL_free(p); + X509_ATTRIBUTE_free(attr); + ASN1_TYPE_free(at); + return 0; +} +/* This is the normal usage: use the "official" OID */ +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} + +/* Request attribute functions */ + +int X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} + +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} + +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} + +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} + +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if(X509at_add1_attr(&req->req_info->attributes, attr)) return 1; + return 0; +} + +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if(X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + type, bytes, len)) return 1; + return 0; +} + +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len) +{ + if(X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + type, bytes, len)) return 1; + return 0; +} + +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if(X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + type, bytes, len)) return 1; + return 0; +} diff --git a/openssl/crypto/x509/x509_set.c b/openssl/crypto/x509/x509_set.c new file mode 100644 index 000000000..aaf61ca06 --- /dev/null +++ b/openssl/crypto/x509/x509_set.c @@ -0,0 +1,150 @@ +/* crypto/x509/x509_set.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> + +int X509_set_version(X509 *x, long version) + { + if (x == NULL) return(0); + if (x->cert_info->version == NULL) + { + if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL) + return(0); + } + return(ASN1_INTEGER_set(x->cert_info->version,version)); + } + +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) + { + ASN1_INTEGER *in; + + if (x == NULL) return(0); + in=x->cert_info->serialNumber; + if (in != serial) + { + in=M_ASN1_INTEGER_dup(serial); + if (in != NULL) + { + M_ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber=in; + } + } + return(in != NULL); + } + +int X509_set_issuer_name(X509 *x, X509_NAME *name) + { + if ((x == NULL) || (x->cert_info == NULL)) return(0); + return(X509_NAME_set(&x->cert_info->issuer,name)); + } + +int X509_set_subject_name(X509 *x, X509_NAME *name) + { + if ((x == NULL) || (x->cert_info == NULL)) return(0); + return(X509_NAME_set(&x->cert_info->subject,name)); + } + +int X509_set_notBefore(X509 *x, ASN1_TIME *tm) + { + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); + in=x->cert_info->validity->notBefore; + if (in != tm) + { + in=M_ASN1_TIME_dup(tm); + if (in != NULL) + { + M_ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore=in; + } + } + return(in != NULL); + } + +int X509_set_notAfter(X509 *x, ASN1_TIME *tm) + { + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); + in=x->cert_info->validity->notAfter; + if (in != tm) + { + in=M_ASN1_TIME_dup(tm); + if (in != NULL) + { + M_ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter=in; + } + } + return(in != NULL); + } + +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) + { + if ((x == NULL) || (x->cert_info == NULL)) return(0); + return(X509_PUBKEY_set(&(x->cert_info->key),pkey)); + } + + + diff --git a/openssl/crypto/x509/x509_trs.c b/openssl/crypto/x509/x509_trs.c new file mode 100644 index 000000000..ed1870058 --- /dev/null +++ b/openssl/crypto/x509/x509_trs.c @@ -0,0 +1,287 @@ +/* x509_trs.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/x509v3.h> + + +static int tr_cmp(const X509_TRUST * const *a, + const X509_TRUST * const *b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; + +/* WARNING: the following table should be kept in order of trust + * and without any gaps so we can just subtract the minimum trust + * value to get an index into the table + */ + +static X509_TRUST trstandard[] = { +{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, +{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL}, +{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL}, +{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, +{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL}, +{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL}, +{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +IMPLEMENT_STACK_OF(X509_TRUST) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST * const *a, + const X509_TRUST * const *b) +{ + return (*a)->trust - (*b)->trust; +} + +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int) +{ + int (*oldtrust)(int , X509 *, int); + oldtrust = default_trust; + default_trust = trust; + return oldtrust; +} + + +int X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + if(id == -1) return 1; + idx = X509_TRUST_get_by_id(id); + if(idx == -1) return default_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} + +int X509_TRUST_get_count(void) +{ + if(!trtable) return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} + +X509_TRUST * X509_TRUST_get0(int idx) +{ + if(idx < 0) return NULL; + if(idx < (int)X509_TRUST_COUNT) return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} + +int X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + int idx; + if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if(!trtable) return -1; + idx = sk_X509_TRUST_find(trtable, &tmp); + if(idx == -1) return -1; + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if(X509_TRUST_get_by_id(trust) == -1) { + X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + /* This is set according to what we change: application can't set it */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if(idx == -1) { + if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else trtmp = X509_TRUST_get0(idx); + + /* OPENSSL_free existing name if dynamic */ + if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name); + /* dup supplied name */ + if(!(trtmp->name = BUF_strdup(name))) { + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); + return 0; + } + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If its a new entry manage the dynamic table */ + if(idx == -1) { + if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +static void trtable_free(X509_TRUST *p) + { + if(!p) return; + if (p->flags & X509_TRUST_DYNAMIC) + { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(p->name); + OPENSSL_free(p); + } + } + +void X509_TRUST_cleanup(void) +{ + unsigned int i; + for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i); + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} + +int X509_TRUST_get_flags(X509_TRUST *xp) +{ + return xp->flags; +} + +char *X509_TRUST_get0_name(X509_TRUST *xp) +{ + return xp->name; +} + +int X509_TRUST_get_trust(X509_TRUST *xp) +{ + return xp->trust; +} + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if(x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* we don't have any trust settings: for compatibility + * we return trusted if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if(x->aux) return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED; + else return X509_TRUST_UNTRUSTED; +} + +static int obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i; + X509_CERT_AUX *ax; + ax = x->aux; + if(!ax) return X509_TRUST_UNTRUSTED; + if(ax->reject) { + for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED; + } + } + if(ax->trust) { + for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} + diff --git a/openssl/crypto/x509/x509_txt.c b/openssl/crypto/x509/x509_txt.c new file mode 100644 index 000000000..73a8ec726 --- /dev/null +++ b/openssl/crypto/x509/x509_txt.c @@ -0,0 +1,173 @@ +/* crypto/x509/x509_txt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include <errno.h> + +#include "cryptlib.h" +#include <openssl/lhash.h> +#include <openssl/buffer.h> +#include <openssl/evp.h> +#include <openssl/asn1.h> +#include <openssl/x509.h> +#include <openssl/objects.h> + +const char *X509_verify_cert_error_string(long n) + { + static char buf[100]; + + switch ((int)n) + { + case X509_V_OK: + return("ok"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return("unable to get issuer certificate"); + case X509_V_ERR_UNABLE_TO_GET_CRL: + return("unable to get certificate CRL"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return("unable to decrypt certificate's signature"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return("unable to decrypt CRL's signature"); + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return("unable to decode issuer public key"); + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return("certificate signature failure"); + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return("CRL signature failure"); + case X509_V_ERR_CERT_NOT_YET_VALID: + return("certificate is not yet valid"); + case X509_V_ERR_CRL_NOT_YET_VALID: + return("CRL is not yet valid"); + case X509_V_ERR_CERT_HAS_EXPIRED: + return("certificate has expired"); + case X509_V_ERR_CRL_HAS_EXPIRED: + return("CRL has expired"); + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return("format error in certificate's notBefore field"); + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return("format error in certificate's notAfter field"); + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return("format error in CRL's lastUpdate field"); + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return("format error in CRL's nextUpdate field"); + case X509_V_ERR_OUT_OF_MEM: + return("out of memory"); + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return("self signed certificate"); + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return("self signed certificate in certificate chain"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return("unable to get local issuer certificate"); + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return("unable to verify the first certificate"); + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return("certificate chain too long"); + case X509_V_ERR_CERT_REVOKED: + return("certificate revoked"); + case X509_V_ERR_INVALID_CA: + return ("invalid CA certificate"); + case X509_V_ERR_INVALID_NON_CA: + return ("invalid non-CA certificate (has CA markings)"); + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return ("path length constraint exceeded"); + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return("proxy path length constraint exceeded"); + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return("proxy certificates not allowed, please set the appropriate flag"); + case X509_V_ERR_INVALID_PURPOSE: + return ("unsupported certificate purpose"); + case X509_V_ERR_CERT_UNTRUSTED: + return ("certificate not trusted"); + case X509_V_ERR_CERT_REJECTED: + return ("certificate rejected"); + case X509_V_ERR_APPLICATION_VERIFICATION: + return("application verification failure"); + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return("subject issuer mismatch"); + case X509_V_ERR_AKID_SKID_MISMATCH: + return("authority and subject key identifier mismatch"); + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return("authority and issuer serial number mismatch"); + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return("key usage does not include certificate signing"); + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return("unable to get CRL issuer certificate"); + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return("unhandled critical extension"); + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return("key usage does not include CRL signing"); + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return("key usage does not include digital signature"); + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return("unhandled critical CRL extension"); + case X509_V_ERR_INVALID_EXTENSION: + return("invalid or inconsistent certificate extension"); + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return("invalid or inconsistent certificate policy extension"); + case X509_V_ERR_NO_EXPLICIT_POLICY: + return("no explicit policy"); + case X509_V_ERR_UNNESTED_RESOURCE: + return("RFC 3779 resource not subset of parent's resources"); + default: + BIO_snprintf(buf,sizeof buf,"error number %ld",n); + return(buf); + } + } + + diff --git a/openssl/crypto/x509/x509_v3.c b/openssl/crypto/x509/x509_v3.c new file mode 100644 index 000000000..42e6f0ab0 --- /dev/null +++ b/openssl/crypto/x509/x509_v3.c @@ -0,0 +1,274 @@ +/* crypto/x509/x509_v3.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <openssl/stack.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) + { + if (x == NULL) return(0); + return(sk_X509_EXTENSION_num(x)); + } + +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, + int lastpos) + { + ASN1_OBJECT *obj; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) return(-2); + return(X509v3_get_ext_by_OBJ(x,obj,lastpos)); + } + +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, ASN1_OBJECT *obj, + int lastpos) + { + int n; + X509_EXTENSION *ex; + + if (sk == NULL) return(-1); + lastpos++; + if (lastpos < 0) + lastpos=0; + n=sk_X509_EXTENSION_num(sk); + for ( ; lastpos < n; lastpos++) + { + ex=sk_X509_EXTENSION_value(sk,lastpos); + if (OBJ_cmp(ex->object,obj) == 0) + return(lastpos); + } + return(-1); + } + +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) + { + int n; + X509_EXTENSION *ex; + + if (sk == NULL) return(-1); + lastpos++; + if (lastpos < 0) + lastpos=0; + n=sk_X509_EXTENSION_num(sk); + for ( ; lastpos < n; lastpos++) + { + ex=sk_X509_EXTENSION_value(sk,lastpos); + if ( ((ex->critical > 0) && crit) || + ((ex->critical <= 0) && !crit)) + return(lastpos); + } + return(-1); + } + +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) + { + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_EXTENSION_value(x,loc); + } + +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) + { + X509_EXTENSION *ret; + + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return(NULL); + ret=sk_X509_EXTENSION_delete(x,loc); + return(ret); + } + +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc) + { + X509_EXTENSION *new_ex=NULL; + int n; + STACK_OF(X509_EXTENSION) *sk=NULL; + + if (x == NULL) + { + X509err(X509_F_X509V3_ADD_EXT,ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) + { + if ((sk=sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } + else + sk= *x; + + n=sk_X509_EXTENSION_num(sk); + if (loc > n) loc=n; + else if (loc < 0) loc=n; + + if ((new_ex=X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk,new_ex,loc)) + goto err; + if (*x == NULL) + *x=sk; + return(sk); +err: + X509err(X509_F_X509V3_ADD_EXT,ERR_R_MALLOC_FAILURE); +err2: + if (new_ex != NULL) X509_EXTENSION_free(new_ex); + if (sk != NULL) sk_X509_EXTENSION_free(sk); + return(NULL); + } + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, + int crit, ASN1_OCTET_STRING *data) + { + ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) + { + X509err(X509_F_X509_EXTENSION_CREATE_BY_NID,X509_R_UNKNOWN_NID); + return(NULL); + } + ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data); + if (ret == NULL) ASN1_OBJECT_free(obj); + return(ret); + } + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data) + { + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) + { + if ((ret=X509_EXTENSION_new()) == NULL) + { + X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE); + return(NULL); + } + } + else + ret= *ex; + + if (!X509_EXTENSION_set_object(ret,obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret,crit)) + goto err; + if (!X509_EXTENSION_set_data(ret,data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) *ex=ret; + return(ret); +err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return(NULL); + } + +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj) + { + if ((ex == NULL) || (obj == NULL)) + return(0); + ASN1_OBJECT_free(ex->object); + ex->object=OBJ_dup(obj); + return(1); + } + +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) + { + if (ex == NULL) return(0); + ex->critical=(crit)?0xFF:-1; + return(1); + } + +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) + { + int i; + + if (ex == NULL) return(0); + i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length); + if (!i) return(0); + return(1); + } + +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) + { + if (ex == NULL) return(NULL); + return(ex->object); + } + +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) + { + if (ex == NULL) return(NULL); + return(ex->value); + } + +int X509_EXTENSION_get_critical(X509_EXTENSION *ex) + { + if (ex == NULL) return(0); + if(ex->critical > 0) return 1; + return 0; + } diff --git a/openssl/crypto/x509/x509_vfy.c b/openssl/crypto/x509/x509_vfy.c new file mode 100644 index 000000000..336c40ddd --- /dev/null +++ b/openssl/crypto/x509/x509_vfy.c @@ -0,0 +1,1552 @@ +/* crypto/x509/x509_vfy.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include <errno.h> + +#include "cryptlib.h" +#include <openssl/crypto.h> +#include <openssl/lhash.h> +#include <openssl/buffer.h> +#include <openssl/evp.h> +#include <openssl/asn1.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/objects.h> + +static int null_callback(int ok,X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx); +static int check_policy(X509_STORE_CTX *ctx); +static int internal_verify(X509_STORE_CTX *ctx); +const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT; + + +static int null_callback(int ok, X509_STORE_CTX *e) + { + return ok; + } + +#if 0 +static int x509_subject_cmp(X509 **a, X509 **b) + { + return X509_subject_name_cmp(*a,*b); + } +#endif + +int X509_verify_cert(X509_STORE_CTX *ctx) + { + X509 *x,*xtmp,*chain_ss=NULL; + X509_NAME *xn; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth,i,ok=0; + int num; + int (*cb)(int xok,X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp=NULL; + if (ctx->cert == NULL) + { + X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + return -1; + } + + cb=ctx->verify_cb; + + /* first we make sure the chain we are going to build is + * present and that the first entry is in place */ + if (ctx->chain == NULL) + { + if ( ((ctx->chain=sk_X509_new_null()) == NULL) || + (!sk_X509_push(ctx->chain,ctx->cert))) + { + X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509); + ctx->last_untrusted=1; + } + + /* We use a temporary STACK so we can chop and hack at it */ + if (ctx->untrusted != NULL + && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL) + { + X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); + goto end; + } + + num=sk_X509_num(ctx->chain); + x=sk_X509_value(ctx->chain,num-1); + depth=param->depth; + + + for (;;) + { + /* If we have enough, we break */ + if (depth < num) break; /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error + * code later. + */ + + /* If we are self signed, we break */ + xn=X509_get_issuer_name(x); + if (ctx->check_issued(ctx, x,x)) break; + + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) + { + xtmp=find_issuer(ctx, sktmp,x); + if (xtmp != NULL) + { + if (!sk_X509_push(ctx->chain,xtmp)) + { + X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); + (void)sk_X509_delete_ptr(sktmp,xtmp); + ctx->last_untrusted++; + x=xtmp; + num++; + /* reparse the full chain for + * the next one */ + continue; + } + } + break; + } + + /* at this point, chain should contain a list of untrusted + * certificates. We now need to add at least one trusted one, + * if possible, otherwise we complain. */ + + /* Examine last certificate in chain and see if it + * is self signed. + */ + + i=sk_X509_num(ctx->chain); + x=sk_X509_value(ctx->chain,i-1); + xn = X509_get_subject_name(x); + if (ctx->check_issued(ctx, x, x)) + { + /* we have a self signed certificate */ + if (sk_X509_num(ctx->chain) == 1) + { + /* We have a single self signed certificate: see if + * we can find it in the store. We must have an exact + * match to avoid possible impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) + { + ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert=x; + ctx->error_depth=i-1; + if (ok == 1) X509_free(xtmp); + bad_chain = 1; + ok=cb(0,ctx); + if (!ok) goto end; + } + else + { + /* We have a match: replace certificate with store version + * so we get any trust settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted=0; + } + } + else + { + /* extract and save self signed certificate for later use */ + chain_ss=sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + x=sk_X509_value(ctx->chain,num-1); + } + } + + /* We now lookup certs from the certificate store */ + for (;;) + { + /* If we have enough, we break */ + if (depth < num) break; + + /* If we are self signed, we break */ + xn=X509_get_issuer_name(x); + if (ctx->check_issued(ctx,x,x)) break; + + ok = ctx->get_issuer(&xtmp, ctx, x); + + if (ok < 0) return ok; + if (ok == 0) break; + + x = xtmp; + if (!sk_X509_push(ctx->chain,x)) + { + X509_free(xtmp); + X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); + return 0; + } + num++; + } + + /* we now have our chain, lets check it... */ + xn=X509_get_issuer_name(x); + + /* Is last certificate looked up self signed? */ + if (!ctx->check_issued(ctx,x,x)) + { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) + { + if (ctx->last_untrusted >= num) + ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert=x; + } + else + { + + sk_X509_push(ctx->chain,chain_ss); + num++; + ctx->last_untrusted=num; + ctx->current_cert=chain_ss; + ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss=NULL; + } + + ctx->error_depth=num-1; + bad_chain = 1; + ok=cb(0,ctx); + if (!ok) goto end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) goto end; + + /* The chain extensions are OK: check trust */ + + if (param->trust > 0) ok = check_trust(ctx); + + if (!ok) goto end; + + /* We may as well copy down any DSA parameters that are required */ + X509_get_pubkey_parameters(NULL,ctx->chain); + + /* Check revocation status: we do this after copying parameters + * because they may be needed for CRL signature verification. + */ + + ok = ctx->check_revocation(ctx); + if(!ok) goto end; + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok=ctx->verify(ctx); + else + ok=internal_verify(ctx); + if(!ok) goto end; + +#ifndef OPENSSL_NO_RFC3779 + /* RFC 3779 path validation, now that CRL check has been done */ + ok = v3_asid_validate_path(ctx); + if (!ok) goto end; + ok = v3_addr_validate_path(ctx); + if (!ok) goto end; +#endif + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + if(!ok) goto end; + if (0) + { +end: + X509_get_pubkey_parameters(NULL,ctx->chain); + } + if (sktmp != NULL) sk_X509_free(sktmp); + if (chain_ss != NULL) X509_free(chain_ss); + return ok; + } + + +/* Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) +{ + int i; + X509 *issuer; + for (i = 0; i < sk_X509_num(sk); i++) + { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) + return issuer; + } + return NULL; +} + +/* Given a possible certificate and issuer check them */ + +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +{ + int ret; + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) + return 1; + /* If we haven't asked for issuer errors don't set ctx */ + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) + return 0; + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); + return 0; +} + +/* Alternative lookup method: look from a STACK stored in other_ctx */ + +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) + { + CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509); + return 1; + } + else + return 0; +} + + +/* Check a certificate chains extensions for consistency + * with the supplied purpose + */ + +static int check_chain_extensions(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok=0, must_be_ca, plen = 0; + X509 *x; + int (*cb)(int xok,X509_STORE_CTX *xctx); + int proxy_path_length = 0; + int allow_proxy_certs = + !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + cb=ctx->verify_cb; + + /* must_be_ca can have 1 of 3 values: + -1: we accept both CA and non-CA certificates, to allow direct + use of self-signed certificates (which are marked as CA). + 0: we only accept non-CA certificates. This is currently not + used, but the possibility is present for future extensions. + 1: we only accept CA certificates. This is currently used for + all certificates in the chain except the leaf certificate. + */ + must_be_ca = -1; + + /* A hack to keep people who don't want to modify their software + happy */ + if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->last_untrusted; i++) + { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (x->ex_flags & EXFLAG_CRITICAL)) + { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) + { + ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + ret = X509_check_ca(x); + switch(must_be_ca) + { + case -1: + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1) && (ret != 0)) + { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } + else + ret = 1; + break; + case 0: + if (ret != 0) + { + ret = 0; + ctx->error = X509_V_ERR_INVALID_NON_CA; + } + else + ret = 1; + break; + default: + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) + { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } + else + ret = 1; + break; + } + if (ret == 0) + { + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + if (ctx->param->purpose > 0) + { + ret = X509_check_purpose(x, ctx->param->purpose, + must_be_ca > 0); + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) + { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + } + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) + { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; + /* If this certificate is a proxy certificate, the next + certificate must be another proxy certificate or a EE + certificate. If not, the next certificate must be a + CA certificate. */ + if (x->ex_flags & EXFLAG_PROXY) + { + if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) + { + ctx->error = + X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok=cb(0,ctx); + if (!ok) goto end; + } + proxy_path_length++; + must_be_ca = 0; + } + else + must_be_ca = 1; + } + ok = 1; + end: + return ok; +#endif +} + +static int check_trust(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok; + X509 *x; + int (*cb)(int xok,X509_STORE_CTX *xctx); + cb=ctx->verify_cb; +/* For now just check the last certificate in the chain */ + i = sk_X509_num(ctx->chain) - 1; + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + if (ok == X509_TRUST_TRUSTED) + return 1; + ctx->error_depth = i; + ctx->current_cert = x; + if (ok == X509_TRUST_REJECTED) + ctx->error = X509_V_ERR_CERT_REJECTED; + else + ctx->error = X509_V_ERR_CERT_UNTRUSTED; + ok = cb(0, ctx); + return ok; +#endif +} + +static int check_revocation(X509_STORE_CTX *ctx) + { + int i, last, ok; + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else + last = 0; + for(i = 0; i <= last; i++) + { + ctx->error_depth = i; + ok = check_cert(ctx); + if (!ok) return ok; + } + return 1; + } + +static int check_cert(X509_STORE_CTX *ctx) + { + X509_CRL *crl = NULL; + X509 *x; + int ok, cnum; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + /* Try to retrieve relevant CRL */ + ok = ctx->get_crl(ctx, &crl, x); + /* If error looking up CRL, nothing we can do except + * notify callback + */ + if(!ok) + { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) goto err; + ok = ctx->cert_crl(ctx, crl, x); + err: + ctx->current_crl = NULL; + X509_CRL_free(crl); + return ok; + + } + +/* Check CRL times against values in X509_STORE_CTX */ + +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) + { + time_t *ptime; + int i; + ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); + if (i == 0) + { + ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!notify || !ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) + { + ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; + if (!notify || !ctx->verify_cb(0, ctx)) + return 0; + } + + if(X509_CRL_get_nextUpdate(crl)) + { + i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); + + if (i == 0) + { + ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!notify || !ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) + { + ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; + if (!notify || !ctx->verify_cb(0, ctx)) + return 0; + } + } + + ctx->current_crl = NULL; + + return 1; + } + +/* Lookup CRLs from the supplied list. Look for matching isser name + * and validity. If we can't find a valid CRL return the last one + * with matching name. This gives more meaningful error codes. Otherwise + * we'd get a CRL not found error if a CRL existed with matching name but + * was invalid. + */ + +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, + X509_NAME *nm, STACK_OF(X509_CRL) *crls) + { + int i; + X509_CRL *crl, *best_crl = NULL; + for (i = 0; i < sk_X509_CRL_num(crls); i++) + { + crl = sk_X509_CRL_value(crls, i); + if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) + continue; + if (check_crl_time(ctx, crl, 0)) + { + *pcrl = crl; + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509); + return 1; + } + best_crl = crl; + } + if (best_crl) + { + *pcrl = best_crl; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); + } + + return 0; + } + +/* Retrieve CRL corresponding to certificate: currently just a + * subject lookup: maybe use AKID later... + */ +static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) + { + int ok; + X509_CRL *crl = NULL; + X509_OBJECT xobj; + X509_NAME *nm; + nm = X509_get_issuer_name(x); + ok = get_crl_sk(ctx, &crl, nm, ctx->crls); + if (ok) + { + *pcrl = crl; + return 1; + } + + ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj); + + if (!ok) + { + /* If we got a near match from get_crl_sk use that */ + if (crl) + { + *pcrl = crl; + return 1; + } + return 0; + } + + *pcrl = xobj.data.crl; + if (crl) + X509_CRL_free(crl); + return 1; + } + +/* Check CRL validity */ +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) + { + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* Find CRL issuer: if not last certificate then issuer + * is next certificate in chain. + */ + if(cnum < chnum) + issuer = sk_X509_value(ctx->chain, cnum + 1); + else + { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if(!ctx->check_issued(ctx, issuer, issuer)) + { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + } + + if(issuer) + { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) + { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if(!ok) goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if(!ikey) + { + ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) goto err; + } + else + { + /* Verify CRL signature */ + if(X509_CRL_verify(crl, ikey) <= 0) + { + ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) goto err; + } + } + } + + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + + ok = 1; + + err: + EVP_PKEY_free(ikey); + return ok; + } + +/* Check certificate against CRL */ +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) + { + int idx, ok; + X509_REVOKED rtmp; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + /* Look for serial number of certificate in CRL */ + rtmp.serialNumber = X509_get_serialNumber(x); + /* Sort revoked into serial number order if not already sorted. + * Do this under a lock to avoid race condition. + */ + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) + { + CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); + sk_X509_REVOKED_sort(crl->crl->revoked); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); + } + idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); + /* If found assume revoked: want something cleverer than + * this to handle entry extensions in V2 CRLs. + */ + if(idx >= 0) + { + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) return 0; + } + + if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + return 1; + + /* See if we have any critical CRL extensions: since we + * currently don't handle any CRL extensions the CRL must be + * rejected. + * This code accesses the X509_CRL structure directly: applications + * shouldn't do this. + */ + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) + { + ext = sk_X509_EXTENSION_value(exts, idx); + if (ext->critical > 0) + { + ctx->error = + X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if(!ok) return 0; + break; + } + } + return 1; + } + +static int check_policy(X509_STORE_CTX *ctx) + { + int ret; + ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, + ctx->param->policies, ctx->param->flags); + if (ret == 0) + { + X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE); + return 0; + } + /* Invalid or inconsistent extensions */ + if (ret == -1) + { + /* Locate certificates with bad extensions and notify + * callback. + */ + X509 *x; + int i; + for (i = 1; i < sk_X509_num(ctx->chain); i++) + { + x = sk_X509_value(ctx->chain, i); + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; + ctx->current_cert = x; + ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; + ret = ctx->verify_cb(0, ctx); + } + return 1; + } + if (ret == -2) + { + ctx->current_cert = NULL; + ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) + { + ctx->current_cert = NULL; + ctx->error = X509_V_OK; + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; + } + +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) + { + time_t *ptime; + int i; + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i=X509_cmp_time(X509_get_notBefore(x), ptime); + if (i == 0) + { + ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert=x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) + { + ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert=x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + i=X509_cmp_time(X509_get_notAfter(x), ptime); + if (i == 0) + { + ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert=x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) + { + ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert=x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + return 1; + } + +static int internal_verify(X509_STORE_CTX *ctx) + { + int ok=0,n; + X509 *xs,*xi; + EVP_PKEY *pkey=NULL; + int (*cb)(int xok,X509_STORE_CTX *xctx); + + cb=ctx->verify_cb; + + n=sk_X509_num(ctx->chain); + ctx->error_depth=n-1; + n--; + xi=sk_X509_value(ctx->chain,n); + + if (ctx->check_issued(ctx, xi, xi)) + xs=xi; + else + { + if (n <= 0) + { + ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert=xi; + ok=cb(0,ctx); + goto end; + } + else + { + n--; + ctx->error_depth=n; + xs=sk_X509_value(ctx->chain,n); + } + } + +/* ctx->error=0; not needed */ + while (n >= 0) + { + ctx->error_depth=n; + if (!xs->valid) + { + if ((pkey=X509_get_pubkey(xi)) == NULL) + { + ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert=xi; + ok=(*cb)(0,ctx); + if (!ok) goto end; + } + else if (X509_verify(xs,pkey) <= 0) + /* XXX For the final trusted self-signed cert, + * this is a waste of time. That check should + * optional so that e.g. 'openssl x509' can be + * used to detect invalid self-signatures, but + * we don't verify again and again in SSL + * handshakes and the like once the cert has + * been declared trusted. */ + { + ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert=xs; + ok=(*cb)(0,ctx); + if (!ok) + { + EVP_PKEY_free(pkey); + goto end; + } + } + EVP_PKEY_free(pkey); + pkey=NULL; + } + + xs->valid = 1; + + ok = check_cert_time(ctx, xs); + if (!ok) + goto end; + + /* The last error (if any) is still in the error value */ + ctx->current_issuer=xi; + ctx->current_cert=xs; + ok=(*cb)(1,ctx); + if (!ok) goto end; + + n--; + if (n >= 0) + { + xi=xs; + xs=sk_X509_value(ctx->chain,n); + } + } + ok=1; +end: + return ok; + } + +int X509_cmp_current_time(ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} + +int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) + { + char *str; + ASN1_TIME atm; + long offset; + char buff1[24],buff2[24],*p; + int i,j; + + p=buff1; + i=ctm->length; + str=(char *)ctm->data; + if (ctm->type == V_ASN1_UTCTIME) + { + if ((i < 11) || (i > 17)) return 0; + memcpy(p,str,10); + p+=10; + str+=10; + } + else + { + if (i < 13) return 0; + memcpy(p,str,12); + p+=12; + str+=12; + } + + if ((*str == 'Z') || (*str == '-') || (*str == '+')) + { *(p++)='0'; *(p++)='0'; } + else + { + *(p++)= *(str++); + *(p++)= *(str++); + /* Skip any fractional seconds... */ + if (*str == '.') + { + str++; + while ((*str >= '0') && (*str <= '9')) str++; + } + + } + *(p++)='Z'; + *(p++)='\0'; + + if (*str == 'Z') + offset=0; + else + { + if ((*str != '+') && (*str != '-')) + return 0; + offset=((str[1]-'0')*10+(str[2]-'0'))*60; + offset+=(str[3]-'0')*10+(str[4]-'0'); + if (*str == '-') + offset= -offset; + } + atm.type=ctm->type; + atm.length=sizeof(buff2); + atm.data=(unsigned char *)buff2; + + if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) + return 0; + + if (ctm->type == V_ASN1_UTCTIME) + { + i=(buff1[0]-'0')*10+(buff1[1]-'0'); + if (i < 50) i+=100; /* cf. RFC 2459 */ + j=(buff2[0]-'0')*10+(buff2[1]-'0'); + if (j < 50) j+=100; + + if (i < j) return -1; + if (i > j) return 1; + } + i=strcmp(buff1,buff2); + if (i == 0) /* wait a second then return younger :-) */ + return -1; + else + return i; + } + +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) +{ + return X509_time_adj(s, adj, NULL); +} + +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) + { + time_t t; + int type = -1; + + if (in_tm) t = *in_tm; + else time(&t); + + t+=adj; + if (s) type = s->type; + if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); + if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t); + return ASN1_TIME_set(s, t); + } + +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) + { + EVP_PKEY *ktmp=NULL,*ktmp2; + int i,j; + + if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1; + + for (i=0; i<sk_X509_num(chain); i++) + { + ktmp=X509_get_pubkey(sk_X509_value(chain,i)); + if (ktmp == NULL) + { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } + if (!EVP_PKEY_missing_parameters(ktmp)) + break; + else + { + EVP_PKEY_free(ktmp); + ktmp=NULL; + } + } + if (ktmp == NULL) + { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + return 0; + } + + /* first, populate the other certs */ + for (j=i-1; j >= 0; j--) + { + ktmp2=X509_get_pubkey(sk_X509_value(chain,j)); + EVP_PKEY_copy_parameters(ktmp2,ktmp); + EVP_PKEY_free(ktmp2); + } + + if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp); + EVP_PKEY_free(ktmp); + return 1; + } + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) + { + /* This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, + new_func, dup_func, free_func); + } + +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) + { + return CRYPTO_set_ex_data(&ctx->ex_data,idx,data); + } + +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) + { + return CRYPTO_get_ex_data(&ctx->ex_data,idx); + } + +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) + { + return ctx->error; + } + +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) + { + ctx->error=err; + } + +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) + { + return ctx->error_depth; + } + +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) + { + return ctx->current_cert; + } + +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) + { + return ctx->chain; + } + +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) + { + int i; + X509 *x; + STACK_OF(X509) *chain; + if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL; + for (i = 0; i < sk_X509_num(chain); i++) + { + x = sk_X509_value(chain, i); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + } + return chain; + } + +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) + { + ctx->cert=x; + } + +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) + { + ctx->untrusted=sk; + } + +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) + { + ctx->crls=sk; + } + +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) + { + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); + } + +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) + { + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); + } + +/* This function is used to set the X509_STORE_CTX purpose and trust + * values. This is intended to be used when another structure has its + * own trust and purpose values which (if set) will be inherited by + * the ctx. If they aren't set then we will usually have a default + * purpose in mind which should then be used to set the trust value. + * An example of this is SSL use: an SSL structure will have its own + * purpose and trust settings which the application can set: if they + * aren't set then we use the default of SSL client/server. + */ + +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + /* If purpose not set use default */ + if (!purpose) purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) + { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) + { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) + { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) + { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) trust = ptmp->trust; + } + if (trust) + { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) + { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) ctx->param->trust = trust; + return 1; +} + +X509_STORE_CTX *X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); + if (!ctx) + { + X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(X509_STORE_CTX)); + return ctx; +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + X509_STORE_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + STACK_OF(X509) *chain) + { + int ret = 1; + ctx->ctx=store; + ctx->current_method=0; + ctx->cert=x509; + ctx->untrusted=chain; + ctx->crls = NULL; + ctx->last_untrusted=0; + ctx->other_ctx=NULL; + ctx->valid=0; + ctx->chain=NULL; + ctx->error=0; + ctx->explicit_policy=0; + ctx->error_depth=0; + ctx->current_cert=NULL; + ctx->current_issuer=NULL; + ctx->tree = NULL; + + ctx->param = X509_VERIFY_PARAM_new(); + + if (!ctx->param) + { + X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Inherit callbacks and flags from X509_STORE if not set + * use defaults. + */ + + + if (store) + ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); + else + ctx->param->flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; + + if (store) + { + ctx->verify_cb = store->verify_cb; + ctx->cleanup = store->cleanup; + } + else + ctx->cleanup = 0; + + if (ret) + ret = X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default")); + + if (ret == 0) + { + X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); + return 0; + } + + if (store && store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store && store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store && store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store && store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store && store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store && store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = get_crl; + + if (store && store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store && store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + ctx->check_policy = check_policy; + + + /* This memset() can't make any sense anyway, so it's removed. As + * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a + * corresponding "new" here and remove this bogus initialisation. */ + /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */ + if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, + &(ctx->ex_data))) + { + OPENSSL_free(ctx); + X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; + } + +/* Set alternative lookup method: just a STACK of trusted certificates. + * This avoids X509_STORE nastiness where it isn't needed. + */ + +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; +} + +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) + { + if (ctx->cleanup) ctx->cleanup(ctx); + if (ctx->param != NULL) + { + X509_VERIFY_PARAM_free(ctx->param); + ctx->param=NULL; + } + if (ctx->tree != NULL) + { + X509_policy_tree_free(ctx->tree); + ctx->tree=NULL; + } + if (ctx->chain != NULL) + { + sk_X509_pop_free(ctx->chain,X509_free); + ctx->chain=NULL; + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); + memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); + } + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) + { + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + } + +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) + { + X509_VERIFY_PARAM_set_flags(ctx->param, flags); + } + +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) + { + X509_VERIFY_PARAM_set_time(ctx->param, t); + } + +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)) + { + ctx->verify_cb=verify_cb; + } + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) + { + return ctx->tree; + } + +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) + { + return ctx->explicit_policy; + } + +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) + { + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); + } + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) + { + return ctx->param; + } + +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) + { + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; + } + +IMPLEMENT_STACK_OF(X509) +IMPLEMENT_ASN1_SET_OF(X509) + +IMPLEMENT_STACK_OF(X509_NAME) + +IMPLEMENT_STACK_OF(X509_ATTRIBUTE) +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) diff --git a/openssl/crypto/x509/x509_vfy.h b/openssl/crypto/x509/x509_vfy.h new file mode 100644 index 000000000..76c76e171 --- /dev/null +++ b/openssl/crypto/x509/x509_vfy.h @@ -0,0 +1,531 @@ +/* crypto/x509/x509_vfy.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +#include <openssl/x509.h> +/* openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. */ +#endif + +#ifndef HEADER_X509_VFY_H +#define HEADER_X509_VFY_H + +#include <openssl/opensslconf.h> +#ifndef OPENSSL_NO_LHASH +#include <openssl/lhash.h> +#endif +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/symhacks.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Outer object */ +typedef struct x509_hash_dir_st + { + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; + } X509_HASH_DIR_CTX; + +typedef struct x509_file_st + { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; + } X509_CERT_FILE_CTX; + +/*******************************/ +/* +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#define X509_LU_X509 1 +#define X509_LU_CRL 2 +#define X509_LU_PKEY 3 + +typedef struct x509_object_st + { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; + } X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st + { + const char *name; + int (*new_item)(X509_LOOKUP *ctx); + void (*free)(X509_LOOKUP *ctx); + int (*init)(X509_LOOKUP *ctx); + int (*shutdown)(X509_LOOKUP *ctx); + int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl, + char **ret); + int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name, + ASN1_INTEGER *serial,X509_OBJECT *ret); + int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type, + unsigned char *bytes,int len, + X509_OBJECT *ret); + int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len, + X509_OBJECT *ret); + } X509_LOOKUP_METHOD; + +/* This structure hold all parameters associated with a verify operation + * by including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st + { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + } X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' + * function is then called to actually check the cert chain. */ +struct x509_store_st + { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*cleanup)(X509_STORE_CTX *ctx); + + CRYPTO_EX_DATA ex_data; + int references; + } /* X509_STORE */; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +#define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st + { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + + X509_STORE *store_ctx; /* who owns us */ + } /* X509_LOOKUP */; + +/* This is a used when verifying cert chains. Since the + * gathering of the cert chain can take some time (and have to be + * 'retried', this needs to be kept and passed around. */ +struct x509_store_ctx_st /* X509_STORE_CTX */ + { + X509_STORE *ctx; + int current_method; /* used when looking up certs */ + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + void *other_ctx; /* Other info for use with get_issuer() */ + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*check_policy)(X509_STORE_CTX *ctx); + int (*cleanup)(X509_STORE_CTX *ctx); + + /* The following is built up */ + int valid; /* if 0, rebuild chain */ + int last_untrusted; /* index of last untrusted cert */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + X509_POLICY_TREE *tree; /* Valid policy tree */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +#define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +#define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +#define X509_L_FILE_LOAD 1 +#define X509_L_ADD_DIR 2 + +#define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +#define X509_V_OK 0 +/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */ + +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 + +#define X509_V_ERR_UNNESTED_RESOURCE 44 + +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +#define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +#define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +#define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +#define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +#define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +#define X509_V_FLAG_NOTIFY_POLICY 0x800 + +#define X509_VP_FLAG_DEFAULT 0x1 +#define X509_VP_FLAG_OVERWRITE 0x2 +#define X509_VP_FLAG_RESET_FLAGS 0x4 +#define X509_VP_FLAG_LOCKED 0x8 +#define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void ); +void X509_STORE_free(X509_STORE *v); + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +#ifndef OPENSSL_NO_STDIO +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +#endif + + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_load_locations (X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); +#endif + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL * + X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) * + X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +const X509_POLICY_NODE * + X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/openssl/crypto/x509/x509_vpm.c b/openssl/crypto/x509/x509_vpm.c new file mode 100644 index 000000000..2b06718ae --- /dev/null +++ b/openssl/crypto/x509/x509_vpm.c @@ -0,0 +1,430 @@ +/* x509_vpm.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> + +#include "cryptlib.h" +#include <openssl/crypto.h> +#include <openssl/lhash.h> +#include <openssl/buffer.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +/* X509_VERIFY_PARAM functions */ + +static void x509_verify_param_zero(X509_VERIFY_PARAM *param) + { + if (!param) + return; + param->name = NULL; + param->purpose = 0; + param->trust = 0; + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) + { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } + } + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) + { + X509_VERIFY_PARAM *param; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + memset(param, 0, sizeof(X509_VERIFY_PARAM)); + x509_verify_param_zero(param); + return param; + } + +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) + { + x509_verify_param_zero(param); + OPENSSL_free(param); + } + +/* This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ + +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != def) && (to_default || (dest->field == def)))) + +/* Macro to test and copy a field if necessary */ + +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + + +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, + const X509_VERIFY_PARAM *src) + { + unsigned long inh_flags; + int to_default, to_overwrite; + if (!src) + return 1; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) + { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) + { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + return 1; + } + +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from) + { + to->inh_flags |= X509_VP_FLAG_DEFAULT; + return X509_VERIFY_PARAM_inherit(to, from); + } + +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) + { + if (param->name) + OPENSSL_free(param->name); + param->name = BUF_strdup(name); + if (param->name) + return 1; + return 0; + } + +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) + { + param->flags |= flags; + if (flags & X509_V_FLAG_POLICY_MASK) + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; + } + +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) + { + param->flags &= ~flags; + return 1; + } + +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) + { + return param->flags; + } + +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) + { + return X509_PURPOSE_set(¶m->purpose, purpose); + } + +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) + { + return X509_TRUST_set(¶m->trust, trust); + } + +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) + { + param->depth = depth; + } + +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) + { + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; + } + +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) + { + if (!param->policies) + { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; + } + +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) + { + int i; + ASN1_OBJECT *oid, *doid; + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) + { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) + { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) + { + ASN1_OBJECT_free(doid); + return 0; + } + } + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; + } + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) + { + return param->depth; + } + +/* Default verify parameters: these are used for various + * applications and can be overridden by the user specified table. + * NB: the 'name' field *must* be in alphabetical order because it + * will be searched using OBJ_search. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + "default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL /* policies */ + }, + { + "pkcs7", /* S/MIME signing parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "smime_sign", /* S/MIME signing parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_client", /* SSL/TLS client parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_CLIENT, /* purpose */ + X509_TRUST_SSL_CLIENT, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_server", /* SSL/TLS server parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_SERVER, /* purpose */ + X509_TRUST_SSL_SERVER, /* trust */ + -1, /* depth */ + NULL /* policies */ + }}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int table_cmp(const void *pa, const void *pb) + { + const X509_VERIFY_PARAM *a = pa, *b = pb; + return strcmp(a->name, b->name); + } + +static int param_cmp(const X509_VERIFY_PARAM * const *a, + const X509_VERIFY_PARAM * const *b) + { + return strcmp((*a)->name, (*b)->name); + } + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) + { + int idx; + X509_VERIFY_PARAM *ptmp; + if (!param_table) + { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } + else + { + idx = sk_X509_VERIFY_PARAM_find(param_table, param); + if (idx != -1) + { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; + } + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) + { + int idx; + X509_VERIFY_PARAM pm; + pm.name = (char *)name; + if (param_table) + { + idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); + if (idx != -1) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm, + (char *)&default_table, + sizeof(default_table)/sizeof(X509_VERIFY_PARAM), + sizeof(X509_VERIFY_PARAM), + table_cmp); + } + +void X509_VERIFY_PARAM_table_cleanup(void) + { + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, + X509_VERIFY_PARAM_free); + param_table = NULL; + } diff --git a/openssl/crypto/x509/x509cset.c b/openssl/crypto/x509/x509cset.c new file mode 100644 index 000000000..7f4004b29 --- /dev/null +++ b/openssl/crypto/x509/x509cset.c @@ -0,0 +1,170 @@ +/* crypto/x509/x509cset.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> + +int X509_CRL_set_version(X509_CRL *x, long version) + { + if (x == NULL) return(0); + if (x->crl->version == NULL) + { + if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL) + return(0); + } + return(ASN1_INTEGER_set(x->crl->version,version)); + } + +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) + { + if ((x == NULL) || (x->crl == NULL)) return(0); + return(X509_NAME_set(&x->crl->issuer,name)); + } + + +int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) + { + ASN1_TIME *in; + + if (x == NULL) return(0); + in=x->crl->lastUpdate; + if (in != tm) + { + in=M_ASN1_TIME_dup(tm); + if (in != NULL) + { + M_ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate=in; + } + } + return(in != NULL); + } + +int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) + { + ASN1_TIME *in; + + if (x == NULL) return(0); + in=x->crl->nextUpdate; + if (in != tm) + { + in=M_ASN1_TIME_dup(tm); + if (in != NULL) + { + M_ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate=in; + } + } + return(in != NULL); + } + +int X509_CRL_sort(X509_CRL *c) + { + int i; + X509_REVOKED *r; + /* sort the data so it will be written in serial + * number order */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) + { + r=sk_X509_REVOKED_value(c->crl->revoked,i); + r->sequence=i; + } + c->crl->enc.modified = 1; + return 1; + } + +int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) + { + ASN1_TIME *in; + + if (x == NULL) return(0); + in=x->revocationDate; + if (in != tm) + { + in=M_ASN1_TIME_dup(tm); + if (in != NULL) + { + M_ASN1_TIME_free(x->revocationDate); + x->revocationDate=in; + } + } + return(in != NULL); + } + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) + { + ASN1_INTEGER *in; + + if (x == NULL) return(0); + in=x->serialNumber; + if (in != serial) + { + in=M_ASN1_INTEGER_dup(serial); + if (in != NULL) + { + M_ASN1_INTEGER_free(x->serialNumber); + x->serialNumber=in; + } + } + return(in != NULL); + } diff --git a/openssl/crypto/x509/x509name.c b/openssl/crypto/x509/x509name.c new file mode 100644 index 000000000..068abfe5f --- /dev/null +++ b/openssl/crypto/x509/x509name.c @@ -0,0 +1,383 @@ +/* crypto/x509/x509name.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <openssl/stack.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) + { + ASN1_OBJECT *obj; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) return(-1); + return(X509_NAME_get_text_by_OBJ(name,obj,buf,len)); + } + +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf, + int len) + { + int i; + ASN1_STRING *data; + + i=X509_NAME_get_index_by_OBJ(name,obj,-1); + if (i < 0) return(-1); + data=X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i)); + i=(data->length > (len-1))?(len-1):data->length; + if (buf == NULL) return(data->length); + memcpy(buf,data->data,i); + buf[i]='\0'; + return(i); + } + +int X509_NAME_entry_count(X509_NAME *name) + { + if (name == NULL) return(0); + return(sk_X509_NAME_ENTRY_num(name->entries)); + } + +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) + { + ASN1_OBJECT *obj; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) return(-2); + return(X509_NAME_get_index_by_OBJ(name,obj,lastpos)); + } + +/* NOTE: you should be passsing -1, not 0 as lastpos */ +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + int lastpos) + { + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) return(-1); + if (lastpos < 0) + lastpos= -1; + sk=name->entries; + n=sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) + { + ne=sk_X509_NAME_ENTRY_value(sk,lastpos); + if (OBJ_cmp(ne->object,obj) == 0) + return(lastpos); + } + return(-1); + } + +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc) + { + if(name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return(NULL); + else + return(sk_X509_NAME_ENTRY_value(name->entries,loc)); + } + +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) + { + X509_NAME_ENTRY *ret; + int i,n,set_prev,set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return(NULL); + sk=name->entries; + ret=sk_X509_NAME_ENTRY_delete(sk,loc); + n=sk_X509_NAME_ENTRY_num(sk); + name->modified=1; + if (loc == n) return(ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev=(sk_X509_NAME_ENTRY_value(sk,loc-1))->set; + else + set_prev=ret->set-1; + set_next=sk_X509_NAME_ENTRY_value(sk,loc)->set; + + /* set_prev is the previous set + * set is the current set + * set_next is the following + * prev 1 1 1 1 1 1 1 1 + * set 1 1 2 2 + * next 1 1 2 2 2 2 3 2 + * so basically only if prev and next differ by 2, then + * re-number down by 1 */ + if (set_prev+1 < set_next) + for (i=loc; i<n; i++) + sk_X509_NAME_ENTRY_value(sk,i)->set--; + return(ret); + } + +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if(!ne) return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if(!ne) return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if(!ne) return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +/* if set is -1, append to previous set, 0 'a new one', and 1, + * prepend to the guy we are about to stomp on. */ +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, + int set) + { + X509_NAME_ENTRY *new_name=NULL; + int n,i,inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) return(0); + sk=name->entries; + n=sk_X509_NAME_ENTRY_num(sk); + if (loc > n) loc=n; + else if (loc < 0) loc=n; + + name->modified=1; + + if (set == -1) + { + if (loc == 0) + { + set=0; + inc=1; + } + else + { + set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set; + inc=0; + } + } + else /* if (set >= 0) */ + { + if (loc >= n) + { + if (loc != 0) + set=sk_X509_NAME_ENTRY_value(sk,loc-1)->set+1; + else + set=0; + } + else + set=sk_X509_NAME_ENTRY_value(sk,loc)->set; + inc=(set == 0)?1:0; + } + + if ((new_name=X509_NAME_ENTRY_dup(ne)) == NULL) + goto err; + new_name->set=set; + if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc)) + { + X509err(X509_F_X509_NAME_ADD_ENTRY,ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) + { + n=sk_X509_NAME_ENTRY_num(sk); + for (i=loc+1; i<n; i++) + sk_X509_NAME_ENTRY_value(sk,i-1)->set+=1; + } + return(1); +err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return(0); + } + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len) + { + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj=OBJ_txt2obj(field, 0); + if (obj == NULL) + { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", field); + return(NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len); + ASN1_OBJECT_free(obj); + return nentry; + } + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, int len) + { + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj=OBJ_nid2obj(nid); + if (obj == NULL) + { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID,X509_R_UNKNOWN_NID); + return(NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len); + ASN1_OBJECT_free(obj); + return nentry; + } + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len) + { + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) + { + if ((ret=X509_NAME_ENTRY_new()) == NULL) + return(NULL); + } + else + ret= *ne; + + if (!X509_NAME_ENTRY_set_object(ret,obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret,type,bytes,len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) *ne=ret; + return(ret); +err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return(NULL); + } + +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) + { + if ((ne == NULL) || (obj == NULL)) + { + X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + ASN1_OBJECT_free(ne->object); + ne->object=OBJ_dup(obj); + return((ne->object == NULL)?0:1); + } + +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) + { + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) return(0); + if((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, + len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) len=strlen((char *)bytes); + i=ASN1_STRING_set(ne->value,bytes,len); + if (!i) return(0); + if (type != V_ASN1_UNDEF) + { + if (type == V_ASN1_APP_CHOOSE) + ne->value->type=ASN1_PRINTABLE_type(bytes,len); + else + ne->value->type=type; + } + return(1); + } + +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) + { + if (ne == NULL) return(NULL); + return(ne->object); + } + +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) + { + if (ne == NULL) return(NULL); + return(ne->value); + } + diff --git a/openssl/crypto/x509/x509rset.c b/openssl/crypto/x509/x509rset.c new file mode 100644 index 000000000..d9f6b5737 --- /dev/null +++ b/openssl/crypto/x509/x509rset.c @@ -0,0 +1,83 @@ +/* crypto/x509/x509rset.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/asn1.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.h> + +int X509_REQ_set_version(X509_REQ *x, long version) + { + if (x == NULL) return(0); + return(ASN1_INTEGER_set(x->req_info->version,version)); + } + +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) + { + if ((x == NULL) || (x->req_info == NULL)) return(0); + return(X509_NAME_set(&x->req_info->subject,name)); + } + +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) + { + if ((x == NULL) || (x->req_info == NULL)) return(0); + return(X509_PUBKEY_set(&x->req_info->pubkey,pkey)); + } + diff --git a/openssl/crypto/x509/x509spki.c b/openssl/crypto/x509/x509spki.c new file mode 100644 index 000000000..02a203d72 --- /dev/null +++ b/openssl/crypto/x509/x509spki.c @@ -0,0 +1,121 @@ +/* x509spki.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/x509.h> + +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) return(0); + return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey)); +} + +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return(NULL); + return(X509_PUBKEY_get(x->spkac->pubkey)); +} + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + int spki_len; + NETSCAPE_SPKI *spki; + if(len <= 0) len = strlen(str); + if (!(spki_der = OPENSSL_malloc(len + 1))) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); + if(spki_len < 0) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, + X509_R_BASE64_DECODE_ERROR); + OPENSSL_free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + OPENSSL_free(spki_der); + return spki; +} + +/* Generate a base64 encoded string from an SPKI */ + +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + der_spki = OPENSSL_malloc(der_len); + b64_str = OPENSSL_malloc(der_len * 2); + if(!der_spki || !b64_str) { + X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + OPENSSL_free(der_spki); + return b64_str; +} diff --git a/openssl/crypto/x509/x509type.c b/openssl/crypto/x509/x509type.c new file mode 100644 index 000000000..2cd994c5b --- /dev/null +++ b/openssl/crypto/x509/x509type.c @@ -0,0 +1,121 @@ +/* crypto/x509/x509type.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/x509.h> + +int X509_certificate_type(X509 *x, EVP_PKEY *pkey) + { + EVP_PKEY *pk; + int ret=0,i; + + if (x == NULL) return(0); + + if (pkey == NULL) + pk=X509_get_pubkey(x); + else + pk=pkey; + + if (pk == NULL) return(0); + + switch (pk->type) + { + case EVP_PKEY_RSA: + ret=EVP_PK_RSA|EVP_PKT_SIGN; +/* if (!sign only extension) */ + ret|=EVP_PKT_ENC; + break; + case EVP_PKEY_DSA: + ret=EVP_PK_DSA|EVP_PKT_SIGN; + break; + case EVP_PKEY_EC: + ret=EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH; + break; + case EVP_PKEY_DH: + ret=EVP_PK_DH|EVP_PKT_EXCH; + break; + default: + break; + } + + i=X509_get_signature_type(x); + switch (i) + { + case EVP_PKEY_RSA: + ret|=EVP_PKS_RSA; + break; + case EVP_PKEY_DSA: + ret|=EVP_PKS_DSA; + break; + case EVP_PKEY_EC: + ret|=EVP_PKS_EC; + break; + default: + break; + } + + if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look + for, not bytes */ + ret|=EVP_PKT_EXP; + if(pkey==NULL) EVP_PKEY_free(pk); + return(ret); + } + diff --git a/openssl/crypto/x509/x_all.c b/openssl/crypto/x509/x_all.c new file mode 100644 index 000000000..9039caad6 --- /dev/null +++ b/openssl/crypto/x509/x_all.c @@ -0,0 +1,522 @@ +/* crypto/x509/x_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#undef SSLEAY_MACROS +#include <openssl/stack.h> +#include "cryptlib.h" +#include <openssl/buffer.h> +#include <openssl/asn1.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#ifndef OPENSSL_NO_DSA +#include <openssl/dsa.h> +#endif + +int X509_verify(X509 *a, EVP_PKEY *r) + { + return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg, + a->signature,a->cert_info,r)); + } + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) + { + return( ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + a->sig_alg,a->signature,a->req_info,r)); + } + +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r) + { + return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), + a->sig_alg, a->signature,a->crl,r)); + } + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) + { + return(ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + a->sig_algor,a->signature,a->spkac,r)); + } + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) + { + return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info,pkey,md)); + } + +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) + { + return(ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO),x->sig_alg, NULL, + x->signature, x->req_info,pkey,md)); + } + +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) + { + x->crl->enc.modified = 1; + return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO),x->crl->sig_alg, + x->sig_alg, x->signature, x->crl,pkey,md)); + } + +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) + { + return(ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,NULL, + x->signature, x->spkac,pkey,md)); + } + +#ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); + } + +int i2d_X509_fp(FILE *fp, X509 *x509) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); + } +#endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); + } + +int i2d_X509_bio(BIO *bp, X509 *x509) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); + } + +#ifndef OPENSSL_NO_FP_API +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); + } + +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); + } +#endif + +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); + } + +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); + } + +#ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + } + +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + } +#endif + +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + } + +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + } + +#ifndef OPENSSL_NO_FP_API +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); + } + +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); + } +#endif + +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); + } + +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); + } + +#ifndef OPENSSL_NO_RSA + +#ifndef OPENSSL_NO_FP_API +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); + } + +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); + } + +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) + { + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); + } + + +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) + { + return ASN1_d2i_fp((void *(*)(void)) + RSA_new,(D2I_OF(void))d2i_RSA_PUBKEY, fp, + (void **)rsa); + } + +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) + { + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); + } + +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) + { + return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY,fp,rsa); + } +#endif + +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); + } + +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); + } + +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) + { + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); + } + + +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) + { + return ASN1_d2i_bio_of(RSA,RSA_new,d2i_RSA_PUBKEY,bp,rsa); + } + +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) + { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); + } + +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) + { + return ASN1_i2d_bio_of(RSA,i2d_RSA_PUBKEY,bp,rsa); + } +#endif + +#ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_FP_API +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) + { + return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSAPrivateKey,fp,dsa); + } + +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) + { + return ASN1_i2d_fp_of_const(DSA,i2d_DSAPrivateKey,fp,dsa); + } + +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) + { + return ASN1_d2i_fp_of(DSA,DSA_new,d2i_DSA_PUBKEY,fp,dsa); + } + +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) + { + return ASN1_i2d_fp_of(DSA,i2d_DSA_PUBKEY,fp,dsa); + } +#endif + +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) + { + return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAPrivateKey,bp,dsa +); + } + +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) + { + return ASN1_i2d_bio_of_const(DSA,i2d_DSAPrivateKey,bp,dsa); + } + +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) + { + return ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSA_PUBKEY,bp,dsa); + } + +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) + { + return ASN1_i2d_bio_of(DSA,i2d_DSA_PUBKEY,bp,dsa); + } + +#endif + +#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_FP_API +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) + { + return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,fp,eckey); + } + +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) + { + return ASN1_i2d_fp_of(EC_KEY,i2d_EC_PUBKEY,fp,eckey); + } + +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) + { + return ASN1_d2i_fp_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,fp,eckey); + } + +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) + { + return ASN1_i2d_fp_of(EC_KEY,i2d_ECPrivateKey,fp,eckey); + } +#endif +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) + { + return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_EC_PUBKEY,bp,eckey); + } + +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) + { + return ASN1_i2d_bio_of(EC_KEY,i2d_EC_PUBKEY,bp,ecdsa); + } + +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) + { + return ASN1_d2i_bio_of(EC_KEY,EC_KEY_new,d2i_ECPrivateKey,bp,eckey); + } + +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) + { + return ASN1_i2d_bio_of(EC_KEY,i2d_ECPrivateKey,bp,eckey); + } +#endif + + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) + { + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if(!key) return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); + } + +int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) + { + return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len)); + } + +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) + { + return(ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL),type,(char *)data,md,len)); + } + +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) + { + return(ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ),type,(char *)data,md,len)); + } + +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) + { + return(ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME),type,(char *)data,md,len)); + } + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) + { + return(ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL),type, + (char *)data,md,len)); + } + + +#ifndef OPENSSL_NO_FP_API +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) + { + return ASN1_d2i_fp_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,fp,p8); + } + +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) + { + return ASN1_i2d_fp_of(X509_SIG,i2d_X509_SIG,fp,p8); + } +#endif + +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) + { + return ASN1_d2i_bio_of(X509_SIG,X509_SIG_new,d2i_X509_SIG,bp,p8); + } + +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) + { + return ASN1_i2d_bio_of(X509_SIG,i2d_X509_SIG,bp,p8); + } + +#ifndef OPENSSL_NO_FP_API +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf) + { + return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO,fp,p8inf); + } + +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) + { + return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,fp, + p8inf); + } + +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) + { + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if(!p8inf) return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } + +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) + { + return ASN1_i2d_fp_of(EVP_PKEY,i2d_PrivateKey,fp,pkey); + } + +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,fp,a); +} + +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) + { + return ASN1_i2d_fp_of(EVP_PKEY,i2d_PUBKEY,fp,pkey); + } + +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,fp,a); +} + +#endif + +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf) + { + return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO,PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO,bp,p8inf); + } + +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) + { + return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO,i2d_PKCS8_PRIV_KEY_INFO,bp, + p8inf); + } + +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) + { + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if(!p8inf) return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } + +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) + { + return ASN1_i2d_bio_of(EVP_PKEY,i2d_PrivateKey,bp,pkey); + } + +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) + { + return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_AutoPrivateKey,bp,a); + } + +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) + { + return ASN1_i2d_bio_of(EVP_PKEY,i2d_PUBKEY,bp,pkey); + } + +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) + { + return ASN1_d2i_bio_of(EVP_PKEY,EVP_PKEY_new,d2i_PUBKEY,bp,a); + } |