aboutsummaryrefslogtreecommitdiff
path: root/crypto/x509
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/Makefile411
-rw-r--r--crypto/x509/build.info10
-rw-r--r--crypto/x509/by_dir.c245
-rw-r--r--crypto/x509/by_file.c116
-rw-r--r--crypto/x509/t_crl.c94
-rw-r--r--crypto/x509/t_req.c210
-rw-r--r--crypto/x509/t_x509.c379
-rw-r--r--crypto/x509/verify_extra_test.c208
-rw-r--r--crypto/x509/vpm_int.h70
-rw-r--r--crypto/x509/x509.h1330
-rw-r--r--crypto/x509/x509_att.c147
-rw-r--r--crypto/x509/x509_cmp.c236
-rw-r--r--crypto/x509/x509_d2.c84
-rw-r--r--crypto/x509/x509_def.c75
-rw-r--r--crypto/x509/x509_err.c303
-rw-r--r--crypto/x509/x509_ext.c154
-rw-r--r--crypto/x509/x509_lcl.h147
-rw-r--r--crypto/x509/x509_lu.c757
-rw-r--r--crypto/x509/x509_meth.c166
-rw-r--r--crypto/x509/x509_obj.c77
-rw-r--r--crypto/x509/x509_r2x.c92
-rw-r--r--crypto/x509/x509_req.c198
-rw-r--r--crypto/x509/x509_set.c293
-rw-r--r--crypto/x509/x509_trs.c191
-rw-r--r--crypto/x509/x509_txt.c240
-rw-r--r--crypto/x509/x509_v3.c143
-rw-r--r--crypto/x509/x509_vfy.c2536
-rw-r--r--crypto/x509/x509_vfy.h652
-rw-r--r--crypto/x509/x509_vpm.c314
-rw-r--r--crypto/x509/x509cset.c230
-rw-r--r--crypto/x509/x509name.c193
-rw-r--r--crypto/x509/x509rset.c83
-rw-r--r--crypto/x509/x509spki.c76
-rw-r--r--crypto/x509/x509type.c91
-rw-r--r--crypto/x509/x_all.c153
-rw-r--r--crypto/x509/x_attrib.c55
-rw-r--r--crypto/x509/x_crl.c466
-rw-r--r--crypto/x509/x_exten.c28
-rw-r--r--crypto/x509/x_name.c551
-rw-r--r--crypto/x509/x_pubkey.c374
-rw-r--r--crypto/x509/x_req.c68
-rw-r--r--crypto/x509/x_x509.c224
-rw-r--r--crypto/x509/x_x509a.c169
43 files changed, 6479 insertions, 6160 deletions
diff --git a/crypto/x509/Makefile b/crypto/x509/Makefile
deleted file mode 100644
index bf197a1d932a..000000000000
--- a/crypto/x509/Makefile
+++ /dev/null
@@ -1,411 +0,0 @@
-#
-# 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=verify_extra_test.c
-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) vpm_int.h
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- $(AR) $(LIB) $(LIBOBJ)
- $(RANLIB) $(LIB) || echo Never mind.
- @touch lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
-
-install:
- @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
- @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done;
-
-tags:
- ctags $(SRC)
-
-tests:
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-update: depend
-
-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/lhash.h ../../include/openssl/obj_mac.h
-by_dir.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-by_dir.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-by_dir.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-by_dir.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-by_dir.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-by_dir.o: ../../include/openssl/x509_vfy.h ../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/lhash.h
-by_file.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-by_file.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-by_file.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-by_file.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-by_file.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-by_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-by_file.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-by_file.o: ../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/lhash.h ../../include/openssl/obj_mac.h
-x509_att.o: ../../include/openssl/objects.h ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_cmp.o: ../../include/openssl/objects.h ../../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/lhash.h
-x509_d2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_d2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x509_d2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-x509_d2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-x509_d2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-x509_d2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-x509_d2.o: ../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/lhash.h
-x509_def.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_def.o: ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_err.o: ../../include/openssl/objects.h ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_ext.o: ../../include/openssl/objects.h ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_lu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x509_lu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x509_lu.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x509_lu.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x509_lu.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_lu.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_lu.o: ../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/lhash.h
-x509_obj.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_obj.o: ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_r2x.o: ../../include/openssl/objects.h ../../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/asn1t.h ../../include/openssl/bio.h
-x509_req.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-x509_req.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-x509_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-x509_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_req.o: ../../include/openssl/evp.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/lhash.h
-x509_set.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_set.o: ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_trs.o: ../../include/openssl/objects.h ../../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/lhash.h
-x509_txt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_txt.o: ../../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/lhash.h ../../include/openssl/obj_mac.h
-x509_v3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x509_v3.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x509_v3.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x509_v3.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x509_v3.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_v3.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_v3.o: ../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/lhash.h ../../include/openssl/obj_mac.h
-x509_vfy.o: ../../include/openssl/objects.h ../../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 vpm_int.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/lhash.h ../../include/openssl/obj_mac.h
-x509_vpm.o: ../../include/openssl/objects.h ../../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 vpm_int.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/lhash.h
-x509cset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509cset.o: ../../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/lhash.h
-x509name.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509name.o: ../../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/lhash.h
-x509rset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509rset.o: ../../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/lhash.h
-x509spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509spki.o: ../../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/lhash.h
-x509type.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509type.o: ../../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/conf.h
-x_all.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
-x_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-x_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-x_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-x_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-x_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-x_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x_all.o: ../cryptlib.h x_all.c
diff --git a/crypto/x509/build.info b/crypto/x509/build.info
new file mode 100644
index 000000000000..afd0b6134e52
--- /dev/null
+++ b/crypto/x509/build.info
@@ -0,0 +1,10 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+ 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_meth.c x509_lu.c x_all.c x509_txt.c \
+ x509_trs.c by_file.c by_dir.c x509_vpm.c \
+ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \
+ x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c
diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c
index 6f0209a275ef..11ac52ce3c55 100644
--- a/crypto/x509/by_dir.c
+++ b/crypto/x509/by_dir.c
@@ -1,106 +1,54 @@
-/* crypto/x509/by_dir.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
+#include "e_os.h"
+#include "internal/cryptlib.h"
#include <stdio.h>
#include <time.h>
#include <errno.h>
+#include <sys/types.h>
-#include "cryptlib.h"
-
-#ifndef NO_SYS_TYPES_H
-# include <sys/types.h>
-#endif
#ifndef OPENSSL_NO_POSIX_IO
# include <sys/stat.h>
#endif
-#include <openssl/lhash.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include "x509_lcl.h"
-typedef struct lookup_dir_hashes_st {
+struct lookup_dir_hashes_st {
unsigned long hash;
int suffix;
-} BY_DIR_HASH;
+};
-typedef struct lookup_dir_entry_st {
+struct lookup_dir_entry_st {
char *dir;
int dir_type;
STACK_OF(BY_DIR_HASH) *hashes;
-} BY_DIR_ENTRY;
+};
typedef struct lookup_dir_st {
BUF_MEM *buffer;
STACK_OF(BY_DIR_ENTRY) *dirs;
+ CRYPTO_RWLOCK *lock;
} BY_DIR;
-DECLARE_STACK_OF(BY_DIR_HASH)
-DECLARE_STACK_OF(BY_DIR_ENTRY)
-
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
char **ret);
static int new_dir(X509_LOOKUP *lu);
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 = {
+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
+ X509_NAME *name, X509_OBJECT *ret);
+static X509_LOOKUP_METHOD x509_dir_lookup = {
"Load certs from files in a directory",
- new_dir, /* new */
+ new_dir, /* new_item */
free_dir, /* free */
NULL, /* init */
NULL, /* shutdown */
@@ -113,22 +61,20 @@ X509_LOOKUP_METHOD x509_dir_lookup = {
X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
{
- return (&x509_dir_lookup);
+ 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;
+ BY_DIR *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());
+ const char *dir = getenv(X509_get_default_cert_dir_env());
+
if (dir)
ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
else
@@ -141,22 +87,35 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
ret = add_cert_dir(ld, argp, (int)argl);
break;
}
- return (ret);
+ return ret;
}
static int new_dir(X509_LOOKUP *lu)
{
- BY_DIR *a;
+ BY_DIR *a = OPENSSL_malloc(sizeof(*a));
+
+ if (a == NULL) {
+ X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
- if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
- return (0);
if ((a->buffer = BUF_MEM_new()) == NULL) {
- OPENSSL_free(a);
- return (0);
+ X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE);
+ goto err;
}
a->dirs = NULL;
- lu->method_data = (char *)a;
- return (1);
+ a->lock = CRYPTO_THREAD_lock_new();
+ if (a->lock == NULL) {
+ BUF_MEM_free(a->buffer);
+ X509err(X509_F_NEW_DIR, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ lu->method_data = a;
+ return 1;
+
+ err:
+ OPENSSL_free(a);
+ return 0;
}
static void by_dir_hash_free(BY_DIR_HASH *hash)
@@ -176,28 +135,25 @@ static int by_dir_hash_cmp(const BY_DIR_HASH *const *a,
static void by_dir_entry_free(BY_DIR_ENTRY *ent)
{
- if (ent->dir)
- OPENSSL_free(ent->dir);
- if (ent->hashes)
- sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+ OPENSSL_free(ent->dir);
+ sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
OPENSSL_free(ent);
}
static void free_dir(X509_LOOKUP *lu)
{
- BY_DIR *a;
+ BY_DIR *a = (BY_DIR *)lu->method_data;
- a = (BY_DIR *)lu->method_data;
- if (a->dirs != NULL)
- sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
- if (a->buffer != NULL)
- BUF_MEM_free(a->buffer);
+ sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+ BUF_MEM_free(a->buffer);
+ CRYPTO_THREAD_lock_free(a->lock);
OPENSSL_free(a);
}
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
{
- int j, len;
+ int j;
+ size_t len;
const char *s, *ss, *p;
if (dir == NULL || !*dir) {
@@ -210,15 +166,15 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
do {
if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) {
BY_DIR_ENTRY *ent;
+
ss = s;
s = p + 1;
- len = (int)(p - ss);
+ len = p - ss;
if (len == 0)
continue;
for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
- if (strlen(ent->dir) == (size_t)len &&
- strncmp(ent->dir, ss, (unsigned int)len) == 0)
+ if (strlen(ent->dir) == len && strncmp(ent->dir, ss, len) == 0)
break;
}
if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
@@ -230,20 +186,21 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
return 0;
}
}
- ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY));
- if (!ent)
+ ent = OPENSSL_malloc(sizeof(*ent));
+ if (ent == NULL) {
+ X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE);
return 0;
+ }
ent->dir_type = type;
ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
- ent->dir = OPENSSL_malloc((unsigned int)len + 1);
- if (!ent->dir || !ent->hashes) {
+ ent->dir = OPENSSL_strndup(ss, len);
+ if (ent->dir == NULL || ent->hashes == NULL) {
by_dir_entry_free(ent);
return 0;
}
- strncpy(ent->dir, ss, (unsigned int)len);
- ent->dir[len] = '\0';
if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
by_dir_entry_free(ent);
+ X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -251,19 +208,13 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
return 1;
}
-static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
- X509_OBJECT *ret)
+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE 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;
+ X509 st_x509;
+ X509_CRL crl;
} data;
int ok = 0;
int i, j, k;
@@ -273,18 +224,16 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
const char *postfix = "";
if (name == NULL)
- return (0);
+ 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;
+ data.st_x509.cert_info.subject = name;
+ stmp.data.x509 = &data.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;
+ data.crl.crl.issuer = name;
+ stmp.data.crl = &data.crl;
postfix = "r";
} else {
X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE);
@@ -303,6 +252,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
BY_DIR_ENTRY *ent;
int idx;
BY_DIR_HASH htmp, *hent;
+
ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
if (!BUF_MEM_grow(b, j)) {
@@ -311,7 +261,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
}
if (type == X509_LU_CRL && ent->hashes) {
htmp.hash = h;
- CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_read_lock(ctx->lock);
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
if (idx >= 0) {
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
@@ -320,7 +270,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
hent = NULL;
k = 0;
}
- CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
} else {
k = 0;
hent = NULL;
@@ -377,47 +327,46 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
/*
* we have added it to the cache so now pull it out again
*/
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_write_lock(ctx->lock);
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_w_unlock(CRYPTO_LOCK_X509_STORE);
+ tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
+ CRYPTO_THREAD_unlock(ctx->lock);
/* If a CRL, update the last file suffix added for this */
if (type == X509_LU_CRL) {
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_write_lock(ctx->lock);
/*
* Look for entry again in case another thread added an entry
* first.
*/
- if (!hent) {
+ if (hent == NULL) {
htmp.hash = h;
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
- if (idx >= 0)
- hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+ hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
}
- if (!hent) {
- hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+ if (hent == NULL) {
+ hent = OPENSSL_malloc(sizeof(*hent));
if (hent == NULL) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+ ok = 0;
goto finish;
}
hent->hash = h;
hent->suffix = k;
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
OPENSSL_free(hent);
+ X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
ok = 0;
goto finish;
}
- } else if (hent->suffix < k)
+ } else if (hent->suffix < k) {
hent->suffix = k;
+ }
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
}
@@ -425,17 +374,17 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
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
+ * Clear any errors that might have been raised processing empty
+ * or malformed files.
*/
- /*- CRYPTO_add(&tmp->data.x509->references,1,
- CRYPTO_LOCK_X509);*/
+ ERR_clear_error();
+
goto finish;
}
}
finish:
- if (b != NULL)
- BUF_MEM_free(b);
- return (ok);
+ BUF_MEM_free(b);
+ return ok;
}
diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c
index 82ce4e8d87c3..78d7fbdf4488 100644
--- a/crypto/x509/by_file.c
+++ b/crypto/x509/by_file.c
@@ -1,78 +1,27 @@
-/* crypto/x509/by_file.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
+#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
-
-#ifndef OPENSSL_NO_STDIO
+#include "x509_lcl.h"
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
-X509_LOOKUP_METHOD x509_file_lookup = {
+static X509_LOOKUP_METHOD x509_file_lookup = {
"Load file into cache",
- NULL, /* new */
+ NULL, /* new_item */
NULL, /* free */
NULL, /* init */
NULL, /* shutdown */
@@ -85,7 +34,7 @@ X509_LOOKUP_METHOD x509_file_lookup = {
X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
{
- return (&x509_file_lookup);
+ return &x509_file_lookup;
}
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
@@ -119,7 +68,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
}
break;
}
- return (ok);
+ return ok;
}
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
@@ -129,9 +78,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
int i, count = 0;
X509 *x = NULL;
- if (file == NULL)
- return (1);
- in = BIO_new(BIO_s_file_internal());
+ in = BIO_new(BIO_s_file());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB);
@@ -173,12 +120,12 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE);
goto err;
}
+ if (ret == 0)
+ X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_NO_CERTIFICATE_FOUND);
err:
- if (x != NULL)
- X509_free(x);
- if (in != NULL)
- BIO_free(in);
- return (ret);
+ X509_free(x);
+ BIO_free(in);
+ return ret;
}
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
@@ -188,9 +135,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
int i, count = 0;
X509_CRL *x = NULL;
- if (file == NULL)
- return (1);
- in = BIO_new(BIO_s_file_internal());
+ in = BIO_new(BIO_s_file());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB);
@@ -232,12 +177,12 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE);
goto err;
}
+ if (ret == 0)
+ X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_NO_CRL_FOUND);
err:
- if (x != NULL)
- X509_CRL_free(x);
- if (in != NULL)
- BIO_free(in);
- return (ret);
+ X509_CRL_free(x);
+ BIO_free(in);
+ return ret;
}
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
@@ -246,6 +191,7 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
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");
@@ -262,16 +208,20 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
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);
+ if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509))
+ goto err;
count++;
}
if (itmp->crl) {
- X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
+ if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl))
+ goto err;
count++;
}
}
+ if (count == 0)
+ X509err(X509_F_X509_LOAD_CERT_CRL_FILE,
+ X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
+ err:
sk_X509_INFO_pop_free(inf, X509_INFO_free);
return count;
}
-
-#endif /* OPENSSL_NO_STDIO */
diff --git a/crypto/x509/t_crl.c b/crypto/x509/t_crl.c
new file mode 100644
index 000000000000..8e262912ffaa
--- /dev/null
+++ b/crypto/x509/t_crl.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_CRL_print(b, x);
+ BIO_free(b);
+ return ret;
+}
+#endif
+
+int X509_CRL_print(BIO *out, X509_CRL *x)
+{
+ return X509_CRL_print_ex(out, x, XN_FLAG_COMPAT);
+}
+
+int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag)
+{
+ STACK_OF(X509_REVOKED) *rev;
+ X509_REVOKED *r;
+ const X509_ALGOR *sig_alg;
+ const ASN1_BIT_STRING *sig;
+ long l;
+ int i;
+
+ BIO_printf(out, "Certificate Revocation List (CRL):\n");
+ l = X509_CRL_get_version(x);
+ if (l >= 0 && l <= 1)
+ BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", l + 1, (unsigned long)l);
+ else
+ BIO_printf(out, "%8sVersion unknown (%ld)\n", "", l);
+ X509_CRL_get0_signature(x, &sig, &sig_alg);
+ BIO_puts(out, " ");
+ X509_signature_print(out, sig_alg, NULL);
+ BIO_printf(out, "%8sIssuer: ", "");
+ X509_NAME_print_ex(out, X509_CRL_get_issuer(x), 0, nmflag);
+ BIO_puts(out, "\n");
+ BIO_printf(out, "%8sLast Update: ", "");
+ ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x));
+ BIO_printf(out, "\n%8sNext Update: ", "");
+ if (X509_CRL_get0_nextUpdate(x))
+ ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x));
+ else
+ BIO_printf(out, "NONE");
+ BIO_printf(out, "\n");
+
+ X509V3_extensions_print(out, "CRL extensions",
+ X509_CRL_get0_extensions(x), 0, 8);
+
+ rev = X509_CRL_get_REVOKED(x);
+
+ if (sk_X509_REVOKED_num(rev) > 0)
+ BIO_printf(out, "Revoked Certificates:\n");
+ else
+ BIO_printf(out, "No Revoked Certificates.\n");
+
+ for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+ r = sk_X509_REVOKED_value(rev, i);
+ BIO_printf(out, " Serial Number: ");
+ i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r));
+ BIO_printf(out, "\n Revocation Date: ");
+ ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r));
+ BIO_printf(out, "\n");
+ X509V3_extensions_print(out, "CRL entry extensions",
+ X509_REVOKED_get0_extensions(r), 0, 8);
+ }
+ X509_signature_print(out, sig_alg, sig);
+
+ return 1;
+
+}
diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c
new file mode 100644
index 000000000000..2d4c591b7445
--- /dev/null
+++ b/crypto/x509/t_req.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_REQ_print(b, x);
+ BIO_free(b);
+ return ret;
+}
+#endif
+
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int i;
+ EVP_PKEY *pkey;
+ STACK_OF(X509_EXTENSION) *exts;
+ char mlch = ' ';
+ int nmindent = 0;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_REQ_get_version(x);
+ if (l >= 0 && l <= 2) {
+ if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
+ goto err;
+ } else {
+ if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
+ nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ X509_PUBKEY *xpkey;
+ ASN1_OBJECT *koid;
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ xpkey = X509_REQ_get_X509_PUBKEY(x);
+ X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey);
+ if (i2a_ASN1_OBJECT(bp, koid) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_REQ_get0_pubkey(x);
+ if (pkey == NULL) {
+ if (BIO_printf(bp, "%12sUnable to load Public Key\n", "") <= 0)
+ goto err;
+ ERR_print_errors(bp);
+ } else {
+ if (EVP_PKEY_print_public(bp, pkey, 16, NULL) <= 0)
+ goto err;
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+ /* may not be */
+ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
+ goto err;
+
+ if (X509_REQ_get_attr_count(x) == 0) {
+ if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
+ goto err;
+ } else {
+ for (i = 0; i < X509_REQ_get_attr_count(x); i++) {
+ ASN1_TYPE *at;
+ X509_ATTRIBUTE *a;
+ ASN1_BIT_STRING *bs = NULL;
+ ASN1_OBJECT *aobj;
+ int j, type = 0, count = 1, ii = 0;
+
+ a = X509_REQ_get_attr(x, i);
+ aobj = X509_ATTRIBUTE_get0_object(a);
+ if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
+ continue;
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
+ ii = 0;
+ count = X509_ATTRIBUTE_count(a);
+ get_next:
+ at = X509_ATTRIBUTE_get0_type(a, ii);
+ type = at->type;
+ bs = at->value.asn1_string;
+ }
+ for (j = 25 - j; j > 0; j--)
+ if (BIO_write(bp, " ", 1) != 1)
+ goto err;
+ if (BIO_puts(bp, ":") <= 0)
+ goto err;
+ switch (type) {
+ case V_ASN1_PRINTABLESTRING:
+ case V_ASN1_T61STRING:
+ case V_ASN1_NUMERICSTRING:
+ case V_ASN1_UTF8STRING:
+ case V_ASN1_IA5STRING:
+ if (BIO_write(bp, (char *)bs->data, bs->length)
+ != bs->length)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+ break;
+ default:
+ if (BIO_puts(bp, "unable to print attribute\n") <= 0)
+ goto err;
+ break;
+ }
+ if (++ii < count)
+ goto get_next;
+ }
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+ exts = X509_REQ_get_extensions(x);
+ if (exts) {
+ if (BIO_printf(bp, "%8sRequested Extensions:\n", "") <= 0)
+ goto err;
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ex;
+ int critical;
+ ex = sk_X509_EXTENSION_value(exts, i);
+ if (BIO_printf(bp, "%12s", "") <= 0)
+ goto err;
+ obj = X509_EXTENSION_get_object(ex);
+ if (i2a_ASN1_OBJECT(bp, obj) <= 0)
+ goto err;
+ critical = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0)
+ goto err;
+ if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
+ if (BIO_printf(bp, "%16s", "") <= 0
+ || ASN1_STRING_print(bp,
+ X509_EXTENSION_get_data(ex)) <= 0)
+ goto err;
+ }
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ const X509_ALGOR *sig_alg;
+ const ASN1_BIT_STRING *sig;
+ X509_REQ_get0_signature(x, &sig, &sig_alg);
+ if (!X509_signature_print(bp, sig_alg, sig))
+ goto err;
+ }
+
+ return 1;
+ err:
+ X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
+ return 0;
+}
+
+int X509_REQ_print(BIO *bp, X509_REQ *x)
+{
+ return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c
new file mode 100644
index 000000000000..ccacbe7cbf8f
--- /dev/null
+++ b/crypto/x509/t_x509.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+
+#ifndef OPENSSL_NO_STDIO
+int X509_print_fp(FILE *fp, X509 *x)
+{
+ return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+ unsigned long cflag)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
+ return 0;
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = X509_print_ex(b, x, nmflag, cflag);
+ BIO_free(b);
+ return ret;
+}
+#endif
+
+int X509_print(BIO *bp, X509 *x)
+{
+ return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+ unsigned long cflag)
+{
+ long l;
+ int ret = 0, i;
+ char *m = NULL, mlch = ' ';
+ int nmindent = 0;
+ ASN1_INTEGER *bs;
+ EVP_PKEY *pkey = NULL;
+ const char *neg;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT)
+ nmindent = 16;
+
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+ goto err;
+ if (BIO_write(bp, " Data:\n", 10) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_get_version(x);
+ if (l >= 0 && l <= 2) {
+ if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
+ goto err;
+ } else {
+ if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_SERIAL)) {
+
+ if (BIO_write(bp, " Serial Number:", 22) <= 0)
+ goto err;
+
+ bs = X509_get_serialNumber(x);
+ if (bs->length <= (int)sizeof(long)) {
+ ERR_set_mark();
+ l = ASN1_INTEGER_get(bs);
+ ERR_pop_to_mark();
+ } else {
+ l = -1;
+ }
+ if (l != -1) {
+ unsigned long ul;
+ if (bs->type == V_ASN1_NEG_INTEGER) {
+ ul = 0 - (unsigned long)l;
+ neg = "-";
+ } else {
+ ul = l;
+ neg = "";
+ }
+ if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0)
+ goto err;
+ } else {
+ neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+ if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+ goto err;
+
+ for (i = 0; i < bs->length; i++) {
+ if (BIO_printf(bp, "%02x%c", bs->data[i],
+ ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+ goto err;
+ }
+ }
+
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+ const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x);
+
+ if (BIO_puts(bp, " ") <= 0)
+ goto err;
+ if (X509_signature_print(bp, tsig_alg, NULL) <= 0)
+ goto err;
+ }
+
+ if (!(cflag & X509_FLAG_NO_ISSUER)) {
+ if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+ < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+ if (BIO_write(bp, " Validity\n", 17) <= 0)
+ goto err;
+ if (BIO_write(bp, " Not Before: ", 24) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get0_notBefore(x)))
+ goto err;
+ if (BIO_write(bp, "\n Not After : ", 25) <= 0)
+ goto err;
+ if (!ASN1_TIME_print(bp, X509_get0_notAfter(x)))
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
+ goto err;
+ if (X509_NAME_print_ex
+ (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+ goto err;
+ if (BIO_write(bp, "\n", 1) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x);
+ ASN1_OBJECT *xpoid;
+ X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
+ goto err;
+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+ goto err;
+ if (i2a_ASN1_OBJECT(bp, xpoid) <= 0)
+ goto err;
+ if (BIO_puts(bp, "\n") <= 0)
+ goto err;
+
+ pkey = X509_get0_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bp);
+ } else {
+ EVP_PKEY_print_public(bp, pkey, 16, NULL);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_IDS)) {
+ const ASN1_BIT_STRING *iuid, *suid;
+ X509_get0_uids(x, &iuid, &suid);
+ if (iuid != NULL) {
+ if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, iuid, 12))
+ goto err;
+ }
+ if (suid != NULL) {
+ if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+ goto err;
+ if (!X509_signature_dump(bp, suid, 12))
+ goto err;
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+ X509V3_extensions_print(bp, "X509v3 extensions",
+ X509_get0_extensions(x), cflag, 8);
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+ const X509_ALGOR *sig_alg;
+ const ASN1_BIT_STRING *sig;
+ X509_get0_signature(&sig, &sig_alg, x);
+ if (X509_signature_print(bp, sig_alg, sig) <= 0)
+ goto err;
+ }
+ if (!(cflag & X509_FLAG_NO_AUX)) {
+ if (!X509_aux_print(bp, x, 0))
+ goto err;
+ }
+ ret = 1;
+ err:
+ OPENSSL_free(m);
+ return ret;
+}
+
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+ unsigned char *der = NULL;
+ unsigned char *dertmp;
+ int derlen;
+ int i;
+ unsigned char SHA1md[SHA_DIGEST_LENGTH];
+ ASN1_BIT_STRING *keybstr;
+ X509_NAME *subj;
+
+ /*
+ * display the hash of the subject as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
+ goto err;
+ subj = X509_get_subject_name(x);
+ derlen = i2d_X509_NAME(subj, NULL);
+ if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
+ goto err;
+ i2d_X509_NAME(subj, &dertmp);
+
+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ OPENSSL_free(der);
+ der = NULL;
+
+ /*
+ * display the hash of the public key as it would appear in OCSP requests
+ */
+ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
+ goto err;
+
+ keybstr = X509_get0_pubkey_bitstr(x);
+
+ if (keybstr == NULL)
+ goto err;
+
+ if (!EVP_Digest(ASN1_STRING_get0_data(keybstr),
+ ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(),
+ NULL))
+ goto err;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+ goto err;
+ }
+ BIO_printf(bp, "\n");
+
+ return 1;
+ err:
+ OPENSSL_free(der);
+ return 0;
+}
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
+{
+ const unsigned char *s;
+ int i, n;
+
+ n = sig->length;
+ s = sig->data;
+ for (i = 0; i < n; i++) {
+ if ((i % 18) == 0) {
+ if (BIO_write(bp, "\n", 1) <= 0)
+ return 0;
+ if (BIO_indent(bp, indent, indent) <= 0)
+ return 0;
+ }
+ if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
+ return 0;
+ }
+ if (BIO_write(bp, "\n", 1) != 1)
+ return 0;
+
+ return 1;
+}
+
+int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig)
+{
+ int sig_nid;
+ if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
+ return 0;
+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+ return 0;
+
+ sig_nid = OBJ_obj2nid(sigalg->algorithm);
+ if (sig_nid != NID_undef) {
+ int pkey_nid, dig_nid;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+ if (ameth && ameth->sig_print)
+ return ameth->sig_print(bp, sigalg, sig, 9, 0);
+ }
+ }
+ if (sig)
+ return X509_signature_dump(bp, sig, 9);
+ else if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ return 1;
+}
+
+int X509_aux_print(BIO *out, X509 *x, int indent)
+{
+ char oidstr[80], first;
+ STACK_OF(ASN1_OBJECT) *trust, *reject;
+ const unsigned char *alias, *keyid;
+ int keyidlen;
+ int i;
+ if (X509_trusted(x) == 0)
+ return 1;
+ trust = X509_get0_trust_objects(x);
+ reject = X509_get0_reject_objects(x);
+ if (trust) {
+ first = 1;
+ BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof(oidstr),
+ sk_ASN1_OBJECT_value(trust, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+ if (reject) {
+ first = 1;
+ BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+ for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
+ if (!first)
+ BIO_puts(out, ", ");
+ else
+ first = 0;
+ OBJ_obj2txt(oidstr, sizeof(oidstr),
+ sk_ASN1_OBJECT_value(reject, i), 0);
+ BIO_puts(out, oidstr);
+ }
+ BIO_puts(out, "\n");
+ } else
+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+ alias = X509_alias_get0(x, NULL);
+ if (alias)
+ BIO_printf(out, "%*sAlias: %s\n", indent, "", alias);
+ keyid = X509_keyid_get0(x, &keyidlen);
+ if (keyid) {
+ BIO_printf(out, "%*sKey Id: ", indent, "");
+ for (i = 0; i < keyidlen; i++)
+ BIO_printf(out, "%s%02X", i ? ":" : "", keyid[i]);
+ BIO_write(out, "\n", 1);
+ }
+ return 1;
+}
diff --git a/crypto/x509/verify_extra_test.c b/crypto/x509/verify_extra_test.c
deleted file mode 100644
index 08509f013194..000000000000
--- a/crypto/x509/verify_extra_test.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Written by Matt Caswell for the OpenSSL project.
- */
-/* ====================================================================
- * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-#include <stdio.h>
-#include <openssl/crypto.h>
-#include <openssl/bio.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-
-static STACK_OF(X509) *load_certs_from_file(const char *filename)
-{
- STACK_OF(X509) *certs;
- BIO *bio;
- X509 *x;
-
- bio = BIO_new_file(filename, "r");
-
- if (bio == NULL) {
- return NULL;
- }
-
- certs = sk_X509_new_null();
- if (certs == NULL) {
- BIO_free(bio);
- return NULL;
- }
-
- ERR_set_mark();
- do {
- x = PEM_read_bio_X509(bio, NULL, 0, NULL);
- if (x != NULL && !sk_X509_push(certs, x)) {
- sk_X509_pop_free(certs, X509_free);
- BIO_free(bio);
- return NULL;
- } else if (x == NULL) {
- /*
- * We probably just ran out of certs, so ignore any errors
- * generated
- */
- ERR_pop_to_mark();
- }
- } while (x != NULL);
-
- BIO_free(bio);
-
- return certs;
-}
-
-/*
- * Test for CVE-2015-1793 (Alternate Chains Certificate Forgery)
- *
- * Chain is as follows:
- *
- * rootCA (self-signed)
- * |
- * interCA
- * |
- * subinterCA subinterCA (self-signed)
- * | |
- * leaf ------------------
- * |
- * bad
- *
- * rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE
- * leaf and bad have CA=FALSE
- *
- * subinterCA and subinterCA (ss) have the same subject name and keys
- *
- * interCA (but not rootCA) and subinterCA (ss) are in the trusted store
- * (roots.pem)
- * leaf and subinterCA are in the untrusted list (untrusted.pem)
- * bad is the certificate being verified (bad.pem)
- *
- * Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has
- * CA=FALSE, and will therefore incorrectly verify bad
- *
- */
-static int test_alt_chains_cert_forgery(void)
-{
- int ret = 0;
- int i;
- X509 *x = NULL;
- STACK_OF(X509) *untrusted = NULL;
- BIO *bio = NULL;
- X509_STORE_CTX *sctx = NULL;
- X509_STORE *store = NULL;
- X509_LOOKUP *lookup = NULL;
-
- store = X509_STORE_new();
- if (store == NULL)
- goto err;
-
- lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
- if (lookup == NULL)
- goto err;
- if(!X509_LOOKUP_load_file(lookup, "certs/roots.pem", X509_FILETYPE_PEM))
- goto err;
-
- untrusted = load_certs_from_file("certs/untrusted.pem");
-
- if ((bio = BIO_new_file("certs/bad.pem", "r")) == NULL)
- goto err;
-
- if((x = PEM_read_bio_X509(bio, NULL, 0, NULL)) == NULL)
- goto err;
-
- sctx = X509_STORE_CTX_new();
- if (sctx == NULL)
- goto err;
-
- if (!X509_STORE_CTX_init(sctx, store, x, untrusted))
- goto err;
-
- i = X509_verify_cert(sctx);
-
- if(i == 0 && X509_STORE_CTX_get_error(sctx) == X509_V_ERR_INVALID_CA) {
- /* This is the result we were expecting: Test passed */
- ret = 1;
- }
- err:
- X509_STORE_CTX_free(sctx);
- X509_free(x);
- BIO_free(bio);
- sk_X509_pop_free(untrusted, X509_free);
- X509_STORE_free(store);
- if (ret != 1)
- ERR_print_errors_fp(stderr);
- return ret;
-}
-
-int main(void)
-{
- CRYPTO_malloc_debug_init();
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
-
- ERR_load_crypto_strings();
- OpenSSL_add_all_digests();
-
- if (!test_alt_chains_cert_forgery()) {
- fprintf(stderr, "Test alt chains cert forgery failed\n");
- return 1;
- }
-
- EVP_cleanup();
- CRYPTO_cleanup_all_ex_data();
- ERR_remove_thread_state(NULL);
- ERR_free_strings();
- CRYPTO_mem_leaks_fp(stderr);
-
- printf("PASS\n");
- return 0;
-}
diff --git a/crypto/x509/vpm_int.h b/crypto/x509/vpm_int.h
deleted file mode 100644
index 9c55defc512a..000000000000
--- a/crypto/x509/vpm_int.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* vpm_int.h */
-/*
- * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
- * 2013.
- */
-/* ====================================================================
- * Copyright (c) 2013 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/* internal only structure to hold additional X509_VERIFY_PARAM data */
-
-struct X509_VERIFY_PARAM_ID_st {
- STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
- unsigned int hostflags; /* Flags to control matching features */
- char *peername; /* Matching hostname in peer certificate */
- char *email; /* If not NULL email address to match */
- size_t emaillen;
- unsigned char *ip; /* If not NULL IP address to match */
- size_t iplen; /* Length of IP address */
-};
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
deleted file mode 100644
index 6fa28ebada46..000000000000
--- a/crypto/x509/x509.h
+++ /dev/null
@@ -1,1330 +0,0 @@
-/* crypto/x509/x509.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * ECDH support in OpenSSL originally developed by
- * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
- */
-
-#ifndef HEADER_X509_H
-# define HEADER_X509_H
-
-# include <openssl/e_os2.h>
-# include <openssl/symhacks.h>
-# ifndef OPENSSL_NO_BUFFER
-# include <openssl/buffer.h>
-# endif
-# ifndef OPENSSL_NO_EVP
-# include <openssl/evp.h>
-# endif
-# ifndef OPENSSL_NO_BIO
-# include <openssl/bio.h>
-# endif
-# include <openssl/stack.h>
-# include <openssl/asn1.h>
-# include <openssl/safestack.h>
-
-# ifndef OPENSSL_NO_EC
-# include <openssl/ec.h>
-# endif
-
-# ifndef OPENSSL_NO_ECDSA
-# include <openssl/ecdsa.h>
-# endif
-
-# ifndef OPENSSL_NO_ECDH
-# include <openssl/ecdh.h>
-# endif
-
-# ifndef OPENSSL_NO_DEPRECATED
-# ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-# endif
-# ifndef OPENSSL_NO_DSA
-# include <openssl/dsa.h>
-# endif
-# ifndef OPENSSL_NO_DH
-# include <openssl/dh.h>
-# endif
-# endif
-
-# ifndef OPENSSL_NO_SHA
-# include <openssl/sha.h>
-# endif
-# include <openssl/ossl_typ.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-# ifdef OPENSSL_SYS_WIN32
-/* Under Win32 these are defined in wincrypt.h */
-# undef X509_NAME
-# undef X509_CERT_PAIR
-# undef X509_EXTENSIONS
-# endif
-
-# define X509_FILETYPE_PEM 1
-# define X509_FILETYPE_ASN1 2
-# define X509_FILETYPE_DEFAULT 3
-
-# define X509v3_KU_DIGITAL_SIGNATURE 0x0080
-# define X509v3_KU_NON_REPUDIATION 0x0040
-# define X509v3_KU_KEY_ENCIPHERMENT 0x0020
-# define X509v3_KU_DATA_ENCIPHERMENT 0x0010
-# define X509v3_KU_KEY_AGREEMENT 0x0008
-# define X509v3_KU_KEY_CERT_SIGN 0x0004
-# define X509v3_KU_CRL_SIGN 0x0002
-# define X509v3_KU_ENCIPHER_ONLY 0x0001
-# define X509v3_KU_DECIPHER_ONLY 0x8000
-# define X509v3_KU_UNDEF 0xffff
-
-typedef struct X509_objects_st {
- int nid;
- int (*a2i) (void);
- int (*i2a) (void);
-} X509_OBJECTS;
-
-struct X509_algor_st {
- ASN1_OBJECT *algorithm;
- ASN1_TYPE *parameter;
-} /* X509_ALGOR */ ;
-
-DECLARE_ASN1_SET_OF(X509_ALGOR)
-
-typedef STACK_OF(X509_ALGOR) X509_ALGORS;
-
-typedef struct X509_val_st {
- ASN1_TIME *notBefore;
- ASN1_TIME *notAfter;
-} X509_VAL;
-
-struct X509_pubkey_st {
- X509_ALGOR *algor;
- ASN1_BIT_STRING *public_key;
- EVP_PKEY *pkey;
-};
-
-typedef struct X509_sig_st {
- X509_ALGOR *algor;
- ASN1_OCTET_STRING *digest;
-} X509_SIG;
-
-typedef struct X509_name_entry_st {
- ASN1_OBJECT *object;
- ASN1_STRING *value;
- int set;
- int size; /* temp variable */
-} X509_NAME_ENTRY;
-
-DECLARE_STACK_OF(X509_NAME_ENTRY)
-DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
-
-/* we always keep X509_NAMEs in 2 forms. */
-struct X509_name_st {
- STACK_OF(X509_NAME_ENTRY) *entries;
- int modified; /* true if 'bytes' needs to be built */
-# ifndef OPENSSL_NO_BUFFER
- BUF_MEM *bytes;
-# else
- char *bytes;
-# endif
-/* unsigned long hash; Keep the hash around for lookups */
- unsigned char *canon_enc;
- int canon_enclen;
-} /* X509_NAME */ ;
-
-DECLARE_STACK_OF(X509_NAME)
-
-# define X509_EX_V_NETSCAPE_HACK 0x8000
-# define X509_EX_V_INIT 0x0001
-typedef struct X509_extension_st {
- ASN1_OBJECT *object;
- ASN1_BOOLEAN critical;
- ASN1_OCTET_STRING *value;
-} X509_EXTENSION;
-
-typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
-
-DECLARE_STACK_OF(X509_EXTENSION)
-DECLARE_ASN1_SET_OF(X509_EXTENSION)
-
-/* a sequence of these are used */
-typedef struct x509_attributes_st {
- ASN1_OBJECT *object;
- int single; /* 0 for a set, 1 for a single item (which is
- * wrong) */
- union {
- char *ptr;
- /*
- * 0
- */ STACK_OF(ASN1_TYPE) *set;
- /*
- * 1
- */ ASN1_TYPE *single;
- } value;
-} X509_ATTRIBUTE;
-
-DECLARE_STACK_OF(X509_ATTRIBUTE)
-DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
-
-typedef struct X509_req_info_st {
- ASN1_ENCODING enc;
- ASN1_INTEGER *version;
- X509_NAME *subject;
- X509_PUBKEY *pubkey;
- /* d=2 hl=2 l= 0 cons: cont: 00 */
- STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
-} X509_REQ_INFO;
-
-typedef struct X509_req_st {
- X509_REQ_INFO *req_info;
- X509_ALGOR *sig_alg;
- ASN1_BIT_STRING *signature;
- int references;
-} X509_REQ;
-
-typedef struct x509_cinf_st {
- ASN1_INTEGER *version; /* [ 0 ] default of v1 */
- ASN1_INTEGER *serialNumber;
- X509_ALGOR *signature;
- X509_NAME *issuer;
- X509_VAL *validity;
- X509_NAME *subject;
- X509_PUBKEY *key;
- ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
- ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
- STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
- ASN1_ENCODING enc;
-} X509_CINF;
-
-/*
- * This stuff is certificate "auxiliary info" it contains details which are
- * useful in certificate stores and databases. When used this is tagged onto
- * the end of the certificate itself
- */
-
-typedef struct x509_cert_aux_st {
- STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
- STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
- ASN1_UTF8STRING *alias; /* "friendly name" */
- ASN1_OCTET_STRING *keyid; /* key id of private key */
- STACK_OF(X509_ALGOR) *other; /* other unspecified info */
-} X509_CERT_AUX;
-
-struct x509_st {
- X509_CINF *cert_info;
- X509_ALGOR *sig_alg;
- ASN1_BIT_STRING *signature;
- int valid;
- int references;
- char *name;
- CRYPTO_EX_DATA ex_data;
- /* These contain copies of various extension values */
- long ex_pathlen;
- long ex_pcpathlen;
- unsigned long ex_flags;
- unsigned long ex_kusage;
- unsigned long ex_xkusage;
- unsigned long ex_nscert;
- ASN1_OCTET_STRING *skid;
- AUTHORITY_KEYID *akid;
- X509_POLICY_CACHE *policy_cache;
- STACK_OF(DIST_POINT) *crldp;
- STACK_OF(GENERAL_NAME) *altname;
- NAME_CONSTRAINTS *nc;
-# ifndef OPENSSL_NO_RFC3779
- STACK_OF(IPAddressFamily) *rfc3779_addr;
- struct ASIdentifiers_st *rfc3779_asid;
-# endif
-# ifndef OPENSSL_NO_SHA
- unsigned char sha1_hash[SHA_DIGEST_LENGTH];
-# endif
- X509_CERT_AUX *aux;
-} /* X509 */ ;
-
-DECLARE_STACK_OF(X509)
-DECLARE_ASN1_SET_OF(X509)
-
-/* This is used for a table of trust checking functions */
-
-typedef struct x509_trust_st {
- int trust;
- int flags;
- int (*check_trust) (struct x509_trust_st *, X509 *, int);
- char *name;
- int arg1;
- void *arg2;
-} X509_TRUST;
-
-DECLARE_STACK_OF(X509_TRUST)
-
-typedef struct x509_cert_pair_st {
- X509 *forward;
- X509 *reverse;
-} X509_CERT_PAIR;
-
-/* standard trust ids */
-
-# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */
-
-# define X509_TRUST_COMPAT 1
-# define X509_TRUST_SSL_CLIENT 2
-# define X509_TRUST_SSL_SERVER 3
-# define X509_TRUST_EMAIL 4
-# define X509_TRUST_OBJECT_SIGN 5
-# define X509_TRUST_OCSP_SIGN 6
-# define X509_TRUST_OCSP_REQUEST 7
-# define X509_TRUST_TSA 8
-
-/* Keep these up to date! */
-# define X509_TRUST_MIN 1
-# define X509_TRUST_MAX 8
-
-/* trust_flags values */
-# define X509_TRUST_DYNAMIC 1
-# define X509_TRUST_DYNAMIC_NAME 2
-
-/* check_trust return codes */
-
-# define X509_TRUST_TRUSTED 1
-# define X509_TRUST_REJECTED 2
-# define X509_TRUST_UNTRUSTED 3
-
-/* Flags for X509_print_ex() */
-
-# define X509_FLAG_COMPAT 0
-# define X509_FLAG_NO_HEADER 1L
-# define X509_FLAG_NO_VERSION (1L << 1)
-# define X509_FLAG_NO_SERIAL (1L << 2)
-# define X509_FLAG_NO_SIGNAME (1L << 3)
-# define X509_FLAG_NO_ISSUER (1L << 4)
-# define X509_FLAG_NO_VALIDITY (1L << 5)
-# define X509_FLAG_NO_SUBJECT (1L << 6)
-# define X509_FLAG_NO_PUBKEY (1L << 7)
-# define X509_FLAG_NO_EXTENSIONS (1L << 8)
-# define X509_FLAG_NO_SIGDUMP (1L << 9)
-# define X509_FLAG_NO_AUX (1L << 10)
-# define X509_FLAG_NO_ATTRIBUTES (1L << 11)
-# define X509_FLAG_NO_IDS (1L << 12)
-
-/* Flags specific to X509_NAME_print_ex() */
-
-/* The field separator information */
-
-# define XN_FLAG_SEP_MASK (0xf << 16)
-
-# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old
- * X509_NAME_print */
-# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */
-# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */
-# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */
-# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */
-
-# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */
-
-/* How the field name is shown */
-
-# define XN_FLAG_FN_MASK (0x3 << 21)
-
-# define XN_FLAG_FN_SN 0/* Object short name */
-# define XN_FLAG_FN_LN (1 << 21)/* Object long name */
-# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */
-# define XN_FLAG_FN_NONE (3 << 21)/* No field names */
-
-# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */
-
-/*
- * This determines if we dump fields we don't recognise: RFC2253 requires
- * this.
- */
-
-# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
-
-# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20
- * characters */
-
-/* Complete set of RFC2253 flags */
-
-# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
- XN_FLAG_SEP_COMMA_PLUS | \
- XN_FLAG_DN_REV | \
- XN_FLAG_FN_SN | \
- XN_FLAG_DUMP_UNKNOWN_FIELDS)
-
-/* readable oneline form */
-
-# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
- ASN1_STRFLGS_ESC_QUOTE | \
- XN_FLAG_SEP_CPLUS_SPC | \
- XN_FLAG_SPC_EQ | \
- XN_FLAG_FN_SN)
-
-/* readable multiline form */
-
-# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
- ASN1_STRFLGS_ESC_MSB | \
- XN_FLAG_SEP_MULTILINE | \
- XN_FLAG_SPC_EQ | \
- XN_FLAG_FN_LN | \
- XN_FLAG_FN_ALIGN)
-
-struct x509_revoked_st {
- ASN1_INTEGER *serialNumber;
- ASN1_TIME *revocationDate;
- STACK_OF(X509_EXTENSION) /* optional */ *extensions;
- /* Set up if indirect CRL */
- STACK_OF(GENERAL_NAME) *issuer;
- /* Revocation reason */
- int reason;
- int sequence; /* load sequence */
-};
-
-DECLARE_STACK_OF(X509_REVOKED)
-DECLARE_ASN1_SET_OF(X509_REVOKED)
-
-typedef struct X509_crl_info_st {
- ASN1_INTEGER *version;
- X509_ALGOR *sig_alg;
- X509_NAME *issuer;
- ASN1_TIME *lastUpdate;
- ASN1_TIME *nextUpdate;
- STACK_OF(X509_REVOKED) *revoked;
- STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
- ASN1_ENCODING enc;
-} X509_CRL_INFO;
-
-struct X509_crl_st {
- /* actual signature */
- X509_CRL_INFO *crl;
- X509_ALGOR *sig_alg;
- ASN1_BIT_STRING *signature;
- int references;
- int flags;
- /* Copies of various extensions */
- AUTHORITY_KEYID *akid;
- ISSUING_DIST_POINT *idp;
- /* Convenient breakdown of IDP */
- int idp_flags;
- int idp_reasons;
- /* CRL and base CRL numbers for delta processing */
- ASN1_INTEGER *crl_number;
- ASN1_INTEGER *base_crl_number;
-# ifndef OPENSSL_NO_SHA
- unsigned char sha1_hash[SHA_DIGEST_LENGTH];
-# endif
- STACK_OF(GENERAL_NAMES) *issuers;
- const X509_CRL_METHOD *meth;
- void *meth_data;
-} /* X509_CRL */ ;
-
-DECLARE_STACK_OF(X509_CRL)
-DECLARE_ASN1_SET_OF(X509_CRL)
-
-typedef struct private_key_st {
- int version;
- /* The PKCS#8 data types */
- X509_ALGOR *enc_algor;
- ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
- /* When decrypted, the following will not be NULL */
- EVP_PKEY *dec_pkey;
- /* used to encrypt and decrypt */
- int key_length;
- char *key_data;
- int key_free; /* true if we should auto free key_data */
- /* expanded version of 'enc_algor' */
- EVP_CIPHER_INFO cipher;
- int references;
-} X509_PKEY;
-
-# ifndef OPENSSL_NO_EVP
-typedef struct X509_info_st {
- X509 *x509;
- X509_CRL *crl;
- X509_PKEY *x_pkey;
- EVP_CIPHER_INFO enc_cipher;
- int enc_len;
- char *enc_data;
- int references;
-} X509_INFO;
-
-DECLARE_STACK_OF(X509_INFO)
-# endif
-
-/*
- * The next 2 structures and their 8 routines were sent to me by Pat Richard
- * <patr@x509.com> and are used to manipulate Netscapes spki structures -
- * useful if you are writing a CA web page
- */
-typedef struct Netscape_spkac_st {
- X509_PUBKEY *pubkey;
- ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */
-} NETSCAPE_SPKAC;
-
-typedef struct Netscape_spki_st {
- NETSCAPE_SPKAC *spkac; /* signed public key and challenge */
- X509_ALGOR *sig_algor;
- ASN1_BIT_STRING *signature;
-} NETSCAPE_SPKI;
-
-/* Netscape certificate sequence structure */
-typedef struct Netscape_certificate_sequence {
- ASN1_OBJECT *type;
- STACK_OF(X509) *certs;
-} NETSCAPE_CERT_SEQUENCE;
-
-/*- Unused (and iv length is wrong)
-typedef struct CBCParameter_st
- {
- unsigned char iv[8];
- } CBC_PARAM;
-*/
-
-/* Password based encryption structure */
-
-typedef struct PBEPARAM_st {
- ASN1_OCTET_STRING *salt;
- ASN1_INTEGER *iter;
-} PBEPARAM;
-
-/* Password based encryption V2 structures */
-
-typedef struct PBE2PARAM_st {
- X509_ALGOR *keyfunc;
- X509_ALGOR *encryption;
-} PBE2PARAM;
-
-typedef struct PBKDF2PARAM_st {
-/* Usually OCTET STRING but could be anything */
- ASN1_TYPE *salt;
- ASN1_INTEGER *iter;
- ASN1_INTEGER *keylength;
- X509_ALGOR *prf;
-} PBKDF2PARAM;
-
-/* PKCS#8 private key info structure */
-
-struct pkcs8_priv_key_info_st {
- /* Flag for various broken formats */
- int broken;
-# define PKCS8_OK 0
-# define PKCS8_NO_OCTET 1
-# define PKCS8_EMBEDDED_PARAM 2
-# define PKCS8_NS_DB 3
-# define PKCS8_NEG_PRIVKEY 4
- ASN1_INTEGER *version;
- X509_ALGOR *pkeyalg;
- /* Should be OCTET STRING but some are broken */
- ASN1_TYPE *pkey;
- STACK_OF(X509_ATTRIBUTE) *attributes;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-# include <openssl/x509_vfy.h>
-# include <openssl/pkcs7.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-# define X509_EXT_PACK_UNKNOWN 1
-# define X509_EXT_PACK_STRING 2
-
-# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
-/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
-# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
-# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
-# define X509_extract_key(x) X509_get_pubkey(x)/*****/
-# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
-# define X509_REQ_get_subject_name(x) ((x)->req_info->subject)
-# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
-# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b))
-# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
-
-# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
-# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
-# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
-# define X509_CRL_get_issuer(x) ((x)->crl->issuer)
-# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
-
-void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
-X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
- int (*crl_free) (X509_CRL *crl),
- int (*crl_lookup) (X509_CRL *crl,
- X509_REVOKED **ret,
- ASN1_INTEGER *ser,
- X509_NAME *issuer),
- int (*crl_verify) (X509_CRL *crl,
- EVP_PKEY *pk));
-void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
-
-void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
-void *X509_CRL_get_meth_data(X509_CRL *crl);
-
-/*
- * This one is only used so that a binary form can output, as in
- * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
- */
-# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
-
-const char *X509_verify_cert_error_string(long n);
-
-# ifndef OPENSSL_NO_EVP
-int X509_verify(X509 *a, EVP_PKEY *r);
-
-int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
-int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
-int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
-
-NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
-char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
-EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
-int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
-
-int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
-
-int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
-int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);
-
-int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
-int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert);
-int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
-int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
-int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
-int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl);
-int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
-
-int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
- unsigned char *md, unsigned int *len);
-int X509_digest(const X509 *data, const EVP_MD *type,
- unsigned char *md, unsigned int *len);
-int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
- unsigned char *md, unsigned int *len);
-int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
- unsigned char *md, unsigned int *len);
-int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
- unsigned char *md, unsigned int *len);
-# endif
-
-# ifndef OPENSSL_NO_FP_API
-X509 *d2i_X509_fp(FILE *fp, X509 **x509);
-int i2d_X509_fp(FILE *fp, X509 *x509);
-X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
-int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
-X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
-int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
-# ifndef OPENSSL_NO_RSA
-RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
-int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
-RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
-int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
-RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
-int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
-# endif
-# ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
-int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
-DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
-int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
-# endif
-# ifndef OPENSSL_NO_EC
-EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
-int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
-EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
-int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
-# endif
-X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
-int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
-PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
- PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
-int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
-int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
-# endif
-
-# ifndef OPENSSL_NO_BIO
-X509 *d2i_X509_bio(BIO *bp, X509 **x509);
-int i2d_X509_bio(BIO *bp, X509 *x509);
-X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
-int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
-X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
-int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
-# ifndef OPENSSL_NO_RSA
-RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
-int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
-RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
-int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
-RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
-int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
-# endif
-# ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
-int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
-DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
-int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
-# endif
-# ifndef OPENSSL_NO_EC
-EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
-int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
-EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
-int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
-# endif
-X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
-int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
-PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
- PKCS8_PRIV_KEY_INFO **p8inf);
-int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
-int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
-int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
-int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
-EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
-# endif
-
-X509 *X509_dup(X509 *x509);
-X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
-X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
-X509_CRL *X509_CRL_dup(X509_CRL *crl);
-X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
-X509_REQ *X509_REQ_dup(X509_REQ *req);
-X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
-int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
- void *pval);
-void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
- X509_ALGOR *algor);
-void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
-int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
-
-X509_NAME *X509_NAME_dup(X509_NAME *xn);
-X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
-
-int X509_cmp_time(const ASN1_TIME *s, time_t *t);
-int X509_cmp_current_time(const ASN1_TIME *s);
-ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
-ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
- int offset_day, long offset_sec, time_t *t);
-ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
-
-const char *X509_get_default_cert_area(void);
-const char *X509_get_default_cert_dir(void);
-const char *X509_get_default_cert_file(void);
-const char *X509_get_default_cert_dir_env(void);
-const char *X509_get_default_cert_file_env(void);
-const char *X509_get_default_private_dir(void);
-
-X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
-X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
-
-DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
-DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
-DECLARE_ASN1_FUNCTIONS(X509_VAL)
-
-DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
-
-int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
-EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
-int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
-int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
-# ifndef OPENSSL_NO_RSA
-int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
-RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
-# endif
-# ifndef OPENSSL_NO_DSA
-int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
-DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
-# endif
-# ifndef OPENSSL_NO_EC
-int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
-EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
-# endif
-
-DECLARE_ASN1_FUNCTIONS(X509_SIG)
-DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
-DECLARE_ASN1_FUNCTIONS(X509_REQ)
-
-DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
-X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
-
-DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
-DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
-
-DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
-
-DECLARE_ASN1_FUNCTIONS(X509_NAME)
-
-int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
-
-DECLARE_ASN1_FUNCTIONS(X509_CINF)
-
-DECLARE_ASN1_FUNCTIONS(X509)
-DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
-
-DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
-
-int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
-int X509_set_ex_data(X509 *r, int idx, void *arg);
-void *X509_get_ex_data(X509 *r, int idx);
-int i2d_X509_AUX(X509 *a, unsigned char **pp);
-X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
-
-int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
-
-void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
- const X509 *x);
-int X509_get_signature_nid(const X509 *x);
-
-int X509_alias_set1(X509 *x, unsigned char *name, int len);
-int X509_keyid_set1(X509 *x, unsigned char *id, int len);
-unsigned char *X509_alias_get0(X509 *x, int *len);
-unsigned char *X509_keyid_get0(X509 *x, int *len);
-int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
- int);
-int X509_TRUST_set(int *t, int trust);
-int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
-int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
-void X509_trust_clear(X509 *x);
-void X509_reject_clear(X509 *x);
-
-DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
-DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
-DECLARE_ASN1_FUNCTIONS(X509_CRL)
-
-int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
-int X509_CRL_get0_by_serial(X509_CRL *crl,
- X509_REVOKED **ret, ASN1_INTEGER *serial);
-int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
-
-X509_PKEY *X509_PKEY_new(void);
-void X509_PKEY_free(X509_PKEY *a);
-int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
-X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
- long length);
-
-DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
-DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
-DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
-
-# ifndef OPENSSL_NO_EVP
-X509_INFO *X509_INFO_new(void);
-void X509_INFO_free(X509_INFO *a);
-char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);
-
-int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
- ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
-
-int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
- unsigned char *md, unsigned int *len);
-
-int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
- X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
- char *data, EVP_PKEY *pkey, const EVP_MD *type);
-
-int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
- unsigned char *md, unsigned int *len);
-
-int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
- ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
-
-int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
- X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
- EVP_PKEY *pkey, const EVP_MD *type);
-int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
- X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
- void *asn, EVP_MD_CTX *ctx);
-# endif
-
-int X509_set_version(X509 *x, long version);
-int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
-ASN1_INTEGER *X509_get_serialNumber(X509 *x);
-int X509_set_issuer_name(X509 *x, X509_NAME *name);
-X509_NAME *X509_get_issuer_name(X509 *a);
-int X509_set_subject_name(X509 *x, X509_NAME *name);
-X509_NAME *X509_get_subject_name(X509 *a);
-int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
-int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
-int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
-EVP_PKEY *X509_get_pubkey(X509 *x);
-ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
-int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );
-
-int X509_REQ_set_version(X509_REQ *x, long version);
-int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
-int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
-EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
-int X509_REQ_extension_nid(int nid);
-int *X509_REQ_get_extension_nids(void);
-void X509_REQ_set_extension_nids(int *nids);
-STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
-int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
- int nid);
-int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
-int X509_REQ_get_attr_count(const X509_REQ *req);
-int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
-int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
- int lastpos);
-X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
-X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
-int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
-int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
- const ASN1_OBJECT *obj, int type,
- const unsigned char *bytes, int len);
-int X509_REQ_add1_attr_by_NID(X509_REQ *req,
- int nid, int type,
- const unsigned char *bytes, int len);
-int X509_REQ_add1_attr_by_txt(X509_REQ *req,
- const char *attrname, int type,
- const unsigned char *bytes, int len);
-
-int X509_CRL_set_version(X509_CRL *x, long version);
-int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
-int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
-int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
-int X509_CRL_sort(X509_CRL *crl);
-
-int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
-int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
-
-X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
- EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);
-
-int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
-
-int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
-int X509_chain_check_suiteb(int *perror_depth,
- X509 *x, STACK_OF(X509) *chain,
- unsigned long flags);
-int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
-STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
-
-int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
-unsigned long X509_issuer_and_serial_hash(X509 *a);
-
-int X509_issuer_name_cmp(const X509 *a, const X509 *b);
-unsigned long X509_issuer_name_hash(X509 *a);
-
-int X509_subject_name_cmp(const X509 *a, const X509 *b);
-unsigned long X509_subject_name_hash(X509 *x);
-
-# ifndef OPENSSL_NO_MD5
-unsigned long X509_issuer_name_hash_old(X509 *a);
-unsigned long X509_subject_name_hash_old(X509 *x);
-# endif
-
-int X509_cmp(const X509 *a, const X509 *b);
-int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
-unsigned long X509_NAME_hash(X509_NAME *x);
-unsigned long X509_NAME_hash_old(X509_NAME *x);
-
-int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
-int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
-# ifndef OPENSSL_NO_FP_API
-int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
- unsigned long cflag);
-int X509_print_fp(FILE *bp, X509 *x);
-int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
-int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
-int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
- unsigned long flags);
-# endif
-
-# ifndef OPENSSL_NO_BIO
-int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
-int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
- unsigned long flags);
-int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
- unsigned long cflag);
-int X509_print(BIO *bp, X509 *x);
-int X509_ocspid_print(BIO *bp, X509 *x);
-int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
-int X509_CRL_print(BIO *bp, X509_CRL *x);
-int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
- unsigned long cflag);
-int X509_REQ_print(BIO *bp, X509_REQ *req);
-# endif
-
-int X509_NAME_entry_count(X509_NAME *name);
-int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
-int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
- char *buf, int len);
-
-/*
- * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use
- * lastpos, search after that position on.
- */
-int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
-int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
- int lastpos);
-X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
-X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
-int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
- int loc, int set);
-int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
- unsigned char *bytes, int len, int loc,
- int set);
-int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
- unsigned char *bytes, int len, int loc,
- int set);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
- const char *field, int type,
- const unsigned char *bytes,
- int len);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
- int type, unsigned char *bytes,
- int len);
-int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
- const unsigned char *bytes, int len, int loc,
- int set);
-X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
- ASN1_OBJECT *obj, int type,
- const unsigned char *bytes,
- int len);
-int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
-int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
- const unsigned char *bytes, int len);
-ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
-ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
-
-int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
-int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
- int nid, int lastpos);
-int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
- ASN1_OBJECT *obj, int lastpos);
-int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
- int crit, int lastpos);
-X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
-X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
-STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
- X509_EXTENSION *ex, int loc);
-
-int X509_get_ext_count(X509 *x);
-int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
-int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
-int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
-X509_EXTENSION *X509_get_ext(X509 *x, int loc);
-X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
-int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
-void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
-int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
- unsigned long flags);
-
-int X509_CRL_get_ext_count(X509_CRL *x);
-int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
-int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
-int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
-X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
-X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
-int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
-void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
-int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
- unsigned long flags);
-
-int X509_REVOKED_get_ext_count(X509_REVOKED *x);
-int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
-int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
- int lastpos);
-int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
-X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
-X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
-int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
-void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
-int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
- unsigned long flags);
-
-X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
- int nid, int crit,
- ASN1_OCTET_STRING *data);
-X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
- ASN1_OBJECT *obj, int crit,
- ASN1_OCTET_STRING *data);
-int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
-int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
-int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
-ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
-ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
-int X509_EXTENSION_get_critical(X509_EXTENSION *ex);
-
-int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
-int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
- int lastpos);
-int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
- ASN1_OBJECT *obj, int lastpos);
-X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
-X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
- X509_ATTRIBUTE *attr);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
- **x, const ASN1_OBJECT *obj,
- int type,
- const unsigned char *bytes,
- int len);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
- **x, int nid, int type,
- const unsigned char *bytes,
- int len);
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
- **x, const char *attrname,
- int type,
- const unsigned char *bytes,
- int len);
-void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
- int lastpos, int type);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
- int atrtype, const void *data,
- int len);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
- const ASN1_OBJECT *obj,
- int atrtype, const void *data,
- int len);
-X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
- const char *atrname, int type,
- const unsigned char *bytes,
- int len);
-int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
-int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
- const void *data, int len);
-void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
- void *data);
-int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
-ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
-ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
-
-int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
-int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
-int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
- int lastpos);
-X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
-X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
-int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
-int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
- const ASN1_OBJECT *obj, int type,
- const unsigned char *bytes, int len);
-int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
- int nid, int type,
- const unsigned char *bytes, int len);
-int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
- const char *attrname, int type,
- const unsigned char *bytes, int len);
-
-int X509_verify_cert(X509_STORE_CTX *ctx);
-
-/* lookup a cert from a X509 STACK */
-X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
- ASN1_INTEGER *serial);
-X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
-
-DECLARE_ASN1_FUNCTIONS(PBEPARAM)
-DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
-DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
-
-int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
- const unsigned char *salt, int saltlen);
-
-X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
- const unsigned char *salt, int saltlen);
-X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
- unsigned char *salt, int saltlen);
-X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
- unsigned char *salt, int saltlen,
- unsigned char *aiv, int prf_nid);
-
-X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
- int prf_nid, int keylen);
-
-/* PKCS#8 utilities */
-
-DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
-
-EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
-PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
-PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
-
-int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
- int version, int ptype, void *pval,
- unsigned char *penc, int penclen);
-int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
- const unsigned char **pk, int *ppklen,
- X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);
-
-int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
- int ptype, void *pval,
- unsigned char *penc, int penclen);
-int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
- const unsigned char **pk, int *ppklen,
- X509_ALGOR **pa, X509_PUBKEY *pub);
-
-int X509_check_trust(X509 *x, int id, int flags);
-int X509_TRUST_get_count(void);
-X509_TRUST *X509_TRUST_get0(int idx);
-int X509_TRUST_get_by_id(int id);
-int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
- char *name, int arg1, void *arg2);
-void X509_TRUST_cleanup(void);
-int X509_TRUST_get_flags(X509_TRUST *xp);
-char *X509_TRUST_get0_name(X509_TRUST *xp);
-int X509_TRUST_get_trust(X509_TRUST *xp);
-
-/* BEGIN ERROR CODES */
-/*
- * The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
- */
-
-void ERR_load_X509_strings(void);
-
-/* Error codes for the X509 functions. */
-
-/* Function codes. */
-# define X509_F_ADD_CERT_DIR 100
-# define X509_F_BY_FILE_CTRL 101
-# define X509_F_CHECK_NAME_CONSTRAINTS 106
-# define X509_F_CHECK_POLICY 145
-# define X509_F_DIR_CTRL 102
-# define X509_F_GET_CERT_BY_SUBJECT 103
-# define X509_F_NETSCAPE_SPKI_B64_DECODE 129
-# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130
-# define X509_F_X509AT_ADD1_ATTR 135
-# define X509_F_X509V3_ADD_EXT 104
-# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136
-# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137
-# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140
-# define X509_F_X509_ATTRIBUTE_GET0_DATA 139
-# define X509_F_X509_ATTRIBUTE_SET1_DATA 138
-# define X509_F_X509_CHECK_PRIVATE_KEY 128
-# define X509_F_X509_CRL_DIFF 105
-# define X509_F_X509_CRL_PRINT_FP 147
-# define X509_F_X509_EXTENSION_CREATE_BY_NID 108
-# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109
-# define X509_F_X509_GET_PUBKEY_PARAMETERS 110
-# define X509_F_X509_LOAD_CERT_CRL_FILE 132
-# define X509_F_X509_LOAD_CERT_FILE 111
-# define X509_F_X509_LOAD_CRL_FILE 112
-# define X509_F_X509_NAME_ADD_ENTRY 113
-# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114
-# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131
-# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115
-# define X509_F_X509_NAME_ONELINE 116
-# define X509_F_X509_NAME_PRINT 117
-# define X509_F_X509_PRINT_EX_FP 118
-# define X509_F_X509_PUBKEY_GET 119
-# define X509_F_X509_PUBKEY_SET 120
-# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144
-# define X509_F_X509_REQ_PRINT_EX 121
-# define X509_F_X509_REQ_PRINT_FP 122
-# define X509_F_X509_REQ_TO_X509 123
-# define X509_F_X509_STORE_ADD_CERT 124
-# define X509_F_X509_STORE_ADD_CRL 125
-# define X509_F_X509_STORE_CTX_GET1_ISSUER 146
-# define X509_F_X509_STORE_CTX_INIT 143
-# define X509_F_X509_STORE_CTX_NEW 142
-# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134
-# define X509_F_X509_TO_X509_REQ 126
-# define X509_F_X509_TRUST_ADD 133
-# define X509_F_X509_TRUST_SET 141
-# define X509_F_X509_VERIFY_CERT 127
-
-/* Reason codes. */
-# define X509_R_AKID_MISMATCH 110
-# define X509_R_BAD_X509_FILETYPE 100
-# define X509_R_BASE64_DECODE_ERROR 118
-# define X509_R_CANT_CHECK_DH_KEY 114
-# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
-# define X509_R_CRL_ALREADY_DELTA 127
-# define X509_R_CRL_VERIFY_FAILURE 131
-# define X509_R_ERR_ASN1_LIB 102
-# define X509_R_IDP_MISMATCH 128
-# define X509_R_INVALID_DIRECTORY 113
-# define X509_R_INVALID_FIELD_NAME 119
-# define X509_R_INVALID_TRUST 123
-# define X509_R_ISSUER_MISMATCH 129
-# define X509_R_KEY_TYPE_MISMATCH 115
-# define X509_R_KEY_VALUES_MISMATCH 116
-# define X509_R_LOADING_CERT_DIR 103
-# define X509_R_LOADING_DEFAULTS 104
-# define X509_R_METHOD_NOT_SUPPORTED 124
-# define X509_R_NAME_TOO_LONG 134
-# define X509_R_NEWER_CRL_NOT_NEWER 132
-# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105
-# define X509_R_NO_CRL_NUMBER 130
-# define X509_R_PUBLIC_KEY_DECODE_ERROR 125
-# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
-# define X509_R_SHOULD_RETRY 106
-# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
-# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
-# define X509_R_UNKNOWN_KEY_TYPE 117
-# define X509_R_UNKNOWN_NID 109
-# define X509_R_UNKNOWN_PURPOSE_ID 121
-# define X509_R_UNKNOWN_TRUST_ID 120
-# define X509_R_UNSUPPORTED_ALGORITHM 111
-# define X509_R_WRONG_LOOKUP_TYPE 112
-# define X509_R_WRONG_TYPE 122
-
-# ifdef __cplusplus
-}
-# endif
-#endif
diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c
index 25010753078c..63895efe4608 100644
--- a/crypto/x509/x509_att.c
+++ b/crypto/x509/x509_att.c
@@ -1,69 +1,21 @@
-/* crypto/x509/x509_att.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <openssl/stack.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include <openssl/safestack.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "x509_lcl.h"
int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{
@@ -73,22 +25,21 @@ 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)
{
- ASN1_OBJECT *obj;
+ const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
- obj = OBJ_nid2obj(nid);
if (obj == NULL)
- return (-2);
- return (X509at_get_attr_by_OBJ(x, obj, lastpos));
+ 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)
+ const ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_ATTRIBUTE *ex;
if (sk == NULL)
- return (-1);
+ return -1;
lastpos++;
if (lastpos < 0)
lastpos = 0;
@@ -96,17 +47,17 @@ int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
for (; lastpos < n; lastpos++) {
ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
if (OBJ_cmp(ex->object, obj) == 0)
- return (lastpos);
+ return lastpos;
}
- return (-1);
+ 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);
+
+ return sk_X509_ATTRIBUTE_value(x, loc);
}
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
@@ -114,9 +65,9 @@ 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);
+ return NULL;
ret = sk_X509_ATTRIBUTE_delete(x, loc);
- return (ret);
+ return ret;
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
@@ -142,15 +93,13 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
goto err;
if (*x == NULL)
*x = sk;
- return (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);
+ X509_ATTRIBUTE_free(new_attr);
+ sk_X509_ATTRIBUTE_free(sk);
+ return NULL;
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
@@ -201,7 +150,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
}
void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
- ASN1_OBJECT *obj, int lastpos, int type)
+ const ASN1_OBJECT *obj, int lastpos, int type)
{
int i;
X509_ATTRIBUTE *at;
@@ -226,12 +175,12 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID);
- return (NULL);
+ return NULL;
}
ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
if (ret == NULL)
ASN1_OBJECT_free(obj);
- return (ret);
+ return ret;
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
@@ -245,7 +194,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
if ((ret = X509_ATTRIBUTE_new()) == NULL) {
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,
ERR_R_MALLOC_FAILURE);
- return (NULL);
+ return NULL;
}
} else
ret = *attr;
@@ -257,11 +206,11 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
if ((attr != NULL) && (*attr == NULL))
*attr = ret;
- return (ret);
+ return ret;
err:
if ((attr == NULL) || (ret != *attr))
X509_ATTRIBUTE_free(ret);
- return (NULL);
+ return NULL;
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
@@ -277,7 +226,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", atrname);
- return (NULL);
+ return NULL;
}
nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
@@ -287,10 +236,10 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
{
if ((attr == NULL) || (obj == NULL))
- return (0);
+ return 0;
ASN1_OBJECT_free(attr->object);
attr->object = OBJ_dup(obj);
- return (1);
+ return attr->object != NULL;
}
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
@@ -310,15 +259,12 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
}
atype = stmp->type;
} else if (len != -1) {
- if (!(stmp = ASN1_STRING_type_new(attrtype)))
+ if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL)
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
@@ -328,7 +274,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
ASN1_STRING_free(stmp);
return 1;
}
- if (!(ttmp = ASN1_TYPE_new()))
+ if ((ttmp = ASN1_TYPE_new()) == NULL)
goto err;
if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
if (!ASN1_TYPE_set1(ttmp, attrtype, data))
@@ -337,7 +283,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
ASN1_TYPE_set(ttmp, atype, stmp);
stmp = NULL;
}
- if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
+ if (!sk_ASN1_TYPE_push(attr->set, ttmp))
goto err;
return 1;
err:
@@ -347,20 +293,18 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
return 0;
}
-int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
+int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
{
- if (!attr->single)
- return sk_ASN1_TYPE_num(attr->value.set);
- if (attr->value.single)
- return 1;
- return 0;
+ if (attr == NULL)
+ return 0;
+ return sk_ASN1_TYPE_num(attr->set);
}
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
{
if (attr == NULL)
- return (NULL);
- return (attr->object);
+ return NULL;
+ return attr->object;
}
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
@@ -380,11 +324,6 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
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;
+ return sk_ASN1_TYPE_value(attr->set, idx);
}
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 49c71b91280e..02fad0c671ce 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -1,174 +1,128 @@
-/* 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.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <ctype.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
{
int i;
- X509_CINF *ai, *bi;
+ const X509_CINF *ai, *bi;
- ai = a->cert_info;
- bi = b->cert_info;
- i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
+ ai = &a->cert_info;
+ bi = &b->cert_info;
+ i = ASN1_INTEGER_cmp(&ai->serialNumber, &bi->serialNumber);
if (i)
- return (i);
- return (X509_NAME_cmp(ai->issuer, bi->issuer));
+ 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;
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
unsigned char md[16];
char *f;
- EVP_MD_CTX_init(&ctx);
- f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
- if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
+ if (ctx == NULL)
+ goto err;
+ f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0);
+ if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL))
goto err;
- if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
+ if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f)))
goto err;
OPENSSL_free(f);
if (!EVP_DigestUpdate
- (&ctx, (unsigned char *)a->cert_info->serialNumber->data,
- (unsigned long)a->cert_info->serialNumber->length))
+ (ctx, (unsigned char *)a->cert_info.serialNumber.data,
+ (unsigned long)a->cert_info.serialNumber.length))
goto err;
- if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
+ if (!EVP_DigestFinal_ex(ctx, &(md[0]), NULL))
goto err;
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
err:
- EVP_MD_CTX_cleanup(&ctx);
- return (ret);
+ EVP_MD_CTX_free(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));
+ 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));
+ 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));
+ return X509_NAME_cmp(a->crl.issuer, b->crl.issuer);
}
-#ifndef OPENSSL_NO_SHA
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
{
return memcmp(a->sha1_hash, b->sha1_hash, 20);
}
-#endif
-X509_NAME *X509_get_issuer_name(X509 *a)
+X509_NAME *X509_get_issuer_name(const X509 *a)
{
- return (a->cert_info->issuer);
+ return a->cert_info.issuer;
}
unsigned long X509_issuer_name_hash(X509 *x)
{
- return (X509_NAME_hash(x->cert_info->issuer));
+ return X509_NAME_hash(x->cert_info.issuer);
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_name_hash_old(X509 *x)
{
- return (X509_NAME_hash_old(x->cert_info->issuer));
+ return X509_NAME_hash_old(x->cert_info.issuer);
}
#endif
-X509_NAME *X509_get_subject_name(X509 *a)
+X509_NAME *X509_get_subject_name(const X509 *a)
{
- return (a->cert_info->subject);
+ return a->cert_info.subject;
}
ASN1_INTEGER *X509_get_serialNumber(X509 *a)
{
- return (a->cert_info->serialNumber);
+ return &a->cert_info.serialNumber;
+}
+
+const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a)
+{
+ return &a->cert_info.serialNumber;
}
unsigned long X509_subject_name_hash(X509 *x)
{
- return (X509_NAME_hash(x->cert_info->subject));
+ return X509_NAME_hash(x->cert_info.subject);
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_subject_name_hash_old(X509 *x)
{
- return (X509_NAME_hash_old(x->cert_info->subject));
+ return X509_NAME_hash_old(x->cert_info.subject);
}
#endif
-#ifndef OPENSSL_NO_SHA
/*
* Compare two certificates: they must be identical for this to work. NB:
* Although "cmp" operations are generally prototyped to take "const"
@@ -188,16 +142,16 @@ int X509_cmp(const X509 *a, const X509 *b)
if (rv)
return rv;
/* Check for match against stored encoding too */
- if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) {
- rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
- if (rv)
- return rv;
- return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
- a->cert_info->enc.len);
+ if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) {
+ if (a->cert_info.enc.len < b->cert_info.enc.len)
+ return -1;
+ if (a->cert_info.enc.len > b->cert_info.enc.len)
+ return 1;
+ return memcmp(a->cert_info.enc.enc, b->cert_info.enc.enc,
+ a->cert_info.enc.len);
}
return rv;
}
-#endif
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
{
@@ -219,7 +173,7 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
ret = a->canon_enclen - b->canon_enclen;
- if (ret)
+ if (ret != 0 || a->canon_enclen == 0)
return ret;
return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
@@ -240,7 +194,7 @@ unsigned long X509_NAME_hash(X509_NAME *x)
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
- return (ret);
+ return ret;
}
#ifndef OPENSSL_NO_MD5
@@ -251,23 +205,25 @@ unsigned long X509_NAME_hash(X509_NAME *x)
unsigned long X509_NAME_hash_old(X509_NAME *x)
{
- EVP_MD_CTX md_ctx;
+ EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
unsigned long ret = 0;
unsigned char md[16];
+ if (md_ctx == NULL)
+ return ret;
+
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x, NULL);
- EVP_MD_CTX_init(&md_ctx);
- EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
- && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
- && EVP_DigestFinal_ex(&md_ctx, md, NULL))
+ EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL)
+ && EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length)
+ && EVP_DigestFinal_ex(md_ctx, md, NULL))
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
- EVP_MD_CTX_cleanup(&md_ctx);
+ EVP_MD_CTX_free(md_ctx);
- return (ret);
+ return ret;
}
#endif
@@ -276,22 +232,20 @@ 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;
+ x.cert_info.serialNumber = *serial;
+ x.cert_info.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 x509;
}
- return (NULL);
+ return NULL;
}
X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
@@ -302,31 +256,31 @@ X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
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 x509;
}
- return (NULL);
+ return NULL;
}
-EVP_PKEY *X509_get_pubkey(X509 *x)
+EVP_PKEY *X509_get0_pubkey(const X509 *x)
{
- if ((x == NULL) || (x->cert_info == NULL))
- return (NULL);
- return (X509_PUBKEY_get(x->cert_info->key));
+ if (x == NULL)
+ return NULL;
+ return X509_PUBKEY_get0(x->cert_info.key);
}
-ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+EVP_PKEY *X509_get_pubkey(X509 *x)
{
- if (!x)
+ if (x == NULL)
return NULL;
- return x->cert_info->key->public_key;
+ return X509_PUBKEY_get(x->cert_info.key);
}
-int X509_check_private_key(X509 *x, EVP_PKEY *k)
+int X509_check_private_key(const X509 *x, const EVP_PKEY *k)
{
- EVP_PKEY *xk;
+ const EVP_PKEY *xk;
int ret;
- xk = X509_get_pubkey(x);
+ xk = X509_get0_pubkey(x);
if (xk)
ret = EVP_PKEY_cmp(xk, k);
@@ -345,8 +299,6 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
case -2:
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
}
- if (xk)
- EVP_PKEY_free(xk);
if (ret > 0)
return 1;
return 0;
@@ -364,8 +316,8 @@ static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
{
const EC_GROUP *grp = NULL;
int curve_nid;
- if (pkey && pkey->type == EVP_PKEY_EC)
- grp = EC_KEY_get0_group(pkey->pkey.ec);
+ if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_EC)
+ grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey));
if (!grp)
return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
curve_nid = EC_GROUP_get_curve_name(grp);
@@ -395,11 +347,12 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
unsigned long flags)
{
int rv, i, sign_nid;
- EVP_PKEY *pk = NULL;
- unsigned long tflags;
+ EVP_PKEY *pk;
+ unsigned long tflags = flags;
+
if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
return X509_V_OK;
- tflags = flags;
+
/* If no EE certificate passed in must be first in chain */
if (x == NULL) {
x = sk_X509_value(chain, 0);
@@ -407,6 +360,17 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
} else
i = 0;
+ pk = X509_get0_pubkey(x);
+
+ /*
+ * With DANE-EE(3) success, or DANE-EE(3)/PKIX-EE(1) failure we don't build
+ * a chain all, just report trust success or failure, but must also report
+ * Suite-B errors if applicable. This is indicated via a NULL chain
+ * pointer. All we need to do is check the leaf key algorithm.
+ */
+ if (chain == NULL)
+ return check_suite_b(pk, -1, &tflags);
+
if (X509_get_version(x) != 2) {
rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
/* Correct error depth */
@@ -414,7 +378,6 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
goto end;
}
- pk = X509_get_pubkey(x);
/* Check EE key only */
rv = check_suite_b(pk, -1, &tflags);
if (rv != X509_V_OK) {
@@ -429,8 +392,7 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
goto end;
}
- EVP_PKEY_free(pk);
- pk = X509_get_pubkey(x);
+ pk = X509_get0_pubkey(x);
rv = check_suite_b(pk, sign_nid, &tflags);
if (rv != X509_V_OK)
goto end;
@@ -439,8 +401,6 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
/* Final check: root CA signature */
rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
end:
- if (pk)
- EVP_PKEY_free(pk);
if (rv != X509_V_OK) {
/* Invalid signature or LOS errors are for previous cert */
if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
@@ -448,7 +408,7 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
i--;
/*
* If we have LOS error and flags changed then we are signing P-384
- * with P-256. Use more meaninggul error.
+ * with P-256. Use more meaningful error.
*/
if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
@@ -463,7 +423,7 @@ int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
int sign_nid;
if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
return X509_V_OK;
- sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
+ sign_nid = OBJ_obj2nid(crl->crl.sig_alg.algorithm);
return check_suite_b(pk, sign_nid, &flags);
}
@@ -492,7 +452,7 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
ret = sk_X509_dup(chain);
for (i = 0; i < sk_X509_num(ret); i++) {
X509 *x = sk_X509_value(ret, i);
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(x);
}
return ret;
}
diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c
index 50ca2a6d1820..099ffda1e15c 100644
--- a/crypto/x509/x509_d2.c
+++ b/crypto/x509/x509_d2.c
@@ -1,85 +1,35 @@
-/* crypto/x509/x509_d2.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/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);
+ 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);
+ return 0;
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
/* clear any errors */
ERR_clear_error();
- return (1);
+ return 1;
}
int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
@@ -90,20 +40,18 @@ int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
if (file != NULL) {
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
if (lookup == NULL)
- return (0);
+ return 0;
if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
- return (0);
+ return 0;
}
if (path != NULL) {
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
if (lookup == NULL)
- return (0);
+ return 0;
if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
- return (0);
+ return 0;
}
if ((path == NULL) && (file == NULL))
- return (0);
- return (1);
+ return 0;
+ return 1;
}
-
-#endif
diff --git a/crypto/x509/x509_def.c b/crypto/x509/x509_def.c
index 25c553755627..bfa8d7d8522a 100644
--- a/crypto/x509/x509_def.c
+++ b/crypto/x509/x509_def.c
@@ -1,92 +1,43 @@
-/* crypto/x509/x509_def.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
const char *X509_get_default_private_dir(void)
{
- return (X509_PRIVATE_DIR);
+ return X509_PRIVATE_DIR;
}
const char *X509_get_default_cert_area(void)
{
- return (X509_CERT_AREA);
+ return X509_CERT_AREA;
}
const char *X509_get_default_cert_dir(void)
{
- return (X509_CERT_DIR);
+ return X509_CERT_DIR;
}
const char *X509_get_default_cert_file(void)
{
- return (X509_CERT_FILE);
+ return X509_CERT_FILE;
}
const char *X509_get_default_cert_dir_env(void)
{
- return (X509_CERT_DIR_EVP);
+ return X509_CERT_DIR_EVP;
}
const char *X509_get_default_cert_file_env(void)
{
- return (X509_CERT_FILE_EVP);
+ return X509_CERT_FILE_EVP;
}
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index a2a8e1b08bb2..739708e24fa3 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -1,188 +1,181 @@
-/* crypto/x509/x509_err.c */
-/* ====================================================================
- * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "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.
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
-#include <stdio.h>
#include <openssl/err.h>
-#include <openssl/x509.h>
+#include <openssl/x509err.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_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"},
- {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),
+static const ERR_STRING_DATA X509_str_functs[] = {
+ {ERR_PACK(ERR_LIB_X509, X509_F_ADD_CERT_DIR, 0), "add_cert_dir"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_BUILD_CHAIN, 0), "build_chain"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_BY_FILE_CTRL, 0), "by_file_ctrl"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_NAME_CONSTRAINTS, 0),
+ "check_name_constraints"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_CHECK_POLICY, 0), "check_policy"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_DANE_I2D, 0), "dane_i2d"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_DIR_CTRL, 0), "dir_ctrl"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_GET_CERT_BY_SUBJECT, 0),
+ "get_cert_by_subject"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_I2D_X509_AUX, 0), "i2d_X509_AUX"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_LOOKUP_CERTS_SK, 0), "lookup_certs_sk"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_DECODE, 0),
+ "NETSCAPE_SPKI_b64_decode"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_NETSCAPE_SPKI_B64_ENCODE, 0),
+ "NETSCAPE_SPKI_b64_encode"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_NEW_DIR, 0), "new_dir"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509AT_ADD1_ATTR, 0), "X509at_add1_attr"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509V3_ADD_EXT, 0), "X509v3_add_ext"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_NID, 0),
"X509_ATTRIBUTE_create_by_NID"},
- {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, 0),
"X509_ATTRIBUTE_create_by_OBJ"},
- {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, 0),
"X509_ATTRIBUTE_create_by_txt"},
- {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"},
- {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"},
- {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"},
- {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"},
- {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"},
- {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_GET0_DATA, 0),
+ "X509_ATTRIBUTE_get0_data"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_ATTRIBUTE_SET1_DATA, 0),
+ "X509_ATTRIBUTE_set1_data"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_CHECK_PRIVATE_KEY, 0),
+ "X509_check_private_key"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_DIFF, 0), "X509_CRL_diff"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_METHOD_NEW, 0),
+ "X509_CRL_METHOD_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_CRL_PRINT_FP, 0), "X509_CRL_print_fp"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_NID, 0),
"X509_EXTENSION_create_by_NID"},
- {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_EXTENSION_CREATE_BY_OBJ, 0),
"X509_EXTENSION_create_by_OBJ"},
- {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_GET_PUBKEY_PARAMETERS, 0),
"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),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_CRL_FILE, 0),
+ "X509_load_cert_crl_file"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CERT_FILE, 0),
+ "X509_load_cert_file"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOAD_CRL_FILE, 0),
+ "X509_load_crl_file"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_METH_NEW, 0),
+ "X509_LOOKUP_meth_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_LOOKUP_NEW, 0), "X509_LOOKUP_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ADD_ENTRY, 0),
+ "X509_NAME_add_entry"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_CANON, 0), "x509_name_canon"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_NID, 0),
"X509_NAME_ENTRY_create_by_NID"},
- {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, 0),
"X509_NAME_ENTRY_create_by_txt"},
- {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ENTRY_SET_OBJECT, 0),
"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),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_ONELINE, 0), "X509_NAME_oneline"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_NAME_PRINT, 0), "X509_NAME_print"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_OBJECT_NEW, 0), "X509_OBJECT_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_PRINT_EX_FP, 0), "X509_print_ex_fp"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_DECODE, 0),
+ "x509_pubkey_decode"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_GET0, 0), "X509_PUBKEY_get0"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_PUBKEY_SET, 0), "X509_PUBKEY_set"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_CHECK_PRIVATE_KEY, 0),
"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),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_EX, 0), "X509_REQ_print_ex"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_PRINT_FP, 0), "X509_REQ_print_fp"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_REQ_TO_X509, 0), "X509_REQ_to_X509"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CERT, 0),
+ "X509_STORE_add_cert"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_CRL, 0),
+ "X509_STORE_add_crl"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_ADD_LOOKUP, 0),
+ "X509_STORE_add_lookup"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_GET1_ISSUER, 0),
"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),
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_INIT, 0),
+ "X509_STORE_CTX_init"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_NEW, 0),
+ "X509_STORE_CTX_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_CTX_PURPOSE_INHERIT, 0),
"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"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_STORE_NEW, 0), "X509_STORE_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_TO_X509_REQ, 0), "X509_to_X509_REQ"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_ADD, 0), "X509_TRUST_add"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_SET, 0), "X509_TRUST_set"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, 0), "X509_verify_cert"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_PARAM_NEW, 0),
+ "X509_VERIFY_PARAM_new"},
{0, NULL}
};
-static ERR_STRING_DATA X509_str_reasons[] = {
- {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"},
- {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
- {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"},
- {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
- {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),
- "cert already in hash table"},
- {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"},
- {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"},
- {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"},
- {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"},
- {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"},
- {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"},
- {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"},
- {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"},
- {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
- {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"},
- {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
- {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
- {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"},
- {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"},
- {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"},
- {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
- "no cert set for us to verify"},
- {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"},
- {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
- {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},
- {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"},
- {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),
- "unable to find parameters in chain"},
- {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),
- "unable to get certs public key"},
- {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
- {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"},
- {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"},
- {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
- {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
- {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
- {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"},
+static const ERR_STRING_DATA X509_str_reasons[] = {
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_AKID_MISMATCH), "akid mismatch"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_SELECTOR), "bad selector"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_BASE64_DECODE_ERROR),
+ "base64 decode error"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE),
+ "cert already in hash table"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
+ "crl verify failure"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME),
+ "invalid field name"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_ISSUER_MISMATCH), "issuer mismatch"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_KEY_VALUES_MISMATCH),
+ "key values mismatch"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_LOADING_CERT_DIR), "loading cert dir"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_LOADING_DEFAULTS), "loading defaults"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_METHOD_NOT_SUPPORTED),
+ "method not supported"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NAME_TOO_LONG), "name too long"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NEWER_CRL_NOT_NEWER),
+ "newer crl not newer"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERTIFICATE_FOUND),
+ "no certificate found"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERTIFICATE_OR_CRL_FOUND),
+ "no certificate or crl found"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
+ "no cert set for us to verify"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CRL_FOUND), "no crl found"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CRL_NUMBER), "no crl number"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_PUBLIC_KEY_DECODE_ERROR),
+ "public key decode error"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_PUBLIC_KEY_ENCODE_ERROR),
+ "public key encode error"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_SHOULD_RETRY), "should retry"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),
+ "unable to find parameters in chain"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),
+ "unable to get certs public key"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID),
+ "unknown purpose id"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM),
+ "unsupported algorithm"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
+ {ERR_PACK(ERR_LIB_X509, 0, X509_R_WRONG_TYPE), "wrong type"},
{0, NULL}
};
#endif
-void ERR_load_X509_strings(void)
+int 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);
+ ERR_load_strings_const(X509_str_functs);
+ ERR_load_strings_const(X509_str_reasons);
}
#endif
+ return 1;
}
diff --git a/crypto/x509/x509_ext.c b/crypto/x509/x509_ext.c
index fb4e311d7100..2db843760c68 100644
--- a/crypto/x509/x509_ext.c
+++ b/crypto/x509/x509_ext.c
@@ -1,193 +1,145 @@
-/* crypto/x509/x509_ext.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <openssl/stack.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
#include <openssl/x509v3.h>
-int X509_CRL_get_ext_count(X509_CRL *x)
+int X509_CRL_get_ext_count(const X509_CRL *x)
{
- return (X509v3_get_ext_count(x->crl->extensions));
+ return X509v3_get_ext_count(x->crl.extensions);
}
-int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
+int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos)
{
- return (X509v3_get_ext_by_NID(x->crl->extensions, nid, 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)
+int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
+ int lastpos)
{
- return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, 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)
+int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos)
{
- return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
+ return X509v3_get_ext_by_critical(x->crl.extensions, crit, lastpos);
}
-X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
+X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc)
{
- return (X509v3_get_ext(x->crl->extensions, 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));
+ return X509v3_delete_ext(x->crl.extensions, loc);
}
-void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
+void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx)
{
- return X509V3_get_d2i(x->crl->extensions, nid, crit, 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);
+ 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);
+ return (X509v3_add_ext(&(x->crl.extensions), ex, loc) != NULL);
}
-int X509_get_ext_count(X509 *x)
+int X509_get_ext_count(const X509 *x)
{
- return (X509v3_get_ext_count(x->cert_info->extensions));
+ return X509v3_get_ext_count(x->cert_info.extensions);
}
-int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
+int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos)
{
- return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, 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)
+int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos)
{
- return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, 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)
+int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos)
{
return (X509v3_get_ext_by_critical
- (x->cert_info->extensions, crit, lastpos));
+ (x->cert_info.extensions, crit, lastpos));
}
-X509_EXTENSION *X509_get_ext(X509 *x, int loc)
+X509_EXTENSION *X509_get_ext(const X509 *x, int loc)
{
- return (X509v3_get_ext(x->cert_info->extensions, 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));
+ 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);
+ return (X509v3_add_ext(&(x->cert_info.extensions), ex, loc) != NULL);
}
-void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
+void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx)
{
- return X509V3_get_d2i(x->cert_info->extensions, nid, crit, 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,
+ return X509V3_add1_i2d(&x->cert_info.extensions, nid, value, crit,
flags);
}
-int X509_REVOKED_get_ext_count(X509_REVOKED *x)
+int X509_REVOKED_get_ext_count(const X509_REVOKED *x)
{
- return (X509v3_get_ext_count(x->extensions));
+ return X509v3_get_ext_count(x->extensions);
}
-int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
+int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos)
{
- return (X509v3_get_ext_by_NID(x->extensions, nid, 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 X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
int lastpos)
{
- return (X509v3_get_ext_by_OBJ(x->extensions, obj, 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)
+int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos)
{
- return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
+ return X509v3_get_ext_by_critical(x->extensions, crit, lastpos);
}
-X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
+X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)
{
- return (X509v3_get_ext(x->extensions, 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));
+ return X509v3_delete_ext(x->extensions, loc);
}
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
@@ -195,7 +147,7 @@ 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)
+void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx)
{
return X509V3_get_d2i(x->extensions, nid, crit, idx);
}
@@ -205,7 +157,3 @@ int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
{
return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
}
-
-IMPLEMENT_STACK_OF(X509_EXTENSION)
-
-IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
diff --git a/crypto/x509/x509_lcl.h b/crypto/x509/x509_lcl.h
new file mode 100644
index 000000000000..c517a7745637
--- /dev/null
+++ b/crypto/x509/x509_lcl.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/refcount.h"
+
+/*
+ * This structure holds all parameters associated with a verify operation by
+ * including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+struct X509_VERIFY_PARAM_st {
+ char *name;
+ time_t check_time; /* Time to use */
+ uint32_t 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 */
+ int auth_level; /* Security level for chain verification */
+ STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
+ /* Peer identity details */
+ STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
+ unsigned int hostflags; /* Flags to control matching features */
+ char *peername; /* Matching hostname in peer certificate */
+ char *email; /* If not NULL email address to match */
+ size_t emaillen;
+ unsigned char *ip; /* If not NULL IP address to match */
+ size_t iplen; /* Length of IP address */
+};
+
+/* No error callback if depth < 0 */
+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth);
+
+/* a sequence of these are used */
+struct x509_attributes_st {
+ ASN1_OBJECT *object;
+ STACK_OF(ASN1_TYPE) *set;
+};
+
+struct X509_extension_st {
+ ASN1_OBJECT *object;
+ ASN1_BOOLEAN critical;
+ ASN1_OCTET_STRING value;
+};
+
+/*
+ * Method to handle CRL access. In general a CRL could be very large (several
+ * Mb) and can consume large amounts of resources if stored in memory by
+ * multiple processes. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC 1
+
+struct x509_crl_method_st {
+ int flags;
+ int (*crl_init) (X509_CRL *crl);
+ int (*crl_free) (X509_CRL *crl);
+ int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+ ASN1_INTEGER *ser, X509_NAME *issuer);
+ int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
+
+struct x509_lookup_method_st {
+ 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, X509_LOOKUP_TYPE type,
+ X509_NAME *name, X509_OBJECT *ret);
+ int (*get_by_issuer_serial) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ X509_NAME *name, ASN1_INTEGER *serial,
+ X509_OBJECT *ret);
+ int (*get_by_fingerprint) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const unsigned char *bytes, int len,
+ X509_OBJECT *ret);
+ int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const char *str, int len, X509_OBJECT *ret);
+};
+
+/* 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 */
+ void *method_data; /* method data */
+ X509_STORE *store_ctx; /* who owns us */
+};
+
+/*
+ * This is used to hold everything. It is used for all certificate
+ * validation. Once we have a certificate chain, the 'verify' function is
+ * then called to actually check the cert chain.
+ */
+struct x509_store_st {
+ /* The following is a cache of trusted certs */
+ int cache; /* if true, stash any hits */
+ STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
+ /* These are external lookup methods */
+ STACK_OF(X509_LOOKUP) *get_cert_methods;
+ X509_VERIFY_PARAM *param;
+ /* Callbacks for various operations */
+ /* called to verify a certificate */
+ int (*verify) (X509_STORE_CTX *ctx);
+ /* error callback */
+ int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+ /* get issuers cert from ctx */
+ int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+ /* check issued */
+ int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+ /* Check revocation status of chain */
+ int (*check_revocation) (X509_STORE_CTX *ctx);
+ /* retrieve CRL */
+ int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+ /* Check CRL validity */
+ int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+ /* Check certificate against CRL */
+ int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+ /* Check policy status of the chain */
+ int (*check_policy) (X509_STORE_CTX *ctx);
+ STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ int (*cleanup) (X509_STORE_CTX *ctx);
+ CRYPTO_EX_DATA ex_data;
+ CRYPTO_REF_COUNT references;
+ CRYPTO_RWLOCK *lock;
+};
+
+typedef struct lookup_dir_hashes_st BY_DIR_HASH;
+typedef struct lookup_dir_entry_st BY_DIR_ENTRY;
+DEFINE_STACK_OF(BY_DIR_HASH)
+DEFINE_STACK_OF(BY_DIR_ENTRY)
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+
+void x509_set_signature_info(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
+ const ASN1_STRING *sig);
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index b7424809fdbb..be39015b0d01 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -1,81 +1,31 @@
-/* crypto/x509/x509_lu.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
#include <openssl/x509.h>
+#include "internal/x509_int.h"
#include <openssl/x509v3.h>
+#include "x509_lcl.h"
X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
{
- X509_LOOKUP *ret;
+ X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret));
- ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
- if (ret == NULL)
+ if (ret == NULL) {
+ X509err(X509_F_X509_LOOKUP_NEW, ERR_R_MALLOC_FAILURE);
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)) {
+ if (method->new_item != NULL && method->new_item(ret) == 0) {
OPENSSL_free(ret);
return NULL;
}
@@ -91,6 +41,16 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx)
OPENSSL_free(ctx);
}
+int X509_STORE_lock(X509_STORE *s)
+{
+ return CRYPTO_THREAD_write_lock(s->lock);
+}
+
+int X509_STORE_unlock(X509_STORE *s)
+{
+ return CRYPTO_THREAD_unlock(s->lock);
+}
+
int X509_LOOKUP_init(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
@@ -122,41 +82,59 @@ int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
return 1;
}
-int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
- X509_OBJECT *ret)
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ X509_NAME *name, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
- return X509_LU_FAIL;
+ return 0;
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)
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE 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 0;
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,
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const unsigned char *bytes, int len,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
- return X509_LU_FAIL;
+ return 0;
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)
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const char *str, int len, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
- return X509_LU_FAIL;
+ return 0;
return ctx->method->get_by_alias(ctx, type, str, len, ret);
}
+int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data)
+{
+ ctx->method_data = data;
+ return 1;
+}
+
+void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx)
+{
+ return ctx->method_data;
+}
+
+X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx)
+{
+ return ctx->store_ctx;
+}
+
+
static int x509_object_cmp(const X509_OBJECT *const *a,
const X509_OBJECT *const *b)
{
@@ -172,7 +150,7 @@ static int x509_object_cmp(const X509_OBJECT *const *a,
case X509_LU_CRL:
ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
break;
- default:
+ case X509_LU_NONE:
/* abort(); */
return 0;
}
@@ -181,63 +159,48 @@ static int x509_object_cmp(const X509_OBJECT *const *a,
X509_STORE *X509_STORE_new(void)
{
- X509_STORE *ret;
+ X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
- if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
+ if (ret == NULL) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
- if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
- goto err0;
+ }
+ if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
ret->cache = 1;
- if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
- goto err1;
- ret->verify = 0;
- ret->verify_cb = 0;
-
- if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
- goto err2;
-
- ret->get_issuer = 0;
- ret->check_issued = 0;
- ret->check_revocation = 0;
- ret->get_crl = 0;
- ret->check_crl = 0;
- ret->cert_crl = 0;
- ret->lookup_certs = 0;
- ret->lookup_crls = 0;
- ret->cleanup = 0;
-
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
- goto err3;
+ if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
ret->references = 1;
return ret;
- err3:
+err:
X509_VERIFY_PARAM_free(ret->param);
- err2:
- sk_X509_LOOKUP_free(ret->get_cert_methods);
- err1:
sk_X509_OBJECT_free(ret->objs);
- err0:
+ sk_X509_LOOKUP_free(ret->get_cert_methods);
OPENSSL_free(ret);
return NULL;
}
-static void cleanup(X509_OBJECT *a)
-{
- if (!a)
- return;
- if (a->type == X509_LU_X509) {
- X509_free(a->data.x509);
- } else if (a->type == X509_LU_CRL) {
- X509_CRL_free(a->data.crl);
- } else {
- /* abort(); */
- }
-
- OPENSSL_free(a);
-}
-
void X509_STORE_free(X509_STORE *vfy)
{
int i;
@@ -246,19 +209,11 @@ void X509_STORE_free(X509_STORE *vfy)
if (vfy == NULL)
return;
-
- i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
-#ifdef REF_PRINT
- REF_PRINT("X509_STORE", vfy);
-#endif
+ CRYPTO_DOWN_REF(&vfy->references, &i, vfy->lock);
+ REF_PRINT_COUNT("X509_STORE", vfy);
if (i > 0)
return;
-#ifdef REF_CHECK
- if (i < 0) {
- fprintf(stderr, "X509_STORE_free, bad reference count\n");
- abort(); /* ok */
- }
-#endif
+ REF_ASSERT_ISNT(i < 0);
sk = vfy->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
@@ -267,14 +222,26 @@ void X509_STORE_free(X509_STORE *vfy)
X509_LOOKUP_free(lu);
}
sk_X509_LOOKUP_free(sk);
- sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+ sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
- if (vfy->param)
- X509_VERIFY_PARAM_free(vfy->param);
+ X509_VERIFY_PARAM_free(vfy->param);
+ CRYPTO_THREAD_lock_free(vfy->lock);
OPENSSL_free(vfy);
}
+int X509_STORE_up_ref(X509_STORE *vfy)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&vfy->references, &i, vfy->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("X509_STORE", a);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
{
int i;
@@ -290,52 +257,63 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
}
/* a new one */
lu = X509_LOOKUP_new(m);
- if (lu == NULL)
+ if (lu == NULL) {
+ X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ lu->store_ctx = v;
+ if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
+ return lu;
+ /* malloc failed */
+ X509err(X509_F_X509_STORE_ADD_LOOKUP, ERR_R_MALLOC_FAILURE);
+ X509_LOOKUP_free(lu);
+ return NULL;
+}
+
+X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
+ X509_LOOKUP_TYPE type,
+ X509_NAME *name)
+{
+ X509_OBJECT *ret = X509_OBJECT_new();
+
+ if (ret == NULL)
+ return NULL;
+ if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
+ X509_OBJECT_free(ret);
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;
- }
}
+ return ret;
}
-int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
- X509_OBJECT *ret)
+int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
+ X509_NAME *name, X509_OBJECT *ret)
{
X509_STORE *ctx = vs->ctx;
X509_LOOKUP *lu;
X509_OBJECT stmp, *tmp;
int i, j;
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ if (ctx == NULL)
+ return 0;
+
+ CRYPTO_THREAD_write_lock(ctx->lock);
tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
if (tmp == NULL || type == X509_LU_CRL) {
- for (i = vs->current_method;
- i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+ for (i = 0; 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) {
+ 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;
@@ -344,94 +322,111 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
return 1;
}
-int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
-{
+static int x509_store_add(X509_STORE *ctx, void *x, int crl) {
X509_OBJECT *obj;
- int ret = 1;
+ int ret = 0, added = 0;
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);
+ obj = X509_OBJECT_new();
+ if (obj == NULL)
return 0;
- }
- obj->type = X509_LU_X509;
- obj->data.x509 = x;
-
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ if (crl) {
+ obj->type = X509_LU_CRL;
+ obj->data.crl = (X509_CRL *)x;
+ } else {
+ obj->type = X509_LU_X509;
+ obj->data.x509 = (X509 *)x;
+ }
X509_OBJECT_up_ref_count(obj);
+ CRYPTO_THREAD_write_lock(ctx->lock);
+
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 if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
- X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
- ret = 0;
+ ret = 1;
+ } else {
+ added = sk_X509_OBJECT_push(ctx->objs, obj);
+ ret = added != 0;
}
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->lock);
+
+ if (added == 0) /* obj not pushed */
+ X509_OBJECT_free(obj);
return ret;
}
-int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
+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_CRL, ERR_R_MALLOC_FAILURE);
+ if (!x509_store_add(ctx, x, 0)) {
+ X509err(X509_F_X509_STORE_ADD_CERT, 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);
+ return 1;
+}
- 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 if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
+{
+ if (!x509_store_add(ctx, x, 1)) {
X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
- ret = 0;
+ return 0;
}
-
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
-
- return ret;
+ return 1;
}
-void X509_OBJECT_up_ref_count(X509_OBJECT *a)
+int 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);
+ case X509_LU_NONE:
break;
+ case X509_LU_X509:
+ return X509_up_ref(a->data.x509);
case X509_LU_CRL:
- CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
- break;
+ return X509_CRL_up_ref(a->data.crl);
}
+ return 1;
+}
+
+X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
+{
+ if (a == NULL || a->type != X509_LU_X509)
+ return NULL;
+ return a->data.x509;
}
-void X509_OBJECT_free_contents(X509_OBJECT *a)
+X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a)
{
+ if (a == NULL || a->type != X509_LU_CRL)
+ return NULL;
+ return a->data.crl;
+}
+
+X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a)
+{
+ return a->type;
+}
+
+X509_OBJECT *X509_OBJECT_new(void)
+{
+ X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->type = X509_LU_NONE;
+ return ret;
+}
+
+static void x509_object_free_internal(X509_OBJECT *a)
+{
+ if (a == NULL)
+ return;
switch (a->type) {
+ case X509_LU_NONE:
+ break;
case X509_LU_X509:
X509_free(a->data.x509);
break;
@@ -441,29 +436,53 @@ void X509_OBJECT_free_contents(X509_OBJECT *a)
}
}
-static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
+int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj)
+{
+ if (a == NULL || !X509_up_ref(obj))
+ return 0;
+
+ x509_object_free_internal(a);
+ a->type = X509_LU_X509;
+ a->data.x509 = obj;
+ return 1;
+}
+
+int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj)
+{
+ if (a == NULL || !X509_CRL_up_ref(obj))
+ return 0;
+
+ x509_object_free_internal(a);
+ a->type = X509_LU_CRL;
+ a->data.crl = obj;
+ return 1;
+}
+
+void X509_OBJECT_free(X509_OBJECT *a)
+{
+ x509_object_free_internal(a);
+ OPENSSL_free(a);
+}
+
+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
X509_NAME *name, int *pnmatch)
{
X509_OBJECT stmp;
X509 x509_s;
- X509_CINF cinf_s;
X509_CRL crl_s;
- X509_CRL_INFO crl_info_s;
int idx;
stmp.type = type;
switch (type) {
case X509_LU_X509:
stmp.data.x509 = &x509_s;
- x509_s.cert_info = &cinf_s;
- cinf_s.subject = name;
+ x509_s.cert_info.subject = name;
break;
case X509_LU_CRL:
stmp.data.crl = &crl_s;
- crl_s.crl = &crl_info_s;
- crl_info_s.issuer = name;
+ crl_s.crl.issuer = name;
break;
- default:
+ case X509_LU_NONE:
/* abort(); */
return -1;
}
@@ -484,14 +503,15 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
return idx;
}
-int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
X509_NAME *name)
{
return x509_object_idx_cnt(h, type, name, NULL);
}
X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
- int type, X509_NAME *name)
+ X509_LOOKUP_TYPE type,
+ X509_NAME *name)
{
int idx;
idx = X509_OBJECT_idx_by_subject(h, type, name);
@@ -500,73 +520,83 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
return sk_X509_OBJECT_value(h, idx);
}
-STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v)
+{
+ return v->objs;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
{
int i, idx, cnt;
- STACK_OF(X509) *sk;
+ STACK_OF(X509) *sk = NULL;
X509 *x;
X509_OBJECT *obj;
- sk = sk_X509_new_null();
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+
+ if (ctx->ctx == NULL)
+ return NULL;
+
+ CRYPTO_THREAD_write_lock(ctx->ctx->lock);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0) {
/*
* Nothing found in cache: do lookup to possibly add new objects to
* cache
*/
- X509_OBJECT xobj;
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
- if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
- sk_X509_free(sk);
+ X509_OBJECT *xobj = X509_OBJECT_new();
+
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
+ if (xobj == NULL)
+ return NULL;
+ if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
+ X509_OBJECT_free(xobj);
return NULL;
}
- X509_OBJECT_free_contents(&xobj);
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ X509_OBJECT_free(xobj);
+ CRYPTO_THREAD_write_lock(ctx->ctx->lock);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
- sk_X509_free(sk);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
return NULL;
}
}
+
+ sk = sk_X509_new_null();
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.x509;
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(x);
if (!sk_X509_push(sk, x)) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
X509_free(x);
sk_X509_pop_free(sk, X509_free);
return NULL;
}
}
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
return sk;
-
}
-STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
{
int i, idx, cnt;
- STACK_OF(X509_CRL) *sk;
+ STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
X509_CRL *x;
- X509_OBJECT *obj, xobj;
- sk = sk_X509_CRL_new_null();
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
-
- /*
- * Always do lookup to possibly add new CRLs to cache
- */
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
- if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
+ X509_OBJECT *obj, *xobj = X509_OBJECT_new();
+
+ /* Always do lookup to possibly add new CRLs to cache */
+ if (sk == NULL
+ || xobj == NULL
+ || ctx->ctx == NULL
+ || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
+ X509_OBJECT_free(xobj);
sk_X509_CRL_free(sk);
return NULL;
}
- X509_OBJECT_free_contents(&xobj);
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ X509_OBJECT_free(xobj);
+ CRYPTO_THREAD_write_lock(ctx->ctx->lock);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
if (idx < 0) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
sk_X509_CRL_free(sk);
return NULL;
}
@@ -574,32 +604,33 @@ STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
for (i = 0; i < cnt; i++, idx++) {
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.crl;
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
+ X509_CRL_up_ref(x);
if (!sk_X509_CRL_push(sk, x)) {
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
X509_CRL_free(x);
sk_X509_CRL_pop_free(sk, X509_CRL_free);
return NULL;
}
}
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
return sk;
}
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
X509_OBJECT *x)
{
- int idx, i;
+ int idx, i, num;
X509_OBJECT *obj;
+
idx = sk_X509_OBJECT_find(h, x);
- if (idx == -1)
+ if (idx < 0)
return NULL;
if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
return sk_X509_OBJECT_value(h, idx);
- for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
+ for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) {
obj = sk_X509_OBJECT_value(h, i);
- if (x509_object_cmp
- ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
+ if (x509_object_cmp((const X509_OBJECT **)&obj,
+ (const X509_OBJECT **)&x))
return NULL;
if (x->type == X509_LU_X509) {
if (!X509_cmp(obj->data.x509, x->data.x509))
@@ -628,32 +659,35 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
X509_NAME *xn;
- X509_OBJECT obj, *pobj;
+ X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
int i, ok, idx, ret;
+
+ if (obj == NULL)
+ return -1;
+ *issuer = NULL;
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;
- }
+ ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
+ if (ok != 1) {
+ X509_OBJECT_free(obj);
return 0;
}
/* If certificate matches all OK */
- if (ctx->check_issued(ctx, x, obj.data.x509)) {
- *issuer = obj.data.x509;
- return 1;
+ if (ctx->check_issued(ctx, x, obj->data.x509)) {
+ if (x509_check_cert_time(ctx, obj->data.x509, -1)) {
+ *issuer = obj->data.x509;
+ X509_up_ref(*issuer);
+ X509_OBJECT_free(obj);
+ return 1;
+ }
}
- X509_OBJECT_free_contents(&obj);
+ X509_OBJECT_free(obj);
+
+ if (ctx->ctx == NULL)
+ return 0;
/* Else find index of first cert accepted by 'check_issued' */
ret = 0;
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_write_lock(ctx->ctx->lock);
idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
if (idx != -1) { /* should be true as we've had at least one
* match */
@@ -667,13 +701,22 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
break;
if (ctx->check_issued(ctx, x, pobj->data.x509)) {
*issuer = pobj->data.x509;
- X509_OBJECT_up_ref_count(pobj);
ret = 1;
- break;
+ /*
+ * If times check, exit with match,
+ * otherwise keep looking. Leave last
+ * match in issuer so we return nearest
+ * match if no certificate time is OK.
+ */
+
+ if (x509_check_cert_time(ctx, *issuer, -1))
+ break;
}
}
}
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+ CRYPTO_THREAD_unlock(ctx->ctx->lock);
+ if (*issuer)
+ X509_up_ref(*issuer);
return ret;
}
@@ -703,25 +746,153 @@ int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
return X509_VERIFY_PARAM_set1(ctx->param, param);
}
+X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
+{
+ return ctx->param;
+}
+
+void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
+{
+ ctx->verify = verify;
+}
+
+X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx)
+{
+ return ctx->verify;
+}
+
void X509_STORE_set_verify_cb(X509_STORE *ctx,
- int (*verify_cb) (int, X509_STORE_CTX *))
+ X509_STORE_CTX_verify_cb verify_cb)
{
ctx->verify_cb = verify_cb;
}
-void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
- STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
- *ctx,
- X509_NAME *nm))
+X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx)
{
- ctx->lookup_crls = cb;
+ return ctx->verify_cb;
}
-X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
+void X509_STORE_set_get_issuer(X509_STORE *ctx,
+ X509_STORE_CTX_get_issuer_fn get_issuer)
{
- return ctx->ctx;
+ ctx->get_issuer = get_issuer;
}
-IMPLEMENT_STACK_OF(X509_LOOKUP)
+X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx)
+{
+ return ctx->get_issuer;
+}
+
+void X509_STORE_set_check_issued(X509_STORE *ctx,
+ X509_STORE_CTX_check_issued_fn check_issued)
+{
+ ctx->check_issued = check_issued;
+}
-IMPLEMENT_STACK_OF(X509_OBJECT)
+X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx)
+{
+ return ctx->check_issued;
+}
+
+void X509_STORE_set_check_revocation(X509_STORE *ctx,
+ X509_STORE_CTX_check_revocation_fn check_revocation)
+{
+ ctx->check_revocation = check_revocation;
+}
+
+X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx)
+{
+ return ctx->check_revocation;
+}
+
+void X509_STORE_set_get_crl(X509_STORE *ctx,
+ X509_STORE_CTX_get_crl_fn get_crl)
+{
+ ctx->get_crl = get_crl;
+}
+
+X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx)
+{
+ return ctx->get_crl;
+}
+
+void X509_STORE_set_check_crl(X509_STORE *ctx,
+ X509_STORE_CTX_check_crl_fn check_crl)
+{
+ ctx->check_crl = check_crl;
+}
+
+X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx)
+{
+ return ctx->check_crl;
+}
+
+void X509_STORE_set_cert_crl(X509_STORE *ctx,
+ X509_STORE_CTX_cert_crl_fn cert_crl)
+{
+ ctx->cert_crl = cert_crl;
+}
+
+X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx)
+{
+ return ctx->cert_crl;
+}
+
+void X509_STORE_set_check_policy(X509_STORE *ctx,
+ X509_STORE_CTX_check_policy_fn check_policy)
+{
+ ctx->check_policy = check_policy;
+}
+
+X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx)
+{
+ return ctx->check_policy;
+}
+
+void X509_STORE_set_lookup_certs(X509_STORE *ctx,
+ X509_STORE_CTX_lookup_certs_fn lookup_certs)
+{
+ ctx->lookup_certs = lookup_certs;
+}
+
+X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx)
+{
+ return ctx->lookup_certs;
+}
+
+void X509_STORE_set_lookup_crls(X509_STORE *ctx,
+ X509_STORE_CTX_lookup_crls_fn lookup_crls)
+{
+ ctx->lookup_crls = lookup_crls;
+}
+
+X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx)
+{
+ return ctx->lookup_crls;
+}
+
+void X509_STORE_set_cleanup(X509_STORE *ctx,
+ X509_STORE_CTX_cleanup_fn ctx_cleanup)
+{
+ ctx->cleanup = ctx_cleanup;
+}
+
+X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx)
+{
+ return ctx->cleanup;
+}
+
+int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data)
+{
+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
+
+void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx)
+{
+ return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
+{
+ return ctx->ctx;
+}
diff --git a/crypto/x509/x509_meth.c b/crypto/x509/x509_meth.c
new file mode 100644
index 000000000000..9dc587a09212
--- /dev/null
+++ b/crypto/x509/x509_meth.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/ossl_typ.h>
+#include "x509_lcl.h"
+
+X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name)
+{
+ X509_LOOKUP_METHOD *method = OPENSSL_zalloc(sizeof(X509_LOOKUP_METHOD));
+
+ if (method != NULL) {
+ method->name = OPENSSL_strdup(name);
+ if (method->name == NULL) {
+ X509err(X509_F_X509_LOOKUP_METH_NEW, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ return method;
+
+err:
+ OPENSSL_free(method);
+ return NULL;
+}
+
+void X509_LOOKUP_meth_free(X509_LOOKUP_METHOD *method)
+{
+ if (method != NULL)
+ OPENSSL_free(method->name);
+ OPENSSL_free(method);
+}
+
+int X509_LOOKUP_meth_set_new_item(X509_LOOKUP_METHOD *method,
+ int (*new_item) (X509_LOOKUP *ctx))
+{
+ method->new_item = new_item;
+ return 1;
+}
+
+int (*X509_LOOKUP_meth_get_new_item(const X509_LOOKUP_METHOD* method))
+ (X509_LOOKUP *ctx)
+{
+ return method->new_item;
+}
+
+int X509_LOOKUP_meth_set_free(
+ X509_LOOKUP_METHOD *method,
+ void (*free_fn) (X509_LOOKUP *ctx))
+{
+ method->free = free_fn;
+ return 1;
+}
+
+void (*X509_LOOKUP_meth_get_free(const X509_LOOKUP_METHOD* method))
+ (X509_LOOKUP *ctx)
+{
+ return method->free;
+}
+
+int X509_LOOKUP_meth_set_init(X509_LOOKUP_METHOD *method,
+ int (*init) (X509_LOOKUP *ctx))
+{
+ method->init = init;
+ return 1;
+}
+
+int (*X509_LOOKUP_meth_get_init(const X509_LOOKUP_METHOD* method))
+ (X509_LOOKUP *ctx)
+{
+ return method->init;
+}
+
+int X509_LOOKUP_meth_set_shutdown(
+ X509_LOOKUP_METHOD *method,
+ int (*shutdown) (X509_LOOKUP *ctx))
+{
+ method->shutdown = shutdown;
+ return 1;
+}
+
+int (*X509_LOOKUP_meth_get_shutdown(const X509_LOOKUP_METHOD* method))
+ (X509_LOOKUP *ctx)
+{
+ return method->shutdown;
+}
+
+int X509_LOOKUP_meth_set_ctrl(
+ X509_LOOKUP_METHOD *method,
+ X509_LOOKUP_ctrl_fn ctrl)
+{
+ method->ctrl = ctrl;
+ return 1;
+}
+
+X509_LOOKUP_ctrl_fn X509_LOOKUP_meth_get_ctrl(const X509_LOOKUP_METHOD *method)
+{
+ return method->ctrl;
+}
+
+int X509_LOOKUP_meth_set_get_by_subject(X509_LOOKUP_METHOD *method,
+ X509_LOOKUP_get_by_subject_fn get_by_subject)
+{
+ method->get_by_subject = get_by_subject;
+ return 1;
+}
+
+X509_LOOKUP_get_by_subject_fn X509_LOOKUP_meth_get_get_by_subject(
+ const X509_LOOKUP_METHOD *method)
+{
+ return method->get_by_subject;
+}
+
+
+int X509_LOOKUP_meth_set_get_by_issuer_serial(X509_LOOKUP_METHOD *method,
+ X509_LOOKUP_get_by_issuer_serial_fn get_by_issuer_serial)
+{
+ method->get_by_issuer_serial = get_by_issuer_serial;
+ return 1;
+}
+
+X509_LOOKUP_get_by_issuer_serial_fn
+ X509_LOOKUP_meth_get_get_by_issuer_serial(const X509_LOOKUP_METHOD *method)
+{
+ return method->get_by_issuer_serial;
+}
+
+
+int X509_LOOKUP_meth_set_get_by_fingerprint(X509_LOOKUP_METHOD *method,
+ X509_LOOKUP_get_by_fingerprint_fn get_by_fingerprint)
+{
+ method->get_by_fingerprint = get_by_fingerprint;
+ return 1;
+}
+
+X509_LOOKUP_get_by_fingerprint_fn X509_LOOKUP_meth_get_get_by_fingerprint(
+ const X509_LOOKUP_METHOD *method)
+{
+ return method->get_by_fingerprint;
+}
+
+int X509_LOOKUP_meth_set_get_by_alias(X509_LOOKUP_METHOD *method,
+ X509_LOOKUP_get_by_alias_fn get_by_alias)
+{
+ method->get_by_alias = get_by_alias;
+ return 1;
+}
+
+X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias(
+ const X509_LOOKUP_METHOD *method)
+{
+ return method->get_by_alias;
+}
+
diff --git a/crypto/x509/x509_obj.c b/crypto/x509/x509_obj.c
index 0a839f3e54ce..85c39415c11e 100644
--- a/crypto/x509/x509_obj.c
+++ b/crypto/x509/x509_obj.c
@@ -1,78 +1,29 @@
-/* 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.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
+#include "internal/cryptlib.h"
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/buffer.h>
+#include "internal/x509_int.h"
/*
* Limit to ensure we don't overflow: much greater than
- * anything enountered in practice.
+ * anything encountered in practice.
*/
#define NAME_ONELINE_MAX (1024 * 1024)
-char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
+char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
{
- X509_NAME_ENTRY *ne;
+ const X509_NAME_ENTRY *ne;
int i;
int n, lold, l, l1, l2, num, j, type;
const char *s;
@@ -83,7 +34,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
int gs_doit[4];
char tmp_buf[80];
#ifdef CHARSET_EBCDIC
- char ebcdic_buf[1024];
+ unsigned char ebcdic_buf[1024];
#endif
if (buf == NULL) {
@@ -221,10 +172,10 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
p = buf;
if (i == 0)
*p = '\0';
- return (p);
+ return p;
err:
X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
end:
BUF_MEM_free(b);
- return (NULL);
+ return NULL;
}
diff --git a/crypto/x509/x509_r2x.c b/crypto/x509/x509_r2x.c
index 2879569ead41..3d72787d3164 100644
--- a/crypto/x509/x509_r2x.c
+++ b/crypto/x509/x509_r2x.c
@@ -1,67 +1,19 @@
-/* crypto/x509/x509_r2x.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
#include <openssl/objects.h>
#include <openssl/buffer.h>
@@ -71,7 +23,6 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
X509_CINF *xi = NULL;
X509_NAME *xn;
EVP_PKEY *pubkey = NULL;
- int res;
if ((ret = X509_new()) == NULL) {
X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
@@ -79,10 +30,10 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
}
/* duplicate the request */
- xi = ret->cert_info;
+ xi = &ret->cert_info;
- if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
- if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
+ if (sk_X509_ATTRIBUTE_num(r->req_info.attributes) != 0) {
+ if ((xi->version = ASN1_INTEGER_new()) == NULL)
goto err;
if (!ASN1_INTEGER_set(xi->version, 2))
goto err;
@@ -96,22 +47,21 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
if (X509_set_issuer_name(ret, xn) == 0)
goto err;
- if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
+ if (X509_gmtime_adj(xi->validity.notBefore, 0) == NULL)
goto err;
- if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
+ if (X509_gmtime_adj(xi->validity.notAfter, (long)60 * 60 * 24 * days) ==
NULL)
goto err;
- pubkey = X509_REQ_get_pubkey(r);
- res = X509_set_pubkey(ret, pubkey);
- EVP_PKEY_free(pubkey);
+ pubkey = X509_REQ_get0_pubkey(r);
+ if (pubkey == NULL || !X509_set_pubkey(ret, pubkey))
+ goto err;
- if (!res || !X509_sign(ret, pkey, EVP_md5()))
+ if (!X509_sign(ret, pkey, EVP_md5()))
goto err;
- if (0) {
+ return ret;
+
err:
- X509_free(ret);
- ret = NULL;
- }
- return (ret);
+ X509_free(ret);
+ return NULL;
}
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c
index 01795f4b3f37..0bdbb81db894 100644
--- a/crypto/x509/x509_req.c
+++ b/crypto/x509/x509_req.c
@@ -1,68 +1,20 @@
-/* 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.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/pem.h>
@@ -80,10 +32,10 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
goto err;
}
- ri = ret->req_info;
+ ri = &ret->req_info;
ri->version->length = 1;
- ri->version->data = (unsigned char *)OPENSSL_malloc(1);
+ ri->version->data = OPENSSL_malloc(1);
if (ri->version->data == NULL)
goto err;
ri->version->data[0] = 0; /* version == 0 */
@@ -91,11 +43,10 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
goto err;
- pktmp = X509_get_pubkey(x);
+ pktmp = X509_get0_pubkey(x);
if (pktmp == NULL)
goto err;
i = X509_REQ_set_pubkey(ret, pktmp);
- EVP_PKEY_free(pktmp);
if (!i)
goto err;
@@ -103,17 +54,29 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
if (!X509_REQ_sign(ret, pkey, md))
goto err;
}
- return (ret);
+ return ret;
err:
X509_REQ_free(ret);
- return (NULL);
+ 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));
+ if (req == NULL)
+ return NULL;
+ return X509_PUBKEY_get(req->req_info.pubkey);
+}
+
+EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req)
+{
+ if (req == NULL)
+ return NULL;
+ return X509_PUBKEY_get0(req->req_info.pubkey);
+}
+
+X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req)
+{
+ return req->req_info.pubkey;
}
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
@@ -135,13 +98,13 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
break;
case -2:
#ifndef OPENSSL_NO_EC
- if (k->type == EVP_PKEY_EC) {
+ if (EVP_PKEY_id(k) == 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) {
+ if (EVP_PKEY_id(k) == EVP_PKEY_DH) {
/* No idea */
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
X509_R_CANT_CHECK_DH_KEY);
@@ -152,7 +115,7 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
}
EVP_PKEY_free(xk);
- return (ok);
+ return ok;
}
/*
@@ -194,17 +157,14 @@ STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
int idx, *pnid;
const unsigned char *p;
- if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
- return (NULL);
+ if ((req == 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);
+ ext = X509_ATTRIBUTE_get0_type(attr, 0);
break;
}
if (!ext || (ext->type != V_ASN1_SEQUENCE))
@@ -223,37 +183,17 @@ 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)
{
- 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;
+ int extlen;
+ int rv = 0;
+ unsigned char *ext = NULL;
/* Generate encoding of extensions */
- at->value.sequence->length =
- ASN1_item_i2d((ASN1_VALUE *)exts,
- &at->value.sequence->data,
- ASN1_ITEM_rptr(X509_EXTENSIONS));
- if (!(attr = X509_ATTRIBUTE_new()))
- goto err;
- if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
- goto err;
- if (!sk_ASN1_TYPE_push(attr->value.set, at))
- goto err;
- at = NULL;
- attr->single = 0;
- attr->object = OBJ_nid2obj(nid);
- if (!req->req_info->attributes) {
- if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
- goto err;
- }
- if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
- goto err;
- return 1;
- err:
- X509_ATTRIBUTE_free(attr);
- ASN1_TYPE_free(at);
- return 0;
+ extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext,
+ ASN1_ITEM_rptr(X509_EXTENSIONS));
+ if (extlen <= 0)
+ return 0;
+ rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen);
+ OPENSSL_free(ext);
+ return rv;
}
/* This is the normal usage: use the "official" OID */
@@ -266,33 +206,33 @@ int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
int X509_REQ_get_attr_count(const X509_REQ *req)
{
- return X509at_get_attr_count(req->req_info->attributes);
+ 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);
+ 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 X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
int lastpos)
{
- return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, 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);
+ 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);
+ 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))
+ if (X509at_add1_attr(&req->req_info.attributes, attr))
return 1;
return 0;
}
@@ -301,7 +241,7 @@ 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,
+ if (X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj,
type, bytes, len))
return 1;
return 0;
@@ -311,7 +251,7 @@ 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,
+ if (X509at_add1_attr_by_NID(&req->req_info.attributes, nid,
type, bytes, len))
return 1;
return 0;
@@ -321,8 +261,38 @@ 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,
+ if (X509at_add1_attr_by_txt(&req->req_info.attributes, attrname,
type, bytes, len))
return 1;
return 0;
}
+
+long X509_REQ_get_version(const X509_REQ *req)
+{
+ return ASN1_INTEGER_get(req->req_info.version);
+}
+
+X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req)
+{
+ return req->req_info.subject;
+}
+
+void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
+ const X509_ALGOR **palg)
+{
+ if (psig != NULL)
+ *psig = req->signature;
+ if (palg != NULL)
+ *palg = &req->sig_alg;
+}
+
+int X509_REQ_get_signature_nid(const X509_REQ *req)
+{
+ return OBJ_obj2nid(req->sig_alg.algorithm);
+}
+
+int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
+{
+ req->req_info.enc.modified = 1;
+ return i2d_X509_REQ_INFO(&req->req_info, pp);
+}
diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c
index 5b802bd6c754..3ab6bf35115f 100644
--- a/crypto/x509/x509_set.c
+++ b/crypto/x509/x509_set.c
@@ -1,82 +1,38 @@
-/* crypto/x509/x509_set.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+#include "internal/x509_int.h"
+#include "x509_lcl.h"
int X509_set_version(X509 *x, long version)
{
if (x == NULL)
- return (0);
+ return 0;
if (version == 0) {
- M_ASN1_INTEGER_free(x->cert_info->version);
- x->cert_info->version = NULL;
- return (1);
+ ASN1_INTEGER_free(x->cert_info.version);
+ x->cert_info.version = NULL;
+ return 1;
}
- if (x->cert_info->version == NULL) {
- if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
- return (0);
+ if (x->cert_info.version == NULL) {
+ if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL)
+ return 0;
}
- return (ASN1_INTEGER_set(x->cert_info->version, version));
+ return ASN1_INTEGER_set(x->cert_info.version, version);
}
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
@@ -84,69 +40,198 @@ 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);
+ return 0;
+ in = &x->cert_info.serialNumber;
+ if (in != serial)
+ return ASN1_STRING_copy(in, serial);
+ return 1;
}
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));
+ if (x == 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));
+ if (x == NULL)
+ return 0;
+ return X509_NAME_set(&x->cert_info.subject, name);
}
-int X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
+int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm)
{
ASN1_TIME *in;
-
- if ((x == NULL) || (x->cert_info->validity == NULL))
- return (0);
- in = x->cert_info->validity->notBefore;
+ in = *ptm;
if (in != tm) {
- in = M_ASN1_TIME_dup(tm);
+ in = ASN1_STRING_dup(tm);
if (in != NULL) {
- M_ASN1_TIME_free(x->cert_info->validity->notBefore);
- x->cert_info->validity->notBefore = in;
+ ASN1_TIME_free(*ptm);
+ *ptm = in;
}
}
return (in != NULL);
}
-int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
+int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
{
- ASN1_TIME *in;
+ if (x == NULL)
+ return 0;
+ return x509_set1_time(&x->cert_info.validity.notBefore, tm);
+}
- 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_set1_notAfter(X509 *x, const ASN1_TIME *tm)
+{
+ if (x == NULL)
+ return 0;
+ return x509_set1_time(&x->cert_info.validity.notAfter, tm);
}
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));
+ if (x == NULL)
+ return 0;
+ return X509_PUBKEY_set(&(x->cert_info.key), pkey);
+}
+
+int X509_up_ref(X509 *x)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&x->references, &i, x->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("X509", x);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+long X509_get_version(const X509 *x)
+{
+ return ASN1_INTEGER_get(x->cert_info.version);
+}
+
+const ASN1_TIME *X509_get0_notBefore(const X509 *x)
+{
+ return x->cert_info.validity.notBefore;
+}
+
+const ASN1_TIME *X509_get0_notAfter(const X509 *x)
+{
+ return x->cert_info.validity.notAfter;
+}
+
+ASN1_TIME *X509_getm_notBefore(const X509 *x)
+{
+ return x->cert_info.validity.notBefore;
+}
+
+ASN1_TIME *X509_getm_notAfter(const X509 *x)
+{
+ return x->cert_info.validity.notAfter;
+}
+
+int X509_get_signature_type(const X509 *x)
+{
+ return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg.algorithm));
+}
+
+X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x)
+{
+ return x->cert_info.key;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x)
+{
+ return x->cert_info.extensions;
+}
+
+void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
+ const ASN1_BIT_STRING **psuid)
+{
+ if (piuid != NULL)
+ *piuid = x->cert_info.issuerUID;
+ if (psuid != NULL)
+ *psuid = x->cert_info.subjectUID;
+}
+
+const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
+{
+ return &x->cert_info.signature;
+}
+
+int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
+ int *secbits, uint32_t *flags)
+{
+ if (mdnid != NULL)
+ *mdnid = siginf->mdnid;
+ if (pknid != NULL)
+ *pknid = siginf->pknid;
+ if (secbits != NULL)
+ *secbits = siginf->secbits;
+ if (flags != NULL)
+ *flags = siginf->flags;
+ return (siginf->flags & X509_SIG_INFO_VALID) != 0;
+}
+
+void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
+ int secbits, uint32_t flags)
+{
+ siginf->mdnid = mdnid;
+ siginf->pknid = pknid;
+ siginf->secbits = secbits;
+ siginf->flags = flags;
+}
+
+int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
+ uint32_t *flags)
+{
+ X509_check_purpose(x, -1, -1);
+ return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
+}
+
+static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
+ const ASN1_STRING *sig)
+{
+ int pknid, mdnid;
+ const EVP_MD *md;
+
+ siginf->mdnid = NID_undef;
+ siginf->pknid = NID_undef;
+ siginf->secbits = -1;
+ siginf->flags = 0;
+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
+ || pknid == NID_undef)
+ return;
+ siginf->pknid = pknid;
+ if (mdnid == NID_undef) {
+ /* If we have one, use a custom handler for this algorithm */
+ const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid);
+ if (ameth == NULL || ameth->siginf_set == NULL
+ || ameth->siginf_set(siginf, alg, sig) == 0)
+ return;
+ siginf->flags |= X509_SIG_INFO_VALID;
+ return;
+ }
+ siginf->flags |= X509_SIG_INFO_VALID;
+ siginf->mdnid = mdnid;
+ md = EVP_get_digestbynid(mdnid);
+ if (md == NULL)
+ return;
+ /* Security bits: half number of bits in digest */
+ siginf->secbits = EVP_MD_size(md) * 4;
+ switch (mdnid) {
+ case NID_sha1:
+ case NID_sha256:
+ case NID_sha384:
+ case NID_sha512:
+ siginf->flags |= X509_SIG_INFO_TLS;
+ }
+}
+
+void x509_init_sig_info(X509 *x)
+{
+ x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
}
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index 11e0763403ae..d749af4d590a 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -1,65 +1,16 @@
-/* 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).
+ * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
*
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
static void trtable_free(X509_TRUST *p);
@@ -94,9 +45,7 @@ static X509_TRUST trstandard[] = {
{X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
};
-#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
-
-IMPLEMENT_STACK_OF(X509_TRUST)
+#define X509_TRUST_COUNT OSSL_NELEM(trstandard)
static STACK_OF(X509_TRUST) *trtable = NULL;
@@ -117,16 +66,11 @@ int X509_check_trust(X509 *x, int id, int flags)
{
X509_TRUST *pt;
int idx;
- if (id == -1)
- return 1;
+
/* We get this as a default value */
- if (id == 0) {
- int rv;
- rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
- if (rv != X509_TRUST_UNTRUSTED)
- return rv;
- return trust_compat(NULL, x, 0);
- }
+ if (id == X509_TRUST_DEFAULT)
+ return obj_trust(NID_anyExtendedKeyUsage, x,
+ flags | X509_TRUST_DO_SS_COMPAT);
idx = X509_TRUST_get_by_id(id);
if (idx == -1)
return default_trust(id, x, flags);
@@ -154,13 +98,14 @@ 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)
+ if (trtable == NULL)
return -1;
+ tmp.trust = id;
idx = sk_X509_TRUST_find(trtable, &tmp);
- if (idx == -1)
+ if (idx < 0)
return -1;
return idx + X509_TRUST_COUNT;
}
@@ -176,7 +121,7 @@ int X509_TRUST_set(int *t, int trust)
}
int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
- char *name, int arg1, void *arg2)
+ const char *name, int arg1, void *arg2)
{
int idx;
X509_TRUST *trtmp;
@@ -190,7 +135,7 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
idx = X509_TRUST_get_by_id(id);
/* Need a new entry */
if (idx == -1) {
- if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
+ if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -202,9 +147,9 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
OPENSSL_free(trtmp->name);
/* dup supplied name */
- if (!(trtmp->name = BUF_strdup(name))) {
+ if ((trtmp->name = OPENSSL_strdup(name)) == NULL) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
- return 0;
+ goto err;
}
/* Keep the dynamic flag of existing entry */
trtmp->flags &= X509_TRUST_DYNAMIC;
@@ -218,16 +163,23 @@ int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
/* If its a new entry manage the dynamic table */
if (idx == -1) {
- if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
+ if (trtable == NULL
+ && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
- return 0;
+ goto err;;
}
if (!sk_X509_TRUST_push(trtable, trtmp)) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
- return 0;
+ goto err;
}
}
return 1;
+ err:
+ if (idx == -1) {
+ OPENSSL_free(trtmp->name);
+ OPENSSL_free(trtmp);
+ }
+ return 0;
}
static void trtable_free(X509_TRUST *p)
@@ -243,50 +195,53 @@ static void trtable_free(X509_TRUST *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)
+int X509_TRUST_get_flags(const X509_TRUST *xp)
{
return xp->flags;
}
-char *X509_TRUST_get0_name(X509_TRUST *xp)
+char *X509_TRUST_get0_name(const X509_TRUST *xp)
{
return xp->name;
}
-int X509_TRUST_get_trust(X509_TRUST *xp)
+int X509_TRUST_get_trust(const 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
+ * Declare the chain verified if the desired trust OID is not rejected in
+ * any auxiliary trust info for this certificate, and the OID is either
+ * expressly trusted, or else either "anyEKU" is trusted, or the
+ * certificate is self-signed.
*/
- return trust_compat(trust, x, flags);
+ flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU;
+ return obj_trust(trust->arg1, 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;
+ /*
+ * Declare the chain verified only if the desired trust OID is not
+ * rejected and is expressly trusted. Neither "anyEKU" nor "compat"
+ * trust in self-signed certificates apply.
+ */
+ flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU);
+ return obj_trust(trust->arg1, x, flags);
}
static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
{
+ /* Call for side-effect of computing hash and caching extensions */
X509_check_purpose(x, -1, 0);
- if (x->ex_flags & EXFLAG_SS)
+ if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && x->ex_flags & EXFLAG_SS)
return X509_TRUST_TRUSTED;
else
return X509_TRUST_UNTRUSTED;
@@ -294,25 +249,51 @@ static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
static int obj_trust(int id, X509 *x, int flags)
{
- ASN1_OBJECT *obj;
+ X509_CERT_AUX *ax = x->aux;
int i;
- X509_CERT_AUX *ax;
- ax = x->aux;
- if (!ax)
- return X509_TRUST_UNTRUSTED;
- if (ax->reject) {
+
+ if (ax && 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)
+ ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i);
+ int nid = OBJ_obj2nid(obj);
+
+ if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+ (flags & X509_TRUST_OK_ANY_EKU)))
return X509_TRUST_REJECTED;
}
}
- if (ax->trust) {
+
+ if (ax && 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)
+ ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i);
+ int nid = OBJ_obj2nid(obj);
+
+ if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+ (flags & X509_TRUST_OK_ANY_EKU)))
return X509_TRUST_TRUSTED;
}
+ /*
+ * Reject when explicit trust EKU are set and none match.
+ *
+ * Returning untrusted is enough for for full chains that end in
+ * self-signed roots, because when explicit trust is specified it
+ * suppresses the default blanket trust of self-signed objects.
+ *
+ * But for partial chains, this is not enough, because absent a similar
+ * trust-self-signed policy, non matching EKUs are indistinguishable
+ * from lack of EKU constraints.
+ *
+ * Therefore, failure to match any trusted purpose must trigger an
+ * explicit reject.
+ */
+ return X509_TRUST_REJECTED;
}
- return X509_TRUST_UNTRUSTED;
+
+ if ((flags & X509_TRUST_DO_SS_COMPAT) == 0)
+ return X509_TRUST_UNTRUSTED;
+
+ /*
+ * Not rejected, and there is no list of accepted uses, try compat.
+ */
+ return trust_compat(NULL, x, flags);
}
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 594031e7722d..4755b39eb4eb 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -1,67 +1,17 @@
-/* crypto/x509/x509_txt.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
-#include "cryptlib.h"
-#include <openssl/lhash.h>
+#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
@@ -70,149 +20,163 @@
const char *X509_verify_cert_error_string(long n)
{
- static char buf[100];
-
switch ((int)n) {
case X509_V_OK:
- return ("ok");
+ return "ok";
+ case X509_V_ERR_UNSPECIFIED:
+ return "unspecified certificate verification error";
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- return ("unable to get issuer certificate");
+ return "unable to get issuer certificate";
case X509_V_ERR_UNABLE_TO_GET_CRL:
- return ("unable to get certificate CRL");
+ return "unable to get certificate CRL";
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- return ("unable to decrypt certificate's signature");
+ return "unable to decrypt certificate's signature";
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- return ("unable to decrypt CRL's 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");
+ return "unable to decode issuer public key";
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- return ("certificate signature failure");
+ return "certificate signature failure";
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
- return ("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");
+ return "certificate is not yet valid";
case X509_V_ERR_CERT_HAS_EXPIRED:
- return ("certificate has expired");
+ return "certificate has expired";
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ return "CRL is not yet valid";
case X509_V_ERR_CRL_HAS_EXPIRED:
- return ("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");
+ 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");
+ 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");
+ 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");
+ return "format error in CRL's nextUpdate field";
case X509_V_ERR_OUT_OF_MEM:
- return ("out of memory");
+ return "out of memory";
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- return ("self signed certificate");
+ return "self signed certificate";
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- return ("self signed certificate in certificate 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");
+ return "unable to get local issuer certificate";
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- return ("unable to verify the first certificate");
+ return "unable to verify the first certificate";
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- return ("certificate chain too long");
+ return "certificate chain too long";
case X509_V_ERR_CERT_REVOKED:
- return ("certificate 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)");
+ return "invalid CA certificate";
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");
+ return "path length constraint exceeded";
case X509_V_ERR_INVALID_PURPOSE:
- return ("unsupported certificate purpose");
+ return "unsupported certificate purpose";
case X509_V_ERR_CERT_UNTRUSTED:
- return ("certificate not trusted");
+ return "certificate not trusted";
case X509_V_ERR_CERT_REJECTED:
- return ("certificate rejected");
- case X509_V_ERR_APPLICATION_VERIFICATION:
- return ("application verification failure");
+ return "certificate rejected";
case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
- return ("subject issuer mismatch");
+ return "subject issuer mismatch";
case X509_V_ERR_AKID_SKID_MISMATCH:
- return ("authority and subject key identifier mismatch");
+ return "authority and subject key identifier mismatch";
case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
- return ("authority and issuer serial number mismatch");
+ return "authority and issuer serial number mismatch";
case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- return ("key usage does not include certificate signing");
+ return "key usage does not include certificate signing";
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
- return ("unable to get CRL issuer certificate");
+ return "unable to get CRL issuer certificate";
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
- return ("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");
+ return "key usage does not include CRL signing";
case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
- return ("unhandled critical CRL extension");
+ return "unhandled critical CRL extension";
+ case X509_V_ERR_INVALID_NON_CA:
+ return "invalid non-CA certificate (has CA markings)";
+ case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+ return "proxy path length constraint exceeded";
+ case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+ return "key usage does not include digital signature";
+ case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+ return
+ "proxy certificates not allowed, please set the appropriate flag";
case X509_V_ERR_INVALID_EXTENSION:
- return ("invalid or inconsistent certificate extension");
+ return "invalid or inconsistent certificate extension";
case X509_V_ERR_INVALID_POLICY_EXTENSION:
- return ("invalid or inconsistent certificate policy extension");
+ return "invalid or inconsistent certificate policy extension";
case X509_V_ERR_NO_EXPLICIT_POLICY:
- return ("no explicit policy");
+ return "no explicit policy";
case X509_V_ERR_DIFFERENT_CRL_SCOPE:
- return ("Different CRL scope");
+ return "Different CRL scope";
case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
- return ("Unsupported extension feature");
+ return "Unsupported extension feature";
case X509_V_ERR_UNNESTED_RESOURCE:
- return ("RFC 3779 resource not subset of parent's resources");
-
+ return "RFC 3779 resource not subset of parent's resources";
case X509_V_ERR_PERMITTED_VIOLATION:
- return ("permitted subtree violation");
+ return "permitted subtree violation";
case X509_V_ERR_EXCLUDED_VIOLATION:
- return ("excluded subtree violation");
+ return "excluded subtree violation";
case X509_V_ERR_SUBTREE_MINMAX:
- return ("name constraints minimum and maximum not supported");
+ return "name constraints minimum and maximum not supported";
+ case X509_V_ERR_APPLICATION_VERIFICATION:
+ return "application verification failure";
case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
- return ("unsupported name constraint type");
+ return "unsupported name constraint type";
case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
- return ("unsupported or invalid name constraint syntax");
+ return "unsupported or invalid name constraint syntax";
case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
- return ("unsupported or invalid name syntax");
+ return "unsupported or invalid name syntax";
case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
- return ("CRL path validation error");
-
+ return "CRL path validation error";
+ case X509_V_ERR_PATH_LOOP:
+ return "Path Loop";
case X509_V_ERR_SUITE_B_INVALID_VERSION:
- return ("Suite B: certificate version invalid");
+ return "Suite B: certificate version invalid";
case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
- return ("Suite B: invalid public key algorithm");
+ return "Suite B: invalid public key algorithm";
case X509_V_ERR_SUITE_B_INVALID_CURVE:
- return ("Suite B: invalid ECC curve");
+ return "Suite B: invalid ECC curve";
case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
- return ("Suite B: invalid signature algorithm");
+ return "Suite B: invalid signature algorithm";
case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
- return ("Suite B: curve not allowed for this LOS");
+ return "Suite B: curve not allowed for this LOS";
case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
- return ("Suite B: cannot sign P-384 with P-256");
-
+ return "Suite B: cannot sign P-384 with P-256";
case X509_V_ERR_HOSTNAME_MISMATCH:
- return ("Hostname mismatch");
+ return "Hostname mismatch";
case X509_V_ERR_EMAIL_MISMATCH:
- return ("Email address mismatch");
+ return "Email address mismatch";
case X509_V_ERR_IP_ADDRESS_MISMATCH:
- return ("IP address mismatch");
-
+ return "IP address mismatch";
+ case X509_V_ERR_DANE_NO_MATCH:
+ return "No matching DANE TLSA records";
+ case X509_V_ERR_EE_KEY_TOO_SMALL:
+ return "EE certificate key too weak";
+ case X509_V_ERR_CA_KEY_TOO_SMALL:
+ return "CA certificate key too weak";
+ case X509_V_ERR_CA_MD_TOO_WEAK:
+ return "CA signature digest algorithm too weak";
case X509_V_ERR_INVALID_CALL:
- return ("Invalid certificate verification context");
+ return "Invalid certificate verification context";
case X509_V_ERR_STORE_LOOKUP:
- return ("Issuer certificate lookup error");
+ return "Issuer certificate lookup error";
+ case X509_V_ERR_NO_VALID_SCTS:
+ return "Certificate Transparency required, but no valid SCTs found";
case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
- return ("proxy subject name violation");
+ return "proxy subject name violation";
+ case X509_V_ERR_OCSP_VERIFY_NEEDED:
+ return "OCSP verification needed";
+ case X509_V_ERR_OCSP_VERIFY_FAILED:
+ return "OCSP verification failed";
+ case X509_V_ERR_OCSP_CERT_UNKNOWN:
+ return "OCSP unknown cert";
default:
- BIO_snprintf(buf, sizeof(buf), "error number %ld", n);
- return (buf);
+ /* Printing an error number into a static buffer is not thread-safe */
+ return "unknown certificate verification error";
}
}
diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c
index 9a3517e02af1..75ae767d608c 100644
--- a/crypto/x509/x509_v3.c
+++ b/crypto/x509/x509_v3.c
@@ -1,75 +1,27 @@
-/* crypto/x509/x509_v3.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <openssl/stack.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include <openssl/safestack.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "x509_lcl.h"
int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
{
if (x == NULL)
- return (0);
- return (sk_X509_EXTENSION_num(x));
+ return 0;
+ return sk_X509_EXTENSION_num(x);
}
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
@@ -79,18 +31,18 @@ int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
obj = OBJ_nid2obj(nid);
if (obj == NULL)
- return (-2);
- return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
+ 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)
+ const ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_EXTENSION *ex;
if (sk == NULL)
- return (-1);
+ return -1;
lastpos++;
if (lastpos < 0)
lastpos = 0;
@@ -98,9 +50,9 @@ int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (OBJ_cmp(ex->object, obj) == 0)
- return (lastpos);
+ return lastpos;
}
- return (-1);
+ return -1;
}
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
@@ -110,7 +62,7 @@ int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
X509_EXTENSION *ex;
if (sk == NULL)
- return (-1);
+ return -1;
lastpos++;
if (lastpos < 0)
lastpos = 0;
@@ -118,9 +70,9 @@ int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
- return (lastpos);
+ return lastpos;
}
- return (-1);
+ return -1;
}
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
@@ -136,9 +88,9 @@ 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);
+ return NULL;
ret = sk_X509_EXTENSION_delete(x, loc);
- return (ret);
+ return ret;
}
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
@@ -171,15 +123,14 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
goto err;
if (*x == NULL)
*x = sk;
- return (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 (x != NULL && *x == NULL && sk != NULL)
+ X509_EXTENSION_free(new_ex);
+ if (x != NULL && *x == NULL)
sk_X509_EXTENSION_free(sk);
- return (NULL);
+ return NULL;
}
X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
@@ -192,16 +143,16 @@ X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID);
- return (NULL);
+ return NULL;
}
ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
if (ret == NULL)
ASN1_OBJECT_free(obj);
- return (ret);
+ return ret;
}
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
- ASN1_OBJECT *obj, int crit,
+ const ASN1_OBJECT *obj, int crit,
ASN1_OCTET_STRING *data)
{
X509_EXTENSION *ret;
@@ -210,7 +161,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
if ((ret = X509_EXTENSION_new()) == NULL) {
X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,
ERR_R_MALLOC_FAILURE);
- return (NULL);
+ return NULL;
}
} else
ret = *ex;
@@ -224,28 +175,28 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
if ((ex != NULL) && (*ex == NULL))
*ex = ret;
- return (ret);
+ return ret;
err:
if ((ex == NULL) || (ret != *ex))
X509_EXTENSION_free(ret);
- return (NULL);
+ return NULL;
}
-int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj)
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
{
if ((ex == NULL) || (obj == NULL))
- return (0);
+ return 0;
ASN1_OBJECT_free(ex->object);
ex->object = OBJ_dup(obj);
- return (1);
+ return ex->object != NULL;
}
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
{
if (ex == NULL)
- return (0);
+ return 0;
ex->critical = (crit) ? 0xFF : -1;
- return (1);
+ return 1;
}
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
@@ -253,31 +204,31 @@ 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);
+ return 0;
+ i = ASN1_OCTET_STRING_set(&ex->value, data->data, data->length);
if (!i)
- return (0);
- return (1);
+ return 0;
+ return 1;
}
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
{
if (ex == NULL)
- return (NULL);
- return (ex->object);
+ return NULL;
+ return ex->object;
}
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
{
if (ex == NULL)
- return (NULL);
- return (ex->value);
+ return NULL;
+ return &ex->value;
}
-int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
+int X509_EXTENSION_get_critical(const X509_EXTENSION *ex)
{
if (ex == NULL)
- return (0);
+ return 0;
if (ex->critical > 0)
return 1;
return 0;
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index b1472018baf7..3a60d412daf8 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1,75 +1,29 @@
-/* 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.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
+#include <limits.h>
-#include "cryptlib.h"
+#include "internal/ctype.h"
+#include "internal/cryptlib.h"
#include <openssl/crypto.h>
-#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
-#include "vpm_int.h"
+#include "internal/dane.h"
+#include "internal/x509_int.h"
+#include "x509_lcl.h"
/* CRL score values */
@@ -109,16 +63,23 @@
#define CRL_SCORE_TIME_DELTA 0x002
+static int build_chain(X509_STORE_CTX *ctx);
+static int verify_chain(X509_STORE_CTX *ctx);
+static int dane_verify(X509_STORE_CTX *ctx);
static int null_callback(int ok, X509_STORE_CTX *e);
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
static int check_chain_extensions(X509_STORE_CTX *ctx);
static int check_name_constraints(X509_STORE_CTX *ctx);
static int check_id(X509_STORE_CTX *ctx);
-static int check_trust(X509_STORE_CTX *ctx);
+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted);
static int check_revocation(X509_STORE_CTX *ctx);
static int check_cert(X509_STORE_CTX *ctx);
static int check_policy(X509_STORE_CTX *ctx);
+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth);
+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert);
+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert);
static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
unsigned int *preasons, X509_CRL *crl, X509 *x);
@@ -137,22 +98,20 @@ static int check_crl_chain(X509_STORE_CTX *ctx,
STACK_OF(X509) *crl_path);
static int internal_verify(X509_STORE_CTX *ctx);
-const char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT;
static int null_callback(int ok, X509_STORE_CTX *e)
{
return ok;
}
-#if 0
-static int x509_subject_cmp(X509 **a, X509 **b)
-{
- return X509_subject_name_cmp(*a, *b);
-}
-#endif
/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x)
{
+ /*
+ * FIXME: x509v3_cache_extensions() needs to detect more failures and not
+ * set EXFLAG_SET when that happens. Especially, if the failures are
+ * parse errors, rather than memory pressure!
+ */
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS)
return 1;
@@ -178,30 +137,130 @@ static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
break;
}
if (i < sk_X509_num(certs))
- CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(xtmp);
else
xtmp = NULL;
sk_X509_pop_free(certs, X509_free);
return xtmp;
}
-int X509_verify_cert(X509_STORE_CTX *ctx)
+/*-
+ * Inform the verify callback of an error.
+ * If B<x> is not NULL it is the error cert, otherwise use the chain cert at
+ * B<depth>.
+ * If B<err> is not X509_V_OK, that's the error value, otherwise leave
+ * unchanged (presumably set by the caller).
+ *
+ * Returns 0 to abort verification with an error, non-zero to continue.
+ */
+static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err)
+{
+ ctx->error_depth = depth;
+ ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth);
+ if (err != X509_V_OK)
+ ctx->error = err;
+ return ctx->verify_cb(0, ctx);
+}
+
+/*-
+ * Inform the verify callback of an error, CRL-specific variant. Here, the
+ * error depth and certificate are already set, we just specify the error
+ * number.
+ *
+ * Returns 0 to abort verification with an error, non-zero to continue.
+ */
+static int verify_cb_crl(X509_STORE_CTX *ctx, int err)
+{
+ ctx->error = err;
+ return ctx->verify_cb(0, ctx);
+}
+
+static int check_auth_level(X509_STORE_CTX *ctx)
+{
+ int i;
+ int num = sk_X509_num(ctx->chain);
+
+ if (ctx->param->auth_level <= 0)
+ return 1;
+
+ for (i = 0; i < num; ++i) {
+ X509 *cert = sk_X509_value(ctx->chain, i);
+
+ /*
+ * We've already checked the security of the leaf key, so here we only
+ * check the security of issuer keys.
+ */
+ if (i > 0 && !check_key_level(ctx, cert) &&
+ verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL) == 0)
+ return 0;
+ /*
+ * We also check the signature algorithm security of all certificates
+ * except those of the trust anchor at index num-1.
+ */
+ if (i < num - 1 && !check_sig_level(ctx, cert) &&
+ verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK) == 0)
+ return 0;
+ }
+ return 1;
+}
+
+static int verify_chain(X509_STORE_CTX *ctx)
{
- X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
- int bad_chain = 0;
- X509_VERIFY_PARAM *param = ctx->param;
- int depth, i, ok = 0;
- int num, j, retry;
- int (*cb) (int xok, X509_STORE_CTX *xctx);
- STACK_OF(X509) *sktmp = NULL;
- int trust = X509_TRUST_UNTRUSTED;
int err;
+ int ok;
+
+ /*
+ * Before either returning with an error, or continuing with CRL checks,
+ * instantiate chain public key parameters.
+ */
+ if ((ok = build_chain(ctx)) == 0 ||
+ (ok = check_chain_extensions(ctx)) == 0 ||
+ (ok = check_auth_level(ctx)) == 0 ||
+ (ok = check_id(ctx)) == 0 || 1)
+ X509_get_pubkey_parameters(NULL, ctx->chain);
+ if (ok == 0 || (ok = ctx->check_revocation(ctx)) == 0)
+ return ok;
+
+ err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+ ctx->param->flags);
+ if (err != X509_V_OK) {
+ if ((ok = verify_cb_cert(ctx, NULL, ctx->error_depth, err)) == 0)
+ return ok;
+ }
+
+ /* Verify chain signatures and expiration times */
+ ok = (ctx->verify != NULL) ? ctx->verify(ctx) : internal_verify(ctx);
+ if (!ok)
+ return ok;
+
+ if ((ok = check_name_constraints(ctx)) == 0)
+ return ok;
+
+#ifndef OPENSSL_NO_RFC3779
+ /* RFC 3779 path validation, now that CRL check has been done */
+ if ((ok = X509v3_asid_validate_path(ctx)) == 0)
+ return ok;
+ if ((ok = X509v3_addr_validate_path(ctx)) == 0)
+ return ok;
+#endif
+
+ /* If we get this far evaluate policies */
+ if (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)
+ ok = ctx->check_policy(ctx);
+ return ok;
+}
+
+int X509_verify_cert(X509_STORE_CTX *ctx)
+{
+ SSL_DANE *dane = ctx->dane;
+ int ret;
if (ctx->cert == NULL) {
X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
ctx->error = X509_V_ERR_INVALID_CALL;
return -1;
}
+
if (ctx->chain != NULL) {
/*
* This X509_STORE_CTX has already been used to verify a cert. We
@@ -212,8 +271,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
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
@@ -222,332 +279,48 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
(!sk_X509_push(ctx->chain, ctx->cert))) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
ctx->error = X509_V_ERR_OUT_OF_MEM;
- ok = -1;
- goto err;
- }
- CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
- ctx->last_untrusted = 1;
-
- /* We use a temporary STACK so we can chop and hack at it */
- if (ctx->untrusted != NULL
- && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
- X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- ctx->error = X509_V_ERR_OUT_OF_MEM;
- ok = -1;
- goto err;
- }
-
- num = sk_X509_num(ctx->chain);
- x = sk_X509_value(ctx->chain, num - 1);
- depth = param->depth;
-
- for (;;) {
- /* If we have enough, we break */
- if (depth < num)
- break; /* FIXME: If this happens, we should take
- * note of it and, if appropriate, use the
- * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
- * later. */
-
- /* If we are self signed, we break */
- if (cert_self_signed(x))
- break;
- /*
- * If asked see if we can find issuer in trusted store first
- */
- if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
- ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0) {
- ctx->error = X509_V_ERR_STORE_LOOKUP;
- goto err;
- }
- /*
- * If successful for now free up cert so it will be picked up
- * again later.
- */
- if (ok > 0) {
- X509_free(xtmp);
- break;
- }
- }
-
- /* If we were passed a cert chain, use it first */
- if (ctx->untrusted != NULL) {
- xtmp = find_issuer(ctx, sktmp, x);
- if (xtmp != NULL) {
- if (!sk_X509_push(ctx->chain, xtmp)) {
- X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- ctx->error = X509_V_ERR_OUT_OF_MEM;
- ok = -1;
- goto err;
- }
- CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
- (void)sk_X509_delete_ptr(sktmp, xtmp);
- ctx->last_untrusted++;
- x = xtmp;
- num++;
- /*
- * reparse the full chain for the next one
- */
- continue;
- }
- }
- break;
- }
-
- /* Remember how many untrusted certs we have */
- j = num;
- /*
- * at this point, chain should contain a list of untrusted certificates.
- * We now need to add at least one trusted one, if possible, otherwise we
- * complain.
- */
-
- do {
- /*
- * Examine last certificate in chain and see if it is self signed.
- */
- i = sk_X509_num(ctx->chain);
- x = sk_X509_value(ctx->chain, i - 1);
- if (cert_self_signed(x)) {
- /* we have a self signed certificate */
- if (sk_X509_num(ctx->chain) == 1) {
- /*
- * We have a single self signed certificate: see if we can
- * find it in the store. We must have an exact match to avoid
- * possible impersonation.
- */
- ok = ctx->get_issuer(&xtmp, ctx, x);
- if ((ok <= 0) || X509_cmp(x, xtmp)) {
- ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
- ctx->current_cert = x;
- ctx->error_depth = i - 1;
- if (ok == 1)
- X509_free(xtmp);
- bad_chain = 1;
- ok = cb(0, ctx);
- if (!ok)
- goto err;
- } else {
- /*
- * We have a match: replace certificate with store
- * version so we get any trust settings.
- */
- X509_free(x);
- x = xtmp;
- (void)sk_X509_set(ctx->chain, i - 1, x);
- ctx->last_untrusted = 0;
- }
- } else {
- /*
- * extract and save self signed certificate for later use
- */
- chain_ss = sk_X509_pop(ctx->chain);
- ctx->last_untrusted--;
- num--;
- j--;
- x = sk_X509_value(ctx->chain, num - 1);
- }
- }
- /* We now lookup certs from the certificate store */
- for (;;) {
- /* If we have enough, we break */
- if (depth < num)
- break;
- /* If we are self signed, we break */
- if (cert_self_signed(x))
- break;
- ok = ctx->get_issuer(&xtmp, ctx, x);
-
- if (ok < 0) {
- ctx->error = X509_V_ERR_STORE_LOOKUP;
- goto err;
- }
- if (ok == 0)
- break;
- x = xtmp;
- if (!sk_X509_push(ctx->chain, x)) {
- X509_free(xtmp);
- X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
- ctx->error = X509_V_ERR_OUT_OF_MEM;
- ok = -1;
- goto err;
- }
- num++;
- }
-
- /* we now have our chain, lets check it... */
- if ((trust = check_trust(ctx)) == X509_TRUST_REJECTED) {
- /* Callback already issued */
- ok = 0;
- goto err;
- }
-
- /*
- * If it's not explicitly trusted then check if there is an alternative
- * chain that could be used. We only do this if we haven't already
- * checked via TRUSTED_FIRST and the user hasn't switched off alternate
- * chain checking
- */
- retry = 0;
- if (trust != X509_TRUST_TRUSTED
- && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
- && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
- while (j-- > 1) {
- xtmp2 = sk_X509_value(ctx->chain, j - 1);
- ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
- if (ok < 0) {
- ctx->error = X509_V_ERR_STORE_LOOKUP;
- goto err;
- }
- /* Check if we found an alternate chain */
- if (ok > 0) {
- /*
- * Free up the found cert we'll add it again later
- */
- X509_free(xtmp);
-
- /*
- * Dump all the certs above this point - we've found an
- * alternate chain
- */
- while (num > j) {
- xtmp = sk_X509_pop(ctx->chain);
- X509_free(xtmp);
- num--;
- }
- ctx->last_untrusted = sk_X509_num(ctx->chain);
- retry = 1;
- break;
- }
- }
- }
- } while (retry);
-
- /*
- * If not explicitly trusted then indicate error unless it's a single
- * self signed certificate in which case we've indicated an error already
- * and set bad_chain == 1
- */
- if (trust != X509_TRUST_TRUSTED && !bad_chain) {
- if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
- if (ctx->last_untrusted >= num)
- ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
- else
- ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
- ctx->current_cert = x;
- } else {
-
- sk_X509_push(ctx->chain, chain_ss);
- num++;
- ctx->last_untrusted = num;
- ctx->current_cert = chain_ss;
- ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
- chain_ss = NULL;
- }
-
- ctx->error_depth = num - 1;
- bad_chain = 1;
- ok = cb(0, ctx);
- if (!ok)
- goto err;
+ return -1;
}
+ X509_up_ref(ctx->cert);
+ ctx->num_untrusted = 1;
- /* We have the chain complete: now we need to check its purpose */
- ok = check_chain_extensions(ctx);
-
- if (!ok)
- goto err;
-
- /* Check name constraints */
-
- ok = check_name_constraints(ctx);
-
- if (!ok)
- goto err;
-
- ok = check_id(ctx);
-
- if (!ok)
- goto err;
+ /* If the peer's public key is too weak, we can stop early. */
+ if (!check_key_level(ctx, ctx->cert) &&
+ !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL))
+ return 0;
- /* We may as well copy down any DSA parameters that are required */
- X509_get_pubkey_parameters(NULL, ctx->chain);
+ if (DANETLS_ENABLED(dane))
+ ret = dane_verify(ctx);
+ else
+ ret = verify_chain(ctx);
/*
- * Check revocation status: we do this after copying parameters because
- * they may be needed for CRL signature verification.
+ * Safety-net. If we are returning an error, we must also set ctx->error,
+ * so that the chain is not considered verified should the error be ignored
+ * (e.g. TLS with SSL_VERIFY_NONE).
*/
-
- ok = ctx->check_revocation(ctx);
- if (!ok)
- goto err;
-
- err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
- ctx->param->flags);
- if (err != X509_V_OK) {
- ctx->error = err;
- ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
- ok = cb(0, ctx);
- if (!ok)
- goto err;
- }
-
- /* At this point, we have a chain and need to verify it */
- if (ctx->verify != NULL)
- ok = ctx->verify(ctx);
- else
- ok = internal_verify(ctx);
- if (!ok)
- goto err;
-
-#ifndef OPENSSL_NO_RFC3779
- /* RFC 3779 path validation, now that CRL check has been done */
- ok = v3_asid_validate_path(ctx);
- if (!ok)
- goto err;
- ok = v3_addr_validate_path(ctx);
- if (!ok)
- goto err;
-#endif
-
- /* If we get this far evaluate policies */
- if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
- ok = ctx->check_policy(ctx);
- if (!ok)
- goto err;
- if (0) {
- err:
- /* Ensure we return an error */
- if (ok > 0)
- ok = 0;
- X509_get_pubkey_parameters(NULL, ctx->chain);
- }
- if (sktmp != NULL)
- sk_X509_free(sktmp);
- if (chain_ss != NULL)
- X509_free(chain_ss);
-
- /* Safety net, error returns must set ctx->error */
- if (ok <= 0 && ctx->error == X509_V_OK)
+ if (ret <= 0 && ctx->error == X509_V_OK)
ctx->error = X509_V_ERR_UNSPECIFIED;
- return ok;
+ return ret;
}
/*
* 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;
+ X509 *issuer, *rv = NULL;
+
for (i = 0; i < sk_X509_num(sk); i++) {
issuer = sk_X509_value(sk, i);
- if (ctx->check_issued(ctx, x, issuer))
- return issuer;
+ if (ctx->check_issued(ctx, x, issuer)) {
+ rv = issuer;
+ if (x509_check_cert_time(ctx, rv, -1))
+ break;
+ }
}
- return NULL;
+ return rv;
}
/* Given a possible certificate and issuer check them */
@@ -555,17 +328,25 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
{
int ret;
+ if (x == issuer)
+ return cert_self_signed(x);
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;
+ if (ret == X509_V_OK) {
+ int i;
+ X509 *ch;
+ /* Special case: single self signed certificate */
+ if (cert_self_signed(x) && sk_X509_num(ctx->chain) == 1)
+ return 1;
+ for (i = 0; i < sk_X509_num(ctx->chain); i++) {
+ ch = sk_X509_value(ctx->chain, i);
+ if (ch == issuer || !X509_cmp(ch, issuer)) {
+ ret = X509_V_ERR_PATH_LOOP;
+ break;
+ }
+ }
+ }
- ctx->error = ret;
- ctx->current_cert = x;
- ctx->current_issuer = issuer;
- return ctx->verify_cb(0, ctx);
+ return (ret == X509_V_OK);
}
/* Alternative lookup method: look from a STACK stored in other_ctx */
@@ -574,12 +355,86 @@ 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);
+ X509_up_ref(*issuer);
return 1;
} else
return 0;
}
+static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+ STACK_OF(X509) *sk = NULL;
+ X509 *x;
+ int i;
+
+ for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) {
+ x = sk_X509_value(ctx->other_ctx, i);
+ if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) {
+ if (sk == NULL)
+ sk = sk_X509_new_null();
+ if (sk == NULL || sk_X509_push(sk, x) == 0) {
+ sk_X509_pop_free(sk, X509_free);
+ X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return NULL;
+ }
+ X509_up_ref(x);
+ }
+ }
+ return sk;
+}
+
+/*
+ * Check EE or CA certificate purpose. For trusted certificates explicit local
+ * auxiliary trust can be used to override EKU-restrictions.
+ */
+static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
+ int must_be_ca)
+{
+ int tr_ok = X509_TRUST_UNTRUSTED;
+
+ /*
+ * For trusted certificates we want to see whether any auxiliary trust
+ * settings trump the purpose constraints.
+ *
+ * This is complicated by the fact that the trust ordinals in
+ * ctx->param->trust are entirely independent of the purpose ordinals in
+ * ctx->param->purpose!
+ *
+ * What connects them is their mutual initialization via calls from
+ * X509_STORE_CTX_set_default() into X509_VERIFY_PARAM_lookup() which sets
+ * related values of both param->trust and param->purpose. It is however
+ * typically possible to infer associated trust values from a purpose value
+ * via the X509_PURPOSE API.
+ *
+ * Therefore, we can only check for trust overrides when the purpose we're
+ * checking is the same as ctx->param->purpose and ctx->param->trust is
+ * also set.
+ */
+ if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
+ tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT);
+
+ switch (tr_ok) {
+ case X509_TRUST_TRUSTED:
+ return 1;
+ case X509_TRUST_REJECTED:
+ break;
+ default:
+ switch (X509_check_purpose(x, purpose, must_be_ca > 0)) {
+ case 1:
+ return 1;
+ case 0:
+ break;
+ default:
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)
+ return 1;
+ }
+ break;
+ }
+
+ return verify_cb_cert(ctx, x, depth, X509_V_ERR_INVALID_PURPOSE);
+}
+
/*
* Check a certificate chains extensions for consistency with the supplied
* purpose
@@ -587,16 +442,12 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
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;
+ int i, must_be_ca, plen = 0;
X509 *x;
- int (*cb) (int xok, X509_STORE_CTX *xctx);
int proxy_path_length = 0;
int purpose;
int allow_proxy_certs;
- cb = ctx->verify_cb;
+ int num = sk_X509_num(ctx->chain);
/*-
* must_be_ca can have 1 of 3 values:
@@ -616,35 +467,22 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
} else {
allow_proxy_certs =
! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
- /*
- * A hack to keep people who don't want to modify their software
- * happy
- */
- if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
- allow_proxy_certs = 1;
purpose = ctx->param->purpose;
}
- /* Check all untrusted certificates */
- for (i = 0; i < ctx->last_untrusted; i++) {
+ for (i = 0; i < num; 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 (!verify_cb_cert(ctx, x, i,
+ X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION))
+ return 0;
}
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;
+ if (!verify_cb_cert(ctx, x, i,
+ X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED))
+ return 0;
}
ret = X509_check_ca(x);
switch (must_be_ca) {
@@ -664,8 +502,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
ret = 1;
break;
default:
+ /* X509_V_FLAG_X509_STRICT is implicit for intermediate CAs */
if ((ret == 0)
- || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+ || ((i + 1 < num || ctx->param->flags & X509_V_FLAG_X509_STRICT)
&& (ret != 1))) {
ret = 0;
ctx->error = X509_V_ERR_INVALID_CA;
@@ -673,36 +512,17 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
ret = 1;
break;
}
- if (ret == 0) {
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok = cb(0, ctx);
- if (!ok)
- goto end;
- }
- if (ctx->param->purpose > 0) {
- ret = X509_check_purpose(x, purpose, must_be_ca > 0);
- if ((ret == 0)
- || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
- && (ret != 1))) {
- ctx->error = X509_V_ERR_INVALID_PURPOSE;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok = cb(0, ctx);
- if (!ok)
- goto end;
- }
- }
+ if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK))
+ return 0;
+ /* check_purpose() makes the callback as needed */
+ if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
+ return 0;
/* 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;
+ if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
+ return 0;
}
/* Increment path length if not self issued */
if (!(x->ex_flags & EXFLAG_SI))
@@ -726,12 +546,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
*/
if (x->ex_pcpathlen != -1) {
if (proxy_path_length > 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;
+ if (!verify_cb_cert(ctx, x, i,
+ X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED))
+ return 0;
}
proxy_path_length = x->ex_pcpathlen;
}
@@ -740,19 +557,39 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
} else
must_be_ca = 1;
}
- ok = 1;
- end:
- return ok;
-#endif
+ return 1;
+}
+
+static int has_san_id(X509 *x, int gtype)
+{
+ int i;
+ int ret = 0;
+ GENERAL_NAMES *gs = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+
+ if (gs == NULL)
+ return 0;
+
+ for (i = 0; i < sk_GENERAL_NAME_num(gs); i++) {
+ GENERAL_NAME *g = sk_GENERAL_NAME_value(gs, i);
+
+ if (g->type == gtype) {
+ ret = 1;
+ break;
+ }
+ }
+ GENERAL_NAMES_free(gs);
+ return ret;
}
static int check_name_constraints(X509_STORE_CTX *ctx)
{
- X509 *x;
- int i, j, rv;
+ int i;
+
/* Check name constraints for all certificates */
for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
- x = sk_X509_value(ctx->chain, i);
+ X509 *x = sk_X509_value(ctx->chain, i);
+ int j;
+
/* Ignore self issued certs unless last in chain */
if (i && (x->ex_flags & EXFLAG_SI))
continue;
@@ -791,8 +628,10 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
* Check that the last subject component isn't part of a
* multivalued RDN
*/
- if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set
- == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) {
+ if (X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+ last_object_loc))
+ == X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+ last_object_loc - 1))) {
err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
goto proxy_name_done;
}
@@ -822,13 +661,9 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
X509_NAME_free(tmpsubject);
proxy_name_done:
- if (err != X509_V_OK) {
- ctx->error = err;
- ctx->error_depth = i;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
+ if (err != X509_V_OK
+ && !verify_cb_cert(ctx, x, i, err))
+ return 0;
}
/*
@@ -839,19 +674,26 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
*/
for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+
if (nc) {
- rv = NAME_CONSTRAINTS_check(x, nc);
+ int rv = NAME_CONSTRAINTS_check(x, nc);
+
+ /* If EE certificate check commonName too */
+ if (rv == X509_V_OK && i == 0
+ && (ctx->param->hostflags
+ & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) == 0
+ && ((ctx->param->hostflags
+ & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) != 0
+ || !has_san_id(x, GEN_DNS)))
+ rv = NAME_CONSTRAINTS_check_CN(x, nc);
+
switch (rv) {
case X509_V_OK:
- continue;
+ break;
case X509_V_ERR_OUT_OF_MEM:
- ctx->error = rv;
return 0;
default:
- ctx->error = rv;
- ctx->error_depth = i;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_cert(ctx, x, i, rv))
return 0;
break;
}
@@ -863,25 +705,22 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
static int check_id_error(X509_STORE_CTX *ctx, int errcode)
{
- ctx->error = errcode;
- ctx->current_cert = ctx->cert;
- ctx->error_depth = 0;
- return ctx->verify_cb(0, ctx);
+ return verify_cb_cert(ctx, ctx->cert, 0, errcode);
}
-static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
+static int check_hosts(X509 *x, X509_VERIFY_PARAM *vpm)
{
int i;
- int n = sk_OPENSSL_STRING_num(id->hosts);
+ int n = sk_OPENSSL_STRING_num(vpm->hosts);
char *name;
- if (id->peername != NULL) {
- OPENSSL_free(id->peername);
- id->peername = NULL;
+ if (vpm->peername != NULL) {
+ OPENSSL_free(vpm->peername);
+ vpm->peername = NULL;
}
for (i = 0; i < n; ++i) {
- name = sk_OPENSSL_STRING_value(id->hosts, i);
- if (X509_check_host(x, name, 0, id->hostflags, &id->peername) > 0)
+ name = sk_OPENSSL_STRING_value(vpm->hosts, i);
+ if (X509_check_host(x, name, 0, vpm->hostflags, &vpm->peername) > 0)
return 1;
}
return n == 0;
@@ -890,65 +729,95 @@ static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
static int check_id(X509_STORE_CTX *ctx)
{
X509_VERIFY_PARAM *vpm = ctx->param;
- X509_VERIFY_PARAM_ID *id = vpm->id;
X509 *x = ctx->cert;
- if (id->hosts && check_hosts(x, id) <= 0) {
+ if (vpm->hosts && check_hosts(x, vpm) <= 0) {
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
return 0;
}
- if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
+ if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) {
if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
return 0;
}
- if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
+ if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) {
if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
return 0;
}
return 1;
}
-static int check_trust(X509_STORE_CTX *ctx)
+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted)
{
- int i, ok;
+ int i;
X509 *x = NULL;
- int (*cb) (int xok, X509_STORE_CTX *xctx);
- cb = ctx->verify_cb;
- /* Check all trusted certificates in chain */
- for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
+ X509 *mx;
+ SSL_DANE *dane = ctx->dane;
+ int num = sk_X509_num(ctx->chain);
+ int trust;
+
+ /*
+ * Check for a DANE issuer at depth 1 or greater, if it is a DANE-TA(2)
+ * match, we're done, otherwise we'll merely record the match depth.
+ */
+ if (DANETLS_HAS_TA(dane) && num_untrusted > 0 && num_untrusted < num) {
+ switch (trust = check_dane_issuer(ctx, num_untrusted)) {
+ case X509_TRUST_TRUSTED:
+ case X509_TRUST_REJECTED:
+ return trust;
+ }
+ }
+
+ /*
+ * Check trusted certificates in chain at depth num_untrusted and up.
+ * Note, that depths 0..num_untrusted-1 may also contain trusted
+ * certificates, but the caller is expected to have already checked those,
+ * and wants to incrementally check just any added since.
+ */
+ for (i = num_untrusted; i < num; i++) {
x = sk_X509_value(ctx->chain, i);
- ok = X509_check_trust(x, ctx->param->trust, 0);
+ trust = X509_check_trust(x, ctx->param->trust, 0);
/* If explicitly trusted return trusted */
- if (ok == X509_TRUST_TRUSTED)
- return X509_TRUST_TRUSTED;
- /*
- * If explicitly rejected notify callback and reject if not
- * overridden.
- */
- if (ok == X509_TRUST_REJECTED) {
- ctx->error_depth = i;
- ctx->current_cert = x;
- ctx->error = X509_V_ERR_CERT_REJECTED;
- ok = cb(0, ctx);
- if (!ok)
- return X509_TRUST_REJECTED;
- }
+ if (trust == X509_TRUST_TRUSTED)
+ goto trusted;
+ if (trust == X509_TRUST_REJECTED)
+ goto rejected;
}
+
/*
- * If we accept partial chains and have at least one trusted certificate
- * return success.
+ * If we are looking at a trusted certificate, and accept partial chains,
+ * the chain is PKIX trusted.
*/
- if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
- X509 *mx;
- if (ctx->last_untrusted < sk_X509_num(ctx->chain))
- return X509_TRUST_TRUSTED;
- x = sk_X509_value(ctx->chain, 0);
+ if (num_untrusted < num) {
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
+ goto trusted;
+ return X509_TRUST_UNTRUSTED;
+ }
+
+ if (num_untrusted == num && ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+ /*
+ * Last-resort call with no new trusted certificates, check the leaf
+ * for a direct trust store match.
+ */
+ i = 0;
+ x = sk_X509_value(ctx->chain, i);
mx = lookup_cert_match(ctx, x);
- if (mx) {
- (void)sk_X509_set(ctx->chain, 0, mx);
- X509_free(x);
- ctx->last_untrusted = 0;
- return X509_TRUST_TRUSTED;
+ if (!mx)
+ return X509_TRUST_UNTRUSTED;
+
+ /*
+ * Check explicit auxiliary trust/reject settings. If none are set,
+ * we'll accept X509_TRUST_UNTRUSTED when not self-signed.
+ */
+ trust = X509_check_trust(mx, ctx->param->trust, 0);
+ if (trust == X509_TRUST_REJECTED) {
+ X509_free(mx);
+ goto rejected;
}
+
+ /* Replace leaf with trusted match */
+ (void) sk_X509_set(ctx->chain, 0, mx);
+ X509_free(x);
+ ctx->num_untrusted = 0;
+ goto trusted;
}
/*
@@ -956,11 +825,26 @@ static int check_trust(X509_STORE_CTX *ctx)
* standard (no issuer cert) etc errors to be indicated.
*/
return X509_TRUST_UNTRUSTED;
+
+ rejected:
+ if (!verify_cb_cert(ctx, x, i, X509_V_ERR_CERT_REJECTED))
+ return X509_TRUST_REJECTED;
+ return X509_TRUST_UNTRUSTED;
+
+ trusted:
+ if (!DANETLS_ENABLED(dane))
+ return X509_TRUST_TRUSTED;
+ if (dane->pdpth < 0)
+ dane->pdpth = num_untrusted;
+ /* With DANE, PKIX alone is not trusted until we have both */
+ if (dane->mdpth >= 0)
+ return X509_TRUST_TRUSTED;
+ return X509_TRUST_UNTRUSTED;
}
static int check_revocation(X509_STORE_CTX *ctx)
{
- int i, last, ok;
+ int i = 0, last = 0, ok = 0;
if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
return 1;
if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
@@ -983,19 +867,21 @@ static int check_revocation(X509_STORE_CTX *ctx)
static int check_cert(X509_STORE_CTX *ctx)
{
X509_CRL *crl = NULL, *dcrl = NULL;
- X509 *x;
- int ok, cnum;
- unsigned int last_reasons;
- cnum = ctx->error_depth;
- x = sk_X509_value(ctx->chain, cnum);
+ int ok = 0;
+ int cnum = ctx->error_depth;
+ X509 *x = sk_X509_value(ctx->chain, cnum);
+
ctx->current_cert = x;
ctx->current_issuer = NULL;
ctx->current_crl_score = 0;
ctx->current_reasons = 0;
+
if (x->ex_flags & EXFLAG_PROXY)
return 1;
+
while (ctx->current_reasons != CRLDP_ALL_REASONS) {
- last_reasons = ctx->current_reasons;
+ unsigned int last_reasons = ctx->current_reasons;
+
/* Try to retrieve relevant CRL */
if (ctx->get_crl)
ok = ctx->get_crl(ctx, &crl, x);
@@ -1005,22 +891,21 @@ static int check_cert(X509_STORE_CTX *ctx)
* 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;
+ ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
+ goto done;
}
ctx->current_crl = crl;
ok = ctx->check_crl(ctx, crl);
if (!ok)
- goto err;
+ goto done;
if (dcrl) {
ok = ctx->check_crl(ctx, dcrl);
if (!ok)
- goto err;
+ goto done;
ok = ctx->cert_crl(ctx, dcrl, x);
if (!ok)
- goto err;
+ goto done;
} else
ok = 1;
@@ -1028,7 +913,7 @@ static int check_cert(X509_STORE_CTX *ctx)
if (ok != 2) {
ok = ctx->cert_crl(ctx, crl, x);
if (!ok)
- goto err;
+ goto done;
}
X509_CRL_free(crl);
@@ -1036,22 +921,20 @@ static int check_cert(X509_STORE_CTX *ctx)
crl = NULL;
dcrl = NULL;
/*
- * If reasons not updated we wont get anywhere by another iteration,
+ * If reasons not updated we won't get anywhere by another iteration,
* so exit loop.
*/
if (last_reasons == ctx->current_reasons) {
- ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
- ok = ctx->verify_cb(0, ctx);
- goto err;
+ ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
+ goto done;
}
}
- err:
+ done:
X509_CRL_free(crl);
X509_CRL_free(dcrl);
ctx->current_crl = NULL;
return ok;
-
}
/* Check CRL times against values in X509_STORE_CTX */
@@ -1060,46 +943,45 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
{
time_t *ptime;
int i;
+
if (notify)
ctx->current_crl = crl;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
else
ptime = NULL;
- i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
+ i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime);
if (i == 0) {
if (!notify)
return 0;
- ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD))
return 0;
}
if (i > 0) {
if (!notify)
return 0;
- ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_crl(ctx, X509_V_ERR_CRL_NOT_YET_VALID))
return 0;
}
- if (X509_CRL_get_nextUpdate(crl)) {
- i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
+ if (X509_CRL_get0_nextUpdate(crl)) {
+ i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime);
if (i == 0) {
if (!notify)
return 0;
- ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD))
return 0;
}
/* Ignore expiry of base CRL is delta is valid */
if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
if (!notify)
return 0;
- ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_crl(ctx, X509_V_ERR_CRL_HAS_EXPIRED))
return 0;
}
}
@@ -1129,8 +1011,8 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
/* If current CRL is equivalent use it if it is newer */
if (crl_score == best_score && best_crl != NULL) {
int day, sec;
- if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
- X509_CRL_get_lastUpdate(crl)) == 0)
+ if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl),
+ X509_CRL_get0_lastUpdate(crl)) == 0)
continue;
/*
* ASN1_TIME_diff never returns inconsistent signs for |day|
@@ -1146,17 +1028,14 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
}
if (best_crl) {
- if (*pcrl)
- X509_CRL_free(*pcrl);
+ X509_CRL_free(*pcrl);
*pcrl = best_crl;
*pissuer = best_crl_issuer;
*pscore = best_score;
*preasons = best_reasons;
- CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
- if (*pdcrl) {
- X509_CRL_free(*pdcrl);
- *pdcrl = NULL;
- }
+ X509_CRL_up_ref(best_crl);
+ X509_CRL_free(*pdcrl);
+ *pdcrl = NULL;
get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
}
@@ -1252,7 +1131,7 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
if (check_delta_base(delta, base)) {
if (check_crl_time(ctx, delta, 0))
*pscore |= CRL_SCORE_TIME_DELTA;
- CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
+ X509_CRL_up_ref(delta);
*dcrl = delta;
return;
}
@@ -1394,6 +1273,7 @@ static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
{
X509_STORE_CTX crl_ctx;
int ret;
+
/* Don't allow recursive CRL path validation */
if (ctx->parent)
return 0;
@@ -1409,12 +1289,10 @@ static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
/* Verify CRL issuer */
ret = X509_verify_cert(&crl_ctx);
-
if (ret <= 0)
goto err;
/* Check chain is acceptable */
-
ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
err:
X509_STORE_CTX_cleanup(&crl_ctx);
@@ -1571,10 +1449,10 @@ static int get_crl_delta(X509_STORE_CTX *ctx,
X509_CRL *crl = NULL, *dcrl = NULL;
STACK_OF(X509_CRL) *skcrl;
X509_NAME *nm = X509_get_issuer_name(x);
+
reasons = ctx->current_reasons;
ok = get_crl_sk(ctx, &crl, &dcrl,
&issuer, &crl_score, &reasons, ctx->crls);
-
if (ok)
goto done;
@@ -1591,7 +1469,6 @@ static int get_crl_delta(X509_STORE_CTX *ctx,
sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
done:
-
/* If we got any kind of CRL use it and return success */
if (crl) {
ctx->current_issuer = issuer;
@@ -1601,7 +1478,6 @@ static int get_crl_delta(X509_STORE_CTX *ctx,
*pdcrl = dcrl;
return 1;
}
-
return 0;
}
@@ -1610,13 +1486,12 @@ 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;
+ int cnum = ctx->error_depth;
+ int chnum = sk_X509_num(ctx->chain) - 1;
+
/* if we have an alternative CRL issuer cert use that */
if (ctx->current_issuer)
issuer = ctx->current_issuer;
-
/*
* Else find CRL issuer: if not last certificate then issuer is next
* certificate in chain.
@@ -1626,121 +1501,85 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
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 (!ctx->check_issued(ctx, issuer, issuer) &&
+ !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER))
+ return 0;
}
- if (issuer) {
- /*
- * Skip most tests for deltas because they have already been done
- */
- if (!crl->base_crl_number) {
- /* Check for cRLSign bit if keyUsage present */
- if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
- !(issuer->ex_kusage & KU_CRL_SIGN)) {
- ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
+ if (issuer == NULL)
+ return 1;
- if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
- ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
+ /*
+ * Skip most tests for deltas because they have already been done
+ */
+ if (!crl->base_crl_number) {
+ /* Check for cRLSign bit if keyUsage present */
+ if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+ !(issuer->ex_kusage & KU_CRL_SIGN) &&
+ !verify_cb_crl(ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN))
+ return 0;
- if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
- if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
- ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
- }
+ if (!(ctx->current_crl_score & CRL_SCORE_SCOPE) &&
+ !verify_cb_crl(ctx, X509_V_ERR_DIFFERENT_CRL_SCOPE))
+ return 0;
- if (crl->idp_flags & IDP_INVALID) {
- ctx->error = X509_V_ERR_INVALID_EXTENSION;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
+ if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH) &&
+ check_crl_path(ctx, ctx->current_issuer) <= 0 &&
+ !verify_cb_crl(ctx, X509_V_ERR_CRL_PATH_VALIDATION_ERROR))
+ return 0;
- }
+ if ((crl->idp_flags & IDP_INVALID) &&
+ !verify_cb_crl(ctx, X509_V_ERR_INVALID_EXTENSION))
+ return 0;
+ }
- if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
- ok = check_crl_time(ctx, crl, 1);
- if (!ok)
- goto err;
- }
+ if (!(ctx->current_crl_score & CRL_SCORE_TIME) &&
+ !check_crl_time(ctx, crl, 1))
+ return 0;
- /* Attempt to get issuer certificate public key */
- ikey = X509_get_pubkey(issuer);
+ /* Attempt to get issuer certificate public key */
+ ikey = X509_get0_pubkey(issuer);
- if (!ikey) {
- ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- } else {
- int rv;
- rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
- if (rv != X509_V_OK) {
- ctx->error = rv;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
- /* Verify CRL signature */
- if (X509_CRL_verify(crl, ikey) <= 0) {
- ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- goto err;
- }
- }
- }
+ if (!ikey &&
+ !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY))
+ return 0;
- ok = 1;
+ if (ikey) {
+ int rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
- err:
- EVP_PKEY_free(ikey);
- return ok;
+ if (rv != X509_V_OK && !verify_cb_crl(ctx, rv))
+ return 0;
+ /* Verify CRL signature */
+ if (X509_CRL_verify(crl, ikey) <= 0 &&
+ !verify_cb_crl(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE))
+ return 0;
+ }
+ return 1;
}
/* Check certificate against CRL */
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
{
- int ok;
X509_REVOKED *rev;
+
/*
* The rules changed for this... previously if a CRL contained unhandled
* critical extensions it could still be used to indicate a certificate
- * was revoked. This has since been changed since critical extension can
+ * was revoked. This has since been changed since critical extensions can
* change the meaning of CRL entries.
*/
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
- && (crl->flags & EXFLAG_CRITICAL)) {
- ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
- return 0;
- }
+ && (crl->flags & EXFLAG_CRITICAL) &&
+ !verify_cb_crl(ctx, X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION))
+ return 0;
/*
- * Look for serial number of certificate in CRL If found make sure reason
- * is not removeFromCRL.
+ * Look for serial number of certificate in CRL. If found, make sure
+ * reason is not removeFromCRL.
*/
if (X509_CRL_get0_by_cert(crl, &rev, x)) {
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
return 2;
- ctx->error = X509_V_ERR_CERT_REVOKED;
- ok = ctx->verify_cb(0, ctx);
- if (!ok)
+ if (!verify_cb_crl(ctx, X509_V_ERR_CERT_REVOKED))
return 0;
}
@@ -1750,38 +1589,60 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
static int check_policy(X509_STORE_CTX *ctx)
{
int ret;
+
if (ctx->parent)
return 1;
+ /*
+ * With DANE, the trust anchor might be a bare public key, not a
+ * certificate! In that case our chain does not have the trust anchor
+ * certificate as a top-most element. This comports well with RFC5280
+ * chain verification, since there too, the trust anchor is not part of the
+ * chain to be verified. In particular, X509_policy_check() does not look
+ * at the TA cert, but assumes that it is present as the top-most chain
+ * element. We therefore temporarily push a NULL cert onto the chain if it
+ * was verified via a bare public key, and pop it off right after the
+ * X509_policy_check() call.
+ */
+ if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) {
+ X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
ctx->param->policies, ctx->param->flags);
- if (ret == 0) {
+ if (ctx->bare_ta_signed)
+ sk_X509_pop(ctx->chain);
+
+ if (ret == X509_PCY_TREE_INTERNAL) {
X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
ctx->error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
/* Invalid or inconsistent extensions */
- if (ret == -1) {
- /*
- * Locate certificates with bad extensions and notify callback.
- */
- X509 *x;
+ if (ret == X509_PCY_TREE_INVALID) {
int i;
+
+ /* Locate certificates with bad extensions and notify callback. */
for (i = 1; i < sk_X509_num(ctx->chain); i++) {
- x = sk_X509_value(ctx->chain, i);
+ X509 *x = sk_X509_value(ctx->chain, i);
+
if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
continue;
- ctx->current_cert = x;
- ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
- if (!ctx->verify_cb(0, ctx))
+ if (!verify_cb_cert(ctx, x, i,
+ X509_V_ERR_INVALID_POLICY_EXTENSION))
return 0;
}
return 1;
}
- if (ret == -2) {
+ if (ret == X509_PCY_TREE_FAILURE) {
ctx->current_cert = NULL;
ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
return ctx->verify_cb(0, ctx);
}
+ if (ret != X509_PCY_TREE_VALID) {
+ X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
ctx->current_cert = NULL;
@@ -1798,62 +1659,61 @@ static int check_policy(X509_STORE_CTX *ctx)
return 1;
}
-static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
+/*-
+ * Check certificate validity times.
+ * If depth >= 0, invoke verification callbacks on error, otherwise just return
+ * the validation status.
+ *
+ * Return 1 on success, 0 otherwise.
+ */
+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
{
time_t *ptime;
int i;
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
ptime = &ctx->param->check_time;
+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+ return 1;
else
ptime = NULL;
- i = X509_cmp_time(X509_get_notBefore(x), ptime);
- if (i == 0) {
- ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if (i > 0) {
- ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- i = X509_cmp_time(X509_get_notAfter(x), ptime);
- if (i == 0) {
- ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
-
- if (i < 0) {
- ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
- ctx->current_cert = x;
- if (!ctx->verify_cb(0, ctx))
- return 0;
- }
+ i = X509_cmp_time(X509_get0_notBefore(x), ptime);
+ if (i >= 0 && depth < 0)
+ return 0;
+ if (i == 0 && !verify_cb_cert(ctx, x, depth,
+ X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD))
+ return 0;
+ if (i > 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_NOT_YET_VALID))
+ return 0;
+ i = X509_cmp_time(X509_get0_notAfter(x), ptime);
+ if (i <= 0 && depth < 0)
+ return 0;
+ if (i == 0 && !verify_cb_cert(ctx, x, depth,
+ X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD))
+ return 0;
+ if (i < 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_HAS_EXPIRED))
+ 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;
+ int n = sk_X509_num(ctx->chain) - 1;
+ X509 *xi = sk_X509_value(ctx->chain, n);
+ X509 *xs;
- n = sk_X509_num(ctx->chain);
- ctx->error_depth = n - 1;
- n--;
- xi = sk_X509_value(ctx->chain, n);
+ /*
+ * With DANE-verified bare public key TA signatures, it remains only to
+ * check the timestamps of the top certificate. We report the issuer as
+ * NULL, since all we have is a bare key.
+ */
+ if (ctx->bare_ta_signed) {
+ xs = xi;
+ xi = NULL;
+ goto check_cert;
+ }
if (ctx->check_issued(ctx, xi, xi))
xs = xi;
@@ -1862,72 +1722,60 @@ static int internal_verify(X509_STORE_CTX *ctx)
xs = xi;
goto check_cert;
}
- if (n <= 0) {
- ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
- ctx->current_cert = xi;
- ok = cb(0, ctx);
- goto end;
- } else {
- n--;
- ctx->error_depth = n;
- xs = sk_X509_value(ctx->chain, n);
- }
+ if (n <= 0)
+ return verify_cb_cert(ctx, xi, 0,
+ X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
+ n--;
+ ctx->error_depth = n;
+ xs = sk_X509_value(ctx->chain, n);
}
-/* ctx->error=0; not needed */
+ /*
+ * Do not clear ctx->error=0, it must be "sticky", only the user's callback
+ * is allowed to reset errors (at its own peril).
+ */
while (n >= 0) {
- ctx->error_depth = n;
+ EVP_PKEY *pkey;
/*
- * Skip signature check for self signed certificates unless
- * explicitly asked for. It doesn't add any security and just wastes
- * time.
+ * Skip signature check for self signed certificates unless explicitly
+ * asked for. It doesn't add any security and just wastes time. If
+ * the issuer's public key is unusable, report the issuer certificate
+ * and its depth (rather than the depth of the subject).
*/
- if (!xs->valid
- && (xs != xi
- || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
- if ((pkey = X509_get_pubkey(xi)) == NULL) {
- ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
- ctx->current_cert = xi;
- ok = (*cb) (0, ctx);
- if (!ok)
- goto end;
+ if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
+ if ((pkey = X509_get0_pubkey(xi)) == NULL) {
+ if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n,
+ X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY))
+ return 0;
} else if (X509_verify(xs, pkey) <= 0) {
- ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
- ctx->current_cert = xs;
- ok = (*cb) (0, ctx);
- if (!ok) {
- EVP_PKEY_free(pkey);
- goto end;
- }
+ if (!verify_cb_cert(ctx, xs, n,
+ X509_V_ERR_CERT_SIGNATURE_FAILURE))
+ return 0;
}
- EVP_PKEY_free(pkey);
- pkey = NULL;
}
- xs->valid = 1;
-
check_cert:
- ok = check_cert_time(ctx, xs);
- if (!ok)
- goto end;
+ /* Calls verify callback as needed */
+ if (!x509_check_cert_time(ctx, xs, n))
+ return 0;
- /* The last error (if any) is still in the error value */
+ /*
+ * Signal success at this depth. However, the previous error (if any)
+ * is retained.
+ */
ctx->current_issuer = xi;
ctx->current_cert = xs;
- ok = (*cb) (1, ctx);
- if (!ok)
- goto end;
+ ctx->error_depth = n;
+ if (!ctx->verify_cb(1, ctx))
+ return 0;
- n--;
- if (n >= 0) {
+ if (--n >= 0) {
xi = xs;
xs = sk_X509_value(ctx->chain, n);
}
}
- ok = 1;
- end:
- return ok;
+ return 1;
}
int X509_cmp_current_time(const ASN1_TIME *ctm)
@@ -1937,119 +1785,67 @@ int X509_cmp_current_time(const ASN1_TIME *ctm)
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
{
- char *str;
- ASN1_TIME atm;
- long offset;
- char buff1[24], buff2[24], *p;
- int i, j, remaining;
+ static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
+ static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
+ ASN1_TIME *asn1_cmp_time = NULL;
+ int i, day, sec, ret = 0;
- p = buff1;
- remaining = ctm->length;
- str = (char *)ctm->data;
/*
- * Note that the following (historical) code allows much more slack in the
- * time format than RFC5280. In RFC5280, the representation is fixed:
+ * Note that ASN.1 allows much more slack in the time format than RFC5280.
+ * In RFC5280, the representation is fixed:
* UTCTime: YYMMDDHHMMSSZ
* GeneralizedTime: YYYYMMDDHHMMSSZ
+ *
+ * We do NOT currently enforce the following RFC 5280 requirement:
+ * "CAs conforming to this profile MUST always encode certificate
+ * validity dates through the year 2049 as UTCTime; certificate validity
+ * dates in 2050 or later MUST be encoded as GeneralizedTime."
*/
- if (ctm->type == V_ASN1_UTCTIME) {
- /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
- int min_length = sizeof("YYMMDDHHMMZ") - 1;
- int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
- if (remaining < min_length || remaining > max_length)
+ switch (ctm->type) {
+ case V_ASN1_UTCTIME:
+ if (ctm->length != (int)(utctime_length))
return 0;
- memcpy(p, str, 10);
- p += 10;
- str += 10;
- remaining -= 10;
- } else {
- /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
- int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
- int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
- if (remaining < min_length || remaining > max_length)
+ break;
+ case V_ASN1_GENERALIZEDTIME:
+ if (ctm->length != (int)(generalizedtime_length))
return 0;
- memcpy(p, str, 12);
- p += 12;
- str += 12;
- remaining -= 12;
+ break;
+ default:
+ return 0;
}
- if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
- *(p++) = '0';
- *(p++) = '0';
- } else {
- /* SS (seconds) */
- if (remaining < 2)
+ /**
+ * Verify the format: the ASN.1 functions we use below allow a more
+ * flexible format than what's mandated by RFC 5280.
+ * Digit and date ranges will be verified in the conversion methods.
+ */
+ for (i = 0; i < ctm->length - 1; i++) {
+ if (!ossl_isdigit(ctm->data[i]))
return 0;
- *(p++) = *(str++);
- *(p++) = *(str++);
- remaining -= 2;
- /*
- * Skip any (up to three) fractional seconds...
- * TODO(emilia): in RFC5280, fractional seconds are forbidden.
- * Can we just kill them altogether?
- */
- if (remaining && *str == '.') {
- str++;
- remaining--;
- for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
- if (*str < '0' || *str > '9')
- break;
- }
- }
-
}
- *(p++) = 'Z';
- *(p++) = '\0';
-
- /* We now need either a terminating 'Z' or an offset. */
- if (!remaining)
+ if (ctm->data[ctm->length - 1] != 'Z')
return 0;
- if (*str == 'Z') {
- if (remaining != 1)
- return 0;
- offset = 0;
- } else {
- /* (+-)HHMM */
- if ((*str != '+') && (*str != '-'))
- return 0;
- /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
- if (remaining != 5)
- return 0;
- if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
- str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
- return 0;
- offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
- offset += (str[3] - '0') * 10 + (str[4] - '0');
- if (*str == '-')
- offset = -offset;
- }
- atm.type = ctm->type;
- atm.flags = 0;
- atm.length = sizeof(buff2);
- atm.data = (unsigned char *)buff2;
- if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
- return 0;
+ /*
+ * There is ASN1_UTCTIME_cmp_time_t but no
+ * ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t,
+ * so we go through ASN.1
+ */
+ asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time);
+ if (asn1_cmp_time == NULL)
+ goto err;
+ if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time))
+ goto err;
- 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;
+ /*
+ * X509_cmp_time comparison is <=.
+ * The return value 0 is reserved for errors.
+ */
+ ret = (day >= 0 && sec >= 0) ? -1 : 1;
+
+ err:
+ ASN1_TIME_free(asn1_cmp_time);
+ return ret;
}
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
@@ -2090,7 +1886,7 @@ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
return 1;
for (i = 0; i < sk_X509_num(chain); i++) {
- ktmp = X509_get_pubkey(sk_X509_value(chain, i));
+ ktmp = X509_get0_pubkey(sk_X509_value(chain, i));
if (ktmp == NULL) {
X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
@@ -2098,10 +1894,6 @@ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
}
if (!EVP_PKEY_missing_parameters(ktmp))
break;
- else {
- EVP_PKEY_free(ktmp);
- ktmp = NULL;
- }
}
if (ktmp == NULL) {
X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
@@ -2111,14 +1903,12 @@ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
/* first, populate the other certs */
for (j = i - 1; j >= 0; j--) {
- ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
+ ktmp2 = X509_get0_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;
}
@@ -2167,15 +1957,15 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
}
/* Create new CRL */
crl = X509_CRL_new();
- if (!crl || !X509_CRL_set_version(crl, 1))
+ if (crl == NULL || !X509_CRL_set_version(crl, 1))
goto memerr;
/* Set issuer name */
if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
goto memerr;
- if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
+ if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer)))
goto memerr;
- if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
+ if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer)))
goto memerr;
/* Set base CRL number: must be critical */
@@ -2206,7 +1996,7 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
* Add only if not also in base. TODO: need something cleverer here
* for some more complex CRLs covering multiple CAs.
*/
- if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
+ if (!X509_CRL_get0_by_serial(base, &rvtmp, &rvn->serialNumber)) {
rvtmp = X509_REVOKED_dup(rvn);
if (!rvtmp)
goto memerr;
@@ -2225,24 +2015,10 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
memerr:
X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE);
- if (crl)
- X509_CRL_free(crl);
+ X509_CRL_free(crl);
return NULL;
}
-int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func)
-{
- /*
- * This function is (usually) called only once, by
- * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
- */
- return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
- new_func, dup_func, free_func);
-}
-
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
{
return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
@@ -2268,12 +2044,22 @@ int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
return ctx->error_depth;
}
+void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth)
+{
+ ctx->error_depth = 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)
+void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x)
+{
+ ctx->current_cert = x;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
{
return ctx->chain;
}
@@ -2305,11 +2091,6 @@ 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;
@@ -2317,11 +2098,20 @@ void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
{
+ /*
+ * XXX: Why isn't this function always used to set the associated trust?
+ * Should there even be a VPM->trust field at all? Or should the trust
+ * always be inferred from the purpose by X509_STORE_CTX_init().
+ */
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
}
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
{
+ /*
+ * XXX: See above, this function would only be needed when the default
+ * trust for the purpose needs an override in a corner case.
+ */
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
}
@@ -2355,6 +2145,11 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
ptmp = X509_PURPOSE_get0(idx);
if (ptmp->trust == X509_TRUST_DEFAULT) {
idx = X509_PURPOSE_get_by_id(def_purpose);
+ /*
+ * XXX: In the two callers above def_purpose is always 0, which is
+ * not a known value, so idx will always be -1. How is the
+ * X509_TRUST_DEFAULT case actually supposed to be handled?
+ */
if (idx == -1) {
X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
X509_R_UNKNOWN_PURPOSE_ID);
@@ -2384,20 +2179,20 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
X509_STORE_CTX *X509_STORE_CTX_new(void)
{
- X509_STORE_CTX *ctx;
- ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
- if (!ctx) {
+ X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx == NULL) {
X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
- memset(ctx, 0, sizeof(X509_STORE_CTX));
return ctx;
}
void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
{
- if (!ctx)
+ if (ctx == NULL)
return;
+
X509_STORE_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
@@ -2406,12 +2201,12 @@ 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->num_untrusted = 0;
ctx->other_ctx = NULL;
ctx->valid = 0;
ctx->chain = NULL;
@@ -2425,39 +2220,17 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->current_reasons = 0;
ctx->tree = NULL;
ctx->parent = NULL;
+ ctx->dane = NULL;
+ ctx->bare_ta_signed = 0;
/* Zero ex_data to make sure we're cleanup-safe */
memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
- ctx->param = X509_VERIFY_PARAM_new();
- if (!ctx->param) {
- X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- /*
- * Inherit callbacks and flags from X509_STORE if not set use defaults.
- */
+ /* store->cleanup is always 0 in OpenSSL, if set must be idempotent */
if (store)
- ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
- else
- ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
-
- if (store) {
- ctx->verify_cb = store->verify_cb;
- /* Seems to always be 0 in OpenSSL, else must be idempotent */
ctx->cleanup = store->cleanup;
- } else
+ else
ctx->cleanup = 0;
- if (ret)
- ret = X509_VERIFY_PARAM_inherit(ctx->param,
- X509_VERIFY_PARAM_lookup("default"));
-
- if (ret == 0) {
- X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
if (store && store->check_issued)
ctx->check_issued = store->check_issued;
else
@@ -2498,17 +2271,55 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
else
ctx->cert_crl = cert_crl;
+ if (store && store->check_policy)
+ ctx->check_policy = store->check_policy;
+ else
+ ctx->check_policy = check_policy;
+
if (store && store->lookup_certs)
ctx->lookup_certs = store->lookup_certs;
else
- ctx->lookup_certs = X509_STORE_get1_certs;
+ ctx->lookup_certs = X509_STORE_CTX_get1_certs;
if (store && store->lookup_crls)
ctx->lookup_crls = store->lookup_crls;
else
- ctx->lookup_crls = X509_STORE_get1_crls;
+ ctx->lookup_crls = X509_STORE_CTX_get1_crls;
+
+ ctx->param = X509_VERIFY_PARAM_new();
+ if (ctx->param == NULL) {
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * Inherit callbacks and flags from X509_STORE if not set use defaults.
+ */
+ if (store)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+ else
+ ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
+
+ if (ret)
+ ret = X509_VERIFY_PARAM_inherit(ctx->param,
+ X509_VERIFY_PARAM_lookup("default"));
+
+ if (ret == 0) {
+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- ctx->check_policy = check_policy;
+ /*
+ * XXX: For now, continue to inherit trust from VPM, but infer from the
+ * purpose if this still yields the default value.
+ */
+ if (ctx->param->trust == X509_TRUST_DEFAULT) {
+ int idx = X509_PURPOSE_get_by_id(ctx->param->purpose);
+ X509_PURPOSE *xp = X509_PURPOSE_get0(idx);
+
+ if (xp != NULL)
+ ctx->param->trust = X509_PURPOSE_get_trust(xp);
+ }
if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
&ctx->ex_data))
@@ -2528,11 +2339,11 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
* 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)
+void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
{
ctx->other_ctx = sk;
ctx->get_issuer = get_issuer_sk;
+ ctx->lookup_certs = lookup_certs_sk;
}
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
@@ -2553,16 +2364,12 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
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;
- }
+ X509_policy_tree_free(ctx->tree);
+ ctx->tree = 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));
+ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
}
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
@@ -2581,12 +2388,99 @@ void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
X509_VERIFY_PARAM_set_time(ctx->param, t);
}
+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
+{
+ return ctx->cert;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
+{
+ return ctx->untrusted;
+}
+
+void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+ ctx->untrusted = sk;
+}
+
+void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+ sk_X509_pop_free(ctx->chain, X509_free);
+ ctx->chain = sk;
+}
+
void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
- int (*verify_cb) (int, X509_STORE_CTX *))
+ X509_STORE_CTX_verify_cb verify_cb)
{
ctx->verify_cb = verify_cb;
}
+X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx)
+{
+ return ctx->verify_cb;
+}
+
+void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx,
+ X509_STORE_CTX_verify_fn verify)
+{
+ ctx->verify = verify;
+}
+
+X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx)
+{
+ return ctx->verify;
+}
+
+X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx)
+{
+ return ctx->get_issuer;
+}
+
+X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx)
+{
+ return ctx->check_issued;
+}
+
+X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx)
+{
+ return ctx->check_revocation;
+}
+
+X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx)
+{
+ return ctx->get_crl;
+}
+
+X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx)
+{
+ return ctx->check_crl;
+}
+
+X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx)
+{
+ return ctx->cert_crl;
+}
+
+X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx)
+{
+ return ctx->check_policy;
+}
+
+X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx)
+{
+ return ctx->lookup_certs;
+}
+
+X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx)
+{
+ return ctx->lookup_crls;
+}
+
+X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx)
+{
+ return ctx->cleanup;
+}
+
X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
{
return ctx->tree;
@@ -2597,6 +2491,11 @@ int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
return ctx->explicit_policy;
}
+int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+{
+ return ctx->num_untrusted;
+}
+
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
{
const X509_VERIFY_PARAM *param;
@@ -2613,17 +2512,758 @@ 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)
{
- if (ctx->param)
- X509_VERIFY_PARAM_free(ctx->param);
+ X509_VERIFY_PARAM_free(ctx->param);
ctx->param = param;
}
-IMPLEMENT_STACK_OF(X509)
+void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane)
+{
+ ctx->dane = dane;
+}
+
+static unsigned char *dane_i2d(
+ X509 *cert,
+ uint8_t selector,
+ unsigned int *i2dlen)
+{
+ unsigned char *buf = NULL;
+ int len;
+
+ /*
+ * Extract ASN.1 DER form of certificate or public key.
+ */
+ switch (selector) {
+ case DANETLS_SELECTOR_CERT:
+ len = i2d_X509(cert, &buf);
+ break;
+ case DANETLS_SELECTOR_SPKI:
+ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf);
+ break;
+ default:
+ X509err(X509_F_DANE_I2D, X509_R_BAD_SELECTOR);
+ return NULL;
+ }
+
+ if (len < 0 || buf == NULL) {
+ X509err(X509_F_DANE_I2D, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ *i2dlen = (unsigned int)len;
+ return buf;
+}
+
+#define DANETLS_NONE 256 /* impossible uint8_t */
+
+static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth)
+{
+ SSL_DANE *dane = ctx->dane;
+ unsigned usage = DANETLS_NONE;
+ unsigned selector = DANETLS_NONE;
+ unsigned ordinal = DANETLS_NONE;
+ unsigned mtype = DANETLS_NONE;
+ unsigned char *i2dbuf = NULL;
+ unsigned int i2dlen = 0;
+ unsigned char mdbuf[EVP_MAX_MD_SIZE];
+ unsigned char *cmpbuf = NULL;
+ unsigned int cmplen = 0;
+ int i;
+ int recnum;
+ int matched = 0;
+ danetls_record *t = NULL;
+ uint32_t mask;
+
+ mask = (depth == 0) ? DANETLS_EE_MASK : DANETLS_TA_MASK;
+
+ /*
+ * The trust store is not applicable with DANE-TA(2)
+ */
+ if (depth >= ctx->num_untrusted)
+ mask &= DANETLS_PKIX_MASK;
+
+ /*
+ * If we've previously matched a PKIX-?? record, no need to test any
+ * further PKIX-?? records, it remains to just build the PKIX chain.
+ * Had the match been a DANE-?? record, we'd be done already.
+ */
+ if (dane->mdpth >= 0)
+ mask &= ~DANETLS_PKIX_MASK;
+
+ /*-
+ * https://tools.ietf.org/html/rfc7671#section-5.1
+ * https://tools.ietf.org/html/rfc7671#section-5.2
+ * https://tools.ietf.org/html/rfc7671#section-5.3
+ * https://tools.ietf.org/html/rfc7671#section-5.4
+ *
+ * We handle DANE-EE(3) records first as they require no chain building
+ * and no expiration or hostname checks. We also process digests with
+ * higher ordinals first and ignore lower priorities except Full(0) which
+ * is always processed (last). If none match, we then process PKIX-EE(1).
+ *
+ * NOTE: This relies on DANE usages sorting before the corresponding PKIX
+ * usages in SSL_dane_tlsa_add(), and also on descending sorting of digest
+ * priorities. See twin comment in ssl/ssl_lib.c.
+ *
+ * We expect that most TLSA RRsets will have just a single usage, so we
+ * don't go out of our way to cache multiple selector-specific i2d buffers
+ * across usages, but if the selector happens to remain the same as switch
+ * usages, that's OK. Thus, a set of "3 1 1", "3 0 1", "1 1 1", "1 0 1",
+ * records would result in us generating each of the certificate and public
+ * key DER forms twice, but more typically we'd just see multiple "3 1 1"
+ * or multiple "3 0 1" records.
+ *
+ * As soon as we find a match at any given depth, we stop, because either
+ * we've matched a DANE-?? record and the peer is authenticated, or, after
+ * exhausting all DANE-?? records, we've matched a PKIX-?? record, which is
+ * sufficient for DANE, and what remains to do is ordinary PKIX validation.
+ */
+ recnum = (dane->umask & mask) ? sk_danetls_record_num(dane->trecs) : 0;
+ for (i = 0; matched == 0 && i < recnum; ++i) {
+ t = sk_danetls_record_value(dane->trecs, i);
+ if ((DANETLS_USAGE_BIT(t->usage) & mask) == 0)
+ continue;
+ if (t->usage != usage) {
+ usage = t->usage;
+
+ /* Reset digest agility for each usage/selector pair */
+ mtype = DANETLS_NONE;
+ ordinal = dane->dctx->mdord[t->mtype];
+ }
+ if (t->selector != selector) {
+ selector = t->selector;
+
+ /* Update per-selector state */
+ OPENSSL_free(i2dbuf);
+ i2dbuf = dane_i2d(cert, selector, &i2dlen);
+ if (i2dbuf == NULL)
+ return -1;
+
+ /* Reset digest agility for each usage/selector pair */
+ mtype = DANETLS_NONE;
+ ordinal = dane->dctx->mdord[t->mtype];
+ } else if (t->mtype != DANETLS_MATCHING_FULL) {
+ /*-
+ * Digest agility:
+ *
+ * <https://tools.ietf.org/html/rfc7671#section-9>
+ *
+ * For a fixed selector, after processing all records with the
+ * highest mtype ordinal, ignore all mtypes with lower ordinals
+ * other than "Full".
+ */
+ if (dane->dctx->mdord[t->mtype] < ordinal)
+ continue;
+ }
+
+ /*
+ * Each time we hit a (new selector or) mtype, re-compute the relevant
+ * digest, more complex caching is not worth the code space.
+ */
+ if (t->mtype != mtype) {
+ const EVP_MD *md = dane->dctx->mdevp[mtype = t->mtype];
+ cmpbuf = i2dbuf;
+ cmplen = i2dlen;
+
+ if (md != NULL) {
+ cmpbuf = mdbuf;
+ if (!EVP_Digest(i2dbuf, i2dlen, cmpbuf, &cmplen, md, 0)) {
+ matched = -1;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Squirrel away the certificate and depth if we have a match. Any
+ * DANE match is dispositive, but with PKIX we still need to build a
+ * full chain.
+ */
+ if (cmplen == t->dlen &&
+ memcmp(cmpbuf, t->data, cmplen) == 0) {
+ if (DANETLS_USAGE_BIT(usage) & DANETLS_DANE_MASK)
+ matched = 1;
+ if (matched || dane->mdpth < 0) {
+ dane->mdpth = depth;
+ dane->mtlsa = t;
+ OPENSSL_free(dane->mcert);
+ dane->mcert = cert;
+ X509_up_ref(cert);
+ }
+ break;
+ }
+ }
+
+ /* Clear the one-element DER cache */
+ OPENSSL_free(i2dbuf);
+ return matched;
+}
+
+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth)
+{
+ SSL_DANE *dane = ctx->dane;
+ int matched = 0;
+ X509 *cert;
+
+ if (!DANETLS_HAS_TA(dane) || depth == 0)
+ return X509_TRUST_UNTRUSTED;
+
+ /*
+ * Record any DANE trust-anchor matches, for the first depth to test, if
+ * there's one at that depth. (This'll be false for length 1 chains looking
+ * for an exact match for the leaf certificate).
+ */
+ cert = sk_X509_value(ctx->chain, depth);
+ if (cert != NULL && (matched = dane_match(ctx, cert, depth)) < 0)
+ return X509_TRUST_REJECTED;
+ if (matched > 0) {
+ ctx->num_untrusted = depth - 1;
+ return X509_TRUST_TRUSTED;
+ }
+
+ return X509_TRUST_UNTRUSTED;
+}
+
+static int check_dane_pkeys(X509_STORE_CTX *ctx)
+{
+ SSL_DANE *dane = ctx->dane;
+ danetls_record *t;
+ int num = ctx->num_untrusted;
+ X509 *cert = sk_X509_value(ctx->chain, num - 1);
+ int recnum = sk_danetls_record_num(dane->trecs);
+ int i;
+
+ for (i = 0; i < recnum; ++i) {
+ t = sk_danetls_record_value(dane->trecs, i);
+ if (t->usage != DANETLS_USAGE_DANE_TA ||
+ t->selector != DANETLS_SELECTOR_SPKI ||
+ t->mtype != DANETLS_MATCHING_FULL ||
+ X509_verify(cert, t->spki) <= 0)
+ continue;
+
+ /* Clear any PKIX-?? matches that failed to extend to a full chain */
+ X509_free(dane->mcert);
+ dane->mcert = NULL;
+
+ /* Record match via a bare TA public key */
+ ctx->bare_ta_signed = 1;
+ dane->mdpth = num - 1;
+ dane->mtlsa = t;
+
+ /* Prune any excess chain certificates */
+ num = sk_X509_num(ctx->chain);
+ for (; num > ctx->num_untrusted; --num)
+ X509_free(sk_X509_pop(ctx->chain));
+
+ return X509_TRUST_TRUSTED;
+ }
+
+ return X509_TRUST_UNTRUSTED;
+}
+
+static void dane_reset(SSL_DANE *dane)
+{
+ /*
+ * Reset state to verify another chain, or clear after failure.
+ */
+ X509_free(dane->mcert);
+ dane->mcert = NULL;
+ dane->mtlsa = NULL;
+ dane->mdpth = -1;
+ dane->pdpth = -1;
+}
+
+static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert)
+{
+ int err = X509_chain_check_suiteb(NULL, cert, NULL, ctx->param->flags);
+
+ if (err == X509_V_OK)
+ return 1;
+ return verify_cb_cert(ctx, cert, 0, err);
+}
+
+static int dane_verify(X509_STORE_CTX *ctx)
+{
+ X509 *cert = ctx->cert;
+ SSL_DANE *dane = ctx->dane;
+ int matched;
+ int done;
+
+ dane_reset(dane);
+
+ /*-
+ * When testing the leaf certificate, if we match a DANE-EE(3) record,
+ * dane_match() returns 1 and we're done. If however we match a PKIX-EE(1)
+ * record, the match depth and matching TLSA record are recorded, but the
+ * return value is 0, because we still need to find a PKIX trust-anchor.
+ * Therefore, when DANE authentication is enabled (required), we're done
+ * if:
+ * + matched < 0, internal error.
+ * + matched == 1, we matched a DANE-EE(3) record
+ * + matched == 0, mdepth < 0 (no PKIX-EE match) and there are no
+ * DANE-TA(2) or PKIX-TA(0) to test.
+ */
+ matched = dane_match(ctx, ctx->cert, 0);
+ done = matched != 0 || (!DANETLS_HAS_TA(dane) && dane->mdpth < 0);
+
+ if (done)
+ X509_get_pubkey_parameters(NULL, ctx->chain);
+
+ if (matched > 0) {
+ /* Callback invoked as needed */
+ if (!check_leaf_suiteb(ctx, cert))
+ return 0;
+ /* Callback invoked as needed */
+ if ((dane->flags & DANE_FLAG_NO_DANE_EE_NAMECHECKS) == 0 &&
+ !check_id(ctx))
+ return 0;
+ /* Bypass internal_verify(), issue depth 0 success callback */
+ ctx->error_depth = 0;
+ ctx->current_cert = cert;
+ return ctx->verify_cb(1, ctx);
+ }
+
+ if (matched < 0) {
+ ctx->error_depth = 0;
+ ctx->current_cert = cert;
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return -1;
+ }
+
+ if (done) {
+ /* Fail early, TA-based success is not possible */
+ if (!check_leaf_suiteb(ctx, cert))
+ return 0;
+ return verify_cb_cert(ctx, cert, 0, X509_V_ERR_DANE_NO_MATCH);
+ }
+
+ /*
+ * Chain verification for usages 0/1/2. TLSA record matching of depth > 0
+ * certificates happens in-line with building the rest of the chain.
+ */
+ return verify_chain(ctx);
+}
+
+/* Get issuer, without duplicate suppression */
+static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert)
+{
+ STACK_OF(X509) *saved_chain = ctx->chain;
+ int ok;
+
+ ctx->chain = NULL;
+ ok = ctx->get_issuer(issuer, ctx, cert);
+ ctx->chain = saved_chain;
+
+ return ok;
+}
+
+static int build_chain(X509_STORE_CTX *ctx)
+{
+ SSL_DANE *dane = ctx->dane;
+ int num = sk_X509_num(ctx->chain);
+ X509 *cert = sk_X509_value(ctx->chain, num - 1);
+ int ss = cert_self_signed(cert);
+ STACK_OF(X509) *sktmp = NULL;
+ unsigned int search;
+ int may_trusted = 0;
+ int may_alternate = 0;
+ int trust = X509_TRUST_UNTRUSTED;
+ int alt_untrusted = 0;
+ int depth;
+ int ok = 0;
+ int i;
+
+ /* Our chain starts with a single untrusted element. */
+ if (!ossl_assert(num == 1 && ctx->num_untrusted == num)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ return 0;
+ }
+
+#define S_DOUNTRUSTED (1 << 0) /* Search untrusted chain */
+#define S_DOTRUSTED (1 << 1) /* Search trusted store */
+#define S_DOALTERNATE (1 << 2) /* Retry with pruned alternate chain */
+ /*
+ * Set up search policy, untrusted if possible, trusted-first if enabled.
+ * If we're doing DANE and not doing PKIX-TA/PKIX-EE, we never look in the
+ * trust_store, otherwise we might look there first. If not trusted-first,
+ * and alternate chains are not disabled, try building an alternate chain
+ * if no luck with untrusted first.
+ */
+ search = (ctx->untrusted != NULL) ? S_DOUNTRUSTED : 0;
+ if (DANETLS_HAS_PKIX(dane) || !DANETLS_HAS_DANE(dane)) {
+ if (search == 0 || ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+ search |= S_DOTRUSTED;
+ else if (!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS))
+ may_alternate = 1;
+ may_trusted = 1;
+ }
+
+ /*
+ * Shallow-copy the stack of untrusted certificates (with TLS, this is
+ * typically the content of the peer's certificate message) so can make
+ * multiple passes over it, while free to remove elements as we go.
+ */
+ if (ctx->untrusted && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
+
+ /*
+ * If we got any "DANE-TA(2) Cert(0) Full(0)" trust-anchors from DNS, add
+ * them to our working copy of the untrusted certificate stack. Since the
+ * caller of X509_STORE_CTX_init() may have provided only a leaf cert with
+ * no corresponding stack of untrusted certificates, we may need to create
+ * an empty stack first. [ At present only the ssl library provides DANE
+ * support, and ssl_verify_cert_chain() always provides a non-null stack
+ * containing at least the leaf certificate, but we must be prepared for
+ * this to change. ]
+ */
+ if (DANETLS_ENABLED(dane) && dane->certs != NULL) {
+ if (sktmp == NULL && (sktmp = sk_X509_new_null()) == NULL) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
+ for (i = 0; i < sk_X509_num(dane->certs); ++i) {
+ if (!sk_X509_push(sktmp, sk_X509_value(dane->certs, i))) {
+ sk_X509_free(sktmp);
+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * Still absurdly large, but arithmetically safe, a lower hard upper bound
+ * might be reasonable.
+ */
+ if (ctx->param->depth > INT_MAX/2)
+ ctx->param->depth = INT_MAX/2;
+
+ /*
+ * Try to Extend the chain until we reach an ultimately trusted issuer.
+ * Build chains up to one longer the limit, later fail if we hit the limit,
+ * with an X509_V_ERR_CERT_CHAIN_TOO_LONG error code.
+ */
+ depth = ctx->param->depth + 1;
+
+ while (search != 0) {
+ X509 *x;
+ X509 *xtmp = NULL;
-IMPLEMENT_ASN1_SET_OF(X509)
+ /*
+ * Look in the trust store if enabled for first lookup, or we've run
+ * out of untrusted issuers and search here is not disabled. When we
+ * reach the depth limit, we stop extending the chain, if by that point
+ * we've not found a trust-anchor, any trusted chain would be too long.
+ *
+ * The error reported to the application verify callback is at the
+ * maximal valid depth with the current certificate equal to the last
+ * not ultimately-trusted issuer. For example, with verify_depth = 0,
+ * the callback will report errors at depth=1 when the immediate issuer
+ * of the leaf certificate is not a trust anchor. No attempt will be
+ * made to locate an issuer for that certificate, since such a chain
+ * would be a-priori too long.
+ */
+ if ((search & S_DOTRUSTED) != 0) {
+ i = num = sk_X509_num(ctx->chain);
+ if ((search & S_DOALTERNATE) != 0) {
+ /*
+ * As high up the chain as we can, look for an alternative
+ * trusted issuer of an untrusted certificate that currently
+ * has an untrusted issuer. We use the alt_untrusted variable
+ * to track how far up the chain we find the first match. It
+ * is only if and when we find a match, that we prune the chain
+ * and reset ctx->num_untrusted to the reduced count of
+ * untrusted certificates. While we're searching for such a
+ * match (which may never be found), it is neither safe nor
+ * wise to preemptively modify either the chain or
+ * ctx->num_untrusted.
+ *
+ * Note, like ctx->num_untrusted, alt_untrusted is a count of
+ * untrusted certificates, not a "depth".
+ */
+ i = alt_untrusted;
+ }
+ x = sk_X509_value(ctx->chain, i-1);
-IMPLEMENT_STACK_OF(X509_NAME)
+ ok = (depth < num) ? 0 : get_issuer(&xtmp, ctx, x);
-IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
+ if (ok < 0) {
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_STORE_LOOKUP;
+ search = 0;
+ continue;
+ }
-IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
+ if (ok > 0) {
+ /*
+ * Alternative trusted issuer for a mid-chain untrusted cert?
+ * Pop the untrusted cert's successors and retry. We might now
+ * be able to complete a valid chain via the trust store. Note
+ * that despite the current trust-store match we might still
+ * fail complete the chain to a suitable trust-anchor, in which
+ * case we may prune some more untrusted certificates and try
+ * again. Thus the S_DOALTERNATE bit may yet be turned on
+ * again with an even shorter untrusted chain!
+ *
+ * If in the process we threw away our matching PKIX-TA trust
+ * anchor, reset DANE trust. We might find a suitable trusted
+ * certificate among the ones from the trust store.
+ */
+ if ((search & S_DOALTERNATE) != 0) {
+ if (!ossl_assert(num > i && i > 0 && ss == 0)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ X509_free(xtmp);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
+ search &= ~S_DOALTERNATE;
+ for (; num > i; --num)
+ X509_free(sk_X509_pop(ctx->chain));
+ ctx->num_untrusted = num;
+
+ if (DANETLS_ENABLED(dane) &&
+ dane->mdpth >= ctx->num_untrusted) {
+ dane->mdpth = -1;
+ X509_free(dane->mcert);
+ dane->mcert = NULL;
+ }
+ if (DANETLS_ENABLED(dane) &&
+ dane->pdpth >= ctx->num_untrusted)
+ dane->pdpth = -1;
+ }
+
+ /*
+ * Self-signed untrusted certificates get replaced by their
+ * trusted matching issuer. Otherwise, grow the chain.
+ */
+ if (ss == 0) {
+ if (!sk_X509_push(ctx->chain, x = xtmp)) {
+ X509_free(xtmp);
+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ search = 0;
+ continue;
+ }
+ ss = cert_self_signed(x);
+ } else if (num == ctx->num_untrusted) {
+ /*
+ * We have a self-signed certificate that has the same
+ * subject name (and perhaps keyid and/or serial number) as
+ * a trust-anchor. We must have an exact match to avoid
+ * possible impersonation via key substitution etc.
+ */
+ if (X509_cmp(x, xtmp) != 0) {
+ /* Self-signed untrusted mimic. */
+ X509_free(xtmp);
+ ok = 0;
+ } else {
+ X509_free(x);
+ ctx->num_untrusted = --num;
+ (void) sk_X509_set(ctx->chain, num, x = xtmp);
+ }
+ }
+
+ /*
+ * We've added a new trusted certificate to the chain, recheck
+ * trust. If not done, and not self-signed look deeper.
+ * Whether or not we're doing "trusted first", we no longer
+ * look for untrusted certificates from the peer's chain.
+ *
+ * At this point ctx->num_trusted and num must reflect the
+ * correct number of untrusted certificates, since the DANE
+ * logic in check_trust() depends on distinguishing CAs from
+ * "the wire" from CAs from the trust store. In particular, the
+ * certificate at depth "num" should be the new trusted
+ * certificate with ctx->num_untrusted <= num.
+ */
+ if (ok) {
+ if (!ossl_assert(ctx->num_untrusted <= num)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
+ search &= ~S_DOUNTRUSTED;
+ switch (trust = check_trust(ctx, num)) {
+ case X509_TRUST_TRUSTED:
+ case X509_TRUST_REJECTED:
+ search = 0;
+ continue;
+ }
+ if (ss == 0)
+ continue;
+ }
+ }
+
+ /*
+ * No dispositive decision, and either self-signed or no match, if
+ * we were doing untrusted-first, and alt-chains are not disabled,
+ * do that, by repeatedly losing one untrusted element at a time,
+ * and trying to extend the shorted chain.
+ */
+ if ((search & S_DOUNTRUSTED) == 0) {
+ /* Continue search for a trusted issuer of a shorter chain? */
+ if ((search & S_DOALTERNATE) != 0 && --alt_untrusted > 0)
+ continue;
+ /* Still no luck and no fallbacks left? */
+ if (!may_alternate || (search & S_DOALTERNATE) != 0 ||
+ ctx->num_untrusted < 2)
+ break;
+ /* Search for a trusted issuer of a shorter chain */
+ search |= S_DOALTERNATE;
+ alt_untrusted = ctx->num_untrusted - 1;
+ ss = 0;
+ }
+ }
+
+ /*
+ * Extend chain with peer-provided certificates
+ */
+ if ((search & S_DOUNTRUSTED) != 0) {
+ num = sk_X509_num(ctx->chain);
+ if (!ossl_assert(num == ctx->num_untrusted)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
+ x = sk_X509_value(ctx->chain, num-1);
+
+ /*
+ * Once we run out of untrusted issuers, we stop looking for more
+ * and start looking only in the trust store if enabled.
+ */
+ xtmp = (ss || depth < num) ? NULL : find_issuer(ctx, sktmp, x);
+ if (xtmp == NULL) {
+ search &= ~S_DOUNTRUSTED;
+ if (may_trusted)
+ search |= S_DOTRUSTED;
+ continue;
+ }
+
+ /* Drop this issuer from future consideration */
+ (void) sk_X509_delete_ptr(sktmp, xtmp);
+
+ if (!sk_X509_push(ctx->chain, xtmp)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ search = 0;
+ continue;
+ }
+
+ X509_up_ref(x = xtmp);
+ ++ctx->num_untrusted;
+ ss = cert_self_signed(xtmp);
+
+ /*
+ * Check for DANE-TA trust of the topmost untrusted certificate.
+ */
+ switch (trust = check_dane_issuer(ctx, ctx->num_untrusted - 1)) {
+ case X509_TRUST_TRUSTED:
+ case X509_TRUST_REJECTED:
+ search = 0;
+ continue;
+ }
+ }
+ }
+ sk_X509_free(sktmp);
+
+ /*
+ * Last chance to make a trusted chain, either bare DANE-TA public-key
+ * signers, or else direct leaf PKIX trust.
+ */
+ num = sk_X509_num(ctx->chain);
+ if (num <= depth) {
+ if (trust == X509_TRUST_UNTRUSTED && DANETLS_HAS_DANE_TA(dane))
+ trust = check_dane_pkeys(ctx);
+ if (trust == X509_TRUST_UNTRUSTED && num == ctx->num_untrusted)
+ trust = check_trust(ctx, num);
+ }
+
+ switch (trust) {
+ case X509_TRUST_TRUSTED:
+ return 1;
+ case X509_TRUST_REJECTED:
+ /* Callback already issued */
+ return 0;
+ case X509_TRUST_UNTRUSTED:
+ default:
+ num = sk_X509_num(ctx->chain);
+ if (num > depth)
+ return verify_cb_cert(ctx, NULL, num-1,
+ X509_V_ERR_CERT_CHAIN_TOO_LONG);
+ if (DANETLS_ENABLED(dane) &&
+ (!DANETLS_HAS_PKIX(dane) || dane->pdpth >= 0))
+ return verify_cb_cert(ctx, NULL, num-1, X509_V_ERR_DANE_NO_MATCH);
+ if (ss && sk_X509_num(ctx->chain) == 1)
+ return verify_cb_cert(ctx, NULL, num-1,
+ X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
+ if (ss)
+ return verify_cb_cert(ctx, NULL, num-1,
+ X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
+ if (ctx->num_untrusted < num)
+ return verify_cb_cert(ctx, NULL, num-1,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
+ return verify_cb_cert(ctx, NULL, num-1,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
+ }
+}
+
+static const int minbits_table[] = { 80, 112, 128, 192, 256 };
+static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table);
+
+/*
+ * Check whether the public key of ``cert`` meets the security level of
+ * ``ctx``.
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert)
+{
+ EVP_PKEY *pkey = X509_get0_pubkey(cert);
+ int level = ctx->param->auth_level;
+
+ /* Unsupported or malformed keys are not secure */
+ if (pkey == NULL)
+ return 0;
+
+ if (level <= 0)
+ return 1;
+ if (level > NUM_AUTH_LEVELS)
+ level = NUM_AUTH_LEVELS;
+
+ return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1];
+}
+
+/*
+ * Check whether the signature digest algorithm of ``cert`` meets the security
+ * level of ``ctx``. Should not be checked for trust anchors (whether
+ * self-signed or otherwise).
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert)
+{
+ int secbits = -1;
+ int level = ctx->param->auth_level;
+
+ if (level <= 0)
+ return 1;
+ if (level > NUM_AUTH_LEVELS)
+ level = NUM_AUTH_LEVELS;
+
+ if (!X509_get_signature_info(cert, NULL, NULL, &secbits, NULL))
+ return 0;
+
+ return secbits >= minbits_table[level - 1];
+}
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
deleted file mode 100644
index 50626826e0b9..000000000000
--- a/crypto/x509/x509_vfy.h
+++ /dev/null
@@ -1,652 +0,0 @@
-/* crypto/x509/x509_vfy.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef HEADER_X509_H
-# include <openssl/x509.h>
-/*
- * openssl/x509.h ends up #include-ing this file at about the only
- * appropriate moment.
- */
-#endif
-
-#ifndef HEADER_X509_VFY_H
-# define HEADER_X509_VFY_H
-
-# include <openssl/opensslconf.h>
-# ifndef OPENSSL_NO_LHASH
-# include <openssl/lhash.h>
-# endif
-# include <openssl/bio.h>
-# include <openssl/crypto.h>
-# include <openssl/symhacks.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-# if 0
-/* Outer object */
-typedef struct x509_hash_dir_st {
- int num_dirs;
- char **dirs;
- int *dirs_type;
- int num_dirs_alloced;
-} X509_HASH_DIR_CTX;
-# endif
-
-typedef struct x509_file_st {
- int num_paths; /* number of paths to files or directories */
- int num_alloced;
- char **paths; /* the list of paths or directories */
- int *path_type;
-} X509_CERT_FILE_CTX;
-
-/*******************************/
-/*-
-SSL_CTX -> X509_STORE
- -> X509_LOOKUP
- ->X509_LOOKUP_METHOD
- -> X509_LOOKUP
- ->X509_LOOKUP_METHOD
-
-SSL -> X509_STORE_CTX
- ->X509_STORE
-
-The X509_STORE holds the tables etc for verification stuff.
-A X509_STORE_CTX is used while validating a single certificate.
-The X509_STORE has X509_LOOKUPs for looking up certs.
-The X509_STORE then calls a function to actually verify the
-certificate chain.
-*/
-
-# define X509_LU_RETRY -1
-# define X509_LU_FAIL 0
-# define X509_LU_X509 1
-# define X509_LU_CRL 2
-# define X509_LU_PKEY 3
-
-typedef struct x509_object_st {
- /* one of the above types */
- int type;
- union {
- char *ptr;
- X509 *x509;
- X509_CRL *crl;
- EVP_PKEY *pkey;
- } data;
-} X509_OBJECT;
-
-typedef struct x509_lookup_st X509_LOOKUP;
-
-DECLARE_STACK_OF(X509_LOOKUP)
-DECLARE_STACK_OF(X509_OBJECT)
-
-/* This is a static that defines the function interface */
-typedef struct x509_lookup_method_st {
- const char *name;
- int (*new_item) (X509_LOOKUP *ctx);
- void (*free) (X509_LOOKUP *ctx);
- int (*init) (X509_LOOKUP *ctx);
- int (*shutdown) (X509_LOOKUP *ctx);
- int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
- char **ret);
- int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
- X509_OBJECT *ret);
- int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
- ASN1_INTEGER *serial, X509_OBJECT *ret);
- int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
- unsigned char *bytes, int len,
- X509_OBJECT *ret);
- int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
- X509_OBJECT *ret);
-} X509_LOOKUP_METHOD;
-
-typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID;
-
-/*
- * This structure hold all parameters associated with a verify operation by
- * including an X509_VERIFY_PARAM structure in related structures the
- * parameters used can be customized
- */
-
-typedef struct X509_VERIFY_PARAM_st {
- char *name;
- time_t check_time; /* Time to use */
- unsigned long inh_flags; /* Inheritance flags */
- unsigned long flags; /* Various verify flags */
- int purpose; /* purpose to check untrusted certificates */
- int trust; /* trust setting to check */
- int depth; /* Verify depth */
- STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
- X509_VERIFY_PARAM_ID *id; /* opaque ID data */
-} X509_VERIFY_PARAM;
-
-DECLARE_STACK_OF(X509_VERIFY_PARAM)
-
-/*
- * This is used to hold everything. It is used for all certificate
- * validation. Once we have a certificate chain, the 'verify' function is
- * then called to actually check the cert chain.
- */
-struct x509_store_st {
- /* The following is a cache of trusted certs */
- int cache; /* if true, stash any hits */
- STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
- /* These are external lookup methods */
- STACK_OF(X509_LOOKUP) *get_cert_methods;
- X509_VERIFY_PARAM *param;
- /* Callbacks for various operations */
- /* called to verify a certificate */
- int (*verify) (X509_STORE_CTX *ctx);
- /* error callback */
- int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
- /* get issuers cert from ctx */
- int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
- /* check issued */
- int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
- /* Check revocation status of chain */
- int (*check_revocation) (X509_STORE_CTX *ctx);
- /* retrieve CRL */
- int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
- /* Check CRL validity */
- int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
- /* Check certificate against CRL */
- int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
- STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
- STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
- int (*cleanup) (X509_STORE_CTX *ctx);
- CRYPTO_EX_DATA ex_data;
- int references;
-} /* X509_STORE */ ;
-
-int X509_STORE_set_depth(X509_STORE *store, int depth);
-
-# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
-# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func))
-
-/* This is the functions plus an instance of the local variables. */
-struct x509_lookup_st {
- int init; /* have we been started */
- int skip; /* don't use us. */
- X509_LOOKUP_METHOD *method; /* the functions */
- char *method_data; /* method data */
- X509_STORE *store_ctx; /* who owns us */
-} /* X509_LOOKUP */ ;
-
-/*
- * This is a used when verifying cert chains. Since the gathering of the
- * cert chain can take some time (and have to be 'retried', this needs to be
- * kept and passed around.
- */
-struct x509_store_ctx_st { /* X509_STORE_CTX */
- X509_STORE *ctx;
- /* used when looking up certs */
- int current_method;
- /* The following are set by the caller */
- /* The cert to check */
- X509 *cert;
- /* chain of X509s - untrusted - passed in */
- STACK_OF(X509) *untrusted;
- /* set of CRLs passed in */
- STACK_OF(X509_CRL) *crls;
- X509_VERIFY_PARAM *param;
- /* Other info for use with get_issuer() */
- void *other_ctx;
- /* Callbacks for various operations */
- /* called to verify a certificate */
- int (*verify) (X509_STORE_CTX *ctx);
- /* error callback */
- int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
- /* get issuers cert from ctx */
- int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
- /* check issued */
- int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
- /* Check revocation status of chain */
- int (*check_revocation) (X509_STORE_CTX *ctx);
- /* retrieve CRL */
- int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
- /* Check CRL validity */
- int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
- /* Check certificate against CRL */
- int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
- int (*check_policy) (X509_STORE_CTX *ctx);
- STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
- STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
- int (*cleanup) (X509_STORE_CTX *ctx);
- /* The following is built up */
- /* if 0, rebuild chain */
- int valid;
- /* index of last untrusted cert */
- int last_untrusted;
- /* chain of X509s - built up and trusted */
- STACK_OF(X509) *chain;
- /* Valid policy tree */
- X509_POLICY_TREE *tree;
- /* Require explicit policy value */
- int explicit_policy;
- /* When something goes wrong, this is why */
- int error_depth;
- int error;
- X509 *current_cert;
- /* cert currently being tested as valid issuer */
- X509 *current_issuer;
- /* current CRL */
- X509_CRL *current_crl;
- /* score of current CRL */
- int current_crl_score;
- /* Reason mask */
- unsigned int current_reasons;
- /* For CRL path validation: parent context */
- X509_STORE_CTX *parent;
- CRYPTO_EX_DATA ex_data;
-} /* X509_STORE_CTX */ ;
-
-void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
-
-# define X509_STORE_CTX_set_app_data(ctx,data) \
- X509_STORE_CTX_set_ex_data(ctx,0,data)
-# define X509_STORE_CTX_get_app_data(ctx) \
- X509_STORE_CTX_get_ex_data(ctx,0)
-
-# define X509_L_FILE_LOAD 1
-# define X509_L_ADD_DIR 2
-
-# define X509_LOOKUP_load_file(x,name,type) \
- X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
-
-# define X509_LOOKUP_add_dir(x,name,type) \
- X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
-
-# define X509_V_OK 0
-# define X509_V_ERR_UNSPECIFIED 1
-
-# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
-# define X509_V_ERR_UNABLE_TO_GET_CRL 3
-# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
-# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
-# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
-# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
-# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
-# define X509_V_ERR_CERT_NOT_YET_VALID 9
-# define X509_V_ERR_CERT_HAS_EXPIRED 10
-# define X509_V_ERR_CRL_NOT_YET_VALID 11
-# define X509_V_ERR_CRL_HAS_EXPIRED 12
-# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
-# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
-# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
-# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
-# define X509_V_ERR_OUT_OF_MEM 17
-# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
-# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
-# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
-# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
-# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
-# define X509_V_ERR_CERT_REVOKED 23
-# define X509_V_ERR_INVALID_CA 24
-# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
-# define X509_V_ERR_INVALID_PURPOSE 26
-# define X509_V_ERR_CERT_UNTRUSTED 27
-# define X509_V_ERR_CERT_REJECTED 28
-/* These are 'informational' when looking for issuer cert */
-# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
-# define X509_V_ERR_AKID_SKID_MISMATCH 30
-# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
-# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
-
-# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
-# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
-# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
-# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
-# define X509_V_ERR_INVALID_NON_CA 37
-# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
-# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
-# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
-
-# define X509_V_ERR_INVALID_EXTENSION 41
-# define X509_V_ERR_INVALID_POLICY_EXTENSION 42
-# define X509_V_ERR_NO_EXPLICIT_POLICY 43
-# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
-# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
-
-# define X509_V_ERR_UNNESTED_RESOURCE 46
-
-# define X509_V_ERR_PERMITTED_VIOLATION 47
-# define X509_V_ERR_EXCLUDED_VIOLATION 48
-# define X509_V_ERR_SUBTREE_MINMAX 49
-# define X509_V_ERR_APPLICATION_VERIFICATION 50
-# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
-# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
-# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
-# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
-
-/* Suite B mode algorithm violation */
-# define X509_V_ERR_SUITE_B_INVALID_VERSION 56
-# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
-# define X509_V_ERR_SUITE_B_INVALID_CURVE 58
-# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
-# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
-# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
-
-/* Host, email and IP check errors */
-# define X509_V_ERR_HOSTNAME_MISMATCH 62
-# define X509_V_ERR_EMAIL_MISMATCH 63
-# define X509_V_ERR_IP_ADDRESS_MISMATCH 64
-
-/* Caller error */
-# define X509_V_ERR_INVALID_CALL 65
-/* Issuer lookup error */
-# define X509_V_ERR_STORE_LOOKUP 66
-
-# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67
-
-/* Certificate verify flags */
-
-/* Send issuer+subject checks to verify_cb */
-# define X509_V_FLAG_CB_ISSUER_CHECK 0x1
-/* Use check time instead of current time */
-# define X509_V_FLAG_USE_CHECK_TIME 0x2
-/* Lookup CRLs */
-# define X509_V_FLAG_CRL_CHECK 0x4
-/* Lookup CRLs for whole chain */
-# define X509_V_FLAG_CRL_CHECK_ALL 0x8
-/* Ignore unhandled critical extensions */
-# define X509_V_FLAG_IGNORE_CRITICAL 0x10
-/* Disable workarounds for broken certificates */
-# define X509_V_FLAG_X509_STRICT 0x20
-/* Enable proxy certificate validation */
-# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40
-/* Enable policy checking */
-# define X509_V_FLAG_POLICY_CHECK 0x80
-/* Policy variable require-explicit-policy */
-# define X509_V_FLAG_EXPLICIT_POLICY 0x100
-/* Policy variable inhibit-any-policy */
-# define X509_V_FLAG_INHIBIT_ANY 0x200
-/* Policy variable inhibit-policy-mapping */
-# define X509_V_FLAG_INHIBIT_MAP 0x400
-/* Notify callback that policy is OK */
-# define X509_V_FLAG_NOTIFY_POLICY 0x800
-/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
-# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000
-/* Delta CRL support */
-# define X509_V_FLAG_USE_DELTAS 0x2000
-/* Check selfsigned CA signature */
-# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
-/* Use trusted store first */
-# define X509_V_FLAG_TRUSTED_FIRST 0x8000
-/* Suite B 128 bit only mode: not normally used */
-# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000
-/* Suite B 192 bit only mode */
-# define X509_V_FLAG_SUITEB_192_LOS 0x20000
-/* Suite B 128 bit mode allowing 192 bit algorithms */
-# define X509_V_FLAG_SUITEB_128_LOS 0x30000
-
-/* Allow partial chains if at least one certificate is in trusted store */
-# define X509_V_FLAG_PARTIAL_CHAIN 0x80000
-/*
- * If the initial chain is not trusted, do not attempt to build an alternative
- * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
- * will force the behaviour to match that of previous versions.
- */
-# define X509_V_FLAG_NO_ALT_CHAINS 0x100000
-
-# define X509_VP_FLAG_DEFAULT 0x1
-# define X509_VP_FLAG_OVERWRITE 0x2
-# define X509_VP_FLAG_RESET_FLAGS 0x4
-# define X509_VP_FLAG_LOCKED 0x8
-# define X509_VP_FLAG_ONCE 0x10
-
-/* Internal use: mask of policy related options */
-# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
- | X509_V_FLAG_EXPLICIT_POLICY \
- | X509_V_FLAG_INHIBIT_ANY \
- | X509_V_FLAG_INHIBIT_MAP)
-
-int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name);
-X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
- int type, X509_NAME *name);
-X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
- X509_OBJECT *x);
-void X509_OBJECT_up_ref_count(X509_OBJECT *a);
-void X509_OBJECT_free_contents(X509_OBJECT *a);
-X509_STORE *X509_STORE_new(void);
-void X509_STORE_free(X509_STORE *v);
-
-STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
-STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
-int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
-int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
-int X509_STORE_set_trust(X509_STORE *ctx, int trust);
-int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
-
-void X509_STORE_set_verify_cb(X509_STORE *ctx,
- int (*verify_cb) (int, X509_STORE_CTX *));
-
-void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
- STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
- *ctx,
- X509_NAME *nm));
-
-X509_STORE_CTX *X509_STORE_CTX_new(void);
-
-int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
-
-void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
-int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
- X509 *x509, STACK_OF(X509) *chain);
-void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
-void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
-
-X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
-
-X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
-
-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);
-X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
-X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
-X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
-STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
-STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
-void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
-void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
-void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
-int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
-int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
-int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
- int purpose, int trust);
-void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
-void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
- time_t t);
-void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
- int (*verify_cb) (int, X509_STORE_CTX *));
-
-X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
-int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
-
-X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
-void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
-int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
-
-/* X509_VERIFY_PARAM functions */
-
-X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
-void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
- const X509_VERIFY_PARAM *from);
-int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
- const X509_VERIFY_PARAM *from);
-int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
-int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
- unsigned long flags);
-int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
- unsigned long flags);
-unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
-int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
-void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
-void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
-int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
- ASN1_OBJECT *policy);
-int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
- STACK_OF(ASN1_OBJECT) *policies);
-
-int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
- const char *name, size_t namelen);
-int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
- const char *name, size_t namelen);
-void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
- unsigned int flags);
-char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
-int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
- const char *email, size_t emaillen);
-int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
- const unsigned char *ip, size_t iplen);
-int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
- const char *ipasc);
-
-int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
-const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
-
-int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
-int X509_VERIFY_PARAM_get_count(void);
-const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
-const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
-void X509_VERIFY_PARAM_table_cleanup(void);
-
-int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
- STACK_OF(X509) *certs,
- STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
-
-void X509_policy_tree_free(X509_POLICY_TREE *tree);
-
-int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
-X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
- int i);
-
-STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
- X509_POLICY_TREE
- *tree);
-
-STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
- X509_POLICY_TREE
- *tree);
-
-int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
-
-X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
- int i);
-
-const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
-
-STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
- X509_POLICY_NODE
- *node);
-const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
- *node);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 7d68a4abbc94..aea186295c2a 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -1,72 +1,22 @@
-/* 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).
+ * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
*
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/crypto.h>
-#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
-#include "vpm_int.h"
+#include "x509_lcl.h"
/* X509_VERIFY_PARAM functions */
@@ -83,9 +33,7 @@ static void str_free(char *s)
OPENSSL_free(s);
}
-#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free)
-
-static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
+static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode,
const char *name, size_t namelen)
{
char *copy;
@@ -101,28 +49,28 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
if (namelen > 0 && name[namelen - 1] == '\0')
--namelen;
- if (mode == SET_HOST && id->hosts) {
- string_stack_free(id->hosts);
- id->hosts = NULL;
+ if (mode == SET_HOST) {
+ sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
+ vpm->hosts = NULL;
}
if (name == NULL || namelen == 0)
return 1;
- copy = BUF_strndup(name, namelen);
+ copy = OPENSSL_strndup(name, namelen);
if (copy == NULL)
return 0;
- if (id->hosts == NULL &&
- (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
+ if (vpm->hosts == NULL &&
+ (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
OPENSSL_free(copy);
return 0;
}
- if (!sk_OPENSSL_STRING_push(id->hosts, copy)) {
+ if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
OPENSSL_free(copy);
- if (sk_OPENSSL_STRING_num(id->hosts) == 0) {
- sk_OPENSSL_STRING_free(id->hosts);
- id->hosts = NULL;
+ if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
+ sk_OPENSSL_STRING_free(vpm->hosts);
+ vpm->hosts = NULL;
}
return 0;
}
@@ -130,68 +78,20 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
return 1;
}
-static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
-{
- X509_VERIFY_PARAM_ID *paramid;
- if (!param)
- return;
- param->name = NULL;
- param->purpose = 0;
- param->trust = 0;
- /*
- * param->inh_flags = X509_VP_FLAG_DEFAULT;
- */
- param->inh_flags = 0;
- param->flags = 0;
- param->depth = -1;
- if (param->policies) {
- sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
- param->policies = NULL;
- }
- paramid = param->id;
- if (paramid->hosts) {
- string_stack_free(paramid->hosts);
- paramid->hosts = NULL;
- }
- if (paramid->peername)
- OPENSSL_free(paramid->peername);
- paramid->peername = NULL;
- if (paramid->email) {
- OPENSSL_free(paramid->email);
- paramid->email = NULL;
- paramid->emaillen = 0;
- }
- if (paramid->ip) {
- OPENSSL_free(paramid->ip);
- paramid->ip = NULL;
- paramid->iplen = 0;
- }
-}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
{
X509_VERIFY_PARAM *param;
- X509_VERIFY_PARAM_ID *paramid;
- param = OPENSSL_malloc(sizeof(*param));
- if (!param)
- return NULL;
- memset(param, 0, sizeof(*param));
-
- paramid = OPENSSL_malloc(sizeof(*paramid));
- if (!paramid) {
- OPENSSL_free(param);
+ param = OPENSSL_zalloc(sizeof(*param));
+ if (param == NULL) {
+ X509err(X509_F_X509_VERIFY_PARAM_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
- memset(paramid, 0, sizeof(*paramid));
- /* Exotic platforms may have non-zero bit representation of NULL */
- paramid->hosts = NULL;
- paramid->peername = NULL;
- paramid->email = NULL;
- paramid->ip = NULL;
-
- param->id = paramid;
- x509_verify_param_zero(param);
+ param->trust = X509_TRUST_DEFAULT;
+ /* param->inh_flags = X509_VP_FLAG_DEFAULT; */
+ param->depth = -1;
+ param->auth_level = -1; /* -1 means unset, 0 is explicit */
return param;
}
@@ -199,8 +99,11 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
{
if (param == NULL)
return;
- x509_verify_param_zero(param);
- OPENSSL_free(param->id);
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+ sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
+ OPENSSL_free(param->peername);
+ OPENSSL_free(param->email);
+ OPENSSL_free(param->ip);
OPENSSL_free(param);
}
@@ -242,11 +145,6 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
(to_overwrite || \
((src->field != def) && (to_default || (dest->field == def))))
-/* As above but for ID fields */
-
-#define test_x509_verify_param_copy_id(idf, def) \
- test_x509_verify_param_copy(id->idf, def)
-
/* Macro to test and copy a field if necessary */
#define x509_verify_param_copy(field, def) \
@@ -258,10 +156,8 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
{
unsigned long inh_flags;
int to_default, to_overwrite;
- X509_VERIFY_PARAM_ID *id;
if (!src)
return 1;
- id = src->id;
inh_flags = dest->inh_flags | src->inh_flags;
if (inh_flags & X509_VP_FLAG_ONCE)
@@ -281,8 +177,9 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
to_overwrite = 0;
x509_verify_param_copy(purpose, 0);
- x509_verify_param_copy(trust, 0);
+ x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
x509_verify_param_copy(depth, -1);
+ x509_verify_param_copy(auth_level, -1);
/* If overwrite or check time not set, copy across */
@@ -303,27 +200,25 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
}
/* Copy the host flags if and only if we're copying the host list */
- if (test_x509_verify_param_copy_id(hosts, NULL)) {
- if (dest->id->hosts) {
- string_stack_free(dest->id->hosts);
- dest->id->hosts = NULL;
- }
- if (id->hosts) {
- dest->id->hosts =
- sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free);
- if (dest->id->hosts == NULL)
+ if (test_x509_verify_param_copy(hosts, NULL)) {
+ sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
+ dest->hosts = NULL;
+ if (src->hosts) {
+ dest->hosts =
+ sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free);
+ if (dest->hosts == NULL)
return 0;
- dest->id->hostflags = id->hostflags;
+ dest->hostflags = src->hostflags;
}
}
- if (test_x509_verify_param_copy_id(email, NULL)) {
- if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen))
+ if (test_x509_verify_param_copy(email, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen))
return 0;
}
- if (test_x509_verify_param_copy_id(ip, NULL)) {
- if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen))
+ if (test_x509_verify_param_copy(ip, NULL)) {
+ if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
return 0;
}
@@ -346,30 +241,27 @@ static int int_x509_param_set1(char **pdest, size_t *pdestlen,
{
void *tmp;
if (src) {
- if (srclen == 0) {
- tmp = BUF_strdup(src);
+ if (srclen == 0)
srclen = strlen(src);
- } else
- tmp = BUF_memdup(src, srclen);
- if (!tmp)
+
+ tmp = OPENSSL_memdup(src, srclen);
+ if (tmp == NULL)
return 0;
} else {
tmp = NULL;
srclen = 0;
}
- if (*pdest)
- OPENSSL_free(*pdest);
+ OPENSSL_free(*pdest);
*pdest = tmp;
- if (pdestlen)
+ if (pdestlen != NULL)
*pdestlen = srclen;
return 1;
}
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
{
- if (param->name)
- OPENSSL_free(param->name);
- param->name = BUF_strdup(name);
+ OPENSSL_free(param->name);
+ param->name = OPENSSL_strdup(name);
if (param->name)
return 1;
return 0;
@@ -395,6 +287,17 @@ unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
return param->flags;
}
+uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param)
+{
+ return param->inh_flags;
+}
+
+int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags)
+{
+ param->inh_flags = flags;
+ return 1;
+}
+
int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
{
return X509_PURPOSE_set(&param->purpose, purpose);
@@ -410,6 +313,16 @@ void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
param->depth = depth;
}
+void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
+{
+ param->auth_level = auth_level;
+}
+
+time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
+{
+ return param->check_time;
+}
+
void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
{
param->check_time = t;
@@ -434,10 +347,10 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
{
int i;
ASN1_OBJECT *oid, *doid;
+
if (!param)
return 0;
- if (param->policies)
- sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
if (!policies) {
param->policies = NULL;
@@ -465,30 +378,53 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
- return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
+ return int_x509_param_set_hosts(param, SET_HOST, name, namelen);
}
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
- return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
+ return int_x509_param_set_hosts(param, ADD_HOST, name, namelen);
}
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
unsigned int flags)
{
- param->id->hostflags = flags;
+ param->hostflags = flags;
+}
+
+unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param)
+{
+ return param->hostflags;
}
char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
{
- return param->id->peername;
+ return param->peername;
+}
+
+/*
+ * Move peername from one param structure to another, freeing any name present
+ * at the target. If the source is a NULL parameter structure, free and zero
+ * the target peername.
+ */
+void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
+ X509_VERIFY_PARAM *from)
+{
+ char *peername = (from != NULL) ? from->peername : NULL;
+
+ if (to->peername != peername) {
+ OPENSSL_free(to->peername);
+ to->peername = peername;
+ }
+ if (from)
+ from->peername = NULL;
}
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
const char *email, size_t emaillen)
{
- return int_x509_param_set1(&param->id->email, &param->id->emaillen,
+ return int_x509_param_set1(&param->email, &param->emaillen,
email, emaillen);
}
@@ -497,7 +433,7 @@ int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
{
if (iplen != 0 && iplen != 4 && iplen != 16)
return 0;
- return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen,
+ return int_x509_param_set1((char **)&param->ip, &param->iplen,
(char *)ip, iplen);
}
@@ -517,14 +453,17 @@ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
return param->depth;
}
+int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param)
+{
+ return param->auth_level;
+}
+
const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
{
return param->name;
}
-static X509_VERIFY_PARAM_ID _empty_id = { NULL, 0U, NULL, NULL, 0, NULL, 0 };
-
-#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
+#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0
/*
* Default verify parameters: these are used for various applications and can
@@ -537,10 +476,11 @@ static const X509_VERIFY_PARAM default_table[] = {
"default", /* X509 default parameters */
0, /* Check time */
0, /* internal flags */
- 0, /* flags */
+ X509_V_FLAG_TRUSTED_FIRST, /* flags */
0, /* purpose */
0, /* trust */
100, /* depth */
+ -1, /* auth_level */
NULL, /* policies */
vpm_empty_id},
{
@@ -551,6 +491,7 @@ static const X509_VERIFY_PARAM default_table[] = {
X509_PURPOSE_SMIME_SIGN, /* purpose */
X509_TRUST_EMAIL, /* trust */
-1, /* depth */
+ -1, /* auth_level */
NULL, /* policies */
vpm_empty_id},
{
@@ -561,6 +502,7 @@ static const X509_VERIFY_PARAM default_table[] = {
X509_PURPOSE_SMIME_SIGN, /* purpose */
X509_TRUST_EMAIL, /* trust */
-1, /* depth */
+ -1, /* auth_level */
NULL, /* policies */
vpm_empty_id},
{
@@ -571,6 +513,7 @@ static const X509_VERIFY_PARAM default_table[] = {
X509_PURPOSE_SSL_CLIENT, /* purpose */
X509_TRUST_SSL_CLIENT, /* trust */
-1, /* depth */
+ -1, /* auth_level */
NULL, /* policies */
vpm_empty_id},
{
@@ -581,6 +524,7 @@ static const X509_VERIFY_PARAM default_table[] = {
X509_PURPOSE_SSL_SERVER, /* purpose */
X509_TRUST_SSL_SERVER, /* trust */
-1, /* depth */
+ -1, /* auth_level */
NULL, /* policies */
vpm_empty_id}
};
@@ -605,16 +549,15 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
{
int idx;
X509_VERIFY_PARAM *ptmp;
- if (!param_table) {
+ if (param_table == NULL) {
param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
- if (!param_table)
+ if (param_table == NULL)
return 0;
} else {
idx = sk_X509_VERIFY_PARAM_find(param_table, param);
- if (idx != -1) {
- ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+ if (idx >= 0) {
+ ptmp = sk_X509_VERIFY_PARAM_delete(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))
@@ -624,7 +567,7 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
int X509_VERIFY_PARAM_get_count(void)
{
- int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ int num = OSSL_NELEM(default_table);
if (param_table)
num += sk_X509_VERIFY_PARAM_num(param_table);
return num;
@@ -632,7 +575,7 @@ int X509_VERIFY_PARAM_get_count(void)
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
{
- int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
+ int num = OSSL_NELEM(default_table);
if (id < num)
return default_table + id;
return sk_X509_VERIFY_PARAM_value(param_table, id - num);
@@ -644,19 +587,16 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
X509_VERIFY_PARAM pm;
pm.name = (char *)name;
- if (param_table) {
+ if (param_table != NULL) {
idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
- if (idx != -1)
+ if (idx >= 0)
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
- return OBJ_bsearch_table(&pm, default_table,
- sizeof(default_table) /
- sizeof(X509_VERIFY_PARAM));
+ return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
}
void X509_VERIFY_PARAM_table_cleanup(void)
{
- if (param_table)
- sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
+ sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
param_table = NULL;
}
diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c
index 24ca35b58b58..7645ce375970 100644
--- a/crypto/x509/x509cset.c
+++ b/crypto/x509/x509cset.c
@@ -1,119 +1,51 @@
-/* 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).
+ * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
*
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include "internal/x509_int.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 0;
+ if (x->crl.version == NULL) {
+ if ((x->crl.version = ASN1_INTEGER_new()) == NULL)
+ return 0;
}
- return (ASN1_INTEGER_set(x->crl->version, version));
+ 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));
+ if (x == NULL)
+ return 0;
+ return X509_NAME_set(&x->crl.issuer, name);
}
-int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
+int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
{
- ASN1_TIME *in;
-
if (x == NULL)
- return (0);
- in = x->crl->lastUpdate;
- if (in != tm) {
- in = M_ASN1_TIME_dup(tm);
- if (in != NULL) {
- M_ASN1_TIME_free(x->crl->lastUpdate);
- x->crl->lastUpdate = in;
- }
- }
- return (in != NULL);
+ return 0;
+ return x509_set1_time(&x->crl.lastUpdate, tm);
}
-int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
+int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
{
- ASN1_TIME *in;
-
if (x == NULL)
- return (0);
- in = x->crl->nextUpdate;
- if (in != tm) {
- in = M_ASN1_TIME_dup(tm);
- if (in != NULL) {
- M_ASN1_TIME_free(x->crl->nextUpdate);
- x->crl->nextUpdate = in;
- }
- }
- return (in != NULL);
+ return 0;
+ return x509_set1_time(&x->crl.nextUpdate, tm);
}
int X509_CRL_sort(X509_CRL *c)
@@ -123,45 +55,129 @@ int X509_CRL_sort(X509_CRL *c)
/*
* 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);
+ 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;
+ c->crl.enc.modified = 1;
return 1;
}
+int X509_CRL_up_ref(X509_CRL *crl)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&crl->references, &i, crl->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("X509_CRL", crl);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+long X509_CRL_get_version(const X509_CRL *crl)
+{
+ return ASN1_INTEGER_get(crl->crl.version);
+}
+
+const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl)
+{
+ return crl->crl.lastUpdate;
+}
+
+const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl)
+{
+ return crl->crl.nextUpdate;
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)
+{
+ return crl->crl.lastUpdate;
+}
+
+ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)
+{
+ return crl->crl.nextUpdate;
+}
+#endif
+
+X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl)
+{
+ return crl->crl.issuer;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl)
+{
+ return crl->crl.extensions;
+}
+
+STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl)
+{
+ return crl->crl.revoked;
+}
+
+void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
+ const X509_ALGOR **palg)
+{
+ if (psig != NULL)
+ *psig = &crl->signature;
+ if (palg != NULL)
+ *palg = &crl->sig_alg;
+}
+
+int X509_CRL_get_signature_nid(const X509_CRL *crl)
+{
+ return OBJ_obj2nid(crl->sig_alg.algorithm);
+}
+
+const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x)
+{
+ return x->revocationDate;
+}
+
int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if (x == NULL)
- return (0);
+ return 0;
in = x->revocationDate;
if (in != tm) {
- in = M_ASN1_TIME_dup(tm);
+ in = ASN1_STRING_dup(tm);
if (in != NULL) {
- M_ASN1_TIME_free(x->revocationDate);
+ ASN1_TIME_free(x->revocationDate);
x->revocationDate = in;
}
}
return (in != NULL);
}
+const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x)
+{
+ return &x->serialNumber;
+}
+
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);
+ return 0;
+ in = &x->serialNumber;
+ if (in != serial)
+ return ASN1_STRING_copy(in, serial);
+ return 1;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r)
+{
+ return r->extensions;
+}
+
+int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp)
+{
+ crl->crl.enc.modified = 1;
+ return i2d_X509_CRL_INFO(&crl->crl, pp);
}
diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c
index 6ea601f96228..64a73e793fdf 100644
--- a/crypto/x509/x509name.c
+++ b/crypto/x509/x509name.c
@@ -1,68 +1,20 @@
-/* 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.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <openssl/stack.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
+#include <openssl/safestack.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
{
@@ -70,33 +22,35 @@ int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
obj = OBJ_nid2obj(nid);
if (obj == NULL)
- return (-1);
- return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
+ 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 X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+ char *buf, int len)
{
int i;
- ASN1_STRING *data;
+ const ASN1_STRING *data;
i = X509_NAME_get_index_by_OBJ(name, obj, -1);
if (i < 0)
- return (-1);
+ 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);
+ return data->length;
+ if (len <= 0)
+ return 0;
+ i = (data->length > (len - 1)) ? (len - 1) : data->length;
memcpy(buf, data->data, i);
buf[i] = '\0';
- return (i);
+ return i;
}
-int X509_NAME_entry_count(X509_NAME *name)
+int X509_NAME_entry_count(const X509_NAME *name)
{
if (name == NULL)
- return (0);
- return (sk_X509_NAME_ENTRY_num(name->entries));
+ return 0;
+ return sk_X509_NAME_ENTRY_num(name->entries);
}
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
@@ -105,19 +59,19 @@ int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
obj = OBJ_nid2obj(nid);
if (obj == NULL)
- return (-2);
- return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
+ 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)
+/* NOTE: you should be passing -1, not 0 as lastpos */
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_NAME_ENTRY *ne;
STACK_OF(X509_NAME_ENTRY) *sk;
if (name == NULL)
- return (-1);
+ return -1;
if (lastpos < 0)
lastpos = -1;
sk = name->entries;
@@ -125,18 +79,18 @@ int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos)
for (lastpos++; lastpos < n; lastpos++) {
ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
if (OBJ_cmp(ne->object, obj) == 0)
- return (lastpos);
+ return lastpos;
}
- return (-1);
+ return -1;
}
-X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
+X509_NAME_ENTRY *X509_NAME_get_entry(const 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));
+ return NULL;
+
+ return sk_X509_NAME_ENTRY_value(name->entries, loc);
}
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
@@ -147,13 +101,14 @@ X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
|| loc < 0)
- return (NULL);
+ 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);
+ return ret;
/* else we need to fixup the set field */
if (loc != 0)
@@ -175,15 +130,16 @@ X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
if (set_prev + 1 < set_next)
for (i = loc; i < n; i++)
sk_X509_NAME_ENTRY_value(sk, i)->set--;
- return (ret);
+ 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 X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
+ const 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;
@@ -193,7 +149,7 @@ int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
}
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
- unsigned char *bytes, int len, int loc,
+ const unsigned char *bytes, int len, int loc,
int set)
{
X509_NAME_ENTRY *ne;
@@ -224,7 +180,7 @@ int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
* 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 X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc,
int set)
{
X509_NAME_ENTRY *new_name = NULL;
@@ -232,14 +188,14 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
STACK_OF(X509_NAME_ENTRY) *sk;
if (name == NULL)
- return (0);
+ return 0;
sk = name->entries;
n = sk_X509_NAME_ENTRY_num(sk);
if (loc > n)
loc = n;
else if (loc < 0)
loc = n;
-
+ inc = (set == 0);
name->modified = 1;
if (set == -1) {
@@ -248,7 +204,6 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
inc = 1;
} else {
set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
- inc = 0;
}
} else { /* if (set >= 0) */
@@ -259,10 +214,13 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
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)
+ /*
+ * X509_NAME_ENTRY_dup is ASN1 generated code, that can't be easily
+ * const'ified; harmless cast since dup() don't modify its input.
+ */
+ if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL)
goto err;
new_name->set = set;
if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
@@ -272,13 +230,12 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
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;
+ sk_X509_NAME_ENTRY_value(sk, i)->set += 1;
}
- return (1);
+ return 1;
err:
- if (new_name != NULL)
- X509_NAME_ENTRY_free(new_name);
- return (0);
+ X509_NAME_ENTRY_free(new_name);
+ return 0;
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
@@ -294,7 +251,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", field);
- return (NULL);
+ return NULL;
}
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
@@ -302,7 +259,8 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
- int type, unsigned char *bytes,
+ int type,
+ const unsigned char *bytes,
int len)
{
ASN1_OBJECT *obj;
@@ -311,7 +269,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID);
- return (NULL);
+ return NULL;
}
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
@@ -319,7 +277,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
- ASN1_OBJECT *obj, int type,
+ const ASN1_OBJECT *obj, int type,
const unsigned char *bytes,
int len)
{
@@ -327,7 +285,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
if ((ne == NULL) || (*ne == NULL)) {
if ((ret = X509_NAME_ENTRY_new()) == NULL)
- return (NULL);
+ return NULL;
} else
ret = *ne;
@@ -338,19 +296,19 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
if ((ne != NULL) && (*ne == NULL))
*ne = ret;
- return (ret);
+ return ret;
err:
if ((ne == NULL) || (ret != *ne))
X509_NAME_ENTRY_free(ret);
- return (NULL);
+ return NULL;
}
-int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
{
if ((ne == NULL) || (obj == NULL)) {
X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,
ERR_R_PASSED_NULL_PARAMETER);
- return (0);
+ return 0;
}
ASN1_OBJECT_free(ne->object);
ne->object = OBJ_dup(obj);
@@ -363,7 +321,7 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
int i;
if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
- return (0);
+ return 0;
if ((type > 0) && (type & MBSTRING_FLAG))
return ASN1_STRING_set_by_NID(&ne->value, bytes,
len, type,
@@ -372,26 +330,31 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
len = strlen((const char *)bytes);
i = ASN1_STRING_set(ne->value, bytes, len);
if (!i)
- return (0);
+ 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);
+ return 1;
}
-ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
{
if (ne == NULL)
- return (NULL);
- return (ne->object);
+ return NULL;
+ return ne->object;
}
-ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
+ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
{
if (ne == NULL)
- return (NULL);
- return (ne->value);
+ return NULL;
+ return ne->value;
+}
+
+int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
+{
+ return ne->set;
}
diff --git a/crypto/x509/x509rset.c b/crypto/x509/x509rset.c
index 80e273e64292..e8921b82a838 100644
--- a/crypto/x509/x509rset.c
+++ b/crypto/x509/x509rset.c
@@ -1,85 +1,40 @@
-/* crypto/x509/x509rset.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include "internal/x509_int.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));
+ return 0;
+ x->req_info.enc.modified = 1;
+ 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));
+ if (x == NULL)
+ return 0;
+ x->req_info.enc.modified = 1;
+ 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));
+ if (x == NULL)
+ return 0;
+ x->req_info.enc.modified = 1;
+ return X509_PUBKEY_set(&x->req_info.pubkey, pkey);
}
diff --git a/crypto/x509/x509spki.c b/crypto/x509/x509spki.c
index 5ae5d30a3516..fd8162af6df2 100644
--- a/crypto/x509/x509spki.c
+++ b/crypto/x509/x509spki.c
@@ -1,78 +1,28 @@
-/* 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).
+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
*
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/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));
+ 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));
+ return NULL;
+ return X509_PUBKEY_get(x->spkac->pubkey);
}
/* Load a Netscape SPKI from a base64 encoded string */
@@ -85,7 +35,7 @@ NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
NETSCAPE_SPKI *spki;
if (len <= 0)
len = strlen(str);
- if (!(spki_der = OPENSSL_malloc(len + 1))) {
+ if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) {
X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -111,10 +61,10 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
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) {
+ if (der_spki == NULL || b64_str == NULL) {
+ X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
OPENSSL_free(der_spki);
OPENSSL_free(b64_str);
- X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
return NULL;
}
p = der_spki;
diff --git a/crypto/x509/x509type.c b/crypto/x509/x509type.c
index 9219f753bf93..0e33b424be51 100644
--- a/crypto/x509/x509type.c
+++ b/crypto/x509/x509type.c
@@ -1,107 +1,66 @@
-/* crypto/x509/x509type.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
-int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
+int X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
{
- EVP_PKEY *pk;
+ const EVP_PKEY *pk;
int ret = 0, i;
if (x == NULL)
- return (0);
+ return 0;
if (pkey == NULL)
- pk = X509_get_pubkey(x);
+ pk = X509_get0_pubkey(x);
else
pk = pkey;
if (pk == NULL)
- return (0);
+ return 0;
- switch (pk->type) {
+ switch (EVP_PKEY_id(pk)) {
case EVP_PKEY_RSA:
ret = EVP_PK_RSA | EVP_PKT_SIGN;
/* if (!sign only extension) */
ret |= EVP_PKT_ENC;
break;
+ case EVP_PKEY_RSA_PSS:
+ ret = EVP_PK_RSA | EVP_PKT_SIGN;
+ 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_ED448:
+ case EVP_PKEY_ED25519:
+ ret = EVP_PKT_SIGN;
+ break;
case EVP_PKEY_DH:
ret = EVP_PK_DH | EVP_PKT_EXCH;
break;
- case NID_id_GostR3410_94:
case NID_id_GostR3410_2001:
+ case NID_id_GostR3410_2012_256:
+ case NID_id_GostR3410_2012_512:
ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
break;
default:
break;
}
- i = OBJ_obj2nid(x->sig_alg->algorithm);
+ i = X509_get_signature_nid(x);
if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
switch (i) {
@@ -121,7 +80,5 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
}
}
- if (pkey == NULL)
- EVP_PKEY_free(pk);
- return (ret);
+ return ret;
}
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 0f26c546d835..24e4114601ca 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -1,159 +1,112 @@
-/* crypto/x509/x_all.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
#include <stdio.h>
-#include <openssl/stack.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include "internal/x509_int.h"
#include <openssl/ocsp.h>
-#ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-# include <openssl/dsa.h>
-#endif
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/x509v3.h>
int X509_verify(X509 *a, EVP_PKEY *r)
{
- if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
+ if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
return 0;
- return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg,
- a->signature, a->cert_info, r));
+ 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));
+ &a->sig_alg, a->signature, &a->req_info, r));
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
{
return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
- a->sig_algor, a->signature, a->spkac, r));
+ &a->sig_algor, a->signature, a->spkac, r));
}
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
- x->cert_info->enc.modified = 1;
- return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
- x->sig_alg, x->signature, x->cert_info, pkey, md));
+ x->cert_info.enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature,
+ &x->sig_alg, &x->signature, &x->cert_info, pkey,
+ md));
}
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
{
- x->cert_info->enc.modified = 1;
+ x->cert_info.enc.modified = 1;
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
- x->cert_info->signature,
- x->sig_alg, x->signature, x->cert_info, ctx);
+ &x->cert_info.signature,
+ &x->sig_alg, &x->signature, &x->cert_info, ctx);
}
+#ifndef OPENSSL_NO_OCSP
int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert)
{
return OCSP_REQ_CTX_nbio_d2i(rctx,
(ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509));
}
+#endif
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));
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL,
+ x->signature, &x->req_info, pkey, md));
}
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
{
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
- x->sig_alg, NULL, x->signature, x->req_info,
+ &x->sig_alg, NULL, x->signature, &x->req_info,
ctx);
}
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
{
- x->crl->enc.modified = 1;
- return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
- x->sig_alg, x->signature, x->crl, pkey, md));
+ x->crl.enc.modified = 1;
+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg,
+ &x->sig_alg, &x->signature, &x->crl, pkey, md));
}
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
{
- x->crl->enc.modified = 1;
+ x->crl.enc.modified = 1;
return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
- x->crl->sig_alg, x->sig_alg, x->signature,
- x->crl, ctx);
+ &x->crl.sig_alg, &x->sig_alg, &x->signature,
+ &x->crl, ctx);
}
+#ifndef OPENSSL_NO_OCSP
int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl)
{
return OCSP_REQ_CTX_nbio_d2i(rctx,
(ASN1_VALUE **)pcrl,
ASN1_ITEM_rptr(X509_CRL));
}
+#endif
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,
+ return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), &x->sig_algor, NULL,
x->signature, x->spkac, pkey, md));
}
-#ifndef OPENSSL_NO_FP_API
+#ifndef OPENSSL_NO_STDIO
X509 *d2i_X509_fp(FILE *fp, X509 **x509)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
@@ -175,7 +128,7 @@ int i2d_X509_bio(BIO *bp, X509 *x509)
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
}
-#ifndef OPENSSL_NO_FP_API
+#ifndef OPENSSL_NO_STDIO
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
@@ -197,7 +150,7 @@ 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
+#ifndef OPENSSL_NO_STDIO
PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
@@ -219,7 +172,7 @@ int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
}
-#ifndef OPENSSL_NO_FP_API
+#ifndef OPENSSL_NO_STDIO
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
@@ -243,7 +196,7 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
#ifndef OPENSSL_NO_RSA
-# ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_STDIO
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
@@ -309,7 +262,7 @@ int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
#endif
#ifndef OPENSSL_NO_DSA
-# ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_STDIO
DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
@@ -354,7 +307,7 @@ int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
#endif
#ifndef OPENSSL_NO_EC
-# ifndef OPENSSL_NO_FP_API
+# ifndef OPENSSL_NO_STDIO
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);
@@ -409,6 +362,13 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
unsigned int *len)
{
+ if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0) {
+ /* Asking for SHA1 and we already computed it. */
+ if (len != NULL)
+ *len = sizeof(data->sha1_hash);
+ memcpy(md, data->sha1_hash, sizeof(data->sha1_hash));
+ return 1;
+ }
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
}
@@ -416,6 +376,13 @@ int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
{
+ if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0) {
+ /* Asking for SHA1; always computed in CRL d2i. */
+ if (len != NULL)
+ *len = sizeof(data->sha1_hash);
+ memcpy(md, data->sha1_hash, sizeof(data->sha1_hash));
+ return 1;
+ }
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
}
@@ -442,7 +409,7 @@ int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
(char *)data, md, len));
}
-#ifndef OPENSSL_NO_FP_API
+#ifndef OPENSSL_NO_STDIO
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);
@@ -464,7 +431,7 @@ 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
+#ifndef OPENSSL_NO_STDIO
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
PKCS8_PRIV_KEY_INFO **p8inf)
{
diff --git a/crypto/x509/x_attrib.c b/crypto/x509/x_attrib.c
new file mode 100644
index 000000000000..9a41e547cb2e
--- /dev/null
+++ b/crypto/x509/x_attrib.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "x509_lcl.h"
+
+/*-
+ * X509_ATTRIBUTE: this has the following form:
+ *
+ * typedef struct x509_attributes_st
+ * {
+ * ASN1_OBJECT *object;
+ * STACK_OF(ASN1_TYPE) *set;
+ * } X509_ATTRIBUTE;
+ *
+ */
+
+ASN1_SEQUENCE(X509_ATTRIBUTE) = {
+ ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+ ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
+{
+ X509_ATTRIBUTE *ret = NULL;
+ ASN1_TYPE *val = NULL;
+
+ if ((ret = X509_ATTRIBUTE_new()) == NULL)
+ return NULL;
+ ret->object = OBJ_nid2obj(nid);
+ if ((val = ASN1_TYPE_new()) == NULL)
+ goto err;
+ if (!sk_ASN1_TYPE_push(ret->set, val))
+ goto err;
+
+ ASN1_TYPE_set(val, atrtype, value);
+ return ret;
+ err:
+ X509_ATTRIBUTE_free(ret);
+ ASN1_TYPE_free(val);
+ return NULL;
+}
diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c
new file mode 100644
index 000000000000..10733b58bca2
--- /dev/null
+++ b/crypto/x509/x_crl.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+#include "x509_lcl.h"
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+ const X509_REVOKED *const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
+
+ASN1_SEQUENCE(X509_REVOKED) = {
+ ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
+} ASN1_SEQUENCE_END(X509_REVOKED)
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth = {
+ 0,
+ 0, 0,
+ def_crl_lookup,
+ def_crl_verify
+};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
+/*
+ * The X509_CRL_INFO structure needs a bit of customisation. Since we cache
+ * the original encoding the signature won't be affected by reordering of the
+ * revoked field.
+ */
+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+ if (!a || !a->revoked)
+ return 1;
+ switch (operation) {
+ /*
+ * Just set cmp function here. We don't sort because that would
+ * affect the output of X509_CRL_print().
+ */
+ case ASN1_OP_D2I_POST:
+ (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+ break;
+ }
+ return 1;
+}
+
+
+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
+ ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+ ASN1_EMBED(X509_CRL_INFO, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+ ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+ ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+ ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
+
+/*
+ * Set CRL entry issuer according to CRL certificate issuer extension. Check
+ * for unhandled critical CRL entry extensions.
+ */
+
+static int crl_set_issuers(X509_CRL *crl)
+{
+
+ int i, j;
+ GENERAL_NAMES *gens, *gtmp;
+ STACK_OF(X509_REVOKED) *revoked;
+
+ revoked = X509_CRL_get_REVOKED(crl);
+
+ gens = NULL;
+ for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+ X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+ STACK_OF(X509_EXTENSION) *exts;
+ ASN1_ENUMERATED *reason;
+ X509_EXTENSION *ext;
+ gtmp = X509_REVOKED_get_ext_d2i(rev,
+ NID_certificate_issuer, &j, NULL);
+ if (!gtmp && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (gtmp) {
+ gens = gtmp;
+ if (!crl->issuers) {
+ crl->issuers = sk_GENERAL_NAMES_new_null();
+ if (!crl->issuers)
+ return 0;
+ }
+ if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+ return 0;
+ }
+ rev->issuer = gens;
+
+ reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
+ if (!reason && (j != -1)) {
+ crl->flags |= EXFLAG_INVALID;
+ return 1;
+ }
+
+ if (reason) {
+ rev->reason = ASN1_ENUMERATED_get(reason);
+ ASN1_ENUMERATED_free(reason);
+ } else
+ rev->reason = CRL_REASON_NONE;
+
+ /* Check for critical CRL entry extensions */
+
+ exts = rev->extensions;
+
+ for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
+ ext = sk_X509_EXTENSION_value(exts, j);
+ if (X509_EXTENSION_get_critical(ext)) {
+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer)
+ continue;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ }
+
+ return 1;
+
+}
+
+/*
+ * The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_CRL *crl = (X509_CRL *)*pval;
+ STACK_OF(X509_EXTENSION) *exts;
+ X509_EXTENSION *ext;
+ int idx;
+
+ switch (operation) {
+ case ASN1_OP_NEW_POST:
+ crl->idp = NULL;
+ crl->akid = NULL;
+ crl->flags = 0;
+ crl->idp_flags = 0;
+ crl->idp_reasons = CRLDP_ALL_REASONS;
+ crl->meth = default_crl_method;
+ crl->meth_data = NULL;
+ crl->issuers = NULL;
+ crl->crl_number = NULL;
+ crl->base_crl_number = NULL;
+ break;
+
+ case ASN1_OP_D2I_POST:
+ X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+ crl->idp = X509_CRL_get_ext_d2i(crl,
+ NID_issuing_distribution_point, NULL,
+ NULL);
+ if (crl->idp)
+ setup_idp(crl, crl->idp);
+
+ crl->akid = X509_CRL_get_ext_d2i(crl,
+ NID_authority_key_identifier, NULL,
+ NULL);
+
+ crl->crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_crl_number, NULL, NULL);
+
+ crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+ NID_delta_crl, NULL,
+ NULL);
+ /* Delta CRLs must have CRL number */
+ if (crl->base_crl_number && !crl->crl_number)
+ crl->flags |= EXFLAG_INVALID;
+
+ /*
+ * See if we have any unhandled critical CRL extensions and indicate
+ * this in a flag. We only currently handle IDP so anything else
+ * critical sets the flag. This code accesses the X509_CRL structure
+ * directly: applications shouldn't do this.
+ */
+
+ exts = crl->crl.extensions;
+
+ for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+ int nid;
+ ext = sk_X509_EXTENSION_value(exts, idx);
+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
+ if (nid == NID_freshest_crl)
+ crl->flags |= EXFLAG_FRESHEST;
+ if (X509_EXTENSION_get_critical(ext)) {
+ /* We handle IDP and deltas */
+ if ((nid == NID_issuing_distribution_point)
+ || (nid == NID_authority_key_identifier)
+ || (nid == NID_delta_crl))
+ continue;
+ crl->flags |= EXFLAG_CRITICAL;
+ break;
+ }
+ }
+
+ if (!crl_set_issuers(crl))
+ return 0;
+
+ if (crl->meth->crl_init) {
+ if (crl->meth->crl_init(crl) == 0)
+ return 0;
+ }
+
+ crl->flags |= EXFLAG_SET;
+ break;
+
+ case ASN1_OP_FREE_POST:
+ if (crl->meth->crl_free) {
+ if (!crl->meth->crl_free(crl))
+ return 0;
+ }
+ AUTHORITY_KEYID_free(crl->akid);
+ ISSUING_DIST_POINT_free(crl->idp);
+ ASN1_INTEGER_free(crl->crl_number);
+ ASN1_INTEGER_free(crl->base_crl_number);
+ sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+ break;
+ }
+ return 1;
+}
+
+/* Convert IDP into a more convenient form */
+
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+{
+ int idp_only = 0;
+ /* Set various flags according to IDP */
+ crl->idp_flags |= IDP_PRESENT;
+ if (idp->onlyuser > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYUSER;
+ }
+ if (idp->onlyCA > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYCA;
+ }
+ if (idp->onlyattr > 0) {
+ idp_only++;
+ crl->idp_flags |= IDP_ONLYATTR;
+ }
+
+ if (idp_only > 1)
+ crl->idp_flags |= IDP_INVALID;
+
+ if (idp->indirectCRL > 0)
+ crl->idp_flags |= IDP_INDIRECT;
+
+ if (idp->onlysomereasons) {
+ crl->idp_flags |= IDP_REASONS;
+ if (idp->onlysomereasons->length > 0)
+ crl->idp_reasons = idp->onlysomereasons->data[0];
+ if (idp->onlysomereasons->length > 1)
+ crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
+ crl->idp_reasons &= CRLDP_ALL_REASONS;
+ }
+
+ DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+}
+
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
+ ASN1_EMBED(X509_CRL, crl, X509_CRL_INFO),
+ ASN1_EMBED(X509_CRL, sig_alg, X509_ALGOR),
+ ASN1_EMBED(X509_CRL, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+ const X509_REVOKED *const *b)
+{
+ return (ASN1_STRING_cmp((ASN1_STRING *)&(*a)->serialNumber,
+ (ASN1_STRING *)&(*b)->serialNumber));
+}
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+ X509_CRL_INFO *inf;
+
+ inf = &crl->crl;
+ if (inf->revoked == NULL)
+ inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+ if (inf->revoked == NULL || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+ ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ inf->enc.modified = 1;
+ return 1;
+}
+
+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+ if (crl->meth->crl_verify)
+ return crl->meth->crl_verify(crl, r);
+ return 0;
+}
+
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial)
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret, serial, NULL);
+ return 0;
+}
+
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+{
+ if (crl->meth->crl_lookup)
+ return crl->meth->crl_lookup(crl, ret,
+ X509_get_serialNumber(x),
+ X509_get_issuer_name(x));
+ return 0;
+}
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+ &crl->sig_alg, &crl->signature, &crl->crl, r));
+}
+
+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
+ X509_REVOKED *rev)
+{
+ int i;
+
+ if (!rev->issuer) {
+ if (!nm)
+ return 1;
+ if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+ return 1;
+ return 0;
+ }
+
+ if (!nm)
+ nm = X509_CRL_get_issuer(crl);
+
+ for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+ if (gen->type != GEN_DIRNAME)
+ continue;
+ if (!X509_NAME_cmp(nm, gen->d.directoryName))
+ return 1;
+ }
+ return 0;
+
+}
+
+static int def_crl_lookup(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial,
+ X509_NAME *issuer)
+{
+ X509_REVOKED rtmp, *rev;
+ int idx, num;
+
+ if (crl->crl.revoked == NULL)
+ return 0;
+
+ /*
+ * 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_THREAD_write_lock(crl->lock);
+ sk_X509_REVOKED_sort(crl->crl.revoked);
+ CRYPTO_THREAD_unlock(crl->lock);
+ }
+ rtmp.serialNumber = *serial;
+ idx = sk_X509_REVOKED_find(crl->crl.revoked, &rtmp);
+ if (idx < 0)
+ return 0;
+ /* Need to look for matching name */
+ for (num = sk_X509_REVOKED_num(crl->crl.revoked); idx < num; idx++) {
+ rev = sk_X509_REVOKED_value(crl->crl.revoked, idx);
+ if (ASN1_INTEGER_cmp(&rev->serialNumber, serial))
+ return 0;
+ if (crl_revoked_issuer_match(crl, issuer, rev)) {
+ if (ret)
+ *ret = rev;
+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+ return 2;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+{
+ if (meth == NULL)
+ default_crl_method = &int_crl_meth;
+ else
+ default_crl_method = meth;
+}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+ int (*crl_free) (X509_CRL *crl),
+ int (*crl_lookup) (X509_CRL *crl,
+ X509_REVOKED **ret,
+ ASN1_INTEGER *ser,
+ X509_NAME *issuer),
+ int (*crl_verify) (X509_CRL *crl,
+ EVP_PKEY *pk))
+{
+ X509_CRL_METHOD *m = OPENSSL_malloc(sizeof(*m));
+
+ if (m == NULL) {
+ X509err(X509_F_X509_CRL_METHOD_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ m->crl_init = crl_init;
+ m->crl_free = crl_free;
+ m->crl_lookup = crl_lookup;
+ m->crl_verify = crl_verify;
+ m->flags = X509_CRL_METHOD_DYNAMIC;
+ return m;
+}
+
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+{
+ if (m == NULL || !(m->flags & X509_CRL_METHOD_DYNAMIC))
+ return;
+ OPENSSL_free(m);
+}
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+{
+ crl->meth_data = dat;
+}
+
+void *X509_CRL_get_meth_data(X509_CRL *crl)
+{
+ return crl->meth_data;
+}
diff --git a/crypto/x509/x_exten.c b/crypto/x509/x_exten.c
new file mode 100644
index 000000000000..f10f4a4d8769
--- /dev/null
+++ b/crypto/x509/x_exten.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "x509_lcl.h"
+
+ASN1_SEQUENCE(X509_EXTENSION) = {
+ ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+ ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+ ASN1_EMBED(X509_EXTENSION, value, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_EXTENSION)
+
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c
new file mode 100644
index 000000000000..a1e9bbdb669d
--- /dev/null
+++ b/crypto/x509/x_name.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/ctype.h"
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include "internal/asn1_int.h"
+#include "x509_lcl.h"
+
+/*
+ * Maximum length of X509_NAME: much larger than anything we should
+ * ever see in practice.
+ */
+
+#define X509_NAME_MAX (1024 * 1024)
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it,
+ int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass);
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
+
+static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+ unsigned char **in);
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx);
+
+ASN1_SEQUENCE(X509_NAME_ENTRY) = {
+ ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+ ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
+
+/*
+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
+ * declare two template wrappers for this
+ */
+
+ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
+
+ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
+
+/*
+ * Normally that's where it would end: we'd have two nested STACK structures
+ * representing the ASN1. Unfortunately X509_NAME uses a completely different
+ * form and caches encodings so we have to process the internal form and
+ * convert to the external form.
+ */
+
+static const ASN1_EXTERN_FUNCS x509_name_ff = {
+ NULL,
+ x509_name_ex_new,
+ x509_name_ex_free,
+ 0, /* Default clear behaviour is OK */
+ x509_name_ex_d2i,
+ x509_name_ex_i2d,
+ x509_name_ex_print
+};
+
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
+
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+{
+ X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL)
+ goto memerr;
+ if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
+ goto memerr;
+ if ((ret->bytes = BUF_MEM_new()) == NULL)
+ goto memerr;
+ ret->modified = 1;
+ *val = (ASN1_VALUE *)ret;
+ return 1;
+
+ memerr:
+ ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
+ if (ret) {
+ sk_X509_NAME_ENTRY_free(ret->entries);
+ OPENSSL_free(ret);
+ }
+ return 0;
+}
+
+static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ X509_NAME *a;
+
+ if (!pval || !*pval)
+ return;
+ a = (X509_NAME *)*pval;
+
+ BUF_MEM_free(a->bytes);
+ sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+ OPENSSL_free(a->canon_enc);
+ OPENSSL_free(a);
+ *pval = NULL;
+}
+
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_free(ne);
+}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+}
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+ const unsigned char **in, long len,
+ const ASN1_ITEM *it, int tag, int aclass,
+ char opt, ASN1_TLC *ctx)
+{
+ const unsigned char *p = *in, *q;
+ union {
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+ ASN1_VALUE *a;
+ } intname = {
+ NULL
+ };
+ union {
+ X509_NAME *x;
+ ASN1_VALUE *a;
+ } nm = {
+ NULL
+ };
+ int i, j, ret;
+ STACK_OF(X509_NAME_ENTRY) *entries;
+ X509_NAME_ENTRY *entry;
+ if (len > X509_NAME_MAX)
+ len = X509_NAME_MAX;
+ q = p;
+
+ /* Get internal representation of Name */
+ ret = ASN1_item_ex_d2i(&intname.a,
+ &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+ tag, aclass, opt, ctx);
+
+ if (ret <= 0)
+ return ret;
+
+ if (*val)
+ x509_name_ex_free(val, NULL);
+ if (!x509_name_ex_new(&nm.a, NULL))
+ goto err;
+ /* We've decoded it: now cache encoding */
+ if (!BUF_MEM_grow(nm.x->bytes, p - q))
+ goto err;
+ memcpy(nm.x->bytes->data, q, p - q);
+
+ /* Convert internal representation to X509_NAME structure */
+ for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+ entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+ for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+ entry = sk_X509_NAME_ENTRY_value(entries, j);
+ entry->set = i;
+ if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+ goto err;
+ sk_X509_NAME_ENTRY_set(entries, j, NULL);
+ }
+ }
+ ret = x509_name_canon(nm.x);
+ if (!ret)
+ goto err;
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ nm.x->modified = 0;
+ *val = nm.a;
+ *in = p;
+ return ret;
+
+ err:
+ if (nm.x != NULL)
+ X509_NAME_free(nm.x);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_pop_free);
+ ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+ return 0;
+}
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass)
+{
+ int ret;
+ X509_NAME *a = (X509_NAME *)*val;
+ if (a->modified) {
+ ret = x509_name_encode(a);
+ if (ret < 0)
+ return ret;
+ ret = x509_name_canon(a);
+ if (ret < 0)
+ return ret;
+ }
+ ret = a->bytes->length;
+ if (out != NULL) {
+ memcpy(*out, a->bytes->data, ret);
+ *out += ret;
+ }
+ return ret;
+}
+
+static int x509_name_encode(X509_NAME *a)
+{
+ union {
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+ ASN1_VALUE *a;
+ } intname = {
+ NULL
+ };
+ int len;
+ unsigned char *p;
+ STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+ X509_NAME_ENTRY *entry;
+ int i, set = -1;
+ intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+ if (!intname.s)
+ goto memerr;
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+ if (entry->set != set) {
+ entries = sk_X509_NAME_ENTRY_new_null();
+ if (!entries)
+ goto memerr;
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
+ sk_X509_NAME_ENTRY_free(entries);
+ goto memerr;
+ }
+ set = entry->set;
+ }
+ if (!sk_X509_NAME_ENTRY_push(entries, entry))
+ goto memerr;
+ }
+ len = ASN1_item_ex_i2d(&intname.a, NULL,
+ ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ if (!BUF_MEM_grow(a->bytes, len))
+ goto memerr;
+ p = (unsigned char *)a->bytes->data;
+ ASN1_item_ex_i2d(&intname.a,
+ &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ a->modified = 0;
+ return len;
+ memerr:
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
+ ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
+ return -1;
+}
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+ int indent,
+ const char *fname, const ASN1_PCTX *pctx)
+{
+ if (X509_NAME_print_ex(out, (const X509_NAME *)*pval,
+ indent, pctx->nm_flags) <= 0)
+ return 0;
+ return 2;
+}
+
+/*
+ * This function generates the canonical encoding of the Name structure. In
+ * it all strings are converted to UTF8, leading, trailing and multiple
+ * spaces collapsed, converted to lower case and the leading SEQUENCE header
+ * removed. In future we could also normalize the UTF8 too. By doing this
+ * comparison of Name structures can be rapidly performed by just using
+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
+ * constraints of type dirName can also be checked with a simple memcmp().
+ */
+
+static int x509_name_canon(X509_NAME *a)
+{
+ unsigned char *p;
+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname;
+ STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+ X509_NAME_ENTRY *entry, *tmpentry = NULL;
+ int i, set = -1, ret = 0, len;
+
+ OPENSSL_free(a->canon_enc);
+ a->canon_enc = NULL;
+ /* Special case: empty X509_NAME => null encoding */
+ if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+ a->canon_enclen = 0;
+ return 1;
+ }
+ intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+ if (intname == NULL) {
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+ entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+ if (entry->set != set) {
+ entries = sk_X509_NAME_ENTRY_new_null();
+ if (entries == NULL)
+ goto err;
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
+ sk_X509_NAME_ENTRY_free(entries);
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ set = entry->set;
+ }
+ tmpentry = X509_NAME_ENTRY_new();
+ if (tmpentry == NULL) {
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ tmpentry->object = OBJ_dup(entry->object);
+ if (tmpentry->object == NULL) {
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!asn1_string_canon(tmpentry->value, entry->value))
+ goto err;
+ if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) {
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ tmpentry = NULL;
+ }
+
+ /* Finally generate encoding */
+ len = i2d_name_canon(intname, NULL);
+ if (len < 0)
+ goto err;
+ a->canon_enclen = len;
+
+ p = OPENSSL_malloc(a->canon_enclen);
+ if (p == NULL) {
+ X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ a->canon_enc = p;
+
+ i2d_name_canon(intname, &p);
+
+ ret = 1;
+
+ err:
+ X509_NAME_ENTRY_free(tmpentry);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+ local_sk_X509_NAME_ENTRY_pop_free);
+ return ret;
+}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON \
+ (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+ | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+ | B_ASN1_VISIBLESTRING)
+
+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
+{
+ unsigned char *to, *from;
+ int len, i;
+
+ /* If type not in bitmask just copy string across */
+ if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+ if (!ASN1_STRING_copy(out, in))
+ return 0;
+ return 1;
+ }
+
+ out->type = V_ASN1_UTF8STRING;
+ out->length = ASN1_STRING_to_UTF8(&out->data, in);
+ if (out->length == -1)
+ return 0;
+
+ to = out->data;
+ from = to;
+
+ len = out->length;
+
+ /*
+ * Convert string in place to canonical form. Ultimately we may need to
+ * handle a wider range of characters but for now ignore anything with
+ * MSB set and rely on the ossl_isspace() to fail on bad characters without
+ * needing isascii or range checks as well.
+ */
+
+ /* Ignore leading spaces */
+ while (len > 0 && ossl_isspace(*from)) {
+ from++;
+ len--;
+ }
+
+ to = from + len;
+
+ /* Ignore trailing spaces */
+ while (len > 0 && ossl_isspace(to[-1])) {
+ to--;
+ len--;
+ }
+
+ to = out->data;
+
+ i = 0;
+ while (i < len) {
+ /* If not ASCII set just copy across */
+ if (!ossl_isascii(*from)) {
+ *to++ = *from++;
+ i++;
+ }
+ /* Collapse multiple spaces */
+ else if (ossl_isspace(*from)) {
+ /* Copy one space across */
+ *to++ = ' ';
+ /*
+ * Ignore subsequent spaces. Note: don't need to check len here
+ * because we know the last character is a non-space so we can't
+ * overflow.
+ */
+ do {
+ from++;
+ i++;
+ }
+ while (ossl_isspace(*from));
+ } else {
+ *to++ = ossl_tolower(*from);
+ from++;
+ i++;
+ }
+ }
+
+ out->length = to - out->data;
+
+ return 1;
+
+}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+ unsigned char **in)
+{
+ int i, len, ltmp;
+ ASN1_VALUE *v;
+ STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+ len = 0;
+ for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+ v = sk_ASN1_VALUE_value(intname, i);
+ ltmp = ASN1_item_ex_i2d(&v, in,
+ ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+ if (ltmp < 0)
+ return ltmp;
+ len += ltmp;
+ }
+ return len;
+}
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+{
+ if (*xn == name)
+ return *xn != NULL;
+ if ((name = X509_NAME_dup(name)) == NULL)
+ return 0;
+ X509_NAME_free(*xn);
+ *xn = name;
+ return 1;
+}
+
+int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
+{
+ char *s, *c, *b;
+ int l, i;
+
+ l = 80 - 2 - obase;
+
+ b = X509_NAME_oneline(name, NULL, 0);
+ if (!b)
+ return 0;
+ if (!*b) {
+ OPENSSL_free(b);
+ return 1;
+ }
+ s = b + 1; /* skip the first slash */
+
+ c = s;
+ for (;;) {
+ if (((*s == '/') &&
+ (ossl_isupper(s[1]) && ((s[2] == '=') ||
+ (ossl_isupper(s[2]) && (s[3] == '='))
+ ))) || (*s == '\0'))
+ {
+ i = s - c;
+ if (BIO_write(bp, c, i) != i)
+ goto err;
+ c = s + 1; /* skip following slash */
+ if (*s != '\0') {
+ if (BIO_write(bp, ", ", 2) != 2)
+ goto err;
+ }
+ l--;
+ }
+ if (*s == '\0')
+ break;
+ s++;
+ l--;
+ }
+
+ OPENSSL_free(b);
+ return 1;
+ err:
+ X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
+ OPENSSL_free(b);
+ return 0;
+}
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+ size_t *pderlen)
+{
+ /* Make sure encoding is valid */
+ if (i2d_X509_NAME(nm, NULL) <= 0)
+ return 0;
+ if (pder != NULL)
+ *pder = (unsigned char *)nm->bytes->data;
+ if (pderlen != NULL)
+ *pderlen = nm->bytes->length;
+ return 1;
+}
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
new file mode 100644
index 000000000000..d050b0b4b3e2
--- /dev/null
+++ b/crypto/x509/x_pubkey.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "internal/x509_int.h"
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+struct X509_pubkey_st {
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *public_key;
+ EVP_PKEY *pkey;
+};
+
+static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key);
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ if (operation == ASN1_OP_FREE_POST) {
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ } else if (operation == ASN1_OP_D2I_POST) {
+ /* Attempt to decode public key and cache in pubkey structure. */
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
+ /*
+ * Opportunistically decode the key but remove any non fatal errors
+ * from the queue. Subsequent explicit attempts to decode/use the key
+ * will return an appropriate error.
+ */
+ ERR_set_mark();
+ if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1)
+ return 0;
+ ERR_pop_to_mark();
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+{
+ X509_PUBKEY *pk = NULL;
+
+ if (x == NULL)
+ return 0;
+
+ if ((pk = X509_PUBKEY_new()) == NULL)
+ goto error;
+
+ if (pkey->ameth) {
+ if (pkey->ameth->pub_encode) {
+ if (!pkey->ameth->pub_encode(pk, pkey)) {
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ X509_PUBKEY_free(*x);
+ *x = pk;
+ pk->pkey = pkey;
+ EVP_PKEY_up_ref(pkey);
+ return 1;
+
+ error:
+ X509_PUBKEY_free(pk);
+ return 0;
+}
+
+/*
+ * Attempt to decode a public key.
+ * Returns 1 on success, 0 for a decode failure and -1 for a fatal
+ * error e.g. malloc failure.
+ */
+
+
+static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
+{
+ EVP_PKEY *pkey = EVP_PKEY_new();
+
+ if (pkey == NULL) {
+ X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
+ goto error;
+ }
+
+ if (pkey->ameth->pub_decode) {
+ /*
+ * Treat any failure of pub_decode as a decode error. In
+ * future we could have different return codes for decode
+ * errors and fatal errors such as malloc failure.
+ */
+ if (!pkey->ameth->pub_decode(pkey, key)) {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+
+ *ppkey = pkey;
+ return 1;
+
+ error:
+ EVP_PKEY_free(pkey);
+ return 0;
+}
+
+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = NULL;
+
+ if (key == NULL || key->public_key == NULL)
+ return NULL;
+
+ if (key->pkey != NULL)
+ return key->pkey;
+
+ /*
+ * When the key ASN.1 is initially parsed an attempt is made to
+ * decode the public key and cache the EVP_PKEY structure. If this
+ * operation fails the cached value will be NULL. Parsing continues
+ * to allow parsing of unknown key types or unsupported forms.
+ * We repeat the decode operation so the appropriate errors are left
+ * in the queue.
+ */
+ x509_pubkey_decode(&ret, key);
+ /* If decode doesn't fail something bad happened */
+ if (ret != NULL) {
+ X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR);
+ EVP_PKEY_free(ret);
+ }
+
+ return NULL;
+}
+
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+{
+ EVP_PKEY *ret = X509_PUBKEY_get0(key);
+ if (ret != NULL)
+ EVP_PKEY_up_ref(ret);
+ return ret;
+}
+
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+ X509_PUBKEY *xpk;
+ EVP_PKEY *pktmp;
+ const unsigned char *q;
+ q = *pp;
+ xpk = d2i_X509_PUBKEY(NULL, &q, length);
+ if (!xpk)
+ return NULL;
+ pktmp = X509_PUBKEY_get(xpk);
+ X509_PUBKEY_free(xpk);
+ if (!pktmp)
+ return NULL;
+ *pp = q;
+ if (a) {
+ EVP_PKEY_free(*a);
+ *a = pktmp;
+ }
+ return pktmp;
+}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+ X509_PUBKEY *xpk = NULL;
+ int ret;
+ if (!a)
+ return 0;
+ if (!X509_PUBKEY_set(&xpk, a))
+ return -1;
+ ret = i2d_X509_PUBKEY(xpk, pp);
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/*
+ * The following are equivalents but which return RSA and DSA keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ RSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (pktmp == NULL) {
+ ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_RSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ DSA *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ pktmp = EVP_PKEY_new();
+ if (pktmp == NULL) {
+ ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_DSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+{
+ EVP_PKEY *pkey;
+ EC_KEY *key;
+ const unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_EC_KEY(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key)
+ return NULL;
+ *pp = q;
+ if (a) {
+ EC_KEY_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if (!a)
+ return 0;
+ if ((pktmp = EVP_PKEY_new()) == NULL) {
+ ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ EVP_PKEY_set1_EC_KEY(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+ int ptype, void *pval,
+ unsigned char *penc, int penclen)
+{
+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+ return 0;
+ if (penc) {
+ OPENSSL_free(pub->public_key->data);
+ pub->public_key->data = penc;
+ pub->public_key->length = penclen;
+ /* Set number of unused bits to zero */
+ pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ }
+ return 1;
+}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+ if (ppkalg)
+ *ppkalg = pub->algor->algorithm;
+ if (pk) {
+ *pk = pub->public_key->data;
+ *ppklen = pub->public_key->length;
+ }
+ if (pa)
+ *pa = pub->algor;
+ return 1;
+}
+
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+{
+ if (x == NULL)
+ return NULL;
+ return x->cert_info.key->public_key;
+}
diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c
new file mode 100644
index 000000000000..c2da95a73ecf
--- /dev/null
+++ b/crypto/x509/x_req.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*-
+ * X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+ if (operation == ASN1_OP_NEW_POST) {
+ rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+ if (!rinf->attributes)
+ return 0;
+ }
+ return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+ /* This isn't really OPTIONAL but it gets round invalid
+ * encodings
+ */
+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+
+ASN1_SEQUENCE_ref(X509_REQ, 0) = {
+ ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO),
+ ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR),
+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
new file mode 100644
index 000000000000..4c04f12c9494
--- /dev/null
+++ b/crypto/x509/x_x509.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
+ ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+ ASN1_EMBED(X509_CINF, serialNumber, ASN1_INTEGER),
+ ASN1_EMBED(X509_CINF, signature, X509_ALGOR),
+ ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+ ASN1_EMBED(X509_CINF, validity, X509_VAL),
+ ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+ ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+ ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+ ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ void *exarg)
+{
+ X509 *ret = (X509 *)*pval;
+
+ switch (operation) {
+
+ case ASN1_OP_NEW_POST:
+ ret->ex_flags = 0;
+ ret->ex_pathlen = -1;
+ ret->ex_pcpathlen = -1;
+ ret->skid = NULL;
+ ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+ ret->rfc3779_addr = NULL;
+ ret->rfc3779_asid = NULL;
+#endif
+ ret->aux = NULL;
+ ret->crldp = NULL;
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data))
+ return 0;
+ break;
+
+ case ASN1_OP_FREE_POST:
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+ X509_CERT_AUX_free(ret->aux);
+ ASN1_OCTET_STRING_free(ret->skid);
+ AUTHORITY_KEYID_free(ret->akid);
+ CRL_DIST_POINTS_free(ret->crldp);
+ policy_cache_free(ret->policy_cache);
+ GENERAL_NAMES_free(ret->altname);
+ NAME_CONSTRAINTS_free(ret->nc);
+#ifndef OPENSSL_NO_RFC3779
+ sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
+ ASIdentifiers_free(ret->rfc3779_asid);
+#endif
+ break;
+
+ }
+
+ return 1;
+
+}
+
+ASN1_SEQUENCE_ref(X509, x509_cb) = {
+ ASN1_EMBED(X509, cert_info, X509_CINF),
+ ASN1_EMBED(X509, sig_alg, X509_ALGOR),
+ ASN1_EMBED(X509, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509, X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+
+int X509_set_ex_data(X509 *r, int idx, void *arg)
+{
+ return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
+}
+
+void *X509_get_ex_data(X509 *r, int idx)
+{
+ return CRYPTO_get_ex_data(&r->ex_data, idx);
+}
+
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
+ */
+
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+ const unsigned char *q;
+ X509 *ret;
+ int freeret = 0;
+
+ /* Save start position */
+ q = *pp;
+
+ if (a == NULL || *a == NULL)
+ freeret = 1;
+ ret = d2i_X509(a, &q, length);
+ /* If certificate unreadable then forget it */
+ if (ret == NULL)
+ return NULL;
+ /* update length */
+ length -= q - *pp;
+ if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+ goto err;
+ *pp = q;
+ return ret;
+ err:
+ if (freeret) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
+ return NULL;
+}
+
+/*
+ * Serialize trusted certificate to *pp or just return the required buffer
+ * length if pp == NULL. We ultimately want to avoid modifying *pp in the
+ * error path, but that depends on similar hygiene in lower-level functions.
+ * Here we avoid compounding the problem.
+ */
+static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
+{
+ int length, tmplen;
+ unsigned char *start = pp != NULL ? *pp : NULL;
+
+ /*
+ * This might perturb *pp on error, but fixing that belongs in i2d_X509()
+ * not here. It should be that if a == NULL length is zero, but we check
+ * both just in case.
+ */
+ length = i2d_X509(a, pp);
+ if (length <= 0 || a == NULL)
+ return length;
+
+ tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+ if (tmplen < 0) {
+ if (start != NULL)
+ *pp = start;
+ return tmplen;
+ }
+ length += tmplen;
+
+ return length;
+}
+
+/*
+ * Serialize trusted certificate to *pp, or just return the required buffer
+ * length if pp == NULL.
+ *
+ * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since
+ * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do
+ * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
+ * allocated buffer.
+ */
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+ int length;
+ unsigned char *tmp;
+
+ /* Buffer provided by caller */
+ if (pp == NULL || *pp != NULL)
+ return i2d_x509_aux_internal(a, pp);
+
+ /* Obtain the combined length */
+ if ((length = i2d_x509_aux_internal(a, NULL)) <= 0)
+ return length;
+
+ /* Allocate requisite combined storage */
+ *pp = tmp = OPENSSL_malloc(length);
+ if (tmp == NULL) {
+ X509err(X509_F_I2D_X509_AUX, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ /* Encode, but keep *pp at the originally malloced pointer */
+ length = i2d_x509_aux_internal(a, &tmp);
+ if (length <= 0) {
+ OPENSSL_free(*pp);
+ *pp = NULL;
+ }
+ return length;
+}
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
+{
+ x->cert_info.enc.modified = 1;
+ return i2d_X509_CINF(&x->cert_info, pp);
+}
+
+void X509_get0_signature(const ASN1_BIT_STRING **psig,
+ const X509_ALGOR **palg, const X509 *x)
+{
+ if (psig)
+ *psig = &x->signature;
+ if (palg)
+ *palg = &x->sig_alg;
+}
+
+int X509_get_signature_nid(const X509 *x)
+{
+ return OBJ_obj2nid(x->sig_alg.algorithm);
+}
diff --git a/crypto/x509/x_x509a.c b/crypto/x509/x_x509a.c
new file mode 100644
index 000000000000..8c9ad71d1b29
--- /dev/null
+++ b/crypto/x509/x_x509a.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+ASN1_SEQUENCE(X509_CERT_AUX) = {
+ ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+ ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+ ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+} ASN1_SEQUENCE_END(X509_CERT_AUX)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+int X509_trusted(const X509 *x)
+{
+ return x->aux ? 1 : 0;
+}
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+ if (x == NULL)
+ return NULL;
+ if (x->aux == NULL && (x->aux = X509_CERT_AUX_new()) == NULL)
+ return NULL;
+ return x->aux;
+}
+
+int X509_alias_set1(X509 *x, const unsigned char *name, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!name) {
+ if (!x || !x->aux || !x->aux->alias)
+ return 1;
+ ASN1_UTF8STRING_free(x->aux->alias);
+ x->aux->alias = NULL;
+ return 1;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ return 0;
+ if (aux->alias == NULL && (aux->alias = ASN1_UTF8STRING_new()) == NULL)
+ return 0;
+ return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int X509_keyid_set1(X509 *x, const unsigned char *id, int len)
+{
+ X509_CERT_AUX *aux;
+ if (!id) {
+ if (!x || !x->aux || !x->aux->keyid)
+ return 1;
+ ASN1_OCTET_STRING_free(x->aux->keyid);
+ x->aux->keyid = NULL;
+ return 1;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ return 0;
+ if (aux->keyid == NULL
+ && (aux->keyid = ASN1_OCTET_STRING_new()) == NULL)
+ return 0;
+ return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *X509_alias_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->alias)
+ return NULL;
+ if (len)
+ *len = x->aux->alias->length;
+ return x->aux->alias->data;
+}
+
+unsigned char *X509_keyid_get0(X509 *x, int *len)
+{
+ if (!x->aux || !x->aux->keyid)
+ return NULL;
+ if (len)
+ *len = x->aux->keyid->length;
+ return x->aux->keyid->data;
+}
+
+int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp = NULL;
+ if (obj) {
+ objtmp = OBJ_dup(obj);
+ if (!objtmp)
+ return 0;
+ }
+ if ((aux = aux_get(x)) == NULL)
+ goto err;
+ if (aux->trust == NULL
+ && (aux->trust = sk_ASN1_OBJECT_new_null()) == NULL)
+ goto err;
+ if (!objtmp || sk_ASN1_OBJECT_push(aux->trust, objtmp))
+ return 1;
+ err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
+}
+
+int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj)
+{
+ X509_CERT_AUX *aux;
+ ASN1_OBJECT *objtmp;
+ if ((objtmp = OBJ_dup(obj)) == NULL)
+ return 0;
+ if ((aux = aux_get(x)) == NULL)
+ goto err;
+ if (aux->reject == NULL
+ && (aux->reject = sk_ASN1_OBJECT_new_null()) == NULL)
+ goto err;
+ return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
+}
+
+void X509_trust_clear(X509 *x)
+{
+ if (x->aux) {
+ sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+ x->aux->trust = NULL;
+ }
+}
+
+void X509_reject_clear(X509 *x)
+{
+ if (x->aux) {
+ sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+ x->aux->reject = NULL;
+ }
+}
+
+STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x)
+{
+ if (x->aux != NULL)
+ return x->aux->trust;
+ return NULL;
+}
+
+STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x)
+{
+ if (x->aux != NULL)
+ return x->aux->reject;
+ return NULL;
+}