From: Rich Salz Date: Fri, 24 Apr 2015 19:26:15 +0000 (-0400) Subject: Big apps cleanup (option-parsing, etc) X-Git-Tag: OpenSSL_1_1_0-pre1~1284 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=7e1b7485706c2b11091b5fa897fe496a2faa56cc Big apps cleanup (option-parsing, etc) This is merges the old "rsalz-monolith" branch over to master. The biggest change is that option parsing switch from cascasding 'else if strcmp("-foo")' to a utility routine and somethin akin to getopt. Also, an error in the command line no longer prints the full summary; use -help (or --help :) for that. There have been many other changes and code-cleanup, see bullet list below. Special thanks to Matt for the long and detailed code review. TEMPORARY: For now, comment out CRYPTO_mem_leaks() at end of main Tickets closed: RT3515: Use 3DES in pkcs12 if built with no-rc2 RT1766: s_client -reconnect and -starttls broke RT2932: Catch write errors RT2604: port should be 'unsigned short' RT2983: total_bytes undeclared #ifdef RENEG RT1523: Add -nocert to fix output in x509 app RT3508: Remove unused variable introduced by b09eb24 RT3511: doc fix; req default serial is random RT1325,2973: Add more extensions to c_rehash RT2119,3407: Updated to dgst.pod RT2379: Additional typo fix RT2693: Extra include of string.h RT2880: HFS is case-insensitive filenames RT3246: req command prints version number wrong Other changes; incompatibilities marked with *: Add SCSV support Add -misalign to speed command Make dhparam, dsaparam, ecparam, x509 output C in proper style Make some internal ocsp.c functions void Only display cert usages with -help in verify Use global bio_err, remove "BIO*err" parameter from functions For filenames, - always means stdin (or stdout as appropriate) Add aliases for -des/aes "wrap" ciphers. *Remove support for IISSGC (server gated crypto) *The undocumented OCSP -header flag is now "-header name=value" *Documented the OCSP -header flag Reviewed-by: Matt Caswell --- diff --git a/apps/Makefile b/apps/Makefile index c7a6094c30..b6f7b2c797 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -6,7 +6,7 @@ DIR= apps TOP= .. CC= cc INCLUDES= -I$(TOP) -I../include $(KRB5_INCLUDES) -CFLAG= -g -static +CFLAG= -g -static -Wswitch MAKEFILE= Makefile PERL= perl RM= rm -f @@ -20,7 +20,7 @@ EXE_EXT= SHLIB_TARGET= -CFLAGS= -DMONOLITH $(INCLUDES) $(CFLAG) +CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile makeapps.com install.com @@ -29,49 +29,48 @@ DLIBSSL=../libssl.a LIBCRYPTO=-L.. -lcrypto LIBSSL=-L.. -lssl -PROGRAM= openssl - SCRIPTS=CA.pl tsget +EXE= openssl$(EXE_EXT) -EXE= $(PROGRAM)$(EXE_EXT) - -E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \ - ca crl rsa rsautl dsa dsaparam ec ecparam \ - x509 genrsa gendsa genpkey s_server s_client speed \ - s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \ - pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp - -PROGS= $(PROGRAM).c +COMMANDS= \ + asn1pars.o ca.o ciphers.o cms.o crl.o crl2p7.o dgst.o dhparam.o \ + dsa.o dsaparam.o ec.o ecparam.o enc.o engine.o errstr.o gendsa.o \ + genpkey.o genrsa.o nseq.o ocsp.o passwd.o pkcs12.o pkcs7.o pkcs8.o \ + pkey.o pkeyparam.o pkeyutl.o prime.o rand.o req.o rsa.o rsautl.o \ + s_client.o s_server.o s_time.o sess_id.o smime.o speed.o spkac.o \ + srp.o ts.o verify.o version.o x509.o -A_OBJ=apps.o -A_SRC=apps.c +A_OBJ=apps.o opt.o +A_SRC=apps.c opt.c S_OBJ= s_cb.o s_socket.o S_SRC= s_cb.c s_socket.c RAND_OBJ=app_rand.o RAND_SRC=app_rand.c -E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \ - ca.o pkcs7.o crl2p7.o crl.o \ - rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \ - x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \ - s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \ - ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \ - spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o +OBJ = \ + asn1pars.o ca.o ciphers.o cms.o crl.o crl2p7.o dgst.o dhparam.o \ + dsa.o dsaparam.o ec.o ecparam.o enc.o engine.o errstr.o gendsa.o \ + genpkey.o genrsa.o nseq.o ocsp.o passwd.o pkcs12.o pkcs7.o pkcs8.o \ + pkey.o pkeyparam.o pkeyutl.o prime.o rand.o req.o rsa.o rsautl.o \ + s_client.o s_server.o s_time.o sess_id.o smime.o speed.o spkac.o \ + srp.o ts.o verify.o version.o x509.o -E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \ - pkcs7.c crl2p7.c crl.c \ - rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \ - x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \ - s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \ - ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \ - spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c -SRC=$(E_SRC) +SRC = \ + asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c \ + dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c \ + genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c \ + pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c \ + s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c \ + srp.c ts.c verify.c version.c x509.c + +EXE_OBJ = openssl.o $(OBJ) $(A_OBJ) $(S_OBJ) $(RAND_OBJ) +EXE_SRC = openssl.c $(SRC) $(A_SRC) $(S_SRC) $(RAND_SRC) HEADER= apps.h progs.h s_apps.h \ - testdsa.h testrsa.h + testdsa.h testrsa.h timeouts.h -ALL= $(GENERAL) $(SRC) $(HEADER) +ALL= $(GENERAL) $(EXE_SRC) $(HEADER) top: @(cd ..; $(MAKE) DIRS=$(DIR) all) @@ -80,18 +79,6 @@ all: exe exe: $(EXE) -req: sreq.o $(A_OBJ) $(DLIBCRYPTO) - shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \ - shlib_target="$(SHLIB_TARGET)"; \ - fi; \ - $(MAKE) -f $(TOP)/Makefile.shared -e \ - APPNAME=req OBJECTS="sreq.o $(A_OBJ) $(RAND_OBJ)" \ - LIBDEPS="$(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)" \ - link_app.$${shlib_target} - -sreq.o: req.c - $(CC) -c $(INCLUDES) $(CFLAG) -o sreq.o req.c - files: $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO @@ -129,18 +116,18 @@ uninstall: $(RM) $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf tags: - ctags $(SRC) + ctags $(EXE_SRC) $(HEADER) tests: lint: - lint -DLINT $(INCLUDES) $(SRC)>fluff + echo nope >fluff depend: @if [ -z "$(THIS)" ]; then \ $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \ else \ - $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \ + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(EXE_SRC); \ fi dclean: @@ -157,21 +144,22 @@ $(DLIBSSL): $(DLIBCRYPTO): (cd ..; $(MAKE) DIRS=crypto all) -$(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL) +$(EXE): progs.h $(EXE_OBJ) $(DLIBCRYPTO) $(DLIBSSL) $(RM) $(EXE) shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \ shlib_target="$(SHLIB_TARGET)"; \ fi; \ LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \ $(MAKE) -f $(TOP)/Makefile.shared -e \ - APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \ + APPNAME=$(EXE) OBJECTS="$(EXE_OBJ)" \ LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \ link_app.$${shlib_target} @(cd ..; $(MAKE) rehash) -progs.h: progs.pl - $(PERL) progs.pl $(E_EXE) >progs.h - $(RM) $(PROGRAM).o +progs.h: progs.pl Makefile + $(RM) progs.h + $(PERL) progs.pl $(COMMANDS) >progs.h + $(RM) openssl.o # DO NOT DELETE THIS LINE -- make depend depends on it. @@ -189,24 +177,30 @@ app_rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h app_rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h app_rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h app_rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h -app_rand.o: app_rand.c apps.h +app_rand.o: app_rand.c apps.h progs.h apps.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h apps.o: ../include/openssl/bn.h ../include/openssl/buffer.h -apps.o: ../include/openssl/conf.h ../include/openssl/crypto.h +apps.o: ../include/openssl/comp.h ../include/openssl/conf.h +apps.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h apps.o: ../include/openssl/e_os2.h ../include/openssl/ec.h apps.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h apps.o: ../include/openssl/engine.h ../include/openssl/err.h -apps.o: ../include/openssl/evp.h ../include/openssl/lhash.h +apps.o: ../include/openssl/evp.h ../include/openssl/hmac.h +apps.o: ../include/openssl/kssl.h ../include/openssl/lhash.h apps.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h apps.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h apps.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h apps.o: ../include/openssl/pem.h ../include/openssl/pem2.h apps.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h -apps.o: ../include/openssl/rsa.h ../include/openssl/safestack.h -apps.o: ../include/openssl/sha.h ../include/openssl/stack.h -apps.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h -apps.o: ../include/openssl/ui.h ../include/openssl/x509.h -apps.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.c apps.h +apps.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h +apps.o: ../include/openssl/safestack.h ../include/openssl/sha.h +apps.o: ../include/openssl/srtp.h ../include/openssl/ssl.h +apps.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h +apps.o: ../include/openssl/ssl3.h ../include/openssl/stack.h +apps.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h +apps.o: ../include/openssl/txt_db.h ../include/openssl/ui.h +apps.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h +apps.o: ../include/openssl/x509v3.h apps.c apps.h progs.h asn1pars.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h asn1pars.o: ../include/openssl/buffer.h ../include/openssl/conf.h asn1pars.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -222,7 +216,7 @@ asn1pars.o: ../include/openssl/safestack.h ../include/openssl/sha.h asn1pars.o: ../include/openssl/stack.h ../include/openssl/symhacks.h asn1pars.o: ../include/openssl/txt_db.h ../include/openssl/x509.h asn1pars.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -asn1pars.o: asn1pars.c +asn1pars.o: asn1pars.c progs.h ca.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ca.o: ../include/openssl/bn.h ../include/openssl/buffer.h ca.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -238,7 +232,7 @@ ca.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h ca.o: ../include/openssl/sha.h ../include/openssl/stack.h ca.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h ca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -ca.o: ../include/openssl/x509v3.h apps.h ca.c +ca.o: ../include/openssl/x509v3.h apps.h ca.c progs.h ciphers.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ciphers.o: ../include/openssl/buffer.h ../include/openssl/comp.h ciphers.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -259,7 +253,7 @@ ciphers.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h ciphers.o: ../include/openssl/stack.h ../include/openssl/symhacks.h ciphers.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h ciphers.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -ciphers.o: ../include/openssl/x509v3.h apps.h ciphers.c +ciphers.o: ../include/openssl/x509v3.h apps.h ciphers.c progs.h cms.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h cms.o: ../include/openssl/buffer.h ../include/openssl/cms.h cms.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -275,7 +269,7 @@ cms.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h cms.o: ../include/openssl/sha.h ../include/openssl/stack.h cms.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h cms.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -cms.o: ../include/openssl/x509v3.h apps.h cms.c +cms.o: ../include/openssl/x509v3.h apps.h cms.c progs.h crl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h crl.o: ../include/openssl/buffer.h ../include/openssl/conf.h crl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -291,6 +285,7 @@ crl.o: ../include/openssl/safestack.h ../include/openssl/sha.h crl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h crl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h crl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h crl.c +crl.o: progs.h crl2p7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h crl2p7.o: ../include/openssl/buffer.h ../include/openssl/conf.h crl2p7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -306,7 +301,7 @@ crl2p7.o: ../include/openssl/safestack.h ../include/openssl/sha.h crl2p7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h crl2p7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h crl2p7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -crl2p7.o: crl2p7.c +crl2p7.o: crl2p7.c progs.h dgst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h dgst.o: ../include/openssl/buffer.h ../include/openssl/conf.h dgst.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -322,23 +317,24 @@ dgst.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h dgst.o: ../include/openssl/sha.h ../include/openssl/stack.h dgst.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h dgst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -dgst.o: ../include/openssl/x509v3.h apps.h dgst.c -dh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h -dh.o: ../include/openssl/bn.h ../include/openssl/buffer.h -dh.o: ../include/openssl/conf.h ../include/openssl/crypto.h -dh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h -dh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h -dh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h -dh.o: ../include/openssl/err.h ../include/openssl/evp.h -dh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h -dh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h -dh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h -dh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h -dh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h -dh.o: ../include/openssl/safestack.h ../include/openssl/sha.h -dh.o: ../include/openssl/stack.h ../include/openssl/symhacks.h -dh.o: ../include/openssl/txt_db.h ../include/openssl/x509.h -dh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dh.c +dgst.o: ../include/openssl/x509v3.h apps.h dgst.c progs.h +dhparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h +dhparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h +dhparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h +dhparam.o: ../include/openssl/dh.h ../include/openssl/dsa.h +dhparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h +dhparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h +dhparam.o: ../include/openssl/engine.h ../include/openssl/err.h +dhparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h +dhparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h +dhparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h +dhparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h +dhparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h +dhparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h +dhparam.o: ../include/openssl/sha.h ../include/openssl/stack.h +dhparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h +dhparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h +dhparam.o: ../include/openssl/x509v3.h apps.h dhparam.c progs.h dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -355,6 +351,7 @@ dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c +dsa.o: progs.h dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -371,7 +368,7 @@ dsaparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h dsaparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h dsaparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -dsaparam.o: dsaparam.c +dsaparam.o: dsaparam.c progs.h ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -387,6 +384,7 @@ ec.o: ../include/openssl/safestack.h ../include/openssl/sha.h ec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h ec.o: ../include/openssl/txt_db.h ../include/openssl/x509.h ec.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ec.c +ec.o: progs.h ecparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ecparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h ecparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -402,7 +400,7 @@ ecparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h ecparam.o: ../include/openssl/sha.h ../include/openssl/stack.h ecparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h ecparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c +ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c progs.h enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h enc.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -419,6 +417,7 @@ enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h enc.o: ../include/openssl/txt_db.h ../include/openssl/x509.h enc.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h enc.c +enc.o: progs.h engine.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h engine.o: ../include/openssl/buffer.h ../include/openssl/comp.h engine.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -439,7 +438,7 @@ engine.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h engine.o: ../include/openssl/stack.h ../include/openssl/symhacks.h engine.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h engine.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -engine.o: ../include/openssl/x509v3.h apps.h engine.c +engine.o: ../include/openssl/x509v3.h apps.h engine.c progs.h errstr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h errstr.o: ../include/openssl/buffer.h ../include/openssl/comp.h errstr.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -460,24 +459,7 @@ errstr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h errstr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h errstr.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h errstr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -errstr.o: ../include/openssl/x509v3.h apps.h errstr.c -gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h -gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h -gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h -gendh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h -gendh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h -gendh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h -gendh.o: ../include/openssl/err.h ../include/openssl/evp.h -gendh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h -gendh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h -gendh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h -gendh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h -gendh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h -gendh.o: ../include/openssl/rand.h ../include/openssl/safestack.h -gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h -gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h -gendh.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -gendh.o: ../include/openssl/x509v3.h apps.h gendh.c +errstr.o: ../include/openssl/x509v3.h apps.h errstr.c progs.h gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -494,7 +476,7 @@ gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -gendsa.o: gendsa.c +gendsa.o: gendsa.c progs.h genpkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h genpkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h genpkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -510,7 +492,7 @@ genpkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h genpkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h genpkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h genpkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -genpkey.o: genpkey.c +genpkey.o: genpkey.c progs.h genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -527,7 +509,7 @@ genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h genrsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -genrsa.o: ../include/openssl/x509v3.h apps.h genrsa.c +genrsa.o: ../include/openssl/x509v3.h apps.h genrsa.c progs.h nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -543,6 +525,7 @@ nseq.o: ../include/openssl/safestack.h ../include/openssl/sha.h nseq.o: ../include/openssl/stack.h ../include/openssl/symhacks.h nseq.o: ../include/openssl/txt_db.h ../include/openssl/x509.h nseq.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h nseq.c +nseq.o: progs.h ocsp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ocsp.o: ../include/openssl/bn.h ../include/openssl/buffer.h ocsp.o: ../include/openssl/comp.h ../include/openssl/conf.h @@ -564,6 +547,7 @@ ocsp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h ocsp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h ocsp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h ocsp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ocsp.c +ocsp.o: progs.h openssl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h openssl.o: ../include/openssl/buffer.h ../include/openssl/comp.h openssl.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -586,6 +570,20 @@ openssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h openssl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h openssl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h openssl.o: openssl.c progs.h s_apps.h +opt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h +opt.o: ../include/openssl/buffer.h ../include/openssl/conf.h +opt.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h +opt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h +opt.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h +opt.o: ../include/openssl/evp.h ../include/openssl/lhash.h +opt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h +opt.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h +opt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h +opt.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h +opt.o: ../include/openssl/sha.h ../include/openssl/stack.h +opt.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h +opt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h +opt.o: ../include/openssl/x509v3.h apps.h opt.c progs.h passwd.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h passwd.o: ../include/openssl/buffer.h ../include/openssl/conf.h passwd.o: ../include/openssl/crypto.h ../include/openssl/des.h @@ -601,7 +599,7 @@ passwd.o: ../include/openssl/rand.h ../include/openssl/safestack.h passwd.o: ../include/openssl/sha.h ../include/openssl/stack.h passwd.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h passwd.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -passwd.o: ../include/openssl/x509v3.h apps.h passwd.c +passwd.o: ../include/openssl/x509v3.h apps.h passwd.c progs.h pkcs12.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkcs12.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkcs12.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -617,7 +615,7 @@ pkcs12.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h pkcs12.o: ../include/openssl/sha.h ../include/openssl/stack.h pkcs12.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h pkcs12.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c +pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c progs.h pkcs7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkcs7.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkcs7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -633,7 +631,7 @@ pkcs7.o: ../include/openssl/safestack.h ../include/openssl/sha.h pkcs7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h pkcs7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h pkcs7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -pkcs7.o: pkcs7.c +pkcs7.o: pkcs7.c progs.h pkcs8.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkcs8.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkcs8.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -649,7 +647,7 @@ pkcs8.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h pkcs8.o: ../include/openssl/sha.h ../include/openssl/stack.h pkcs8.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h pkcs8.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c +pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c progs.h pkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -665,6 +663,7 @@ pkey.o: ../include/openssl/safestack.h ../include/openssl/sha.h pkey.o: ../include/openssl/stack.h ../include/openssl/symhacks.h pkey.o: ../include/openssl/txt_db.h ../include/openssl/x509.h pkey.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h pkey.c +pkey.o: progs.h pkeyparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkeyparam.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkeyparam.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -680,7 +679,7 @@ pkeyparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h pkeyparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h pkeyparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h pkeyparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -pkeyparam.o: pkeyparam.c +pkeyparam.o: pkeyparam.c progs.h pkeyutl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h pkeyutl.o: ../include/openssl/buffer.h ../include/openssl/conf.h pkeyutl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -696,7 +695,7 @@ pkeyutl.o: ../include/openssl/safestack.h ../include/openssl/sha.h pkeyutl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h pkeyutl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h pkeyutl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -pkeyutl.o: pkeyutl.c +pkeyutl.o: pkeyutl.c progs.h prime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h prime.o: ../include/openssl/bn.h ../include/openssl/buffer.h prime.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -711,7 +710,7 @@ prime.o: ../include/openssl/safestack.h ../include/openssl/sha.h prime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h prime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h prime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -prime.o: prime.c +prime.o: prime.c progs.h rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -726,7 +725,7 @@ rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h rand.o: ../include/openssl/sha.h ../include/openssl/stack.h rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -rand.o: ../include/openssl/x509v3.h apps.h rand.c +rand.o: ../include/openssl/x509v3.h apps.h progs.h rand.c req.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h req.o: ../include/openssl/bn.h ../include/openssl/buffer.h req.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -743,7 +742,7 @@ req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h req.o: ../include/openssl/sha.h ../include/openssl/stack.h req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h req.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -req.o: ../include/openssl/x509v3.h apps.h req.c +req.o: ../include/openssl/x509v3.h apps.h progs.h req.c rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h rsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -759,7 +758,8 @@ rsa.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h -rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c +rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h progs.h +rsa.o: rsa.c rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -775,7 +775,7 @@ rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c +rsautl.o: ../include/openssl/x509v3.h apps.h progs.h rsautl.c s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s_cb.o: ../include/openssl/bn.h ../include/openssl/buffer.h s_cb.o: ../include/openssl/comp.h ../include/openssl/conf.h @@ -798,7 +798,7 @@ s_cb.o: ../include/openssl/ssl3.h ../include/openssl/stack.h s_cb.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h s_cb.o: ../include/openssl/txt_db.h ../include/openssl/x509.h s_cb.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -s_cb.o: s_apps.h s_cb.c +s_cb.o: progs.h s_apps.h s_cb.c s_client.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s_client.o: ../include/openssl/bn.h ../include/openssl/buffer.h s_client.o: ../include/openssl/comp.h ../include/openssl/conf.h @@ -821,7 +821,7 @@ s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -s_client.o: s_apps.h s_client.c timeouts.h +s_client.o: progs.h s_apps.h s_client.c timeouts.h s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h @@ -845,7 +845,7 @@ s_server.o: ../include/openssl/ssl3.h ../include/openssl/stack.h s_server.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h s_server.o: ../include/openssl/txt_db.h ../include/openssl/x509.h s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -s_server.o: s_apps.h s_server.c timeouts.h +s_server.o: progs.h s_apps.h s_server.c timeouts.h s_socket.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s_socket.o: ../include/openssl/buffer.h ../include/openssl/comp.h s_socket.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -866,7 +866,7 @@ s_socket.o: ../include/openssl/ssl3.h ../include/openssl/stack.h s_socket.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h s_socket.o: ../include/openssl/txt_db.h ../include/openssl/x509.h s_socket.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -s_socket.o: s_apps.h s_socket.c +s_socket.o: progs.h s_apps.h s_socket.c s_time.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s_time.o: ../include/openssl/buffer.h ../include/openssl/comp.h s_time.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -887,7 +887,7 @@ s_time.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h s_time.o: ../include/openssl/stack.h ../include/openssl/symhacks.h s_time.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h s_time.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -s_time.o: ../include/openssl/x509v3.h apps.h s_apps.h s_time.c +s_time.o: ../include/openssl/x509v3.h apps.h progs.h s_apps.h s_time.c sess_id.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h sess_id.o: ../include/openssl/buffer.h ../include/openssl/comp.h sess_id.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -908,7 +908,7 @@ sess_id.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h sess_id.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sess_id.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h sess_id.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -sess_id.o: ../include/openssl/x509v3.h apps.h sess_id.c +sess_id.o: ../include/openssl/x509v3.h apps.h progs.h sess_id.c smime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h smime.o: ../include/openssl/buffer.h ../include/openssl/conf.h smime.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -924,7 +924,7 @@ smime.o: ../include/openssl/safestack.h ../include/openssl/sha.h smime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h smime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h smime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -smime.o: smime.c +smime.o: progs.h smime.c speed.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h speed.o: ../include/openssl/bio.h ../include/openssl/blowfish.h speed.o: ../include/openssl/bn.h ../include/openssl/buffer.h @@ -949,7 +949,7 @@ speed.o: ../include/openssl/sha.h ../include/openssl/stack.h speed.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h speed.o: ../include/openssl/whrlpool.h ../include/openssl/x509.h speed.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -speed.o: speed.c testdsa.h testrsa.h +speed.o: progs.h speed.c testdsa.h testrsa.h spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -965,7 +965,7 @@ spkac.o: ../include/openssl/safestack.h ../include/openssl/sha.h spkac.o: ../include/openssl/stack.h ../include/openssl/symhacks.h spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -spkac.o: spkac.c +spkac.o: progs.h spkac.c srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h srp.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -980,7 +980,8 @@ srp.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h srp.o: ../include/openssl/sha.h ../include/openssl/srp.h srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h srp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h -srp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h srp.c +srp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h progs.h +srp.o: srp.c ts.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h ts.o: ../include/openssl/bn.h ../include/openssl/buffer.h ts.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -998,7 +999,8 @@ ts.o: ../include/openssl/rsa.h ../include/openssl/safestack.h ts.o: ../include/openssl/sha.h ../include/openssl/stack.h ts.o: ../include/openssl/symhacks.h ../include/openssl/ts.h ts.o: ../include/openssl/txt_db.h ../include/openssl/x509.h -ts.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ts.c +ts.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h progs.h +ts.o: ts.c verify.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h verify.o: ../include/openssl/buffer.h ../include/openssl/conf.h verify.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h @@ -1014,7 +1016,7 @@ verify.o: ../include/openssl/safestack.h ../include/openssl/sha.h verify.o: ../include/openssl/stack.h ../include/openssl/symhacks.h verify.o: ../include/openssl/txt_db.h ../include/openssl/x509.h verify.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -verify.o: verify.c +verify.o: progs.h verify.c version.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h version.o: ../include/openssl/buffer.h ../include/openssl/conf.h @@ -1031,7 +1033,7 @@ version.o: ../include/openssl/safestack.h ../include/openssl/sha.h version.o: ../include/openssl/stack.h ../include/openssl/symhacks.h version.o: ../include/openssl/txt_db.h ../include/openssl/x509.h version.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h -version.o: version.c +version.o: progs.h version.c x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h @@ -1048,4 +1050,4 @@ x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h x509.o: ../include/openssl/sha.h ../include/openssl/stack.h x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h -x509.o: ../include/openssl/x509v3.h apps.h x509.c +x509.o: ../include/openssl/x509v3.h apps.h progs.h x509.c diff --git a/apps/app_rand.c b/apps/app_rand.c index 595fc7821c..906144bb6d 100644 --- a/apps/app_rand.c +++ b/apps/app_rand.c @@ -1,4 +1,3 @@ -/* apps/app_rand.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -109,25 +108,23 @@ * */ -#define NON_MAIN #include "apps.h" -#undef NON_MAIN #include #include static int seeded = 0; static int egdsocket = 0; -int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn) +int app_RAND_load_file(const char *file, int dont_warn) { int consider_randfile = (file == NULL); char buffer[200]; #ifdef OPENSSL_SYS_WINDOWS - BIO_printf(bio_e, "Loading 'screen' into random state -"); - BIO_flush(bio_e); + BIO_printf(bio_err, "Loading 'screen' into random state -"); + BIO_flush(bio_err); RAND_screen(); - BIO_printf(bio_e, " done\n"); + BIO_printf(bio_err, " done\n"); #endif if (file == NULL) @@ -143,15 +140,15 @@ int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn) if (file == NULL || !RAND_load_file(file, -1)) { if (RAND_status() == 0) { if (!dont_warn) { - BIO_printf(bio_e, "unable to load 'random state'\n"); - BIO_printf(bio_e, + BIO_printf(bio_err, "unable to load 'random state'\n"); + BIO_printf(bio_err, "This means that the random number generator has not been seeded\n"); - BIO_printf(bio_e, "with much random data.\n"); + BIO_printf(bio_err, "with much random data.\n"); if (consider_randfile) { /* explanation does not apply when a * file is explicitly named */ - BIO_printf(bio_e, + BIO_printf(bio_err, "Consider setting the RANDFILE environment variable to point at a file that\n"); - BIO_printf(bio_e, + BIO_printf(bio_err, "'random' data can be kept in (the file will be overwritten).\n"); } } @@ -193,7 +190,7 @@ long app_RAND_load_files(char *name) return (tot); } -int app_RAND_write_file(const char *file, BIO *bio_e) +int app_RAND_write_file(const char *file) { char buffer[200]; @@ -208,7 +205,7 @@ int app_RAND_write_file(const char *file, BIO *bio_e) if (file == NULL) file = RAND_file_name(buffer, sizeof buffer); if (file == NULL || !RAND_write_file(file)) { - BIO_printf(bio_e, "unable to write 'random state'\n"); + BIO_printf(bio_err, "unable to write 'random state'\n"); return 0; } return 1; diff --git a/apps/apps.c b/apps/apps.c index 76e0ee3c13..7440d392c4 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1,4 +1,3 @@ -/* apps/apps.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -143,10 +142,9 @@ #ifndef OPENSSL_NO_JPAKE # include #endif +#include -#define NON_MAIN #include "apps.h" -#undef NON_MAIN #ifdef _WIN32 static int WIN32_rename(const char *from, const char *to); @@ -168,285 +166,58 @@ static int set_multi_opts(unsigned long *flags, const char *arg, #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) /* Looks like this stuff is worth moving into separate function */ -static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, +static EVP_PKEY *load_netscape_key(BIO *key, const char *file, const char *key_descrip, int format); #endif int app_init(long mesgwin); -#ifdef undef /* never finished - probably never will be - * :-) */ -int args_from_file(char *file, int *argc, char **argv[]) -{ - FILE *fp; - int num, i; - unsigned int len; - static char *buf = NULL; - static char **arg = NULL; - char *p; - - fp = fopen(file, "r"); - if (fp == NULL) - return (0); - - if (fseek(fp, 0, SEEK_END) == 0) - len = ftell(fp), rewind(fp); - else - len = -1; - if (len <= 0) { - fclose(fp); - return (0); - } - - *argc = 0; - *argv = NULL; - if (buf != NULL) - OPENSSL_free(buf); - buf = (char *)OPENSSL_malloc(len + 1); - if (buf == NULL) - return (0); - - len = fread(buf, 1, len, fp); - if (len <= 1) - return (0); - buf[len] = '\0'; - - i = 0; - for (p = buf; *p; p++) - if (*p == '\n') - i++; - if (arg != NULL) - OPENSSL_free(arg); - arg = (char **)OPENSSL_malloc(sizeof(char *) * (i * 2)); - - *argv = arg; - num = 0; - p = buf; - for (;;) { - if (!*p) - break; - if (*p == '#') { /* comment line */ - while (*p && (*p != '\n')) - p++; - continue; - } - /* else we have a line */ - *(arg++) = p; - num++; - while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n'))) - p++; - if (!*p) - break; - if (*p == '\n') { - *(p++) = '\0'; - continue; - } - /* else it is a tab or space */ - p++; - while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) - p++; - if (!*p) - break; - if (*p == '\n') { - p++; - continue; - } - *(arg++) = p++; - num++; - while (*p && (*p != '\n')) - p++; - if (!*p) - break; - /* else *p == '\n' */ - *(p++) = '\0'; - } - *argc = num; - return (1); -} -#endif - -int str2fmt(char *s) -{ - if (s == NULL) - return FORMAT_UNDEF; - if ((*s == 'D') || (*s == 'd')) - return (FORMAT_ASN1); - else if ((*s == 'T') || (*s == 't')) - return (FORMAT_TEXT); - else if ((strcmp(s, "NSS") == 0) || (strcmp(s, "nss") == 0)) - return (FORMAT_NSS); - else if ((*s == 'N') || (*s == 'n')) - return (FORMAT_NETSCAPE); - else if ((*s == 'S') || (*s == 's')) - return (FORMAT_SMIME); - else if ((*s == 'M') || (*s == 'm')) - return (FORMAT_MSBLOB); - else if ((*s == '1') - || (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0) - || (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0)) - return (FORMAT_PKCS12); - else if ((*s == 'E') || (*s == 'e')) - return (FORMAT_ENGINE); - else if ((*s == 'H') || (*s == 'h')) - return FORMAT_HTTP; - else if ((*s == 'P') || (*s == 'p')) { - if (s[1] == 'V' || s[1] == 'v') - return FORMAT_PVK; - else - return (FORMAT_PEM); - } else - return (FORMAT_UNDEF); -} - -#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_NETWARE) -void program_name(char *in, char *out, int size) -{ - int i, n; - char *p = NULL; - - n = strlen(in); - /* find the last '/', '\' or ':' */ - for (i = n - 1; i > 0; i--) { - if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) { - p = &(in[i + 1]); - break; - } - } - if (p == NULL) - p = in; - n = strlen(p); - -# if defined(OPENSSL_SYS_NETWARE) - /* strip off trailing .nlm if present. */ - if ((n > 4) && (p[n - 4] == '.') && - ((p[n - 3] == 'n') || (p[n - 3] == 'N')) && - ((p[n - 2] == 'l') || (p[n - 2] == 'L')) && - ((p[n - 1] == 'm') || (p[n - 1] == 'M'))) - n -= 4; -# else - /* strip off trailing .exe if present. */ - if ((n > 4) && (p[n - 4] == '.') && - ((p[n - 3] == 'e') || (p[n - 3] == 'E')) && - ((p[n - 2] == 'x') || (p[n - 2] == 'X')) && - ((p[n - 1] == 'e') || (p[n - 1] == 'E'))) - n -= 4; -# endif - - if (n > size - 1) - n = size - 1; - - for (i = 0; i < n; i++) { - if ((p[i] >= 'A') && (p[i] <= 'Z')) - out[i] = p[i] - 'A' + 'a'; - else - out[i] = p[i]; - } - out[n] = '\0'; -} -#else -# ifdef OPENSSL_SYS_VMS -void program_name(char *in, char *out, int size) +int chopup_args(ARGS *arg, char *buf) { - char *p = in, *q; - char *chars = ":]>"; - - while (*chars != '\0') { - q = strrchr(p, *chars); - if (q > p) - p = q + 1; - chars++; - } + int quoted; + char c, *p; - q = strrchr(p, '.'); - if (q == NULL) - q = p + strlen(p); - strncpy(out, p, size - 1); - if (q - p >= size) { - out[size - 1] = '\0'; - } else { - out[q - p] = '\0'; - } -} -# else -void program_name(char *in, char *out, int size) -{ - char *p; - - p = strrchr(in, '/'); - if (p != NULL) - p++; - else - p = in; - BUF_strlcpy(out, p, size); -} -# endif -#endif - -int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]) -{ - int num, i; - char *p; - - *argc = 0; - *argv = NULL; - - i = 0; - if (arg->count == 0) { - arg->count = 20; - arg->data = (char **)OPENSSL_malloc(sizeof(char *) * arg->count); - if (arg->data == NULL) + arg->argc = 0; + if (arg->size == 0) { + arg->size = 20; + arg->argv = (char **)OPENSSL_malloc(sizeof(char *) * arg->size); + if (arg->argv == NULL) return 0; } - for (i = 0; i < arg->count; i++) - arg->data[i] = NULL; - num = 0; - p = buf; - for (;;) { - /* first scan over white space */ - if (!*p) - break; - while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n'))) + for (p = buf;;) { + /* Skip whitespace. */ + while (*p && isspace(*p)) p++; if (!*p) break; /* The start of something good :-) */ - if (num >= arg->count) { - char **tmp_p; - int tlen = arg->count + 20; - tmp_p = (char **)OPENSSL_realloc(arg->data, - sizeof(char *) * tlen); - if (tmp_p == NULL) + if (arg->argc >= arg->size) { + arg->size += 20; + arg->argv = (char **)OPENSSL_realloc(arg->argv, + sizeof(char *) * arg->size); + if (arg->argv == NULL) return 0; - arg->data = tmp_p; - arg->count = tlen; - /* initialize newly allocated data */ - for (i = num; i < arg->count; i++) - arg->data[i] = NULL; } - arg->data[num++] = p; + quoted = *p == '\'' || *p == '"'; + if (quoted) + c = *p++; + arg->argv[arg->argc++] = p; /* now look for the end of this */ - if ((*p == '\'') || (*p == '\"')) { /* scan for closing quote */ - i = *(p++); - arg->data[num - 1]++; /* jump over quote */ - while (*p && (*p != i)) + if (quoted) { + while (*p && *p != c) p++; - *p = '\0'; + *p++ = '\0'; } else { - while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n'))) + while (*p && !isspace(*p)) p++; - - if (*p == '\0') - p--; - else - *p = '\0'; + if (*p) + *p++ = '\0'; } - p++; } - *argc = num; - *argv = arg->data; + arg->argv[arg->argc] = NULL; return (1); } @@ -457,6 +228,14 @@ int app_init(long mesgwin) } #endif +int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, const char *CApath) +{ + if (CAfile == NULL && CApath == NULL) + return SSL_CTX_set_default_verify_paths(ctx); + return SSL_CTX_load_verify_locations(ctx, CAfile, CApath); +} + int dump_cert_text(BIO *out, X509 *x) { char *p; @@ -573,7 +352,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) int ok = 0; char *buff = NULL; int ui_flags = 0; - char *prompt = NULL; + char *prompt; prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); if (!prompt) { @@ -629,9 +408,9 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) return res; } -static char *app_get_pass(BIO *err, char *arg, int keepbio); +static char *app_get_pass(char *arg, int keepbio); -int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) +int app_passwd(char *arg1, char *arg2, char **pass1, char **pass2) { int same; if (!arg2 || !arg1 || strcmp(arg1, arg2)) @@ -639,13 +418,13 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) else same = 1; if (arg1) { - *pass1 = app_get_pass(err, arg1, same); + *pass1 = app_get_pass(arg1, same); if (!*pass1) return 0; } else if (pass1) *pass1 = NULL; if (arg2) { - *pass2 = app_get_pass(err, arg2, same ? 2 : 0); + *pass2 = app_get_pass(arg2, same ? 2 : 0); if (!*pass2) return 0; } else if (pass2) @@ -653,7 +432,7 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) return 1; } -static char *app_get_pass(BIO *err, char *arg, int keepbio) +static char *app_get_pass(char *arg, int keepbio) { char *tmp, tpass[APP_PASS_LEN]; static BIO *pwdbio = NULL; @@ -663,7 +442,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) if (!strncmp(arg, "env:", 4)) { tmp = getenv(arg + 4); if (!tmp) { - BIO_printf(err, "Can't read environment variable %s\n", arg + 4); + BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4); return NULL; } return BUF_strdup(tmp); @@ -672,7 +451,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) if (!strncmp(arg, "file:", 5)) { pwdbio = BIO_new_file(arg + 5, "r"); if (!pwdbio) { - BIO_printf(err, "Can't open file %s\n", arg + 5); + BIO_printf(bio_err, "Can't open file %s\n", arg + 5); return NULL; } #if !defined(_WIN32) @@ -690,7 +469,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) if (i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE); if ((i < 0) || !pwdbio) { - BIO_printf(err, "Can't access file descriptor %s\n", arg + 3); + BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3); return NULL; } /* @@ -700,13 +479,13 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) pwdbio = BIO_push(btmp, pwdbio); #endif } else if (!strcmp(arg, "stdin")) { - pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); + pwdbio = dup_bio_in(); if (!pwdbio) { - BIO_printf(err, "Can't open BIO for stdin\n"); + BIO_printf(bio_err, "Can't open BIO for stdin\n"); return NULL; } } else { - BIO_printf(err, "Invalid password argument \"%s\"\n", arg); + BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg); return NULL; } } @@ -716,7 +495,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) pwdbio = NULL; } if (i <= 0) { - BIO_printf(err, "Error reading password from BIO\n"); + BIO_printf(bio_err, "Error reading password from BIO\n"); return NULL; } tmp = strchr(tpass, '\n'); @@ -725,7 +504,7 @@ static char *app_get_pass(BIO *err, char *arg, int keepbio) return BUF_strdup(tpass); } -int add_oid_section(BIO *err, CONF *conf) +int add_oid_section(CONF *conf) { char *p; STACK_OF(CONF_VALUE) *sktmp; @@ -736,13 +515,13 @@ int add_oid_section(BIO *err, CONF *conf) return 1; } if (!(sktmp = NCONF_get_section(conf, p))) { - BIO_printf(err, "problem loading oid section %s\n", p); + BIO_printf(bio_err, "problem loading oid section %s\n", p); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { cnf = sk_CONF_VALUE_value(sktmp, i); if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { - BIO_printf(err, "problem creating object %s=%s\n", + BIO_printf(bio_err, "problem creating object %s=%s\n", cnf->name, cnf->value); return 0; } @@ -750,7 +529,7 @@ int add_oid_section(BIO *err, CONF *conf) return 1; } -static int load_pkcs12(BIO *err, BIO *in, const char *desc, +static int load_pkcs12(BIO *in, const char *desc, pem_password_cb *pem_cb, void *cb_data, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) { @@ -760,7 +539,7 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc, PKCS12 *p12; p12 = d2i_PKCS12_bio(in, NULL); if (p12 == NULL) { - BIO_printf(err, "Error loading PKCS12 file for %s\n", desc); + BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc); goto die; } /* See if an empty password will do */ @@ -771,13 +550,13 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc, pem_cb = (pem_password_cb *)password_callback; len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); if (len < 0) { - BIO_printf(err, "Passpharse callback error for %s\n", desc); + BIO_printf(bio_err, "Passphrase callback error for %s\n", desc); goto die; } if (len < PEM_BUFSIZE) tpass[len] = 0; if (!PKCS12_verify_mac(p12, tpass, len)) { - BIO_printf(err, + BIO_printf(bio_err, "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc); goto die; @@ -790,8 +569,7 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc, return ret; } -int load_cert_crl_http(const char *url, BIO *err, - X509 **pcert, X509_CRL **pcrl) +int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl) { char *host = NULL, *port = NULL, *path = NULL; BIO *bio = NULL; @@ -800,8 +578,7 @@ int load_cert_crl_http(const char *url, BIO *err, if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) goto err; if (use_ssl) { - if (err) - BIO_puts(err, "https not supported\n"); + BIO_puts(bio_err, "https not supported\n"); goto err; } bio = BIO_new_connect(host); @@ -817,8 +594,7 @@ int load_cert_crl_http(const char *url, BIO *err, if (pcert) { do { rv = X509_http_nbio(rctx, pcert); - } - while (rv == -1); + } while (rv == -1); } else { do { rv = X509_CRL_http_nbio(rctx, pcrl); @@ -837,40 +613,31 @@ int load_cert_crl_http(const char *url, BIO *err, if (rctx) OCSP_REQ_CTX_free(rctx); if (rv != 1) { - if (bio && err) - BIO_printf(bio_err, "Error loading %s from %s\n", - pcert ? "certificate" : "CRL", url); + BIO_printf(bio_err, "Error loading %s from %s\n", + pcert ? "certificate" : "CRL", url); ERR_print_errors(bio_err); } return rv; } -X509 *load_cert(BIO *err, const char *file, int format, +X509 *load_cert(const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip) { X509 *x = NULL; BIO *cert; if (format == FORMAT_HTTP) { - load_cert_crl_http(file, err, &x, NULL); + load_cert_crl_http(file, &x, NULL); return x; } - if ((cert = BIO_new(BIO_s_file())) == NULL) { - ERR_print_errors(err); - goto end; - } - if (file == NULL) { - setbuf(stdin, NULL); /* don't do buffered reads */ - BIO_set_fp(cert, stdin, BIO_NOCLOSE); - } else { - if (BIO_read_filename(cert, file) <= 0) { - BIO_printf(err, "Error opening %s %s\n", cert_descrip, file); - ERR_print_errors(err); - goto end; - } - } + unbuffer(stdin); + cert = dup_bio_in(); + } else + cert = bio_open_default(file, RB(format)); + if (cert == NULL) + goto end; if (format == FORMAT_ASN1) x = d2i_X509_bio(cert, NULL); @@ -883,7 +650,7 @@ X509 *load_cert(BIO *err, const char *file, int format, if ((strncmp(NETSCAPE_CERT_HDR, (char *)nx->header->data, nx->header->length) != 0)) { NETSCAPE_X509_free(nx); - BIO_printf(err, "Error reading header on certificate\n"); + BIO_printf(bio_err, "Error reading header on certificate\n"); goto end; } x = nx->cert; @@ -893,16 +660,16 @@ X509 *load_cert(BIO *err, const char *file, int format, x = PEM_read_bio_X509_AUX(cert, NULL, (pem_password_cb *)password_callback, NULL); else if (format == FORMAT_PKCS12) { - if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, NULL, &x, NULL)) + if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL)) goto end; } else { - BIO_printf(err, "bad input format specified for %s\n", cert_descrip); + BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip); goto end; } end: if (x == NULL) { - BIO_printf(err, "unable to load certificate\n"); - ERR_print_errors(err); + BIO_printf(bio_err, "unable to load certificate\n"); + ERR_print_errors(bio_err); } if (cert != NULL) BIO_free(cert); @@ -915,24 +682,13 @@ X509_CRL *load_crl(const char *infile, int format) BIO *in = NULL; if (format == FORMAT_HTTP) { - load_cert_crl_http(infile, bio_err, NULL, &x); + load_cert_crl_http(infile, NULL, &x); return x; } - in = BIO_new(BIO_s_file()); - if (in == NULL) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, RB(format)); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } if (format == FORMAT_ASN1) x = d2i_X509_CRL_bio(in, NULL); else if (format == FORMAT_PEM) @@ -952,7 +708,7 @@ X509_CRL *load_crl(const char *infile, int format) return (x); } -EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, +EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { BIO *key = NULL; @@ -963,36 +719,30 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, cb_data.prompt_info = file; if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { - BIO_printf(err, "no keyfile specified\n"); + BIO_printf(bio_err, "no keyfile specified\n"); goto end; } #ifndef OPENSSL_NO_ENGINE if (format == FORMAT_ENGINE) { if (!e) - BIO_printf(err, "no engine specified\n"); + BIO_printf(bio_err, "no engine specified\n"); else { pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data); if (!pkey) { - BIO_printf(err, "cannot load %s from engine\n", key_descrip); - ERR_print_errors(err); + BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); + ERR_print_errors(bio_err); } } goto end; } #endif - key = BIO_new(BIO_s_file()); - if (key == NULL) { - ERR_print_errors(err); - goto end; - } if (file == NULL && maybe_stdin) { - setbuf(stdin, NULL); /* don't do buffered reads */ - BIO_set_fp(key, stdin, BIO_NOCLOSE); - } else if (BIO_read_filename(key, file) <= 0) { - BIO_printf(err, "Error opening %s %s\n", key_descrip, file); - ERR_print_errors(err); + unbuffer(stdin); + key = dup_bio_in(); + } else + key = bio_open_default(file, RB(format)); + if (key == NULL) goto end; - } if (format == FORMAT_ASN1) { pkey = d2i_PrivateKey_bio(key, NULL); } else if (format == FORMAT_PEM) { @@ -1001,11 +751,11 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, &cb_data); } #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) - else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) - pkey = load_netscape_key(err, key, file, key_descrip, format); + else if (format == FORMAT_NETSCAPE) + pkey = load_netscape_key(key, file, key_descrip, format); #endif else if (format == FORMAT_PKCS12) { - if (!load_pkcs12(err, key, key_descrip, + if (!load_pkcs12(key, key_descrip, (pem_password_cb *)password_callback, &cb_data, &pkey, NULL, NULL)) goto end; @@ -1018,20 +768,27 @@ EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, &cb_data); #endif else { - BIO_printf(err, "bad input format specified for key file\n"); + BIO_printf(bio_err, "bad input format specified for key file\n"); goto end; } end: if (key != NULL) BIO_free(key); if (pkey == NULL) { - BIO_printf(err, "unable to load %s\n", key_descrip); - ERR_print_errors(err); + BIO_printf(bio_err, "unable to load %s\n", key_descrip); + ERR_print_errors(bio_err); } return (pkey); } -EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, +static const char *key_file_format(int format) +{ + if (format == FORMAT_PEM || format == FORMAT_PEMRSA) + return "r"; + return "rb"; +} + +EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { BIO *key = NULL; @@ -1042,7 +799,7 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, cb_data.prompt_info = file; if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { - BIO_printf(err, "no keyfile specified\n"); + BIO_printf(bio_err, "no keyfile specified\n"); goto end; } #ifndef OPENSSL_NO_ENGINE @@ -1054,19 +811,13 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, goto end; } #endif - key = BIO_new(BIO_s_file()); - if (key == NULL) { - ERR_print_errors(err); - goto end; - } if (file == NULL && maybe_stdin) { - setbuf(stdin, NULL); /* don't do buffered reads */ - BIO_set_fp(key, stdin, BIO_NOCLOSE); - } else if (BIO_read_filename(key, file) <= 0) { - BIO_printf(err, "Error opening %s %s\n", key_descrip, file); - ERR_print_errors(err); + unbuffer(stdin); + key = dup_bio_in(); + } else + key = bio_open_default(file, key_file_format(format)); + if (key == NULL) goto end; - } if (format == FORMAT_ASN1) { pkey = d2i_PUBKEY_bio(key, NULL); } @@ -1101,26 +852,23 @@ EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, &cb_data); } #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) - else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC) - pkey = load_netscape_key(err, key, file, key_descrip, format); + else if (format == FORMAT_NETSCAPE) + pkey = load_netscape_key(key, file, key_descrip, format); #endif #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) else if (format == FORMAT_MSBLOB) pkey = b2i_PublicKey_bio(key); #endif - else { - BIO_printf(err, "bad input format specified for key file\n"); - goto end; - } end: - BIO_free(key); + if (key != NULL) + BIO_free(key); if (pkey == NULL) - BIO_printf(err, "unable to load %s\n", key_descrip); + BIO_printf(bio_err, "unable to load %s\n", key_descrip); return (pkey); } #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA) -static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, +static EVP_PKEY *load_netscape_key(BIO *key, const char *file, const char *key_descrip, int format) { EVP_PKEY *pkey; @@ -1142,13 +890,12 @@ static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, if (i == 0) break; if (i < 0) { - BIO_printf(err, "Error reading %s %s", key_descrip, file); + BIO_printf(bio_err, "Error reading %s %s", key_descrip, file); goto error; } } p = (unsigned char *)buf->data; - rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL, - (format == FORMAT_IISSGC ? 1 : 0)); + rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL, 0); if (rsa == NULL) goto error; BUF_MEM_free(buf); @@ -1161,7 +908,7 @@ static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file, } #endif /* ndef OPENSSL_NO_RC4 */ -static int load_certs_crls(BIO *err, const char *file, int format, +static int load_certs_crls(const char *file, int format, const char *pass, ENGINE *e, const char *desc, STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls) @@ -1177,20 +924,13 @@ static int load_certs_crls(BIO *err, const char *file, int format, cb_data.prompt_info = file; if (format != FORMAT_PEM) { - BIO_printf(err, "bad input format specified for %s\n", desc); + BIO_printf(bio_err, "bad input format specified for %s\n", desc); return 0; } - if (file == NULL) - bio = BIO_new_fp(stdin, BIO_NOCLOSE); - else - bio = BIO_new_file(file, "r"); - - if (bio == NULL) { - BIO_printf(err, "Error opening %s %s\n", desc, file ? file : "stdin"); - ERR_print_errors(err); + bio = bio_open_default(file, "r"); + if (bio == NULL) return 0; - } xis = PEM_X509_INFO_read_bio(bio, NULL, (pem_password_cb *)password_callback, @@ -1244,27 +984,27 @@ static int load_certs_crls(BIO *err, const char *file, int format, sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); *pcrls = NULL; } - BIO_printf(err, "unable to load %s\n", + BIO_printf(bio_err, "unable to load %s\n", pcerts ? "certificates" : "CRLs"); - ERR_print_errors(err); + ERR_print_errors(bio_err); } return rv; } -STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, +STACK_OF(X509) *load_certs(const char *file, int format, const char *pass, ENGINE *e, const char *desc) { STACK_OF(X509) *certs; - if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL)) + if (!load_certs_crls(file, format, pass, e, desc, &certs, NULL)) return NULL; return certs; } -STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, +STACK_OF(X509_CRL) *load_crls(const char *file, int format, const char *pass, ENGINE *e, const char *desc) { STACK_OF(X509_CRL) *crls; - if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls)) + if (!load_certs_crls(file, format, pass, e, desc, NULL, &crls)) return NULL; return crls; } @@ -1469,18 +1209,56 @@ void print_name(BIO *out, const char *title, X509_NAME *nm, } } -X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) +void print_bignum_var(BIO *out, BIGNUM *in, const char *var, + int len, unsigned char *buffer) { - X509_STORE *store; + BIO_printf(out, " static unsigned char %s_%d[] = {", var, len); + if (BN_is_zero(in)) + BIO_printf(out, "\n\t0x00"); + else { + int i, l; + + l = BN_bn2bin(in, buffer); + for (i = 0; i < l; i++) { + if ((i % 10) == 0) + BIO_printf(out, "\n\t"); + if (i < l - 1) + BIO_printf(out, "0x%02X, ", buffer[i]); + else + BIO_printf(out, "0x%02X", buffer[i]); + } + } + BIO_printf(out, "\n };\n"); +} +void print_array(BIO *out, const char* title, int len, const unsigned char* d) +{ + int i; + + BIO_printf(out, "unsigned char %s[%d] = {", title, len); + for (i = 0; i < len; i++) { + if ((i % 10) == 0) + BIO_printf(out, "\n "); + if (i < len - 1) + BIO_printf(out, "0x%02X, ", d[i]); + else + BIO_printf(out, "0x%02X", d[i]); + } + BIO_printf(out, "\n};\n"); +} + +X509_STORE *setup_verify(char *CAfile, char *CApath) +{ + X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup; - if (!(store = X509_STORE_new())) + + if (!store) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; if (CAfile) { if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { - BIO_printf(bp, "Error loading file %s\n", CAfile); + BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto end; } } else @@ -1491,7 +1269,7 @@ X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) goto end; if (CApath) { if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { - BIO_printf(bp, "Error loading directory %s\n", CApath); + BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto end; } } else @@ -1506,7 +1284,7 @@ X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) #ifndef OPENSSL_NO_ENGINE /* Try to load an engine in a shareable library */ -static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) +static ENGINE *try_load_engine(const char *engine, int debug) { ENGINE *e = ENGINE_by_id("dynamic"); if (e) { @@ -1519,34 +1297,34 @@ static ENGINE *try_load_engine(BIO *err, const char *engine, int debug) return e; } -ENGINE *setup_engine(BIO *err, const char *engine, int debug) +ENGINE *setup_engine(const char *engine, int debug) { ENGINE *e = NULL; if (engine) { if (strcmp(engine, "auto") == 0) { - BIO_printf(err, "enabling auto ENGINE support\n"); + BIO_printf(bio_err, "enabling auto ENGINE support\n"); ENGINE_register_all_complete(); return NULL; } if ((e = ENGINE_by_id(engine)) == NULL - && (e = try_load_engine(err, engine, debug)) == NULL) { - BIO_printf(err, "invalid engine \"%s\"\n", engine); - ERR_print_errors(err); + && (e = try_load_engine(engine, debug)) == NULL) { + BIO_printf(bio_err, "invalid engine \"%s\"\n", engine); + ERR_print_errors(bio_err); return NULL; } if (debug) { - ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, err, 0); + ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); } ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { - BIO_printf(err, "can't use that engine\n"); - ERR_print_errors(err); + BIO_printf(bio_err, "can't use that engine\n"); + ERR_print_errors(bio_err); ENGINE_free(e); return NULL; } - BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e)); + BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e)); /* Free our "structural" reference. */ ENGINE_free(e); @@ -1555,46 +1333,6 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug) } #endif -int load_config(BIO *err, CONF *cnf) -{ - static int load_config_called = 0; - if (load_config_called) - return 1; - load_config_called = 1; - if (!cnf) - cnf = config; - if (!cnf) - return 1; - - OPENSSL_load_builtin_modules(); - - if (CONF_modules_load(cnf, NULL, 0) <= 0) { - BIO_printf(err, "Error configuring OpenSSL\n"); - ERR_print_errors(err); - return 0; - } - return 1; -} - -char *make_config_name() -{ - const char *t = X509_get_default_cert_area(); - size_t len; - char *p; - - len = strlen(t) + strlen(OPENSSL_CONF) + 2; - p = OPENSSL_malloc(len); - if (p == NULL) - return NULL; - BUF_strlcpy(p, t, len); -#ifndef OPENSSL_SYS_VMS - BUF_strlcat(p, "/", len); -#endif - BUF_strlcat(p, OPENSSL_CONF, len); - - return p; -} - static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) { const char *n; @@ -1647,20 +1385,16 @@ BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) if (ai == NULL) goto err; - if ((in = BIO_new(BIO_s_file())) == NULL) { - ERR_print_errors(bio_err); - goto err; - } - - if (BIO_read_filename(in, serialfile) <= 0) { + in = BIO_new_file(serialfile, "r"); + if (in == NULL) { if (!create) { perror(serialfile); goto err; - } else { - ret = BN_new(); - if (ret == NULL || !rand_serial(ret, ai)) - BIO_printf(bio_err, "Out of memory\n"); } + ERR_clear_error(); + ret = BN_new(); + if (ret == NULL || !rand_serial(ret, ai)) + BIO_printf(bio_err, "Out of memory\n"); } else { if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { BIO_printf(bio_err, "unable to load number from %s\n", @@ -1716,15 +1450,11 @@ int save_serial(char *serialfile, char *suffix, BIGNUM *serial, #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); #endif - out = BIO_new(BIO_s_file()); + out = BIO_new_file(buf[0], "w"); if (out == NULL) { ERR_print_errors(bio_err); goto err; } - if (BIO_write_filename(out, buf[0]) <= 0) { - perror(serialfile); - goto err; - } if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) { BIO_printf(bio_err, "error converting serial to ASN.1 format\n"); @@ -1828,20 +1558,16 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) { CA_DB *retdb = NULL; TXT_DB *tmpdb = NULL; - BIO *in = BIO_new(BIO_s_file()); + BIO *in; CONF *dbattr_conf = NULL; char buf[1][BSIZE]; long errorline = -1; + in = BIO_new_file(dbfile, "r"); if (in == NULL) { ERR_print_errors(bio_err); goto err; } - if (BIO_read_filename(in, dbfile) <= 0) { - perror(dbfile); - BIO_printf(bio_err, "unable to open '%s'\n", dbfile); - goto err; - } if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) goto err; @@ -1921,14 +1647,9 @@ int index_index(CA_DB *db) int save_index(const char *dbfile, const char *suffix, CA_DB *db) { char buf[3][BSIZE]; - BIO *out = BIO_new(BIO_s_file()); + BIO *out; int j; - if (out == NULL) { - ERR_print_errors(bio_err); - goto err; - } - j = strlen(dbfile) + strlen(suffix); if (j + 6 >= BSIZE) { BIO_printf(bio_err, "file name too long\n"); @@ -1952,22 +1673,22 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); #endif - if (BIO_write_filename(out, buf[0]) <= 0) { + out = BIO_new_file(buf[0], "w"); + if (out == NULL) { perror(dbfile); BIO_printf(bio_err, "unable to open '%s'\n", dbfile); goto err; } j = TXT_DB_write(out, db->db); + BIO_free(out); if (j <= 0) goto err; - BIO_free(out); - - out = BIO_new(BIO_s_file()); + out = BIO_new_file(buf[1], "w"); #ifdef RL_DEBUG BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]); #endif - if (BIO_write_filename(out, buf[1]) <= 0) { + if (out == NULL) { perror(buf[2]); BIO_printf(bio_err, "unable to open '%s'\n", buf[2]); goto err; @@ -2239,189 +1960,6 @@ X509_NAME *parse_name(char *subject, long chtype, int multirdn) return NULL; } -int args_verify(char ***pargs, int *pargc, - int *badarg, BIO *err, X509_VERIFY_PARAM **pm) -{ - ASN1_OBJECT *otmp = NULL; - unsigned long flags = 0; - int i; - int purpose = 0, depth = -1; - char **oldargs = *pargs; - char *arg = **pargs, *argn = (*pargs)[1]; - const X509_VERIFY_PARAM *vpm = NULL; - time_t at_time = 0; - char *hostname = NULL; - char *email = NULL; - char *ipasc = NULL; - if (!strcmp(arg, "-policy")) { - if (!argn) - *badarg = 1; - else { - otmp = OBJ_txt2obj(argn, 0); - if (!otmp) { - BIO_printf(err, "Invalid Policy \"%s\"\n", argn); - *badarg = 1; - } - } - (*pargs)++; - } else if (strcmp(arg, "-purpose") == 0) { - X509_PURPOSE *xptmp; - if (!argn) - *badarg = 1; - else { - i = X509_PURPOSE_get_by_sname(argn); - if (i < 0) { - BIO_printf(err, "unrecognized purpose\n"); - *badarg = 1; - } else { - xptmp = X509_PURPOSE_get0(i); - purpose = X509_PURPOSE_get_id(xptmp); - } - } - (*pargs)++; - } else if (strcmp(arg, "-verify_name") == 0) { - if (!argn) - *badarg = 1; - else { - vpm = X509_VERIFY_PARAM_lookup(argn); - if (!vpm) { - BIO_printf(err, "unrecognized verify name\n"); - *badarg = 1; - } - } - (*pargs)++; - } else if (strcmp(arg, "-verify_depth") == 0) { - if (!argn) - *badarg = 1; - else { - depth = atoi(argn); - if (depth < 0) { - BIO_printf(err, "invalid depth\n"); - *badarg = 1; - } - } - (*pargs)++; - } else if (strcmp(arg, "-attime") == 0) { - if (!argn) - *badarg = 1; - else { - long timestamp; - /* - * interpret the -attime argument as seconds since Epoch - */ - if (sscanf(argn, "%li", ×tamp) != 1) { - BIO_printf(bio_err, "Error parsing timestamp %s\n", argn); - *badarg = 1; - } - /* on some platforms time_t may be a float */ - at_time = (time_t)timestamp; - } - (*pargs)++; - } else if (strcmp(arg, "-verify_hostname") == 0) { - if (!argn) - *badarg = 1; - hostname = argn; - (*pargs)++; - } else if (strcmp(arg, "-verify_email") == 0) { - if (!argn) - *badarg = 1; - email = argn; - (*pargs)++; - } else if (strcmp(arg, "-verify_ip") == 0) { - if (!argn) - *badarg = 1; - ipasc = argn; - (*pargs)++; - } else if (!strcmp(arg, "-ignore_critical")) - flags |= X509_V_FLAG_IGNORE_CRITICAL; - else if (!strcmp(arg, "-issuer_checks")) - flags |= X509_V_FLAG_CB_ISSUER_CHECK; - else if (!strcmp(arg, "-crl_check")) - flags |= X509_V_FLAG_CRL_CHECK; - else if (!strcmp(arg, "-crl_check_all")) - flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL; - else if (!strcmp(arg, "-policy_check")) - flags |= X509_V_FLAG_POLICY_CHECK; - else if (!strcmp(arg, "-explicit_policy")) - flags |= X509_V_FLAG_EXPLICIT_POLICY; - else if (!strcmp(arg, "-inhibit_any")) - flags |= X509_V_FLAG_INHIBIT_ANY; - else if (!strcmp(arg, "-inhibit_map")) - flags |= X509_V_FLAG_INHIBIT_MAP; - else if (!strcmp(arg, "-x509_strict")) - flags |= X509_V_FLAG_X509_STRICT; - else if (!strcmp(arg, "-extended_crl")) - flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; - else if (!strcmp(arg, "-use_deltas")) - flags |= X509_V_FLAG_USE_DELTAS; - else if (!strcmp(arg, "-policy_print")) - flags |= X509_V_FLAG_NOTIFY_POLICY; - else if (!strcmp(arg, "-check_ss_sig")) - flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; - else if (!strcmp(arg, "-trusted_first")) - flags |= X509_V_FLAG_TRUSTED_FIRST; - else if (!strcmp(arg, "-suiteB_128_only")) - flags |= X509_V_FLAG_SUITEB_128_LOS_ONLY; - else if (!strcmp(arg, "-suiteB_128")) - flags |= X509_V_FLAG_SUITEB_128_LOS; - else if (!strcmp(arg, "-suiteB_192")) - flags |= X509_V_FLAG_SUITEB_192_LOS; - else if (!strcmp(arg, "-partial_chain")) - flags |= X509_V_FLAG_PARTIAL_CHAIN; - else if (!strcmp(arg, "-no_alt_chains")) - flags |= X509_V_FLAG_NO_ALT_CHAINS; - else - return 0; - - if (*badarg) { - if (*pm) - X509_VERIFY_PARAM_free(*pm); - *pm = NULL; - goto end; - } - - if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) { - *badarg = 1; - goto end; - } - - if (vpm) - X509_VERIFY_PARAM_set1(*pm, vpm); - - if (otmp) - X509_VERIFY_PARAM_add0_policy(*pm, otmp); - if (flags) - X509_VERIFY_PARAM_set_flags(*pm, flags); - - if (purpose) - X509_VERIFY_PARAM_set_purpose(*pm, purpose); - - if (depth >= 0) - X509_VERIFY_PARAM_set_depth(*pm, depth); - - if (at_time) - X509_VERIFY_PARAM_set_time(*pm, at_time); - - if (hostname && !X509_VERIFY_PARAM_set1_host(*pm, hostname, 0)) - *badarg = 1; - - if (email && !X509_VERIFY_PARAM_set1_email(*pm, email, 0)) - *badarg = 1; - - if (ipasc && !X509_VERIFY_PARAM_set1_ip_asc(*pm, ipasc)) - *badarg = 1; - - end: - - (*pargs)++; - - if (pargc) - *pargc -= *pargs - oldargs; - - return 1; - -} - /* * Read whole contents of a BIO into an allocated memory buffer and return * it. @@ -2495,11 +2033,6 @@ void policies_print(BIO *out, X509_STORE_CTX *ctx) { X509_POLICY_TREE *tree; int explicit_policy; - int free_out = 0; - if (out == NULL) { - out = BIO_new_fp(stderr, BIO_NOCLOSE); - free_out = 1; - } tree = X509_STORE_CTX_get0_policy_tree(ctx); explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); @@ -2508,8 +2041,6 @@ void policies_print(BIO *out, X509_STORE_CTX *ctx) nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); - if (free_out) - BIO_free(out); } #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) @@ -2788,14 +2319,15 @@ void print_cert_checks(BIO *bio, X509 *x, return; if (checkhost) { BIO_printf(bio, "Hostname %s does%s match certificate\n", - checkhost, X509_check_host(x, checkhost, 0, 0, NULL) == 1 - ? "" : " NOT"); + checkhost, + X509_check_host(x, checkhost, 0, 0, NULL) == 1 + ? "" : " NOT"); } if (checkemail) { BIO_printf(bio, "Email %s does%s match certificate\n", - checkemail, X509_check_email(x, checkemail, 0, - 0) ? "" : " NOT"); + checkemail, X509_check_email(x, checkemail, 0, 0) + ? "" : " NOT"); } if (checkip) { @@ -2857,13 +2389,16 @@ static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm) STACK_OF(X509_CRL) *crls = NULL; X509_CRL *crl; STACK_OF(DIST_POINT) *crldp; + + crls = sk_X509_CRL_new_null(); + if (!crls) + return NULL; x = X509_STORE_CTX_get_current_cert(ctx); crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); crl = load_crl_crldp(crldp); sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); if (!crl) return NULL; - crls = sk_X509_CRL_new_null(); sk_X509_CRL_push(crls, crl); /* Try to download delta CRL */ crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL); @@ -2992,15 +2527,14 @@ double app_tminterval(int stop, int usertime) return (ret); } - #elif defined(OPENSSL_SYS_NETWARE) # include double app_tminterval(int stop, int usertime) { - double ret = 0; static clock_t tmstart; static int warning = 1; + double ret = 0; if (usertime && warning) { BIO_printf(bio_err, "To get meaningful results, run " @@ -3016,6 +2550,7 @@ double app_tminterval(int stop, int usertime) return (ret); } + #elif defined(OPENSSL_SYSTEM_VXWORKS) # include @@ -3136,6 +2671,15 @@ double app_tminterval(int stop, int usertime) } #endif +int app_access(const char* name, int flag) +{ +#ifdef _WIN32 + return _access(name, flag); +#else + return access(name, flag); +#endif +} + /* app_isdir section */ #ifdef _WIN32 int app_isdir(const char *name) diff --git a/apps/apps.h b/apps/apps.h index 2e346f9b66..ad17b1a821 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -126,9 +126,18 @@ # include # endif # include +# ifndef OPENSSL_SYS_NETWARE +# include +# endif -int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn); -int app_RAND_write_file(const char *file, BIO *bio_e); +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE) +# define openssl_fdset(a,b) FD_SET((unsigned int)a, b) +# else +# define openssl_fdset(a,b) FD_SET(a, b) +# endif + +int app_RAND_load_file(const char *file, int dont_warn); +int app_RAND_write_file(const char *file); /* * When `file' is NULL, use defaults. `bio_e' is for error messages. */ @@ -138,82 +147,246 @@ long app_RAND_load_files(char *file); /* `file' is a list of files to read, * (see e_os.h). The string is * destroyed! */ -# ifndef MONOLITH - -# define MAIN(a,v) main(a,v) - -# ifndef NON_MAIN -CONF *config = NULL; -BIO *bio_err = NULL; -# else -extern CONF *config; -extern BIO *bio_err; -# endif - -# else - -# define MAIN(a,v) PROG(a,v) extern CONF *config; extern char *default_config_file; +extern BIO *bio_in; +extern BIO *bio_out; extern BIO *bio_err; +BIO *dup_bio_in(void); +BIO *dup_bio_out(void); +BIO *bio_open_default(const char *filename, const char *mode); +void unbuffer(FILE *fp); -# endif +/* Often used in calls to bio_open_default. */ +# define RB(xformat) ((xformat) == FORMAT_ASN1 ? "rb" : "r") +# define WB(xformat) ((xformat) == FORMAT_ASN1 ? "wb" : "w") -# ifndef OPENSSL_SYS_NETWARE -# include -# endif - -# ifdef SIGPIPE -# define do_pipe_sig() signal(SIGPIPE,SIG_IGN) -# else -# define do_pipe_sig() -# endif +/* + * Common verification options. + */ +# define OPT_V_ENUM \ + OPT_V__FIRST=2000, \ + OPT_V_POLICY, OPT_V_PURPOSE, OPT_V_VERIFY_NAME, OPT_V_VERIFY_DEPTH, \ + OPT_V_ATTIME, OPT_V_VERIFY_HOSTNAME, OPT_V_VERIFY_EMAIL, \ + OPT_V_VERIFY_IP, OPT_V_IGNORE_CRITICAL, OPT_V_ISSUER_CHECKS, \ + OPT_V_CRL_CHECK, OPT_V_CRL_CHECK_ALL, OPT_V_POLICY_CHECK, \ + OPT_V_EXPLICIT_POLICY, OPT_V_INHIBIT_ANY, OPT_V_INHIBIT_MAP, \ + OPT_V_X509_STRICT, OPT_V_EXTENDED_CRL, OPT_V_USE_DELTAS, \ + OPT_V_POLICY_PRINT, OPT_V_CHECK_SS_SIG, OPT_V_TRUSTED_FIRST, \ + OPT_V_SUITEB_128_ONLY, OPT_V_SUITEB_128, OPT_V_SUITEB_192, \ + OPT_V_PARTIAL_CHAIN, OPT_V_NO_ALT_CHAINS, \ + OPT_V__LAST + +# define OPT_V_OPTIONS \ + { "policy", OPT_V_POLICY, 's' }, \ + { "purpose", OPT_V_PURPOSE, 's' }, \ + { "verify_name", OPT_V_VERIFY_NAME, 's' }, \ + { "verify_depth", OPT_V_VERIFY_DEPTH, 'p' }, \ + { "attime", OPT_V_ATTIME, 'p' }, \ + { "verify_hostname", OPT_V_VERIFY_HOSTNAME, 's' }, \ + { "verify_email", OPT_V_VERIFY_EMAIL, 's' }, \ + { "verify_ip", OPT_V_VERIFY_IP, 's' }, \ + { "ignore_critical", OPT_V_IGNORE_CRITICAL, '-' }, \ + { "issuer_checks", OPT_V_ISSUER_CHECKS, '-' }, \ + { "crl_check", OPT_V_CRL_CHECK, '-', "Check that peer cert has not been revoked" }, \ + { "crl_check_all", OPT_V_CRL_CHECK_ALL, '-', "Also check all certs in the chain" }, \ + { "policy_check", OPT_V_POLICY_CHECK, '-' }, \ + { "explicit_policy", OPT_V_EXPLICIT_POLICY, '-' }, \ + { "inhibit_any", OPT_V_INHIBIT_ANY, '-' }, \ + { "inhibit_map", OPT_V_INHIBIT_MAP, '-' }, \ + { "x509_strict", OPT_V_X509_STRICT, '-' }, \ + { "extended_crl", OPT_V_EXTENDED_CRL, '-' }, \ + { "use_deltas", OPT_V_USE_DELTAS, '-' }, \ + { "policy_print", OPT_V_POLICY_PRINT, '-' }, \ + { "check_ss_sig", OPT_V_CHECK_SS_SIG, '-' }, \ + { "trusted_first", OPT_V_TRUSTED_FIRST, '-', "Use locally-trusted CA's first in building chain" }, \ + { "suiteB_128_only", OPT_V_SUITEB_128_ONLY, '-' }, \ + { "suiteB_128", OPT_V_SUITEB_128, '-' }, \ + { "suiteB_192", OPT_V_SUITEB_192, '-' }, \ + { "partial_chain", OPT_V_PARTIAL_CHAIN, '-' }, \ + { "no_alt_chains", OPT_V_NO_ALT_CHAINS, '-', "Only use the first cert chain found" } + +# define OPT_V_CASES \ + OPT_V__FIRST: case OPT_V__LAST: break; \ + case OPT_V_POLICY: \ + case OPT_V_PURPOSE: \ + case OPT_V_VERIFY_NAME: \ + case OPT_V_VERIFY_DEPTH: \ + case OPT_V_ATTIME: \ + case OPT_V_VERIFY_HOSTNAME: \ + case OPT_V_VERIFY_EMAIL: \ + case OPT_V_VERIFY_IP: \ + case OPT_V_IGNORE_CRITICAL: \ + case OPT_V_ISSUER_CHECKS: \ + case OPT_V_CRL_CHECK: \ + case OPT_V_CRL_CHECK_ALL: \ + case OPT_V_POLICY_CHECK: \ + case OPT_V_EXPLICIT_POLICY: \ + case OPT_V_INHIBIT_ANY: \ + case OPT_V_INHIBIT_MAP: \ + case OPT_V_X509_STRICT: \ + case OPT_V_EXTENDED_CRL: \ + case OPT_V_USE_DELTAS: \ + case OPT_V_POLICY_PRINT: \ + case OPT_V_CHECK_SS_SIG: \ + case OPT_V_TRUSTED_FIRST: \ + case OPT_V_SUITEB_128_ONLY: \ + case OPT_V_SUITEB_128: \ + case OPT_V_SUITEB_192: \ + case OPT_V_PARTIAL_CHAIN: \ + case OPT_V_NO_ALT_CHAINS -# ifdef OPENSSL_NO_COMP -# define zlib_cleanup() -# else -# define zlib_cleanup() COMP_zlib_cleanup() -# endif +/* + * Common "extended"? options. + */ +# define OPT_X_ENUM \ + OPT_X__FIRST=1000, \ + OPT_X_KEY, OPT_X_CERT, OPT_X_CHAIN, OPT_X_CHAIN_BUILD, \ + OPT_X_CERTFORM, OPT_X_KEYFORM, \ + OPT_X__LAST + +# define OPT_X_OPTIONS \ + { "xkey", OPT_X_KEY, '<' }, \ + { "xcert", OPT_X_CERT, '<' }, \ + { "xchain", OPT_X_CHAIN, '<' }, \ + { "xchain_build", OPT_X_CHAIN_BUILD, '-' }, \ + { "xcertform", OPT_X_CERTFORM, 'F' }, \ + { "xkeyform", OPT_X_KEYFORM, 'F' } + +# define OPT_X_CASES \ + OPT_X__FIRST: case OPT_X__LAST: break; \ + case OPT_X_KEY: \ + case OPT_X_CERT: \ + case OPT_X_CHAIN: \ + case OPT_X_CHAIN_BUILD: \ + case OPT_X_CERTFORM: \ + case OPT_X_KEYFORM -# if defined(MONOLITH) && !defined(OPENSSL_C) -# define apps_startup() \ - do_pipe_sig() -# define apps_shutdown() -# else -# ifndef OPENSSL_NO_ENGINE -# define apps_startup() \ - do { do_pipe_sig(); CRYPTO_malloc_init(); \ - ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ - ENGINE_load_builtin_engines(); setup_ui_method(); } while(0) -# define apps_shutdown() \ - do { CONF_modules_unload(1); destroy_ui_method(); \ - OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \ - CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \ - RAND_cleanup(); \ - ERR_free_strings(); zlib_cleanup();} while(0) -# else -# define apps_startup() \ - do { do_pipe_sig(); CRYPTO_malloc_init(); \ - ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); \ - setup_ui_method(); } while(0) -# define apps_shutdown() \ - do { CONF_modules_unload(1); destroy_ui_method(); \ - OBJ_cleanup(); EVP_cleanup(); \ - CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \ - RAND_cleanup(); \ - ERR_free_strings(); zlib_cleanup(); } while(0) -# endif -# endif +/* + * Common SSL options. + * Any changes here must be coordinated with ../ssl/ssl_conf.c + */ +# define OPT_S_ENUM \ + OPT_S__FIRST=3000, \ + OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \ + OPT_S_BUGS, OPT_S_NOCOMP, OPT_S_ECDHSINGLE, OPT_S_NOTICKET, \ + OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \ + OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_STRICT, OPT_S_SIGALGS, \ + OPT_S_CLIENTSIGALGS, OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, \ + OPT_S_DHPARAM, OPT_S_DEBUGBROKE, \ + OPT_S__LAST + +# define OPT_S_OPTIONS \ + {"no_ssl3", OPT_S_NOSSL3, '-' }, \ + {"no_tls1", OPT_S_NOTLS1, '-' }, \ + {"no_tls1_1", OPT_S_NOTLS1_1, '-' }, \ + {"no_tls1_2", OPT_S_NOTLS1_2, '-' }, \ + {"bugs", OPT_S_BUGS, '-' }, \ + {"no_comp", OPT_S_NOCOMP, '-' }, \ + {"ecdh_single", OPT_S_ECDHSINGLE, '-' }, \ + {"no_ticket", OPT_S_NOTICKET, '-' }, \ + {"serverpref", OPT_S_SERVERPREF, '-' }, \ + {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-' }, \ + {"legacy_server_connect", OPT_S_LEGACYCONN, '-' }, \ + {"no_resumption_on_reneg", OPT_S_ONRESUMP, '-' }, \ + {"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-' }, \ + {"strict", OPT_S_STRICT, '-' }, \ + {"sigalgs", OPT_S_SIGALGS, 's', }, \ + {"client_sigalgs", OPT_S_CLIENTSIGALGS, 's', }, \ + {"curves", OPT_S_CURVES, 's', }, \ + {"named_curve", OPT_S_NAMEDCURVE, 's', }, \ + {"cipher", OPT_S_CIPHER, 's', }, \ + {"dhparam", OPT_S_DHPARAM, '<' }, \ + {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-' } + +# define OPT_S_CASES \ + OPT_S__FIRST: case OPT_S__LAST: break; \ + case OPT_S_NOSSL3: \ + case OPT_S_NOTLS1: \ + case OPT_S_NOTLS1_1: \ + case OPT_S_NOTLS1_2: \ + case OPT_S_BUGS: \ + case OPT_S_NOCOMP: \ + case OPT_S_ECDHSINGLE: \ + case OPT_S_NOTICKET: \ + case OPT_S_SERVERPREF: \ + case OPT_S_LEGACYRENEG: \ + case OPT_S_LEGACYCONN: \ + case OPT_S_ONRESUMP: \ + case OPT_S_NOLEGACYCONN: \ + case OPT_S_STRICT: \ + case OPT_S_SIGALGS: \ + case OPT_S_CLIENTSIGALGS: \ + case OPT_S_CURVES: \ + case OPT_S_NAMEDCURVE: \ + case OPT_S_CIPHER: \ + case OPT_S_DHPARAM: \ + case OPT_S_DEBUGBROKE -# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE) -# define openssl_fdset(a,b) FD_SET((unsigned int)a, b) -# else -# define openssl_fdset(a,b) FD_SET(a, b) -# endif +/* + * Option parsing. + */ +extern const char OPT_HELP_STR[]; +extern const char OPT_MORE_STR[]; +typedef struct options_st { + const char *name; + int retval; + /* + * value type: - no value (also the value zero), n number, p positive + * number, u unsigned, s string, < input file, > output file, f der/pem + * format, F any format identifier. n and u include zero; p does not. + */ + int valtype; + const char *helpstr; +} OPTIONS; + +typedef struct opt_pair_st { + const char *name; + int retval; +} OPT_PAIR; + +/* Flags to pass into opt_format; see FORMAT_xxx, below. */ +# define OPT_FMT_PEMDER (1L << 1) +# define OPT_FMT_PKCS12 (1L << 2) +# define OPT_FMT_SMIME (1L << 3) +# define OPT_FMT_ENGINE (1L << 4) +# define OPT_FMT_MSBLOB (1L << 5) +# define OPT_FMT_NETSCAPE (1L << 6) +# define OPT_FMT_NSS (1L << 7) +# define OPT_FMT_TEXT (1L << 8) +# define OPT_FMT_HTTP (1L << 9) +# define OPT_FMT_PVK (1L << 10) +# define OPT_FMT_ANY ( \ + OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \ + OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NETSCAPE | \ + OPT_FMT_NSS | OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) + +char *opt_progname(const char *argv0); +char *opt_getprog(void); +char *opt_init(int ac, char **av, const OPTIONS * o); +int opt_next(); +int opt_format(const char *s, unsigned long flags, int *result); +int opt_int(const char *arg, int *result); +int opt_ulong(const char *arg, unsigned long *result); +int opt_long(const char *arg, long *result); +int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); +int opt_cipher(const char *name, const EVP_CIPHER **cipherp); +int opt_md(const char *name, const EVP_MD **mdp); +char *opt_arg(void); +char *opt_flag(void); +char *opt_unknown(void); +char *opt_reset(void); +char **opt_rest(void); +int opt_num_rest(void); +int opt_verify(int i, X509_VERIFY_PARAM *vpm); +void opt_help(const OPTIONS * list); +int opt_format_error(const char *s, unsigned long flags); +int opt_next(void); typedef struct args_st { - char **data; - int count; + int size; + int argc; + char **argv; } ARGS; # define PW_MIN_LENGTH 4 @@ -227,53 +400,48 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data); int setup_ui_method(void); void destroy_ui_method(void); -int should_retry(int i); -int args_from_file(char *file, int *argc, char **argv[]); -int str2fmt(char *s); -void program_name(char *in, char *out, int size); -int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[]); +int chopup_args(ARGS *arg, char *buf); # ifdef HEADER_X509_H int dump_cert_text(BIO *out, X509 *x); void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags); # endif +void print_bignum_var(BIO *, BIGNUM *, const char*, int, unsigned char *); +void print_array(BIO *, const char *, int, const unsigned char *); int set_cert_ex(unsigned long *flags, const char *arg); int set_name_ex(unsigned long *flags, const char *arg); int set_ext_copy(int *copy_type, const char *arg); int copy_extensions(X509 *x, X509_REQ *req, int copy_type); -int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2); -int add_oid_section(BIO *err, CONF *conf); -X509 *load_cert(BIO *err, const char *file, int format, +int app_passwd(char *arg1, char *arg2, char **pass1, char **pass2); +int add_oid_section(CONF *conf); +X509 *load_cert(const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); X509_CRL *load_crl(const char *infile, int format); -int load_cert_crl_http(const char *url, BIO *err, - X509 **pcert, X509_CRL **pcrl); -EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, +int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl); +EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip); -EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, +EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip); -STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, +STACK_OF(X509) *load_certs(const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); -STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, +STACK_OF(X509_CRL) *load_crls(const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); -X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath); +X509_STORE *setup_verify(char *CAfile, char *CApath); +int ctx_set_verify_locations(SSL_CTX *ctx, + const char *CAfile, const char *CApath); # ifndef OPENSSL_NO_ENGINE -ENGINE *setup_engine(BIO *err, const char *engine, int debug); +ENGINE *setup_engine(const char *engine, int debug); # endif - # ifndef OPENSSL_NO_OCSP -OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, +OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, const char *path, const char *port, int use_ssl, const STACK_OF(CONF_VALUE) *headers, int req_timeout); # endif -int load_config(BIO *err, CONF *cnf); -char *make_config_name(void); - /* Functions defined in ca.c and also used in ocsp.c */ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str); @@ -318,17 +486,17 @@ int parse_yesno(const char *str, int def); X509_NAME *parse_name(char *str, long chtype, int multirdn); int args_verify(char ***pargs, int *pargc, - int *badarg, BIO *err, X509_VERIFY_PARAM **pm); + int *badarg, X509_VERIFY_PARAM **pm); void policies_print(BIO *out, X509_STORE_CTX *ctx); int bio_to_mem(unsigned char **out, int maxlen, BIO *in); int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value); -int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, +int init_gen_str(EVP_PKEY_CTX **pctx, const char *algname, ENGINE *e, int do_param); -int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts); -int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts); -int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts); # ifndef OPENSSL_NO_PSK extern char *psk_key; @@ -348,6 +516,7 @@ void print_cert_checks(BIO *bio, X509 *x, void store_setup_crl_download(X509_STORE *st); +/* See OPT_FMT_xxx, above. */ # define FORMAT_UNDEF 0 # define FORMAT_ASN1 1 # define FORMAT_TEXT 2 @@ -356,8 +525,6 @@ void store_setup_crl_download(X509_STORE *st); # define FORMAT_PKCS12 5 # define FORMAT_SMIME 6 # define FORMAT_ENGINE 7 -# define FORMAT_IISSGC 8 /* XXX this stupid macro helps us to avoid - * adding yet another param to load_*key() */ # define FORMAT_PEMRSA 9 /* PEM RSAPubicKey format */ # define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ # define FORMAT_MSBLOB 11 /* MS Key blob format */ @@ -376,6 +543,7 @@ void store_setup_crl_download(X509_STORE *st); # define SERIAL_RAND_BITS 64 int app_isdir(const char *); +int app_access(const char *, int flag); int raw_read_stdin(void *, int); int raw_write_stdout(const void *, int); @@ -383,4 +551,6 @@ int raw_write_stdout(const void *, int); # define TM_STOP 1 double app_tminterval(int stop, int usertime); +# include "progs.h" + #endif diff --git a/apps/asn1pars.c b/apps/asn1pars.c index 1576f1cc05..e96491a40c 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c @@ -1,4 +1,3 @@ -/* apps/asn1pars.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -70,190 +69,136 @@ #include #include -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -in arg - input file - default stdin - * -i - indent the details by depth - * -offset - where in the file to start - * -length - how many bytes to use - * -oid file - extra oid description file - */ - -#undef PROG -#define PROG asn1parse_main - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT, + OPT_OID, OPT_OFFSET, OPT_LENGTH, OPT_DUMP, OPT_DLIMIT, + OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM +} OPTION_CHOICE; + +OPTIONS asn1parse_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"}, + {"in", OPT_IN, '<', "input file"}, + {"out", OPT_OUT, '>', "output file (output format is always DER)"}, + {"i", OPT_INDENT, 0, "entries"}, + {"noout", OPT_NOOUT, 0, "don't produce any output"}, + {"offset", OPT_OFFSET, 'p', "offset into file"}, + {"length", OPT_LENGTH, 'p', "length of section in file"}, + {"oid", OPT_OID, '<', "file of extra oid definitions"}, + {"dump", OPT_DUMP, 0, "unknown data in hex form"}, + {"dlimit", OPT_DLIMIT, 'p', + "dump the first arg bytes of unknown data in hex form"}, + {"strparse", OPT_STRPARSE, 's', + "offset; a series of these can be used to 'dig'"}, + {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, + {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"}, + {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, + {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, + {"strictpem", OPT_STRICTPEM, 0, + "do not attempt base64 decode outside PEM markers"}, + {NULL} +}; static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf); -int MAIN(int argc, char **argv) +int asn1parse_main(int argc, char **argv) { - int i, badops = 0, offset = 0, ret = 1, j; - unsigned int length = 0; - long num, tmplen; - BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL; - int informat, indent = 0, noout = 0, dump = 0, strictpem = 0; - char *infile = NULL, *str = NULL, *prog, *oidfile = NULL, *derfile = - NULL, *name = NULL, *header = NULL; - char *genstr = NULL, *genconf = NULL; - unsigned char *tmpbuf; - const unsigned char *ctmpbuf; + ASN1_TYPE *at = NULL; + BIO *in = NULL, *b64 = NULL, *derout = NULL; BUF_MEM *buf = NULL; STACK_OF(OPENSSL_STRING) *osk = NULL; - ASN1_TYPE *at = NULL; - - informat = FORMAT_PEM; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); + char *genstr = NULL, *genconf = NULL; + char *infile = NULL, *str = NULL, *oidfile = NULL, *derfile = NULL; + char *name = NULL, *header = NULL, *prog; + const unsigned char *ctmpbuf; + int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM; + int offset = 0, ret = 1, i, j; + long num, tmplen; + unsigned char *tmpbuf; + unsigned int length = 0; + OPTION_CHOICE o; - if (!load_config(bio_err, NULL)) - goto end; + prog = opt_init(argc, argv, asn1parse_options); - prog = argv[0]; - argc--; - argv++; if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) { - BIO_printf(bio_err, "Memory allocation failure\n"); + BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); goto end; } - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - derfile = *(++argv); - } else if (strcmp(*argv, "-i") == 0) { + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(asn1parse_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + derfile = opt_arg(); + break; + case OPT_INDENT: indent = 1; - } else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-oid") == 0) { - if (--argc < 1) - goto bad; - oidfile = *(++argv); - } else if (strcmp(*argv, "-offset") == 0) { - if (--argc < 1) - goto bad; - offset = atoi(*(++argv)); - } else if (strcmp(*argv, "-length") == 0) { - if (--argc < 1) - goto bad; - length = atoi(*(++argv)); - if (length == 0) - goto bad; - } else if (strcmp(*argv, "-dump") == 0) { + break; + case OPT_OID: + oidfile = opt_arg(); + break; + case OPT_OFFSET: + offset = strtol(opt_arg(), NULL, 0); + break; + case OPT_LENGTH: + length = atoi(opt_arg()); + break; + case OPT_DUMP: dump = -1; - } else if (strcmp(*argv, "-dlimit") == 0) { - if (--argc < 1) - goto bad; - dump = atoi(*(++argv)); - if (dump <= 0) - goto bad; - } else if (strcmp(*argv, "-strparse") == 0) { - if (--argc < 1) - goto bad; - sk_OPENSSL_STRING_push(osk, *(++argv)); - } else if (strcmp(*argv, "-genstr") == 0) { - if (--argc < 1) - goto bad; - genstr = *(++argv); - } else if (strcmp(*argv, "-genconf") == 0) { - if (--argc < 1) - goto bad; - genconf = *(++argv); - } else if (strcmp(*argv, "-strictpem") == 0) { + break; + case OPT_DLIMIT: + dump = atoi(opt_arg()); + break; + case OPT_STRPARSE: + sk_OPENSSL_STRING_push(osk, opt_arg()); + break; + case OPT_GENSTR: + genstr = opt_arg(); + break; + case OPT_GENCONF: + genconf = opt_arg(); + break; + case OPT_STRICTPEM: strictpem = 1; informat = FORMAT_PEM; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; } - argc--; - argv++; } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] ', "Where to put the output file(s)"}, + {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, + {"sigopt", OPT_SIGOPT, 's'}, + {"notext", OPT_NOTEXT, '-'}, + {"batch", OPT_BATCH, '-', "Don't ask questions"}, + {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, + {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, + {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"}, + {"msie_hack", OPT_MSIE_HACK, '-', + "msie modifications to handle all those universal strings"}, + {"crldays", OPT_CRLDAYS, 'p', "Days is when the next CRL is due"}, + {"crlhours", OPT_CRLHOURS, 'p', "Hours is when the next CRL is due"}, + {"crlsec", OPT_CRLSEC, 'p'}, + {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, + {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, + {"spkac", OPT_SPKAC, '<', + "File contains DN and signed public key and challenge"}, + {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, + {"valid", OPT_VALID, 's'}, + {"extensions", OPT_EXTENSIONS, 's', + "Extension section (override value in config file)"}, + {"extfile", OPT_EXTFILE, '<', + "Configuration file with X509v3 extensions to add"}, + {"status", OPT_STATUS, 's', "Shows cert status given the serial number"}, + {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"}, + {"crlexts", OPT_CRLEXTS, 's', + "CRL extension section (override value in config file)"}, + {"crl_reason", OPT_CRL_REASON, 's'}, + {"crl_hold", OPT_CRL_HOLD, 's'}, + {"crl_compromise", OPT_CRL_COMPROMISE, 's'}, + {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int ca_main(int argc, char **argv) { ENGINE *e = NULL; - char *key = NULL, *passargin = NULL; - int create_ser = 0; - int free_key = 0; - int total = 0; - int total_done = 0; - int badops = 0; - int ret = 1; - int email_dn = 1; - int req = 0; - int verbose = 0; - int gencrl = 0; - int dorevoke = 0; - int doupdatedb = 0; - long crldays = 0; - long crlhours = 0; - long crlsec = 0; - long errorline = -1; - char *configfile = NULL; - char *md = NULL; - char *policy = NULL; - char *keyfile = NULL; - char *certfile = NULL; - int keyform = FORMAT_PEM; - char *infile = NULL; - char *spkac_file = NULL; - char *ss_cert_file = NULL; - char *ser_status = NULL; + BIGNUM *crlnumber = NULL, *serial = NULL; EVP_PKEY *pkey = NULL; - int output_der = 0; - char *outfile = NULL; - char *outdir = NULL; - char *serialfile = NULL; - char *crlnumberfile = NULL; - char *extensions = NULL; - char *extfile = NULL; - char *subj = NULL; - unsigned long chtype = MBSTRING_ASC; - int multirdn = 0; - char *tmp_email_dn = NULL; - char *crl_ext = NULL; - int rev_type = REV_NONE; - char *rev_arg = NULL; - BIGNUM *serial = NULL; - BIGNUM *crlnumber = NULL; - char *startdate = NULL; - char *enddate = NULL; - long days = 0; - int batch = 0; - int notext = 0; - unsigned long nameopt = 0, certopt = 0; - int default_op = 1; - int ext_copy = EXT_COPY_NONE; - int selfsign = 0; - X509 *x509 = NULL, *x509p = NULL; - X509 *x = NULL; BIO *in = NULL, *out = NULL, *Sout = NULL, *Cout = NULL; - char *dbfile = NULL; - CA_DB *db = NULL; - X509_CRL *crl = NULL; - X509_REVOKED *r = NULL; - ASN1_TIME *tmptm; ASN1_INTEGER *tmpser; - char *f; - const char *p; - char *const *pp; - int i, j; - const EVP_MD *dgst = NULL; + ASN1_TIME *tmptm; + CA_DB *db = NULL; + DB_ATTR db_attr; STACK_OF(CONF_VALUE) *attribs = NULL; - STACK_OF(X509) *cert_sk = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL; -#undef BSIZE -#define BSIZE 256 + STACK_OF(X509) *cert_sk = NULL; + X509_CRL *crl = NULL; + const EVP_MD *dgst = NULL; + char *configfile = NULL, *md = NULL, *policy = NULL, *keyfile = NULL; + char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *enddate = + NULL; + char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL; + char *extensions = NULL, *extfile = NULL, *key = NULL, *passinarg = NULL; + char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL; + char *serialfile = NULL, *startdate = NULL, *subj = NULL, *tmp_email_dn = + NULL; + char *prog; + char *const *pp; + char *dbfile = NULL, *engine = NULL, *f, *randfile = NULL, *tofree = NULL; char buf[3][BSIZE]; - char *randfile = NULL; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - char *tofree = NULL; - DB_ATTR db_attr; + const char *p; + int create_ser = 0, free_key = 0, total = 0, total_done = 0; + int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE; + int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0; + int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0; + int i, j, rev_type = REV_NONE, selfsign = 0; + long crldays = 0, crlhours = 0, crlsec = 0, errorline = -1, days = 0; + unsigned long chtype = MBSTRING_ASC, nameopt = 0, certopt = 0; + X509 *x509 = NULL, *x509p = NULL, *x = NULL; + X509_REVOKED *r = NULL; + OPTION_CHOICE o; #ifdef EFENCE EF_PROTECT_FREE = 1; @@ -337,220 +321,181 @@ int MAIN(int argc, char **argv) EF_ALIGNMENT = 0; #endif - apps_startup(); - conf = NULL; - key = NULL; section = NULL; - preserve = 0; msie_hack = 0; - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-verbose") == 0) - verbose = 1; - else if (strcmp(*argv, "-config") == 0) { - if (--argc < 1) - goto bad; - configfile = *(++argv); - } else if (strcmp(*argv, "-name") == 0) { - if (--argc < 1) - goto bad; - section = *(++argv); - } else if (strcmp(*argv, "-subj") == 0) { - if (--argc < 1) - goto bad; - subj = *(++argv); - /* preserve=1; */ - } else if (strcmp(*argv, "-utf8") == 0) - chtype = MBSTRING_UTF8; - else if (strcmp(*argv, "-create_serial") == 0) + + prog = opt_init(argc, argv, ca_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(ca_options); + ret = 0; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_VERBOSE: + verbose = 1; + break; + case OPT_CONFIG: + configfile = opt_arg(); + break; + case OPT_NAME: + section = opt_arg(); + break; + case OPT_SUBJ: + subj = opt_arg(); + /* preserve=1; */ + break; + case OPT_UTF8: + chtype = MBSTRING_UTF8; + break; + case OPT_CREATE_SERIAL: create_ser = 1; - else if (strcmp(*argv, "-multivalue-rdn") == 0) + break; + case OPT_MULTIVALUE_RDN: multirdn = 1; - else if (strcmp(*argv, "-startdate") == 0) { - if (--argc < 1) - goto bad; - startdate = *(++argv); - } else if (strcmp(*argv, "-enddate") == 0) { - if (--argc < 1) - goto bad; - enddate = *(++argv); - } else if (strcmp(*argv, "-days") == 0) { - if (--argc < 1) - goto bad; - days = atoi(*(++argv)); - } else if (strcmp(*argv, "-md") == 0) { - if (--argc < 1) - goto bad; - md = *(++argv); - } else if (strcmp(*argv, "-policy") == 0) { - if (--argc < 1) - goto bad; - policy = *(++argv); - } else if (strcmp(*argv, "-keyfile") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - keyform = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - key = *(++argv); - } else if (strcmp(*argv, "-cert") == 0) { - if (--argc < 1) - goto bad; - certfile = *(++argv); - } else if (strcmp(*argv, "-selfsign") == 0) + break; + case OPT_STARTDATE: + startdate = opt_arg(); + break; + case OPT_ENDDATE: + enddate = opt_arg(); + break; + case OPT_DAYS: + days = atoi(opt_arg()); + break; + case OPT_MD: + md = opt_arg(); + break; + case OPT_POLICY: + policy = opt_arg(); + break; + case OPT_KEYFILE: + keyfile = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat)) + goto opthelp; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_KEY: + key = opt_arg(); + break; + case OPT_CERT: + certfile = opt_arg(); + break; + case OPT_SELFSIGN: selfsign = 1; - else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - req = 1; - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-outdir") == 0) { - if (--argc < 1) - goto bad; - outdir = *(++argv); - } else if (strcmp(*argv, "-sigopt") == 0) { - if (--argc < 1) - goto bad; - if (!sigopts) + break; + case OPT_OUTDIR: + outdir = opt_arg(); + break; + case OPT_SIGOPT: + if (sigopts == NULL) sigopts = sk_OPENSSL_STRING_new_null(); - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-notext") == 0) + if (sigopts == NULL + || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto end; + break; + case OPT_NOTEXT: notext = 1; - else if (strcmp(*argv, "-batch") == 0) + break; + case OPT_BATCH: batch = 1; - else if (strcmp(*argv, "-preserveDN") == 0) + break; + case OPT_PRESERVEDN: preserve = 1; - else if (strcmp(*argv, "-noemailDN") == 0) + break; + case OPT_NOEMAILDN: email_dn = 0; - else if (strcmp(*argv, "-gencrl") == 0) + break; + case OPT_GENCRL: gencrl = 1; - else if (strcmp(*argv, "-msie_hack") == 0) + break; + case OPT_MSIE_HACK: msie_hack = 1; - else if (strcmp(*argv, "-crldays") == 0) { - if (--argc < 1) - goto bad; - crldays = atol(*(++argv)); - } else if (strcmp(*argv, "-crlhours") == 0) { - if (--argc < 1) - goto bad; - crlhours = atol(*(++argv)); - } else if (strcmp(*argv, "-crlsec") == 0) { - if (--argc < 1) - goto bad; - crlsec = atol(*(++argv)); - } else if (strcmp(*argv, "-infiles") == 0) { - argc--; - argv++; - req = 1; break; - } else if (strcmp(*argv, "-ss_cert") == 0) { - if (--argc < 1) - goto bad; - ss_cert_file = *(++argv); + case OPT_CRLDAYS: + crldays = atol(opt_arg()); + break; + case OPT_CRLHOURS: + crlhours = atol(opt_arg()); + break; + case OPT_CRLSEC: + crlsec = atol(opt_arg()); + break; + case OPT_INFILES: req = 1; - } else if (strcmp(*argv, "-spkac") == 0) { - if (--argc < 1) - goto bad; - spkac_file = *(++argv); + goto end_of_options; + case OPT_SS_CERT: + ss_cert_file = opt_arg(); req = 1; - } else if (strcmp(*argv, "-revoke") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); + break; + case OPT_SPKAC: + spkac_file = opt_arg(); + req = 1; + break; + case OPT_REVOKE: + infile = opt_arg(); dorevoke = 1; - } else if (strcmp(*argv, "-valid") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); + break; + case OPT_VALID: + infile = opt_arg(); dorevoke = 2; - } else if (strcmp(*argv, "-extensions") == 0) { - if (--argc < 1) - goto bad; - extensions = *(++argv); - } else if (strcmp(*argv, "-extfile") == 0) { - if (--argc < 1) - goto bad; - extfile = *(++argv); - } else if (strcmp(*argv, "-status") == 0) { - if (--argc < 1) - goto bad; - ser_status = *(++argv); - } else if (strcmp(*argv, "-updatedb") == 0) { + break; + case OPT_EXTENSIONS: + extensions = opt_arg(); + break; + case OPT_EXTFILE: + extfile = opt_arg(); + break; + case OPT_STATUS: + ser_status = opt_arg(); + break; + case OPT_UPDATEDB: doupdatedb = 1; - } else if (strcmp(*argv, "-crlexts") == 0) { - if (--argc < 1) - goto bad; - crl_ext = *(++argv); - } else if (strcmp(*argv, "-crl_reason") == 0) { - if (--argc < 1) - goto bad; - rev_arg = *(++argv); + break; + case OPT_CRLEXTS: + crl_ext = opt_arg(); + break; + case OPT_CRL_REASON: + rev_arg = opt_arg(); rev_type = REV_CRL_REASON; - } else if (strcmp(*argv, "-crl_hold") == 0) { - if (--argc < 1) - goto bad; - rev_arg = *(++argv); + break; + case OPT_CRL_HOLD: + rev_arg = opt_arg(); rev_type = REV_HOLD; - } else if (strcmp(*argv, "-crl_compromise") == 0) { - if (--argc < 1) - goto bad; - rev_arg = *(++argv); + break; + case OPT_CRL_COMPROMISE: + rev_arg = opt_arg(); rev_type = REV_KEY_COMPROMISE; - } else if (strcmp(*argv, "-crl_CA_compromise") == 0) { - if (--argc < 1) - goto bad; - rev_arg = *(++argv); + break; + case OPT_CRL_CA_COMPROMISE: + rev_arg = opt_arg(); rev_type = REV_CA_COMPROMISE; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else { - bad: - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_ENGINE: + engine = opt_arg(); break; } - argc--; - argv++; } +end_of_options: + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - const char **pp2; - - for (pp2 = ca_usage; (*pp2 != NULL); pp2++) - BIO_printf(bio_err, "%s", *pp2); - goto err; - } - - ERR_load_crypto_strings(); - - /*****************************************************************/ tofree = NULL; if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); @@ -565,7 +510,7 @@ int MAIN(int argc, char **argv) tofree = OPENSSL_malloc(len); if (!tofree) { BIO_printf(bio_err, "Out of memory\n"); - goto err; + goto end; } strcpy(tofree, s); #else @@ -573,7 +518,7 @@ int MAIN(int argc, char **argv) tofree = OPENSSL_malloc(len); if (!tofree) { BIO_printf(bio_err, "Out of memory\n"); - goto err; + goto end; } BUF_strlcpy(tofree, s, len); BUF_strlcat(tofree, "/", len); @@ -591,18 +536,14 @@ int MAIN(int argc, char **argv) else BIO_printf(bio_err, "error on line %ld of config file '%s'\n", errorline, configfile); - goto err; + goto end; } if (tofree) { OPENSSL_free(tofree); tofree = NULL; } - - if (!load_config(bio_err, conf)) - goto err; - #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif /* Lets get the config section we are using */ @@ -610,7 +551,7 @@ int MAIN(int argc, char **argv) section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_CA); if (section == NULL) { lookup_fail(BASE_SECTION, ENV_DEFAULT_CA); - goto err; + goto end; } } @@ -633,16 +574,16 @@ int MAIN(int argc, char **argv) BIO_free(oid_bio); } } - if (!add_oid_section(bio_err, conf)) { + if (!add_oid_section(conf)) { ERR_print_errors(bio_err); - goto err; + goto end; } } randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); if (randfile == NULL) ERR_clear_error(); - app_RAND_load_file(randfile, bio_err, 0); + app_RAND_load_file(randfile, 0); f = NCONF_get_string(conf, section, STRING_MASK); if (!f) @@ -650,7 +591,7 @@ int MAIN(int argc, char **argv) if (f && !ASN1_STRING_set_default_mask_asc(f)) { BIO_printf(bio_err, "Invalid global string mask setting %s\n", f); - goto err; + goto end; } if (chtype != MBSTRING_UTF8) { @@ -664,47 +605,27 @@ int MAIN(int argc, char **argv) db_attr.unique_subject = 1; p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT); if (p) { -#ifdef RL_DEBUG - BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p); -#endif db_attr.unique_subject = parse_yesno(p, 1); } else ERR_clear_error(); -#ifdef RL_DEBUG - if (!p) - BIO_printf(bio_err, "DEBUG: unique_subject undefined\n"); -#endif -#ifdef RL_DEBUG - BIO_printf(bio_err, "DEBUG: configured unique_subject is %d\n", - db_attr.unique_subject); -#endif - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - Sout = BIO_new(BIO_s_file()); - Cout = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL)) { - ERR_print_errors(bio_err); - goto err; - } /*****************************************************************/ /* report status of cert with serial number given on command line */ if (ser_status) { if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { lookup_fail(section, ENV_DATABASE); - goto err; + goto end; } db = load_index(dbfile, &db_attr); if (db == NULL) - goto err; + goto end; if (!index_index(db)) - goto err; + goto end; if (get_certificate_status(ser_status, db) != 1) BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status); - goto err; + goto end; } /*****************************************************************/ @@ -715,21 +636,21 @@ int MAIN(int argc, char **argv) ENV_PRIVATE_KEY)) == NULL)) { lookup_fail(section, ENV_PRIVATE_KEY); - goto err; + goto end; } if (!key) { free_key = 1; - if (!app_passwd(bio_err, passargin, NULL, &key, NULL)) { + if (!app_passwd(passinarg, NULL, &key, NULL)) { BIO_printf(bio_err, "Error getting password\n"); - goto err; + goto end; } } - pkey = load_key(bio_err, keyfile, keyform, 0, key, e, "CA private key"); + pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key"); if (key) OPENSSL_cleanse(key, strlen(key)); if (pkey == NULL) { /* load_key() has already printed an appropriate message */ - goto err; + goto end; } /*****************************************************************/ @@ -740,17 +661,16 @@ int MAIN(int argc, char **argv) section, ENV_CERTIFICATE)) == NULL)) { lookup_fail(section, ENV_CERTIFICATE); - goto err; + goto end; } - x509 = load_cert(bio_err, certfile, FORMAT_PEM, NULL, e, - "CA certificate"); + x509 = load_cert(certfile, FORMAT_PEM, NULL, e, "CA certificate"); if (x509 == NULL) - goto err; + goto end; if (!X509_check_private_key(x509, pkey)) { BIO_printf(bio_err, "CA certificate and CA private key do not match\n"); - goto err; + goto end; } } if (!selfsign) @@ -772,7 +692,7 @@ int MAIN(int argc, char **argv) if (f) { if (!set_name_ex(&nameopt, f)) { BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f); - goto err; + goto end; } default_op = 0; } else @@ -783,7 +703,7 @@ int MAIN(int argc, char **argv) if (f) { if (!set_cert_ex(&certopt, f)) { BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f); - goto err; + goto end; } default_op = 0; } else @@ -794,7 +714,7 @@ int MAIN(int argc, char **argv) if (f) { if (!set_ext_copy(&ext_copy, f)) { BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f); - goto err; + goto end; } } else ERR_clear_error(); @@ -807,7 +727,7 @@ int MAIN(int argc, char **argv) == NULL) { BIO_printf(bio_err, "there needs to be defined a directory for new certificate to be placed in\n"); - goto err; + goto end; } #ifndef OPENSSL_SYS_VMS /* @@ -820,22 +740,18 @@ int MAIN(int argc, char **argv) * routines to convert the directory syntax to Unixly, and give that * to access(). However, time's too short to do that just now. */ -# ifndef _WIN32 - if (access(outdir, R_OK | W_OK | X_OK) != 0) -# else - if (_access(outdir, R_OK | W_OK | X_OK) != 0) -# endif + if (app_access(outdir, R_OK | W_OK | X_OK) != 0) { BIO_printf(bio_err, "I am unable to access the %s directory\n", outdir); perror(outdir); - goto err; + goto end; } if (app_isdir(outdir) <= 0) { BIO_printf(bio_err, "%s need to be a directory\n", outdir); perror(outdir); - goto err; + goto end; } #endif } @@ -844,11 +760,11 @@ int MAIN(int argc, char **argv) /* we need to load the database file */ if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { lookup_fail(section, ENV_DATABASE); - goto err; + goto end; } db = load_index(dbfile, &db_attr); if (db == NULL) - goto err; + goto end; /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { @@ -857,16 +773,16 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "entry %d: not revoked yet, but has a revocation date\n", i + 1); - goto err; + goto end; } if ((pp[DB_type][0] == DB_TYPE_REV) && !make_revoked(NULL, pp[DB_rev_date])) { BIO_printf(bio_err, " in entry %d\n", i + 1); - goto err; + goto end; } if (!check_time_format((char *)pp[DB_exp_date])) { BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1); - goto err; + goto end; } p = pp[DB_serial]; j = strlen(p); @@ -877,7 +793,7 @@ int MAIN(int argc, char **argv) if ((j & 1) || (j < 2)) { BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n", i + 1, j); - goto err; + goto end; } while (*p) { if (!(((*p >= '0') && (*p <= '9')) || @@ -886,27 +802,20 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "entry %d: bad serial number characters, char pos %ld, char is '%c'\n", i + 1, (long)(p - pp[DB_serial]), *p); - goto err; + goto end; } p++; } } if (verbose) { - BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); /* cannot fail */ -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - TXT_DB_write(out, db->db); + TXT_DB_write(bio_out, db->db); BIO_printf(bio_err, "%d entries loaded from the database\n", sk_OPENSSL_PSTRING_num(db->db->data)); BIO_printf(bio_err, "generating index\n"); } if (!index_index(db)) - goto err; + goto end; /*****************************************************************/ /* Update the db file for expired certificates */ @@ -917,16 +826,16 @@ int MAIN(int argc, char **argv) i = do_updatedb(db); if (i == -1) { BIO_printf(bio_err, "Malloc failure\n"); - goto err; + goto end; } else if (i == 0) { if (verbose) BIO_printf(bio_err, "No entries found to mark expired\n"); } else { if (!save_index(dbfile, "new", db)) - goto err; + goto end; if (!rotate_index(dbfile, "new", "old")) - goto err; + goto end; if (verbose) BIO_printf(bio_err, @@ -947,7 +856,7 @@ int MAIN(int argc, char **argv) "ERROR: on line %ld of config file '%s'\n", errorline, extfile); ret = 1; - goto err; + goto end; } if (verbose) @@ -963,41 +872,29 @@ int MAIN(int argc, char **argv) /*****************************************************************/ if (req || gencrl) { - if (outfile != NULL) { - if (BIO_write_filename(Sout, outfile) <= 0) { - perror(outfile); - goto err; - } - } else { - BIO_set_fp(Sout, stdout, BIO_NOCLOSE | BIO_FP_TEXT); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - Sout = BIO_push(tmpbio, Sout); - } -#endif - } + Sout = bio_open_default(outfile, "w"); + if (Sout == NULL) + goto end; } if ((md == NULL) && ((md = NCONF_get_string(conf, section, ENV_DEFAULT_MD)) == NULL)) { lookup_fail(section, ENV_DEFAULT_MD); - goto err; + goto end; } if (!strcmp(md, "default")) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) { BIO_puts(bio_err, "no default digest\n"); - goto err; + goto end; } md = (char *)OBJ_nid2sn(def_nid); } - if ((dgst = EVP_get_digestbyname(md)) == NULL) { - BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); - goto err; + if (!opt_md(md, &dgst)) { + goto end; } if (req) { @@ -1016,7 +913,7 @@ int MAIN(int argc, char **argv) ENV_POLICY)) == NULL)) { lookup_fail(section, ENV_POLICY); - goto err; + goto end; } if (verbose) BIO_printf(bio_err, "policy is %s\n", policy); @@ -1024,7 +921,7 @@ int MAIN(int argc, char **argv) if ((serialfile = NCONF_get_string(conf, section, ENV_SERIAL)) == NULL) { lookup_fail(section, ENV_SERIAL); - goto err; + goto end; } if (!extconf) { @@ -1047,7 +944,7 @@ int MAIN(int argc, char **argv) "Error Loading extension section %s\n", extensions); ret = 1; - goto err; + goto end; } } } @@ -1061,7 +958,7 @@ int MAIN(int argc, char **argv) if (startdate && !ASN1_TIME_set_string(NULL, startdate)) { BIO_printf(bio_err, "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); - goto err; + goto end; } if (startdate == NULL) startdate = "today"; @@ -1074,7 +971,7 @@ int MAIN(int argc, char **argv) if (enddate && !ASN1_TIME_set_string(NULL, enddate)) { BIO_printf(bio_err, "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); - goto err; + goto end; } if (days == 0) { @@ -1084,19 +981,19 @@ int MAIN(int argc, char **argv) if (!enddate && (days == 0)) { BIO_printf(bio_err, "cannot lookup how many days to certify for\n"); - goto err; + goto end; } if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) { BIO_printf(bio_err, "error while loading serial number\n"); - goto err; + goto end; } if (verbose) { if (BN_is_zero(serial)) BIO_printf(bio_err, "next serial number is 00\n"); else { if ((f = BN_bn2hex(serial)) == NULL) - goto err; + goto end; BIO_printf(bio_err, "next serial number is %s\n", f); OPENSSL_free(f); } @@ -1104,12 +1001,12 @@ int MAIN(int argc, char **argv) if ((attribs = NCONF_get_section(conf, policy)) == NULL) { BIO_printf(bio_err, "unable to find 'section' for %s\n", policy); - goto err; + goto end; } if ((cert_sk = sk_X509_new_null()) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } if (spkac_file != NULL) { total++; @@ -1119,15 +1016,15 @@ int MAIN(int argc, char **argv) conf, verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) - goto err; + goto end; if (j > 0) { total_done++; BIO_printf(bio_err, "\n"); if (!BN_add_word(serial, 1)) - goto err; + goto end; if (!sk_X509_push(cert_sk, x)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } if (outfile) { output_der = 1; @@ -1144,15 +1041,15 @@ int MAIN(int argc, char **argv) conf, verbose, certopt, nameopt, default_op, ext_copy, e); if (j < 0) - goto err; + goto end; if (j > 0) { total_done++; BIO_printf(bio_err, "\n"); if (!BN_add_word(serial, 1)) - goto err; + goto end; if (!sk_X509_push(cert_sk, x)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } } } @@ -1163,15 +1060,15 @@ int MAIN(int argc, char **argv) enddate, days, batch, extensions, conf, verbose, certopt, nameopt, default_op, ext_copy, selfsign); if (j < 0) - goto err; + goto end; if (j > 0) { total_done++; BIO_printf(bio_err, "\n"); if (!BN_add_word(serial, 1)) - goto err; + goto end; if (!sk_X509_push(cert_sk, x)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } } } @@ -1182,15 +1079,15 @@ int MAIN(int argc, char **argv) enddate, days, batch, extensions, conf, verbose, certopt, nameopt, default_op, ext_copy, selfsign); if (j < 0) - goto err; + goto end; if (j > 0) { total_done++; BIO_printf(bio_err, "\n"); if (!BN_add_word(serial, 1)) - goto err; + goto end; if (!sk_X509_push(cert_sk, x)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } } } @@ -1210,12 +1107,12 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n"); ret = 0; - goto err; + goto end; } if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) { BIO_printf(bio_err, "CERTIFICATION CANCELED\n"); ret = 0; - goto err; + goto end; } } @@ -1223,10 +1120,10 @@ int MAIN(int argc, char **argv) sk_X509_num(cert_sk)); if (!save_serial(serialfile, "new", serial, NULL)) - goto err; + goto end; if (!save_index(dbfile, "new", db)) - goto err; + goto end; } if (verbose) @@ -1242,7 +1139,7 @@ int MAIN(int argc, char **argv) if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) { BIO_printf(bio_err, "certificate file name too long\n"); - goto err; + goto end; } strcpy(buf[2], outdir); @@ -1273,9 +1170,10 @@ int MAIN(int argc, char **argv) if (verbose) BIO_printf(bio_err, "writing %s\n", buf[2]); - if (BIO_write_filename(Cout, buf[2]) <= 0) { + Cout = BIO_new_file(buf[2], "w"); + if (Cout == NULL) { perror(buf[2]); - goto err; + goto end; } write_new_certificate(Cout, x, 0, notext); write_new_certificate(Sout, x, output_der, notext); @@ -1284,10 +1182,10 @@ int MAIN(int argc, char **argv) if (sk_X509_num(cert_sk)) { /* Rename the database and the serial file */ if (!rotate_serial(serialfile, "new", "old")) - goto err; + goto end; if (!rotate_index(dbfile, "new", "old")) - goto err; + goto end; BIO_printf(bio_err, "Data Base Updated\n"); } @@ -1311,7 +1209,7 @@ int MAIN(int argc, char **argv) "Error Loading CRL extension section %s\n", crl_ext); ret = 1; - goto err; + goto end; } } @@ -1319,7 +1217,7 @@ int MAIN(int argc, char **argv) != NULL) if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) { BIO_printf(bio_err, "error while loading CRL number\n"); - goto err; + goto end; } if (!crldays && !crlhours && !crlsec) { @@ -1334,25 +1232,25 @@ int MAIN(int argc, char **argv) if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { BIO_printf(bio_err, "cannot lookup how long until the next CRL is issued\n"); - goto err; + goto end; } if (verbose) BIO_printf(bio_err, "making CRL\n"); if ((crl = X509_CRL_new()) == NULL) - goto err; + goto end; if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) - goto err; + goto end; tmptm = ASN1_TIME_new(); if (!tmptm) - goto err; + goto end; X509_gmtime_adj(tmptm, 0); X509_CRL_set_lastUpdate(crl, tmptm); if (!X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec, NULL)) { BIO_puts(bio_err, "error setting CRL nextUpdate\n"); - goto err; + goto end; } X509_CRL_set_nextUpdate(crl, tmptm); @@ -1362,19 +1260,19 @@ int MAIN(int argc, char **argv) pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_type][0] == DB_TYPE_REV) { if ((r = X509_REVOKED_new()) == NULL) - goto err; + goto end; j = make_revoked(r, pp[DB_rev_date]); if (!j) - goto err; + goto end; if (j == 2) crl_v2 = 1; if (!BN_hex2bn(&serial, pp[DB_serial])) - goto err; + goto end; tmpser = BN_to_ASN1_INTEGER(serial, NULL); BN_free(serial); serial = NULL; if (!tmpser) - goto err; + goto end; X509_REVOKED_set_serialNumber(r, tmpser); ASN1_INTEGER_free(tmpser); X509_CRL_add0_revoked(crl, r); @@ -1399,72 +1297,72 @@ int MAIN(int argc, char **argv) if (crl_ext) if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) - goto err; + goto end; if (crlnumberfile != NULL) { tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL); if (!tmpser) - goto err; + goto end; X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0); ASN1_INTEGER_free(tmpser); crl_v2 = 1; if (!BN_add_word(crlnumber, 1)) - goto err; + goto end; } } if (crl_ext || crl_v2) { if (!X509_CRL_set_version(crl, 1)) - goto err; /* version 2 CRL */ + goto end; /* version 2 CRL */ } /* we have a CRL number that need updating */ if (crlnumberfile != NULL) if (!save_serial(crlnumberfile, "new", crlnumber, NULL)) - goto err; + goto end; if (crlnumber) { BN_free(crlnumber); crlnumber = NULL; } - if (!do_X509_CRL_sign(bio_err, crl, pkey, dgst, sigopts)) - goto err; + if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts)) + goto end; PEM_write_bio_X509_CRL(Sout, crl); if (crlnumberfile != NULL) /* Rename the crlnumber file */ if (!rotate_serial(crlnumberfile, "new", "old")) - goto err; + goto end; } /*****************************************************************/ if (dorevoke) { if (infile == NULL) { BIO_printf(bio_err, "no input files\n"); - goto err; + goto end; } else { X509 *revcert; - revcert = load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile); + revcert = load_cert(infile, FORMAT_PEM, NULL, e, infile); if (revcert == NULL) - goto err; + goto end; if (dorevoke == 2) rev_type = -1; j = do_revoke(revcert, db, rev_type, rev_arg); if (j <= 0) - goto err; + goto end; X509_free(revcert); if (!save_index(dbfile, "new", db)) - goto err; + goto end; if (!rotate_index(dbfile, "new", "old")) - goto err; + goto end; BIO_printf(bio_err, "Data Base Updated\n"); } } /*****************************************************************/ ret = 0; - err: + end: if (tofree) OPENSSL_free(tofree); BIO_free_all(Cout); @@ -1477,7 +1375,7 @@ int MAIN(int argc, char **argv) if (ret) ERR_print_errors(bio_err); - app_RAND_write_file(randfile, bio_err); + app_RAND_write_file(randfile); if (free_key && key) OPENSSL_free(key); BN_free(serial); @@ -1492,8 +1390,7 @@ int MAIN(int argc, char **argv) NCONF_free(conf); NCONF_free(extconf); OBJ_cleanup(); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static void lookup_fail(const char *name, const char *tag) @@ -1515,16 +1412,15 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, EVP_PKEY *pktmp = NULL; int ok = -1, i; - in = BIO_new(BIO_s_file()); - - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto err; + in = BIO_new_file(infile, "r"); + if (in == NULL) { + ERR_print_errors(bio_err); + goto end; } if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) { BIO_printf(bio_err, "Error reading certificate request in %s\n", infile); - goto err; + goto end; } if (verbose) X509_REQ_print(bio_err, req); @@ -1535,11 +1431,11 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "Certificate request and CA private key do not match\n"); ok = 0; - goto err; + goto end; } if ((pktmp = X509_REQ_get_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); - goto err; + goto end; } i = X509_REQ_verify(req, pktmp); EVP_PKEY_free(pktmp); @@ -1547,14 +1443,14 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, ok = 0; BIO_printf(bio_err, "Signature verification problems....\n"); ERR_print_errors(bio_err); - goto err; + goto end; } if (i == 0) { ok = 0; BIO_printf(bio_err, "Signature did not match the certificate request\n"); ERR_print_errors(bio_err); - goto err; + goto end; } else BIO_printf(bio_err, "Signature ok\n"); @@ -1563,7 +1459,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, ext_copy, selfsign); - err: + end: if (req != NULL) X509_REQ_free(req); BIO_free(in); @@ -1585,9 +1481,8 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, EVP_PKEY *pktmp = NULL; int ok = -1, i; - if ((req = - load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL) - goto err; + if ((req = load_cert(infile, FORMAT_PEM, NULL, e, infile)) == NULL) + goto end; if (verbose) X509_print(bio_err, req); @@ -1595,31 +1490,31 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, if ((pktmp = X509_get_pubkey(req)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); - goto err; + goto end; } i = X509_verify(req, pktmp); EVP_PKEY_free(pktmp); if (i < 0) { ok = 0; BIO_printf(bio_err, "Signature verification problems....\n"); - goto err; + goto end; } if (i == 0) { ok = 0; BIO_printf(bio_err, "Signature did not match the certificate\n"); - goto err; + goto end; } else BIO_printf(bio_err, "Signature ok\n"); if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL) - goto err; + goto end; ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op, ext_copy, 0); - err: + end: if (rreq != NULL) X509_REQ_free(rreq); if (req != NULL) @@ -1668,7 +1563,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (!n) { ERR_print_errors(bio_err); - goto err; + goto end; } X509_REQ_set_subject_name(req, n); req->req_info->enc.modified = 1; @@ -1710,7 +1605,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, (str->type != V_ASN1_IA5STRING)) { BIO_printf(bio_err, "\nemailAddress type needs to be of type IA5STRING\n"); - goto err; + goto end; } if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING)) { @@ -1721,7 +1616,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, (str->type == V_ASN1_PRINTABLESTRING))) { BIO_printf(bio_err, "\nThe string contains characters that are illegal for the ASN.1 type\n"); - goto err; + goto end; } } @@ -1732,7 +1627,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* Ok, now we check the 'policy' stuff. */ if ((subject = X509_NAME_new()) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } /* take a copy of the issuer name before we mess with it. */ @@ -1741,7 +1636,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, else CAname = X509_NAME_dup(x509->cert_info->subject); if (CAname == NULL) - goto err; + goto end; str = str2 = NULL; for (i = 0; i < sk_CONF_VALUE_num(policy); i++) { @@ -1750,7 +1645,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "%s:unknown object type in 'policy' configuration\n", cv->name); - goto err; + goto end; } obj = OBJ_nid2obj(j); @@ -1777,7 +1672,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "The %s field needed to be supplied and was missing\n", cv->name); - goto err; + goto end; } else push = tne; } else if (strcmp(cv->value, "match") == 0) { @@ -1787,7 +1682,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "The mandatory %s field was missing\n", cv->name); - goto err; + goto end; } last2 = -1; @@ -1798,7 +1693,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n", cv->name); - goto err; + goto end; } if (j >= 0) { push = X509_NAME_get_entry(CAname, j); @@ -1814,13 +1709,13 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, cv->name, ((str2 == NULL) ? "NULL" : (char *)str2->data), ((str == NULL) ? "NULL" : (char *)str->data)); - goto err; + goto end; } } else { BIO_printf(bio_err, "%s:invalid type in 'policy' configuration\n", cv->value); - goto err; + goto end; } if (push != NULL) { @@ -1828,7 +1723,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (push != NULL) X509_NAME_ENTRY_free(push); BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } } if (j < 0) @@ -1841,7 +1736,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ subject = X509_NAME_dup(name); if (subject == NULL) - goto err; + goto end; } if (verbose) @@ -1864,7 +1759,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, */ if (!(dn_subject = X509_NAME_dup(subject))) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } while ((i = X509_NAME_get_index_by_NID(dn_subject, NID_pkcs9_emailAddress, @@ -1881,7 +1776,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, row[DB_serial] = BN_bn2hex(serial); if (row[DB_serial] == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } if (db->attributes.unique_subject) { @@ -1939,7 +1834,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, p = "undef"; BIO_printf(bio_err, "Subject Name :%s\n", p); ok = -1; /* This is now a 'bad' error. */ - goto err; + goto end; } /* We are now totally happy, lets make and sign the certificate */ @@ -1948,23 +1843,23 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, "Everything appears to be ok, creating and signing the certificate\n"); if ((ret = X509_new()) == NULL) - goto err; + goto end; ci = ret->cert_info; #ifdef X509_V3 /* Make it an X509 v3 certificate. */ if (!X509_set_version(ret, 2)) - goto err; + goto end; #endif if (BN_to_ASN1_INTEGER(serial, ci->serialNumber) == NULL) - goto err; + goto end; if (selfsign) { if (!X509_set_issuer_name(ret, subject)) - goto err; + goto end; } else { if (!X509_set_issuer_name(ret, X509_get_subject_name(x509))) - goto err; + goto end; } if (strcmp(startdate, "today") == 0) @@ -1982,20 +1877,20 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, } if (!X509_set_subject_name(ret, subject)) - goto err; + goto end; pktmp = X509_REQ_get_pubkey(req); i = X509_set_pubkey(ret, pktmp); EVP_PKEY_free(pktmp); if (!i) - goto err; + goto end; /* Lets add the extensions, if there are any */ if (ext_sect) { X509V3_CTX ctx; if (ci->version == NULL) if ((ci->version = ASN1_INTEGER_new()) == NULL) - goto err; + goto end; ASN1_INTEGER_set(ci->version, 2); /* version 3 certificate */ /* @@ -2028,7 +1923,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, "ERROR: adding extensions in section %s\n", ext_sect); ERR_print_errors(bio_err); - goto err; + goto end; } if (verbose) BIO_printf(bio_err, @@ -2042,7 +1937,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, "ERROR: adding extensions in section %s\n", ext_sect); ERR_print_errors(bio_err); - goto err; + goto end; } if (verbose) @@ -2056,13 +1951,13 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (!copy_extensions(ret, req, ext_copy)) { BIO_printf(bio_err, "ERROR: adding extensions from request\n"); ERR_print_errors(bio_err); - goto err; + goto end; } /* Set the right value for the noemailDN option */ if (email_dn == 0) { if (!X509_set_subject_name(ret, dn_subject)) - goto err; + goto end; } if (!default_op) { @@ -2089,12 +1984,12 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n"); ok = 0; - goto err; + goto end; } if (!((buf[0] == 'y') || (buf[0] == 'Y'))) { BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n"); ok = 0; - goto err; + goto end; } } @@ -2104,8 +1999,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, EVP_PKEY_copy_parameters(pktmp, pkey); EVP_PKEY_free(pktmp); - if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts)) - goto err; + if (!do_X509_sign(ret, pkey, dgst, sigopts)) + goto end; /* We now just add it to the database */ row[DB_type] = (char *)OPENSSL_malloc(2); @@ -2124,7 +2019,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || (row[DB_file] == NULL) || (row[DB_name] == NULL)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } BUF_strlcpy(row[DB_file], "unknown", 8); row[DB_type][0] = 'V'; @@ -2133,7 +2028,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if ((irow = (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } for (i = 0; i < DB_NUMBER; i++) { @@ -2145,10 +2040,10 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (!TXT_DB_insert(db->db, irow)) { BIO_printf(bio_err, "failed to update database\n"); BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); - goto err; + goto end; } ok = 1; - err: + end: for (i = 0; i < DB_NUMBER; i++) if (row[i] != NULL) OPENSSL_free(row[i]); @@ -2216,14 +2111,14 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, if (parms == NULL) { BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile); ERR_print_errors(bio_err); - goto err; + goto end; } sk = CONF_get_section(parms, "default"); if (sk_CONF_VALUE_num(sk) == 0) { BIO_printf(bio_err, "no name/value pairs found in %s\n", infile); CONF_free(parms); - goto err; + goto end; } /* @@ -2236,7 +2131,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, req = X509_REQ_new(); if (req == NULL) { ERR_print_errors(bio_err); - goto err; + goto end; } /* @@ -2270,7 +2165,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, BIO_printf(bio_err, "unable to load Netscape SPKAC structure\n"); ERR_print_errors(bio_err); - goto err; + goto end; } } continue; @@ -2278,12 +2173,12 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char *)buf, -1, -1, 0)) - goto err; + goto end; } if (spki == NULL) { BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n", infile); - goto err; + goto end; } /* @@ -2295,14 +2190,14 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { BIO_printf(bio_err, "error unpacking SPKAC public key\n"); - goto err; + goto end; } j = NETSCAPE_SPKI_verify(spki, pktmp); if (j <= 0) { BIO_printf(bio_err, "signature verification failed on SPKAC public key\n"); - goto err; + goto end; } BIO_printf(bio_err, "Signature ok\n"); @@ -2312,7 +2207,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, chtype, multirdn, email_dn, startdate, enddate, days, 1, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, ext_copy, 0); - err: + end: if (req != NULL) X509_REQ_free(req); if (parms != NULL) @@ -2343,7 +2238,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0); bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL); if (!bn) - goto err; + goto end; if (BN_is_zero(bn)) row[DB_serial] = BUF_strdup("00"); else @@ -2351,7 +2246,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) BN_free(bn); if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } /* * We have to lookup by serial number because name lookup skips revoked @@ -2381,7 +2276,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || (row[DB_file] == NULL)) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } BUF_strlcpy(row[DB_file], "unknown", 8); row[DB_type][0] = 'V'; @@ -2391,7 +2286,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); - goto err; + goto end; } for (i = 0; i < DB_NUMBER; i++) { @@ -2403,7 +2298,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) if (!TXT_DB_insert(db->db, irow)) { BIO_printf(bio_err, "failed to update database\n"); BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); - goto err; + goto end; } /* Revoke Certificate */ @@ -2412,32 +2307,32 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) else ok = do_revoke(x509, db, type, value); - goto err; + goto end; } else if (index_name_cmp_noconst(row, rrow)) { BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]); - goto err; + goto end; } else if (type == -1) { BIO_printf(bio_err, "ERROR:Already present, serial number %s\n", row[DB_serial]); - goto err; + goto end; } else if (rrow[DB_type][0] == 'R') { BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n", row[DB_serial]); - goto err; + goto end; } else { BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]); rev_str = make_revocation_str(type, value); if (!rev_str) { BIO_printf(bio_err, "Error in revocation arguments\n"); - goto err; + goto end; } rrow[DB_type][0] = 'R'; rrow[DB_type][1] = '\0'; rrow[DB_rev_date] = rev_str; } ok = 1; - err: + end: for (i = 0; i < DB_NUMBER; i++) { if (row[i] != NULL) OPENSSL_free(row[i]); @@ -2458,7 +2353,7 @@ static int get_certificate_status(const char *serial, CA_DB *db) row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2); if (row[DB_serial] == NULL) { BIO_printf(bio_err, "Malloc failure\n"); - goto err; + goto end; } if (strlen(serial) % 2) { @@ -2487,29 +2382,29 @@ static int get_certificate_status(const char *serial, CA_DB *db) if (rrow == NULL) { BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]); ok = -1; - goto err; + goto end; } else if (rrow[DB_type][0] == 'V') { BIO_printf(bio_err, "%s=Valid (%c)\n", row[DB_serial], rrow[DB_type][0]); - goto err; + goto end; } else if (rrow[DB_type][0] == 'R') { BIO_printf(bio_err, "%s=Revoked (%c)\n", row[DB_serial], rrow[DB_type][0]); - goto err; + goto end; } else if (rrow[DB_type][0] == 'E') { BIO_printf(bio_err, "%s=Expired (%c)\n", row[DB_serial], rrow[DB_type][0]); - goto err; + goto end; } else if (rrow[DB_type][0] == 'S') { BIO_printf(bio_err, "%s=Suspended (%c)\n", row[DB_serial], rrow[DB_type][0]); - goto err; + goto end; } else { BIO_printf(bio_err, "%s=Unknown (%c).\n", row[DB_serial], rrow[DB_type][0]); ok = -1; } - err: + end: for (i = 0; i < DB_NUMBER; i++) { if (row[i] != NULL) OPENSSL_free(row[i]); @@ -2531,7 +2426,7 @@ static int do_updatedb(CA_DB *db) a_tm_s = (char *)OPENSSL_malloc(a_tm->length + 1); if (a_tm_s == NULL) { cnt = -1; - goto err; + goto end; } memcpy(a_tm_s, a_tm->data, a_tm->length); @@ -2572,7 +2467,7 @@ static int do_updatedb(CA_DB *db) } } - err: + end: ASN1_UTCTIME_free(a_tm); OPENSSL_free(a_tm_s); @@ -2716,28 +2611,28 @@ int make_revoked(X509_REVOKED *rev, const char *str) i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str); if (i == 0) - goto err; + goto end; if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) - goto err; + goto end; if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) { rtmp = ASN1_ENUMERATED_new(); if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) - goto err; + goto end; if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) - goto err; + goto end; } if (rev && comp_time) { if (!X509_REVOKED_add1_ext_i2d (rev, NID_invalidity_date, comp_time, 0, 0)) - goto err; + goto end; } if (rev && hold) { if (!X509_REVOKED_add1_ext_i2d (rev, NID_hold_instruction_code, hold, 0, 0)) - goto err; + goto end; } if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) @@ -2745,7 +2640,7 @@ int make_revoked(X509_REVOKED *rev, const char *str) else ret = 1; - err: + end: if (tmp) OPENSSL_free(tmp); @@ -2799,18 +2694,18 @@ int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str) { - char *tmp = NULL; + char *tmp; char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; int reason_code = -1; int ret = 0; unsigned int i; ASN1_OBJECT *hold = NULL; ASN1_GENERALIZEDTIME *comp_time = NULL; - tmp = BUF_strdup(str); + tmp = BUF_strdup(str); if (!tmp) { BIO_printf(bio_err, "memory allocation failure\n"); - goto err; + goto end; } p = strchr(tmp, ','); @@ -2832,11 +2727,11 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, *prevtm = ASN1_UTCTIME_new(); if (!*prevtm) { BIO_printf(bio_err, "memory allocation failure\n"); - goto err; + goto end; } if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) { BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str); - goto err; + goto end; } } if (reason_str) { @@ -2848,7 +2743,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, } if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) { BIO_printf(bio_err, "invalid reason code %s\n", reason_str); - goto err; + goto end; } if (reason_code == 7) @@ -2856,7 +2751,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, else if (reason_code == 8) { /* Hold instruction */ if (!arg_str) { BIO_printf(bio_err, "missing hold instruction\n"); - goto err; + goto end; } reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; hold = OBJ_txt2obj(arg_str, 0); @@ -2864,23 +2759,23 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, if (!hold) { BIO_printf(bio_err, "invalid object identifier %s\n", arg_str); - goto err; + goto end; } if (phold) *phold = hold; } else if ((reason_code == 9) || (reason_code == 10)) { if (!arg_str) { BIO_printf(bio_err, "missing compromised time\n"); - goto err; + goto end; } comp_time = ASN1_GENERALIZEDTIME_new(); if (!comp_time) { BIO_printf(bio_err, "memory allocation failure\n"); - goto err; + goto end; } if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) { BIO_printf(bio_err, "invalid compromised time %s\n", arg_str); - goto err; + goto end; } if (reason_code == 9) reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; @@ -2898,7 +2793,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ret = 1; - err: + end: if (tmp) OPENSSL_free(tmp); diff --git a/apps/ciphers.c b/apps/ciphers.c index 4b9a114666..3d84a2b14e 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -1,4 +1,3 @@ -/* apps/ciphers.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -63,91 +62,91 @@ #include #include -#undef PROG -#define PROG ciphers_main - -static const char *ciphers_usage[] = { - "usage: ciphers args\n", - " -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n", - " -V - even more verbose\n", - " -ssl3 - SSL3 mode\n", - " -tls1 - TLS1 mode\n", - NULL +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, +#ifndef OPENSSL_NO_SSL_TRACE + OPT_STDNAME, +#endif +#ifndef OPENSSL_NO_SSL3 + OPT_SSL3, +#endif + OPT_TLS1, + OPT_V, OPT_UPPER_V, OPT_S +} OPTION_CHOICE; + +OPTIONS ciphers_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, + {"V", OPT_UPPER_V, '-', "Even more verbose"}, + {"s", OPT_S, '-', "Only supported ciphers"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, +#endif +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "SSL3 mode"}, +#endif + {"tls1", OPT_TLS1, '-', "TLS1 mode"}, + {NULL} }; -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int ciphers_main(int argc, char **argv) { - int ret = 1, i; - int verbose = 0, Verbose = 0; - int use_supported = 0; + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + STACK_OF(SSL_CIPHER) *sk = NULL; + const SSL_METHOD *meth = SSLv23_server_method(); + int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; #ifndef OPENSSL_NO_SSL_TRACE int stdname = 0; #endif - const char **pp; const char *p; - int badops = 0; - SSL_CTX *ctx = NULL; - SSL *ssl = NULL; - char *ciphers = NULL; - const SSL_METHOD *meth = NULL; - STACK_OF(SSL_CIPHER) *sk = NULL; + char *ciphers = NULL, *prog; char buf[512]; - BIO *STDout = NULL; - - meth = SSLv23_server_method(); - - apps_startup(); - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - STDout = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - STDout = BIO_push(tmpbio, STDout); - } -#endif - if (!load_config(bio_err, NULL)) - goto end; - - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-v") == 0) + OPTION_CHOICE o; + + prog = opt_init(argc, argv, ciphers_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(ciphers_options); + ret = 0; + goto end; + case OPT_V: verbose = 1; - else if (strcmp(*argv, "-V") == 0) + break; + case OPT_UPPER_V: verbose = Verbose = 1; - else if (strcmp(*argv, "-s") == 0) + break; + case OPT_S: use_supported = 1; + break; #ifndef OPENSSL_NO_SSL_TRACE - else if (strcmp(*argv, "-stdname") == 0) + case OPT_STDNAME: stdname = verbose = 1; + break; #endif #ifndef OPENSSL_NO_SSL3 - else if (strcmp(*argv, "-ssl3") == 0) + case OPT_SSL3: meth = SSLv3_client_method(); + break; #endif - else if (strcmp(*argv, "-tls1") == 0) + case OPT_TLS1: meth = TLSv1_client_method(); - else if ((strncmp(*argv, "-h", 2) == 0) || (strcmp(*argv, "-?") == 0)) { - badops = 1; break; - } else { - ciphers = *argv; } - argc--; - argv++; } + argv = opt_rest(); + argc = opt_num_rest(); - if (badops) { - for (pp = ciphers_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); - goto end; - } - - OpenSSL_add_ssl_algorithms(); + if (argc == 1) + ciphers = *argv; + else if (argc != 0) + goto opthelp; ctx = SSL_CTX_new(meth); if (ctx == NULL) @@ -174,11 +173,11 @@ int MAIN(int argc, char **argv) if (p == NULL) break; if (i != 0) - BIO_printf(STDout, ":"); - BIO_printf(STDout, "%s", p); + BIO_printf(bio_out, ":"); + BIO_printf(bio_out, "%s", p); } - BIO_printf(STDout, "\n"); - } else { /* verbose */ + BIO_printf(bio_out, "\n"); + } else { for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { SSL_CIPHER *c; @@ -192,40 +191,32 @@ int MAIN(int argc, char **argv) int id2 = (int)((id >> 8) & 0xffL); int id3 = (int)(id & 0xffL); - if ((id & 0xff000000L) == 0x03000000L) { - /* SSL3 cipher */ - BIO_printf(STDout, " 0x%02X,0x%02X - ", id2, - id3); - } else { - /* whatever */ - BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, - id1, id2, id3); - } + if ((id & 0xff000000L) == 0x03000000L) + BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 + * cipher */ + else + BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ } #ifndef OPENSSL_NO_SSL_TRACE if (stdname) { const char *nm = SSL_CIPHER_standard_name(c); if (nm == NULL) nm = "UNKNOWN"; - BIO_printf(STDout, "%s - ", nm); + BIO_printf(bio_out, "%s - ", nm); } #endif - BIO_puts(STDout, SSL_CIPHER_description(c, buf, sizeof buf)); + BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof buf)); } } ret = 0; - if (0) { + goto end; err: - SSL_load_error_strings(); - ERR_print_errors(bio_err); - } + ERR_print_errors(bio_err); end: if (use_supported && sk) sk_SSL_CIPHER_free(sk); SSL_CTX_free(ctx); SSL_free(ssl); - BIO_free_all(STDout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/cms.c b/apps/cms.c index 73f9037c04..397071ca7f 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -1,4 +1,3 @@ -/* apps/cms.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -67,8 +66,6 @@ # include # include -# undef PROG -# define PROG cms_main static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int cms_cb(int ok, X509_STORE_CTX *ctx); static void receipt_request_print(BIO *out, CMS_ContentInfo *cms); @@ -108,347 +105,456 @@ struct cms_key_param_st { cms_key_param *next; }; -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENCRYPT, + OPT_DECRYPT, OPT_SIGN, OPT_SIGN_RECEIPT, OPT_RESIGN, + OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT, + OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY, + OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS, + OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT, + OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS, + OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID, + OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF, + OPT_NOINDEF, OPT_NOOLDMIME, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT, + OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE, + OPT_CAPATH, OPT_CONTENT, OPT_PRINT, OPT_SECRETKEY, + OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE, OPT_RAND, + OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, + OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM, + OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP, + OPT_3DES_WRAP, OPT_ENGINE, + OPT_V_ENUM, + OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS cms_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, + {OPT_HELP_STR, 1, '-', + " cert.pem... recipient certs for encryption\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format SMIME (default), PEM or DER"}, + {"outform", OPT_OUTFORM, 'F', + "Output format SMIME (default), PEM or DER"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, + {"sign", OPT_SIGN, '-', "Sign message"}, + {"sign_receipt", OPT_SIGN_RECEIPT, '-'}, + {"resign", OPT_RESIGN, '-'}, + {"verify", OPT_VERIFY, '-', "Verify signed message"}, + {"verify_retcode", OPT_VERIFY_RETCODE, '-'}, + {"verify_receipt", OPT_VERIFY_RECEIPT, '<'}, + {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"}, + {"data_out", OPT_DATA_OUT, '-'}, + {"data_create", OPT_DATA_CREATE, '-'}, + {"digest_verify", OPT_DIGEST_VERIFY, '-'}, + {"digest_create", OPT_DIGEST_CREATE, '-'}, + {"compress", OPT_COMPRESS, '-'}, + {"uncompress", OPT_UNCOMPRESS, '-'}, + {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-'}, + {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-'}, + {"debug_decrypt", OPT_DEBUG_DECRYPT, '-'}, + {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"asciicrlf", OPT_ASCIICRLF, '-'}, + {"nointern", OPT_NOINTERN, '-', + "Don't search certificates in message for signer"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signers certificate when signing"}, + {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, + {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, + {"nosmimecap", OPT_NOSMIMECAP, '-'}, + {"binary", OPT_BINARY, '-', "Don't translate message to text"}, + {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-'}, + {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-'}, + {"stream", OPT_INDEF, '-'}, + {"indef", OPT_INDEF, '-'}, + {"noindef", OPT_NOINDEF, '-'}, + {"nooldmime", OPT_NOOLDMIME, '-'}, + {"crlfeol", OPT_CRLFEOL, '-'}, + {"noout", OPT_NOOUT, '-'}, + {"receipt_request_print", OPT_RR_PRINT, '-'}, + {"receipt_request_all", OPT_RR_ALL, '-'}, + {"receipt_request_first", OPT_RR_FIRST, '-'}, + {"rctform", OPT_RCTFORM, 'F'}, + {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CApath", OPT_CAPATH, '/', "trusted certificates directory"}, + {"content", OPT_CONTENT, '<', + "Supply or override content for detached signature"}, + {"print", OPT_PRINT, '-'}, + {"secretkey", OPT_SECRETKEY, 's'}, + {"secretkeyid", OPT_SECRETKEYID, 's'}, + {"pwri_password", OPT_PWRI_PASSWORD, 's'}, + {"econtent_type", OPT_ECONTENT_TYPE, 's'}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"to", OPT_TO, 's', "To address"}, + {"from", OPT_FROM, 's', "From address"}, + {"subject", OPT_SUBJECT, 's', "Subject"}, + {"signer", OPT_SIGNER, 's', "Signer certificate file"}, + {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, + {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, + {"md", OPT_MD, 's'}, + {"inkey", OPT_INKEY, '<', + "Input private key (if not signer or recipient)"}, + {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, + {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, + {"receipt_request_from", OPT_RR_FROM, 's'}, + {"receipt_request_to", OPT_RR_TO, 's'}, +# ifndef OPENSSL_NO_AES + {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, + {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, + {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, +# endif +# ifndef OPENSSL_NO_DES + {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, +# endif +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +# endif + {"", OPT_CIPHER, '-', "Any supported cipher"}, + OPT_V_OPTIONS, + {NULL}, +}; -int MAIN(int argc, char **argv) +int cms_main(int argc, char **argv) { - ENGINE *e = NULL; - int operation = 0; - int ret = 0; - char **args; - const char *inmode = "r", *outmode = "w"; - char *infile = NULL, *outfile = NULL, *rctfile = NULL; - char *signerfile = NULL, *recipfile = NULL; - STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; - char *certfile = NULL, *keyfile = NULL, *contfile = NULL; - char *certsoutfile = NULL; - const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; - CMS_ContentInfo *cms = NULL, *rcms = NULL; - X509_STORE *store = NULL; - X509 *cert = NULL, *recip = NULL, *signer = NULL; - EVP_PKEY *key = NULL; - STACK_OF(X509) *encerts = NULL, *other = NULL; + ASN1_OBJECT *econtent_type = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; - int badarg = 0; - int flags = CMS_DETACHED, noout = 0, print = 0; - int verify_retcode = 0; - int rr_print = 0, rr_allorfirst = -1; - STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; + CMS_ContentInfo *cms = NULL, *rcms = NULL; CMS_ReceiptRequest *rr = NULL; - char *to = NULL, *from = NULL, *subject = NULL; - char *CAfile = NULL, *CApath = NULL; - char *passargin = NULL, *passin = NULL; - char *inrand = NULL; - int need_rand = 0; + ENGINE *e = NULL; + EVP_PKEY *key = NULL; + const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; const EVP_MD *sign_md = NULL; + STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; + STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; + STACK_OF(X509) *encerts = NULL, *other = NULL; + X509 *cert = NULL, *recip = NULL, *signer = NULL; + X509_STORE *store = NULL; + X509_VERIFY_PARAM *vpm = NULL; + char *certfile = NULL, *keyfile = NULL, *contfile = NULL; + char *CAfile = NULL, *CApath = NULL, *certsoutfile = NULL, *engine = NULL; + char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL; + char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = + NULL; + char *to = NULL, *from = NULL, *subject = NULL, *prog; + cms_key_param *key_first = NULL, *key_param = NULL; + const char *inmode = "r", *outmode = "w"; + int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = + 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; - int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - unsigned char *secret_key = NULL, *secret_keyid = NULL; - unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; + int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst = + -1; + int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; size_t secret_keylen = 0, secret_keyidlen = 0; + unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; + unsigned char *secret_key = NULL, *secret_keyid = NULL; + long ltmp; + OPTION_CHOICE o; - cms_key_param *key_first = NULL, *key_param = NULL; - - ASN1_OBJECT *econtent_type = NULL; - - X509_VERIFY_PARAM *vpm = NULL; - - args = argv + 1; - ret = 1; - - apps_startup(); - - if (bio_err == NULL) { - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - } - - if (!load_config(bio_err, NULL)) - goto end; + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) + return 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-encrypt")) + prog = opt_init(argc, argv, cms_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(cms_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENCRYPT: operation = SMIME_ENCRYPT; - else if (!strcmp(*args, "-decrypt")) + break; + case OPT_DECRYPT: operation = SMIME_DECRYPT; - else if (!strcmp(*args, "-sign")) + break; + case OPT_SIGN: operation = SMIME_SIGN; - else if (!strcmp(*args, "-sign_receipt")) + break; + case OPT_SIGN_RECEIPT: operation = SMIME_SIGN_RECEIPT; - else if (!strcmp(*args, "-resign")) + break; + case OPT_RESIGN: operation = SMIME_RESIGN; - else if (!strcmp(*args, "-verify")) + break; + case OPT_VERIFY: operation = SMIME_VERIFY; - else if (!strcmp(*args, "-verify_retcode")) + break; + case OPT_VERIFY_RETCODE: verify_retcode = 1; - else if (!strcmp(*args, "-verify_receipt")) { + break; + case OPT_VERIFY_RECEIPT: operation = SMIME_VERIFY_RECEIPT; - if (!args[1]) - goto argerr; - args++; - rctfile = *args; - } else if (!strcmp(*args, "-cmsout")) + rctfile = opt_arg(); + break; + case OPT_CMSOUT: operation = SMIME_CMSOUT; - else if (!strcmp(*args, "-data_out")) + break; + case OPT_DATA_OUT: operation = SMIME_DATAOUT; - else if (!strcmp(*args, "-data_create")) + break; + case OPT_DATA_CREATE: operation = SMIME_DATA_CREATE; - else if (!strcmp(*args, "-digest_verify")) + break; + case OPT_DIGEST_VERIFY: operation = SMIME_DIGEST_VERIFY; - else if (!strcmp(*args, "-digest_create")) + break; + case OPT_DIGEST_CREATE: operation = SMIME_DIGEST_CREATE; - else if (!strcmp(*args, "-compress")) + break; + case OPT_COMPRESS: operation = SMIME_COMPRESS; - else if (!strcmp(*args, "-uncompress")) + break; + case OPT_UNCOMPRESS: operation = SMIME_UNCOMPRESS; - else if (!strcmp(*args, "-EncryptedData_decrypt")) + break; + case OPT_ED_DECRYPT: operation = SMIME_ENCRYPTED_DECRYPT; - else if (!strcmp(*args, "-EncryptedData_encrypt")) + break; + case OPT_ED_ENCRYPT: operation = SMIME_ENCRYPTED_ENCRYPT; -# ifndef OPENSSL_NO_DES - else if (!strcmp(*args, "-des3")) - cipher = EVP_des_ede3_cbc(); - else if (!strcmp(*args, "-des")) - cipher = EVP_des_cbc(); - else if (!strcmp(*args, "-des3-wrap")) - wrap_cipher = EVP_des_ede3_wrap(); -# endif -# ifndef OPENSSL_NO_SEED - else if (!strcmp(*args, "-seed")) - cipher = EVP_seed_cbc(); -# endif -# ifndef OPENSSL_NO_RC2 - else if (!strcmp(*args, "-rc2-40")) - cipher = EVP_rc2_40_cbc(); - else if (!strcmp(*args, "-rc2-128")) - cipher = EVP_rc2_cbc(); - else if (!strcmp(*args, "-rc2-64")) - cipher = EVP_rc2_64_cbc(); -# endif -# ifndef OPENSSL_NO_AES - else if (!strcmp(*args, "-aes128")) - cipher = EVP_aes_128_cbc(); - else if (!strcmp(*args, "-aes192")) - cipher = EVP_aes_192_cbc(); - else if (!strcmp(*args, "-aes256")) - cipher = EVP_aes_256_cbc(); - else if (!strcmp(*args, "-aes128-wrap")) - wrap_cipher = EVP_aes_128_wrap(); - else if (!strcmp(*args, "-aes192-wrap")) - wrap_cipher = EVP_aes_192_wrap(); - else if (!strcmp(*args, "-aes256-wrap")) - wrap_cipher = EVP_aes_256_wrap(); -# endif -# ifndef OPENSSL_NO_CAMELLIA - else if (!strcmp(*args, "-camellia128")) - cipher = EVP_camellia_128_cbc(); - else if (!strcmp(*args, "-camellia192")) - cipher = EVP_camellia_192_cbc(); - else if (!strcmp(*args, "-camellia256")) - cipher = EVP_camellia_256_cbc(); -# endif - else if (!strcmp(*args, "-debug_decrypt")) + break; + case OPT_DEBUG_DECRYPT: flags |= CMS_DEBUG_DECRYPT; - else if (!strcmp(*args, "-text")) + break; + case OPT_TEXT: flags |= CMS_TEXT; - else if (!strcmp(*args, "-asciicrlf")) + break; + case OPT_ASCIICRLF: flags |= CMS_ASCIICRLF; - else if (!strcmp(*args, "-nointern")) + break; + case OPT_NOINTERN: flags |= CMS_NOINTERN; - else if (!strcmp(*args, "-noverify") - || !strcmp(*args, "-no_signer_cert_verify")) + break; + case OPT_NOVERIFY: flags |= CMS_NO_SIGNER_CERT_VERIFY; - else if (!strcmp(*args, "-nocerts")) + break; + case OPT_NOCERTS: flags |= CMS_NOCERTS; - else if (!strcmp(*args, "-noattr")) + break; + case OPT_NOATTR: flags |= CMS_NOATTR; - else if (!strcmp(*args, "-nodetach")) + break; + case OPT_NODETACH: flags &= ~CMS_DETACHED; - else if (!strcmp(*args, "-nosmimecap")) + break; + case OPT_NOSMIMECAP: flags |= CMS_NOSMIMECAP; - else if (!strcmp(*args, "-binary")) + break; + case OPT_BINARY: flags |= CMS_BINARY; - else if (!strcmp(*args, "-keyid")) + break; + case OPT_KEYID: flags |= CMS_USE_KEYID; - else if (!strcmp(*args, "-nosigs")) + break; + case OPT_NOSIGS: flags |= CMS_NOSIGS; - else if (!strcmp(*args, "-no_content_verify")) + break; + case OPT_NO_CONTENT_VERIFY: flags |= CMS_NO_CONTENT_VERIFY; - else if (!strcmp(*args, "-no_attr_verify")) + break; + case OPT_NO_ATTR_VERIFY: flags |= CMS_NO_ATTR_VERIFY; - else if (!strcmp(*args, "-stream")) + break; + case OPT_INDEF: flags |= CMS_STREAM; - else if (!strcmp(*args, "-indef")) - flags |= CMS_STREAM; - else if (!strcmp(*args, "-noindef")) + break; + case OPT_NOINDEF: flags &= ~CMS_STREAM; - else if (!strcmp(*args, "-nooldmime")) + break; + case OPT_NOOLDMIME: flags |= CMS_NOOLDMIMETYPE; - else if (!strcmp(*args, "-crlfeol")) + break; + case OPT_CRLFEOL: flags |= CMS_CRLFEOL; - else if (!strcmp(*args, "-noout")) + break; + case OPT_NOOUT: noout = 1; - else if (!strcmp(*args, "-receipt_request_print")) + break; + case OPT_RR_PRINT: rr_print = 1; - else if (!strcmp(*args, "-receipt_request_all")) + break; + case OPT_RR_ALL: rr_allorfirst = 0; - else if (!strcmp(*args, "-receipt_request_first")) + break; + case OPT_RR_FIRST: rr_allorfirst = 1; - else if (!strcmp(*args, "-receipt_request_from")) { - if (!args[1]) - goto argerr; - args++; - if (!rr_from) - rr_from = sk_OPENSSL_STRING_new_null(); - sk_OPENSSL_STRING_push(rr_from, *args); - } else if (!strcmp(*args, "-receipt_request_to")) { - if (!args[1]) - goto argerr; - args++; - if (!rr_to) - rr_to = sk_OPENSSL_STRING_new_null(); - sk_OPENSSL_STRING_push(rr_to, *args); - } else if (!strcmp(*args, "-print")) { - noout = 1; - print = 1; - } else if (!strcmp(*args, "-secretkey")) { - long ltmp; - if (!args[1]) - goto argerr; - args++; - secret_key = string_to_hex(*args, <mp); - if (!secret_key) { - BIO_printf(bio_err, "Invalid key %s\n", *args); - goto argerr; + break; + case OPT_RCTFORM: + if (rctformat == FORMAT_SMIME) + rcms = SMIME_read_CMS(rctin, NULL); + else if (rctformat == FORMAT_PEM) + rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); + else if (rctformat == FORMAT_ASN1) + if (!opt_format(opt_arg(), + OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) + goto opthelp; + break; + case OPT_CERTFILE: + certfile = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_CONTENT: + contfile = opt_arg(); + break; + case OPT_RR_FROM: + if (rr_from == NULL + && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; + sk_OPENSSL_STRING_push(rr_from, opt_arg()); + break; + case OPT_RR_TO: + if (rr_to == NULL + && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; + sk_OPENSSL_STRING_push(rr_to, opt_arg()); + break; + case OPT_PRINT: + noout = print = 1; + break; + case OPT_SECRETKEY: + secret_key = string_to_hex(opt_arg(), <mp); + if (secret_key == NULL) { + BIO_printf(bio_err, "Invalid key %s\n", opt_arg()); + goto end; } secret_keylen = (size_t)ltmp; - } else if (!strcmp(*args, "-secretkeyid")) { - long ltmp; - if (!args[1]) - goto argerr; - args++; - secret_keyid = string_to_hex(*args, <mp); - if (!secret_keyid) { - BIO_printf(bio_err, "Invalid id %s\n", *args); - goto argerr; + break; + case OPT_SECRETKEYID: + secret_keyid = string_to_hex(opt_arg(), <mp); + if (secret_keyid == NULL) { + BIO_printf(bio_err, "Invalid id %s\n", opt_arg()); + goto opthelp; } secret_keyidlen = (size_t)ltmp; - } else if (!strcmp(*args, "-pwri_password")) { - if (!args[1]) - goto argerr; - args++; - pwri_pass = (unsigned char *)*args; - } else if (!strcmp(*args, "-econtent_type")) { - if (!args[1]) - goto argerr; - args++; - econtent_type = OBJ_txt2obj(*args, 0); - if (!econtent_type) { - BIO_printf(bio_err, "Invalid OID %s\n", *args); - goto argerr; + break; + case OPT_PWRI_PASSWORD: + pwri_pass = (unsigned char *)opt_arg(); + break; + case OPT_ECONTENT_TYPE: + econtent_type = OBJ_txt2obj(opt_arg(), 0); + if (econtent_type == NULL) { + BIO_printf(bio_err, "Invalid OID %s\n", opt_arg()); + goto opthelp; } - } else if (!strcmp(*args, "-rand")) { - if (!args[1]) - goto argerr; - args++; - inrand = *args; + break; + case OPT_RAND: + inrand = opt_arg(); need_rand = 1; - } -# ifndef OPENSSL_NO_ENGINE - else if (!strcmp(*args, "-engine")) { - if (!args[1]) - goto argerr; - engine = *++args; - } -# endif - else if (!strcmp(*args, "-passin")) { - if (!args[1]) - goto argerr; - passargin = *++args; - } else if (!strcmp(*args, "-to")) { - if (!args[1]) - goto argerr; - to = *++args; - } else if (!strcmp(*args, "-from")) { - if (!args[1]) - goto argerr; - from = *++args; - } else if (!strcmp(*args, "-subject")) { - if (!args[1]) - goto argerr; - subject = *++args; - } else if (!strcmp(*args, "-signer")) { - if (!args[1]) - goto argerr; + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_TO: + to = opt_arg(); + break; + case OPT_FROM: + from = opt_arg(); + break; + case OPT_SUBJECT: + subject = opt_arg(); + break; + case OPT_CERTSOUT: + certsoutfile = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_arg(), &sign_md)) + goto end; + break; + case OPT_SIGNER: /* If previous -signer argument add signer to list */ - if (signerfile) { - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (sksigners == NULL + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); - if (!keyfile) + if (keyfile == NULL) keyfile = signerfile; - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (skkeys == NULL + && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } - signerfile = *++args; - } else if (!strcmp(*args, "-recip")) { - if (!args[1]) - goto argerr; - if (operation == SMIME_ENCRYPT) { - if (!encerts) - encerts = sk_X509_new_null(); - cert = load_cert(bio_err, *++args, FORMAT_PEM, - NULL, e, "recipient certificate file"); - if (!cert) - goto end; - sk_X509_push(encerts, cert); - cert = NULL; - } else - recipfile = *++args; - } else if (!strcmp(*args, "-certsout")) { - if (!args[1]) - goto argerr; - certsoutfile = *++args; - } else if (!strcmp(*args, "-md")) { - if (!args[1]) - goto argerr; - sign_md = EVP_get_digestbyname(*++args); - if (sign_md == NULL) { - BIO_printf(bio_err, "Unknown digest %s\n", *args); - goto argerr; - } - } else if (!strcmp(*args, "-inkey")) { - if (!args[1]) - goto argerr; + signerfile = opt_arg(); + break; + case OPT_INKEY: /* If previous -inkey arument add signer to list */ if (keyfile) { - if (!signerfile) { + if (signerfile == NULL) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); - goto argerr; + goto end; } - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (sksigners == NULL + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (skkeys == NULL + && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); } - keyfile = *++args; - } else if (!strcmp(*args, "-keyform")) { - if (!args[1]) - goto argerr; - keyform = str2fmt(*++args); - } else if (!strcmp(*args, "-keyopt")) { - int keyidx = -1; - if (!args[1]) - goto argerr; + keyfile = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) + goto opthelp; + break; + case OPT_RECIP: + if (operation == SMIME_ENCRYPT) { + if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL) + goto end; + cert = load_cert(opt_arg(), FORMAT_PEM, NULL, e, + "recipient certificate file"); + if (cert == NULL) + goto end; + sk_X509_push(encerts, cert); + cert = NULL; + } else + recipfile = opt_arg(); + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &cipher)) + goto end; + break; + case OPT_KEYOPT: + keyidx = -1; if (operation == SMIME_ENCRYPT) { if (encerts) keyidx += sk_X509_num(encerts); @@ -460,17 +566,18 @@ int MAIN(int argc, char **argv) } if (keyidx < 0) { BIO_printf(bio_err, "No key specified\n"); - goto argerr; + goto opthelp; } if (key_param == NULL || key_param->idx != keyidx) { cms_key_param *nparam; nparam = OPENSSL_malloc(sizeof(cms_key_param)); if (!nparam) { BIO_printf(bio_err, "Out of memory\n"); - goto argerr; + goto end; } nparam->idx = keyidx; - nparam->param = sk_OPENSSL_STRING_new_null(); + if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; nparam->next = NULL; if (key_first == NULL) key_first = nparam; @@ -478,83 +585,68 @@ int MAIN(int argc, char **argv) key_param->next = nparam; key_param = nparam; } - sk_OPENSSL_STRING_push(key_param->param, *++args); - } else if (!strcmp(*args, "-rctform")) { - if (!args[1]) - goto argerr; - rctformat = str2fmt(*++args); - } else if (!strcmp(*args, "-certfile")) { - if (!args[1]) - goto argerr; - certfile = *++args; - } else if (!strcmp(*args, "-CAfile")) { - if (!args[1]) - goto argerr; - CAfile = *++args; - } else if (!strcmp(*args, "-CApath")) { - if (!args[1]) - goto argerr; - CApath = *++args; - } else if (!strcmp(*args, "-in")) { - if (!args[1]) - goto argerr; - infile = *++args; - } else if (!strcmp(*args, "-inform")) { - if (!args[1]) - goto argerr; - informat = str2fmt(*++args); - } else if (!strcmp(*args, "-outform")) { - if (!args[1]) - goto argerr; - outformat = str2fmt(*++args); - } else if (!strcmp(*args, "-out")) { - if (!args[1]) - goto argerr; - outfile = *++args; - } else if (!strcmp(*args, "-content")) { - if (!args[1]) - goto argerr; - contfile = *++args; - } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) - continue; - else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) - badarg = 1; - args++; + sk_OPENSSL_STRING_push(key_param->param, opt_arg()); + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto end; + vpmtouched++; + break; +# ifndef OPENSSL_NO_DES + case OPT_3DES_WRAP: + wrap_cipher = EVP_des_ede3_wrap(); + break; +# endif +# ifndef OPENSSL_NO_AES + case OPT_AES128_WRAP: + wrap_cipher = EVP_aes_128_wrap(); + break; + case OPT_AES192_WRAP: + wrap_cipher = EVP_aes_192_wrap(); + break; + case OPT_AES256_WRAP: + wrap_cipher = EVP_aes_256_wrap(); + break; +# endif + } } + argc = opt_num_rest(); + argv = opt_rest(); if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); - goto argerr; + goto opthelp; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); - goto argerr; + goto opthelp; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); - goto argerr; + goto opthelp; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); - goto argerr; + goto opthelp; } /* Check to see if any final signer needs to be appended */ if (signerfile) { - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (!sksigners + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); - badarg = 1; + goto opthelp; } signerfile = NULL; keyfile = NULL; @@ -565,121 +657,28 @@ int MAIN(int argc, char **argv) if (!recipfile && !keyfile && !secret_key && !pwri_pass) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); - badarg = 1; + goto opthelp; } } else if (operation == SMIME_ENCRYPT) { - if (!*args && !secret_key && !pwri_pass && !encerts) { + if (*argv == NULL && !secret_key && !pwri_pass && !encerts) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); - badarg = 1; + goto opthelp; } need_rand = 1; } else if (!operation) - badarg = 1; - - if (badarg) { - argerr: - BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-encrypt encrypt message\n"); - BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); - BIO_printf(bio_err, "-sign sign message\n"); - BIO_printf(bio_err, "-verify verify signed message\n"); - BIO_printf(bio_err, "-cmsout output CMS structure\n"); -# ifndef OPENSSL_NO_DES - BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); - BIO_printf(bio_err, "-des encrypt with DES\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, "-seed encrypt with SEED\n"); -# endif -# ifndef OPENSSL_NO_RC2 - BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); - BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); - BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif - BIO_printf(bio_err, - "-nointern don't search certificates in message for signer\n"); - BIO_printf(bio_err, - "-nosigs don't verify message signature\n"); - BIO_printf(bio_err, - "-noverify don't verify signers certificate\n"); - BIO_printf(bio_err, - "-nocerts don't include signers certificate when signing\n"); - BIO_printf(bio_err, "-nodetach use opaque signing\n"); - BIO_printf(bio_err, - "-noattr don't include any signed attributes\n"); - BIO_printf(bio_err, - "-binary don't translate message to text\n"); - BIO_printf(bio_err, "-certfile file other certificates file\n"); - BIO_printf(bio_err, "-certsout file certificate output file\n"); - BIO_printf(bio_err, "-signer file signer certificate file\n"); - BIO_printf(bio_err, - "-recip file recipient certificate file for decryption\n"); - BIO_printf(bio_err, "-keyid use subject key identifier\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, - "-inform arg input format SMIME (default), PEM or DER\n"); - BIO_printf(bio_err, - "-inkey file input private key (if not signer or recipient)\n"); - BIO_printf(bio_err, - "-keyform arg input private key format (PEM or ENGINE)\n"); - BIO_printf(bio_err, "-keyopt nm:v set public key parameters\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-outform arg output format SMIME (default), PEM or DER\n"); - BIO_printf(bio_err, - "-content file supply or override content for detached signature\n"); - BIO_printf(bio_err, "-to addr to address\n"); - BIO_printf(bio_err, "-from ad from address\n"); - BIO_printf(bio_err, "-subject s subject\n"); - BIO_printf(bio_err, - "-text include or delete text MIME headers\n"); - BIO_printf(bio_err, - "-CApath dir trusted certificates directory\n"); - BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); - BIO_printf(bio_err, - "-trusted_first use locally trusted certificates first when building trust chain\n"); - BIO_printf(bio_err, - "-no_alt_chains only ever use the first certificate chain found\n"); - BIO_printf(bio_err, - "-crl_check check revocation status of signer's certificate using CRLs\n"); - BIO_printf(bio_err, - "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); - BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, - "cert.pem recipient certificate(s) for encryption\n"); - goto end; - } + goto opthelp; + # ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); @@ -721,20 +720,21 @@ int MAIN(int argc, char **argv) goto end; } - if (*args && !encerts) - encerts = sk_X509_new_null(); - while (*args) { - if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, + if (*argv && !encerts) + if ((encerts = sk_X509_new_null()) == NULL) + goto end; + while (*argv) { + if (!(cert = load_cert(*argv, FORMAT_PEM, NULL, e, "recipient certificate file"))) goto end; sk_X509_push(encerts, cert); cert = NULL; - args++; + argv++; } } if (certfile) { - if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, + if (!(other = load_certs(certfile, FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; @@ -742,7 +742,7 @@ int MAIN(int argc, char **argv) } if (recipfile && (operation == SMIME_DECRYPT)) { - if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, + if (!(recip = load_cert(recipfile, FORMAT_PEM, NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; @@ -750,7 +750,7 @@ int MAIN(int argc, char **argv) } if (operation == SMIME_SIGN_RECEIPT) { - if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, + if (!(signer = load_cert(signerfile, FORMAT_PEM, NULL, e, "receipt signer certificate file"))) { ERR_print_errors(bio_err); goto end; @@ -767,19 +767,14 @@ int MAIN(int argc, char **argv) keyfile = NULL; if (keyfile) { - key = load_key(bio_err, keyfile, keyform, 0, passin, e, - "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } - if (infile) { - if (!(in = BIO_new_file(infile, inmode))) { - BIO_printf(bio_err, "Can't open input file %s\n", infile); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); + in = bio_open_default(infile, inmode); + if (in == NULL) + goto end; if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) @@ -841,26 +836,15 @@ int MAIN(int argc, char **argv) } } - if (outfile) { - if (!(out = BIO_new_file(outfile, outmode))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } + out = bio_open_default(outfile, outmode); + if (out == NULL) + goto end; if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { - if (!(store = setup_verify(bio_err, CAfile, CApath))) + if (!(store = setup_verify(CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, cms_cb); - if (vpm) + if (vpmtouched) X509_STORE_set1_param(store, vpm); } @@ -983,12 +967,11 @@ int MAIN(int argc, char **argv) signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); - signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, + signer = load_cert(signerfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; - key = load_key(bio_err, keyfile, keyform, 0, passin, e, - "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; for (kparam = key_first; kparam; kparam = kparam->next) { @@ -1137,11 +1120,10 @@ int MAIN(int argc, char **argv) if (ret) ERR_print_errors(bio_err); if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); - if (vpm) - X509_VERIFY_PARAM_free(vpm); + X509_VERIFY_PARAM_free(vpm); if (sksigners) sk_OPENSSL_STRING_free(sksigners); if (skkeys) @@ -1211,7 +1193,8 @@ static int cms_cb(int ok, X509_STORE_CTX *ctx) && ((error != X509_V_OK) || (ok != 2))) return ok; - policies_print(NULL, ctx); + /* Should be bio_err? */ + policies_print(bio_out, ctx); return ok; diff --git a/apps/crl.c b/apps/crl.c index 6819faa5b9..b8c592c6e2 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -1,4 +1,3 @@ -/* apps/crl.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,199 +65,168 @@ #include #include -#undef PROG -#define PROG crl_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY, + OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT, + OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, + OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD, OPT_NOOUT, + OPT_NAMEOPT, OPT_MD +} OPTION_CHOICE; -#undef POSTFIX -#define POSTFIX ".rvk" - -static const char *crl_usage[] = { - "usage: crl args\n", - "\n", - " -inform arg - input format - default PEM (DER or PEM)\n", - " -outform arg - output format - default PEM\n", - " -text - print out a text format version\n", - " -in arg - input file - default stdin\n", - " -out arg - output file - default stdout\n", - " -hash - print hash value\n", +OPTIONS crl_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format; default PEM"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"out", OPT_OUT, '>', "output file - default stdout"}, + {"keyform", OPT_KEYFORM, 'F'}, + {"key", OPT_KEY, '<'}, + {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, + {"lastupdate", OPT_LASTUPDATE, '-', "Set lastUpdate field"}, + {"nextupdate", OPT_NEXTUPDATE, '-', "Set nextUpdate field"}, + {"noout", OPT_NOOUT, '-', "No CRL output"}, + {"fingerprint", OPT_FINGERPRINT, '-', "Print the crl fingerprint"}, + {"crlnumber", OPT_CRLNUMBER, '-', "Print CRL number"}, + {"badsig", OPT_BADSIG, '-'}, + {"gendelta", OPT_GENDELTA, '<'}, + {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"}, + {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"}, + {"verify", OPT_VERIFY, '-'}, + {"text", OPT_TEXT, '-', "Print out a text format version"}, + {"hash", OPT_HASH, '-', "Print hash value"}, #ifndef OPENSSL_NO_MD5 - " -hash_old - print old-style (MD5) hash value\n", + {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, #endif - " -fingerprint - print the crl fingerprint\n", - " -issuer - print issuer DN\n", - " -lastupdate - lastUpdate field\n", - " -nextupdate - nextUpdate field\n", - " -crlnumber - print CRL number\n", - " -noout - no CRL output\n", - " -CAfile name - verify CRL using certificates in file \"name\"\n", - " -CApath dir - verify CRL using certificates in \"dir\"\n", - " -nameopt arg - various certificate name options\n", - NULL + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"", OPT_MD, '-', "Any supported digest"}, + {NULL} }; -static BIO *bio_out = NULL; - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int crl_main(int argc, char **argv) { - unsigned long nmflag = 0; X509_CRL *x = NULL; - char *CAfile = NULL, *CApath = NULL; - int ret = 1, i, num, badops = 0, badsig = 0; BIO *out = NULL; - int informat, outformat, keyformat; - char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; - int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = - 0, text = 0; -#ifndef OPENSSL_NO_MD5 - int hash_old = 0; -#endif - int fingerprint = 0, crlnumber = 0; - const char **pp; X509_STORE *store = NULL; X509_STORE_CTX ctx; X509_LOOKUP *lookup = NULL; X509_OBJECT xobj; EVP_PKEY *pkey; - int do_ver = 0; - const EVP_MD *md_alg, *digest = EVP_sha1(); - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - if (bio_out == NULL) - if ((bio_out = BIO_new(BIO_s_file())) != NULL) { - BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - bio_out = BIO_push(tmpbio, bio_out); - } + const EVP_MD *digest = EVP_sha1(); + unsigned long nmflag = 0; + char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; + char *CAfile = NULL, *CApath = NULL, *prog; + OPTION_CHOICE o; + int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = + 0, text = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; + int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = + 0, i, do_ver = 0; +#ifndef OPENSSL_NO_MD5 + int hash_old = 0; #endif - } - - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - keyformat = FORMAT_PEM; - argc--; - argv++; - num = 0; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-gendelta") == 0) { - if (--argc < 1) - goto bad; - crldiff = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - keyformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-CApath") == 0) { - if (--argc < 1) - goto bad; - CApath = *(++argv); - do_ver = 1; - } else if (strcmp(*argv, "-CAfile") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); + prog = opt_init(argc, argv, crl_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(crl_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + goto opthelp; + break; + case OPT_KEY: + keyfile = opt_arg(); + break; + case OPT_GENDELTA: + crldiff = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); do_ver = 1; - } else if (strcmp(*argv, "-verify") == 0) + break; + case OPT_CAFILE: + CAfile = opt_arg(); do_ver = 1; - else if (strcmp(*argv, "-text") == 0) - text = 1; - else if (strcmp(*argv, "-hash") == 0) - hash = ++num; + break; #ifndef OPENSSL_NO_MD5 - else if (strcmp(*argv, "-hash_old") == 0) + case OPT_HASH_OLD: hash_old = ++num; + break; #endif - else if (strcmp(*argv, "-nameopt") == 0) { - if (--argc < 1) - goto bad; - if (!set_name_ex(&nmflag, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-issuer") == 0) + case OPT_VERIFY: + do_ver = 1; + break; + case OPT_TEXT: + text = 1; + break; + case OPT_HASH: + hash = ++num; + break; + case OPT_ISSUER: issuer = ++num; - else if (strcmp(*argv, "-lastupdate") == 0) + break; + case OPT_LASTUPDATE: lastupdate = ++num; - else if (strcmp(*argv, "-nextupdate") == 0) + break; + case OPT_NEXTUPDATE: nextupdate = ++num; - else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = ++num; - else if (strcmp(*argv, "-fingerprint") == 0) + break; + case OPT_FINGERPRINT: fingerprint = ++num; - else if (strcmp(*argv, "-crlnumber") == 0) + break; + case OPT_CRLNUMBER: crlnumber = ++num; - else if (strcmp(*argv, "-badsig") == 0) + break; + case OPT_BADSIG: badsig = 1; - else if ((md_alg = EVP_get_digestbyname(*argv + 1))) { - /* ok */ - digest = md_alg; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; + case OPT_NAMEOPT: + if (!set_name_ex(&nmflag, opt_arg())) + goto opthelp; + break; + case OPT_MD: + if (!opt_md(opt_unknown(), &digest)) + goto opthelp; } - argc--; - argv++; - } - - if (badops) { - bad: - for (pp = crl_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); - goto end; } + argc = opt_num_rest(); + argv = opt_rest(); - ERR_load_crypto_strings(); x = load_crl(infile, informat); - if (x == NULL) { + if (x == NULL) goto end; - } if (do_ver) { - store = X509_STORE_new(); - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if (lookup == NULL) + if (!(store = setup_verify(CAfile, CApath))) goto end; - if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); - - lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; - if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - ERR_clear_error(); - if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; @@ -295,8 +263,7 @@ int MAIN(int argc, char **argv) newcrl = load_crl(crldiff, informat); if (!newcrl) goto end; - pkey = load_key(bio_err, keyfile, keyformat, 0, NULL, NULL, - "CRL signing key"); + pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); if (!pkey) { X509_CRL_free(newcrl); goto end; @@ -371,27 +338,9 @@ int MAIN(int argc, char **argv) } } } - - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } - - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } if (text) X509_CRL_print(out, x); @@ -406,28 +355,22 @@ int MAIN(int argc, char **argv) if (outformat == FORMAT_ASN1) i = (int)i2d_X509_CRL_bio(out, x); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_X509_CRL(out, x); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write CRL\n"); goto end; } ret = 0; + end: if (ret != 0) ERR_print_errors(bio_err); BIO_free_all(out); - BIO_free_all(bio_out); - bio_out = NULL; X509_CRL_free(x); if (store) { X509_STORE_CTX_cleanup(&ctx); X509_STORE_free(store); } - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/crl2p7.c b/apps/crl2p7.c index 86b3a94760..d75b6674a5 100644 --- a/apps/crl2p7.c +++ b/apps/crl2p7.c @@ -1,4 +1,3 @@ -/* apps/crl2p7.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -74,129 +73,89 @@ #include static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile); -#undef PROG -#define PROG crl2pkcs7_main -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - */ +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS crl2pkcs7_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"nocrl", OPT_NOCRL, '-', "No crl to load, just certs from '-certfile'"}, + {"certfile", OPT_CERTFILE, '<', + "File of chain of certs to a trusted CA; can be repeated"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int crl2pkcs7_main(int argc, char **argv) { - int i, badops = 0; BIO *in = NULL, *out = NULL; - int informat, outformat; - char *infile, *outfile, *prog, *certfile; PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; - X509_CRL *crl = NULL; STACK_OF(OPENSSL_STRING) *certflst = NULL; - STACK_OF(X509_CRL) *crl_stack = NULL; STACK_OF(X509) *cert_stack = NULL; - int ret = 1, nocrl = 0; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; + STACK_OF(X509_CRL) *crl_stack = NULL; + X509_CRL *crl = NULL; + char *infile = NULL, *outfile = NULL, *prog, *certfile; + int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl = + 0; + OPTION_CHOICE o; - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-nocrl") == 0) { + prog = opt_init(argc, argv, crl2pkcs7_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(crl2pkcs7_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_NOCRL: nocrl = 1; - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-certfile") == 0) { - if (--argc < 1) - goto bad; - if (!certflst) - certflst = sk_OPENSSL_STRING_new_null(); - if (!certflst) + break; + case OPT_CERTFILE: + if (!certflst && !(certflst = sk_OPENSSL_STRING_new_null())) goto end; if (!sk_OPENSSL_STRING_push(certflst, *(++argv))) { sk_OPENSSL_STRING_free(certflst); goto end; } - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; } - argc--; - argv++; - } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, - " -certfile arg certificates file of chain to a trusted CA\n"); - BIO_printf(bio_err, " (can be used more than once)\n"); - BIO_printf(bio_err, - " -nocrl no crl to load, just certs from '-certfile'\n"); - ret = 1; - goto end; - } - - ERR_load_crypto_strings(); - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); - goto end; } + argc = opt_num_rest(); + argv = opt_rest(); if (!nocrl) { - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } + in = bio_open_default(infile, RB(informat)); + if (in == NULL) + goto end; if (informat == FORMAT_ASN1) crl = d2i_X509_CRL_bio(in, NULL); else if (informat == FORMAT_PEM) crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, "bad input format specified for input crl\n"); - goto end; - } if (crl == NULL) { BIO_printf(bio_err, "unable to load CRL\n"); ERR_print_errors(bio_err); @@ -238,29 +197,14 @@ int MAIN(int argc, char **argv) sk_OPENSSL_STRING_free(certflst); - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, WB(outformat)); + if (out == NULL) + goto end; if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else if (outformat == FORMAT_PEM) i = PEM_write_bio_PKCS7(out, p7); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); @@ -274,8 +218,7 @@ int MAIN(int argc, char **argv) if (crl != NULL) X509_CRL_free(crl); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } /*- @@ -296,8 +239,8 @@ static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile) STACK_OF(X509_INFO) *sk = NULL; X509_INFO *xi; - in = BIO_new(BIO_s_file()); - if ((in == NULL) || (BIO_read_filename(in, certfile) <= 0)) { + in = BIO_new_file(certfile, "r"); + if (in == NULL) { BIO_printf(bio_err, "error opening the file, %s\n", certfile); goto end; } diff --git a/apps/dgst.c b/apps/dgst.c index 700600011c..21b8c7fc66 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -1,4 +1,3 @@ -/* apps/dgst.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,221 +70,186 @@ #undef BUFSIZE #define BUFSIZE 1024*8 -#undef PROG -#define PROG dgst_main - int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file, BIO *bmd); -static void list_md_fn(const EVP_MD *m, - const char *from, const char *to, void *arg) -{ - const char *mname; - /* Skip aliases */ - if (!m) - return; - mname = OBJ_nid2ln(EVP_MD_type(m)); - /* Skip shortnames */ - if (strcmp(from, mname)) - return; - /* Skip clones */ - if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) - return; - if (strchr(mname, ' ')) - mname = EVP_MD_name(m); - BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", - mname, mname); -} - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, + OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, + OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, + OPT_NON_FIPS_ALLOW, OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, + OPT_DIGEST +} OPTION_CHOICE; + +OPTIONS dgst_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, + {OPT_HELP_STR, 1, '-', + " file... files to digest (default is stdin)\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"c", OPT_C, '-', "Print the digest with separating colons"}, + {"r", OPT_R, '-', "Print the digest in coreutils format"}, + {"rand", OPT_RAND, 's'}, + {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, + {"passin", OPT_PASSIN, 's'}, + {"sign", OPT_SIGN, '<', "Sign digest using private key in file"}, + {"verify", OPT_VERIFY, '<', + "Verify a signature using public key in file"}, + {"prverify", OPT_PRVERIFY, '<', + "Verify a signature using private key in file"}, + {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, + {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +#endif + {"engine_impl", OPT_ENGINE_IMPL, '-'}, + {"hex", OPT_HEX, '-', "Print as hex dump"}, + {"binary", OPT_BINARY, '-', "Print in binary form"}, + {"d", OPT_DEBUG, '-', "Print debug info"}, + {"debug", OPT_DEBUG, '-'}, + {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-'}, + {"non-fips-allow", OPT_NON_FIPS_ALLOW, '-'}, + {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, + {"mac", OPT_MAC, 's', "Create MAC (not neccessarily HMAC)"}, + {"sigop", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"macop", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, + {"", OPT_DIGEST, '-', "Any supported digest"}, + {NULL} +}; + +int dgst_main(int argc, char **argv) { + BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; ENGINE *e = NULL, *impl = NULL; - unsigned char *buf = NULL; - int i, err = 1; + EVP_PKEY *sigkey = NULL; + STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; + char *hmac_key = NULL; + char *mac_name = NULL; + char *passinarg = NULL, *passin = NULL; const EVP_MD *md = NULL, *m; - BIO *in = NULL, *inp; - BIO *bmd = NULL; - BIO *out = NULL; -#define PROG_NAME_SIZE 39 - char pname[PROG_NAME_SIZE + 1]; - int separator = 0; - int debug = 0; - int keyform = FORMAT_PEM; - const char *outfile = NULL, *keyfile = NULL; + const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL, *randfile = NULL; - int out_bin = -1, want_pub = 0, do_verify = 0; - EVP_PKEY *sigkey = NULL; - unsigned char *sigbuf = NULL; - int siglen = 0; - char *passargin = NULL, *passin = NULL; + OPTION_CHOICE o; + int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; + int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = + 0, non_fips_allow = 0; + unsigned char *buf = NULL, *sigbuf = NULL; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; int engine_impl = 0; #endif - char *hmac_key = NULL; - char *mac_name = NULL; - int non_fips_allow = 0; - STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; - - apps_startup(); + prog = opt_progname(argv[0]); if ((buf = (unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) { - BIO_printf(bio_err, "out of memory\n"); + BIO_printf(bio_err, "%s: out of memory\n", prog); goto end; } - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - /* first check the program name */ - program_name(argv[0], pname, sizeof pname); - - md = EVP_get_digestbyname(pname); - - argc--; - argv++; - while (argc > 0) { - if ((*argv)[0] != '-') - break; - if (strcmp(*argv, "-c") == 0) + md = EVP_get_digestbyname(prog); + + prog = opt_init(argc, argv, dgst_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(dgst_options); + ret = 0; + goto end; + case OPT_C: separator = 1; - else if (strcmp(*argv, "-r") == 0) + break; + case OPT_R: separator = 2; - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - break; - randfile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - break; - outfile = *(++argv); - } else if (strcmp(*argv, "-sign") == 0) { - if (--argc < 1) - break; - keyfile = *(++argv); - } else if (!strcmp(*argv, "-passin")) { - if (--argc < 1) - break; - passargin = *++argv; - } else if (strcmp(*argv, "-verify") == 0) { - if (--argc < 1) - break; - keyfile = *(++argv); - want_pub = 1; - do_verify = 1; - } else if (strcmp(*argv, "-prverify") == 0) { - if (--argc < 1) - break; - keyfile = *(++argv); + break; + case OPT_RAND: + randfile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_SIGN: + keyfile = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_VERIFY: + keyfile = opt_arg(); + want_pub = do_verify = 1; + break; + case OPT_PRVERIFY: + keyfile = opt_arg(); do_verify = 1; - } else if (strcmp(*argv, "-signature") == 0) { - if (--argc < 1) - break; - sigfile = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - break; - keyform = str2fmt(*(++argv)); - } + break; + case OPT_SIGNATURE: + sigfile = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) + goto opthelp; + break; #ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - break; - engine = *(++argv); - e = setup_engine(bio_err, engine, 0); - } else if (strcmp(*argv, "-engine_impl") == 0) + case OPT_ENGINE: + engine = opt_arg(); + e = setup_engine(engine, 0); + break; + case OPT_ENGINE_IMPL: engine_impl = 1; + break; #endif - else if (strcmp(*argv, "-hex") == 0) + case OPT_HEX: out_bin = 0; - else if (strcmp(*argv, "-binary") == 0) + break; + case OPT_BINARY: out_bin = 1; - else if (strcmp(*argv, "-d") == 0) + break; + case OPT_DEBUG: debug = 1; - else if (!strcmp(*argv, "-fips-fingerprint")) + break; + case OPT_FIPS_FINGERPRINT: hmac_key = "etaonrishdlcupfm"; - else if (strcmp(*argv, "-non-fips-allow") == 0) + break; + case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; - else if (!strcmp(*argv, "-hmac")) { - if (--argc < 1) - break; - hmac_key = *++argv; - } else if (!strcmp(*argv, "-mac")) { - if (--argc < 1) - break; - mac_name = *++argv; - } else if (strcmp(*argv, "-sigopt") == 0) { - if (--argc < 1) - break; + break; + case OPT_HMAC: + hmac_key = opt_arg(); + break; + case OPT_MAC: + mac_name = opt_arg(); + break; + case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) - break; - } else if (strcmp(*argv, "-macopt") == 0) { - if (--argc < 1) - break; + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto opthelp; + break; + case OPT_MACOPT: if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); - if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) - break; - } else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL) + if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) + goto opthelp; + break; + case OPT_DIGEST: + if (!opt_md(opt_unknown(), &m)) + goto opthelp; md = m; - else break; - argc--; - argv++; + } } + argc = opt_num_rest(); + argv = opt_rest(); if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } - - if ((argc > 0) && (argv[0][0] == '-')) { /* bad option */ - BIO_printf(bio_err, "unknown option '%s'\n", *argv); - BIO_printf(bio_err, "options are\n"); - BIO_printf(bio_err, - "-c to output the digest with separating colons\n"); - BIO_printf(bio_err, - "-r to output the digest in coreutils format\n"); - BIO_printf(bio_err, "-d to output debug info\n"); - BIO_printf(bio_err, "-hex output as hex dump\n"); - BIO_printf(bio_err, "-binary output in binary form\n"); - BIO_printf(bio_err, "-hmac arg set the HMAC key to arg\n"); - BIO_printf(bio_err, "-non-fips-allow allow use of non FIPS digest\n"); - BIO_printf(bio_err, - "-sign file sign digest using private key in file\n"); - BIO_printf(bio_err, - "-verify file verify a signature using public key in file\n"); - BIO_printf(bio_err, - "-prverify file verify a signature using private key in file\n"); - BIO_printf(bio_err, - "-keyform arg key file format (PEM or ENGINE)\n"); - BIO_printf(bio_err, - "-out filename output to filename rather than stdout\n"); - BIO_printf(bio_err, "-signature file signature to verify\n"); - BIO_printf(bio_err, "-sigopt nm:v signature parameter\n"); - BIO_printf(bio_err, "-hmac key create hashed MAC with key\n"); - BIO_printf(bio_err, - "-mac algorithm create MAC (not neccessarily HMAC)\n"); - BIO_printf(bio_err, - "-macopt nm:v MAC algorithm parameters or key\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - - EVP_MD_do_all_sorted(list_md_fn, bio_err); - goto end; - } #ifndef OPENSSL_NO_ENGINE if (engine_impl) impl = e; @@ -304,7 +268,7 @@ int MAIN(int argc, char **argv) BIO_set_callback_arg(in, (char *)bio_err); } - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -317,29 +281,12 @@ int MAIN(int argc, char **argv) } if (randfile) - app_RAND_load_file(randfile, bio_err, 0); + app_RAND_load_file(randfile, 0); - if (outfile) { - if (out_bin) - out = BIO_new_file(outfile, "wb"); - else - out = BIO_new_file(outfile, "w"); - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } - - if (!out) { - BIO_printf(bio_err, "Error opening output file %s\n", - outfile ? outfile : "(stdout)"); - ERR_print_errors(bio_err); + out = bio_open_default(outfile, out_bin ? "wb" : "w"); + if (out == NULL) goto end; - } + if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; @@ -347,11 +294,9 @@ int MAIN(int argc, char **argv) if (keyfile) { if (want_pub) - sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, - e, "key file"); + sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); else - sigkey = load_key(bio_err, keyfile, keyform, 0, passin, - e, "key file"); + sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate message @@ -363,7 +308,7 @@ int MAIN(int argc, char **argv) if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; - if (!init_gen_str(bio_err, &mac_ctx, mac_name, impl, 0)) + if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) goto mac_end; if (macopts) { char *macopt; @@ -443,25 +388,23 @@ int MAIN(int argc, char **argv) if (md == NULL) md = EVP_md5(); if (!EVP_DigestInit_ex(mctx, md, impl)) { - BIO_printf(bio_err, "Error setting digest %s\n", pname); + BIO_printf(bio_err, "Error setting digest\n"); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { - BIO *sigbio; - sigbio = BIO_new_file(sigfile, "rb"); - siglen = EVP_PKEY_size(sigkey); - sigbuf = OPENSSL_malloc(siglen); + BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } + siglen = EVP_PKEY_size(sigkey); + sigbuf = OPENSSL_malloc(siglen); if (!sigbuf) { BIO_printf(bio_err, "Out of memory\n"); - ERR_print_errors(bio_err); goto end; } siglen = BIO_read(sigbio, sigbuf, siglen); @@ -482,7 +425,7 @@ int MAIN(int argc, char **argv) if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); - err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, + ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin", bmd); } else { const char *md_name = NULL, *sig_name = NULL; @@ -497,18 +440,18 @@ int MAIN(int argc, char **argv) if (md) md_name = EVP_MD_name(md); } - err = 0; + ret = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); - err++; + ret++; continue; } else r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i], bmd); if (r) - err = r; + ret = r; (void)BIO_reset(bmd); } } @@ -529,8 +472,7 @@ int MAIN(int argc, char **argv) if (sigbuf) OPENSSL_free(sigbuf); BIO_free(bmd); - apps_shutdown(); - OPENSSL_EXIT(err); + return (ret); } int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, diff --git a/apps/dh.c b/apps/dh.c deleted file mode 100644 index 1b653f548a..0000000000 --- a/apps/dh.c +++ /dev/null @@ -1,325 +0,0 @@ -/* apps/dh.c */ -/* obsoleted by dhparam.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include /* for OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_DH -# include -# include -# include -# include -# include "apps.h" -# include -# include -# include -# include -# include -# include - -# undef PROG -# define PROG dh_main - -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -check - check the parameters are ok - * -noout - * -text - * -C - */ - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) -{ - DH *dh = NULL; - int i, badops = 0, text = 0; - BIO *in = NULL, *out = NULL; - int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; - char *infile, *outfile, *prog; -# ifndef OPENSSL_NO_ENGINE - char *engine; -# endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - -# ifndef OPENSSL_NO_ENGINE - engine = NULL; -# endif - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif - else if (strcmp(*argv, "-check") == 0) - check = 1; - else if (strcmp(*argv, "-text") == 0) - text = 1; - else if (strcmp(*argv, "-C") == 0) - C = 1; - else if (strcmp(*argv, "-noout") == 0) - noout = 1; - else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; - break; - } - argc--; - argv++; - } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); - BIO_printf(bio_err, - " -outform arg output format - one of DER PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, " -check check the DH parameters\n"); - BIO_printf(bio_err, - " -text print a text form of the DH parameters\n"); - BIO_printf(bio_err, " -C Output C code\n"); - BIO_printf(bio_err, " -noout no output\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -# endif - goto end; - } - - ERR_load_crypto_strings(); - -# ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); -# endif - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); - goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } - - if (informat == FORMAT_ASN1) - dh = d2i_DHparams_bio(in, NULL); - else if (informat == FORMAT_PEM) - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, "bad input format specified\n"); - goto end; - } - if (dh == NULL) { - BIO_printf(bio_err, "unable to load DH parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - - if (text) { - DHparams_print(out, dh); - } - - if (check) { - if (!DH_check(dh, &i)) { - ERR_print_errors(bio_err); - goto end; - } - if (i & DH_CHECK_P_NOT_PRIME) - printf("p value is not prime\n"); - if (i & DH_CHECK_P_NOT_SAFE_PRIME) - printf("p value is not a safe prime\n"); - if (i & DH_UNABLE_TO_CHECK_GENERATOR) - printf("unable to check the generator value\n"); - if (i & DH_NOT_SUITABLE_GENERATOR) - printf("the g value is not a generator\n"); - if (i == 0) - printf("DH parameters appear to be ok.\n"); - } - if (C) { - unsigned char *data; - int len, l, bits; - - len = BN_num_bytes(dh->p); - bits = BN_num_bits(dh->p); - data = (unsigned char *)OPENSSL_malloc(len); - if (data == NULL) { - perror("OPENSSL_malloc"); - goto end; - } - l = BN_bn2bin(dh->p, data); - printf("static unsigned char dh%d_p[]={", bits); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t};\n"); - - l = BN_bn2bin(dh->g, data); - printf("static unsigned char dh%d_g[]={", bits); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t};\n\n"); - - printf("DH *get_dh%d()\n\t{\n", bits); - printf("\tDH *dh;\n\n"); - printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); - printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", - bits, bits); - printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", - bits, bits); - printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); - printf("\t\treturn(NULL);\n"); - printf("\treturn(dh);\n\t}\n"); - OPENSSL_free(data); - } - - if (!noout) { - if (outformat == FORMAT_ASN1) - i = i2d_DHparams_bio(out, dh); - else if (outformat == FORMAT_PEM) - i = PEM_write_bio_DHparams(out, dh); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } - if (!i) { - BIO_printf(bio_err, "unable to write DH parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - } - ret = 0; - end: - BIO_free(in); - BIO_free_all(out); - DH_free(dh); - apps_shutdown(); - OPENSSL_EXIT(ret); -} -#else /* !OPENSSL_NO_DH */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/apps/dhparam.c b/apps/dhparam.c index fc5962a7a1..e842ca5f20 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -1,4 +1,3 @@ -/* apps/dhparam.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -127,170 +126,131 @@ # include # endif -# undef PROG -# define PROG dhparam_main - # define DEFBITS 2048 -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -dsaparam - read or generate DSA parameters, convert to DH - * -check - check the parameters are ok - * -noout - * -text - * -C - */ - static int dh_cb(int p, int n, BN_GENCB *cb); -int MAIN(int, char **); - -int MAIN(int argc, char **argv) -{ - DH *dh = NULL; - int i, badops = 0, text = 0; -# ifndef OPENSSL_NO_DSA - int dsaparam = 0; -# endif - BIO *in = NULL, *out = NULL; - int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; - char *infile, *outfile, *prog; - char *inrand = NULL; +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, + OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, + OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5 +} OPTION_CHOICE; + +OPTIONS dhparam_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, + {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, + {"out", OPT_OUT, '>', "Output file"}, + {"check", OPT_CHECK, '-', "Check the DH parameters"}, + {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, + {"noout", OPT_NOOUT, '-'}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"C", OPT_C, '-', "Print C code"}, + {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, + {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, # ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif - int num = 0, g = 0; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } +# ifndef OPENSSL_NO_DSA + {"dsaparam", OPT_DSAPARAM, '-', + "Read or generate DSA parameters, convert to DH"}, # endif - else if (strcmp(*argv, "-check") == 0) + {NULL} +}; + +int dhparam_main(int argc, char **argv) +{ + BIO *in = NULL, *out = NULL; + DH *dh = NULL; + char *engine = NULL, *infile = NULL, *outfile = NULL, *prog, *inrand = + NULL; + int dsaparam = 0, i, text = 0, C = 0, ret = 1, num = 0, g = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, dhparam_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(dhparam_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_CHECK: check = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = 1; -# ifndef OPENSSL_NO_DSA - else if (strcmp(*argv, "-dsaparam") == 0) + break; + case OPT_DSAPARAM: dsaparam = 1; -# endif - else if (strcmp(*argv, "-C") == 0) + break; + case OPT_C: C = 1; - else if (strcmp(*argv, "-noout") == 0) - noout = 1; - else if (strcmp(*argv, "-2") == 0) + break; + case OPT_2: g = 2; - else if (strcmp(*argv, "-5") == 0) + break; + case OPT_5: g = 5; - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } else if (((sscanf(*argv, "%d", &num) == 0) || (num <= 0))) - goto bad; - argv++; - argc--; + break; + case OPT_NOOUT: + noout = 1; + break; + case OPT_RAND: + inrand = opt_arg(); + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] [numbits]\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); - BIO_printf(bio_err, - " -outform arg output format - one of DER PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); -# ifndef OPENSSL_NO_DSA - BIO_printf(bio_err, - " -dsaparam read or generate DSA parameters, convert to DH\n"); -# endif - BIO_printf(bio_err, " -check check the DH parameters\n"); - BIO_printf(bio_err, - " -text print a text form of the DH parameters\n"); - BIO_printf(bio_err, " -C Output C code\n"); - BIO_printf(bio_err, - " -2 generate parameters using 2 as the generator value\n"); - BIO_printf(bio_err, - " -5 generate parameters using 5 as the generator value\n"); - BIO_printf(bio_err, - " numbits number of bits in to generate (default 2048)\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " - load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, " -noout no output\n"); + if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) goto end; - } - - ERR_load_crypto_strings(); # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif if (g && !num) num = DEFBITS; # ifndef OPENSSL_NO_DSA - if (dsaparam) { - if (g) { - BIO_printf(bio_err, - "generator may not be chosen for DSA parameters\n"); - goto end; - } - } else -# endif - { - /* DH parameters */ - if (num && !g) - g = 2; + if (dsaparam && g) { + BIO_printf(bio_err, + "generator may not be chosen for DSA parameters\n"); + goto end; } +# endif + /* DH parameters */ + if (num && !g) + g = 2; if (num) { @@ -302,7 +262,7 @@ int MAIN(int argc, char **argv) } BN_GENCB_set(cb, dh_cb, bio_err); - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { + if (!app_RAND_load_file(NULL, 1) && inrand == NULL) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } @@ -348,27 +308,13 @@ int MAIN(int argc, char **argv) } BN_GENCB_free(cb); - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); } else { - in = BIO_new(BIO_s_file()); - if (in == NULL) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, RB(informat)); + if (in == NULL) goto end; - } - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } - if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) { - BIO_printf(bio_err, "bad input format specified\n"); - goto end; - } # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; @@ -408,25 +354,9 @@ int MAIN(int argc, char **argv) /* dh != NULL */ } - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } if (text) { DHparams_print(out, dh); @@ -450,7 +380,7 @@ int MAIN(int argc, char **argv) } if (C) { unsigned char *data; - int len, l, bits; + int len, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); @@ -459,54 +389,39 @@ int MAIN(int argc, char **argv) perror("OPENSSL_malloc"); goto end; } - printf("#ifndef HEADER_DH_H\n" - "#include \n" "#endif\n"); - printf("DH *get_dh%d()\n\t{\n", bits); - - l = BN_bn2bin(dh->p, data); - printf("\tstatic unsigned char dh%d_p[]={", bits); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t\t};\n"); - - l = BN_bn2bin(dh->g, data); - printf("\tstatic unsigned char dh%d_g[]={", bits); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t\t};\n"); - - printf("\tDH *dh;\n\n"); - printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); - printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", + BIO_printf(out, "#ifndef HEADER_DH_H\n" + "# include \n" + "#endif\n" + "\n"); + BIO_printf(out, "DH *get_dh%d()\n{\n", bits); + print_bignum_var(out, dh->p, "dhp", bits, data); + print_bignum_var(out, dh->g, "dhg", bits, data); + BIO_printf(out, " DH *dh = DN_new();\n" + "\n" + " if (dh == NULL)\n" + " return NULL;\n"); + BIO_printf(out, " dh->p = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n", bits, bits); - printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", + BIO_printf(out, " dh->g = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n", bits, bits); - printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); - printf("\t\t{ DH_free(dh); return(NULL); }\n"); + BIO_printf(out, " if (!dh->p || !dh->g) {\n" + " DH_free(dh);\n" + " return NULL;\n" + " }\n"); if (dh->length) - printf("\tdh->length = %ld;\n", dh->length); - printf("\treturn(dh);\n\t}\n"); + BIO_printf(out, + " dh->length = %ld;\n", dh->length); + BIO_printf(out, " return dh;\n}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); - else if (outformat == FORMAT_PEM) { - if (dh->q) - i = PEM_write_bio_DHxparams(out, dh); - else - i = PEM_write_bio_DHparams(out, dh); - } else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } + else if (dh->q) + i = PEM_write_bio_DHxparams(out, dh); + else + i = PEM_write_bio_DHparams(out, dh); if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); @@ -518,11 +433,9 @@ int MAIN(int argc, char **argv) BIO_free(in); BIO_free_all(out); DH_free(dh); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } -/* dh_cb is identical to dsa_cb in apps/dsaparam.c */ static int dh_cb(int p, int n, BN_GENCB *cb) { char c = '*'; diff --git a/apps/dsa.c b/apps/dsa.c index 1ea0d7346d..9d7c97f609 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -1,4 +1,3 @@ -/* apps/dsa.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,214 +70,145 @@ # include # include -# undef PROG -# define PROG dsa_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, + OPT_ENGINE, OPT_PVK_STRONG, OPT_PVK_WEAK, + OPT_PVK_NONE, OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_PUBIN, + OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT +} OPTION_CHOICE; -/*- - * -inform arg - input format - default PEM (one of DER, NET or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -des - encrypt output if PEM format with DES in cbc mode - * -des3 - encrypt output if PEM format - * -idea - encrypt output if PEM format - * -aes128 - encrypt output if PEM format - * -aes192 - encrypt output if PEM format - * -aes256 - encrypt output if PEM format - * -camellia128 - encrypt output if PEM format - * -camellia192 - encrypt output if PEM format - * -camellia256 - encrypt output if PEM format - * -seed - encrypt output if PEM format - * -text - print a text version - * -modulus - print the DSA public key - */ - -int MAIN(int, char **); +OPTIONS dsa_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format, DER PEM PVK"}, + {"outform", OPT_OUTFORM, 'F', "Output format, DER PEM PVK"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +# endif + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pvk-strong", OPT_PVK_STRONG, '-'}, + {"pvk-weak", OPT_PVK_WEAK, '-'}, + {"pvk-none", OPT_PVK_NONE, '-'}, + {"noout", OPT_NOOUT, '-', "Don't print key out"}, + {"text", OPT_TEXT, '-', "Print the key in text"}, + {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, + {"pubin", OPT_PUBIN, '-'}, + {"pubout", OPT_PUBOUT, '-'}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int dsa_main(int argc, char **argv) { - ENGINE *e = NULL; - int ret = 1; + BIO *out = NULL; DSA *dsa = NULL; - int i, badops = 0; + ENGINE *e = NULL; const EVP_CIPHER *enc = NULL; - BIO *in = NULL, *out = NULL; - int informat, outformat, text = 0, noout = 0; - int pubin = 0, pubout = 0; - char *infile, *outfile, *prog; -# ifndef OPENSSL_NO_ENGINE - char *engine; -# endif - char *passargin = NULL, *passargout = NULL; - char *passin = NULL, *passout = NULL; - int modulus = 0; + char *engine = NULL, *infile = NULL, *outfile = NULL, *prog; + char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = + NULL; + OPTION_CHOICE o; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; + int i, modulus = 0, pubin = 0, pubout = 0, pvk_encr = 2, ret = 1; -#ifndef OPENSSL_NO_RC4 - int pvk_encr = 2; + prog = opt_init(argc, argv, dsa_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +#ifdef OPENSSL_NO_RC4 + case OPT_PVK_STRONG: + case OPT_PVK_WEAK: + case OPT_PVK_NONE: #endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - -# ifndef OPENSSL_NO_ENGINE - engine = NULL; -# endif - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif + opthelp: + ret = 0; + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(dsa_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format + (opt_arg(), OPT_FMT_PEMDER | OPT_FMT_PVK, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format + (opt_arg(), OPT_FMT_PEMDER | OPT_FMT_PVK, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; #ifndef OPENSSL_NO_RC4 - else if (strcmp(*argv, "-pvk-strong") == 0) + case OPT_PVK_STRONG: pvk_encr = 2; - else if (strcmp(*argv, "-pvk-weak") == 0) + break; + case OPT_PVK_WEAK: pvk_encr = 1; - else if (strcmp(*argv, "-pvk-none") == 0) + break; + case OPT_PVK_NONE: pvk_encr = 0; + break; #endif - else if (strcmp(*argv, "-noout") == 0) + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-modulus") == 0) + break; + case OPT_MODULUS: modulus = 1; - else if (strcmp(*argv, "-pubin") == 0) + break; + case OPT_PUBIN: pubin = 1; - else if (strcmp(*argv, "-pubout") == 0) + break; + case OPT_PUBOUT: pubout = 1; - else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto end; break; } - argc--; - argv++; - } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, - " -passin arg input file pass phrase source\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, - " -passout arg output file pass phrase source\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, - " -des encrypt PEM output with cbc des\n"); - BIO_printf(bio_err, - " -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); -# ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, - " -idea encrypt PEM output with cbc idea\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, - " -seed encrypt PEM output with cbc seed\n"); -# endif - BIO_printf(bio_err, " -text print the key in text\n"); - BIO_printf(bio_err, " -noout don't print key out\n"); - BIO_printf(bio_err, " -modulus print the DSA public value\n"); - goto end; } - - ERR_load_crypto_strings(); + argc = opt_num_rest(); + argv = opt_rest(); # ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); - goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } - BIO_printf(bio_err, "read DSA key\n"); - { EVP_PKEY *pkey; if (pubin) - pkey = load_pubkey(bio_err, infile, informat, 1, - passin, e, "Public Key"); + pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); else - pkey = load_key(bio_err, infile, informat, 1, - passin, e, "Private Key"); + pkey = load_key(infile, informat, 1, passin, e, "Private Key"); if (pkey) { dsa = EVP_PKEY_get1_DSA(pkey); @@ -291,20 +221,9 @@ int MAIN(int argc, char **argv) goto end; } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; if (text) if (!DSA_print(out, dsa, 0)) { @@ -314,13 +233,15 @@ int MAIN(int argc, char **argv) } if (modulus) { - fprintf(stdout, "Public Key="); + BIO_printf(out, "Public Key="); BN_print(out, dsa->pub_key); - fprintf(stdout, "\n"); + BIO_printf(out, "\n"); } - if (noout) + if (noout) { + ret = 0; goto end; + } BIO_printf(bio_err, "writing DSA key\n"); if (outformat == FORMAT_ASN1) { if (pubin || pubout) @@ -353,18 +274,17 @@ int MAIN(int argc, char **argv) if (i <= 0) { BIO_printf(bio_err, "unable to write private key\n"); ERR_print_errors(bio_err); - } else - ret = 0; + goto end; + } + ret = 0; end: - BIO_free(in); BIO_free_all(out); DSA_free(dsa); if (passin) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } #else /* !OPENSSL_NO_DSA */ diff --git a/apps/dsaparam.c b/apps/dsaparam.c index f63ecb28ec..b314409762 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -1,4 +1,3 @@ -/* apps/dsaparam.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -72,24 +71,6 @@ # include # include -# undef PROG -# define PROG dsaparam_main - -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -noout - * -text - * -C - * -noout - * -genkey - * #ifdef GENCB_TEST - * -timebomb n - interrupt keygen after seconds - * #endif - */ - # ifdef GENCB_TEST static int stop_keygen_flag = 0; @@ -103,169 +84,129 @@ static void timebomb_sigalarm(int foo) static int dsa_cb(int p, int n, BN_GENCB *cb); -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, + OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_NON_FIPS_ALLOW, OPT_ENGINE, + OPT_TIMEBOMB +} OPTION_CHOICE; + +OPTIONS dsaparam_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"in", OPT_IN, '<', "Input file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"out", OPT_OUT, '>', "Output file"}, + {"text", OPT_TEXT, '-', "Print as text"}, + {"C", OPT_C, '-', "Output C code"}, + {"noout", OPT_NOOUT, '-', "No output"}, + {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, + {"rand", OPT_RAND, 's', "Files to use for random number input"}, + {"non-fips-allow", OPT_NON_FIPS_ALLOW, '-'}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, +# endif +# ifdef GENCB_TEST + {"timebomb", OPT_TIMEBOMB, 'p', "Interrupt keygen after 'pnum' seconds"}, +# endif + {NULL} +}; -int MAIN(int argc, char **argv) +int dsaparam_main(int argc, char **argv) { DSA *dsa = NULL; - int i, badops = 0, text = 0; BIO *in = NULL, *out = NULL; - int informat, outformat, noout = 0, C = 0, ret = 1; - char *infile, *outfile, *prog, *inrand = NULL; - int numbits = -1, num, genkey = 0; - int need_rand = 0; - int non_fips_allow = 0; BN_GENCB *cb = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif + int numbits = -1, num, genkey = 0, need_rand = 0, non_fips_allow = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret = + 1; + int i, text = 0; # ifdef GENCB_TEST int timebomb = 0; # endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif + char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL, *engine = + NULL; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, dsaparam_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(dsaparam_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_TIMEBOMB: # ifdef GENCB_TEST - else if (strcmp(*argv, "-timebomb") == 0) { - if (--argc < 1) - goto bad; - timebomb = atoi(*(++argv)); - } + timebomb = atoi(opt_arg()); + break; # endif - else if (strcmp(*argv, "-text") == 0) + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-C") == 0) + break; + case OPT_C: C = 1; - else if (strcmp(*argv, "-genkey") == 0) { - genkey = 1; - need_rand = 1; - } else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); + break; + case OPT_GENKEY: + genkey = need_rand = 1; + break; + case OPT_RAND: + inrand = opt_arg(); need_rand = 1; - } else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-non-fips-allow") == 0) + break; + case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; - else if (sscanf(*argv, "%d", &num) == 1) { - /* generate a key */ - numbits = num; - need_rand = 1; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] [bits] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, " -text print as text\n"); - BIO_printf(bio_err, " -C Output C code\n"); - BIO_printf(bio_err, " -noout no output\n"); - BIO_printf(bio_err, " -genkey generate a DSA key\n"); - BIO_printf(bio_err, - " -rand files to use for random number input\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -# endif -# ifdef GENCB_TEST - BIO_printf(bio_err, - " -timebomb n interrupt keygen after seconds\n"); -# endif - BIO_printf(bio_err, - " number number of bits to use for generating private key\n"); - goto end; + if (argc == 1) { + if (!opt_int(argv[0], &num)) + goto end; + /* generate a key */ + numbits = num; + need_rand = 1; } - ERR_load_crypto_strings(); - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif if (need_rand) { - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); @@ -319,12 +260,8 @@ int MAIN(int argc, char **argv) } } else if (informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); - else if (informat == FORMAT_PEM) + else dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, "bad input format specified\n"); - goto end; - } if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); @@ -337,7 +274,7 @@ int MAIN(int argc, char **argv) if (C) { unsigned char *data; - int l, len, bits_p; + int len, bits_p; len = BN_num_bytes(dsa->p); bits_p = BN_num_bits(dsa->p); @@ -346,57 +283,33 @@ int MAIN(int argc, char **argv) perror("OPENSSL_malloc"); goto end; } - l = BN_bn2bin(dsa->p, data); - printf("static unsigned char dsa%d_p[]={", bits_p); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t};\n"); - - l = BN_bn2bin(dsa->q, data); - printf("static unsigned char dsa%d_q[]={", bits_p); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t};\n"); - - l = BN_bn2bin(dsa->g, data); - printf("static unsigned char dsa%d_g[]={", bits_p); - for (i = 0; i < l; i++) { - if ((i % 12) == 0) - printf("\n\t"); - printf("0x%02X,", data[i]); - } - printf("\n\t};\n\n"); - printf("DSA *get_dsa%d()\n\t{\n", bits_p); - printf("\tDSA *dsa;\n\n"); - printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n"); - printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n", + BIO_printf(bio_out, "DSA *get_dsa%d()\n{\n", bits_p); + print_bignum_var(bio_out, dsa->p, "dsap", len, data); + print_bignum_var(bio_out, dsa->q, "dsaq", len, data); + print_bignum_var(bio_out, dsa->g, "dsag", len, data); + BIO_printf(bio_out, " DSA *dsa = DSA_new();\n" + "\n"); + BIO_printf(bio_out, " if (dsa == NULL)\n" + " return NULL;\n"); + BIO_printf(bio_out, " dsa->p = BN_bin2bn(dsap_%d, sizeof (dsap_%d), NULL);\n", bits_p, bits_p); - printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n", + BIO_printf(bio_out, " dsa->q = BN_bin2bn(dsaq_%d, sizeof (dsaq_%d), NULL);\n", bits_p, bits_p); - printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n", + BIO_printf(bio_out, " dsa->g = BN_bin2bn(dsag_%d, sizeof (dsag_%d), NULL);\n", bits_p, bits_p); - printf - ("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n"); - printf("\t\t{ DSA_free(dsa); return(NULL); }\n"); - printf("\treturn(dsa);\n\t}\n"); + BIO_printf(bio_out, " if (!dsa->p || !dsa->q || !dsa->g) {\n" + " DSA_free(dsa);\n" + " return NULL;\n" + " }\n" + " return(dsa);\n}\n"); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DSAparams_bio(out, dsa); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_DSAparams(out, dsa); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write DSA parameters\n"); ERR_print_errors(bio_err); @@ -418,18 +331,13 @@ int MAIN(int argc, char **argv) } if (outformat == FORMAT_ASN1) i = i2d_DSAPrivateKey_bio(out, dsakey); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - DSA_free(dsakey); - goto end; - } DSA_free(dsakey); } if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); ret = 0; end: if (cb != NULL) @@ -437,8 +345,7 @@ int MAIN(int argc, char **argv) BIO_free(in); BIO_free_all(out); DSA_free(dsa); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static int dsa_cb(int p, int n, BN_GENCB *cb) diff --git a/apps/ec.c b/apps/ec.c index aca28540dd..d6bce6d28a 100644 --- a/apps/ec.c +++ b/apps/ec.c @@ -1,4 +1,3 @@ -/* apps/ec.c */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -67,198 +66,146 @@ # include # include -# undef PROG -# define PROG ec_main +static OPT_PAIR conv_forms[] = { + {"compressed", POINT_CONVERSION_COMPRESSED}, + {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, + {"hybrid", POINT_CONVERSION_HYBRID}, + {NULL} +}; -/*- - * -inform arg - input format - default PEM (one of DER, NET or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -des - encrypt output if PEM format with DES in cbc mode - * -text - print a text version - * -param_out - print the elliptic curve parameters - * -conv_form arg - specifies the point encoding form - * -param_enc arg - specifies the parameter encoding - */ +static OPT_PAIR param_enc[] = { + {"named_curve", OPENSSL_EC_NAMED_CURVE}, + {"explicit", 0}, + {NULL} +}; + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, + OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT, + OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS ec_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {"noout", OPT_NOOUT, '-', "Don't print key out"}, + {"text", OPT_TEXT, '-', "Print the key"}, + {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"}, + {"pubin", OPT_PUBIN, '-'}, + {"pubout", OPT_PUBOUT, '-'}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int ec_main(int argc, char **argv) { - int ret = 1; + BIO *in = NULL, *out = NULL; EC_KEY *eckey = NULL; const EC_GROUP *group; - int i, badops = 0; const EVP_CIPHER *enc = NULL; - BIO *in = NULL, *out = NULL; - int informat, outformat, text = 0, noout = 0; - int pubin = 0, pubout = 0, param_out = 0; - char *infile, *outfile, *prog, *engine; - char *passargin = NULL, *passargout = NULL; - char *passin = NULL, *passout = NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; - int new_form = 0; - int asn1_flag = OPENSSL_EC_NAMED_CURVE; - int new_asn1_flag = 0; - - apps_startup(); + char *infile = NULL, *outfile = NULL, *prog, *engine = NULL; + char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = + NULL; + OPTION_CHOICE o; + int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; + int pubin = 0, pubout = 0, param_out = 0, i, ret = 1; - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - engine = NULL; - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } else if (strcmp(*argv, "-noout") == 0) + prog = opt_init(argc, argv, ec_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(ec_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-conv_form") == 0) { - if (--argc < 1) - goto bad; - ++argv; - new_form = 1; - if (strcmp(*argv, "compressed") == 0) - form = POINT_CONVERSION_COMPRESSED; - else if (strcmp(*argv, "uncompressed") == 0) - form = POINT_CONVERSION_UNCOMPRESSED; - else if (strcmp(*argv, "hybrid") == 0) - form = POINT_CONVERSION_HYBRID; - else - goto bad; - } else if (strcmp(*argv, "-param_enc") == 0) { - if (--argc < 1) - goto bad; - ++argv; - new_asn1_flag = 1; - if (strcmp(*argv, "named_curve") == 0) - asn1_flag = OPENSSL_EC_NAMED_CURVE; - else if (strcmp(*argv, "explicit") == 0) - asn1_flag = 0; - else - goto bad; - } else if (strcmp(*argv, "-param_out") == 0) + break; + case OPT_PARAM_OUT: param_out = 1; - else if (strcmp(*argv, "-pubin") == 0) + break; + case OPT_PUBIN: pubin = 1; - else if (strcmp(*argv, "-pubout") == 0) + break; + case OPT_PUBOUT: pubout = 1; - else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto opthelp; + case OPT_CONV_FORM: + if (!opt_pair(opt_arg(), conv_forms, &i)) + goto opthelp; + new_form = 1; + form = i; + break; + case OPT_PARAM_ENC: + if (!opt_pair(opt_arg(), param_enc, &i)) + goto opthelp; + new_asn1_flag = 1; + asn1_flag = i; break; } - argc--; - argv++; } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - " - "DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - " - "DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -passin arg input file pass " - "phrase source\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, " -passout arg output file pass " - "phrase source\n"); - BIO_printf(bio_err, " -engine e use engine e, " - "possibly a hardware device.\n"); - BIO_printf(bio_err, " -des encrypt PEM output, " - "instead of 'des' every other \n" - " cipher " - "supported by OpenSSL can be used\n"); - BIO_printf(bio_err, " -text print the key\n"); - BIO_printf(bio_err, " -noout don't print key out\n"); - BIO_printf(bio_err, " -param_out print the elliptic " - "curve parameters\n"); - BIO_printf(bio_err, " -conv_form arg specifies the " - "point conversion form \n"); - BIO_printf(bio_err, " possible values:" - " compressed\n"); - BIO_printf(bio_err, " " - " uncompressed (default)\n"); - BIO_printf(bio_err, " " " hybrid\n"); - BIO_printf(bio_err, " -param_enc arg specifies the way" - " the ec parameters are encoded\n"); - BIO_printf(bio_err, " in the asn1 der " "encoding\n"); - BIO_printf(bio_err, " possible values:" - " named_curve (default)\n"); - BIO_printf(bio_err, " " - "explicit\n"); - goto end; - } - - ERR_load_crypto_strings(); + argc = opt_num_rest(); + argv = opt_rest(); # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, RB(informat)); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } BIO_printf(bio_err, "read EC key\n"); if (informat == FORMAT_ASN1) { @@ -266,14 +213,11 @@ int MAIN(int argc, char **argv) eckey = d2i_EC_PUBKEY_bio(in, NULL); else eckey = d2i_ECPrivateKey_bio(in, NULL); - } else if (informat == FORMAT_PEM) { + } else { if (pubin) eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); else eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin); - } else { - BIO_printf(bio_err, "bad input format specified for key\n"); - goto end; } if (eckey == NULL) { BIO_printf(bio_err, "unable to load Key\n"); @@ -281,20 +225,9 @@ int MAIN(int argc, char **argv) goto end; } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, WB(outformat)); + if (out == NULL) + goto end; group = EC_KEY_get0_group(eckey); @@ -324,7 +257,7 @@ int MAIN(int argc, char **argv) i = i2d_EC_PUBKEY_bio(out, eckey); else i = i2d_ECPrivateKey_bio(out, eckey); - } else if (outformat == FORMAT_PEM) { + } else { if (param_out) i = PEM_write_bio_ECPKParameters(out, group); else if (pubin || pubout) @@ -332,9 +265,6 @@ int MAIN(int argc, char **argv) else i = PEM_write_bio_ECPrivateKey(out, eckey, enc, NULL, 0, NULL, passout); - } else { - BIO_printf(bio_err, "bad output format specified for " "outfile\n"); - goto end; } if (!i) { @@ -350,8 +280,7 @@ int MAIN(int argc, char **argv) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } #else /* !OPENSSL_NO_EC */ diff --git a/apps/ecparam.c b/apps/ecparam.c index c6a175146c..167ef39f6d 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -1,4 +1,3 @@ -/* apps/ecparam.c */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -84,235 +83,152 @@ # include # include -# undef PROG -# define PROG ecparam_main - -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -noout - do not print the ec parameter - * -text - print the ec parameters in text form - * -check - validate the ec parameters - * -C - print a 'C' function creating the parameters - * -name arg - use the ec parameters with 'short name' name - * -list_curves - prints a list of all currently available curve 'short names' - * -conv_form arg - specifies the point conversion form - * - possible values: compressed - * uncompressed (default) - * hybrid - * -param_enc arg - specifies the way the ec parameters are encoded - * in the asn1 der encoding - * possible values: named_curve (default) - * explicit - * -no_seed - if 'explicit' parameters are chosen do not use the seed - * -genkey - generate ec key - * -rand file - files to use for random number input - * -engine e - use engine e, possibly a hardware device - */ - -static int ecparam_print_var(BIO *, BIGNUM *, const char *, int, - unsigned char *); - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, + OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME, + OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE +} OPTION_CHOICE; + +OPTIONS ecparam_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, + {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"text", OPT_TEXT, '-', "Print the ec parameters in text form"}, + {"C", OPT_C, '-', "Print a 'C' function creating the parameters"}, + {"check", OPT_CHECK, '-', "Validate the ec parameters"}, + {"list_curves", OPT_LIST_CURVES, '-', + "Prints a list of all curve 'short names'"}, + {"no_seed", OPT_NO_SEED, '-', + "If 'explicit' parameters are chosen do not use the seed"}, + {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, + {"name", OPT_NAME, 's', + "Use the ec parameters with specified 'short name'"}, + {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, + {"param_enc", OPT_PARAM_ENC, 's', + "Specifies the way the ec parameters are encoded"}, + {"genkey", OPT_GENKEY, '-', "Generate ec key"}, + {"rand", OPT_RAND, 's', "Files to use for random number input"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {NULL} +}; + +OPT_PAIR forms[] = { + {"compressed", POINT_CONVERSION_COMPRESSED}, + {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, + {"hybrid", POINT_CONVERSION_HYBRID}, + {NULL} +}; + +OPT_PAIR encodings[] = { + {"named_curve", OPENSSL_EC_NAMED_CURVE}, + {"explicit", 0}, + {NULL} +}; + +int ecparam_main(int argc, char **argv) { + BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; + BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL; + BIO *in = NULL, *out = NULL; EC_GROUP *group = NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; - int new_form = 0; - int asn1_flag = OPENSSL_EC_NAMED_CURVE; - int new_asn1_flag = 0; char *curve_name = NULL, *inrand = NULL; - int list_curves = 0, no_seed = 0, check = 0, - badops = 0, text = 0, i, need_rand = 0, genkey = 0; - char *infile = NULL, *outfile = NULL, *prog; - BIO *in = NULL, *out = NULL; - int informat, outformat, noout = 0, C = 0, ret = 1; - char *engine = NULL; - - BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, - *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; + char *engine = NULL, *infile = NULL, *outfile = NULL, *prog; unsigned char *buffer = NULL; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-text") == 0) + OPTION_CHOICE o; + int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret = + 1; + int list_curves = 0, no_seed = 0, check = 0, new_form = 0; + int text = 0, i, need_rand = 0, genkey = 0; + + prog = opt_init(argc, argv, ecparam_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(ecparam_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-C") == 0) + break; + case OPT_C: C = 1; - else if (strcmp(*argv, "-check") == 0) + break; + case OPT_CHECK: check = 1; - else if (strcmp(*argv, "-name") == 0) { - if (--argc < 1) - goto bad; - curve_name = *(++argv); - } else if (strcmp(*argv, "-list_curves") == 0) + break; + case OPT_LIST_CURVES: list_curves = 1; - else if (strcmp(*argv, "-conv_form") == 0) { - if (--argc < 1) - goto bad; - ++argv; - new_form = 1; - if (strcmp(*argv, "compressed") == 0) - form = POINT_CONVERSION_COMPRESSED; - else if (strcmp(*argv, "uncompressed") == 0) - form = POINT_CONVERSION_UNCOMPRESSED; - else if (strcmp(*argv, "hybrid") == 0) - form = POINT_CONVERSION_HYBRID; - else - goto bad; - } else if (strcmp(*argv, "-param_enc") == 0) { - if (--argc < 1) - goto bad; - ++argv; - new_asn1_flag = 1; - if (strcmp(*argv, "named_curve") == 0) - asn1_flag = OPENSSL_EC_NAMED_CURVE; - else if (strcmp(*argv, "explicit") == 0) - asn1_flag = 0; - else - goto bad; - } else if (strcmp(*argv, "-no_seed") == 0) + break; + case OPT_NO_SEED: no_seed = 1; - else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-genkey") == 0) { - genkey = 1; - need_rand = 1; - } else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); + break; + case OPT_NAME: + curve_name = opt_arg(); + break; + case OPT_CONV_FORM: + if (!opt_pair(opt_arg(), forms, &new_form)) + goto opthelp; + form = new_form; + new_form = 1; + break; + case OPT_PARAM_ENC: + if (!opt_pair(opt_arg(), encodings, &asn1_flag)) + goto opthelp; + new_asn1_flag = 1; + break; + case OPT_GENKEY: + genkey = need_rand = 1; + break; + case OPT_RAND: + inrand = opt_arg(); need_rand = 1; - } else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_ENGINE: + engine = opt_arg(); break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - " - "default PEM (DER or PEM)\n"); - BIO_printf(bio_err, " -outform arg output format - " - "default PEM\n"); - BIO_printf(bio_err, " -in arg input file - " - "default stdin\n"); - BIO_printf(bio_err, " -out arg output file - " - "default stdout\n"); - BIO_printf(bio_err, " -noout do not print the " - "ec parameter\n"); - BIO_printf(bio_err, " -text print the ec " - "parameters in text form\n"); - BIO_printf(bio_err, " -check validate the ec " - "parameters\n"); - BIO_printf(bio_err, " -C print a 'C' " - "function creating the parameters\n"); - BIO_printf(bio_err, " -name arg use the " - "ec parameters with 'short name' name\n"); - BIO_printf(bio_err, " -list_curves prints a list of " - "all currently available curve 'short names'\n"); - BIO_printf(bio_err, " -conv_form arg specifies the " - "point conversion form \n"); - BIO_printf(bio_err, " possible values:" - " compressed\n"); - BIO_printf(bio_err, " " - " uncompressed (default)\n"); - BIO_printf(bio_err, " " - " hybrid\n"); - BIO_printf(bio_err, " -param_enc arg specifies the way" - " the ec parameters are encoded\n"); - BIO_printf(bio_err, " in the asn1 der " - "encoding\n"); - BIO_printf(bio_err, " possible values:" - " named_curve (default)\n"); - BIO_printf(bio_err, " " - " explicit\n"); - BIO_printf(bio_err, " -no_seed if 'explicit'" - " parameters are chosen do not" " use the seed\n"); - BIO_printf(bio_err, " -genkey generate ec" " key\n"); - BIO_printf(bio_err, " -rand file files to use for" - " random number input\n"); - BIO_printf(bio_err, " -engine e use engine e, " - "possibly a hardware device\n"); + in = bio_open_default(infile, RB(informat)); + if (in == NULL) goto end; - } - - ERR_load_crypto_strings(); - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); + out = bio_open_default(outfile, WB(outformat)); + if (out == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif if (list_curves) { @@ -385,15 +301,10 @@ int MAIN(int argc, char **argv) } EC_GROUP_set_asn1_flag(group, asn1_flag); EC_GROUP_set_point_conversion_form(group, form); - } else if (informat == FORMAT_ASN1) { + } else if (informat == FORMAT_ASN1) group = d2i_ECPKParameters_bio(in, NULL); - } else if (informat == FORMAT_PEM) { + else group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); - } else { - BIO_printf(bio_err, "bad input format specified\n"); - goto end; - } - if (group == NULL) { BIO_printf(bio_err, "unable to load elliptic curve parameters\n"); ERR_print_errors(bio_err); @@ -433,24 +344,25 @@ int MAIN(int argc, char **argv) int is_prime, len = 0; const EC_METHOD *meth = EC_GROUP_method_of(group); - if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL || - (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL || - (ec_order = BN_new()) == NULL || - (ec_cofactor = BN_new()) == NULL) { + if ((ec_p = BN_new()) == NULL + || (ec_a = BN_new()) == NULL + || (ec_b = BN_new()) == NULL + || (ec_gen = BN_new()) == NULL + || (ec_order = BN_new()) == NULL + || (ec_cofactor = BN_new()) == NULL) { perror("OPENSSL_malloc"); goto end; } is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); - - if (is_prime) { - if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL)) - goto end; - } else { - /* TODO */ + if (!is_prime) { + BIO_printf(bio_err, "Can only handle X9.62 prime fields\n"); goto end; } + if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL)) + goto end; + if ((point = EC_GROUP_get0_generator(group)) == NULL) goto end; if (!EC_POINT_point2bn(group, point, @@ -487,77 +399,62 @@ int MAIN(int argc, char **argv) goto end; } - ecparam_print_var(out, ec_p, "ec_p", len, buffer); - ecparam_print_var(out, ec_a, "ec_a", len, buffer); - ecparam_print_var(out, ec_b, "ec_b", len, buffer); - ecparam_print_var(out, ec_gen, "ec_gen", len, buffer); - ecparam_print_var(out, ec_order, "ec_order", len, buffer); - ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, buffer); - - BIO_printf(out, "\n\n"); - - BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len); - BIO_printf(out, "\tint ok=0;\n"); - BIO_printf(out, "\tEC_GROUP *group = NULL;\n"); - BIO_printf(out, "\tEC_POINT *point = NULL;\n"); - BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, " - "*tmp_3 = NULL;\n\n"); - BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, " - "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t" - "goto err;\n", len, len); - BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, " - "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t" - "goto err;\n", len, len); - BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, " - "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t" - "goto err;\n", len, len); - if (is_prime) { - BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_" - "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)" - "\n\t\tgoto err;\n\n"); - } else { - /* TODO */ - goto end; - } - BIO_printf(out, "\t/* build generator */\n"); - BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, " - "sizeof(ec_gen_%d), tmp_1)) == NULL)" - "\n\t\tgoto err;\n", len, len); - BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, " - "NULL, NULL);\n"); - BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n"); - BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, " - "sizeof(ec_order_%d), tmp_2)) == NULL)" - "\n\t\tgoto err;\n", len, len); - BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, " - "sizeof(ec_cofactor_%d), tmp_3)) == NULL)" - "\n\t\tgoto err;\n", len, len); - BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point," - " tmp_2, tmp_3))\n\t\tgoto err;\n"); - BIO_printf(out, "\n\tok=1;\n"); - BIO_printf(out, "err:\n"); - BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n"); - BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n"); - BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n"); - BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n"); - BIO_printf(out, "\tif (!ok)\n"); - BIO_printf(out, "\t\t{\n"); - BIO_printf(out, "\t\tEC_GROUP_free(group);\n"); - BIO_printf(out, "\t\tgroup = NULL;\n"); - BIO_printf(out, "\t\t}\n"); - BIO_printf(out, "\treturn(group);\n\t}\n"); + BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len); + print_bignum_var(out, ec_p, "ec_p", len, buffer); + print_bignum_var(out, ec_a, "ec_a", len, buffer); + print_bignum_var(out, ec_b, "ec_b", len, buffer); + print_bignum_var(out, ec_gen, "ec_gen", len, buffer); + print_bignum_var(out, ec_order, "ec_order", len, buffer); + print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer); + BIO_printf(out, " int ok = 0;\n" + " EC_GROUP *group = NULL;\n" + " EC_POINT *point = NULL;\n" + " BIGNUM *tmp_1 = NULL;\n" + " BIGNUM *tmp_2 = NULL;\n" + " BIGNUM *tmp_3 = NULL;\n" + "\n"); + + BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n" + " goto err;\n" + "\n"); + BIO_printf(out, " /* build generator */\n"); + BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n"); + BIO_printf(out, " if (point == NULL)\n" + " goto err;\n"); + BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n" + " goto err;\n", len, len); + BIO_printf(out, " if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n" + " goto err;\n" + "ok = 1;" + "\n"); + BIO_printf(out, "err:\n" + " BN_free(tmp_1);\n" + " BN_free(tmp_2);\n" + " BN_free(tmp_3);\n" + " EC_POINT_free(point);\n" + " if (!ok) {\n" + " EC_GROUP_free(group);\n" + " return NULL;\n" + " }\n" + " return (group);\n" + "}\n"); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_ECPKParameters_bio(out, group); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_ECPKParameters(out, group); - else { - BIO_printf(bio_err, "bad output format specified for" - " outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write elliptic " "curve parameters\n"); @@ -567,7 +464,7 @@ int MAIN(int argc, char **argv) } if (need_rand) { - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); @@ -590,20 +487,14 @@ int MAIN(int argc, char **argv) } if (outformat == FORMAT_ASN1) i = i2d_ECPrivateKey_bio(out, eckey); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL); - else { - BIO_printf(bio_err, "bad output format specified " - "for outfile\n"); - EC_KEY_free(eckey); - goto end; - } EC_KEY_free(eckey); } if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); ret = 0; end: @@ -624,32 +515,9 @@ int MAIN(int argc, char **argv) BIO_free(in); BIO_free_all(out); EC_GROUP_free(group); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } -static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var, - int len, unsigned char *buffer) -{ - BIO_printf(out, "static unsigned char %s_%d[] = {", var, len); - if (BN_is_zero(in)) - BIO_printf(out, "\n\t0x00"); - else { - int i, l; - - l = BN_bn2bin(in, buffer); - for (i = 0; i < l - 1; i++) { - if ((i % 12) == 0) - BIO_printf(out, "\n\t"); - BIO_printf(out, "0x%02X,", buffer[i]); - } - if ((i % 12) == 0) - BIO_printf(out, "\n\t"); - BIO_printf(out, "0x%02X", buffer[i]); - } - BIO_printf(out, "\n\t};\n\n"); - return 1; -} #else /* !OPENSSL_NO_EC */ # if PEDANTIC diff --git a/apps/enc.c b/apps/enc.c index b95a6a2031..06b056b45d 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -1,4 +1,3 @@ -/* apps/enc.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -72,307 +71,251 @@ #endif #include -int set_hex(char *in, unsigned char *out, int size); #undef SIZE #undef BSIZE -#undef PROG - #define SIZE (512) #define BSIZE (8*1024) -#define PROG enc_main - -static void show_ciphers(const OBJ_NAME *name, void *bio_) -{ - BIO *bio = bio_; - static int n; - - if (!islower((unsigned char)*name->name)) - return; - - BIO_printf(bio, "-%-25s", name->name); - if (++n == 3) { - BIO_printf(bio, "\n"); - n = 0; - } else - BIO_printf(bio, " "); -} -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +static int set_hex(char *in, unsigned char *out, int size); +static void show_ciphers(const OBJ_NAME *name, void *bio_); + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V, + OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A, + OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE, + OPT_UPPER_S, OPT_IV, OPT_MD, OPT_NON_FIPS_ALLOW, OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS enc_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pass", OPT_PASS, 's', "Passphrase source"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"e", OPT_E, '-', "Encrypt"}, + {"d", OPT_D, '-', "Decrypt"}, + {"p", OPT_P, '-', "Print the iv/key"}, + {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"}, + {"v", OPT_V, '-'}, + {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, + {"salt", OPT_SALT, '-'}, + {"nosalt", OPT_NOSALT, '-'}, + {"debug", OPT_DEBUG, '-'}, + {"A", OPT_UPPER_A, '-'}, + {"a", OPT_A, '-', "base64 encode/decode, depending on encryption flag"}, + {"base64", OPT_A, '-', "Base64 output as a single line"}, +#ifdef ZLIB + {"z", OPT_Z, '-', "Use zlib as the 'encryption'"}, +#endif + {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, + {"k", OPT_K, 's', "Passphrase"}, + {"kfile", OPT_KFILE, '<', "Fead passphrase from file"}, + {"K", OPT_UPPER_K, '-', "Same as -iv"}, + {"S", OPT_UPPER_S, 's', "Salt, in hex"}, + {"iv", OPT_IV, 's', "IV in hex"}, + {"md", OPT_MD, 's', "Use specified digest to create key from passphrase"}, + {"non-fips-allow", OPT_NON_FIPS_ALLOW, '-'}, + {"none", OPT_NONE, '-', "Don't encrypt"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {NULL} +}; + +int enc_main(int argc, char **argv) { + static char buf[128]; static const char magic[] = "Salted__"; + BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = + NULL, *wbio = NULL; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher = NULL, *c; + const EVP_MD *dgst = NULL; + char *engine = NULL, *hkey = NULL, *hiv = NULL, *hsalt = NULL, *p; + char *infile = NULL, *outfile = NULL, *prog; + char *str = NULL, *passarg = NULL, *pass = NULL, *strbuf = NULL; char mbuf[sizeof magic - 1]; - char *strbuf = NULL; - unsigned char *buff = NULL, *bufsize = NULL; - int bsize = BSIZE, verbose = 0; - int ret = 1, inl; - int nopad = 0; + OPTION_CHOICE o; + int bsize = BSIZE, verbose = 0, debug = 0, olb64 = 0, nosalt = 0; + int enc = 1, printkey = 0, i, k, base64 = 0; + int ret = 1, inl, nopad = 0, non_fips_allow = 0; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - unsigned char salt[PKCS5_SALT_LEN]; - char *str = NULL, *passarg = NULL, *pass = NULL; - char *hkey = NULL, *hiv = NULL, *hsalt = NULL; - char *md = NULL; - int enc = 1, printkey = 0, i, base64 = 0; + unsigned char *buff = NULL, salt[PKCS5_SALT_LEN]; + unsigned long n; #ifdef ZLIB int do_zlib = 0; BIO *bzl = NULL; #endif - int debug = 0, olb64 = 0, nosalt = 0; - const EVP_CIPHER *cipher = NULL, *c; - EVP_CIPHER_CTX *ctx = NULL; - char *inf = NULL, *outf = NULL; - BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = - NULL, *wbio = NULL; -#define PROG_NAME_SIZE 39 - char pname[PROG_NAME_SIZE + 1]; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - const EVP_MD *dgst = NULL; - int non_fips_allow = 0; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; /* first check the program name */ - program_name(argv[0], pname, sizeof pname); - if (strcmp(pname, "base64") == 0) + prog = opt_progname(argv[0]); + if (strcmp(prog, "base64") == 0) base64 = 1; #ifdef ZLIB - if (strcmp(pname, "zlib") == 0) + else if (strcmp(prog, "zlib") == 0) do_zlib = 1; #endif - - cipher = EVP_get_cipherbyname(pname); -#ifdef ZLIB - if (!do_zlib && !base64 && (cipher == NULL) - && (strcmp(pname, "enc") != 0)) -#else - if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0)) -#endif - { - BIO_printf(bio_err, "%s is an unknown cipher\n", pname); - goto bad; + else { + cipher = EVP_get_cipherbyname(prog); + if (cipher == NULL && strcmp(prog, "enc") != 0) { + BIO_printf(bio_err, "%s is not a known cipher\n", prog); + goto end; + } } - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-e") == 0) + prog = opt_init(argc, argv, enc_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(enc_options); + ret = 0; + BIO_printf(bio_err, "Cipher Types\n"); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, + show_ciphers, bio_err); + BIO_printf(bio_err, "\n"); + goto end; + case OPT_E: enc = 1; - else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - inf = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outf = *(++argv); - } else if (strcmp(*argv, "-pass") == 0) { - if (--argc < 1) - goto bad; - passarg = *(++argv); - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else if (strcmp(*argv, "-d") == 0) + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PASS: + passarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_D: enc = 0; - else if (strcmp(*argv, "-p") == 0) + break; + case OPT_P: printkey = 1; - else if (strcmp(*argv, "-v") == 0) + break; + case OPT_V: verbose = 1; - else if (strcmp(*argv, "-nopad") == 0) + break; + case OPT_NOPAD: nopad = 1; - else if (strcmp(*argv, "-salt") == 0) + break; + case OPT_SALT: nosalt = 0; - else if (strcmp(*argv, "-nosalt") == 0) + break; + case OPT_NOSALT: nosalt = 1; - else if (strcmp(*argv, "-debug") == 0) + break; + case OPT_DEBUG: debug = 1; - else if (strcmp(*argv, "-P") == 0) + break; + case OPT_UPPER_P: printkey = 2; - else if (strcmp(*argv, "-A") == 0) + break; + case OPT_UPPER_A: olb64 = 1; - else if (strcmp(*argv, "-a") == 0) - base64 = 1; - else if (strcmp(*argv, "-base64") == 0) + break; + case OPT_A: base64 = 1; + break; + case OPT_Z: #ifdef ZLIB - else if (strcmp(*argv, "-z") == 0) do_zlib = 1; #endif - else if (strcmp(*argv, "-bufsize") == 0) { - if (--argc < 1) - goto bad; - bufsize = (unsigned char *)*(++argv); - } else if (strcmp(*argv, "-k") == 0) { - if (--argc < 1) - goto bad; - str = *(++argv); - } else if (strcmp(*argv, "-kfile") == 0) { - static char buf[128]; - FILE *infile; - char *file; - - if (--argc < 1) - goto bad; - file = *(++argv); - infile = fopen(file, "r"); - if (infile == NULL) { - BIO_printf(bio_err, "unable to read key from '%s'\n", file); - goto bad; - } - buf[0] = '\0'; - if (!fgets(buf, sizeof buf, infile)) { - BIO_printf(bio_err, "unable to read key from '%s'\n", file); - goto bad; + break; + case OPT_BUFSIZE: + p = opt_arg(); + i = (int)strlen(p) - 1; + k = i >= 1 && p[i] == 'k'; + if (k) + p[i] = '\0'; + if (!opt_ulong(opt_arg(), &n)) + goto opthelp; + if (k) + n *= 1024; + bsize = (int)n; + break; + case OPT_K: + str = opt_arg(); + break; + case OPT_KFILE: + in = bio_open_default(opt_arg(), "r"); + if (in == NULL) + goto opthelp; + i = BIO_gets(in, buf, sizeof buf); + BIO_free(in); + in = NULL; + if (i <= 0) { + BIO_printf(bio_err, + "%s Can't read key from %s\n", prog, opt_arg()); + goto opthelp; } - fclose(infile); - i = strlen(buf); - if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) - buf[--i] = '\0'; - if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r'))) - buf[--i] = '\0'; - if (i < 1) { - BIO_printf(bio_err, "zero length password\n"); - goto bad; + while (--i > 0 && (buf[i] == '\r' || buf[i] == '\n')) + buf[i] = '\0'; + if (i <= 0) { + BIO_printf(bio_err, "%s: zero length password\n", prog); + goto opthelp; } str = buf; - } else if (strcmp(*argv, "-K") == 0) { - if (--argc < 1) - goto bad; - hkey = *(++argv); - } else if (strcmp(*argv, "-S") == 0) { - if (--argc < 1) - goto bad; - hsalt = *(++argv); - } else if (strcmp(*argv, "-iv") == 0) { - if (--argc < 1) - goto bad; - hiv = *(++argv); - } else if (strcmp(*argv, "-md") == 0) { - if (--argc < 1) - goto bad; - md = *(++argv); - } else if (strcmp(*argv, "-non-fips-allow") == 0) + break; + case OPT_UPPER_K: + hkey = opt_arg(); + break; + case OPT_UPPER_S: + hsalt = opt_arg(); + break; + case OPT_IV: + hiv = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_arg(), &dgst)) + goto opthelp; + break; + case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; - else if ((argv[0][0] == '-') && - ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &c)) + goto opthelp; cipher = c; - } else if (strcmp(*argv, "-none") == 0) + break; + case OPT_NONE: cipher = NULL; - else { - BIO_printf(bio_err, "unknown option '%s'\n", *argv); - bad: - BIO_printf(bio_err, "options are\n"); - BIO_printf(bio_err, "%-14s input file\n", "-in "); - BIO_printf(bio_err, "%-14s output file\n", "-out "); - BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass "); - BIO_printf(bio_err, "%-14s encrypt\n", "-e"); - BIO_printf(bio_err, "%-14s decrypt\n", "-d"); - BIO_printf(bio_err, - "%-14s base64 encode/decode, depending on encryption flag\n", - "-a/-base64"); - BIO_printf(bio_err, "%-14s passphrase is the next argument\n", - "-k"); - BIO_printf(bio_err, - "%-14s passphrase is the first line of the file argument\n", - "-kfile"); - BIO_printf(bio_err, - "%-14s the next argument is the md to use to create a key\n", - "-md"); - BIO_printf(bio_err, - "%-14s from a passphrase. One of md2, md5, sha or sha1\n", - ""); - BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", - "-S"); - BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n", - "-K/-iv"); - BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n", - "-[pP]"); - BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize "); - BIO_printf(bio_err, "%-14s disable standard block padding\n", - "-nopad"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "%-14s use engine e, possibly a hardware device.\n", - "-engine e"); -#endif - - BIO_printf(bio_err, "Cipher Types\n"); - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - show_ciphers, bio_err); - BIO_printf(bio_err, "\n"); - - goto end; + break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); #ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); #endif if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - BIO_printf(bio_err, - "AEAD ciphers not supported by the enc utility\n"); + BIO_printf(bio_err, "%s: AEAD ciphers not supported\n", prog); goto end; } if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { - BIO_printf(bio_err, - "Ciphers in XTS mode are not supported by the enc utility\n"); + BIO_printf(bio_err, "%s XTS ciphers not supported\n", prog); goto end; } - if (md && (dgst = EVP_get_digestbyname(md)) == NULL) { - BIO_printf(bio_err, "%s is an unsupported message digest type\n", md); - goto end; - } - - if (dgst == NULL) { + if (dgst == NULL) dgst = EVP_md5(); - } - - if (bufsize != NULL) { - unsigned long n; - - for (n = 0; *bufsize; bufsize++) { - i = *bufsize; - if ((i <= '9') && (i >= '0')) - n = n * 10 + i - '0'; - else if (i == 'k') { - n *= 1024; - bufsize++; - break; - } - } - if (*bufsize != '\0') { - BIO_printf(bio_err, "invalid 'bufsize' specified.\n"); - goto end; - } - /* It must be large enough for a base64 encoded line */ - if (base64 && n < 80) - n = 80; - - bsize = (int)n; - if (verbose) - BIO_printf(bio_err, "bufsize=%d\n", bsize); - } + /* It must be large enough for a base64 encoded line */ + if (base64 && bsize < 80) + bsize = 80; + if (verbose) + BIO_printf(bio_err, "bufsize=%d\n", bsize); strbuf = OPENSSL_malloc(SIZE); buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); @@ -382,12 +325,6 @@ int MAIN(int argc, char **argv) goto end; } - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); - goto end; - } if (debug) { BIO_set_callback(in, BIO_debug_callback); BIO_set_callback(out, BIO_debug_callback); @@ -395,19 +332,16 @@ int MAIN(int argc, char **argv) BIO_set_callback_arg(out, (char *)bio_err); } - if (inf == NULL) { - if (bufsize != NULL) - setbuf(stdin, NULL); - BIO_set_fp(in, stdin, BIO_NOCLOSE); - } else { - if (BIO_read_filename(in, inf) <= 0) { - perror(inf); - goto end; - } - } + if (infile == NULL) { + unbuffer(stdin); + in = dup_bio_in(); + } else + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; if (!str && passarg) { - if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -416,13 +350,13 @@ int MAIN(int argc, char **argv) if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { for (;;) { - char buf[200]; + char prompt[200]; - BIO_snprintf(buf, sizeof buf, "enter %s %s password:", + BIO_snprintf(prompt, sizeof prompt, "enter %s %s password:", OBJ_nid2ln(EVP_CIPHER_nid(cipher)), (enc) ? "encryption" : "decryption"); strbuf[0] = '\0'; - i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc); + i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc); if (i == 0) { if (strbuf[0] == '\0') { ret = 1; @@ -438,28 +372,14 @@ int MAIN(int argc, char **argv) } } - if (outf == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); - if (bufsize != NULL) - setbuf(stdin, NULL); /* don't do buffered reads */ -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outf) <= 0) { - perror(outf); - goto end; - } - } + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; rbio = in; wbio = out; #ifdef ZLIB - if (do_zlib) { if ((bzl = BIO_new(BIO_f_zlib())) == NULL) goto end; @@ -666,11 +586,26 @@ int MAIN(int argc, char **argv) #endif if (pass) OPENSSL_free(pass); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); +} + +static void show_ciphers(const OBJ_NAME *name, void *bio_) +{ + BIO *bio = bio_; + static int n; + + if (!islower((unsigned char)*name->name)) + return; + + BIO_printf(bio, "-%-25s", name->name); + if (++n == 3) { + BIO_printf(bio, "\n"); + n = 0; + } else + BIO_printf(bio, " "); } -int set_hex(char *in, unsigned char *out, int size) +static int set_hex(char *in, unsigned char *out, int size) { int i, n; unsigned char j; diff --git a/apps/engine.c b/apps/engine.c index 53864650ac..7dcc1b0817 100644 --- a/apps/engine.c +++ b/apps/engine.c @@ -1,4 +1,3 @@ -/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */ /* * Written by Richard Levitte for the OpenSSL project * 2000. @@ -66,27 +65,26 @@ # include # include -# undef PROG -# define PROG engine_main - -static const char *engine_usage[] = { - "usage: engine opts [engine ...]\n", - " -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n", - " -vv will additionally display each command's description\n", - " -vvv will also add the input flags for each command\n", - " -vvvv will also show internal input flags\n", - " -c - for each engine, also list the capabilities\n", - " -t[t] - for each engine, check that they are really available\n", - " -tt will display error trace for unavailable engines\n", - " -pre - runs command 'cmd' against the ENGINE before any attempts\n", - " to load it (if -t is used)\n", - " -post - runs command 'cmd' against the ENGINE after loading it\n", - " (only used if -t is also provided)\n", - " NB: -pre and -post will be applied to all ENGINEs supplied on the command\n", - " line, or all supported ENGINEs if none are specified.\n", - " Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n", - " argument \"/lib/libdriver.so\".\n", - NULL +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST, + OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV +} OPTION_CHOICE; + +OPTIONS engine_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, + {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, + {"vv", OPT_VV, '-', "Also display each command's description"}, + {"v", OPT_V, '-', "For each engine, list its 'control commands'"}, + {"c", OPT_C, '-', "List the capabilities of each engine"}, + {"t", OPT_T, '-', "Check that each engine is available"}, + {"tt", OPT_TT, '-', "Display error trace for unavailable engines"}, + {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, + {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, + {OPT_MORE_STR, OPT_EOF, 1, + "Commands are like \"SO_PATH:/lib/libdriver.so\""}, + {NULL} }; static void identity(char *ptr) @@ -124,13 +122,13 @@ static int append_buf(char **buf, const char *s, int *size, int step) return 1; } -static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) +static int util_flags(BIO *out, unsigned int flags, const char *indent) { int started = 0, err = 0; /* Indent before displaying input flags */ - BIO_printf(bio_out, "%s%s(input flags): ", indent, indent); + BIO_printf(out, "%s%s(input flags): ", indent, indent); if (flags == 0) { - BIO_printf(bio_out, "\n"); + BIO_printf(out, "\n"); return 1; } /* @@ -138,11 +136,11 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) * having it part of all the other flags, even if it really is. */ if (flags & ENGINE_CMD_FLAG_INTERNAL) { - BIO_printf(bio_out, "[Internal] "); + BIO_printf(out, "[Internal] "); } if (flags & ENGINE_CMD_FLAG_NUMERIC) { - BIO_printf(bio_out, "NUMERIC"); + BIO_printf(out, "NUMERIC"); started = 1; } /* @@ -153,18 +151,18 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) */ if (flags & ENGINE_CMD_FLAG_STRING) { if (started) { - BIO_printf(bio_out, "|"); + BIO_printf(out, "|"); err = 1; } - BIO_printf(bio_out, "STRING"); + BIO_printf(out, "STRING"); started = 1; } if (flags & ENGINE_CMD_FLAG_NO_INPUT) { if (started) { - BIO_printf(bio_out, "|"); + BIO_printf(out, "|"); err = 1; } - BIO_printf(bio_out, "NO_INPUT"); + BIO_printf(out, "NO_INPUT"); started = 1; } /* Check for unknown flags */ @@ -173,17 +171,16 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent) ~ENGINE_CMD_FLAG_NO_INPUT & ~ENGINE_CMD_FLAG_INTERNAL; if (flags) { if (started) - BIO_printf(bio_out, "|"); - BIO_printf(bio_out, "<0x%04X>", flags); + BIO_printf(out, "|"); + BIO_printf(out, "<0x%04X>", flags); } if (err) - BIO_printf(bio_out, " "); - BIO_printf(bio_out, "\n"); + BIO_printf(out, " "); + BIO_printf(out, "\n"); return 1; } -static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, - const char *indent) +static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent) { static const int line_wrap = 78; int num; @@ -200,9 +197,9 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, } cmds = sk_OPENSSL_STRING_new_null(); - if (!cmds) goto err; + do { int len; /* Get the command input flags */ @@ -233,26 +230,26 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, /* Now decide on the output */ if (xpos == 0) /* Do an indent */ - xpos = BIO_puts(bio_out, indent); + xpos = BIO_puts(out, indent); else /* Otherwise prepend a ", " */ - xpos += BIO_printf(bio_out, ", "); + xpos += BIO_printf(out, ", "); if (verbose == 1) { /* * We're just listing names, comma-delimited */ if ((xpos > (int)strlen(indent)) && (xpos + (int)strlen(name) > line_wrap)) { - BIO_printf(bio_out, "\n"); - xpos = BIO_puts(bio_out, indent); + BIO_printf(out, "\n"); + xpos = BIO_puts(out, indent); } - xpos += BIO_printf(bio_out, "%s", name); + xpos += BIO_printf(out, "%s", name); } else { /* We're listing names plus descriptions */ - BIO_printf(bio_out, "%s: %s\n", name, + BIO_printf(out, "%s: %s\n", name, (desc == NULL) ? "" : desc); /* ... and sometimes input flags */ - if ((verbose >= 3) && !util_flags(bio_out, flags, indent)) + if ((verbose >= 3) && !util_flags(out, flags, indent)) goto err; xpos = 0; } @@ -267,7 +264,7 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL); } while (num > 0); if (xpos > 0) - BIO_printf(bio_out, "\n"); + BIO_printf(out, "\n"); ret = 1; err: if (cmds) @@ -280,12 +277,12 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, } static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, - BIO *bio_out, const char *indent) + BIO *out, const char *indent) { int loop, res, num = sk_OPENSSL_STRING_num(cmds); if (num < 0) { - BIO_printf(bio_out, "[Error]: internal stack error\n"); + BIO_printf(out, "[Error]: internal stack error\n"); return; } for (loop = 0; loop < num; loop++) { @@ -299,7 +296,7 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, res = 0; } else { if ((int)(arg - cmd) > 254) { - BIO_printf(bio_out, "[Error]: command name too long\n"); + BIO_printf(out, "[Error]: command name too long\n"); return; } memcpy(buf, cmd, (int)(arg - cmd)); @@ -310,90 +307,70 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, res = 0; } if (res) - BIO_printf(bio_out, "[Success]: %s\n", cmd); + BIO_printf(out, "[Success]: %s\n", cmd); else { - BIO_printf(bio_out, "[Failure]: %s\n", cmd); - ERR_print_errors(bio_out); + BIO_printf(out, "[Failure]: %s\n", cmd); + ERR_print_errors(out); } } } -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int engine_main(int argc, char **argv) { int ret = 1, i; - const char **pp; int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0; ENGINE *e; STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null(); STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null(); STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null(); - int badops = 1; - BIO *bio_out = NULL; + BIO *out; const char *indent = " "; + OPTION_CHOICE o; + char *prog; - apps_startup(); - SSL_load_error_strings(); - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) + out = dup_bio_out(); + prog = opt_init(argc, argv, engine_options); + if (!engines || !pre_cmds || !post_cmds) goto end; - bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - bio_out = BIO_push(tmpbio, bio_out); - } -# endif - - argc--; - argv++; - while (argc >= 1) { - if (strncmp(*argv, "-v", 2) == 0) { - if (strspn(*argv + 1, "v") < strlen(*argv + 1)) - goto skip_arg_loop; - if ((verbose = strlen(*argv + 1)) > 4) - goto skip_arg_loop; - } else if (strcmp(*argv, "-c") == 0) + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(engine_options); + ret = 0; + goto end; + case OPT_VVVV: + case OPT_VVV: + case OPT_VV: + case OPT_V: + /* Convert to an integer from one to four. */ + i = (int)(o - OPT_V) + 1; + if (verbose < i) + verbose = i; + break; + case OPT_C: list_cap = 1; - else if (strncmp(*argv, "-t", 2) == 0) { - test_avail = 1; - if (strspn(*argv + 1, "t") < strlen(*argv + 1)) - goto skip_arg_loop; - if ((test_avail_noise = strlen(*argv + 1) - 1) > 1) - goto skip_arg_loop; - } else if (strcmp(*argv, "-pre") == 0) { - argc--; - argv++; - if (argc == 0) - goto skip_arg_loop; - sk_OPENSSL_STRING_push(pre_cmds, *argv); - } else if (strcmp(*argv, "-post") == 0) { - argc--; - argv++; - if (argc == 0) - goto skip_arg_loop; - sk_OPENSSL_STRING_push(post_cmds, *argv); - } else if ((strncmp(*argv, "-h", 2) == 0) || - (strcmp(*argv, "-?") == 0)) - goto skip_arg_loop; - else - sk_OPENSSL_STRING_push(engines, *argv); - argc--; - argv++; - } - /* Looks like everything went OK */ - badops = 0; - skip_arg_loop: - - if (badops) { - for (pp = engine_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); - goto end; + break; + case OPT_TT: + test_avail_noise++; + case OPT_T: + test_avail++; + break; + case OPT_PRE: + sk_OPENSSL_STRING_push(pre_cmds, opt_arg()); + break; + case OPT_POST: + sk_OPENSSL_STRING_push(post_cmds, opt_arg()); + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); + for ( ; *argv; argv++) + sk_OPENSSL_STRING_push(engines, *argv); if (sk_OPENSSL_STRING_num(engines) == 0) { for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { @@ -408,10 +385,10 @@ int MAIN(int argc, char **argv) /* * Do "id" first, then "name". Easier to auto-parse. */ - BIO_printf(bio_out, "(%s) %s\n", id, name); - util_do_cmds(e, pre_cmds, bio_out, indent); + BIO_printf(out, "(%s) %s\n", id, name); + util_do_cmds(e, pre_cmds, out, indent); if (strcmp(ENGINE_get_id(e), id) != 0) { - BIO_printf(bio_out, "Loaded: (%s) %s\n", + BIO_printf(out, "Loaded: (%s) %s\n", ENGINE_get_id(e), ENGINE_get_name(e)); } if (list_cap) { @@ -466,24 +443,24 @@ int MAIN(int argc, char **argv) goto end; skip_pmeths: if (cap_buf && (*cap_buf != '\0')) - BIO_printf(bio_out, " [%s]\n", cap_buf); + BIO_printf(out, " [%s]\n", cap_buf); OPENSSL_free(cap_buf); } if (test_avail) { - BIO_printf(bio_out, "%s", indent); + BIO_printf(out, "%s", indent); if (ENGINE_init(e)) { - BIO_printf(bio_out, "[ available ]\n"); - util_do_cmds(e, post_cmds, bio_out, indent); + BIO_printf(out, "[ available ]\n"); + util_do_cmds(e, post_cmds, out, indent); ENGINE_finish(e); } else { - BIO_printf(bio_out, "[ unavailable ]\n"); + BIO_printf(out, "[ unavailable ]\n"); if (test_avail_noise) ERR_print_errors_fp(stdout); ERR_clear_error(); } } - if ((verbose > 0) && !util_verbose(e, verbose, bio_out, indent)) + if ((verbose > 0) && !util_verbose(e, verbose, out, indent)) goto end; ENGINE_free(e); } else @@ -497,9 +474,8 @@ int MAIN(int argc, char **argv) sk_OPENSSL_STRING_pop_free(engines, identity); sk_OPENSSL_STRING_pop_free(pre_cmds, identity); sk_OPENSSL_STRING_pop_free(post_cmds, identity); - BIO_free_all(bio_out); - apps_shutdown(); - OPENSSL_EXIT(ret); + BIO_free_all(out); + return (ret); } #else diff --git a/apps/errstr.c b/apps/errstr.c index 668c5f3024..960815da65 100644 --- a/apps/errstr.c +++ b/apps/errstr.c @@ -1,4 +1,3 @@ -/* apps/errstr.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -65,56 +64,60 @@ #include #include -#undef PROG -#define PROG errstr_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_STATS +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS errstr_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"}, + {OPT_HELP_STR, 1, '-', " errnum Error number\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"stats", OPT_STATS, '-', + "Print internal hashtable statistics (long!)"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int errstr_main(int argc, char **argv) { - int i, ret = 0; - char buf[256]; + OPTION_CHOICE o; + char buf[256], *prog; + int ret = 1; unsigned long l; - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - SSL_load_error_strings(); - - if ((argc > 1) && (strcmp(argv[1], "-stats") == 0)) { - BIO *out = NULL; - - out = BIO_new(BIO_s_file()); - if ((out != NULL) && BIO_set_fp(out, stdout, BIO_NOCLOSE)) { -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - lh_ERR_STRING_DATA_node_stats_bio(ERR_get_string_table(), out); - lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(), out); + prog = opt_init(argc, argv, errstr_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(errstr_options); + ret = 0; + goto end; + case OPT_STATS: + lh_ERR_STRING_DATA_node_stats_bio(ERR_get_string_table(), + bio_out); + lh_ERR_STRING_DATA_stats_bio(ERR_get_string_table(), bio_out); lh_ERR_STRING_DATA_node_usage_stats_bio(ERR_get_string_table(), - out); + bio_out); + ret = 0; + goto end; } - BIO_free_all(out); - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - for (i = 1; i < argc; i++) { - if (sscanf(argv[i], "%lx", &l)) { - ERR_error_string_n(l, buf, sizeof buf); - printf("%s\n", buf); - } else { - printf("%s: bad error code\n", argv[i]); - printf("usage: errstr [-stats] ...\n"); + ret = 0; + for (argv = opt_rest(); *argv; argv++) { + if (!opt_ulong(*argv, &l)) ret++; + else { + ERR_error_string_n(l, buf, sizeof buf); + BIO_printf(bio_out, "%s\n", buf); } } - apps_shutdown(); - OPENSSL_EXIT(ret); + end: + return (ret); } diff --git a/apps/gendh.c b/apps/gendh.c deleted file mode 100644 index 904bcf3a94..0000000000 --- a/apps/gendh.c +++ /dev/null @@ -1,243 +0,0 @@ -/* apps/gendh.c */ -/* obsoleted by dhparam.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#ifndef OPENSSL_NO_DH -# include -# include -# include -# include -# include "apps.h" -# include -# include -# include -# include -# include -# include -# include - -# define DEFBITS 2048 -# undef PROG -# define PROG gendh_main - -static int dh_cb(int p, int n, BN_GENCB *cb); - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) -{ - BN_GENCB *cb = NULL; - DH *dh = NULL; - int ret = 1, num = DEFBITS; - int g = 2; - char *outfile = NULL; - char *inrand = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - BIO *out = NULL; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - cb = BN_GENCB_new(); - if (!cb) - goto end; - - BN_GENCB_set(cb, dh_cb, bio_err); - - if (!load_config(bio_err, NULL)) - goto end; - - argv++; - argc--; - for (;;) { - if (argc <= 0) - break; - if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-2") == 0) - g = 2; -/*- else if (strcmp(*argv,"-3") == 0) - g=3; */ - else if (strcmp(*argv, "-5") == 0) - g = 5; -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } else - break; - argv++; - argc--; - } - if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { - bad: - BIO_printf(bio_err, "usage: gendh [args] [numbits]\n"); - BIO_printf(bio_err, " -out file - output the key to 'file\n"); - BIO_printf(bio_err, " -2 - use 2 as the generator value\n"); - /* - * BIO_printf(bio_err," -3 - use 3 as the generator value\n"); - */ - BIO_printf(bio_err, " -5 - use 5 as the generator value\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e - use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " - load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - goto end; - } -# ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); -# endif - - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); - goto end; - } - - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } - - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { - BIO_printf(bio_err, - "warning, not much extra random data, consider using the -rand option\n"); - } - if (inrand != NULL) - BIO_printf(bio_err, "%ld semi-random bytes loaded\n", - app_RAND_load_files(inrand)); - - BIO_printf(bio_err, - "Generating DH parameters, %d bit long safe prime, generator %d\n", - num, g); - BIO_printf(bio_err, "This is going to take a long time\n"); - - if (((dh = DH_new()) == NULL) - || !DH_generate_parameters_ex(dh, num, g, cb)) - goto end; - - app_RAND_write_file(NULL, bio_err); - - if (!PEM_write_bio_DHparams(out, dh)) - goto end; - ret = 0; - end: - if (ret != 0) - ERR_print_errors(bio_err); - BIO_free_all(out); - DH_free(dh); - if (cb != NULL) - BN_GENCB_free(cb); - apps_shutdown(); - OPENSSL_EXIT(ret); -} - -static int dh_cb(int p, int n, BN_GENCB *cb) -{ - char c = '*'; - - if (p == 0) - c = '.'; - if (p == 1) - c = '+'; - if (p == 2) - c = '*'; - if (p == 3) - c = '\n'; - BIO_write(BN_GENCB_get_arg(cb), &c, 1); - (void)BIO_flush(BN_GENCB_get_arg(cb)); - return 1; -} -#else /* !OPENSSL_NO_DH */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/apps/gendsa.c b/apps/gendsa.c index 8288eb90ab..1eaaa45504 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -1,4 +1,3 @@ -/* apps/gendsa.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -71,155 +70,86 @@ # include # define DEFBITS 512 -# undef PROG -# define PROG gendsa_main -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS gendsa_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"out", OPT_OUT, '>', "Output the key to the specified file"}, + {"passout", OPT_PASSOUT, 's'}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int gendsa_main(int argc, char **argv) { - DSA *dsa = NULL; - int ret = 1; - char *outfile = NULL; - char *inrand = NULL, *dsaparams = NULL; - char *passargout = NULL, *passout = NULL; BIO *out = NULL, *in = NULL; + DSA *dsa = NULL; const EVP_CIPHER *enc = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; + char *engine = NULL, *inrand = NULL, *dsaparams = NULL; + char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog; + OPTION_CHOICE o; + int ret = 1; - argv++; - argc--; - for (;;) { - if (argc <= 0) + prog = opt_init(argc, argv, gendsa_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + ret = 0; + opt_help(gendsa_options); + goto end; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto end; break; - if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); } -# endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } else if (strcmp(*argv, "-") == 0) - goto bad; -# ifndef OPENSSL_NO_DES - else if (strcmp(*argv, "-des") == 0) - enc = EVP_des_cbc(); - else if (strcmp(*argv, "-des3") == 0) - enc = EVP_des_ede3_cbc(); -# endif -# ifndef OPENSSL_NO_IDEA - else if (strcmp(*argv, "-idea") == 0) - enc = EVP_idea_cbc(); -# endif -# ifndef OPENSSL_NO_SEED - else if (strcmp(*argv, "-seed") == 0) - enc = EVP_seed_cbc(); -# endif -# ifndef OPENSSL_NO_AES - else if (strcmp(*argv, "-aes128") == 0) - enc = EVP_aes_128_cbc(); - else if (strcmp(*argv, "-aes192") == 0) - enc = EVP_aes_192_cbc(); - else if (strcmp(*argv, "-aes256") == 0) - enc = EVP_aes_256_cbc(); -# endif -# ifndef OPENSSL_NO_CAMELLIA - else if (strcmp(*argv, "-camellia128") == 0) - enc = EVP_camellia_128_cbc(); - else if (strcmp(*argv, "-camellia192") == 0) - enc = EVP_camellia_192_cbc(); - else if (strcmp(*argv, "-camellia256") == 0) - enc = EVP_camellia_256_cbc(); -# endif - else if (**argv != '-' && dsaparams == NULL) { - dsaparams = *argv; - } else - goto bad; - argv++; - argc--; } + argc = opt_num_rest(); + argv = opt_rest(); + + if (argc != 1) + goto opthelp; + dsaparams = *argv; - if (dsaparams == NULL) { - bad: - BIO_printf(bio_err, "usage: gendsa [args] dsaparam-file\n"); - BIO_printf(bio_err, " -out file - output the key to 'file'\n"); -# ifndef OPENSSL_NO_DES - BIO_printf(bio_err, - " -des - encrypt the generated key with DES in cbc mode\n"); - BIO_printf(bio_err, - " -des3 - encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); -# endif -# ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, - " -idea - encrypt the generated key with IDEA in cbc mode\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, " -seed\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc seed\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e - use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " - load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, " dsaparam-file\n"); - BIO_printf(bio_err, - " - a DSA parameter file as generated by the dsaparam command\n"); - goto end; - } # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { + if (!app_passwd(NULL, passoutarg, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } - in = BIO_new(BIO_s_file()); - if (!(BIO_read_filename(in, dsaparams))) { - perror(dsaparams); - goto end; - } + in = bio_open_default(dsaparams, "r"); + if (in == NULL) + goto end2; if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { BIO_printf(bio_err, "unable to load DSA parameter file\n"); @@ -228,26 +158,11 @@ int MAIN(int argc, char **argv) BIO_free(in); in = NULL; - out = BIO_new(BIO_s_file()); + out = bio_open_default(outfile, "w"); if (out == NULL) - goto end; - - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + goto end2; - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { + if (!app_RAND_load_file(NULL, 1) && inrand == NULL) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } @@ -259,7 +174,7 @@ int MAIN(int argc, char **argv) if (!DSA_generate_key(dsa)) goto end; - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) goto end; @@ -267,13 +182,13 @@ int MAIN(int argc, char **argv) end: if (ret != 0) ERR_print_errors(bio_err); + end2: BIO_free(in); BIO_free_all(out); DSA_free(dsa); if (passout) OPENSSL_free(passout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } #else /* !OPENSSL_NO_DSA */ diff --git a/apps/genpkey.c b/apps/genpkey.c index bd81d51a22..5130b40a82 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -1,4 +1,3 @@ -/* apps/genpkey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006 @@ -66,159 +65,125 @@ # include #endif -static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, - const char *file, ENGINE *e); +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e); static int genpkey_cb(EVP_PKEY_CTX *ctx); -#define PROG genpkey_main - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, + OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS genpkey_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, + {"pass", OPT_PASS, 's', "Output file pass phrase source"}, + {"paramfile", OPT_PARAMFILE, '<', "Parameters file"}, + {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, + {"pkeyopt", OPT_PKEYOPT, 's', + "Set the public key algorithm option as opt:value"}, + {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, + {"text", OPT_TEXT, '-', "Print the in text"}, + {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {OPT_HELP_STR, 1, 1, + "Order of options may be important! See the documentation.\n"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int genpkey_main(int argc, char **argv) { - ENGINE *e = NULL; - char **args, *outfile = NULL; - char *passarg = NULL; BIO *in = NULL, *out = NULL; - const EVP_CIPHER *cipher = NULL; - int outformat; - int text = 0; + ENGINE *e = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; - char *pass = NULL; - int badarg = 0; - int ret = 1, rv; - - int do_param = 0; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - outformat = FORMAT_PEM; - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - args = argv + 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-outform")) { - if (args[1]) { - args++; - outformat = str2fmt(*args); - } else - badarg = 1; - } else if (!strcmp(*args, "-pass")) { - if (!args[1]) - goto bad; - passarg = *(++args); - } + char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog; + const EVP_CIPHER *cipher = NULL; + OPTION_CHOICE o; + int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0; + + prog = opt_init(argc, argv, genpkey_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + ret = 0; + opt_help(genpkey_options); + goto end; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + + case OPT_PASS: + passarg = opt_arg(); + break; #ifndef OPENSSL_NO_ENGINE - else if (strcmp(*args, "-engine") == 0) { - if (!args[1]) - goto bad; - e = setup_engine(bio_err, *(++args), 0); - } + case OPT_ENGINE: + e = setup_engine(opt_arg(), 0); + break; #endif - else if (!strcmp(*args, "-paramfile")) { - if (!args[1]) - goto bad; - args++; + case OPT_PARAMFILE: if (do_param == 1) - goto bad; - if (!init_keygen_file(bio_err, &ctx, *args, e)) + goto opthelp; + if (!init_keygen_file(&ctx, opt_arg(), e)) goto end; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else if (strcmp(*args, "-algorithm") == 0) { - if (!args[1]) - goto bad; - if (!init_gen_str(bio_err, &ctx, *(++args), e, do_param)) + break; + case OPT_ALGORITHM: + if (!init_gen_str(&ctx, opt_arg(), e, do_param)) goto end; - } else if (strcmp(*args, "-pkeyopt") == 0) { - if (!args[1]) - goto bad; - if (!ctx) { - BIO_puts(bio_err, "No keytype specified\n"); - goto bad; - } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) { - BIO_puts(bio_err, "parameter setting error\n"); + break; + case OPT_PKEYOPT: + if (ctx == NULL) { + BIO_printf(bio_err, "%s: No keytype specified.\n", prog); + goto opthelp; + } + if (pkey_ctrl_string(ctx, opt_arg()) <= 0) { + BIO_printf(bio_err, + "%s: Error setting %s parameter:\n", + prog, opt_arg()); ERR_print_errors(bio_err); goto end; } - } else if (strcmp(*args, "-genparam") == 0) { - if (ctx) - goto bad; + break; + case OPT_GENPARAM: + if (ctx != NULL) + goto opthelp; do_param = 1; - } else if (strcmp(*args, "-text") == 0) + break; + case OPT_TEXT: text = 1; - else { - cipher = EVP_get_cipherbyname(*args + 1); - if (!cipher) { - BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); - badarg = 1; - } - if (do_param == 1) - badarg = 1; + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &cipher) + || do_param == 1) + goto opthelp; } - args++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (!ctx) - badarg = 1; - - if (badarg) { - bad: - BIO_printf(bio_err, "Usage: genpkey [options]\n"); - BIO_printf(bio_err, "where options may be\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-outform X output format (DER or PEM)\n"); - BIO_printf(bio_err, - "-pass arg output file pass phrase source\n"); - BIO_printf(bio_err, - "- use cipher to encrypt the key\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - BIO_printf(bio_err, "-paramfile file parameters file\n"); - BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); - BIO_printf(bio_err, - "-pkeyopt opt:value set the public key algorithm option \n" - " to value \n"); - BIO_printf(bio_err, - "-genparam generate parameters, not key\n"); - BIO_printf(bio_err, "-text print the in text\n"); - BIO_printf(bio_err, - "NB: options order may be important! See the manual page.\n"); - goto end; - } + if (ctx == NULL) + goto opthelp; - if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_puts(bio_err, "Error getting password\n"); goto end; } - if (outfile) { - if (!(out = BIO_new_file(outfile, "wb"))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } + out = bio_open_default(outfile, "wb"); + if (out == NULL) + goto end; EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); @@ -278,20 +243,19 @@ int MAIN(int argc, char **argv) return ret; } -static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, - const char *file, ENGINE *e) +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) { BIO *pbio; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; if (*pctx) { - BIO_puts(err, "Parameters already set!\n"); + BIO_puts(bio_err, "Parameters already set!\n"); return 0; } pbio = BIO_new_file(file, "r"); if (!pbio) { - BIO_printf(err, "Can't open parameter file %s\n", file); + BIO_printf(bio_err, "Can't open parameter file %s\n", file); return 0; } @@ -313,15 +277,15 @@ static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, return 1; err: - BIO_puts(err, "Error initializing context\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error initializing context\n"); + ERR_print_errors(bio_err); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); return 0; } -int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, +int init_gen_str(EVP_PKEY_CTX **pctx, const char *algname, ENGINE *e, int do_param) { EVP_PKEY_CTX *ctx = NULL; @@ -330,7 +294,7 @@ int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, int pkey_id; if (*pctx) { - BIO_puts(err, "Algorithm already set!\n"); + BIO_puts(bio_err, "Algorithm already set!\n"); return 0; } @@ -369,8 +333,8 @@ int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, return 1; err: - BIO_printf(err, "Error initializing %s context\n", algname); - ERR_print_errors(err); + BIO_printf(bio_err, "Error initializing %s context\n", algname); + ERR_print_errors(bio_err); EVP_PKEY_CTX_free(ctx); return 0; diff --git a/apps/genrsa.c b/apps/genrsa.c index cf60219642..b7275aef7a 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -1,4 +1,3 @@ -/* apps/genrsa.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -74,192 +73,108 @@ # include # define DEFBITS 2048 -# undef PROG -# define PROG genrsa_main static int genrsa_cb(int p, int n, BN_GENCB *cb); -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_3, OPT_F4, OPT_NON_FIPS_ALLOW, OPT_ENGINE, + OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER +} OPTION_CHOICE; -int MAIN(int argc, char **argv) -{ - BN_GENCB *cb = NULL; +OPTIONS genrsa_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"3", OPT_3, '-', "Use 3 for the E value"}, + {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, + {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, + {"non-fips-allow", OPT_NON_FIPS_ALLOW, '-'}, + {"out", OPT_OUT, 's', "Output the key to specified file"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, # ifndef OPENSSL_NO_ENGINE - ENGINE *e = NULL; + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif - int ret = 1; - int non_fips_allow = 0; - int num = DEFBITS; + {NULL} +}; + +int genrsa_main(int argc, char **argv) +{ + BN_GENCB *cb = BN_GENCB_new(); + ENGINE *e = NULL; + BIGNUM *bn = BN_new(); + BIO *out = NULL; + RSA *rsa = NULL; const EVP_CIPHER *enc = NULL; + int ret = 1, non_fips_allow = 0, num = DEFBITS; unsigned long f4 = RSA_F4; - char *outfile = NULL; - char *passargout = NULL, *passout = NULL; + char *outfile = NULL, *passoutarg = NULL, *passout = NULL; + char *engine = NULL, *inrand = NULL, *prog; char *hexe, *dece; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - char *inrand = NULL; - BIO *out = NULL; - BIGNUM *bn = BN_new(); - RSA *rsa = NULL; - if (!bn) - goto err; - - cb = BN_GENCB_new(); - if (!cb) - goto err; + OPTION_CHOICE o; - apps_startup(); + if (!bn || !cb) + goto end; BN_GENCB_set(cb, genrsa_cb, bio_err); - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto err; - if ((out = BIO_new(BIO_s_file())) == NULL) { - BIO_printf(bio_err, "unable to create BIO for output\n"); - goto err; - } - - argv++; - argc--; - for (;;) { - if (argc <= 0) - break; - if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-3") == 0) + prog = opt_init(argc, argv, genrsa_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + ret = 0; + opt_help(genrsa_options); + goto end; + case OPT_3: f4 = 3; - else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0) + break; + case OPT_F4: f4 = RSA_F4; -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } -# ifndef OPENSSL_NO_DES - else if (strcmp(*argv, "-des") == 0) - enc = EVP_des_cbc(); - else if (strcmp(*argv, "-des3") == 0) - enc = EVP_des_ede3_cbc(); -# endif -# ifndef OPENSSL_NO_IDEA - else if (strcmp(*argv, "-idea") == 0) - enc = EVP_idea_cbc(); -# endif -# ifndef OPENSSL_NO_SEED - else if (strcmp(*argv, "-seed") == 0) - enc = EVP_seed_cbc(); -# endif -# ifndef OPENSSL_NO_AES - else if (strcmp(*argv, "-aes128") == 0) - enc = EVP_aes_128_cbc(); - else if (strcmp(*argv, "-aes192") == 0) - enc = EVP_aes_192_cbc(); - else if (strcmp(*argv, "-aes256") == 0) - enc = EVP_aes_256_cbc(); -# endif -# ifndef OPENSSL_NO_CAMELLIA - else if (strcmp(*argv, "-camellia128") == 0) - enc = EVP_camellia_128_cbc(); - else if (strcmp(*argv, "-camellia192") == 0) - enc = EVP_camellia_192_cbc(); - else if (strcmp(*argv, "-camellia256") == 0) - enc = EVP_camellia_256_cbc(); -# endif - else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } else if (strcmp(*argv, "-non-fips-allow") == 0) + break; + case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; - else break; - argv++; - argc--; - } - if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { - bad: - BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n"); - BIO_printf(bio_err, - " -des encrypt the generated key with DES in cbc mode\n"); - BIO_printf(bio_err, - " -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n"); -# ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, - " -idea encrypt the generated key with IDEA in cbc mode\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, " -seed\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc seed\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif - BIO_printf(bio_err, " -out file output the key to 'file\n"); - BIO_printf(bio_err, - " -passout arg output file pass phrase source\n"); - BIO_printf(bio_err, - " -f4 use F4 (0x10001) for the E value\n"); - BIO_printf(bio_err, " -3 use 3 for the E value\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - goto err; + case OPT_OUT: + outfile = opt_arg(); + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto end; + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); - ERR_load_crypto_strings(); + if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) + goto end; - if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { + if (!app_passwd(NULL, passoutarg, NULL, &passout)) { BIO_printf(bio_err, "Error getting password\n"); - goto err; + goto end; } # ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); # endif - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto err; - } - } + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL + if (!app_RAND_load_file(NULL, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); @@ -276,15 +191,15 @@ int MAIN(int argc, char **argv) rsa = RSA_new_method(e); # endif if (!rsa) - goto err; + goto end; if (non_fips_allow) rsa->flags |= RSA_FLAG_NON_FIPS_ALLOW; if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb)) - goto err; + goto end; - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); hexe = BN_bn2hex(rsa->e); dece = BN_bn2dec(rsa->e); @@ -302,11 +217,11 @@ int MAIN(int argc, char **argv) if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, (pem_password_cb *)password_callback, &cb_data)) - goto err; + goto end; } ret = 0; - err: + end: if (bn) BN_free(bn); if (cb) @@ -317,8 +232,7 @@ int MAIN(int argc, char **argv) OPENSSL_free(passout); if (ret != 0) ERR_print_errors(bio_err); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static int genrsa_cb(int p, int n, BN_GENCB *cb) diff --git a/apps/makeapps.com b/apps/makeapps.com index efc213c8ee..2724cc6051 100644 --- a/apps/makeapps.com +++ b/apps/makeapps.com @@ -178,7 +178,7 @@ $! NOTE: Some might think this list ugly. However, it's made this way to $! reflect the E_OBJ variable in Makefile as closely as possible, thereby $! making it fairly easy to verify that the lists are the same. $! -$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+- +$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DHPARAM,ENC,PASSWD,ERRSTR,"+- "CA,PKCS7,CRL2P7,CRL,"+- "RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+- "X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+- diff --git a/apps/nseq.c b/apps/nseq.c index c3067385d2..3fa496c488 100644 --- a/apps/nseq.c +++ b/apps/nseq.c @@ -1,4 +1,3 @@ -/* nseq.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. @@ -63,84 +62,71 @@ #include #include -#undef PROG -#define PROG nseq_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_TOSEQ, OPT_IN, OPT_OUT +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS nseq_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int nseq_main(int argc, char **argv) { - char **args, *infile = NULL, *outfile = NULL; BIO *in = NULL, *out = NULL; - int toseq = 0; X509 *x509 = NULL; NETSCAPE_CERT_SEQUENCE *seq = NULL; - int i, ret = 1; - int badarg = 0; - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - ERR_load_crypto_strings(); - args = argv + 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-toseq")) - toseq = 1; - else if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else - badarg = 1; - args++; - } - - if (badarg) { - BIO_printf(bio_err, "Netscape certificate sequence utility\n"); - BIO_printf(bio_err, "Usage nseq [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, "-toseq output NS Sequence file\n"); - OPENSSL_EXIT(1); - } + OPTION_CHOICE o; + int toseq = 0, ret = 1, i; + char *infile = NULL, *outfile = NULL, *prog; - if (infile) { - if (!(in = BIO_new_file(infile, "r"))) { - BIO_printf(bio_err, "Can't open input file %s\n", infile); + prog = opt_init(argc, argv, nseq_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - - if (outfile) { - if (!(out = BIO_new_file(outfile, "w"))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); + case OPT_HELP: + ret = 0; + opt_help(nseq_options); goto end; + case OPT_TOSEQ: + toseq = 1; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif } + argc = opt_num_rest(); + argv = opt_rest(); + + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; + if (toseq) { seq = NETSCAPE_CERT_SEQUENCE_new(); seq->certs = sk_X509_new_null(); + if (!seq->certs) + goto end; while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) sk_X509_push(seq->certs, x509); if (!sk_X509_num(seq->certs)) { - BIO_printf(bio_err, "Error reading certs file %s\n", infile); + BIO_printf(bio_err, "%s: Error reading certs file %s\n", + prog, infile); ERR_print_errors(bio_err); goto end; } @@ -149,8 +135,10 @@ int MAIN(int argc, char **argv) goto end; } - if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) { - BIO_printf(bio_err, "Error reading sequence file %s\n", infile); + seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL); + if (seq == NULL) { + BIO_printf(bio_err, "%s: Error reading sequence file %s\n", + prog, infile); ERR_print_errors(bio_err); goto end; } @@ -166,5 +154,5 @@ int MAIN(int argc, char **argv) BIO_free_all(out); NETSCAPE_CERT_SEQUENCE_free(seq); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/ocsp.c b/apps/ocsp.c index 96f4c67421..840e506a5c 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1,4 +1,3 @@ -/* ocsp.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2000. @@ -95,7 +94,7 @@ # endif /* Maximum leeway in validity period: default 5 minutes */ -# define MAX_VALIDITY_PERIOD (5 * 60) +# define MAX_VALIDITY_PERIOD (5 * 60) static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, @@ -103,12 +102,11 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); -static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage); - -static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, +static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, X509 *ca, X509 *rcert, EVP_PKEY *rkey, const EVP_MD *md, STACK_OF(X509) *rother, unsigned long flags, @@ -119,498 +117,372 @@ static BIO *init_responder(const char *port); static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, const char *port); static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); -static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, const STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout); -# undef PROG -# define PROG ocsp_main - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT, + OPT_IGNORE_ERR, OPT_NOVERIFY, OPT_NONCE, OPT_NO_NONCE, + OPT_RESP_NO_CERTS, OPT_RESP_KEY_ID, OPT_NO_CERTS, + OPT_NO_SIGNATURE_VERIFY, OPT_NO_CERT_VERIFY, OPT_NO_CHAIN, + OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, + OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, + OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, + OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, + OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, + OPT_RESPOUT, OPT_PATH, OPT_CERT, OPT_SERIAL, + OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, + OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_HEADER, + OPT_V_ENUM, + OPT_MD +} OPTION_CHOICE; + +OPTIONS ocsp_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"out", OPT_OUTFILE, '>', "Output filename"}, + {"timeout", OPT_TIMEOUT, 'p'}, + {"url", OPT_URL, 's', "Responder URL"}, + {"host", OPT_HOST, 's', "host:prot top to connect to"}, + {"port", OPT_PORT, 'p', "Port to run responder on"}, + {"ignore_err", OPT_IGNORE_ERR, '-'}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, + {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, + {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, + {"resp_no_certs", OPT_RESP_NO_CERTS, '-', + "Don't include any certificates in response"}, + {"resp_key_id", OPT_RESP_KEY_ID, '-', + "Identify reponse by signing certificate key ID"}, + {"no_certs", OPT_NO_CERTS, '-', + "Don't include any certificates in signed request"}, + {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', + "Don't check signature on response"}, + {"no_cert_verify", OPT_NO_CERT_VERIFY, '-', + "Don't check signing certificate"}, + {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, + {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', + "Don't do additional checks on signing certificate"}, + {"no_explicit", OPT_NO_EXPLICIT, '-'}, + {"trust_other", OPT_TRUST_OTHER, '-', + "Don't verify additional certificates"}, + {"no_intern", OPT_NO_INTERN, '-', + "Don't search certificates contained in response for signer"}, + {"badsig", OPT_BADSIG, '-'}, + {"text", OPT_TEXT, '-', "Print text form of request and response"}, + {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, + {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, + {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, + {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"}, + {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, + {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, + {"sign_other", OPT_SIGN_OTHER, '<', + "Additional certificates to include in signed request"}, + {"verify_other", OPT_VERIFY_OTHER, '<', + "Additional certificates to search for signer"}, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, + {"validity_period", OPT_VALIDITY_PERIOD, 'u', + "Maximum validity discrepancy in seconds"}, + {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, + {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, + {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"}, + {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"}, + {"path", OPT_PATH, 's', "Path to use in OCSP request"}, + {"cert", OPT_CERT, '<', "Certificate to check"}, + {"serial", OPT_SERIAL, 's', "Nerial number to check"}, + {"index", OPT_INDEX, '<', "Certificate status index file"}, + {"CA", OPT_CA, '<', "CA certificate"}, + {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, + {"nrequest", OPT_REQUEST, 'p', + "Number of requests to accept (default unlimited)"}, + {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, + {"rsigner", OPT_RSIGNER, '<', + "Sesponder certificate to sign responses with"}, + {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, + {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, + {"rmd", OPT_RMD, 's'}, + {"header", OPT_HEADER, 's', "key=value header to add"}, + {"", OPT_MD, '-', "Any supported digest"}, + OPT_V_OPTIONS, + {NULL} +}; + +int ocsp_main(int argc, char **argv) { - ENGINE *e = NULL; - char **args; - char *host = NULL, *port = NULL, *path = "/"; - char *thost = NULL, *tport = NULL, *tpath = NULL; - char *reqin = NULL, *respin = NULL; - char *reqout = NULL, *respout = NULL; - char *signfile = NULL, *keyfile = NULL; - char *rsignfile = NULL, *rkeyfile = NULL; - char *outfile = NULL; - int add_nonce = 1, noverify = 0, use_ssl = -1; - STACK_OF(CONF_VALUE) *headers = NULL; + BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; + const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; + CA_DB *rdb = NULL; + EVP_PKEY *key = NULL, *rkey = NULL; + OCSP_BASICRESP *bs = NULL; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; - OCSP_BASICRESP *bs = NULL; - X509 *issuer = NULL, *cert = NULL; + STACK_OF(CONF_VALUE) *headers = NULL; + STACK_OF(OCSP_CERTID) *ids = NULL; + STACK_OF(OPENSSL_STRING) *reqnames = NULL; + STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; + X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL; X509 *signer = NULL, *rsigner = NULL; - EVP_PKEY *key = NULL, *rkey = NULL; - BIO *acbio = NULL, *cbio = NULL; - BIO *derbio = NULL; - BIO *out = NULL; - int req_timeout = -1; - int req_text = 0, resp_text = 0; - long nsec = MAX_VALIDITY_PERIOD, maxage = -1; - char *CAfile = NULL, *CApath = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; + char *CAfile = NULL, *CApath = NULL, *header, *value; + char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; + char *rca_filename = NULL, *reqin = NULL, *respin = NULL; + char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; + char *rsignfile = NULL, *rkeyfile = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; + char *signfile = NULL, *keyfile = NULL; + char *thost = NULL, *tport = NULL, *tpath = NULL; + int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; + int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; + int req_text = 0, resp_text = 0, req_timeout = -1, ret = 1; + long nsec = MAX_VALIDITY_PERIOD, maxage = -1; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; - int ret = 1; - int accept_count = -1; - int badarg = 0; - int badsig = 0; - int i; - int ignore_err = 0; - STACK_OF(OPENSSL_STRING) *reqnames = NULL; - STACK_OF(OCSP_CERTID) *ids = NULL; - - X509 *rca_cert = NULL; - char *ridx_filename = NULL; - char *rca_filename = NULL; - CA_DB *rdb = NULL; - int nmin = 0, ndays = -1; - const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; + OPTION_CHOICE o; + char *prog; - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); - args = argv + 1; reqnames = sk_OPENSSL_STRING_new_null(); + if (!reqnames) + goto end; ids = sk_OCSP_CERTID_new_null(); - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-timeout")) { - if (args[1]) { - args++; - req_timeout = atol(*args); - if (req_timeout < 0) { - BIO_printf(bio_err, "Illegal timeout value %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-url")) { + if (!ids) + goto end; + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) + return 1; + + prog = opt_init(argc, argv, ocsp_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + ret = 0; + opt_help(ocsp_options); + goto end; + case OPT_OUTFILE: + outfile = opt_arg(); + break; + case OPT_TIMEOUT: + req_timeout = atoi(opt_arg()); + break; + case OPT_URL: if (thost) OPENSSL_free(thost); if (tport) OPENSSL_free(tport); if (tpath) OPENSSL_free(tpath); - if (args[1]) { - args++; - if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { - BIO_printf(bio_err, "Error parsing URL\n"); - badarg = 1; - } - thost = host; - tport = port; - tpath = path; - } else - badarg = 1; - } else if (!strcmp(*args, "-host")) { - if (args[1]) { - args++; - host = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-port")) { - if (args[1]) { - args++; - port = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-header")) { - if (args[1] && args[2]) { - if (!X509V3_add_value(args[1], args[2], &headers)) - goto end; - args += 2; - } else - badarg = 1; - } else if (!strcmp(*args, "-ignore_err")) + if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { + BIO_printf(bio_err, "%s Error parsing URL\n", prog); + goto end; + } + thost = host; + tport = port; + tpath = path; + break; + case OPT_HOST: + host = opt_arg(); + break; + case OPT_PORT: + port = opt_arg(); + break; + case OPT_IGNORE_ERR: ignore_err = 1; - else if (!strcmp(*args, "-noverify")) + break; + case OPT_NOVERIFY: noverify = 1; - else if (!strcmp(*args, "-nonce")) + break; + case OPT_NONCE: add_nonce = 2; - else if (!strcmp(*args, "-no_nonce")) + break; + case OPT_NO_NONCE: add_nonce = 0; - else if (!strcmp(*args, "-resp_no_certs")) + break; + case OPT_RESP_NO_CERTS: rflags |= OCSP_NOCERTS; - else if (!strcmp(*args, "-resp_key_id")) + break; + case OPT_RESP_KEY_ID: rflags |= OCSP_RESPID_KEY; - else if (!strcmp(*args, "-no_certs")) + break; + case OPT_NO_CERTS: sign_flags |= OCSP_NOCERTS; - else if (!strcmp(*args, "-no_signature_verify")) + break; + case OPT_NO_SIGNATURE_VERIFY: verify_flags |= OCSP_NOSIGS; - else if (!strcmp(*args, "-no_cert_verify")) + break; + case OPT_NO_CERT_VERIFY: verify_flags |= OCSP_NOVERIFY; - else if (!strcmp(*args, "-no_chain")) + break; + case OPT_NO_CHAIN: verify_flags |= OCSP_NOCHAIN; - else if (!strcmp(*args, "-no_cert_checks")) + break; + case OPT_NO_CERT_CHECKS: verify_flags |= OCSP_NOCHECKS; - else if (!strcmp(*args, "-no_explicit")) + break; + case OPT_NO_EXPLICIT: verify_flags |= OCSP_NOEXPLICIT; - else if (!strcmp(*args, "-trust_other")) + break; + case OPT_TRUST_OTHER: verify_flags |= OCSP_TRUSTOTHER; - else if (!strcmp(*args, "-no_intern")) + break; + case OPT_NO_INTERN: verify_flags |= OCSP_NOINTERN; - else if (!strcmp(*args, "-badsig")) + break; + case OPT_BADSIG: badsig = 1; - else if (!strcmp(*args, "-text")) { - req_text = 1; - resp_text = 1; - } else if (!strcmp(*args, "-req_text")) + break; + case OPT_TEXT: + req_text = resp_text = 1; + break; + case OPT_REQ_TEXT: req_text = 1; - else if (!strcmp(*args, "-resp_text")) + break; + case OPT_RESP_TEXT: resp_text = 1; - else if (!strcmp(*args, "-reqin")) { - if (args[1]) { - args++; - reqin = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-respin")) { - if (args[1]) { - args++; - respin = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-signer")) { - if (args[1]) { - args++; - signfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-VAfile")) { - if (args[1]) { - args++; - verify_certfile = *args; - verify_flags |= OCSP_TRUSTOTHER; - } else - badarg = 1; - } else if (!strcmp(*args, "-sign_other")) { - if (args[1]) { - args++; - sign_certfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-verify_other")) { - if (args[1]) { - args++; - verify_certfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-CAfile")) { - if (args[1]) { - args++; - CAfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-CApath")) { - if (args[1]) { - args++; - CApath = *args; - } else - badarg = 1; - } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) { - if (badarg) + break; + case OPT_REQIN: + reqin = opt_arg(); + break; + case OPT_RESPIN: + respin = opt_arg(); + break; + case OPT_SIGNER: + signfile = opt_arg(); + break; + case OPT_VAFILE: + verify_certfile = opt_arg(); + verify_flags |= OCSP_TRUSTOTHER; + break; + case OPT_SIGN_OTHER: + sign_certfile = opt_arg(); + break; + case OPT_VERIFY_OTHER: + verify_certfile = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) goto end; - continue; - } else if (!strcmp(*args, "-validity_period")) { - if (args[1]) { - args++; - nsec = atol(*args); - if (nsec < 0) { - BIO_printf(bio_err, - "Illegal validity period %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-status_age")) { - if (args[1]) { - args++; - maxage = atol(*args); - if (maxage < 0) { - BIO_printf(bio_err, "Illegal validity age %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-signkey")) { - if (args[1]) { - args++; - keyfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-reqout")) { - if (args[1]) { - args++; - reqout = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-respout")) { - if (args[1]) { - args++; - respout = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-path")) { - if (args[1]) { - args++; - path = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-issuer")) { - if (args[1]) { - args++; - X509_free(issuer); - issuer = load_cert(bio_err, *args, FORMAT_PEM, - NULL, e, "issuer certificate"); - if (!issuer) - goto end; - } else - badarg = 1; - } else if (!strcmp(*args, "-cert")) { - if (args[1]) { - args++; - X509_free(cert); - cert = load_cert(bio_err, *args, FORMAT_PEM, - NULL, e, "certificate"); - if (!cert) - goto end; - if (!cert_id_md) - cert_id_md = EVP_sha1(); - if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) - goto end; - if (!sk_OPENSSL_STRING_push(reqnames, *args)) - goto end; - } else - badarg = 1; - } else if (!strcmp(*args, "-serial")) { - if (args[1]) { - args++; - if (!cert_id_md) - cert_id_md = EVP_sha1(); - if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids)) - goto end; - if (!sk_OPENSSL_STRING_push(reqnames, *args)) - goto end; - } else - badarg = 1; - } else if (!strcmp(*args, "-index")) { - if (args[1]) { - args++; - ridx_filename = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-CA")) { - if (args[1]) { - args++; - rca_filename = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-nmin")) { - if (args[1]) { - args++; - nmin = atol(*args); - if (nmin < 0) { - BIO_printf(bio_err, "Illegal update period %s\n", *args); - badarg = 1; - } - } + vpmtouched++; + break; + case OPT_VALIDITY_PERIOD: + opt_long(opt_arg(), &nsec); + break; + case OPT_STATUS_AGE: + opt_long(opt_arg(), &maxage); + break; + case OPT_SIGNKEY: + keyfile = opt_arg(); + break; + case OPT_REQOUT: + reqout = opt_arg(); + break; + case OPT_RESPOUT: + respout = opt_arg(); + break; + case OPT_PATH: + path = opt_arg(); + break; + case OPT_CERT: + X509_free(cert); + cert = load_cert(opt_arg(), FORMAT_PEM, + NULL, NULL, "certificate"); + if (cert == NULL) + goto end; + if (cert_id_md == NULL) + cert_id_md = EVP_sha1(); + if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) + goto end; + if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) + goto end; + break; + case OPT_SERIAL: + if (cert_id_md == NULL) + cert_id_md = EVP_sha1(); + if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) + goto end; + if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) + goto end; + break; + case OPT_INDEX: + ridx_filename = opt_arg(); + break; + case OPT_CA: + rca_filename = opt_arg(); + break; + case OPT_NMIN: + opt_int(opt_arg(), &nmin); if (ndays == -1) ndays = 0; - else - badarg = 1; - } else if (!strcmp(*args, "-nrequest")) { - if (args[1]) { - args++; - accept_count = atol(*args); - if (accept_count < 0) { - BIO_printf(bio_err, "Illegal accept count %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-ndays")) { - if (args[1]) { - args++; - ndays = atol(*args); - if (ndays < 0) { - BIO_printf(bio_err, "Illegal update period %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-rsigner")) { - if (args[1]) { - args++; - rsignfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-rkey")) { - if (args[1]) { - args++; - rkeyfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-rother")) { - if (args[1]) { - args++; - rcertfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-rmd")) { - if (args[1]) { - args++; - rsign_md = EVP_get_digestbyname(*args); - if (!rsign_md) - badarg = 1; - } else - badarg = 1; - } else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) { - badarg = 1; + break; + case OPT_REQUEST: + opt_int(opt_arg(), &accept_count); + break; + case OPT_NDAYS: + ndays = atoi(opt_arg()); + break; + case OPT_RSIGNER: + rsignfile = opt_arg(); + break; + case OPT_RKEY: + rkeyfile = opt_arg(); + break; + case OPT_ROTHER: + rcertfile = opt_arg(); + break; + case OPT_RMD: + if (!opt_md(opt_arg(), &rsign_md)) + goto end; + break; + case OPT_HEADER: + header = opt_arg(); + value = strchr(header, '='); + if (value == NULL) { + BIO_printf(bio_err, "Missing = in header key=value\n"); + goto opthelp; + } + *value++ = '\0'; + if (!X509V3_add_value(header, value, &headers)) + goto end; + break; + case OPT_MD: + if (cert_id_md != NULL) { + BIO_printf(bio_err, + "%s: Digest must be before -cert or -serial\n", + prog); + goto opthelp; + } + if (!opt_md(opt_unknown(), &cert_id_md)) + goto opthelp; + break; } - args++; } + argc = opt_num_rest(); + argv = opt_rest(); /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) - badarg = 1; - - if (badarg) { - BIO_printf(bio_err, "OCSP utility\n"); - BIO_printf(bio_err, "Usage ocsp [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-out file output filename\n"); - BIO_printf(bio_err, "-issuer file issuer certificate\n"); - BIO_printf(bio_err, "-cert file certificate to check\n"); - BIO_printf(bio_err, "-serial n serial number to check\n"); - BIO_printf(bio_err, - "-signer file certificate to sign OCSP request with\n"); - BIO_printf(bio_err, - "-signkey file private key to sign OCSP request with\n"); - BIO_printf(bio_err, - "-sign_other file additional certificates to include in signed request\n"); - BIO_printf(bio_err, - "-no_certs don't include any certificates in signed request\n"); - BIO_printf(bio_err, - "-req_text print text form of request\n"); - BIO_printf(bio_err, - "-resp_text print text form of response\n"); - BIO_printf(bio_err, - "-text print text form of request and response\n"); - BIO_printf(bio_err, - "-reqout file write DER encoded OCSP request to \"file\"\n"); - BIO_printf(bio_err, - "-respout file write DER encoded OCSP reponse to \"file\"\n"); - BIO_printf(bio_err, - "-reqin file read DER encoded OCSP request from \"file\"\n"); - BIO_printf(bio_err, - "-respin file read DER encoded OCSP reponse from \"file\"\n"); - BIO_printf(bio_err, - "-nonce add OCSP nonce to request\n"); - BIO_printf(bio_err, - "-no_nonce don't add OCSP nonce to request\n"); - BIO_printf(bio_err, "-url URL OCSP responder URL\n"); - BIO_printf(bio_err, - "-host host:n send OCSP request to host on port n\n"); - BIO_printf(bio_err, - "-path path to use in OCSP request\n"); - BIO_printf(bio_err, - "-CApath dir trusted certificates directory\n"); - BIO_printf(bio_err, - "-CAfile file trusted certificates file\n"); - BIO_printf(bio_err, - "-trusted_first use locally trusted CA's first when building trust chain\n"); - BIO_printf(bio_err, - "-no_alt_chains only ever use the first certificate chain found\n"); - BIO_printf(bio_err, - "-VAfile file validator certificates file\n"); - BIO_printf(bio_err, - "-validity_period n maximum validity discrepancy in seconds\n"); - BIO_printf(bio_err, - "-status_age n maximum status age in seconds\n"); - BIO_printf(bio_err, - "-noverify don't verify response at all\n"); - BIO_printf(bio_err, - "-verify_other file additional certificates to search for signer\n"); - BIO_printf(bio_err, - "-trust_other don't verify additional certificates\n"); - BIO_printf(bio_err, - "-no_intern don't search certificates contained in response for signer\n"); - BIO_printf(bio_err, - "-no_signature_verify don't check signature on response\n"); - BIO_printf(bio_err, - "-no_cert_verify don't check signing certificate\n"); - BIO_printf(bio_err, - "-no_chain don't chain verify response\n"); - BIO_printf(bio_err, - "-no_cert_checks don't do additional checks on signing certificate\n"); - BIO_printf(bio_err, - "-port num port to run responder on\n"); - BIO_printf(bio_err, - "-index file certificate status index file\n"); - BIO_printf(bio_err, "-CA file CA certificate\n"); - BIO_printf(bio_err, - "-rsigner file responder certificate to sign responses with\n"); - BIO_printf(bio_err, - "-rkey file responder key to sign responses with\n"); - BIO_printf(bio_err, - "-rother file other certificates to include in response\n"); - BIO_printf(bio_err, - "-resp_no_certs don't include any certificates in response\n"); - BIO_printf(bio_err, - "-nmin n number of minutes before next update\n"); - BIO_printf(bio_err, - "-ndays n number of days before next update\n"); - BIO_printf(bio_err, - "-resp_key_id identify reponse by signing certificate key ID\n"); - BIO_printf(bio_err, - "-nrequest n number of requests to accept (default unlimited)\n"); - BIO_printf(bio_err, - "- use specified digest in the request\n"); - BIO_printf(bio_err, - "-timeout n timeout connection to OCSP responder after n seconds\n"); - goto end; - } + goto opthelp; - if (outfile) - out = BIO_new_file(outfile, "w"); - else - out = BIO_new_fp(stdout, BIO_NOCLOSE); - - if (!out) { - BIO_printf(bio_err, "Error opening output file\n"); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } if (!req && (add_nonce != 2)) add_nonce = 0; if (!req && reqin) { - if (!strcmp(reqin, "-")) - derbio = BIO_new_fp(stdin, BIO_NOCLOSE); - else - derbio = BIO_new_file(reqin, "rb"); - if (!derbio) { - BIO_printf(bio_err, "Error Opening OCSP request file\n"); + derbio = bio_open_default(reqin, "rb"); + if (derbio == NULL) goto end; - } req = d2i_OCSP_REQUEST_bio(derbio, NULL); BIO_free(derbio); if (!req) { @@ -628,21 +500,21 @@ int MAIN(int argc, char **argv) if (rsignfile && !rdb) { if (!rkeyfile) rkeyfile = rsignfile; - rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, - NULL, e, "responder certificate"); + rsigner = load_cert(rsignfile, FORMAT_PEM, + NULL, NULL, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, - NULL, e, "CA certificate"); + rca_cert = load_cert(rca_filename, FORMAT_PEM, + NULL, NULL, "CA certificate"); if (rcertfile) { - rother = load_certs(bio_err, rcertfile, FORMAT_PEM, - NULL, e, "responder other certificates"); + rother = load_certs(rcertfile, FORMAT_PEM, + NULL, NULL, "responder other certificates"); if (!rother) goto end; } - rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, + rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, "responder private key"); if (!rkey) goto end; @@ -675,19 +547,19 @@ int MAIN(int argc, char **argv) if (signfile) { if (!keyfile) keyfile = signfile; - signer = load_cert(bio_err, signfile, FORMAT_PEM, - NULL, e, "signer certificate"); + signer = load_cert(signfile, FORMAT_PEM, + NULL, NULL, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { - sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, - NULL, e, "signer certificates"); + sign_other = load_certs(sign_certfile, FORMAT_PEM, + NULL, NULL, "signer certificates"); if (!sign_other) goto end; } - key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, + key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL, "signer private key"); if (!key) goto end; @@ -703,14 +575,9 @@ int MAIN(int argc, char **argv) OCSP_REQUEST_print(out, req, 0); if (reqout) { - if (!strcmp(reqout, "-")) - derbio = BIO_new_fp(stdout, BIO_NOCLOSE); - else - derbio = BIO_new_file(reqout, "wb"); - if (!derbio) { - BIO_printf(bio_err, "Error opening file %s\n", reqout); + derbio = bio_open_default(reqout, "wb"); + if (derbio == NULL) goto end; - } i2d_OCSP_REQUEST_bio(derbio, req); BIO_free(derbio); } @@ -730,13 +597,13 @@ int MAIN(int argc, char **argv) } if (rdb) { - i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, + make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rsign_md, rother, rflags, nmin, ndays, badsig); if (cbio) send_ocsp_response(cbio, resp); } else if (host) { # ifndef OPENSSL_NO_SOCK - resp = process_responder(bio_err, req, host, path, + resp = process_responder(req, host, path, port, use_ssl, headers, req_timeout); if (!resp) goto end; @@ -746,21 +613,15 @@ int MAIN(int argc, char **argv) goto end; # endif } else if (respin) { - if (!strcmp(respin, "-")) - derbio = BIO_new_fp(stdin, BIO_NOCLOSE); - else - derbio = BIO_new_file(respin, "rb"); - if (!derbio) { - BIO_printf(bio_err, "Error Opening OCSP response file\n"); + derbio = bio_open_default(respin, "rb"); + if (derbio == NULL) goto end; - } resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); BIO_free(derbio); if (!resp) { BIO_printf(bio_err, "Error reading OCSP response\n"); goto end; } - } else { ret = 0; goto end; @@ -769,20 +630,14 @@ int MAIN(int argc, char **argv) done_resp: if (respout) { - if (!strcmp(respout, "-")) - derbio = BIO_new_fp(stdout, BIO_NOCLOSE); - else - derbio = BIO_new_file(respout, "wb"); - if (!derbio) { - BIO_printf(bio_err, "Error opening file %s\n", respout); + derbio = bio_open_default(respout, "wb"); + if (derbio == NULL) goto end; - } i2d_OCSP_RESPONSE_bio(derbio, resp); BIO_free(derbio); } i = OCSP_response_status(resp); - if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { BIO_printf(out, "Responder Error: %s (%d)\n", OCSP_response_status_str(i), i); @@ -797,40 +652,38 @@ int MAIN(int argc, char **argv) /* If running as responder don't verify our own response */ if (cbio) { - if (accept_count > 0) - accept_count--; - /* Redo if more connections needed */ - if (accept_count) { - BIO_free_all(cbio); - cbio = NULL; - OCSP_REQUEST_free(req); - req = NULL; - OCSP_RESPONSE_free(resp); - resp = NULL; - goto redo_accept; + if (--accept_count <= 0) { + ret = 0; + goto end; } - ret = 0; - goto end; - } else if (ridx_filename) { + BIO_free_all(cbio); + cbio = NULL; + OCSP_REQUEST_free(req); + req = NULL; + OCSP_RESPONSE_free(resp); + resp = NULL; + goto redo_accept; + } + if (ridx_filename) { ret = 0; goto end; } - if (!store) - store = setup_verify(bio_err, CAfile, CApath); - if (!store) - goto end; - if (vpm) + if (!store) { + store = setup_verify(CAfile, CApath); + if (!store) + goto end; + } + if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile) { - verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, - NULL, e, "validator certificate"); + verify_other = load_certs(verify_certfile, FORMAT_PEM, + NULL, NULL, "validator certificate"); if (!verify_other) goto end; } bs = OCSP_response_get1_basic(resp); - if (!bs) { BIO_printf(bio_err, "Error parsing response\n"); goto end; @@ -859,8 +712,7 @@ int MAIN(int argc, char **argv) } - if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) - ret = 1; + print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage); end: ERR_print_errors(bio_err); @@ -870,7 +722,6 @@ int MAIN(int argc, char **argv) X509_VERIFY_PARAM_free(vpm); EVP_PKEY_free(key); EVP_PKEY_free(rkey); - X509_free(issuer); X509_free(cert); X509_free(rsigner); X509_free(rca_cert); @@ -894,7 +745,7 @@ int MAIN(int argc, char **argv) if (tpath) OPENSSL_free(tpath); - OPENSSL_EXIT(ret); + return (ret); } static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, @@ -958,22 +809,19 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, return 0; } -static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage) { OCSP_CERTID *id; char *name; - int i; - - int status, reason; - + int i, status, reason; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids)) - return 1; + return; for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { id = sk_OCSP_CERTID_value(ids, i); @@ -1016,11 +864,9 @@ static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, ASN1_GENERALIZEDTIME_print(out, rev); BIO_puts(out, "\n"); } - - return 1; } -static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, +static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, X509 *ca, X509 *rcert, EVP_PKEY *rkey, const EVP_MD *rmd, STACK_OF(X509) *rother, unsigned long flags, @@ -1029,7 +875,7 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, ASN1_TIME *thisupd = NULL, *nextupd = NULL; OCSP_CERTID *cid, *ca_id = NULL; OCSP_BASICRESP *bs = NULL; - int i, id_count, ret = 1; + int i, id_count; id_count = OCSP_request_onereq_count(req); @@ -1112,8 +958,7 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, if (badsig) { ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs); - unsigned char *sigptr; - sigptr = ASN1_STRING_data(sig); + unsigned char *sigptr = ASN1_STRING_data(sig); sigptr[ASN1_STRING_length(sig) - 1] ^= 0x1; } @@ -1124,8 +969,6 @@ static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, ASN1_TIME_free(nextupd); OCSP_CERTID_free(ca_id); OCSP_BASICRESP_free(bs); - return ret; - } static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) @@ -1154,6 +997,7 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) static BIO *init_responder(const char *port) { BIO *acbio = NULL, *bufbio = NULL; + bufbio = BIO_new(BIO_f_buffer()); if (!bufbio) goto err; @@ -1185,9 +1029,9 @@ static BIO *init_responder(const char *port) static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, const char *port) { - int have_post = 0, len; + int len; OCSP_REQUEST *req = NULL; - char inbuf[1024]; + char inbuf[2048]; BIO *cbio = NULL; if (BIO_do_accept(acbio) <= 0) { @@ -1199,25 +1043,24 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, cbio = BIO_pop(acbio); *pcbio = cbio; + /* Read the request line. */ + len = BIO_gets(cbio, inbuf, sizeof inbuf); + if (len <= 0) + return 1; + if (strncmp(inbuf, "POST", 4) != 0) { + BIO_printf(bio_err, "Invalid request\n"); + return 1; + } for (;;) { len = BIO_gets(cbio, inbuf, sizeof inbuf); if (len <= 0) return 1; - /* Look for "POST" signalling start of query */ - if (!have_post) { - if (strncmp(inbuf, "POST", 4)) { - BIO_printf(bio_err, "Invalid request\n"); - return 1; - } - have_post = 1; - } /* Look for end of headers */ if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) break; } /* Try to read OCSP request */ - req = d2i_OCSP_REQUEST_bio(cbio, NULL); if (!req) { @@ -1244,7 +1087,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) return 1; } -static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *path, const STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout) { @@ -1262,12 +1105,12 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, rv = BIO_do_connect(cbio); if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { - BIO_puts(err, "Error connecting BIO\n"); + BIO_puts(bio_err, "Error connecting BIO\n"); return NULL; } if (BIO_get_fd(cbio, &fd) <= 0) { - BIO_puts(err, "Can't get connection fd\n"); + BIO_puts(bio_err, "Can't get connection fd\n"); goto err; } @@ -1278,7 +1121,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, tv.tv_sec = req_timeout; rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); if (rv == 0) { - BIO_puts(err, "Timeout on connect\n"); + BIO_puts(bio_err, "Timeout on connect\n"); return NULL; } } @@ -1311,15 +1154,15 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, else if (BIO_should_write(cbio)) rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); else { - BIO_puts(err, "Unexpected retry condition\n"); + BIO_puts(bio_err, "Unexpected retry condition\n"); goto err; } if (rv == 0) { - BIO_puts(err, "Timeout on request\n"); + BIO_puts(bio_err, "Timeout on request\n"); break; } if (rv == -1) { - BIO_puts(err, "Select error\n"); + BIO_puts(bio_err, "Select error\n"); break; } @@ -1331,7 +1174,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, const char *path, return rsp; } -OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, +OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, const char *path, const char *port, int use_ssl, const STACK_OF(CONF_VALUE) *headers, @@ -1342,7 +1185,7 @@ OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, OCSP_RESPONSE *resp = NULL; cbio = BIO_new_connect(host); if (!cbio) { - BIO_printf(err, "Error creating connect BIO\n"); + BIO_printf(bio_err, "Error creating connect BIO\n"); goto end; } if (port) @@ -1351,14 +1194,14 @@ OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, BIO *sbio; ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { - BIO_printf(err, "Error creating SSL context.\n"); + BIO_printf(bio_err, "Error creating SSL context.\n"); goto end; } SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } - resp = query_responder(err, cbio, path, headers, req, req_timeout); + resp = query_responder(cbio, path, headers, req, req_timeout); if (!resp) BIO_printf(bio_err, "Error querying OCSP responder\n"); end: diff --git a/apps/openssl.c b/apps/openssl.c index e93aed702a..de73fac7a9 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -1,4 +1,3 @@ -/* apps/openssl.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -112,9 +111,6 @@ #include #include #include -#define OPENSSL_C /* tells apps.h to use complete - * apps_startup() */ -#include "apps.h" #include #include #include @@ -126,14 +122,35 @@ #ifndef OPENSSL_NO_ENGINE # include #endif -#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS - * world */ -#include "progs.h" +/* needed for the _O_BINARY defs in the MS world */ +#define USE_SOCKETS #include "s_apps.h" #include #ifdef OPENSSL_FIPS # include #endif +#define INCLUDE_FUNCTION_TABLE +#include "apps.h" + +#if 1 +# define LIST_STANDARD_COMMANDS "list-standard-commands" +# define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" +# define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" +# define LIST_CIPHER_COMMANDS "list-cipher-commands" +# define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" +# define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" +#endif + +#ifdef OPENSSL_NO_CAMELLIA +# define FORMAT "%-15s" +# define COLUMNS 5 +#else +# define FORMAT "%-18s" +# define COLUMNS 4 +#endif + +/* Special sentinel to exit the program. */ +#define EXIT_THE_PROGRAM (-1) /* * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with @@ -141,28 +158,103 @@ * required type of "FUNCTION*"). This removes the necessity for * macro-generated wrapper functions. */ - +DECLARE_LHASH_OF(FUNCTION); static LHASH_OF(FUNCTION) *prog_init(void); static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); -static void list_pkey(BIO *out); -static void list_cipher(BIO *out); -static void list_md(BIO *out); +static int list_pkey(void); +static int list_cipher(void); +static int list_md(void); +static int list_type(FUNC_TYPE list_type); char *default_config_file = NULL; -/* Make sure there is only one when MONOLITH is defined */ -#ifdef MONOLITH CONF *config = NULL; +BIO *bio_in = NULL; +BIO *bio_out = NULL; BIO *bio_err = NULL; + +static void apps_startup() +{ +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif + CRYPTO_malloc_init(); + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + OpenSSL_add_all_algorithms(); + OpenSSL_add_ssl_algorithms(); + setup_ui_method(); + /*SSL_library_init();*/ +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); +#endif +} + +static void apps_shutdown() +{ +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + destroy_ui_method(); + CONF_modules_unload(1); +#ifndef OPENSSL_NO_COMP + COMP_zlib_cleanup(); +#endif + OBJ_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + RAND_cleanup(); + ERR_free_strings(); +} + +static char *make_config_name() +{ + const char *t = X509_get_default_cert_area(); + size_t len; + char *p; + + len = strlen(t) + strlen(OPENSSL_CONF) + 2; + p = OPENSSL_malloc(len); + if (p == NULL) + return NULL; + BUF_strlcpy(p, t, len); +#ifndef OPENSSL_SYS_VMS + BUF_strlcat(p, "/", len); #endif + BUF_strlcat(p, OPENSSL_CONF, len); + + return p; +} + +static int load_config(CONF *cnf) +{ + static int load_config_called = 0; + + if (load_config_called) + return 1; + load_config_called = 1; + if (!cnf) + cnf = config; + if (!cnf) + return 1; + + OPENSSL_load_builtin_modules(); + + if (CONF_modules_load(cnf, NULL, 0) <= 0) { + BIO_printf(bio_err, "Error configuring OpenSSL\n"); + ERR_print_errors(bio_err); + return 0; + } + return 1; +} static void lock_dbg_cb(int mode, int type, const char *file, int line) { - static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ + static int modes[CRYPTO_NUM_LOCKS]; const char *errstr = NULL; - int rw; + int rw = mode & (CRYPTO_READ | CRYPTO_WRITE); - rw = mode & (CRYPTO_READ | CRYPTO_WRITE); - if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { + if (rw != CRYPTO_READ && rw != CRYPTO_WRITE) { errstr = "invalid mode"; goto err; } @@ -175,12 +267,9 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line) if (mode & CRYPTO_LOCK) { if (modes[type]) { errstr = "already locked"; - /* - * must not happen in a single-threaded program (would deadlock) - */ + /* must not happen in a single-threaded program --> deadlock! */ goto err; } - modes[type] = rw; } else if (mode & CRYPTO_UNLOCK) { if (!modes[type]) { @@ -209,98 +298,83 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line) } } -#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) -# define ARGV _Argv -#else -# define ARGV Argv +BIO *dup_bio_in(void) +{ + return BIO_new_fp(stdin, BIO_NOCLOSE | BIO_FP_TEXT); +} + +BIO *dup_bio_out(void) +{ + BIO *b = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); +#ifdef OPENSSL_SYS_VMS + b = BIO_push(BIO_new(BIO_f_linebuffer()), b); #endif + return b; +} -int main(int Argc, char *ARGV[]) +void unbuffer(FILE *fp) +{ + setbuf(fp, NULL); +} + +BIO *bio_open_default(const char *filename, const char *mode) +{ + BIO *ret; + + if (filename == NULL || strcmp(filename, "-") == 0) { + ret = *mode == 'r' ? dup_bio_in() : dup_bio_out(); + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s, %s\n", + *mode == 'r' ? "stdin" : "stdout", strerror(errno)); + } else { + ret = BIO_new_file(filename, mode); + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s for %s, %s\n", + filename, + *mode == 'r' ? "reading" : "writing", strerror(errno)); + } + ERR_print_errors(bio_err); + return NULL; +} + +#if defined( OPENSSL_SYS_VMS) +extern char **copy_argv(int *argc, char **argv); +#endif + +int main(int argc, char *argv[]) { - ARGS arg; -#define PROG_NAME_SIZE 39 - char pname[PROG_NAME_SIZE + 1]; FUNCTION f, *fp; - const char *prompt; - char buf[1024]; - char *to_free = NULL; - int n, i, ret = 0; - int argc; - char **argv, *p; LHASH_OF(FUNCTION) *prog = NULL; + char **copied_argv = NULL; + char *p, *pname, *to_free = NULL; + char buf[1024]; + const char *prompt; + ARGS arg; + int first, n, i, ret = 0; long errline; -#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) - /*- - * 2011-03-22 SMS. - * If we have 32-bit pointers everywhere, then we're safe, and - * we bypass this mess, as on non-VMS systems. (See ARGV, - * above.) - * Problem 1: Compaq/HP C before V7.3 always used 32-bit - * pointers for argv[]. - * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers - * everywhere else, we always allocate and use a 64-bit - * duplicate of argv[]. - * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed - * to NULL-terminate a 64-bit argv[]. (As this was written, the - * compiler ECO was available only on IA64.) - * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a - * 64-bit argv[argc] for NULL, and, if necessary, use a - * (properly) NULL-terminated (64-bit) duplicate of argv[]. - * The same code is used in either case to duplicate argv[]. - * Some of these decisions could be handled in preprocessing, - * but the code tends to get even uglier, and the penalty for - * deciding at compile- or run-time is tiny. - */ - char **Argv = NULL; - int free_Argv = 0; - - if ((sizeof(_Argv) < 8) /* 32-bit argv[]. */ -# if !defined( VMS_TRUST_ARGV) - || (_Argv[Argc] != NULL) /* Untrusted argv[argc] not NULL. */ -# endif - ) { - int i; - Argv = OPENSSL_malloc((Argc + 1) * sizeof(char *)); - if (Argv == NULL) { - ret = -1; - goto end; - } - for (i = 0; i < Argc; i++) - Argv[i] = _Argv[i]; - Argv[Argc] = NULL; /* Certain NULL termination. */ - free_Argv = 1; + arg.argv = NULL; + arg.size = 0; + +#if defined( OPENSSL_SYS_VMS) + copied_argv = argv = copy_argv(&argc, argv); +#endif + + p = getenv("OPENSSL_DEBUG_MEMORY"); + if (p == NULL) + /* if not set, use compiled-in default */ + ; + else if (strcmp(p, "off") != 0) { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { - /* - * Use the known-good 32-bit argv[] (which needs the type cast to - * satisfy the compiler), or the trusted or tested-good 64-bit argv[] - * as-is. - */ - Argv = (char **)_Argv; - } -#endif /* defined( OPENSSL_SYS_VMS) && - * (__INITIAL_POINTER_SIZE == 64) */ - - arg.data = NULL; - arg.count = 0; - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) { /* if not defined, use - * compiled-in library - * defaults */ - if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { - CRYPTO_malloc_debug_init(); - CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); - } else { - /* OPENSSL_DEBUG_MEMORY=off */ - CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); - } + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - CRYPTO_set_locking_callback(lock_dbg_cb); if (getenv("OPENSSL_FIPS")) { @@ -318,21 +392,40 @@ int main(int Argc, char *ARGV[]) apps_startup(); - /* Lets load up our environment a little */ - p = getenv("OPENSSL_CONF"); - if (p == NULL) - p = getenv("SSLEAY_CONF"); - if (p == NULL) - p = to_free = make_config_name(); - - default_config_file = p; + /* + * If first argument is a colon, skip it. Because in "interactive" + * mode our prompt is a colon and we can cut/paste whole lines + * by doing this hack. + */ + if (argv[1] && strcmp(argv[1], ":") == 0) { + argv[1] = argv[0]; + argc--; + argv++; + } + prog = prog_init(); + pname = opt_progname(argv[0]); + /* Lets load up our environment a little */ + bio_in = dup_bio_in(); + bio_out = dup_bio_out(); + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + + /* Determine and load the config file. */ + default_config_file = getenv("OPENSSL_CONF"); + if (default_config_file == NULL) + default_config_file = getenv("SSLEAY_CONF"); + if (default_config_file == NULL) + default_config_file = to_free = make_config_name(); + if (!load_config(NULL)) + goto end; config = NCONF_new(NULL); - i = NCONF_load(config, p, &errline); + i = NCONF_load(config, default_config_file, &errline); if (i == 0) { if (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE) { - BIO_printf(bio_err, "WARNING: can't open config file: %s\n", p); + BIO_printf(bio_err, + "%s: WARNING: can't open config file: %s\n", + pname, default_config_file); ERR_clear_error(); NCONF_free(config); config = NULL; @@ -343,45 +436,31 @@ int main(int Argc, char *ARGV[]) } } - prog = prog_init(); - /* first check the program name */ - program_name(Argv[0], pname, sizeof pname); - f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); if (fp != NULL) { - Argv[0] = pname; - ret = fp->func(Argc, Argv); + argv[0] = pname; + ret = fp->func(argc, argv); goto end; } - /* - * ok, now check that there are not arguments, if there are, run with - * them, shifting the ssleay off the front - */ - if (Argc != 1) { - Argc--; - Argv++; - ret = do_cmd(prog, Argc, Argv); + /* If there is stuff on the command line, run with that. */ + if (argc != 1) { + argc--; + argv++; + ret = do_cmd(prog, argc, argv); if (ret < 0) ret = 0; goto end; } - /* ok, lets enter the old 'OpenSSL>' mode */ - + /* ok, lets enter interactive mode */ for (;;) { ret = 0; - p = buf; - n = sizeof buf; - i = 0; - for (;;) { + for (p = buf, n = sizeof buf, i = 0, first = 1;; first = 0) { + prompt = first ? "OpenSSL> " : "> "; p[0] = '\0'; - if (i++) - prompt = ">"; - else - prompt = "OpenSSL> "; fputs(prompt, stdout); fflush(stdout); if (!fgets(p, n, stdin)) @@ -397,21 +476,25 @@ int main(int Argc, char *ARGV[]) p += i; n -= i; } - if (!chopup_args(&arg, buf, &argc, &argv)) + if (!chopup_args(&arg, buf)) { + BIO_printf(bio_err, "Can't parse (no memory?)\n"); break; + } - ret = do_cmd(prog, argc, argv); - if (ret < 0) { + ret = do_cmd(prog, arg.argc, arg.argv); + if (ret == EXIT_THE_PROGRAM) { ret = 0; goto end; } if (ret != 0) - BIO_printf(bio_err, "error in %s\n", argv[0]); + BIO_printf(bio_err, "error in %s\n", arg.argv[0]); + (void)BIO_flush(bio_out); (void)BIO_flush(bio_err); } - BIO_printf(bio_err, "bad exit\n"); ret = 1; end: + if (copied_argv) + OPENSSL_free(copied_argv); if (to_free) OPENSSL_free(to_free); if (config != NULL) { @@ -420,179 +503,222 @@ int main(int Argc, char *ARGV[]) } if (prog != NULL) lh_FUNCTION_free(prog); - if (arg.data != NULL) - OPENSSL_free(arg.data); + if (arg.argv != NULL) + OPENSSL_free(arg.argv); -#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) - /* Free any duplicate Argv[] storage. */ - if (free_Argv) { - OPENSSL_free(Argv); - } -#endif + BIO_free(bio_in); + BIO_free_all(bio_out); apps_shutdown(); - CRYPTO_mem_leaks(bio_err); + /*CRYPTO_mem_leaks(bio_err); + */ BIO_free(bio_err); - bio_err = NULL; + return (ret); +} + +OPTIONS exit_options[] = { + {NULL} +}; + +/* Unified enum for help and list commands. */ +typedef enum HELPLIST_CHOICE { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_COMMANDS, OPT_DIGEST_COMMANDS, + OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, + OPT_PK_ALGORITHMS +} HELPLIST_CHOICE; + +OPTIONS list_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"commands", OPT_COMMANDS, '-', "List of standard commands"}, + {"digest-commands", OPT_DIGEST_COMMANDS, '-', + "List of message digest commands"}, + {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', + "List of message digest algorithms"}, + {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, + {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', + "List of cipher algorithms"}, + {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', + "List of public key algorithms"}, + {NULL} +}; + +int list_main(int argc, char **argv) +{ + char *prog; + HELPLIST_CHOICE o; + + prog = opt_init(argc, argv, list_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + return 1; + case OPT_HELP: + opt_help(list_options); + break; + case OPT_COMMANDS: + return list_type(FT_general); + case OPT_DIGEST_COMMANDS: + return list_type(FT_md); + case OPT_DIGEST_ALGORITHMS: + return list_md(); + case OPT_CIPHER_COMMANDS: + return list_type(FT_cipher); + case OPT_CIPHER_ALGORITHMS: + return list_cipher(); + case OPT_PK_ALGORITHMS: + return list_pkey(); + } + } + + return 0; +} + +OPTIONS help_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {NULL} +}; + +int help_main(int argc, char **argv) +{ + FUNCTION *fp; + int i, nl; + FUNC_TYPE tp; + char *prog; + HELPLIST_CHOICE o; + + prog = opt_init(argc, argv, help_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + default: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + return 1; + case OPT_HELP: + opt_help(help_options); + return 0; + } + } + argc = opt_num_rest(); + argv = opt_rest(); + + if (argc != 0) { + BIO_printf(bio_err, "Usage: %s\n", prog); + return 1; + } + + BIO_printf(bio_err, "\nStandard commands"); + i = 0; + tp = FT_none; + for (fp = functions; fp->name != NULL; fp++) { + nl = 0; + if (((i++) % COLUMNS) == 0) { + BIO_printf(bio_err, "\n"); + nl = 1; + } + if (fp->type != tp) { + tp = fp->type; + if (!nl) + BIO_printf(bio_err, "\n"); + if (tp == FT_md) { + i = 1; + BIO_printf(bio_err, + "\nMessage Digest commands (see the `dgst' command for more details)\n"); + } else if (tp == FT_cipher) { + i = 1; + BIO_printf(bio_err, + "\nCipher commands (see the `enc' command for more details)\n"); + } + } + BIO_printf(bio_err, FORMAT, fp->name); + } + BIO_printf(bio_err, "\n\n"); + return 0; +} - OPENSSL_EXIT(ret); +int exit_main(int argc, char **argv) +{ + return EXIT_THE_PROGRAM; } -#define LIST_STANDARD_COMMANDS "list-standard-commands" -#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" -#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" -#define LIST_CIPHER_COMMANDS "list-cipher-commands" -#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" -#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" +static int list_type(FUNC_TYPE flist_type) +{ + FUNCTION *fp; + int i = 0; + + for (fp = functions; fp->name != NULL; fp++) + if (fp->type == flist_type) { + if ((i++ % COLUMNS) == 0) + BIO_printf(bio_out, "\n"); + BIO_printf(bio_out, FORMAT, fp->name); + } + BIO_printf(bio_out, "\n"); + return 0; +} static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) { FUNCTION f, *fp; - int i, ret = 1, tp, nl; - if ((argc <= 0) || (argv[0] == NULL)) { - ret = 0; - goto end; - } + if (argc <= 0 || argv[0] == NULL) + return (0); f.name = argv[0]; fp = lh_FUNCTION_retrieve(prog, &f); if (fp == NULL) { if (EVP_get_digestbyname(argv[0])) { - f.type = FUNC_TYPE_MD; + f.type = FT_md; f.func = dgst_main; fp = &f; } else if (EVP_get_cipherbyname(argv[0])) { - f.type = FUNC_TYPE_CIPHER; + f.type = FT_cipher; f.func = enc_main; fp = &f; } } if (fp != NULL) { - ret = fp->func(argc, argv); - } else if ((strncmp(argv[0], "no-", 3)) == 0) { - BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - bio_stdout = BIO_push(tmpbio, bio_stdout); - } -#endif + return (fp->func(argc, argv)); + } + if ((strncmp(argv[0], "no-", 3)) == 0) { + /* + * User is asking if foo is unsupported, by trying to "run" the + * no-foo command. Strange. + */ f.name = argv[0] + 3; - ret = (lh_FUNCTION_retrieve(prog, &f) != NULL); - if (!ret) - BIO_printf(bio_stdout, "%s\n", argv[0]); - else - BIO_printf(bio_stdout, "%s\n", argv[0] + 3); - BIO_free_all(bio_stdout); - goto end; - } else if ((strcmp(argv[0], "quit") == 0) || - (strcmp(argv[0], "q") == 0) || - (strcmp(argv[0], "exit") == 0) || - (strcmp(argv[0], "bye") == 0)) { - ret = -1; - goto end; - } else if ((strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) || - (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) || - (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) || - (strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) || - (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) || - (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)) { - int list_type; - BIO *bio_stdout; - - if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) - list_type = FUNC_TYPE_GENERAL; - else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) - list_type = FUNC_TYPE_MD; - else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) - list_type = FUNC_TYPE_MD_ALG; - else if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0) - list_type = FUNC_TYPE_PKEY; - else if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) - list_type = FUNC_TYPE_CIPHER_ALG; - else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ - list_type = FUNC_TYPE_CIPHER; - bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - bio_stdout = BIO_push(tmpbio, bio_stdout); + if (lh_FUNCTION_retrieve(prog, &f) == NULL) { + BIO_printf(bio_out, "%s\n", argv[0]); + return (0); } -#endif - - if (!load_config(bio_err, NULL)) - goto end; - - if (list_type == FUNC_TYPE_PKEY) - list_pkey(bio_stdout); - if (list_type == FUNC_TYPE_MD_ALG) - list_md(bio_stdout); - if (list_type == FUNC_TYPE_CIPHER_ALG) - list_cipher(bio_stdout); - else { - for (fp = functions; fp->name != NULL; fp++) - if (fp->type == list_type) - BIO_printf(bio_stdout, "%s\n", fp->name); - } - BIO_free_all(bio_stdout); - ret = 0; - goto end; - } else { - BIO_printf(bio_err, "openssl:Error: '%s' is an invalid command.\n", - argv[0]); - BIO_printf(bio_err, "\nStandard commands"); - i = 0; - tp = 0; - for (fp = functions; fp->name != NULL; fp++) { - nl = 0; -#ifdef OPENSSL_NO_CAMELLIA - if (((i++) % 5) == 0) -#else - if (((i++) % 4) == 0) -#endif - { - BIO_printf(bio_err, "\n"); - nl = 1; - } - if (fp->type != tp) { - tp = fp->type; - if (!nl) - BIO_printf(bio_err, "\n"); - if (tp == FUNC_TYPE_MD) { - i = 1; - BIO_printf(bio_err, - "\nMessage Digest commands (see the `dgst' command for more details)\n"); - } else if (tp == FUNC_TYPE_CIPHER) { - i = 1; - BIO_printf(bio_err, - "\nCipher commands (see the `enc' command for more details)\n"); - } - } -#ifdef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "%-15s", fp->name); -#else - BIO_printf(bio_err, "%-18s", fp->name); -#endif - } - BIO_printf(bio_err, "\n\n"); - ret = 0; + BIO_printf(bio_out, "%s\n", argv[0] + 3); + return 1; } - end: - return (ret); -} - -static int SortFnByName(const void *_f1, const void *_f2) -{ - const FUNCTION *f1 = _f1; - const FUNCTION *f2 = _f2; + if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || + strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) + /* Special value to mean "exit the program. */ + return EXIT_THE_PROGRAM; +#ifdef LIST_STANDARD_COMMANDS + if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) + return list_type(FT_general); + if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) + return list_md(); + if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0) + return list_pkey(); + if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) + return list_cipher(); + if (strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) + return list_type(FT_cipher); + if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) + return list_type(FT_md); +#endif - if (f1->type != f2->type) - return f1->type - f2->type; - return strcmp(f1->name, f2->name); + BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", + argv[0]); + return (1); } -static void list_pkey(BIO *out) +static int list_pkey(void) { int i; + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { const EVP_PKEY_ASN1_METHOD *ameth; int pkey_id, pkey_base_id, pkey_flags; @@ -601,21 +727,22 @@ static void list_pkey(BIO *out) EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, &pinfo, &pem_str, ameth); if (pkey_flags & ASN1_PKEY_ALIAS) { - BIO_printf(out, "Name: %s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(out, "\tType: Alias to %s\n", + BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tAlias for: %s\n", OBJ_nid2ln(pkey_base_id)); } else { - BIO_printf(out, "Name: %s\n", pinfo); - BIO_printf(out, "\tType: %s Algorithm\n", + BIO_printf(bio_out, "Name: %s\n", pinfo); + BIO_printf(bio_out, "\tType: %s Algorithm\n", pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); - BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); if (pem_str == NULL) pem_str = "(none)"; - BIO_printf(out, "\tPEM string: %s\n", pem_str); + BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); } } + return 0; } static void list_cipher_fn(const EVP_CIPHER *c, @@ -632,9 +759,10 @@ static void list_cipher_fn(const EVP_CIPHER *c, } } -static void list_cipher(BIO *out) +static int list_cipher(void) { - EVP_CIPHER_do_all_sorted(list_cipher_fn, out); + EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); + return 0; } static void list_md_fn(const EVP_MD *m, @@ -647,13 +775,14 @@ static void list_md_fn(const EVP_MD *m, from = ""; if (!to) to = ""; - BIO_printf(arg, "%s => %s\n", from, to); + BIO_printf((BIO *)arg, "%s => %s\n", from, to); } } -static void list_md(BIO *out) +static int list_md(void) { - EVP_MD_do_all_sorted(list_md_fn, out); + EVP_MD_do_all_sorted(list_md_fn, bio_out); + return 0; } static int function_cmp(const FUNCTION * a, const FUNCTION * b) @@ -670,13 +799,23 @@ static unsigned long function_hash(const FUNCTION * a) static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION) +static int SortFnByName(const void *_f1, const void *_f2) +{ + const FUNCTION *f1 = _f1; + const FUNCTION *f2 = _f2; + + if (f1->type != f2->type) + return f1->type - f2->type; + return strcmp(f1->name, f2->name); +} + static LHASH_OF(FUNCTION) *prog_init(void) { LHASH_OF(FUNCTION) *ret; FUNCTION *f; size_t i; - /* Purely so it looks nice when the user hits ? */ + /* Sort alphabetically within category. For nicer help displays. */ for (i = 0, f = functions; f->name != NULL; ++f, ++i) ; qsort(functions, i, sizeof *functions, SortFnByName); diff --git a/apps/opt.c b/apps/opt.c new file mode 100644 index 0000000000..3706739c03 --- /dev/null +++ b/apps/opt.c @@ -0,0 +1,915 @@ +/* ==================================================================== + * Copyright (c) 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 + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* #define COMPILE_STANDALONE_TEST_DRIVER */ +#include "apps.h" +#include +#include +#if !defined(OPENSSL_SYS_MSDOS) +# include OPENSSL_UNISTD +#endif +#include +#include +#include +#include +#include + +#define MAX_OPT_HELP_WIDTH 30 +const char OPT_HELP_STR[] = "--"; +const char OPT_MORE_STR[] = "---"; + +/* Our state */ +static char **argv; +static int argc; +static int opt_index; +static char *arg; +static char *flag; +static char *dunno; +static const OPTIONS *unknown; +static const OPTIONS *opts; +static char prog[40]; + +/* + * Return the simple name of the program; removing various platform gunk. + */ +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_NETWARE) +char *opt_progname(const char *argv0) +{ + int i; + int n; + const char *p; + char *q; + + /* find the last '/', '\' or ':' */ + for (p = argv0 + strlen(argv0); --p > argv0;) + if (*p == '/' || *p == '\\' || *p == ':') { + p++; + break; + } + + /* Strip off trailing nonsense. */ + n = strlen(p); + if (n > 4 && + (strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0) + n -= 4; +#if defined(OPENSSL_SYS_NETWARE) + if (n > 4 && + (strcmp(&p[n - 4], ".nlm") == 0 || strcmp(&p[n - 4], ".NLM") == 0) + n -= 4; +#endif + + /* Copy over the name, in lowercase. */ + if (n > sizeof prog - 1) + n = sizeof prog - 1; + for (q = prog, i = 0; i < n; i++, p++) + q++ = isupper(*p) ? tolower(*p) : *p; + *q = '\0'; + return prog; +} + +#elif defined(OPENSSL_SYS_VMS) + +char *opt_progname(const char *argv0) +{ + const char *p, *q; + + /* Find last special charcter sys:[foo.bar]openssl */ + for (p = argv0 + strlen(argv0); --p > argv0;) + if (*p == ':' || *p == ']' || *p == '>') { + p++; + break; + } + + q = strrchr(p, '.'); + strncpy(prog, p, sizeof prog - 1); + prog[sizeof prog - 1] = '\0'; + if (q == NULL || q - p >= sizeof prog) + prog[q - p] = '\0'; + return prog; +} + +#else + +char *opt_progname(const char *argv0) +{ + const char *p; + + /* Could use strchr, but this is like the ones above. */ + for (p = argv0 + strlen(argv0); --p > argv0;) + if (*p == '/') { + p++; + break; + } + strncpy(prog, p, sizeof prog - 1); + prog[sizeof prog - 1] = '\0'; + return prog; +} +#endif + +char *opt_getprog(void) +{ + return prog; +} + +/* Set up the arg parsing. */ +char *opt_init(int ac, char **av, const OPTIONS *o) +{ + /* Store state. */ + argc = ac; + argv = av; + opt_index = 1; + opts = o; + opt_progname(av[0]); + unknown = NULL; + + for (; o->name; ++o) { + const OPTIONS *next; +#ifndef NDEBUG + int i; +#endif + + if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR) + continue; +#ifndef NDEBUG + i = o->valtype; + + /* Make sure options are legit. */ + assert(o->name[0] != '-'); + assert(o->retval > 0); + assert(i == 0 || i == '-' + || i == 'n' || i == 'p' || i == 'u' + || i == 's' || i == '<' || i == '>' || i == '/' + || i == 'f' || i == 'F'); + + /* Make sure there are no duplicates. */ + for (next = o; (++next)->name;) { + /* + * do allow aliases: assert(o->retval != next->retval); + */ + assert(strcmp(o->name, next->name) != 0); + } +#endif + if (o->name[0] == '\0') { + assert(unknown == NULL); + unknown = o; + assert(unknown->valtype == 0 || unknown->valtype == '-'); + } + } + return prog; +} + +static OPT_PAIR formats[] = { + {"PEM/DER", OPT_FMT_PEMDER}, + {"pkcs12", OPT_FMT_PKCS12}, + {"smime", OPT_FMT_SMIME}, + {"engine", OPT_FMT_ENGINE}, + {"msblob", OPT_FMT_MSBLOB}, + {"netscape", OPT_FMT_NETSCAPE}, + {"nss", OPT_FMT_NSS}, + {"text", OPT_FMT_TEXT}, + {"http", OPT_FMT_HTTP}, + {"pvk", OPT_FMT_PVK}, + {NULL} +}; + +/* Print an error message about a failed format parse. */ +int opt_format_error(const char *s, unsigned long flags) +{ + OPT_PAIR *ap; + + if (flags == OPT_FMT_PEMDER) + BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n", + prog, s); + else { + BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n", + prog, s); + for (ap = formats; ap->name; ap++) + if (flags & ap->retval) + BIO_printf(bio_err, " %s\n", ap->name); + } + return 0; +} + +/* Parse a format string, put it into *result; return 0 on failure, else 1. */ +int opt_format(const char *s, unsigned long flags, int *result) +{ + switch (*s) { + default: + return 0; + case 'D': + case 'd': + if ((flags & OPT_FMT_PEMDER) == 0) + return opt_format_error(s, flags); + *result = FORMAT_ASN1; + break; + case 'T': + case 't': + if ((flags & OPT_FMT_TEXT) == 0) + return opt_format_error(s, flags); + *result = FORMAT_TEXT; + break; + case 'N': + case 'n': + if (strcmp(s, "NSS") == 0 || strcmp(s, "nss") == 0) { + if ((flags & OPT_FMT_NSS) == 0) + return opt_format_error(s, flags); + *result = FORMAT_NSS; + } else { + if ((flags & OPT_FMT_NETSCAPE) == 0) + return opt_format_error(s, flags); + *result = FORMAT_NETSCAPE; + } + break; + case 'S': + case 's': + if ((flags & OPT_FMT_SMIME) == 0) + return opt_format_error(s, flags); + *result = FORMAT_SMIME; + break; + case 'M': + case 'm': + if ((flags & OPT_FMT_MSBLOB) == 0) + return opt_format_error(s, flags); + *result = FORMAT_MSBLOB; + break; + case 'E': + case 'e': + if ((flags & OPT_FMT_ENGINE) == 0) + return opt_format_error(s, flags); + *result = FORMAT_ENGINE; + break; + case 'H': + case 'h': + if ((flags & OPT_FMT_HTTP) == 0) + return opt_format_error(s, flags); + *result = FORMAT_HTTP; + break; + case '1': + if ((flags & OPT_FMT_PKCS12) == 0) + return opt_format_error(s, flags); + *result = FORMAT_PKCS12; + break; + case 'P': + case 'p': + if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) { + if ((flags & OPT_FMT_PEMDER) == 0) + return opt_format_error(s, flags); + *result = FORMAT_PEM; + } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) { + if ((flags & OPT_FMT_PVK) == 0) + return opt_format_error(s, flags); + *result = FORMAT_PVK; + } else if (strcmp(s, "P12") == 0 || strcmp(s, "p12") == 0 + || strcmp(s, "PKCS12") == 0 || strcmp(s, "pkcs12") == 0) { + if ((flags & OPT_FMT_PKCS12) == 0) + return opt_format_error(s, flags); + *result = FORMAT_PKCS12; + } else + return 0; + break; + } + return 1; +} + +/* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */ +int opt_cipher(const char *name, const EVP_CIPHER **cipherp) +{ + *cipherp = EVP_get_cipherbyname(name); + if (*cipherp) + return 1; + BIO_printf(bio_err, "%s: Unknown cipher %s\n", prog, name); + return 0; +} + +/* + * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1. + */ +int opt_md(const char *name, const EVP_MD **mdp) +{ + *mdp = EVP_get_digestbyname(name); + if (*mdp) + return 1; + BIO_printf(bio_err, "%s: Unknown digest %s\n", prog, name); + return 0; +} + +/* Look through a list of name/value pairs. */ +int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) +{ + const OPT_PAIR *pp; + + for (pp = pairs; pp->name; pp++) + if (strcmp(pp->name, name) == 0) { + *result = pp->retval; + return 1; + } + BIO_printf(bio_err, "%s: Value must be one of:\n", prog); + for (pp = pairs; pp->name; pp++) + BIO_printf(bio_err, "\t%s\n", pp->name); + return 0; +} + +/* See if cp looks like a hex number, in case user left off the 0x */ +static int scanforhex(const char *cp) +{ + if (*cp == '0' && (cp[1] == 'x' || cp[1] == 'X')) + return 16; + for (; *cp; cp++) + /* Look for a hex digit that isn't a regular digit. */ + if (isxdigit(*cp) && !isdigit(*cp)) + return 16; + return 0; +} + +/* Parse an int, put it into *result; return 0 on failure, else 1. */ +int opt_int(const char *value, int *result) +{ + const char *fmt = "%d"; + int base = scanforhex(value); + + if (base == 16) + fmt = "%x"; + else if (*value == '0') + fmt = "%o"; + if (sscanf(value, fmt, result) != 1) { + BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", + prog, value); + return 0; + } + return 1; +} + +/* Parse a long, put it into *result; return 0 on failure, else 1. */ +int opt_long(const char *value, long *result) +{ + char *endptr; + int base = scanforhex(value); + + *result = strtol(value, &endptr, base); + if (*endptr) { + BIO_printf(bio_err, + "%s: Bad char %c in number %s\n", prog, *endptr, value); + return 0; + } + return 1; +} + +/* + * Parse an unsigned long, put it into *result; return 0 on failure, else 1. + */ +int opt_ulong(const char *value, unsigned long *result) +{ + char *endptr; + int base = scanforhex(value); + + *result = strtoul(value, &endptr, base); + if (*endptr) { + BIO_printf(bio_err, + "%s: Bad char %c in number %s\n", prog, *endptr, value); + return 0; + } + return 1; +} + +/* + * We pass opt as an int but cast it to "enum range" so that all the + * items in the OPT_V_ENUM enumeration are caught; this makes -Wswitch + * in gcc do the right thing. + */ +enum range { OPT_V_ENUM }; + +int opt_verify(int opt, X509_VERIFY_PARAM *vpm) +{ + unsigned long ul; + int i; + ASN1_OBJECT *otmp; + X509_PURPOSE *xptmp; + const X509_VERIFY_PARAM *vtmp; + + assert(vpm != NULL); + assert(opt > OPT_V__FIRST); + assert(opt < OPT_V__LAST); + + switch ((enum range)opt) { + case OPT_V__FIRST: + case OPT_V__LAST: + return 0; + case OPT_V_POLICY: + otmp = OBJ_txt2obj(opt_arg(), 0); + if (otmp == NULL) { + BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); + return 0; + } + X509_VERIFY_PARAM_add0_policy(vpm, otmp); + break; + case OPT_V_PURPOSE: + i = X509_PURPOSE_get_by_sname(opt_arg()); + if (i < 0) { + BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); + return 0; + } + xptmp = X509_PURPOSE_get0(i); + i = X509_PURPOSE_get_id(xptmp); + X509_VERIFY_PARAM_set_purpose(vpm, i); + break; + case OPT_V_VERIFY_NAME: + vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); + if (vtmp == NULL) { + BIO_printf(bio_err, "%s: Invalid verify name %s\n", + prog, opt_arg()); + return 0; + } + X509_VERIFY_PARAM_set1(vpm, vtmp); + break; + case OPT_V_VERIFY_DEPTH: + i = atoi(opt_arg()); + if (i >= 0) + X509_VERIFY_PARAM_set_depth(vpm, i); + break; + case OPT_V_ATTIME: + opt_ulong(opt_arg(), &ul); + if (ul) + X509_VERIFY_PARAM_set_time(vpm, (time_t)ul); + break; + case OPT_V_VERIFY_HOSTNAME: + if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) + return 0; + break; + case OPT_V_VERIFY_EMAIL: + if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) + return 0; + break; + case OPT_V_VERIFY_IP: + if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) + return 0; + break; + case OPT_V_IGNORE_CRITICAL: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); + break; + case OPT_V_ISSUER_CHECKS: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CB_ISSUER_CHECK); + break; + case OPT_V_CRL_CHECK: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); + break; + case OPT_V_CRL_CHECK_ALL: + X509_VERIFY_PARAM_set_flags(vpm, + X509_V_FLAG_CRL_CHECK | + X509_V_FLAG_CRL_CHECK_ALL); + break; + case OPT_V_POLICY_CHECK: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); + break; + case OPT_V_EXPLICIT_POLICY: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); + break; + case OPT_V_INHIBIT_ANY: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); + break; + case OPT_V_INHIBIT_MAP: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); + break; + case OPT_V_X509_STRICT: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); + break; + case OPT_V_EXTENDED_CRL: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); + break; + case OPT_V_USE_DELTAS: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); + break; + case OPT_V_POLICY_PRINT: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); + break; + case OPT_V_CHECK_SS_SIG: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); + break; + case OPT_V_TRUSTED_FIRST: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); + break; + case OPT_V_SUITEB_128_ONLY: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); + break; + case OPT_V_SUITEB_128: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); + break; + case OPT_V_SUITEB_192: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); + break; + case OPT_V_PARTIAL_CHAIN: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); + break; + case OPT_V_NO_ALT_CHAINS: + X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); + } + return 1; + +} + +/* + * Parse the next flag (and value if specified), return 0 if done, -1 on + * error, otherwise the flag's retval. + */ +int opt_next(void) +{ + char *p; + char *endptr; + const OPTIONS *o; + int dummy; + int base; + long val; + + /* Look at current arg; at end of the list? */ + arg = NULL; + p = argv[opt_index]; + if (p == NULL) + return 0; + + /* If word doesn't start with a -, we're done. */ + if (*p != '-') + return 0; + + /* Hit "--" ? We're done. */ + opt_index++; + if (strcmp(p, "--") == 0) + return 0; + + /* Allow -nnn and --nnn */ + if (*++p == '-') + p++; + flag = p - 1; + + /* If we have --flag=foo, snip it off */ + if ((arg = strchr(p, '=')) != NULL) + *arg++ = '\0'; + for (o = opts; o->name; ++o) { + /* If not this option, move on to the next one. */ + if (strcmp(p, o->name) != 0) + continue; + + /* If it doesn't take a value, make sure none was given. */ + if (o->valtype == 0 || o->valtype == '-') { + if (arg) { + BIO_printf(bio_err, + "%s: Option -%s does not take a value\n", prog, p); + return -1; + } + return o->retval; + } + + /* Want a value; get the next param if =foo not used. */ + if (arg == NULL) { + if (argv[opt_index] == NULL) { + BIO_printf(bio_err, + "%s: Option -%s needs a value\n", prog, o->name); + return -1; + } + arg = argv[opt_index++]; + } + + /* Syntax-check value. */ + /* + * Do some basic syntax-checking on the value. These tests aren't + * perfect (ignore range overflow) but they catch common failures. + */ + switch (o->valtype) { + default: + case 's': + /* Just a string. */ + break; + case '/': + if (app_isdir(arg) >= 0) + break; + BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg); + return -1; + case '<': + /* Input file. */ + if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0) + break; + BIO_printf(bio_err, + "%s: Cannot open input file %s, %s\n", + prog, arg, strerror(errno)); + return -1; + case '>': + /* Output file. */ + if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT) + break; + BIO_printf(bio_err, + "%s: Cannot open output file %s, %s\n", + prog, arg, strerror(errno)); + return -1; + case 'p': + case 'n': + base = scanforhex(arg); + val = strtol(arg, &endptr, base); + if (*endptr == '\0') { + if (o->valtype == 'p' && val <= 0) { + BIO_printf(bio_err, + "%s: Non-positive number \"%s\" for -%s\n", + prog, arg, o->name); + return -1; + } + break; + } + BIO_printf(bio_err, + "%s: Invalid number \"%s\" for -%s\n", + prog, arg, o->name); + return -1; + case 'u': + base = scanforhex(arg); + strtoul(arg, &endptr, base); + if (*endptr == '\0') + break; + BIO_printf(bio_err, + "%s: Invalid number \"%s\" for -%s\n", + prog, arg, o->name); + return -1; + case 'f': + case 'F': + if (opt_format(arg, + o->valtype == 'F' ? OPT_FMT_PEMDER + : OPT_FMT_ANY, &dummy)) + break; + BIO_printf(bio_err, + "%s: Invalid format \"%s\" for -%s\n", + prog, arg, o->name); + return -1; + } + + /* Return the flag value. */ + return o->retval; + } + if (unknown != NULL) { + dunno = p; + return unknown->retval; + } + BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p); + return -1; +} + +/* Return the most recent flag parameter. */ +char *opt_arg(void) +{ + return arg; +} + +/* Return the most recent flag. */ +char *opt_flag(void) +{ + return flag; +} + +/* Return the unknown option. */ +char *opt_unknown(void) +{ + return dunno; +} + +/* Return the rest of the arguments after parsing flags. */ +char **opt_rest(void) +{ + return &argv[opt_index]; +} + +/* How many items in remaining args? */ +int opt_num_rest(void) +{ + int i = 0; + char **pp; + + for (pp = opt_rest(); *pp; pp++, i++) + continue; + return i; +} + +/* Return a string describing the parameter type. */ +static const char *valtype2param(const OPTIONS *o) +{ + switch (o->valtype) { + case '-': + return ""; + case 's': + return "val"; + case '/': + return "dir"; + case '<': + return "infile"; + case '>': + return "outfile"; + case 'p': + return "pnum"; + case 'n': + return "num"; + case 'u': + return "unum"; + case 'F': + return "der/pem"; + case 'f': + return "format"; + } + return "parm"; +} + +void opt_help(const OPTIONS *list) +{ + const OPTIONS *o; + int i; + int standard_prolog; + int width = 5; + char start[80 + 1]; + char *p; + const char *help; + + /* Starts with its own help message? */ + standard_prolog = list[0].name != OPT_HELP_STR; + + /* Find the widest help. */ + for (o = list; o->name; o++) { + if (o->name == OPT_MORE_STR) + continue; + i = 2 + (int)strlen(o->name); + if (o->valtype != '-') + i += 1 + strlen(valtype2param(o)); + if (i < MAX_OPT_HELP_WIDTH && i > width) + width = i; + assert(i < (int)sizeof start); + } + + if (standard_prolog) + BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n", + prog); + + /* Now let's print. */ + for (o = list; o->name; o++) { + help = o->helpstr ? o->helpstr : "(No additional info)"; + if (o->name == OPT_HELP_STR) { + BIO_printf(bio_err, help, prog); + continue; + } + + /* Pad out prefix */ + memset(start, ' ', sizeof start - 1); + start[sizeof start - 1] = '\0'; + + if (o->name == OPT_MORE_STR) { + /* Continuation of previous line; padd and print. */ + start[width] = '\0'; + BIO_printf(bio_err, "%s %s\n", start, help); + continue; + } + + /* Build up the "-flag [param]" part. */ + p = start; + *p++ = ' '; + *p++ = '-'; + if (o->name[0]) + p += strlen(strcpy(p, o->name)); + else + *p++ = '*'; + if (o->valtype != '-') { + *p++ = ' '; + p += strlen(strcpy(p, valtype2param(o))); + } + *p = ' '; + if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) { + *p = '\0'; + BIO_printf(bio_err, "%s\n", start); + memset(start, ' ', sizeof start); + } + start[width] = '\0'; + BIO_printf(bio_err, "%s %s\n", start, help); + } +} + +#ifdef COMPILE_STANDALONE_TEST_DRIVER +# include + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_IN, OPT_INFORM, OPT_OUT, OPT_COUNT, OPT_U, OPT_FLAG, + OPT_STR, OPT_NOTUSED +} OPTION_CHOICE; + +static OPTIONS options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s flags\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "input file"}, + {OPT_MORE_STR, 1, '-', "more detail about input"}, + {"inform", OPT_INFORM, 'f', "input file format; defaults to pem"}, + {"out", OPT_OUT, '>', "output file"}, + {"count", OPT_COUNT, 'p', "a counter greater than zero"}, + {"u", OPT_U, 'u', "an unsigned number"}, + {"flag", OPT_FLAG, 0, "just some flag"}, + {"str", OPT_STR, 's', "the magic word"}, + {"areallyverylongoption", OPT_HELP, '-', "long way for help"}, + {NULL} +}; + +BIO *bio_err; + +int app_isdir(const char *name) +{ + struct stat sb; + + return name != NULL && stat(name, &sb) >= 0 && S_ISDIR(sb.st_mode); +} + +int main(int ac, char **av) +{ + OPTION_CHOICE o; + char **rest; + char *prog; + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + + prog = opt_init(ac, av, options); + while ((o = opt_next()) != OPT_EOF) { + switch (c) { + case OPT_NOTUSED: + case OPT_EOF: + case OPT_ERR: + printf("%s: Usage error; try -help.\n", prog); + return 1; + case OPT_HELP: + opt_help(options); + return 0; + case OPT_IN: + printf("in %s\n", opt_arg()); + break; + case OPT_INFORM: + printf("inform %s\n", opt_arg()); + break; + case OPT_OUT: + printf("out %s\n", opt_arg()); + break; + case OPT_COUNT: + printf("count %s\n", opt_arg()); + break; + case OPT_U: + printf("u %s\n", opt_arg()); + break; + case OPT_FLAG: + printf("flag\n"); + break; + case OPT_STR: + printf("str %s\n", opt_arg()); + break; + } + } + argc = opt_num_rest(); + argv = opt_rest(); + + printf("args = %d\n", argc); + if (argc) + while (*argv) + printf(" %s\n", *argv++); + return 0; +} +#endif diff --git a/apps/passwd.c b/apps/passwd.c index 2814b32c75..3c6fd5204e 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -1,4 +1,51 @@ -/* apps/passwd.c */ +/* ==================================================================== + * Copyright (c) 2000-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 + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ #if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC # define NO_MD5CRYPT_1 @@ -22,9 +69,6 @@ # include # endif -# undef PROG -# define PROG passwd_main - static unsigned const char cov_2char[64] = { /* from crypto/des/fcrypt.c */ 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, @@ -42,156 +86,130 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, int reverse, size_t pw_maxlen, int usecrypt, int use1, int useapr1); -/*- - * -crypt - standard Unix password algorithm (default) - * -1 - MD5-based password algorithm - * -apr1 - MD5-based password algorithm, Apache variant - * -salt string - salt - * -in file - read passwords from file - * -stdin - read passwords from stdin - * -noverify - never verify when reading password from terminal - * -quiet - no warnings - * -table - format output as table - * -reverse - switch table columns - */ - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_IN, + OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1, + OPT_1, OPT_CRYPT, OPT_SALT, OPT_STDIN +} OPTION_CHOICE; + +OPTIONS passwd_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Pead passwords from file"}, + {"noverify", OPT_NOVERIFY, '-', + "Never verify when reading password from terminal"}, + {"quiet", OPT_QUIET, '-', "No warnings"}, + {"table", OPT_TABLE, '-', "Format output as table"}, + {"reverse", OPT_REVERSE, '-', "Switch table columns"}, +# ifndef NO_MD5CRYPT_1 + {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"}, + {"1", OPT_1, '-', "MD5-based password algorithm"}, +# endif +# ifndef OPENSSL_NO_DES + {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"}, +# endif + {"salt", OPT_SALT, 's', "Use provided salt"}, + {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int passwd_main(int argc, char **argv) { - int ret = 1; - char *infile = NULL; - int in_stdin = 0; - int in_noverify = 0; - char *salt = NULL, *passwd = NULL, **passwds = NULL; - char *salt_malloc = NULL, *passwd_malloc = NULL; - size_t passwd_malloc_size = 0; - int pw_source_defined = 0; - BIO *in = NULL, *out = NULL; - int i, badopt, opt_done; + BIO *in = NULL; + char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL; + char *salt_malloc = NULL, *passwd_malloc = NULL, *prog; + OPTION_CHOICE o; + int in_stdin = 0, in_noverify = 0, pw_source_defined = 0; int passed_salt = 0, quiet = 0, table = 0, reverse = 0; - int usecrypt = 0, use1 = 0, useapr1 = 0; - size_t pw_maxlen = 0; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto err; - out = BIO_new(BIO_s_file()); - if (out == NULL) - goto err; - BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - - badopt = 0, opt_done = 0; - i = 0; - while (!badopt && !opt_done && argv[++i] != NULL) { - if (strcmp(argv[i], "-crypt") == 0) - usecrypt = 1; - else if (strcmp(argv[i], "-1") == 0) - use1 = 1; - else if (strcmp(argv[i], "-apr1") == 0) - useapr1 = 1; - else if (strcmp(argv[i], "-salt") == 0) { - if ((argv[i + 1] != NULL) && (salt == NULL)) { - passed_salt = 1; - salt = argv[++i]; - } else - badopt = 1; - } else if (strcmp(argv[i], "-in") == 0) { - if ((argv[i + 1] != NULL) && !pw_source_defined) { - pw_source_defined = 1; - infile = argv[++i]; - } else - badopt = 1; - } else if (strcmp(argv[i], "-stdin") == 0) { - if (!pw_source_defined) { - pw_source_defined = 1; - in_stdin = 1; - } else - badopt = 1; - } else if (strcmp(argv[i], "-noverify") == 0) + int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0; + size_t passwd_malloc_size = 0, pw_maxlen = 256; + + prog = opt_init(argc, argv, passwd_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(passwd_options); + ret = 0; + goto end; + case OPT_IN: + if (pw_source_defined) + goto opthelp; + infile = opt_arg(); + pw_source_defined = 1; + break; + case OPT_NOVERIFY: in_noverify = 1; - else if (strcmp(argv[i], "-quiet") == 0) + break; + case OPT_QUIET: quiet = 1; - else if (strcmp(argv[i], "-table") == 0) + break; + case OPT_TABLE: table = 1; - else if (strcmp(argv[i], "-reverse") == 0) + break; + case OPT_REVERSE: reverse = 1; - else if (argv[i][0] == '-') - badopt = 1; - else if (!pw_source_defined) - /* non-option arguments, use as passwords */ - { - pw_source_defined = 1; - passwds = &argv[i]; - opt_done = 1; - } else - badopt = 1; + break; + case OPT_1: + use1 = 1; + break; + case OPT_APR1: + useapr1 = 1; + break; + case OPT_CRYPT: + usecrypt = 1; + break; + case OPT_SALT: + passed_salt = 1; + salt = opt_arg(); + break; + case OPT_STDIN: + if (pw_source_defined) + goto opthelp; + in_stdin = 1; + break; + } + } + argc = opt_num_rest(); + argv = opt_rest(); + + if (*argv) { + if (pw_source_defined) + goto opthelp; + pw_source_defined = 1; + passwds = argv; } - if (!usecrypt && !use1 && !useapr1) /* use default */ + if (!usecrypt && !use1 && !useapr1) { + /* use default */ usecrypt = 1; - if (usecrypt + use1 + useapr1 > 1) /* conflict */ - badopt = 1; + } + if (usecrypt + use1 + useapr1 > 1) { + /* conflict */ + goto opthelp; + } - /* reject unsupported algorithms */ # ifdef OPENSSL_NO_DES if (usecrypt) - badopt = 1; + goto opthelp; # endif # ifdef NO_MD5CRYPT_1 if (use1 || useapr1) - badopt = 1; + goto opthelp; # endif - if (badopt) { - BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n"); - BIO_printf(bio_err, "where options are\n"); -# ifndef OPENSSL_NO_DES - BIO_printf(bio_err, - "-crypt standard Unix password algorithm (default)\n"); -# endif -# ifndef NO_MD5CRYPT_1 - BIO_printf(bio_err, - "-1 MD5-based password algorithm\n"); - BIO_printf(bio_err, - "-apr1 MD5-based password algorithm, Apache variant\n"); -# endif - BIO_printf(bio_err, "-salt string use provided salt\n"); - BIO_printf(bio_err, "-in file read passwords from file\n"); - BIO_printf(bio_err, "-stdin read passwords from stdin\n"); - BIO_printf(bio_err, - "-noverify never verify when reading password from terminal\n"); - BIO_printf(bio_err, "-quiet no warnings\n"); - BIO_printf(bio_err, "-table format output as table\n"); - BIO_printf(bio_err, "-reverse switch table columns\n"); - - goto err; + if (infile && in_stdin) { + BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog); + goto end; } - if ((infile != NULL) || in_stdin) { - in = BIO_new(BIO_s_file()); - if (in == NULL) - goto err; - if (infile != NULL) { - assert(in_stdin == 0); - if (BIO_read_filename(in, infile) <= 0) - goto err; - } else { - assert(in_stdin); - BIO_set_fp(in, stdin, BIO_NOCLOSE); - } - } + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; if (usecrypt) pw_maxlen = 8; @@ -208,7 +226,7 @@ int MAIN(int argc, char **argv) */ passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size); if (passwd_malloc == NULL) - goto err; + goto end; } if ((in == NULL) && (passwds == NULL)) { @@ -220,7 +238,7 @@ int MAIN(int argc, char **argv) if (EVP_read_pw_string (passwd_malloc, passwd_malloc_size, "Password: ", !(passed_salt || in_noverify)) != 0) - goto err; + goto end; passwds[0] = passwd_malloc; } @@ -230,10 +248,10 @@ int MAIN(int argc, char **argv) do { /* loop over list of passwords */ passwd = *passwds++; - if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out, + if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1)) - goto err; + goto end; } while (*passwds != NULL); } else @@ -256,10 +274,10 @@ int MAIN(int argc, char **argv) while ((r > 0) && (!strchr(trash, '\n'))); } - if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out, - quiet, table, reverse, pw_maxlen, usecrypt, - use1, useapr1)) - goto err; + if (!do_passwd + (passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet, + table, reverse, pw_maxlen, usecrypt, use1, useapr1)) + goto end; } done = (r <= 0); } @@ -267,16 +285,14 @@ int MAIN(int argc, char **argv) } ret = 0; - err: + end: ERR_print_errors(bio_err); if (salt_malloc) OPENSSL_free(salt_malloc); if (passwd_malloc) OPENSSL_free(passwd_malloc); BIO_free(in); - BIO_free_all(out); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } # ifndef NO_MD5CRYPT_1 @@ -412,10 +428,10 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, if (*salt_malloc_p == NULL) { *salt_p = *salt_malloc_p = OPENSSL_malloc(3); if (*salt_malloc_p == NULL) - goto err; + goto end; } if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0) - goto err; + goto end; (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */ (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */ (*salt_p)[2] = 0; @@ -433,10 +449,10 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, if (*salt_malloc_p == NULL) { *salt_p = *salt_malloc_p = OPENSSL_malloc(9); if (*salt_malloc_p == NULL) - goto err; + goto end; } if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0) - goto err; + goto end; for (i = 0; i < 8; i++) (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ @@ -477,16 +493,16 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, BIO_printf(out, "%s\t%s\n", hash, passwd); else BIO_printf(out, "%s\n", hash); - return 1; - - err: return 0; + + end: + return 1; } #else -int MAIN(int argc, char **argv) +int passwd_main(int argc, char **argv) { fputs("Program not available.\n", stderr) - OPENSSL_EXIT(1); + return (1); } #endif diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 43892e5798..a031c1ba25 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -1,4 +1,3 @@ -/* pkcs12.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -69,10 +68,6 @@ # include # include -# define PROG pkcs12_main - -const EVP_CIPHER *enc; - # define NOKEYS 0x1 # define NOCERTS 0x2 # define INFO 0x4 @@ -81,335 +76,257 @@ const EVP_CIPHER *enc; int get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain); int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, - int options, char *pempass); + int options, char *pempass, const EVP_CIPHER *enc); int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, - char *pass, int passlen, int options, - char *pempass); + char *pass, int passlen, int options, char *pempass, + const EVP_CIPHER *enc); int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, - int passlen, int options, char *pempass); + int passlen, int options, char *pempass, + const EVP_CIPHER *enc); int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); int alg_print(BIO *x, X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); -static int set_pbe(BIO *err, int *ppbe, const char *str); - -int MAIN(int, char **); +static int set_pbe(int *ppbe, const char *str); + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS, + OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER, + OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, + OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, + OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, + OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, + OPT_CAFILE, OPT_ENGINE +} OPTION_CHOICE; + +OPTIONS pkcs12_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, + {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, + {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, + {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"}, + {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, + {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, + {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"}, + {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, + {"chain", OPT_CHAIN, '-', "Add certificate chain"}, + {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, + {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, +# ifndef OPENSSL_NO_RC2 + {"descert", OPT_DESCERT, '-', + "Encrypt output with 3DES (default RC2-40)"}, + {"certpbe", OPT_CERTPBE, 's', + "Certificate PBE algorithm (default RC2-40)"}, +# else + {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, + {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, +# endif + {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, + {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, + {"maciter", OPT_MACITER, '-', "Use MAC iteration"}, + {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"}, + {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, + {"LMK", OPT_LMK, '-', + "Add local machine keyset attribute to private key"}, + {"nodes", OPT_NODES, '-', "Don't encrypt private keys"}, + {"macalg", OPT_MACALG, 's', + "Digest algorithm used in MAC (default SHA1)"}, + {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"inkey", OPT_INKEY, '<', "Private key if not infile"}, + {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, + {"name", OPT_NAME, 's', "Use name as friendly name"}, + {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, + {"caname", OPT_CANAME, 's', + "Use name as CA friendly name (can be repeated)"}, + {"in", OPT_IN, '<', "Input filename"}, + {"out", OPT_OUT, '>', "Output filename"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"password", OPT_PASSWORD, 's', "Set import/export password source"}, + {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {"", OPT_CIPHER, '-', "Any supported cipher"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int pkcs12_main(int argc, char **argv) { - ENGINE *e = NULL; - char *infile = NULL, *outfile = NULL, *keyname = NULL; - char *certfile = NULL; - BIO *in = NULL, *out = NULL; - char **args; - char *name = NULL; - char *csp_name = NULL; - int add_lmk = 0; - PKCS12 *p12 = NULL; + char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; + char *name = NULL, *csp_name = NULL; char pass[50], macpass[50]; - int export_cert = 0; - int options = 0; - int chain = 0; - int badarg = 0; - int iter = PKCS12_DEFAULT_ITER; - int maciter = PKCS12_DEFAULT_ITER; - int twopass = 0; - int keytype = 0; + int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; + int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; +# ifndef OPENSSL_NO_RC2 int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; +# else + int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +# endif int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - int ret = 1; - int macver = 1; - int noprompt = 0; + int ret = 1, macver = 1, noprompt = 0, add_lmk = 0; + char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; + char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL; + char *cpass = NULL, *mpass = NULL, *CApath = NULL, *CAfile = NULL; + char *engine = NULL, *prog; + ENGINE *e = NULL; + BIO *in = NULL, *out = NULL; + PKCS12 *p12 = NULL; STACK_OF(OPENSSL_STRING) *canames = NULL; - char *cpass = NULL, *mpass = NULL; - char *passargin = NULL, *passargout = NULL, *passarg = NULL; - char *passin = NULL, *passout = NULL; - char *inrand = NULL; - char *macalg = NULL; - char *CApath = NULL, *CAfile = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - - apps_startup(); - - enc = EVP_des_ede3_cbc(); - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - args = argv + 1; - - while (*args) { - if (*args[0] == '-') { - if (!strcmp(*args, "-nokeys")) - options |= NOKEYS; - else if (!strcmp(*args, "-keyex")) - keytype = KEY_EX; - else if (!strcmp(*args, "-keysig")) - keytype = KEY_SIG; - else if (!strcmp(*args, "-nocerts")) - options |= NOCERTS; - else if (!strcmp(*args, "-clcerts")) - options |= CLCERTS; - else if (!strcmp(*args, "-cacerts")) - options |= CACERTS; - else if (!strcmp(*args, "-noout")) - options |= (NOKEYS | NOCERTS); - else if (!strcmp(*args, "-info")) - options |= INFO; - else if (!strcmp(*args, "-chain")) - chain = 1; - else if (!strcmp(*args, "-twopass")) - twopass = 1; - else if (!strcmp(*args, "-nomacver")) - macver = 0; - else if (!strcmp(*args, "-descert")) - cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - else if (!strcmp(*args, "-export")) - export_cert = 1; - else if (!strcmp(*args, "-des")) - enc = EVP_des_cbc(); - else if (!strcmp(*args, "-des3")) - enc = EVP_des_ede3_cbc(); -# ifndef OPENSSL_NO_IDEA - else if (!strcmp(*args, "-idea")) - enc = EVP_idea_cbc(); -# endif -# ifndef OPENSSL_NO_SEED - else if (!strcmp(*args, "-seed")) - enc = EVP_seed_cbc(); -# endif -# ifndef OPENSSL_NO_AES - else if (!strcmp(*args, "-aes128")) - enc = EVP_aes_128_cbc(); - else if (!strcmp(*args, "-aes192")) - enc = EVP_aes_192_cbc(); - else if (!strcmp(*args, "-aes256")) - enc = EVP_aes_256_cbc(); -# endif -# ifndef OPENSSL_NO_CAMELLIA - else if (!strcmp(*args, "-camellia128")) - enc = EVP_camellia_128_cbc(); - else if (!strcmp(*args, "-camellia192")) - enc = EVP_camellia_192_cbc(); - else if (!strcmp(*args, "-camellia256")) - enc = EVP_camellia_256_cbc(); -# endif - else if (!strcmp(*args, "-noiter")) - iter = 1; - else if (!strcmp(*args, "-maciter")) - maciter = PKCS12_DEFAULT_ITER; - else if (!strcmp(*args, "-nomaciter")) - maciter = 1; - else if (!strcmp(*args, "-nomac")) - maciter = -1; - else if (!strcmp(*args, "-macalg")) - if (args[1]) { - args++; - macalg = *args; - } else - badarg = 1; - else if (!strcmp(*args, "-nodes")) - enc = NULL; - else if (!strcmp(*args, "-certpbe")) { - if (!set_pbe(bio_err, &cert_pbe, *++args)) - badarg = 1; - } else if (!strcmp(*args, "-keypbe")) { - if (!set_pbe(bio_err, &key_pbe, *++args)) - badarg = 1; - } else if (!strcmp(*args, "-rand")) { - if (args[1]) { - args++; - inrand = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-inkey")) { - if (args[1]) { - args++; - keyname = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-certfile")) { - if (args[1]) { - args++; - certfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-name")) { - if (args[1]) { - args++; - name = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-LMK")) - add_lmk = 1; - else if (!strcmp(*args, "-CSP")) { - if (args[1]) { - args++; - csp_name = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-caname")) { - if (args[1]) { - args++; - if (!canames) - canames = sk_OPENSSL_STRING_new_null(); - sk_OPENSSL_STRING_push(canames, *args); - } else - badarg = 1; - } else if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-passin")) { - if (args[1]) { - args++; - passargin = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-passout")) { - if (args[1]) { - args++; - passargout = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-password")) { - if (args[1]) { - args++; - passarg = *args; - noprompt = 1; - } else - badarg = 1; - } else if (!strcmp(*args, "-CApath")) { - if (args[1]) { - args++; - CApath = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-CAfile")) { - if (args[1]) { - args++; - CAfile = *args; - } else - badarg = 1; -# ifndef OPENSSL_NO_ENGINE - } else if (!strcmp(*args, "-engine")) { - if (args[1]) { - args++; - engine = *args; - } else - badarg = 1; -# endif - } else - badarg = 1; - - } else - badarg = 1; - args++; + const EVP_CIPHER *enc = EVP_des_ede3_cbc(); + OPTION_CHOICE o; + + prog = opt_init(argc, argv, pkcs12_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkcs12_options); + ret = 0; + goto end; + case OPT_NOKEYS: + options |= NOKEYS; + break; + case OPT_KEYEX: + keytype = KEY_EX; + break; + case OPT_KEYSIG: + keytype = KEY_SIG; + break; + case OPT_NOCERTS: + options |= NOCERTS; + break; + case OPT_CLCERTS: + options |= CLCERTS; + break; + case OPT_CACERTS: + options |= CACERTS; + break; + case OPT_NOOUT: + options |= (NOKEYS | NOCERTS); + break; + case OPT_INFO: + options |= INFO; + break; + case OPT_CHAIN: + chain = 1; + break; + case OPT_TWOPASS: + twopass = 1; + break; + case OPT_NOMACVER: + macver = 0; + break; + case OPT_DESCERT: + cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + break; + case OPT_EXPORT: + export_cert = 1; + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto opthelp; + break; + case OPT_NOITER: + iter = 1; + break; + case OPT_MACITER: + maciter = PKCS12_DEFAULT_ITER; + break; + case OPT_NOMACITER: + maciter = 1; + break; + case OPT_NOMAC: + maciter = -1; + break; + case OPT_MACALG: + macalg = opt_arg(); + break; + case OPT_NODES: + enc = NULL; + break; + case OPT_CERTPBE: + if (!set_pbe(&cert_pbe, opt_arg())) + goto opthelp; + break; + case OPT_KEYPBE: + if (!set_pbe(&key_pbe, opt_arg())) + goto opthelp; + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_INKEY: + keyname = opt_arg(); + break; + case OPT_CERTFILE: + certfile = opt_arg(); + break; + case OPT_NAME: + name = opt_arg(); + break; + case OPT_LMK: + add_lmk = 1; + break; + case OPT_CSP: + csp_name = opt_arg(); + break; + case OPT_CANAME: + if (canames == NULL + && (canames = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; + sk_OPENSSL_STRING_push(canames, opt_arg()); + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_PASSWORD: + passarg = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); - if (badarg) { - BIO_printf(bio_err, "Usage: pkcs12 [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-export output PKCS12 file\n"); - BIO_printf(bio_err, "-chain add certificate chain\n"); - BIO_printf(bio_err, "-inkey file private key if not infile\n"); - BIO_printf(bio_err, "-certfile f add all certs in f\n"); - BIO_printf(bio_err, "-CApath arg - PEM format directory of CA's\n"); - BIO_printf(bio_err, "-CAfile arg - PEM format file of CA's\n"); - BIO_printf(bio_err, "-name \"name\" use name as friendly name\n"); - BIO_printf(bio_err, - "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); - BIO_printf(bio_err, "-in infile input filename\n"); - BIO_printf(bio_err, "-out outfile output filename\n"); - BIO_printf(bio_err, - "-noout don't output anything, just verify.\n"); - BIO_printf(bio_err, "-nomacver don't verify MAC.\n"); - BIO_printf(bio_err, "-nocerts don't output certificates.\n"); - BIO_printf(bio_err, - "-clcerts only output client certificates.\n"); - BIO_printf(bio_err, "-cacerts only output CA certificates.\n"); - BIO_printf(bio_err, "-nokeys don't output private keys.\n"); - BIO_printf(bio_err, - "-info give info about PKCS#12 structure.\n"); - BIO_printf(bio_err, "-des encrypt private keys with DES\n"); - BIO_printf(bio_err, - "-des3 encrypt private keys with triple DES (default)\n"); -# ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, "-idea encrypt private keys with idea\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, "-seed encrypt private keys with seed\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif - BIO_printf(bio_err, "-nodes don't encrypt private keys\n"); - BIO_printf(bio_err, "-noiter don't use encryption iteration\n"); - BIO_printf(bio_err, "-nomaciter don't use MAC iteration\n"); - BIO_printf(bio_err, "-maciter use MAC iteration\n"); - BIO_printf(bio_err, "-nomac don't generate MAC\n"); - BIO_printf(bio_err, - "-twopass separate MAC, encryption passwords\n"); - BIO_printf(bio_err, - "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); - BIO_printf(bio_err, - "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); - BIO_printf(bio_err, - "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); - BIO_printf(bio_err, - "-macalg alg digest algorithm used in MAC (default SHA1)\n"); - BIO_printf(bio_err, "-keyex set MS key exchange type\n"); - BIO_printf(bio_err, "-keysig set MS key signature type\n"); - BIO_printf(bio_err, - "-password p set import/export password source\n"); - BIO_printf(bio_err, "-passin p input file pass phrase source\n"); - BIO_printf(bio_err, "-passout p output file pass phrase source\n"); # ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -# endif - BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, "-CSP name Microsoft CSP name\n"); - BIO_printf(bio_err, - "-LMK Add local machine keyset attribute to private key\n"); - goto end; - } -# ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); # endif if (passarg) { if (export_cert) - passargout = passarg; + passoutarg = passarg; else - passargin = passarg; + passinarg = passarg; } - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } @@ -430,60 +347,26 @@ int MAIN(int argc, char **argv) } if (export_cert || inrand) { - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } - ERR_load_crypto_strings(); - -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("read files"); -# endif - if (!infile) - in = BIO_new_fp(stdin, BIO_NOCLOSE); - else - in = BIO_new_file(infile, "rb"); - if (!in) { - BIO_printf(bio_err, "Error opening input file %s\n", - infile ? infile : ""); - perror(infile); + in = bio_open_default(infile, "rb"); + if (in == NULL) goto end; - } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("write files"); -# endif - if (!outfile) { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else - out = BIO_new_file(outfile, "wb"); - if (!out) { - BIO_printf(bio_err, "Error opening output file %s\n", - outfile ? outfile : ""); - perror(outfile); + out = bio_open_default(outfile, "wb"); + if (out == NULL) goto end; - } + if (twopass) { -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("read MAC password"); -# endif if (EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { BIO_printf(bio_err, "Can't read Password\n"); goto end; } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif } if (export_cert) { @@ -502,24 +385,16 @@ int MAIN(int argc, char **argv) if (options & NOCERTS) chain = 0; -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("process -export_cert"); - CRYPTO_push_info("reading private key"); -# endif if (!(options & NOKEYS)) { - key = load_key(bio_err, keyname ? keyname : infile, + key = load_key(keyname ? keyname : infile, FORMAT_PEM, 1, passin, e, "private key"); if (!key) goto export_end; } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("reading certs from input"); -# endif /* Load in all certs in input file */ if (!(options & NOCERTS)) { - certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, + certs = load_certs(infile, FORMAT_PEM, NULL, e, "certificates"); if (!certs) goto export_end; @@ -546,43 +421,25 @@ int MAIN(int argc, char **argv) } } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("reading certs from input 2"); -# endif /* Add any more certificates asked for */ if (certfile) { STACK_OF(X509) *morecerts = NULL; - if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, - NULL, e, + if (!(morecerts = load_certs(certfile, FORMAT_PEM, NULL, e, "certificates from certfile"))) goto export_end; while (sk_X509_num(morecerts) > 0) sk_X509_push(certs, sk_X509_shift(morecerts)); sk_X509_free(morecerts); } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("reading certs from certfile"); -# endif - -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("building chain"); -# endif /* If chaining get chain from user cert */ if (chain) { int vret; STACK_OF(X509) *chain2; - X509_STORE *store = X509_STORE_new(); - if (!store) { - BIO_printf(bio_err, "Memory allocation error\n"); + X509_STORE *store; + if (!(store = setup_verify(CAfile, CApath))) goto export_end; - } - if (!X509_STORE_load_locations(store, CAfile, CApath)) - X509_STORE_set_default_paths(store); vret = get_cert_chain(ucert, store, &chain2); X509_STORE_free(store); @@ -619,11 +476,6 @@ int MAIN(int argc, char **argv) if (add_lmk && key) EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("reading password"); -# endif - if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) { @@ -633,11 +485,6 @@ int MAIN(int argc, char **argv) if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("creating PKCS#12 structure"); -# endif - p12 = PKCS12_create(cpass, name, key, ucert, certs, key_pbe, cert_pbe, iter, -1, keytype); @@ -647,30 +494,18 @@ int MAIN(int argc, char **argv) } if (macalg) { - macmd = EVP_get_digestbyname(macalg); - if (!macmd) { - BIO_printf(bio_err, "Unknown digest algorithm %s\n", macalg); - } + if (!opt_md(macalg, &macmd)) + goto opthelp; } if (maciter != -1) PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_push_info("writing pkcs12"); -# endif - i2d_PKCS12_bio(out, p12); ret = 0; export_end: -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); - CRYPTO_pop_info(); - CRYPTO_push_info("process -export_cert: freeing"); -# endif EVP_PKEY_free(key); if (certs) @@ -678,9 +513,6 @@ int MAIN(int argc, char **argv) if (ucert) X509_free(ucert); -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif goto end; } @@ -689,18 +521,13 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("read import password"); -# endif + if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) { BIO_printf(bio_err, "Can't read Password\n"); goto end; } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); @@ -709,9 +536,6 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); if (macver) { -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("verify MAC"); -# endif /* If we enter empty password try no password first */ if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ @@ -722,30 +546,18 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - BIO_printf(bio_err, "MAC verified OK\n"); -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif } -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("output keys and certificates"); -# endif - if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) { + + if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors(bio_err); goto end; } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif ret = 0; end: PKCS12_free(p12); if (export_cert || inrand) - app_RAND_write_file(NULL, bio_err); -# ifdef CRYPTO_MDEBUG - CRYPTO_remove_all_info(); -# endif + app_RAND_write_file(NULL); BIO_free(in); BIO_free_all(out); if (canames) @@ -754,12 +566,12 @@ int MAIN(int argc, char **argv) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, - int passlen, int options, char *pempass) + int passlen, int options, char *pempass, + const EVP_CIPHER *enc) { STACK_OF(PKCS7) *asafes = NULL; STACK_OF(PKCS12_SAFEBAG) *bags; @@ -787,7 +599,7 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, if (!bags) goto err; if (!dump_certs_pkeys_bags(out, bags, pass, passlen, - options, pempass)) { + options, pempass, enc)) { sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); goto err; } @@ -802,20 +614,22 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, } int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, - char *pass, int passlen, int options, char *pempass) + char *pass, int passlen, int options, char *pempass, + const EVP_CIPHER *enc) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { if (!dump_certs_pkeys_bag(out, sk_PKCS12_SAFEBAG_value(bags, i), - pass, passlen, options, pempass)) + pass, passlen, options, pempass, enc)) return 0; } return 1; } int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, - int passlen, int options, char *pempass) + int passlen, int options, char *pempass, + const EVP_CIPHER *enc) { EVP_PKEY *pkey; PKCS8_PRIV_KEY_INFO *p8; @@ -881,7 +695,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, BIO_printf(bio_err, "Safe Contents bag\n"); print_attribs(out, bag->attrib, "Bag Attributes"); return dump_certs_pkeys_bags(out, bag->value.safes, pass, - passlen, options, pempass); + passlen, options, pempass, enc); default: BIO_printf(bio_err, "Warning unsupported bag type: "); @@ -949,22 +763,10 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) int ret; X509 *cert; ret = 0; -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("cert_load(): reading one cert"); -# endif while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif ret = 1; sk_X509_push(sk, cert); -# ifdef CRYPTO_MDEBUG - CRYPTO_push_info("cert_load(): reading one cert"); -# endif } -# ifdef CRYPTO_MDEBUG - CRYPTO_pop_info(); -# endif if (ret) ERR_clear_error(); return ret; @@ -1039,7 +841,7 @@ void hex_prin(BIO *out, unsigned char *buf, int len) BIO_printf(out, "%02X ", buf[i]); } -static int set_pbe(BIO *err, int *ppbe, const char *str) +static int set_pbe(int *ppbe, const char *str) { if (!str) return 0; diff --git a/apps/pkcs7.c b/apps/pkcs7.c index 4fcb089b2b..ca052730ea 100644 --- a/apps/pkcs7.c +++ b/apps/pkcs7.c @@ -1,4 +1,3 @@ -/* apps/pkcs7.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,6 +54,54 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ #include #include @@ -68,162 +115,105 @@ #include #include -#undef PROG -#define PROG pkcs7_main - -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -print_certs - */ +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT, + OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS pkcs7_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"in", OPT_IN, '<', "Input file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"out", OPT_OUT, '>', "Output file"}, + {"noout", OPT_NOOUT, '-', "Don't output encoded data"}, + {"text", OPT_TEXT, '-', "Print full details of certificates"}, + {"print", OPT_PRINT, '-'}, + {"print_certs", OPT_PRINT_CERTS, '-', + "Print_certs print any certs or crl in the input"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int pkcs7_main(int argc, char **argv) { PKCS7 *p7 = NULL; - int i, badops = 0; BIO *in = NULL, *out = NULL; - int informat, outformat; - char *infile, *outfile, *prog; - int print_certs = 0, text = 0, noout = 0, p7_print = 0; - int ret = 1; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; + int informat = FORMAT_PEM, outformat = FORMAT_PEM; + char *engine = NULL, *infile = NULL, *outfile = NULL, *prog; + int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; + OPTION_CHOICE o; - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-noout") == 0) + prog = opt_init(argc, argv, pkcs7_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkcs7_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-print") == 0) + break; + case OPT_PRINT: p7_print = 1; - else if (strcmp(*argv, "-print_certs") == 0) + break; + case OPT_PRINT_CERTS: print_certs = 1; -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_ENGINE: + engine = opt_arg(); break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, - " -print_certs print any certs or crl in the input\n"); - BIO_printf(bio_err, - " -text print full details of certificates\n"); - BIO_printf(bio_err, " -noout don't output encoded data\n"); #ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); + setup_engine(engine, 0); #endif - ret = 1; - goto end; - } - - ERR_load_crypto_strings(); -#ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); -#endif - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, RB(informat)); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - BIO_printf(bio_err, "unable to load input file\n"); - ERR_print_errors(bio_err); - goto end; - } - } if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); - else if (informat == FORMAT_PEM) + else p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, "bad input format specified for pkcs7 object\n"); - goto end; - } if (p7 == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, WB(outformat)); + if (out == NULL) + goto end; if (p7_print) PKCS7_print_ctx(out, p7, 0, NULL); @@ -282,12 +272,8 @@ int MAIN(int argc, char **argv) if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_PKCS7(out, p7); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); @@ -300,6 +286,5 @@ int MAIN(int argc, char **argv) PKCS7_free(p7); BIO_free(in); BIO_free_all(out); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/pkcs8.c b/apps/pkcs8.c index a56b9f42b1..7b361cfec6 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -1,4 +1,3 @@ -/* pkcs8.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999-2004. @@ -65,180 +64,142 @@ #include #include -#define PROG pkcs8_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, + OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, OPT_NOOCT, OPT_NSDB, OPT_EMBED, + OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS pkcs8_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, + {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, + {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, + {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, + {"nooct", OPT_NOOCT, '-', "Use (nonstandard) no octet format"}, + {"nsdb", OPT_NSDB, '-', "Use (nonstandard) DSA Netscape DB format"}, + {"embed", OPT_EMBED, '-', + "Use (nonstandard) embedded DSA parameters format"}, + {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, + {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, + {"v2prf", OPT_V2PRF, 's'}, + {"iter", OPT_ITER, 'p', "Specify the iteration count"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int pkcs8_main(int argc, char **argv) { - ENGINE *e = NULL; - char **args, *infile = NULL, *outfile = NULL; - char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; - int topk8 = 0; - int pbe_nid = -1; - const EVP_CIPHER *cipher = NULL; - int iter = PKCS12_DEFAULT_ITER; - int informat, outformat; - int p8_broken = PKCS8_OK; - int nocrypt = 0; - X509_SIG *p8 = NULL; - PKCS8_PRIV_KEY_INFO *p8inf = NULL; + ENGINE *e = NULL; EVP_PKEY *pkey = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + const EVP_CIPHER *cipher = NULL; + char *engine = NULL, *infile = NULL, *outfile = NULL; + char *passinarg = NULL, *passoutarg = NULL, *prog; char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL; - int badarg = 0; - int ret = 1; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - informat = FORMAT_PEM; - outformat = FORMAT_PEM; + OPTION_CHOICE o; + int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER, p8_broken = + PKCS8_OK; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = + -1; - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - args = argv + 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-v2")) { - if (args[1]) { - args++; - cipher = EVP_get_cipherbyname(*args); - if (!cipher) { - BIO_printf(bio_err, "Unknown cipher %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-v1")) { - if (args[1]) { - args++; - pbe_nid = OBJ_txt2nid(*args); - if (pbe_nid == NID_undef) { - BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-v2prf")) { - if (args[1]) { - args++; - pbe_nid = OBJ_txt2nid(*args); - if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { - BIO_printf(bio_err, "Unknown PRF algorithm %s\n", *args); - badarg = 1; - } - } else - badarg = 1; - } else if (!strcmp(*args, "-inform")) { - if (args[1]) { - args++; - informat = str2fmt(*args); - } else - badarg = 1; - } else if (!strcmp(*args, "-outform")) { - if (args[1]) { - args++; - outformat = str2fmt(*args); - } else - badarg = 1; - } else if (!strcmp(*args, "-topk8")) + prog = opt_init(argc, argv, pkcs8_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkcs8_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_TOPK8: topk8 = 1; - else if (!strcmp(*args, "-noiter")) + break; + case OPT_NOITER: iter = 1; - else if (!strcmp(*args, "-iter")) { - if (args[1]) { - iter = atoi(*(++args)); - if (iter <= 0) - badarg = 1; - } else - badarg = 1; - } else if (!strcmp(*args, "-nocrypt")) + break; + case OPT_NOCRYPT: nocrypt = 1; - else if (!strcmp(*args, "-nooct")) + break; + case OPT_NOOCT: p8_broken = PKCS8_NO_OCTET; - else if (!strcmp(*args, "-nsdb")) + break; + case OPT_NSDB: p8_broken = PKCS8_NS_DB; - else if (!strcmp(*args, "-embed")) + break; + case OPT_EMBED: p8_broken = PKCS8_EMBEDDED_PARAM; - else if (!strcmp(*args, "-passin")) { - if (args[1]) - passargin = *(++args); - else - badarg = 1; - } else if (!strcmp(*args, "-passout")) { - if (args[1]) - passargout = *(++args); - else - badarg = 1; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*args, "-engine") == 0) { - if (args[1]) - engine = *(++args); - else - badarg = 1; + break; + case OPT_V2: + if (!opt_cipher(opt_arg(), &cipher)) + goto opthelp; + break; + case OPT_V1: + pbe_nid = OBJ_txt2nid(opt_arg()); + if (pbe_nid == NID_undef) { + BIO_printf(bio_err, + "%s: Unknown PBE algorithm %s\n", prog, opt_arg()); + goto opthelp; + } + break; + case OPT_V2PRF: + pbe_nid = OBJ_txt2nid(opt_arg()); + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { + BIO_printf(bio_err, + "%s: Unknown PRF algorithm %s\n", prog, opt_arg()); + goto opthelp; + } + break; + case OPT_ITER: + if (!opt_int(opt_arg(), &iter)) + goto opthelp; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; } -#endif - else if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else - badarg = 1; - args++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badarg) { - BIO_printf(bio_err, "Usage pkcs8 [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); - BIO_printf(bio_err, - "-passin arg input file pass phrase source\n"); - BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-passout arg output file pass phrase source\n"); - BIO_printf(bio_err, "-topk8 output PKCS8 file\n"); - BIO_printf(bio_err, - "-nooct use (nonstandard) no octet format\n"); - BIO_printf(bio_err, - "-embed use (nonstandard) embedded DSA parameters format\n"); - BIO_printf(bio_err, - "-nsdb use (nonstandard) DSA Netscape DB format\n"); - BIO_printf(bio_err, "-iter count use count as iteration count\n"); - BIO_printf(bio_err, "-noiter use 1 as iteration count\n"); - BIO_printf(bio_err, - "-nocrypt use or expect unencrypted private key\n"); - BIO_printf(bio_err, - "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n"); - BIO_printf(bio_err, - "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n"); #ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -#endif - goto end; - } -#ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } @@ -246,30 +207,14 @@ int MAIN(int argc, char **argv) if ((pbe_nid == -1) && !cipher) pbe_nid = NID_pbeWithMD5AndDES_CBC; - if (infile) { - if (!(in = BIO_new_file(infile, "rb"))) { - BIO_printf(bio_err, "Can't open input file %s\n", infile); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - - if (outfile) { - if (!(out = BIO_new_file(outfile, "wb"))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } + in = bio_open_default(infile, "rb"); + if (in == NULL) + goto end; + out = bio_open_default(outfile, "wb"); + if (out == NULL) + goto end; if (topk8) { - pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); + pkey = load_key(infile, informat, 1, passin, e, "key"); if (!pkey) goto end; if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) { @@ -295,7 +240,7 @@ int MAIN(int argc, char **argv) (pass, sizeof pass, "Enter Encryption Password:", 1)) goto end; } - app_RAND_load_file(NULL, bio_err, 0); + app_RAND_load_file(NULL, 0); if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, p8pass, strlen(p8pass), NULL, 0, iter, p8inf))) { @@ -303,7 +248,7 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8(out, p8); else if (outformat == FORMAT_ASN1) diff --git a/apps/pkey.c b/apps/pkey.c index e848049c3a..3597be0ee6 100644 --- a/apps/pkey.c +++ b/apps/pkey.c @@ -1,4 +1,3 @@ -/* apps/pkey.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006 @@ -63,150 +62,121 @@ #include #include -#define PROG pkey_main - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, + OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB, + OPT_TEXT, OPT_NOOUT, OPT_MD +} OPTION_CHOICE; + +OPTIONS pkey_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, + {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pubin", OPT_PUBIN, '-', + "Read public key from input (default is private key)"}, + {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, + {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"}, + {"text", OPT_TEXT, '-', "Output in plaintext as well"}, + {"noout", OPT_NOOUT, '-', "Don't output the key"}, + {"", OPT_MD, '-', "Any supported cipher"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int pkey_main(int argc, char **argv) { - ENGINE *e = NULL; - char **args, *infile = NULL, *outfile = NULL; - char *passargin = NULL, *passargout = NULL; BIO *in = NULL, *out = NULL; - const EVP_CIPHER *cipher = NULL; - int informat, outformat; - int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; + ENGINE *e = NULL; EVP_PKEY *pkey = NULL; - char *passin = NULL, *passout = NULL; - int badarg = 0; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - int ret = 1; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - args = argv + 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-inform")) { - if (args[1]) { - args++; - informat = str2fmt(*args); - } else - badarg = 1; - } else if (!strcmp(*args, "-outform")) { - if (args[1]) { - args++; - outformat = str2fmt(*args); - } else - badarg = 1; - } else if (!strcmp(*args, "-passin")) { - if (!args[1]) - goto bad; - passargin = *(++args); - } else if (!strcmp(*args, "-passout")) { - if (!args[1]) - goto bad; - passargout = *(++args); - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*args, "-engine") == 0) { - if (!args[1]) - goto bad; - engine = *(++args); - } -#endif - else if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } else if (strcmp(*args, "-pubin") == 0) { - pubin = 1; - pubout = 1; - pubtext = 1; - } else if (strcmp(*args, "-pubout") == 0) + const EVP_CIPHER *cipher = NULL; + char *infile = NULL, *outfile = NULL, *passin = NULL, *passout = NULL; + char *passinarg = NULL, *passoutarg = NULL, *prog, *engine = NULL; + OPTION_CHOICE o; + int informat = FORMAT_PEM, outformat = FORMAT_PEM; + int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1; + + prog = opt_init(argc, argv, pkey_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkey_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PUBIN: + pubin = pubout = pubtext = 1; + break; + case OPT_PUBOUT: pubout = 1; - else if (strcmp(*args, "-text_pub") == 0) { - pubtext = 1; - text = 1; - } else if (strcmp(*args, "-text") == 0) + break; + case OPT_TEXT_PUB: + pubtext = text = 1; + break; + case OPT_TEXT: text = 1; - else if (strcmp(*args, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - else { - cipher = EVP_get_cipherbyname(*args + 1); - if (!cipher) { - BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); - badarg = 1; - } + break; + case OPT_MD: + if (!opt_cipher(opt_unknown(), &cipher)) + goto opthelp; } - args++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badarg) { - bad: - BIO_printf(bio_err, "Usage pkey [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); - BIO_printf(bio_err, - "-passin arg input file pass phrase source\n"); - BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-passout arg output file pass phrase source\n"); #ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - return 1; - } -#ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } - if (outfile) { - if (!(out = BIO_new_file(outfile, "wb"))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } + out = bio_open_default(outfile, "wb"); + if (out == NULL) + goto end; if (pubin) - pkey = load_pubkey(bio_err, infile, informat, 1, - passin, e, "Public Key"); + pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); else - pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); + pkey = load_key(infile, informat, 1, passin, e, "key"); if (!pkey) goto end; diff --git a/apps/pkeyparam.c b/apps/pkeyparam.c index a148a6621a..5a5caf56bd 100644 --- a/apps/pkeyparam.c +++ b/apps/pkeyparam.c @@ -1,4 +1,3 @@ -/* apps/pkeyparam.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006 @@ -63,104 +62,72 @@ #include #include -#define PROG pkeyparam_main - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, OPT_ENGINE +} OPTION_CHOICE; + +OPTIONS pkeyparam_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"text", OPT_TEXT, '-', "Print parameters as text"}, + {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int pkeyparam_main(int argc, char **argv) { - char **args, *infile = NULL, *outfile = NULL; BIO *in = NULL, *out = NULL; - int text = 0, noout = 0; EVP_PKEY *pkey = NULL; - int badarg = 0; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - int ret = 1; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - args = argv + 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } else - badarg = 1; - } else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } else - badarg = 1; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*args, "-engine") == 0) { - if (!args[1]) - goto bad; - engine = *(++args); - } -#endif - - else if (strcmp(*args, "-text") == 0) + int text = 0, noout = 0, ret = 1; + OPTION_CHOICE o; + char *infile = NULL, *outfile = NULL, *prog, *engine = NULL; + + prog = opt_init(argc, argv, pkeyparam_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkeyparam_options); + ret = 0; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_TEXT: text = 1; - else if (strcmp(*args, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - args++; + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); - if (badarg) { #ifndef OPENSSL_NO_ENGINE - bad: + setup_engine(engine, 0); #endif - BIO_printf(bio_err, "Usage pkeyparam [options]\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, "-text print parameters as text\n"); - BIO_printf(bio_err, - "-noout don't output encoded parameters\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - return 1; - } -#ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); -#endif - - if (infile) { - if (!(in = BIO_new_file(infile, "r"))) { - BIO_printf(bio_err, "Can't open input file %s\n", infile); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - - if (outfile) { - if (!(out = BIO_new_file(outfile, "w"))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } + in = bio_open_default(infile, "r"); + if (in == NULL) + goto end; + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; pkey = PEM_read_bio_Parameters(in, NULL); if (!pkey) { BIO_printf(bio_err, "Error reading parameters\n"); diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 1028686738..942ba05ded 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -66,200 +66,194 @@ #define KEY_PUBKEY 2 #define KEY_CERT 3 -static void usage(void); - -#undef PROG - -#define PROG pkeyutl_main - static EVP_PKEY_CTX *init_ctx(int *pkeysize, char *keyfile, int keyform, int key_type, - char *passargin, int pkey_op, ENGINE *e); + char *passinarg, int pkey_op, ENGINE *e); -static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, - const char *file); +static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file); static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, unsigned char *out, size_t *poutlen, unsigned char *in, size_t inlen); -int MAIN(int argc, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_IN, OPT_OUT, + OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN, + OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, + OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, + OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT +} OPTION_CHOICE; + +OPTIONS pkeyutl_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pubin", OPT_PUBIN, '-', "Input is a public key"}, + {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, + {"asn1parse", OPT_ASN1PARSE, '-'}, + {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, + {"sign", OPT_SIGN, '-', "Sign with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"verifyrecover", OPT_VERIFYRECOVER, '-', + "Verify with public key, recover original data"}, + {"rev", OPT_REV, '-'}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, + {"derive", OPT_DERIVE, '-', "Derive shared secret"}, + {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, + {"inkey", OPT_INKEY, 's', "Input key"}, + {"peerkey", OPT_PEERKEY, 's'}, + {"passin", OPT_PASSIN, 's', "Pass phrase source"}, + {"peerform", OPT_PEERFORM, 'F'}, + {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, + {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int pkeyutl_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; - char *infile = NULL, *outfile = NULL, *sigfile = NULL; ENGINE *e = NULL; - int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; - int keyform = FORMAT_PEM, peerform = FORMAT_PEM; - char badarg = 0, rev = 0; - char hexdump = 0, asn1parse = 0; EVP_PKEY_CTX *ctx = NULL; - char *passargin = NULL; - int keysize = -1; - + char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; + char hexdump = 0, asn1parse = 0, rev = 0, *prog; unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; - size_t buf_outlen; - int buf_inlen = 0, siglen = -1; - + OPTION_CHOICE o; + int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = + FORMAT_PEM; + int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; int ret = 1, rv = -1; + size_t buf_outlen; - argc--; - argv++; - - if (!bio_err) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - - while (argc >= 1) { - if (!strcmp(*argv, "-in")) { - if (--argc < 1) - badarg = 1; - else - infile = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) - badarg = 1; - else - outfile = *(++argv); - } else if (!strcmp(*argv, "-sigfile")) { - if (--argc < 1) - badarg = 1; - else - sigfile = *(++argv); - } else if (!strcmp(*argv, "-inkey")) { - if (--argc < 1) - badarg = 1; - else { - ctx = init_ctx(&keysize, - *(++argv), keyform, key_type, - passargin, pkey_op, e); - if (!ctx) { - BIO_puts(bio_err, "Error initializing context\n"); - ERR_print_errors(bio_err); - badarg = 1; - } + prog = opt_init(argc, argv, pkeyutl_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(pkeyutl_options); + ret = 0; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_SIGFILE: + sigfile = opt_arg(); + break; + case OPT_INKEY: + ctx = init_ctx(&keysize, opt_arg(), keyform, key_type, + passinarg, pkey_op, e); + if (ctx == NULL) { + BIO_puts(bio_err, "%s: Error initializing context\n"); + ERR_print_errors(bio_err); + goto opthelp; } - } else if (!strcmp(*argv, "-peerkey")) { - if (--argc < 1) - badarg = 1; - else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) - badarg = 1; - } else if (!strcmp(*argv, "-passin")) { - if (--argc < 1) - badarg = 1; - else - passargin = *(++argv); - } else if (strcmp(*argv, "-peerform") == 0) { - if (--argc < 1) - badarg = 1; - else - peerform = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - badarg = 1; - else - keyform = str2fmt(*(++argv)); - } + break; + case OPT_PEERKEY: + if (!setup_peer(ctx, peerform, opt_arg())) + goto opthelp; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PEERFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &peerform)) + goto opthelp; + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyform)) + goto opthelp; + break; #ifndef OPENSSL_NO_ENGINE - else if (!strcmp(*argv, "-engine")) { - if (--argc < 1) - badarg = 1; - else - e = setup_engine(bio_err, *(++argv), 0); - } + case OPT_ENGINE: + e = setup_engine(opt_arg(), 0); + break; #endif - else if (!strcmp(*argv, "-pubin")) + case OPT_PUBIN: key_type = KEY_PUBKEY; - else if (!strcmp(*argv, "-certin")) + break; + case OPT_CERTIN: key_type = KEY_CERT; - else if (!strcmp(*argv, "-asn1parse")) + break; + case OPT_ASN1PARSE: asn1parse = 1; - else if (!strcmp(*argv, "-hexdump")) + break; + case OPT_HEXDUMP: hexdump = 1; - else if (!strcmp(*argv, "-sign")) + break; + case OPT_SIGN: pkey_op = EVP_PKEY_OP_SIGN; - else if (!strcmp(*argv, "-verify")) + break; + case OPT_VERIFY: pkey_op = EVP_PKEY_OP_VERIFY; - else if (!strcmp(*argv, "-verifyrecover")) + break; + case OPT_VERIFYRECOVER: pkey_op = EVP_PKEY_OP_VERIFYRECOVER; - else if (!strcmp(*argv, "-rev")) + break; + case OPT_REV: rev = 1; - else if (!strcmp(*argv, "-encrypt")) + case OPT_ENCRYPT: pkey_op = EVP_PKEY_OP_ENCRYPT; - else if (!strcmp(*argv, "-decrypt")) + break; + case OPT_DECRYPT: pkey_op = EVP_PKEY_OP_DECRYPT; - else if (!strcmp(*argv, "-derive")) + break; + case OPT_DERIVE: pkey_op = EVP_PKEY_OP_DERIVE; - else if (strcmp(*argv, "-pkeyopt") == 0) { - if (--argc < 1) - badarg = 1; - else if (!ctx) { - BIO_puts(bio_err, "-pkeyopt command before -inkey\n"); - badarg = 1; - } else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) { - BIO_puts(bio_err, "parameter setting error\n"); + break; + case OPT_PKEYOPT: + if (ctx == NULL) { + BIO_printf(bio_err, + "%s: Must have -inkey before -pkeyopt\n", prog); + goto opthelp; + } + if (pkey_ctrl_string(ctx, opt_arg()) <= 0) { + BIO_printf(bio_err, "%s: Can't set parameter:\n", prog); ERR_print_errors(bio_err); goto end; } - } else - badarg = 1; - if (badarg) { - usage(); - goto end; + break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (!ctx) { - usage(); - goto end; - } + if (ctx == NULL) + goto opthelp; if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { - BIO_puts(bio_err, "Signature file specified for non verify\n"); + BIO_printf(bio_err, + "%s: Signature file specified for non verify\n", prog); goto end; } if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { - BIO_puts(bio_err, "No signature file specified for verify\n"); + BIO_printf(bio_err, + "%s: No signature file specified for verify\n", prog); goto end; } /* FIXME: seed PRNG only if needed */ - app_RAND_load_file(NULL, bio_err, 0); + app_RAND_load_file(NULL, 0); if (pkey_op != EVP_PKEY_OP_DERIVE) { - if (infile) { - if (!(in = BIO_new_file(infile, "rb"))) { - BIO_puts(bio_err, "Error Opening Input File\n"); - ERR_print_errors(bio_err); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - } - - if (outfile) { - if (!(out = BIO_new_file(outfile, "wb"))) { - BIO_printf(bio_err, "Error Creating Output File\n"); - ERR_print_errors(bio_err); + in = bio_open_default(infile, "rb"); + if (in == NULL) goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif } + out = bio_open_default(outfile, "wb"); + if (out == NULL) + goto end; if (sigfile) { BIO *sigbio = BIO_new_file(sigfile, "rb"); @@ -297,32 +291,30 @@ int MAIN(int argc, char **argv) if (pkey_op == EVP_PKEY_OP_VERIFY) { rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, buf_in, (size_t)buf_inlen); - if (rv == 0) - BIO_puts(out, "Signature Verification Failure\n"); - else if (rv == 1) + if (rv == 1) { BIO_puts(out, "Signature Verified Successfully\n"); - if (rv >= 0) - goto end; - } else { - rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, - buf_in, (size_t)buf_inlen); - if (rv > 0) { - buf_out = OPENSSL_malloc(buf_outlen); - if (!buf_out) - rv = -1; - else - rv = do_keyop(ctx, pkey_op, - buf_out, (size_t *)&buf_outlen, - buf_in, (size_t)buf_inlen); - } + ret = 0; + } else + BIO_puts(out, "Signature Verification Failure\n"); + goto end; + } + rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); + if (rv > 0) { + buf_out = OPENSSL_malloc(buf_outlen); + if (!buf_out) + rv = -1; + else + rv = do_keyop(ctx, pkey_op, + buf_out, (size_t *)&buf_outlen, + buf_in, (size_t)buf_inlen); } - if (rv <= 0) { - BIO_printf(bio_err, "Public Key operation error\n"); ERR_print_errors(bio_err); goto end; } ret = 0; + if (asn1parse) { if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) ERR_print_errors(bio_err); @@ -344,38 +336,9 @@ int MAIN(int argc, char **argv) return ret; } -static void usage() -{ - BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-sigfile file signature file (verify operation only)\n"); - BIO_printf(bio_err, "-inkey file input key\n"); - BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); - BIO_printf(bio_err, "-pubin input is a public key\n"); - BIO_printf(bio_err, - "-certin input is a certificate carrying a public key\n"); - BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); - BIO_printf(bio_err, "-sign sign with private key\n"); - BIO_printf(bio_err, "-verify verify with public key\n"); - BIO_printf(bio_err, - "-verifyrecover verify with public key, recover original data\n"); - BIO_printf(bio_err, "-encrypt encrypt with public key\n"); - BIO_printf(bio_err, "-decrypt decrypt with private key\n"); - BIO_printf(bio_err, "-derive derive shared secret\n"); - BIO_printf(bio_err, "-hexdump hex dump output\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - BIO_printf(bio_err, "-passin arg pass phrase source\n"); - -} - static EVP_PKEY_CTX *init_ctx(int *pkeysize, char *keyfile, int keyform, int key_type, - char *passargin, int pkey_op, ENGINE *e) + char *passinarg, int pkey_op, ENGINE *e) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -388,23 +351,21 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize, BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(bio_err, keyfile, keyform, 0, - passin, e, "Private Key"); + pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: - pkey = load_pubkey(bio_err, keyfile, keyform, 0, - NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); break; case KEY_CERT: - x = load_cert(bio_err, keyfile, keyform, NULL, e, "Certificate"); + x = load_cert(keyfile, keyform, NULL, e, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); @@ -465,21 +426,20 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize, } -static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, - const char *file) +static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file) { EVP_PKEY *peer = NULL; int ret; if (!ctx) { - BIO_puts(err, "-peerkey command before -inkey\n"); + BIO_puts(bio_err, "-peerkey command before -inkey\n"); return 0; } - peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key"); + peer = load_pubkey(file, peerform, 0, NULL, NULL, "Peer Key"); if (!peer) { BIO_printf(bio_err, "Error reading peer key %s\n", file); - ERR_print_errors(err); + ERR_print_errors(bio_err); return 0; } @@ -487,7 +447,7 @@ static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, EVP_PKEY_free(peer); if (ret <= 0) - ERR_print_errors(err); + ERR_print_errors(bio_err); return ret; } diff --git a/apps/prime.c b/apps/prime.c index 1fb1c8d845..04a83ab04e 100644 --- a/apps/prime.c +++ b/apps/prime.c @@ -52,67 +52,66 @@ #include "apps.h" #include -#undef PROG -#define PROG prime_main - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS +} OPTION_CHOICE; + +OPTIONS prime_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, + {OPT_HELP_STR, 1, '-', + " number Number to check for primarility\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"hex", OPT_HEX, '-', "Hex output"}, + {"generate", OPT_GENERATE, '-', "Generate a prime"}, + {"bits", OPT_BITS, 'p', "Size of number in bits"}, + {"safe", OPT_SAFE, '-', + "When used with -generate, generate a safe prime"}, + {"checks", OPT_CHECKS, 'p', "Number of checks"}, + {NULL} +}; + +int prime_main(int argc, char **argv) { - int hex = 0; - int checks = 20; - int generate = 0; - int bits = 0; - int safe = 0; BIGNUM *bn = NULL; - BIO *bio_out; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - --argc; - ++argv; - while (argc >= 1 && **argv == '-') { - if (!strcmp(*argv, "-hex")) + int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1; + char *prog; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, prime_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(prime_options); + ret = 0; + goto end; + case OPT_HEX: hex = 1; - else if (!strcmp(*argv, "-generate")) + break; + case OPT_GENERATE: generate = 1; - else if (!strcmp(*argv, "-bits")) - if (--argc < 1) - goto bad; - else - bits = atoi(*++argv); - else if (!strcmp(*argv, "-safe")) + break; + case OPT_BITS: + bits = atoi(opt_arg()); + break; + case OPT_SAFE: safe = 1; - else if (!strcmp(*argv, "-checks")) - if (--argc < 1) - goto bad; - else - checks = atoi(*++argv); - else { - BIO_printf(bio_err, "Unknown option '%s'\n", *argv); - goto bad; + break; + case OPT_CHECKS: + checks = atoi(opt_arg()); + break; } - --argc; - ++argv; } + argc = opt_num_rest(); + argv = opt_rest(); - if (argv[0] == NULL && !generate) { - BIO_printf(bio_err, "No prime specified\n"); - goto bad; - } - - if ((bio_out = BIO_new(BIO_s_file())) != NULL) { - BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - bio_out = BIO_push(tmpbio, bio_out); - } -#endif + if (argc == 0 && !generate) { + BIO_printf(bio_err, "%s: No prime specified\n", prog); + goto end; } if (generate) { @@ -120,7 +119,7 @@ int MAIN(int argc, char **argv) if (!bits) { BIO_printf(bio_err, "Specifiy the number of bits.\n"); - return 1; + goto end; } bn = BN_new(); BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL); @@ -128,24 +127,22 @@ int MAIN(int argc, char **argv) BIO_printf(bio_out, "%s\n", s); OPENSSL_free(s); } else { - if (hex) - BN_hex2bn(&bn, argv[0]); - else - BN_dec2bn(&bn, argv[0]); + for ( ; *argv; argv++) { + if (hex) + BN_hex2bn(&bn, argv[0]); + else + BN_dec2bn(&bn, argv[0]); - BN_print(bio_out, bn); - BIO_printf(bio_out, " is %sprime\n", - BN_is_prime_ex(bn, checks, NULL, NULL) ? "" : "not "); + BN_print(bio_out, bn); + BIO_printf(bio_out, " (%s) %s prime\n", + argv[0], + BN_is_prime_ex(bn, checks, NULL, NULL) + ? "is" : "is not"); + } } BN_free(bn); - BIO_free_all(bio_out); - - return 0; - bad: - BIO_printf(bio_err, "options are\n"); - BIO_printf(bio_err, "%-14s hex\n", "-hex"); - BIO_printf(bio_err, "%-14s number of checks\n", "-checks "); - return 1; + end: + return ret; } diff --git a/apps/progs.h b/apps/progs.h index 9a8a1923ee..33bdef7b27 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -1,364 +1,415 @@ -/* apps/progs.h */ -/* automatically generated by progs.pl for openssl.c */ +/* + * Automatically generated by progs.pl for openssl.c + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * See the openssl.c for copyright details. + */ + +typedef enum FUNC_TYPE { + FT_none, FT_general, FT_md, FT_cipher, FT_pkey, + FT_md_alg, FT_cipher_alg +} FUNC_TYPE; + +typedef struct function_st { + FUNC_TYPE type; + const char *name; + int (*func)(int argc,char *argv[]); + const OPTIONS *help; +} FUNCTION; -extern int verify_main(int argc, char *argv[]); extern int asn1parse_main(int argc, char *argv[]); -extern int req_main(int argc, char *argv[]); -extern int dgst_main(int argc, char *argv[]); -extern int dh_main(int argc, char *argv[]); -extern int dhparam_main(int argc, char *argv[]); -extern int enc_main(int argc, char *argv[]); -extern int passwd_main(int argc, char *argv[]); -extern int gendh_main(int argc, char *argv[]); -extern int errstr_main(int argc, char *argv[]); extern int ca_main(int argc, char *argv[]); +extern int ciphers_main(int argc, char *argv[]); +extern int cms_main(int argc, char *argv[]); extern int crl_main(int argc, char *argv[]); -extern int rsa_main(int argc, char *argv[]); -extern int rsautl_main(int argc, char *argv[]); +extern int crl2pkcs7_main(int argc, char *argv[]); +extern int dgst_main(int argc, char *argv[]); +extern int dhparam_main(int argc, char *argv[]); extern int dsa_main(int argc, char *argv[]); extern int dsaparam_main(int argc, char *argv[]); extern int ec_main(int argc, char *argv[]); extern int ecparam_main(int argc, char *argv[]); -extern int x509_main(int argc, char *argv[]); -extern int genrsa_main(int argc, char *argv[]); +extern int enc_main(int argc, char *argv[]); +extern int engine_main(int argc, char *argv[]); +extern int errstr_main(int argc, char *argv[]); extern int gendsa_main(int argc, char *argv[]); extern int genpkey_main(int argc, char *argv[]); -extern int s_server_main(int argc, char *argv[]); -extern int s_client_main(int argc, char *argv[]); -extern int speed_main(int argc, char *argv[]); -extern int s_time_main(int argc, char *argv[]); -extern int version_main(int argc, char *argv[]); -extern int pkcs7_main(int argc, char *argv[]); -extern int cms_main(int argc, char *argv[]); -extern int crl2pkcs7_main(int argc, char *argv[]); -extern int sess_id_main(int argc, char *argv[]); -extern int ciphers_main(int argc, char *argv[]); +extern int genrsa_main(int argc, char *argv[]); extern int nseq_main(int argc, char *argv[]); +extern int ocsp_main(int argc, char *argv[]); +extern int passwd_main(int argc, char *argv[]); extern int pkcs12_main(int argc, char *argv[]); +extern int pkcs7_main(int argc, char *argv[]); extern int pkcs8_main(int argc, char *argv[]); extern int pkey_main(int argc, char *argv[]); extern int pkeyparam_main(int argc, char *argv[]); extern int pkeyutl_main(int argc, char *argv[]); -extern int spkac_main(int argc, char *argv[]); -extern int smime_main(int argc, char *argv[]); -extern int rand_main(int argc, char *argv[]); -extern int engine_main(int argc, char *argv[]); -extern int ocsp_main(int argc, char *argv[]); extern int prime_main(int argc, char *argv[]); -extern int ts_main(int argc, char *argv[]); +extern int rand_main(int argc, char *argv[]); +extern int req_main(int argc, char *argv[]); +extern int rsa_main(int argc, char *argv[]); +extern int rsautl_main(int argc, char *argv[]); +extern int s_client_main(int argc, char *argv[]); +extern int s_server_main(int argc, char *argv[]); +extern int s_time_main(int argc, char *argv[]); +extern int sess_id_main(int argc, char *argv[]); +extern int smime_main(int argc, char *argv[]); +extern int speed_main(int argc, char *argv[]); +extern int spkac_main(int argc, char *argv[]); extern int srp_main(int argc, char *argv[]); +extern int ts_main(int argc, char *argv[]); +extern int verify_main(int argc, char *argv[]); +extern int version_main(int argc, char *argv[]); +extern int x509_main(int argc, char *argv[]); +extern int list_main(int argc, char *argv[]); +extern int help_main(int argc, char *argv[]); +extern int exit_main(int argc, char *argv[]); -#define FUNC_TYPE_GENERAL 1 -#define FUNC_TYPE_MD 2 -#define FUNC_TYPE_CIPHER 3 -#define FUNC_TYPE_PKEY 4 -#define FUNC_TYPE_MD_ALG 5 -#define FUNC_TYPE_CIPHER_ALG 6 - -typedef struct { - int type; - const char *name; - int (*func) (int argc, char *argv[]); -} FUNCTION; -DECLARE_LHASH_OF(FUNCTION); - +#ifdef INCLUDE_FUNCTION_TABLE +extern OPTIONS asn1parse_options[]; +extern OPTIONS ca_options[]; +extern OPTIONS ciphers_options[]; +extern OPTIONS cms_options[]; +extern OPTIONS crl_options[]; +extern OPTIONS crl2pkcs7_options[]; +extern OPTIONS dgst_options[]; +extern OPTIONS dhparam_options[]; +extern OPTIONS dsa_options[]; +extern OPTIONS dsaparam_options[]; +extern OPTIONS ec_options[]; +extern OPTIONS ecparam_options[]; +extern OPTIONS enc_options[]; +extern OPTIONS engine_options[]; +extern OPTIONS errstr_options[]; +extern OPTIONS gendsa_options[]; +extern OPTIONS genpkey_options[]; +extern OPTIONS genrsa_options[]; +extern OPTIONS nseq_options[]; +extern OPTIONS ocsp_options[]; +extern OPTIONS passwd_options[]; +extern OPTIONS pkcs12_options[]; +extern OPTIONS pkcs7_options[]; +extern OPTIONS pkcs8_options[]; +extern OPTIONS pkey_options[]; +extern OPTIONS pkeyparam_options[]; +extern OPTIONS pkeyutl_options[]; +extern OPTIONS prime_options[]; +extern OPTIONS rand_options[]; +extern OPTIONS req_options[]; +extern OPTIONS rsa_options[]; +extern OPTIONS rsautl_options[]; +extern OPTIONS s_client_options[]; +extern OPTIONS s_server_options[]; +extern OPTIONS s_time_options[]; +extern OPTIONS sess_id_options[]; +extern OPTIONS smime_options[]; +extern OPTIONS speed_options[]; +extern OPTIONS spkac_options[]; +extern OPTIONS srp_options[]; +extern OPTIONS ts_options[]; +extern OPTIONS verify_options[]; +extern OPTIONS version_options[]; +extern OPTIONS x509_options[]; +extern OPTIONS list_options[]; +extern OPTIONS help_options[]; +extern OPTIONS exit_options[]; FUNCTION functions[] = { - {FUNC_TYPE_GENERAL, "verify", verify_main}, - {FUNC_TYPE_GENERAL, "asn1parse", asn1parse_main}, - {FUNC_TYPE_GENERAL, "req", req_main}, - {FUNC_TYPE_GENERAL, "dgst", dgst_main}, -#ifndef OPENSSL_NO_DH - {FUNC_TYPE_GENERAL, "dh", dh_main}, + { FT_general, "asn1parse", asn1parse_main, asn1parse_options }, + { FT_general, "ca", ca_main, ca_options }, +#if !defined(OPENSSL_NO_SOCK) + { FT_general, "ciphers", ciphers_main, ciphers_options }, #endif -#ifndef OPENSSL_NO_DH - {FUNC_TYPE_GENERAL, "dhparam", dhparam_main}, +#ifndef OPENSSL_NO_CMS + { FT_general, "cms", cms_main, cms_options }, #endif - {FUNC_TYPE_GENERAL, "enc", enc_main}, - {FUNC_TYPE_GENERAL, "passwd", passwd_main}, + { FT_general, "crl", crl_main, crl_options }, + { FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options }, + { FT_general, "dgst", dgst_main, dgst_options }, #ifndef OPENSSL_NO_DH - {FUNC_TYPE_GENERAL, "gendh", gendh_main}, -#endif - {FUNC_TYPE_GENERAL, "errstr", errstr_main}, - {FUNC_TYPE_GENERAL, "ca", ca_main}, - {FUNC_TYPE_GENERAL, "crl", crl_main}, -#ifndef OPENSSL_NO_RSA - {FUNC_TYPE_GENERAL, "rsa", rsa_main}, -#endif -#ifndef OPENSSL_NO_RSA - {FUNC_TYPE_GENERAL, "rsautl", rsautl_main}, + { FT_general, "dhparam", dhparam_main, dhparam_options }, #endif #ifndef OPENSSL_NO_DSA - {FUNC_TYPE_GENERAL, "dsa", dsa_main}, + { FT_general, "dsa", dsa_main, dsa_options }, #endif #ifndef OPENSSL_NO_DSA - {FUNC_TYPE_GENERAL, "dsaparam", dsaparam_main}, + { FT_general, "dsaparam", dsaparam_main, dsaparam_options }, #endif #ifndef OPENSSL_NO_EC - {FUNC_TYPE_GENERAL, "ec", ec_main}, + { FT_general, "ec", ec_main, ec_options }, #endif #ifndef OPENSSL_NO_EC - {FUNC_TYPE_GENERAL, "ecparam", ecparam_main}, + { FT_general, "ecparam", ecparam_main, ecparam_options }, #endif - {FUNC_TYPE_GENERAL, "x509", x509_main}, -#ifndef OPENSSL_NO_RSA - {FUNC_TYPE_GENERAL, "genrsa", genrsa_main}, + { FT_general, "enc", enc_main, enc_options }, +#ifndef OPENSSL_NO_ENGINE + { FT_general, "engine", engine_main, engine_options }, #endif + { FT_general, "errstr", errstr_main, errstr_options }, #ifndef OPENSSL_NO_DSA - {FUNC_TYPE_GENERAL, "gendsa", gendsa_main}, + { FT_general, "gendsa", gendsa_main, gendsa_options }, #endif - {FUNC_TYPE_GENERAL, "genpkey", genpkey_main}, -#if !defined(OPENSSL_NO_SOCK) - {FUNC_TYPE_GENERAL, "s_server", s_server_main}, + { FT_general, "genpkey", genpkey_main, genpkey_options }, +#ifndef OPENSSL_NO_RSA + { FT_general, "genrsa", genrsa_main, genrsa_options }, #endif -#if !defined(OPENSSL_NO_SOCK) - {FUNC_TYPE_GENERAL, "s_client", s_client_main}, + { FT_general, "nseq", nseq_main, nseq_options }, +#ifndef OPENSSL_NO_OCSP + { FT_general, "ocsp", ocsp_main, ocsp_options }, #endif - {FUNC_TYPE_GENERAL, "speed", speed_main}, -#if !defined(OPENSSL_NO_SOCK) - {FUNC_TYPE_GENERAL, "s_time", s_time_main}, + { FT_general, "passwd", passwd_main, passwd_options }, +#if !defined(OPENSSL_NO_DES) + { FT_general, "pkcs12", pkcs12_main, pkcs12_options }, +#endif + { FT_general, "pkcs7", pkcs7_main, pkcs7_options }, + { FT_general, "pkcs8", pkcs8_main, pkcs8_options }, + { FT_general, "pkey", pkey_main, pkey_options }, + { FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options }, + { FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options }, + { FT_general, "prime", prime_main, prime_options }, + { FT_general, "rand", rand_main, rand_options }, + { FT_general, "req", req_main, req_options }, +#ifndef OPENSSL_NO_RSA + { FT_general, "rsa", rsa_main, rsa_options }, #endif - {FUNC_TYPE_GENERAL, "version", version_main}, - {FUNC_TYPE_GENERAL, "pkcs7", pkcs7_main}, -#ifndef OPENSSL_NO_CMS - {FUNC_TYPE_GENERAL, "cms", cms_main}, +#ifndef OPENSSL_NO_RSA + { FT_general, "rsautl", rsautl_main, rsautl_options }, #endif - {FUNC_TYPE_GENERAL, "crl2pkcs7", crl2pkcs7_main}, - {FUNC_TYPE_GENERAL, "sess_id", sess_id_main}, #if !defined(OPENSSL_NO_SOCK) - {FUNC_TYPE_GENERAL, "ciphers", ciphers_main}, + { FT_general, "s_client", s_client_main, s_client_options }, #endif - {FUNC_TYPE_GENERAL, "nseq", nseq_main}, -#if !defined(OPENSSL_NO_DES) - {FUNC_TYPE_GENERAL, "pkcs12", pkcs12_main}, -#endif - {FUNC_TYPE_GENERAL, "pkcs8", pkcs8_main}, - {FUNC_TYPE_GENERAL, "pkey", pkey_main}, - {FUNC_TYPE_GENERAL, "pkeyparam", pkeyparam_main}, - {FUNC_TYPE_GENERAL, "pkeyutl", pkeyutl_main}, - {FUNC_TYPE_GENERAL, "spkac", spkac_main}, - {FUNC_TYPE_GENERAL, "smime", smime_main}, - {FUNC_TYPE_GENERAL, "rand", rand_main}, -#ifndef OPENSSL_NO_ENGINE - {FUNC_TYPE_GENERAL, "engine", engine_main}, +#if !defined(OPENSSL_NO_SOCK) + { FT_general, "s_server", s_server_main, s_server_options }, #endif -#ifndef OPENSSL_NO_OCSP - {FUNC_TYPE_GENERAL, "ocsp", ocsp_main}, +#if !defined(OPENSSL_NO_SOCK) + { FT_general, "s_time", s_time_main, s_time_options }, #endif - {FUNC_TYPE_GENERAL, "prime", prime_main}, - {FUNC_TYPE_GENERAL, "ts", ts_main}, + { FT_general, "sess_id", sess_id_main, sess_id_options }, + { FT_general, "smime", smime_main, smime_options }, + { FT_general, "speed", speed_main, speed_options }, + { FT_general, "spkac", spkac_main, spkac_options }, #ifndef OPENSSL_NO_SRP - {FUNC_TYPE_GENERAL, "srp", srp_main}, -#endif + { FT_general, "srp", srp_main, srp_options }, +#endif + { FT_general, "ts", ts_main, ts_options }, + { FT_general, "verify", verify_main, verify_options }, + { FT_general, "version", version_main, version_options }, + { FT_general, "x509", x509_main, x509_options }, + { FT_general, "list", list_main, list_options }, + { FT_general, "help", help_main, help_options }, + { FT_general, "exit", exit_main, exit_options }, #ifndef OPENSSL_NO_MD2 - {FUNC_TYPE_MD, "md2", dgst_main}, + { FT_md, "md2", dgst_main}, #endif #ifndef OPENSSL_NO_MD4 - {FUNC_TYPE_MD, "md4", dgst_main}, + { FT_md, "md4", dgst_main}, #endif #ifndef OPENSSL_NO_MD5 - {FUNC_TYPE_MD, "md5", dgst_main}, + { FT_md, "md5", dgst_main}, #endif - {FUNC_TYPE_MD, "sha", dgst_main}, - {FUNC_TYPE_MD, "sha1", dgst_main}, +#ifndef OPENSSL_NO_MD_GHOST94 + { FT_md, "md_ghost94", dgst_main}, +#endif + { FT_md, "sha", dgst_main}, + { FT_md, "sha1", dgst_main}, + { FT_md, "sha224", dgst_main}, + { FT_md, "sha256", dgst_main}, + { FT_md, "sha384", dgst_main}, + { FT_md, "sha512", dgst_main}, #ifndef OPENSSL_NO_MDC2 - {FUNC_TYPE_MD, "mdc2", dgst_main}, + { FT_md, "mdc2", dgst_main}, #endif #ifndef OPENSSL_NO_RMD160 - {FUNC_TYPE_MD, "rmd160", dgst_main}, + { FT_md, "rmd160", dgst_main}, #endif - {FUNC_TYPE_MD, "sha224", dgst_main}, - {FUNC_TYPE_MD, "sha256", dgst_main}, - {FUNC_TYPE_MD, "sha384", dgst_main}, - {FUNC_TYPE_MD, "sha512", dgst_main}, #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-128-cbc", enc_main}, + { FT_cipher, "aes-128-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-128-ecb", enc_main}, + { FT_cipher, "aes-128-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-192-cbc", enc_main}, + { FT_cipher, "aes-192-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-192-ecb", enc_main}, + { FT_cipher, "aes-192-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-256-cbc", enc_main}, + { FT_cipher, "aes-256-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_AES - {FUNC_TYPE_CIPHER, "aes-256-ecb", enc_main}, + { FT_cipher, "aes-256-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-128-cbc", enc_main}, + { FT_cipher, "camellia-128-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-128-ecb", enc_main}, + { FT_cipher, "camellia-128-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-192-cbc", enc_main}, + { FT_cipher, "camellia-192-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-192-ecb", enc_main}, + { FT_cipher, "camellia-192-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-256-cbc", enc_main}, + { FT_cipher, "camellia-256-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAMELLIA - {FUNC_TYPE_CIPHER, "camellia-256-ecb", enc_main}, + { FT_cipher, "camellia-256-ecb", enc_main, enc_options }, #endif - {FUNC_TYPE_CIPHER, "base64", enc_main}, + { FT_cipher, "base64", enc_main, enc_options }, #ifdef ZLIB - {FUNC_TYPE_CIPHER, "zlib", enc_main}, + { FT_cipher, "zlib", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des", enc_main}, + { FT_cipher, "des", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des3", enc_main}, + { FT_cipher, "des3", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "desx", enc_main}, + { FT_cipher, "desx", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_IDEA - {FUNC_TYPE_CIPHER, "idea", enc_main}, + { FT_cipher, "idea", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_SEED - {FUNC_TYPE_CIPHER, "seed", enc_main}, + { FT_cipher, "seed", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC4 - {FUNC_TYPE_CIPHER, "rc4", enc_main}, + { FT_cipher, "rc4", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC4 - {FUNC_TYPE_CIPHER, "rc4-40", enc_main}, + { FT_cipher, "rc4-40", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2", enc_main}, + { FT_cipher, "rc2", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_BF - {FUNC_TYPE_CIPHER, "bf", enc_main}, + { FT_cipher, "bf", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast", enc_main}, + { FT_cipher, "cast", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC5 - {FUNC_TYPE_CIPHER, "rc5", enc_main}, + { FT_cipher, "rc5", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ecb", enc_main}, + { FT_cipher, "des-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede", enc_main}, + { FT_cipher, "des-ede", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede3", enc_main}, + { FT_cipher, "des-ede3", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-cbc", enc_main}, + { FT_cipher, "des-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede-cbc", enc_main}, + { FT_cipher, "des-ede-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede3-cbc", enc_main}, + { FT_cipher, "des-ede3-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-cfb", enc_main}, + { FT_cipher, "des-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede-cfb", enc_main}, + { FT_cipher, "des-ede-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede3-cfb", enc_main}, + { FT_cipher, "des-ede3-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ofb", enc_main}, + { FT_cipher, "des-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede-ofb", enc_main}, + { FT_cipher, "des-ede-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_DES - {FUNC_TYPE_CIPHER, "des-ede3-ofb", enc_main}, + { FT_cipher, "des-ede3-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_IDEA - {FUNC_TYPE_CIPHER, "idea-cbc", enc_main}, + { FT_cipher, "idea-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_IDEA - {FUNC_TYPE_CIPHER, "idea-ecb", enc_main}, + { FT_cipher, "idea-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_IDEA - {FUNC_TYPE_CIPHER, "idea-cfb", enc_main}, + { FT_cipher, "idea-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_IDEA - {FUNC_TYPE_CIPHER, "idea-ofb", enc_main}, + { FT_cipher, "idea-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_SEED - {FUNC_TYPE_CIPHER, "seed-cbc", enc_main}, + { FT_cipher, "seed-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_SEED - {FUNC_TYPE_CIPHER, "seed-ecb", enc_main}, + { FT_cipher, "seed-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_SEED - {FUNC_TYPE_CIPHER, "seed-cfb", enc_main}, + { FT_cipher, "seed-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_SEED - {FUNC_TYPE_CIPHER, "seed-ofb", enc_main}, + { FT_cipher, "seed-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-cbc", enc_main}, + { FT_cipher, "rc2-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-ecb", enc_main}, + { FT_cipher, "rc2-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-cfb", enc_main}, + { FT_cipher, "rc2-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-ofb", enc_main}, + { FT_cipher, "rc2-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-64-cbc", enc_main}, + { FT_cipher, "rc2-64-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC2 - {FUNC_TYPE_CIPHER, "rc2-40-cbc", enc_main}, + { FT_cipher, "rc2-40-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_BF - {FUNC_TYPE_CIPHER, "bf-cbc", enc_main}, + { FT_cipher, "bf-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_BF - {FUNC_TYPE_CIPHER, "bf-ecb", enc_main}, + { FT_cipher, "bf-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_BF - {FUNC_TYPE_CIPHER, "bf-cfb", enc_main}, + { FT_cipher, "bf-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_BF - {FUNC_TYPE_CIPHER, "bf-ofb", enc_main}, + { FT_cipher, "bf-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast5-cbc", enc_main}, + { FT_cipher, "cast5-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast5-ecb", enc_main}, + { FT_cipher, "cast5-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast5-cfb", enc_main}, + { FT_cipher, "cast5-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast5-ofb", enc_main}, + { FT_cipher, "cast5-ofb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_CAST - {FUNC_TYPE_CIPHER, "cast-cbc", enc_main}, + { FT_cipher, "cast-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC5 - {FUNC_TYPE_CIPHER, "rc5-cbc", enc_main}, + { FT_cipher, "rc5-cbc", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC5 - {FUNC_TYPE_CIPHER, "rc5-ecb", enc_main}, + { FT_cipher, "rc5-ecb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC5 - {FUNC_TYPE_CIPHER, "rc5-cfb", enc_main}, + { FT_cipher, "rc5-cfb", enc_main, enc_options }, #endif #ifndef OPENSSL_NO_RC5 - {FUNC_TYPE_CIPHER, "rc5-ofb", enc_main}, + { FT_cipher, "rc5-ofb", enc_main, enc_options }, #endif - {0, NULL, NULL} + { 0, NULL, NULL} }; +#endif diff --git a/apps/progs.pl b/apps/progs.pl index 09dd00b7ee..38e091e26e 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -1,67 +1,80 @@ #!/usr/local/bin/perl - -print "/* apps/progs.h */\n"; -print "/* automatically generated by progs.pl for openssl.c */\n\n"; - -grep(s/^asn1pars$/asn1parse/,@ARGV); - -foreach (@ARGV) - { printf "extern int %s_main(int argc, char *argv[]);\n",$_; } +# Generate progs.h file from list of "programs" passed on the command line. print <<'EOF'; +/* + * Automatically generated by progs.pl for openssl.c + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * See the openssl.c for copyright details. + */ -#define FUNC_TYPE_GENERAL 1 -#define FUNC_TYPE_MD 2 -#define FUNC_TYPE_CIPHER 3 -#define FUNC_TYPE_PKEY 4 -#define FUNC_TYPE_MD_ALG 5 -#define FUNC_TYPE_CIPHER_ALG 6 +typedef enum FUNC_TYPE { + FT_none, FT_general, FT_md, FT_cipher, FT_pkey, + FT_md_alg, FT_cipher_alg +} FUNC_TYPE; -typedef struct { - int type; +typedef struct function_st { + FUNC_TYPE type; const char *name; - int (*func) (int argc, char *argv[]); + int (*func)(int argc,char *argv[]); + const OPTIONS *help; } FUNCTION; -DECLARE_LHASH_OF(FUNCTION); -FUNCTION functions[] = { EOF -foreach (@ARGV) - { - push(@files,$_); - $str=" {FUNC_TYPE_GENERAL, \"$_\", ${_}_main},\n"; - if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/)) - { print "#if !defined(OPENSSL_NO_SOCK)\n${str}#endif\n"; } - elsif ( ($_ =~ /^engine$/)) - { print "#ifndef OPENSSL_NO_ENGINE\n${str}#endif\n"; } - elsif ( ($_ =~ /^rsa$/) || ($_ =~ /^genrsa$/) || ($_ =~ /^rsautl$/)) - { print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n"; } - elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/)) - { print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; } - elsif ( ($_ =~ /^ec$/) || ($_ =~ /^ecparam$/)) - { print "#ifndef OPENSSL_NO_EC\n${str}#endif\n";} - elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/)) - { print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; } - elsif ( ($_ =~ /^pkcs12$/)) - { print "#if !defined(OPENSSL_NO_DES)\n${str}#endif\n"; } - elsif ( ($_ =~ /^cms$/)) - { print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; } - elsif ( ($_ =~ /^ocsp$/)) - { print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; } - elsif ( ($_ =~ /^srp$/)) - { print "#ifndef OPENSSL_NO_SRP\n${str}#endif\n"; } - else - { print $str; } +grep(s/\.o//, @ARGV); +grep(s/^asn1pars$/asn1parse/, @ARGV); +grep(s/^crl2p7$/crl2pkcs7/, @ARGV); +push @ARGV, 'list'; +push @ARGV, 'help'; +push @ARGV, 'exit'; + +foreach (@ARGV) { + printf "extern int %s_main(int argc, char *argv[]);\n", $_; +} + +printf "\n#ifdef INCLUDE_FUNCTION_TABLE\n"; +foreach (@ARGV) { + printf "extern OPTIONS %s_options[];\n", $_; +} +printf "FUNCTION functions[] = {\n"; +foreach (@ARGV) { + $str=" { FT_general, \"$_\", ${_}_main, ${_}_options },\n"; + if (/^s_/ || /^ciphers$/) { + print "#if !defined(OPENSSL_NO_SOCK)\n${str}#endif\n"; + } elsif (/^engine$/) { + print "#ifndef OPENSSL_NO_ENGINE\n${str}#endif\n"; + } elsif (/^rsa$/ || /^genrsa$/ || /^rsautl$/) { + print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n"; + } elsif (/^dsa$/ || /^gendsa$/ || /^dsaparam$/) { + print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; + } elsif (/^ec$/ || /^ecparam$/) { + print "#ifndef OPENSSL_NO_EC\n${str}#endif\n"; + } elsif (/^dh$/ || /^gendh$/ || /^dhparam$/) { + print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; + } elsif (/^pkcs12$/) { + print "#if !defined(OPENSSL_NO_DES)\n${str}#endif\n"; + } elsif (/^cms$/) { + print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; + } elsif (/^ocsp$/) { + print "#ifndef OPENSSL_NO_OCSP\n${str}#endif\n"; + } elsif (/^srp$/) { + print "#ifndef OPENSSL_NO_SRP\n${str}#endif\n"; + } else { + print $str; } +} -foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160","sha224","sha256","sha384","sha512") - { - push(@files,$_); +foreach ( + "md2", "md4", "md5", + "md_ghost94", + "sha", "sha1", "sha224", "sha256", "sha384", "sha512", + "mdc2", "rmd160" +) { printf "#ifndef OPENSSL_NO_".uc($_)."\n" if ! /sha/; - printf " {FUNC_TYPE_MD, \"".$_."\", dgst_main},\n"; + printf " { FT_md, \"".$_."\", dgst_main},\n"; printf "#endif\n" if ! /sha/; - } +} foreach ( "aes-128-cbc", "aes-128-ecb", @@ -82,23 +95,35 @@ foreach ( "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", - "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb") - { - push(@files,$_); - - $t=sprintf(" {FUNC_TYPE_CIPHER, \"%s\", enc_main},\n", $_); - if ($_ =~ /des/) { $t="#ifndef OPENSSL_NO_DES\n${t}#endif\n"; } - elsif ($_ =~ /aes/) { $t="#ifndef OPENSSL_NO_AES\n${t}#endif\n"; } - elsif ($_ =~ /camellia/) { $t="#ifndef OPENSSL_NO_CAMELLIA\n${t}#endif\n"; } - elsif ($_ =~ /idea/) { $t="#ifndef OPENSSL_NO_IDEA\n${t}#endif\n"; } - elsif ($_ =~ /seed/) { $t="#ifndef OPENSSL_NO_SEED\n${t}#endif\n"; } - elsif ($_ =~ /rc4/) { $t="#ifndef OPENSSL_NO_RC4\n${t}#endif\n"; } - elsif ($_ =~ /rc2/) { $t="#ifndef OPENSSL_NO_RC2\n${t}#endif\n"; } - elsif ($_ =~ /bf/) { $t="#ifndef OPENSSL_NO_BF\n${t}#endif\n"; } - elsif ($_ =~ /cast/) { $t="#ifndef OPENSSL_NO_CAST\n${t}#endif\n"; } - elsif ($_ =~ /rc5/) { $t="#ifndef OPENSSL_NO_RC5\n${t}#endif\n"; } - elsif ($_ =~ /zlib/) { $t="#ifdef ZLIB\n${t}#endif\n"; } - print $t; + "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb" +) { + $str=" { FT_cipher, \"$_\", enc_main, enc_options },\n"; + if (/des/) { + printf "#ifndef OPENSSL_NO_DES\n${str}#endif\n"; + } elsif (/aes/) { + printf "#ifndef OPENSSL_NO_AES\n${str}#endif\n"; + } elsif (/camellia/) { + printf "#ifndef OPENSSL_NO_CAMELLIA\n${str}#endif\n"; + } elsif (/idea/) { + printf "#ifndef OPENSSL_NO_IDEA\n${str}#endif\n"; + } elsif (/seed/) { + printf "#ifndef OPENSSL_NO_SEED\n${str}#endif\n"; + } elsif (/rc4/) { + printf "#ifndef OPENSSL_NO_RC4\n${str}#endif\n"; + } elsif (/rc2/) { + printf "#ifndef OPENSSL_NO_RC2\n${str}#endif\n"; + } elsif (/bf/) { + printf "#ifndef OPENSSL_NO_BF\n${str}#endif\n"; + } elsif (/cast/) { + printf "#ifndef OPENSSL_NO_CAST\n${str}#endif\n"; + } elsif (/rc5/) { + printf "#ifndef OPENSSL_NO_RC5\n${str}#endif\n"; + } elsif (/zlib/) { + printf "#ifdef ZLIB\n${str}#endif\n"; + } else { + print $str; } +} -print " {0, NULL, NULL}\n};\n"; +print " { 0, NULL, NULL}\n};\n"; +printf "#endif\n"; diff --git a/apps/rand.c b/apps/rand.c index 45f16b9094..9a73935acc 100644 --- a/apps/rand.c +++ b/apps/rand.c @@ -1,4 +1,3 @@ -/* apps/rand.c */ /* ==================================================================== * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * @@ -63,135 +62,87 @@ #include #include -#undef PROG -#define PROG rand_main - -/*- - * -out file - write to file - * -rand file:file - PRNG seed files - * -base64 - base64 encode output - * -hex - hex encode output - * num - write 'num' bytes - */ - -int MAIN(int, char **); - -int MAIN(int argc, char **argv) -{ - int i, r, ret = 1; - int badopt; - char *outfile = NULL; - char *inrand = NULL; - int base64 = 0; - int hex = 0; - BIO *out = NULL; - int num = -1; +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX +} OPTION_CHOICE; + +OPTIONS rand_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"out", OPT_OUT, '>', "Output file"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"base64", OPT_BASE64, '-', "Base64 encode output"}, + {"hex", OPT_HEX, '-', "Hex encode output"}, #ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {NULL} +}; - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto err; - - badopt = 0; - i = 0; - while (!badopt && argv[++i] != NULL) { - if (strcmp(argv[i], "-out") == 0) { - if ((argv[i + 1] != NULL) && (outfile == NULL)) - outfile = argv[++i]; - else - badopt = 1; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(argv[i], "-engine") == 0) { - if ((argv[i + 1] != NULL) && (engine == NULL)) - engine = argv[++i]; - else - badopt = 1; +int rand_main(int argc, char **argv) +{ + BIO *out = NULL; + char *engine = NULL, *inrand = NULL, *outfile = NULL, *prog; + OPTION_CHOICE o; + int base64 = 0, hex = 0, i, num = -1, r, ret = 1; + + prog = opt_init(argc, argv, rand_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(rand_options); + ret = 0; + goto end; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_BASE64: + base64 = 1; + break; + case OPT_HEX: + hex = 1; + break; } -#endif - else if (strcmp(argv[i], "-rand") == 0) { - if ((argv[i + 1] != NULL) && (inrand == NULL)) - inrand = argv[++i]; - else - badopt = 1; - } else if (strcmp(argv[i], "-base64") == 0) { - if (!base64) - base64 = 1; - else - badopt = 1; - } else if (strcmp(argv[i], "-hex") == 0) { - if (!hex) - hex = 1; - else - badopt = 1; - } else if (isdigit((unsigned char)argv[i][0])) { - if (num < 0) { - r = sscanf(argv[i], "%d", &num); - if (r == 0 || num < 0) - badopt = 1; - } else - badopt = 1; - } else - badopt = 1; } + argc = opt_num_rest(); + argv = opt_rest(); - if (hex && base64) - badopt = 1; + if (argc != 1 || (hex && base64)) + goto opthelp; + if (sscanf(argv[0], "%d", &num) != 1 || num < 0) + goto opthelp; - if (num < 0) - badopt = 1; - - if (badopt) { - BIO_printf(bio_err, "Usage: rand [options] num\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-out file - write to file\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e - use engine e, possibly a hardware device.\n"); -#endif - BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", - LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, "-base64 - base64 encode output\n"); - BIO_printf(bio_err, "-hex - hex encode output\n"); - goto err; - } #ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); #endif - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); - out = BIO_new(BIO_s_file()); + out = bio_open_default(outfile, "w"); if (out == NULL) - goto err; - if (outfile != NULL) - r = BIO_write_filename(out, outfile); - else { - r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } - if (r <= 0) - goto err; + goto end; if (base64) { BIO *b64 = BIO_new(BIO_f_base64()); if (b64 == NULL) - goto err; + goto end; out = BIO_push(b64, out); } @@ -204,7 +155,7 @@ int MAIN(int argc, char **argv) chunk = sizeof buf; r = RAND_bytes(buf, chunk); if (r <= 0) - goto err; + goto end; if (!hex) BIO_write(out, buf, chunk); else { @@ -217,12 +168,10 @@ int MAIN(int argc, char **argv) BIO_puts(out, "\n"); (void)BIO_flush(out); - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); ret = 0; - err: - ERR_print_errors(bio_err); + end: BIO_free_all(out); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/req.c b/apps/req.c index 3cedf2c8a6..1237c33ec1 100644 --- a/apps/req.c +++ b/apps/req.c @@ -1,4 +1,3 @@ -/* apps/req.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -93,30 +92,6 @@ #define DEFAULT_KEY_LENGTH 512 #define MIN_KEY_LENGTH 384 -#undef PROG -#define PROG req_main - -/*- - * -inform arg - input format - default PEM (DER or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -verify - check request signature - * -noout - don't print stuff out. - * -text - print out human readable text. - * -nodes - no des encryption - * -config file - Load configuration file. - * -key file - make a request using key in file (or use it for verification). - * -keyform arg - key file format. - * -rand file(s) - load the file(s) into the PRNG. - * -newkey - make a key and a request. - * -modulus - print RSA modulus. - * -pubkey - output Public Key. - * -x509 - output a self signed X509 structure instead. - * -asn1-kludge - output new certificate request in a format that some CA's - * require. This format is wrong - */ - static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, int attribs, unsigned long chtype); static int build_subject(X509_REQ *req, char *subj, unsigned long chtype, @@ -137,323 +112,270 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def, static int genpkey_cb(EVP_PKEY_CTX *ctx); static int req_check_len(int len, int n_min, int n_max); static int check_end(const char *str, const char *end); -static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, +static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, int *pkey_type, long *pkeylen, char **palgnam, ENGINE *keygen_engine); -#ifndef MONOLITH -static char *default_config_file = NULL; -#endif static CONF *req_conf = NULL; static int batch = 0; -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY, + OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT, + OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY, + OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, + OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, + OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJECT, OPT_TEXT, OPT_X509, + OPT_ASN1_KLUDGE, OPT_NO_ASN1_KLUDGE, OPT_MULTIVALUE_RDN, + OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS, OPT_REQEXTS, OPT_MD +} OPTION_CHOICE; + +OPTIONS req_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"keygen_engine", OPT_KEYGEN_ENGINE, 's'}, + {"key", OPT_KEY, '<', "Use the private key contained in file"}, + {"keyform", OPT_KEYFORM, 'F', "Key file format"}, + {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"new", OPT_NEW, '-', "New request"}, + {"config", OPT_CONFIG, '<', "Request template file"}, + {"keyout", OPT_KEYOUT, '>', "File to send the key to"}, + {"passin", OPT_PASSIN, 's', "Private key password source"}, + {"passout", OPT_PASSOUT, 's'}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, + {"pkeyopt", OPT_PKEYOPT, 's'}, + {"sigopt", OPT_SIGOPT, 's'}, + {"batch", OPT_BATCH, '-', + "Do not ask anything during request generation"}, + {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, + {"modulus", OPT_MODULUS, '-', "RSA modulus"}, + {"verify", OPT_VERIFY, '-', "Verify signature on REQ"}, + {"nodes", OPT_NODES, '-', "Don't encrypt the output key"}, + {"noout", OPT_NOOUT, '-', "Do not output REQ"}, + {"verbose", OPT_VERBOSE, '-'}, + {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"reqopt", OPT_REQOPT, 's', "Various request text options"}, + {"text", OPT_TEXT, '-', "Text form of request"}, + {"x509", OPT_X509, '-', + "Output a x509 structure instead of a cert request"}, + {"asn1-kludge", OPT_ASN1_KLUDGE, '-', + "Output the request in a format that is wrong"}, + {OPT_MORE_STR, 1, 1, "(Required by some CA's)"}, + {"no-asn1-kludge", OPT_NO_ASN1_KLUDGE, '-'}, + {"subject", OPT_SUBJECT, 's', "Output the request's subject"}, + {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', + "Enable support for multivalued RDNs"}, + {"days", OPT_DAYS, 'p', "Number of days cert is valid for"}, + {"set-serial", OPT_SET_SERIAL, 'p', "Serial number to use"}, + {"extensions", OPT_EXTENSIONS, 's', + "Cert extension section (override value in config file)"}, + {"reqexts", OPT_REQEXTS, 's', + "Request extension section (override value in config file)"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"", OPT_MD, '-', "Any supported digest"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int req_main(int argc, char **argv) { + ASN1_INTEGER *serial = NULL; + BIO *in = NULL, *out = NULL; ENGINE *e = NULL, *gen_eng = NULL; - unsigned long nmflag = 0, reqflag = 0; - int ex = 1, x509 = 0, days = 30; - X509 *x509ss = NULL; - X509_REQ *req = NULL; + EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *genctx = NULL; - const char *keyalg = NULL; - char *keyalgstr = NULL; STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; - EVP_PKEY *pkey = NULL; - int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1; - long newkey = -1; - BIO *in = NULL, *out = NULL; - int informat, outformat, verify = 0, noout = 0, text = 0, keyform = - FORMAT_PEM; - int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; - char *infile, *outfile, *prog, *keyfile = NULL, *template = - NULL, *keyout = NULL; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - char *extensions = NULL; - char *req_exts = NULL; + X509 *x509ss = NULL; + X509_REQ *req = NULL; const EVP_CIPHER *cipher = NULL; - ASN1_INTEGER *serial = NULL; - int modulus = 0; - char *inrand = NULL; - char *passargin = NULL, *passargout = NULL; - char *passin = NULL, *passout = NULL; - char *p; - char *subj = NULL; - int multirdn = 0; const EVP_MD *md_alg = NULL, *digest = NULL; - unsigned long chtype = MBSTRING_ASC; -#ifndef MONOLITH - char *to_free; - long errline; -#endif + char *engine = NULL, *extensions = NULL, *infile = NULL; + char *outfile = NULL, *keyfile = NULL, *inrand = NULL; + char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL; + char *passin = NULL, *passout = NULL, *req_exts = NULL, *subj = NULL; + char *template = NULL, *keyout = NULL; + const char *keyalg = NULL; + OPTION_CHOICE o; + int ret = 1, x509 = 0, days = 30, i = 0, newreq = 0, verbose = + 0, pkey_type = -1; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM; + int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0; + int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; + long newkey = -1; + unsigned long chtype = MBSTRING_ASC, nmflag = 0, reqflag = 0; - req_conf = NULL; #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #endif - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } + + prog = opt_init(argc, argv, req_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(req_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; #ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } else if (strcmp(*argv, "-keygen_engine") == 0) { - if (--argc < 1) - goto bad; - gen_eng = ENGINE_by_id(*(++argv)); + case OPT_ENGINE: + engine = optarg; + break; + case OPT_KEYGEN_ENGINE: + gen_eng = ENGINE_by_id(opt_arg()); if (gen_eng == NULL) { BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); goto end; } - } + break; #endif - else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); - } else if (strcmp(*argv, "-pubkey") == 0) { + case OPT_KEY: + keyfile = opt_arg(); + break; + case OPT_PUBKEY: pubkey = 1; - } else if (strcmp(*argv, "-new") == 0) { + break; + case OPT_NEW: newreq = 1; - } else if (strcmp(*argv, "-config") == 0) { - if (--argc < 1) - goto bad; - template = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - keyform = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-keyout") == 0) { - if (--argc < 1) - goto bad; - keyout = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } else if (strcmp(*argv, "-newkey") == 0) { - if (--argc < 1) - goto bad; - keyalg = *(++argv); + break; + case OPT_CONFIG: + template = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyform)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_KEYOUT: + keyout = opt_arg(); + break; + case OPT_PASSIN: + passargin = opt_arg(); + break; + case OPT_PASSOUT: + passargout = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_NEWKEY: + keyalg = opt_arg(); newreq = 1; - } else if (strcmp(*argv, "-pkeyopt") == 0) { - if (--argc < 1) - goto bad; + break; + case OPT_PKEYOPT: if (!pkeyopts) pkeyopts = sk_OPENSSL_STRING_new_null(); - if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-sigopt") == 0) { - if (--argc < 1) - goto bad; + if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, opt_arg())) + goto opthelp; + break; + case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-batch") == 0) + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto opthelp; + break; + case OPT_BATCH: batch = 1; - else if (strcmp(*argv, "-newhdr") == 0) + break; + case OPT_NEWHDR: newhdr = 1; - else if (strcmp(*argv, "-modulus") == 0) + break; + case OPT_MODULUS: modulus = 1; - else if (strcmp(*argv, "-verify") == 0) + break; + case OPT_VERIFY: verify = 1; - else if (strcmp(*argv, "-nodes") == 0) + break; + case OPT_NODES: nodes = 1; - else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-verbose") == 0) + break; + case OPT_VERBOSE: verbose = 1; - else if (strcmp(*argv, "-utf8") == 0) + break; + case OPT_UTF8: chtype = MBSTRING_UTF8; - else if (strcmp(*argv, "-nameopt") == 0) { - if (--argc < 1) - goto bad; - if (!set_name_ex(&nmflag, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-reqopt") == 0) { - if (--argc < 1) - goto bad; - if (!set_cert_ex(&reqflag, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-subject") == 0) - subject = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_NAMEOPT: + if (!set_name_ex(&nmflag, opt_arg())) + goto opthelp; + break; + case OPT_REQOPT: + if (!set_cert_ex(&reqflag, opt_arg())) + goto opthelp; + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-x509") == 0) + break; + case OPT_X509: x509 = 1; - else if (strcmp(*argv, "-asn1-kludge") == 0) + break; + case OPT_ASN1_KLUDGE: kludge = 1; - else if (strcmp(*argv, "-no-asn1-kludge") == 0) + break; + case OPT_NO_ASN1_KLUDGE: kludge = 0; - else if (strcmp(*argv, "-subj") == 0) { - if (--argc < 1) - goto bad; - subj = *(++argv); - } else if (strcmp(*argv, "-multivalue-rdn") == 0) + break; + multirdn = 1; + case OPT_DAYS: + days = atoi(opt_arg()); + break; + case OPT_SET_SERIAL: + serial = s2i_ASN1_INTEGER(NULL, opt_arg()); + if (serial == NULL) + goto opthelp; + break; + case OPT_SUBJECT: + subj = opt_arg(); + break; + case OPT_MULTIVALUE_RDN: multirdn = 1; - else if (strcmp(*argv, "-days") == 0) { - if (--argc < 1) - goto bad; - days = atoi(*(++argv)); - if (days == 0) - days = 30; - } else if (strcmp(*argv, "-set_serial") == 0) { - if (--argc < 1) - goto bad; - serial = s2i_ASN1_INTEGER(NULL, *(++argv)); - if (!serial) - goto bad; - } else if (strcmp(*argv, "-extensions") == 0) { - if (--argc < 1) - goto bad; - extensions = *(++argv); - } else if (strcmp(*argv, "-reqexts") == 0) { - if (--argc < 1) - goto bad; - req_exts = *(++argv); - } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) { - /* ok */ + break; + case OPT_EXTENSIONS: + extensions = opt_arg(); + break; + case OPT_REQEXTS: + req_exts = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_unknown(), &md_alg)) + goto opthelp; digest = md_alg; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; } - argc--; - argv++; - } - - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); - BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, " -text text form of request\n"); - BIO_printf(bio_err, " -pubkey output public key\n"); - BIO_printf(bio_err, " -noout do not output REQ\n"); - BIO_printf(bio_err, " -verify verify signature on REQ\n"); - BIO_printf(bio_err, " -modulus RSA modulus\n"); - BIO_printf(bio_err, " -nodes don't encrypt the output key\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device\n"); -#endif - BIO_printf(bio_err, " -subject output the request's subject\n"); - BIO_printf(bio_err, " -passin private key password source\n"); - BIO_printf(bio_err, - " -key file use the private key contained in file\n"); - BIO_printf(bio_err, " -keyform arg key file format\n"); - BIO_printf(bio_err, " -keyout arg file to send the key to\n"); - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, - " -newkey rsa:bits generate a new RSA key of 'bits' in size\n"); - BIO_printf(bio_err, - " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n"); -#ifndef OPENSSL_NO_EC - BIO_printf(bio_err, - " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); -#endif - BIO_printf(bio_err, - " -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n"); - BIO_printf(bio_err, " -config file request template file.\n"); - BIO_printf(bio_err, - " -subj arg set or modify request subject\n"); - BIO_printf(bio_err, - " -multivalue-rdn enable support for multivalued RDNs\n"); - BIO_printf(bio_err, " -new new request.\n"); - BIO_printf(bio_err, - " -batch do not ask anything during request generation\n"); - BIO_printf(bio_err, - " -x509 output a x509 structure instead of a cert. req.\n"); - BIO_printf(bio_err, - " -days number of days a certificate generated by -x509 is valid for.\n"); - BIO_printf(bio_err, - " -set_serial serial number to use for a certificate generated by -x509.\n"); - BIO_printf(bio_err, - " -newhdr output \"NEW\" in the header lines\n"); - BIO_printf(bio_err, - " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); - BIO_printf(bio_err, - " have been reported as requiring\n"); - BIO_printf(bio_err, - " -extensions .. specify certificate extension section (override value in config file)\n"); - BIO_printf(bio_err, - " -reqexts .. specify request extension section (override value in config file)\n"); - BIO_printf(bio_err, - " -utf8 input characters are UTF8 (default ASCII)\n"); - BIO_printf(bio_err, - " -nameopt arg - various certificate name options\n"); - BIO_printf(bio_err, - " -reqopt arg - various request text options\n\n"); - goto end; } + argc = opt_num_rest(); + argv = opt_rest(); - ERR_load_crypto_strings(); - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } -#ifndef MONOLITH /* else this has happened in openssl.c - * (global `config') */ - /* Lets load up our environment a little */ - p = getenv("OPENSSL_CONF"); - if (p == NULL) - p = getenv("SSLEAY_CONF"); - if (p == NULL) - p = to_free = make_config_name(); - default_config_file = p; - config = NCONF_new(NULL); - i = NCONF_load(config, p, &errline); -#endif if (template != NULL) { long errline = -1; @@ -481,8 +403,6 @@ int MAIN(int argc, char **argv) } if (req_conf != NULL) { - if (!load_config(bio_err, req_conf)) - goto end; p = NCONF_get_string(req_conf, NULL, "oid_file"); if (p == NULL) ERR_clear_error(); @@ -501,16 +421,17 @@ int MAIN(int argc, char **argv) } } } - if (!add_oid_section(bio_err, req_conf)) + if (!add_oid_section(req_conf)) goto end; if (md_alg == NULL) { p = NCONF_get_string(req_conf, SECTION, "default_md"); if (p == NULL) ERR_clear_error(); - if (p != NULL) { - if ((md_alg = EVP_get_digestbyname(p)) != NULL) - digest = md_alg; + else { + if (!opt_md(p, &md_alg)) + goto opthelp; + digest = md_alg; } } @@ -577,29 +498,20 @@ int MAIN(int argc, char **argv) goto end; } } - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - if ((in == NULL) || (out == NULL)) - goto end; - #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif if (keyfile != NULL) { - pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, - "Private Key"); + pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); if (!pkey) { - /* - * load_key() has already printed an appropriate message - */ + /* load_key() has already printed an appropriate message */ goto end; } else { char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); if (randfile == NULL) ERR_clear_error(); - app_RAND_load_file(randfile, bio_err, 0); + app_RAND_load_file(randfile, 0); } } @@ -607,7 +519,7 @@ int MAIN(int argc, char **argv) char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); if (randfile == NULL) ERR_clear_error(); - app_RAND_load_file(randfile, bio_err, 0); + app_RAND_load_file(randfile, 0); if (inrand) app_RAND_load_files(inrand); @@ -616,7 +528,7 @@ int MAIN(int argc, char **argv) } if (keyalg) { - genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, + genctx = set_keygen_ctx(keyalg, &pkey_type, &newkey, &keyalgstr, gen_eng); if (!genctx) goto end; @@ -631,7 +543,7 @@ int MAIN(int argc, char **argv) } if (!genctx) { - genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey, + genctx = set_keygen_ctx(NULL, &pkey_type, &newkey, &keyalgstr, gen_eng); if (!genctx) goto end; @@ -663,7 +575,7 @@ int MAIN(int argc, char **argv) EVP_PKEY_CTX_free(genctx); genctx = NULL; - app_RAND_write_file(randfile, bio_err); + app_RAND_write_file(randfile); if (keyout == NULL) { keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); @@ -671,22 +583,13 @@ int MAIN(int argc, char **argv) ERR_clear_error(); } - if (keyout == NULL) { + if (keyout == NULL) BIO_printf(bio_err, "writing new private key to stdout\n"); - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { + else BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); - if (BIO_write_filename(out, keyout) <= 0) { - perror(keyout); - goto end; - } - } + out = bio_open_default(keyout, "w"); + if (out == NULL) + goto end; p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); if (p == NULL) { @@ -721,24 +624,14 @@ int MAIN(int argc, char **argv) * 'format' info should not be changed. */ kludge = -1; - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } + in = bio_open_default(infile, RB(informat)); + if (in == NULL) + goto end; if (informat == FORMAT_ASN1) req = d2i_X509_REQ_bio(in, NULL); - else if (informat == FORMAT_PEM) + else req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, - "bad input format specified for X509 request\n"); - goto end; - } if (req == NULL) { BIO_printf(bio_err, "unable to load X509 request\n"); goto end; @@ -814,7 +707,7 @@ int MAIN(int argc, char **argv) goto end; } - i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts); + i = do_X509_sign(x509ss, pkey, digest, sigopts); if (!i) { ERR_print_errors(bio_err); goto end; @@ -835,7 +728,7 @@ int MAIN(int argc, char **argv) req_exts); goto end; } - i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts); + i = do_X509_REQ_sign(req, pkey, digest, sigopts); if (!i) { ERR_print_errors(bio_err); goto end; @@ -857,7 +750,7 @@ int MAIN(int argc, char **argv) if (build_subject(req, subj, chtype, multirdn) == 0) { BIO_printf(bio_err, "ERROR: cannot modify subject\n"); - ex = 1; + ret = 1; goto end; } @@ -874,9 +767,9 @@ int MAIN(int argc, char **argv) if (pkey == NULL) { pkey = X509_REQ_get_pubkey(req); + tmp = 1; if (pkey == NULL) goto end; - tmp = 1; } i = X509_REQ_verify(req, pkey); @@ -895,28 +788,15 @@ int MAIN(int argc, char **argv) } if (noout && !text && !modulus && !subject && !pubkey) { - ex = 0; + ret = 0; goto end; } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if ((keyout != NULL) && (strcmp(outfile, keyout) == 0)) - i = (int)BIO_append_filename(out, outfile); - else - i = (int)BIO_write_filename(out, outfile); - if (!i) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, + keyout != NULL && outfile != NULL && + strcmp(keyout, outfile) == 0 ? "a" : "w"); + if (out == NULL) + goto end; if (pubkey) { EVP_PKEY *tpubkey; @@ -971,15 +851,10 @@ int MAIN(int argc, char **argv) if (!noout && !x509) { if (outformat == FORMAT_ASN1) i = i2d_X509_REQ_bio(out, req); - else if (outformat == FORMAT_PEM) { - if (newhdr) - i = PEM_write_bio_X509_REQ_NEW(out, req); - else - i = PEM_write_bio_X509_REQ(out, req); - } else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } + else if (newhdr) + i = PEM_write_bio_X509_REQ_NEW(out, req); + else + i = PEM_write_bio_X509_REQ(out, req); if (!i) { BIO_printf(bio_err, "unable to write X509 request\n"); goto end; @@ -988,24 +863,16 @@ int MAIN(int argc, char **argv) if (!noout && x509 && (x509ss != NULL)) { if (outformat == FORMAT_ASN1) i = i2d_X509_bio(out, x509ss); - else if (outformat == FORMAT_PEM) + else i = PEM_write_bio_X509(out, x509ss); - else { - BIO_printf(bio_err, "bad output format specified for outfile\n"); - goto end; - } if (!i) { BIO_printf(bio_err, "unable to write X509 certificate\n"); goto end; } } - ex = 0; + ret = 0; end: -#ifndef MONOLITH - if (to_free) - OPENSSL_free(to_free); -#endif - if (ex) { + if (ret) { ERR_print_errors(bio_err); } if ((req_conf != NULL) && (req_conf != config)) @@ -1032,8 +899,7 @@ int MAIN(int argc, char **argv) if (passargout && passout) OPENSSL_free(passout); OBJ_cleanup(); - apps_shutdown(); - OPENSSL_EXIT(ex); + return (ret); } static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, @@ -1499,7 +1365,7 @@ static int check_end(const char *str, const char *end) return strcmp(tmp, end); } -static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, +static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, int *pkey_type, long *pkeylen, char **palgnam, ENGINE *keygen_engine) { @@ -1536,7 +1402,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); if (!ameth) { - BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); + BIO_printf(bio_err, "Unknown algorithm %.*s\n", len, gstr); return NULL; } @@ -1558,7 +1424,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, if (paramfile) { pbio = BIO_new_file(paramfile, "r"); if (!pbio) { - BIO_printf(err, "Can't open parameter file %s\n", paramfile); + BIO_printf(bio_err, "Can't open parameter file %s\n", paramfile); return NULL; } param = PEM_read_bio_Parameters(pbio, NULL); @@ -1576,13 +1442,13 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, BIO_free(pbio); if (!param) { - BIO_printf(err, "Error reading parameter file %s\n", paramfile); + BIO_printf(bio_err, "Error reading parameter file %s\n", paramfile); return NULL; } if (*pkey_type == -1) *pkey_type = EVP_PKEY_id(param); else if (*pkey_type != EVP_PKEY_base_id(param)) { - BIO_printf(err, "Key Type does not match parameters\n"); + BIO_printf(bio_err, "Key Type does not match parameters\n"); EVP_PKEY_free(param); return NULL; } @@ -1594,7 +1460,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, const char *anam; ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); if (!ameth) { - BIO_puts(err, "Internal error: can't find key algorithm\n"); + BIO_puts(bio_err, "Internal error: can't find key algorithm\n"); return NULL; } EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); @@ -1613,21 +1479,21 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); if (!gctx) { - BIO_puts(err, "Error allocating keygen context\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error allocating keygen context\n"); + ERR_print_errors(bio_err); return NULL; } if (EVP_PKEY_keygen_init(gctx) <= 0) { - BIO_puts(err, "Error initializing keygen context\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error initializing keygen context\n"); + ERR_print_errors(bio_err); return NULL; } #ifndef OPENSSL_NO_RSA if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { - BIO_puts(err, "Error setting RSA keysize\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error setting RSA keysize\n"); + ERR_print_errors(bio_err); EVP_PKEY_CTX_free(gctx); return NULL; } @@ -1656,18 +1522,19 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) return 1; } -static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey, +static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) { EVP_PKEY_CTX *pkctx = NULL; int i; + EVP_MD_CTX_init(ctx); if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) return 0; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pkctx, sigopt) <= 0) { - BIO_printf(err, "parameter error \"%s\"\n", sigopt); + BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); return 0; } @@ -1675,39 +1542,42 @@ static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey, return 1; } -int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) { int rv; EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); - rv = do_sign_init(err, &mctx, pkey, md, sigopts); + rv = do_sign_init(&mctx, pkey, md, sigopts); if (rv > 0) rv = X509_sign_ctx(x, &mctx); EVP_MD_CTX_cleanup(&mctx); return rv > 0 ? 1 : 0; } -int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) { int rv; EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); - rv = do_sign_init(err, &mctx, pkey, md, sigopts); + rv = do_sign_init(&mctx, pkey, md, sigopts); if (rv > 0) rv = X509_REQ_sign_ctx(x, &mctx); EVP_MD_CTX_cleanup(&mctx); return rv > 0 ? 1 : 0; } -int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, +int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) { int rv; EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); - rv = do_sign_init(err, &mctx, pkey, md, sigopts); + rv = do_sign_init(&mctx, pkey, md, sigopts); if (rv > 0) rv = X509_CRL_sign_ctx(x, &mctx); EVP_MD_CTX_cleanup(&mctx); diff --git a/apps/rsa.c b/apps/rsa.c index 2f3f871a33..7f7069c899 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -1,4 +1,3 @@ -/* apps/rsa.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,6 +54,54 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ #include #ifndef OPENSSL_NO_RSA @@ -71,197 +118,142 @@ # include # include -# undef PROG -# define PROG rsa_main - -/*- - * -inform arg - input format - default PEM (one of DER, NET or PEM) - * -outform arg - output format - default PEM - * -in arg - input file - default stdin - * -out arg - output file - default stdout - * -des - encrypt output if PEM format with DES in cbc mode - * -des3 - encrypt output if PEM format - * -idea - encrypt output if PEM format - * -seed - encrypt output if PEM format - * -aes128 - encrypt output if PEM format - * -aes192 - encrypt output if PEM format - * -aes256 - encrypt output if PEM format - * -camellia128 - encrypt output if PEM format - * -camellia192 - encrypt output if PEM format - * -camellia256 - encrypt output if PEM format - * -text - print a text version - * -modulus - print the RSA key modulus - * -check - verify key consistency - * -pubin - Expect a public key in input file. - * -pubout - Output a public key. - */ - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, + OPT_PUBIN, OPT_PUBOUT, OPT_PASSOUT, OPT_PASSIN, + OPT_RSAPUBKEY_IN, OPT_RSAPUBKEY_OUT, OPT_PVK_STRONG, OPT_PVK_WEAK, + OPT_PVK_NONE, OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER +} OPTION_CHOICE; + +OPTIONS rsa_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'f', "Input format, one of DER NET PEM"}, + {"outform", OPT_OUTFORM, 'f', "Output format, one of DER NET PEM PVK"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, + {"pubout", OPT_PUBOUT, '-', "Output a public key"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"RSAPublicKey_in", OPT_RSAPUBKEY_IN, '-', "Input is an RSAPublicKye"}, + {"RSAPublicKey_out", OPT_RSAPUBKEY_OUT, '-', "Output is an RSAPublicKye"}, + {"pvk-strong", OPT_PVK_STRONG, '-'}, + {"pvk-weak", OPT_PVK_WEAK, '-'}, + {"pvk-none", OPT_PVK_NONE, '-'}, + {"noout", OPT_NOOUT, '-', "Don't print key out"}, + {"text", OPT_TEXT, '-', "Print the key in text"}, + {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, + {"check", OPT_CHECK, '-', "Verify key consistency"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {NULL} +}; -int MAIN(int argc, char **argv) +int rsa_main(int argc, char **argv) { ENGINE *e = NULL; - int ret = 1; + BIO *out = NULL; RSA *rsa = NULL; - int i, badops = 0, sgckey = 0; const EVP_CIPHER *enc = NULL; - BIO *out = NULL; - int informat, outformat, text = 0, check = 0, noout = 0; - int pubin = 0, pubout = 0; - char *infile, *outfile, *prog; - char *passargin = NULL, *passargout = NULL; - char *passin = NULL, *passout = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - int modulus = 0; -#ifndef OPENSSL_NO_RC4 - int pvk_encr = 2; + char *engine = NULL, *infile = NULL, *outfile = NULL, *prog; + char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; + int i; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; + int noout = 0, modulus = 0, pubin = 0, pubout = 0, pvk_encr = 2, ret = 1; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, rsa_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: +#ifdef OPENSSL_NO_RC4 + case OPT_PVK_STRONG: + case OPT_PVK_WEAK: + case OPT_PVK_NONE: #endif - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - - infile = NULL; - outfile = NULL; - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif - else if (strcmp(*argv, "-sgckey") == 0) - sgckey = 1; - else if (strcmp(*argv, "-pubin") == 0) + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(rsa_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_PUBIN: pubin = 1; - else if (strcmp(*argv, "-pubout") == 0) + break; + case OPT_PUBOUT: pubout = 1; - else if (strcmp(*argv, "-RSAPublicKey_in") == 0) + break; + case OPT_RSAPUBKEY_IN: pubin = 2; - else if (strcmp(*argv, "-RSAPublicKey_out") == 0) + break; + case OPT_RSAPUBKEY_OUT: pubout = 2; + break; #ifndef OPENSSL_NO_RC4 - else if (strcmp(*argv, "-pvk-strong") == 0) + case OPT_PVK_STRONG: pvk_encr = 2; - else if (strcmp(*argv, "-pvk-weak") == 0) + break; + case OPT_PVK_WEAK: pvk_encr = 1; - else if (strcmp(*argv, "-pvk-none") == 0) + break; + case OPT_PVK_NONE: pvk_encr = 0; + break; #endif - else if (strcmp(*argv, "-noout") == 0) + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = 1; - else if (strcmp(*argv, "-modulus") == 0) + break; + case OPT_MODULUS: modulus = 1; - else if (strcmp(*argv, "-check") == 0) + break; + case OPT_CHECK: check = 1; - else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &enc)) + goto opthelp; break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - BIO_printf(bio_err, "%s [options] outfile\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, - " -inform arg input format - one of DER NET PEM\n"); - BIO_printf(bio_err, - " -outform arg output format - one of DER NET PEM\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -sgckey Use IIS SGC key format\n"); - BIO_printf(bio_err, - " -passin arg input file pass phrase source\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, - " -passout arg output file pass phrase source\n"); - BIO_printf(bio_err, - " -des encrypt PEM output with cbc des\n"); - BIO_printf(bio_err, - " -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); -# ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, - " -idea encrypt PEM output with cbc idea\n"); -# endif -# ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, - " -seed encrypt PEM output with cbc seed\n"); -# endif -# ifndef OPENSSL_NO_AES - BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -# endif -# ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -# endif - BIO_printf(bio_err, " -text print the key in text\n"); - BIO_printf(bio_err, " -noout don't print key out\n"); - BIO_printf(bio_err, " -modulus print the RSA key modulus\n"); - BIO_printf(bio_err, " -check verify key consistency\n"); - BIO_printf(bio_err, - " -pubin expect a public key in input file\n"); - BIO_printf(bio_err, " -pubout output a public key\n"); # ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); + e = setup_engine(engine, 0); # endif - goto end; - } - - ERR_load_crypto_strings(); -# ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); -# endif - - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } @@ -271,8 +263,6 @@ int MAIN(int argc, char **argv) goto end; } - out = BIO_new(BIO_s_file()); - { EVP_PKEY *pkey; @@ -283,18 +273,12 @@ int MAIN(int argc, char **argv) tmpformat = FORMAT_PEMRSA; else if (informat == FORMAT_ASN1) tmpformat = FORMAT_ASN1RSA; - } else if (informat == FORMAT_NETSCAPE && sgckey) - tmpformat = FORMAT_IISSGC; - else + } else tmpformat = informat; - pkey = load_pubkey(bio_err, infile, tmpformat, 1, - passin, e, "Public Key"); + pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key"); } else - pkey = load_key(bio_err, infile, - (informat == FORMAT_NETSCAPE && sgckey ? - FORMAT_IISSGC : informat), 1, - passin, e, "Private Key"); + pkey = load_key(infile, informat, 1, passin, e, "Private Key"); if (pkey != NULL) rsa = EVP_PKEY_get1_RSA(pkey); @@ -306,20 +290,9 @@ int MAIN(int argc, char **argv) goto end; } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } + out = bio_open_default(outfile, "w"); + if (out == NULL) + goto end; if (text) if (!RSA_print(out, rsa, 0)) { @@ -379,13 +352,13 @@ int MAIN(int argc, char **argv) int size; i = 1; - size = i2d_RSA_NET(rsa, NULL, NULL, sgckey); + size = i2d_RSA_NET(rsa, NULL, NULL, 0); if ((p = (unsigned char *)OPENSSL_malloc(size)) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); goto end; } pp = p; - i2d_RSA_NET(rsa, &p, NULL, sgckey); + i2d_RSA_NET(rsa, &p, NULL, 0); BIO_write(out, (char *)pp, size); OPENSSL_free(pp); } @@ -428,8 +401,7 @@ int MAIN(int argc, char **argv) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } #else /* !OPENSSL_NO_RSA */ diff --git a/apps/rsautl.c b/apps/rsautl.c index d642f9ad97..04667469f6 100644 --- a/apps/rsautl.c +++ b/apps/rsautl.c @@ -1,4 +1,3 @@ -/* rsautl.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2000. @@ -75,150 +74,162 @@ # define KEY_PUBKEY 2 # define KEY_CERT 3 -static void usage(void); - -# undef PROG - -# define PROG rsautl_main - -int MAIN(int argc, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP, + OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931, + OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, + OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM +} OPTION_CHOICE; + +OPTIONS rsautl_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"inkey", OPT_INKEY, '<', "Input key"}, + {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, + {"pubin", OPT_PUBIN, '-', "Input is an RSA public"}, + {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"}, + {"ssl", OPT_SSL, '-', "Use SSL v2 padding"}, + {"raw", OPT_RAW, '-', "Use no padding"}, + {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"}, + {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"}, + {"sign", OPT_SIGN, '-', "Sign with private key"}, + {"verify", OPT_VERIFY, '-', "Verify with public key"}, + {"asn1parse", OPT_ASN1PARSE, '-'}, + {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, + {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, + {"rev", OPT_REV, '-'}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, + {"passin", OPT_PASSIN, 's', "Pass phrase source"}, +# ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +# endif + {NULL} +}; -int MAIN(int argc, char **argv) +int rsautl_main(int argc, char **argv) { - ENGINE *e = NULL; BIO *in = NULL, *out = NULL; - char *infile = NULL, *outfile = NULL; -# ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -# endif - char *keyfile = NULL; - char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; - int keyform = FORMAT_PEM; - char need_priv = 0, badarg = 0, rev = 0; - char hexdump = 0, asn1parse = 0; - X509 *x; + ENGINE *e = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; - unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; - char *passargin = NULL, *passin = NULL; - int rsa_inlen, rsa_outlen = 0; - int keysize; - - int ret = 1; - - argc--; - argv++; - - if (!bio_err) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - pad = RSA_PKCS1_PADDING; - - while (argc >= 1) { - if (!strcmp(*argv, "-in")) { - if (--argc < 1) - badarg = 1; - else - infile = *(++argv); - } else if (!strcmp(*argv, "-out")) { - if (--argc < 1) - badarg = 1; - else - outfile = *(++argv); - } else if (!strcmp(*argv, "-inkey")) { - if (--argc < 1) - badarg = 1; - else - keyfile = *(++argv); - } else if (!strcmp(*argv, "-passin")) { - if (--argc < 1) - badarg = 1; - else - passargin = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - badarg = 1; - else - keyform = str2fmt(*(++argv)); -# ifndef OPENSSL_NO_ENGINE - } else if (!strcmp(*argv, "-engine")) { - if (--argc < 1) - badarg = 1; - else - engine = *(++argv); -# endif - } else if (!strcmp(*argv, "-pubin")) { - key_type = KEY_PUBKEY; - } else if (!strcmp(*argv, "-certin")) { - key_type = KEY_CERT; - } else if (!strcmp(*argv, "-asn1parse")) + X509 *x; + char *engine = NULL, *infile = NULL, *outfile = NULL, *keyfile = NULL; + char *passinarg = NULL, *passin = NULL, *prog; + char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; + unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING; + int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1; + int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, rsautl_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(rsautl_options); + ret = 0; + goto end; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_ASN1PARSE: asn1parse = 1; - else if (!strcmp(*argv, "-hexdump")) + break; + case OPT_HEXDUMP: hexdump = 1; - else if (!strcmp(*argv, "-raw")) + break; + case OPT_RAW: pad = RSA_NO_PADDING; - else if (!strcmp(*argv, "-oaep")) + break; + case OPT_OAEP: pad = RSA_PKCS1_OAEP_PADDING; - else if (!strcmp(*argv, "-ssl")) + break; + case OPT_SSL: pad = RSA_SSLV23_PADDING; - else if (!strcmp(*argv, "-pkcs")) + break; + case OPT_PKCS: pad = RSA_PKCS1_PADDING; - else if (!strcmp(*argv, "-x931")) + break; + case OPT_X931: pad = RSA_X931_PADDING; - else if (!strcmp(*argv, "-sign")) { + break; + case OPT_SIGN: rsa_mode = RSA_SIGN; need_priv = 1; - } else if (!strcmp(*argv, "-verify")) + break; + case OPT_VERIFY: rsa_mode = RSA_VERIFY; - else if (!strcmp(*argv, "-rev")) + break; + case OPT_REV: rev = 1; - else if (!strcmp(*argv, "-encrypt")) + break; + case OPT_ENCRYPT: rsa_mode = RSA_ENCRYPT; - else if (!strcmp(*argv, "-decrypt")) { + break; + case OPT_DECRYPT: rsa_mode = RSA_DECRYPT; need_priv = 1; - } else - badarg = 1; - if (badarg) { - usage(); - goto end; + break; + case OPT_PUBIN: + key_type = KEY_PUBKEY; + break; + case OPT_CERTIN: + key_type = KEY_CERT; + break; + case OPT_INKEY: + keyfile = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); if (need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } # ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } /* FIXME: seed PRNG only if needed */ - app_RAND_load_file(NULL, bio_err, 0); + app_RAND_load_file(NULL, 0); switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(bio_err, keyfile, keyform, 0, - passin, e, "Private Key"); + pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: - pkey = load_pubkey(bio_err, keyfile, keyform, 0, - NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); break; case KEY_CERT: - x = load_cert(bio_err, keyfile, keyform, NULL, e, "Certificate"); + x = load_cert(keyfile, keyformat, NULL, e, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); @@ -239,30 +250,12 @@ int MAIN(int argc, char **argv) goto end; } - if (infile) { - if (!(in = BIO_new_file(infile, "rb"))) { - BIO_printf(bio_err, "Error Reading Input File\n"); - ERR_print_errors(bio_err); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - - if (outfile) { - if (!(out = BIO_new_file(outfile, "wb"))) { - BIO_printf(bio_err, "Error Reading Output File\n"); - ERR_print_errors(bio_err); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -# ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -# endif - } + in = bio_open_default(infile, "rb"); + if (in == NULL) + goto end; + out = bio_open_default(outfile, "wb"); + if (out == NULL) + goto end; keysize = RSA_size(rsa); @@ -270,7 +263,6 @@ int MAIN(int argc, char **argv) rsa_out = OPENSSL_malloc(keysize); if (!rsa_in || !rsa_out) { BIO_printf(bio_err, "Out of memory\n"); - ERR_print_errors(bio_err); goto end; } @@ -278,7 +270,7 @@ int MAIN(int argc, char **argv) rsa_inlen = BIO_read(in, rsa_in, keysize * 2); if (rsa_inlen <= 0) { BIO_printf(bio_err, "Error reading input Data\n"); - exit(1); + goto end; } if (rev) { int i; @@ -338,34 +330,6 @@ int MAIN(int argc, char **argv) return ret; } -static void usage() -{ - BIO_printf(bio_err, "Usage: rsautl [options]\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, "-inkey file input key\n"); - BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); - BIO_printf(bio_err, "-pubin input is an RSA public\n"); - BIO_printf(bio_err, - "-certin input is a certificate carrying an RSA public key\n"); - BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); - BIO_printf(bio_err, "-raw use no padding\n"); - BIO_printf(bio_err, - "-pkcs use PKCS#1 v1.5 padding (default)\n"); - BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); - BIO_printf(bio_err, "-sign sign with private key\n"); - BIO_printf(bio_err, "-verify verify with public key\n"); - BIO_printf(bio_err, "-encrypt encrypt with public key\n"); - BIO_printf(bio_err, "-decrypt decrypt with private key\n"); - BIO_printf(bio_err, "-hexdump hex dump output\n"); -# ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); - BIO_printf(bio_err, "-passin arg pass phrase source\n"); -# endif - -} - #else /* !OPENSSL_NO_RSA */ # if PEDANTIC diff --git a/apps/s_apps.h b/apps/s_apps.h index b0aeeffebf..db8d039178 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -178,9 +178,9 @@ int init_client(int *sock, const char *server, int port, int type); int init_client_unix(int *sock, const char *server); #endif int should_retry(int i); -int extract_port(const char *str, short *port_ptr); +int extract_port(const char *str, unsigned short *port_ptr); int extract_host_port(char *str, char **host_ptr, unsigned char *ip, - short *p); + unsigned short *p); long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret); @@ -202,15 +202,12 @@ typedef struct ssl_excert_st SSL_EXCERT; void ssl_ctx_set_excert(SSL_CTX *ctx, SSL_EXCERT *exc); void ssl_excert_free(SSL_EXCERT *exc); -int args_excert(char ***pargs, int *pargc, - int *badarg, BIO *err, SSL_EXCERT **pexc); -int load_excert(SSL_EXCERT **pexc, BIO *err); +int args_excert(int option, SSL_EXCERT **pexc); +int load_excert(SSL_EXCERT **pexc); void print_ssl_summary(BIO *bio, SSL *s); #ifdef HEADER_SSL_H -int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, - int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr); -int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, - STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake); +int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, + SSL_CTX *ctx, int no_ecdhe, int no_jpake); int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download); int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, diff --git a/apps/s_cb.c b/apps/s_cb.c index 06050dbc7c..ddd65a968d 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -1,4 +1,3 @@ -/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -109,12 +108,12 @@ * */ +/* callback functions used by s_client, s_server, and s_time */ #include #include +#include #define USE_SOCKETS -#define NON_MAIN #include "apps.h" -#undef NON_MAIN #undef USE_SOCKETS #include #include @@ -200,11 +199,6 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) { if (cert_file != NULL) { - /*- - SSL *ssl; - X509 *x509; - */ - if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) { BIO_printf(bio_err, "unable to get certificate from '%s'\n", @@ -221,21 +215,6 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) return (0); } - /*- - In theory this is no longer needed - ssl=SSL_new(ctx); - x509=SSL_get_certificate(ssl); - - if (x509 != NULL) { - EVP_PKEY *pktmp; - pktmp = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp, - SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - SSL_free(ssl); - */ - /* * If we are using DSA, we can copy the parameters from the private * key @@ -456,17 +435,17 @@ int ssl_print_curves(BIO *out, SSL *s, int noshared) { int i, ncurves, *curves, nid; const char *cname; + ncurves = SSL_get1_curves(s, NULL); if (ncurves <= 0) return 1; curves = OPENSSL_malloc(ncurves * sizeof(int)); if (!curves) { - BIO_puts(out, "Malloc error getting supported curves\n"); + BIO_printf(out, "Out of memory\n"); return 0; } SSL_get1_curves(s, curves); - BIO_puts(out, "Supported Elliptic Curves: "); for (i = 0; i < ncurves; i++) { if (i) @@ -1178,11 +1157,10 @@ static int set_cert_cb(SSL *ssl, void *arg) X509_NAME_print_ex(bio_err, X509_get_subject_name(exc->cert), 0, XN_FLAG_ONELINE); BIO_puts(bio_err, "\n"); - print_chain_flags(bio_err, ssl, rv); if (rv & CERT_PKEY_VALID) { if (!SSL_use_certificate(ssl, exc->cert) - || !SSL_use_PrivateKey(ssl, exc->key)) { + || !SSL_use_PrivateKey(ssl, exc->key)) { return 0; } /* @@ -1251,7 +1229,7 @@ void ssl_excert_free(SSL_EXCERT *exc) } } -int load_excert(SSL_EXCERT **pexc, BIO *err) +int load_excert(SSL_EXCERT **pexc) { SSL_EXCERT *exc = *pexc; if (!exc) @@ -1264,25 +1242,24 @@ int load_excert(SSL_EXCERT **pexc, BIO *err) } for (; exc; exc = exc->next) { if (!exc->certfile) { - BIO_printf(err, "Missing filename\n"); + BIO_printf(bio_err, "Missing filename\n"); return 0; } - exc->cert = load_cert(err, exc->certfile, exc->certform, + exc->cert = load_cert(exc->certfile, exc->certform, NULL, NULL, "Server Certificate"); if (!exc->cert) return 0; if (exc->keyfile) { - exc->key = load_key(err, exc->keyfile, exc->keyform, + exc->key = load_key(exc->keyfile, exc->keyform, 0, NULL, NULL, "Server Key"); } else { - exc->key = load_key(err, exc->certfile, exc->certform, + exc->key = load_key(exc->certfile, exc->certform, 0, NULL, NULL, "Server Key"); } if (!exc->key) return 0; if (exc->chainfile) { - exc->chain = load_certs(err, - exc->chainfile, FORMAT_PEM, + exc->chain = load_certs(exc->chainfile, FORMAT_PEM, NULL, NULL, "Server Chain"); if (!exc->chain) return 0; @@ -1291,86 +1268,70 @@ int load_excert(SSL_EXCERT **pexc, BIO *err) return 1; } -int args_excert(char ***pargs, int *pargc, - int *badarg, BIO *err, SSL_EXCERT **pexc) +enum range { OPT_X_ENUM }; + +int args_excert(int opt, SSL_EXCERT **pexc) { - char *arg = **pargs, *argn = (*pargs)[1]; SSL_EXCERT *exc = *pexc; - int narg = 2; - if (!exc) { - if (ssl_excert_prepend(&exc)) - *pexc = exc; - else { - BIO_printf(err, "Error initialising xcert\n"); - *badarg = 1; + + assert(opt > OPT_X__FIRST); + assert(opt < OPT_X__LAST); + + if (exc == NULL) { + if (!ssl_excert_prepend(&exc)) { + BIO_printf(bio_err, " %s: Error initialising xcert\n", + opt_getprog()); goto err; } + *pexc = exc; } - if (strcmp(arg, "-xcert") == 0) { - if (!argn) { - *badarg = 1; - return 1; - } + + switch ((enum range)opt) { + case OPT_X__FIRST: + case OPT_X__LAST: + return 0; + case OPT_X_CERT: if (exc->certfile && !ssl_excert_prepend(&exc)) { - BIO_printf(err, "Error adding xcert\n"); - *badarg = 1; + BIO_printf(bio_err, "%s: Error adding xcert\n", opt_getprog()); goto err; } - exc->certfile = argn; - } else if (strcmp(arg, "-xkey") == 0) { - if (!argn) { - *badarg = 1; - return 1; - } + exc->certfile = opt_arg(); + break; + case OPT_X_KEY: if (exc->keyfile) { - BIO_printf(err, "Key already specified\n"); - *badarg = 1; - return 1; - } - exc->keyfile = argn; - } else if (strcmp(arg, "-xchain") == 0) { - if (!argn) { - *badarg = 1; - return 1; - } - if (exc->chainfile) { - BIO_printf(err, "Chain already specified\n"); - *badarg = 1; - return 1; - } - exc->chainfile = argn; - } else if (strcmp(arg, "-xchain_build") == 0) { - narg = 1; - exc->build_chain = 1; - } else if (strcmp(arg, "-xcertform") == 0) { - if (!argn) { - *badarg = 1; + BIO_printf(bio_err, "%s: Key already specified\n", opt_getprog()); goto err; } - exc->certform = str2fmt(argn); - } else if (strcmp(arg, "-xkeyform") == 0) { - if (!argn) { - *badarg = 1; + exc->keyfile = opt_arg(); + break; + case OPT_X_CHAIN: + if (exc->chainfile) { + BIO_printf(bio_err, "%s: Chain already specified\n", + opt_getprog()); goto err; } - exc->keyform = str2fmt(argn); - } else - return 0; - - (*pargs) += narg; - - if (pargc) - *pargc -= narg; - - *pexc = exc; - + exc->chainfile = opt_arg(); + break; + case OPT_X_CHAIN_BUILD: + exc->build_chain = 1; + break; + case OPT_X_CERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->certform)) + return 0; + break; + case OPT_X_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->keyform)) + return 0; + break; + } return 1; err: - ERR_print_errors(err); - ssl_excert_free(exc); + ERR_print_errors(bio_err); + if (exc) + ssl_excert_free(exc); *pexc = NULL; - return 1; + return 0; } static void print_raw_cipherlist(BIO *bio, SSL *s) @@ -1438,72 +1399,31 @@ void print_ssl_summary(BIO *bio, SSL *s) #endif } -int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, - int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr) -{ - char *arg = **pargs, *argn = (*pargs)[1]; - int rv; - - /* Attempt to run SSL configuration command */ - rv = SSL_CONF_cmd_argv(cctx, pargc, pargs); - /* If parameter not recognised just return */ - if (rv == 0) - return 0; - /* see if missing argument error */ - if (rv == -3) { - BIO_printf(err, "%s needs an argument\n", arg); - *badarg = 1; - goto end; - } - /* Check for some other error */ - if (rv < 0) { - BIO_printf(err, "Error with command: \"%s %s\"\n", - arg, argn ? argn : ""); - *badarg = 1; - goto end; - } - /* Store command and argument */ - /* If only one argument processed store value as NULL */ - if (rv == 1) - argn = NULL; - if (!*pstr) - *pstr = sk_OPENSSL_STRING_new_null(); - if (!*pstr || !sk_OPENSSL_STRING_push(*pstr, arg) || - !sk_OPENSSL_STRING_push(*pstr, argn)) { - BIO_puts(err, "Memory allocation failure\n"); - goto end; - } - - end: - if (*badarg) - ERR_print_errors(err); - - return 1; -} - -int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, - STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake) +int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, + SSL_CTX *ctx, int no_ecdhe, int no_jpake) { int i; + SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) { - const char *param = sk_OPENSSL_STRING_value(str, i); - const char *value = sk_OPENSSL_STRING_value(str, i + 1); - /* - * If no_ecdhe or named curve already specified don't need a default. - */ - if (!no_ecdhe && !strcmp(param, "-named_curve")) + const char *flag = sk_OPENSSL_STRING_value(str, i); + const char *arg = sk_OPENSSL_STRING_value(str, i + 1); + /* If no_ecdhe or named curve already specified don't need a default. */ + if (!no_ecdhe && !strcmp(flag, "-named_curve")) no_ecdhe = 1; #ifndef OPENSSL_NO_JPAKE - if (!no_jpake && !strcmp(param, "-cipher")) { - BIO_puts(err, "JPAKE sets cipher to PSK\n"); + if (!no_jpake && !strcmp(flag, "-cipher")) { + BIO_puts(bio_err, "JPAKE sets cipher to PSK\n"); return 0; } #endif - if (SSL_CONF_cmd(cctx, param, value) <= 0) { - BIO_printf(err, "Error with command: \"%s %s\"\n", - param, value ? value : ""); - ERR_print_errors(err); + if (SSL_CONF_cmd(cctx, flag, arg) <= 0) { + if (arg) + BIO_printf(bio_err, "Error with command: \"%s %s\"\n", + flag, arg); + else + BIO_printf(bio_err, "Error with command: \"%s\"\n", flag); + ERR_print_errors(bio_err); return 0; } } @@ -1514,23 +1434,23 @@ int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, */ if (!no_ecdhe) { if (SSL_CONF_cmd(cctx, "-named_curve", "P-256") <= 0) { - BIO_puts(err, "Error setting EC curve\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error setting EC curve\n"); + ERR_print_errors(bio_err); return 0; } } #ifndef OPENSSL_NO_JPAKE if (!no_jpake) { if (SSL_CONF_cmd(cctx, "-cipher", "PSK") <= 0) { - BIO_puts(err, "Error setting cipher to PSK\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error setting cipher to PSK\n"); + ERR_print_errors(bio_err); return 0; } } #endif if (!SSL_CONF_CTX_finish(cctx)) { - BIO_puts(err, "Error finishing context\n"); - ERR_print_errors(err); + BIO_puts(bio_err, "Error finishing context\n"); + ERR_print_errors(bio_err); return 0; } return 1; diff --git a/apps/s_client.c b/apps/s_client.c index 761f352fe3..900efe7c86 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1,4 +1,3 @@ -/* apps/s_client.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -141,6 +140,7 @@ #include #include #include + /* * With IPv6, it looks like Digital has mixed up the proper order of * recursive header file inclusion, resulting in the compiler complaining @@ -172,22 +172,8 @@ typedef unsigned int u_int; # undef FIONBIO #endif -#undef PROG -#define PROG s_client_main - -/* - * #define SSL_HOST_NAME "www.netscape.com" - */ -/* - * #define SSL_HOST_NAME "193.118.187.102" - */ #define SSL_HOST_NAME "localhost" -/* no default cert. */ -/* - * #define TEST_CERT "client.pem" - */ - #undef BUFSIZZ #define BUFSIZZ 1024*8 @@ -196,32 +182,26 @@ extern int verify_error; extern int verify_return_error; extern int verify_quiet; -#ifdef FIONBIO static int c_nbio = 0; -#endif -static int c_Pause = 0; -static int c_debug = 0; -#ifndef OPENSSL_NO_TLSEXT static int c_tlsextdebug = 0; static int c_status_req = 0; -#endif +static int c_Pause = 0; +static int c_debug = 0; static int c_msg = 0; static int c_showcerts = 0; - static char *keymatexportlabel = NULL; static int keymatexportlen = 20; - -static void sc_usage(void); -static void print_stuff(BIO *berr, SSL *con, int full); -#ifndef OPENSSL_NO_TLSEXT -static int ocsp_resp_cb(SSL *s, void *arg); -#endif static BIO *bio_c_out = NULL; static BIO *bio_c_msg = NULL; static int c_quiet = 0; static int c_ign_eof = 0; static int c_brief = 0; +static void print_stuff(BIO *berr, SSL *con, int full); +#ifndef OPENSSL_NO_TLSEXT +static int ocsp_resp_cb(SSL *s, void *arg); +#endif + #ifndef OPENSSL_NO_PSK /* Default PSK identity and key */ static char *psk_identity = "Client_identity"; @@ -290,147 +270,6 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, } #endif -static void sc_usage(void) -{ - BIO_printf(bio_err, "usage: s_client args\n"); - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, " -host host - use -connect instead\n"); - BIO_printf(bio_err, " -port port - use -connect instead\n"); - BIO_printf(bio_err, - " -connect host:port - connect over TCP/IP (default is %s:%s)\n", - SSL_HOST_NAME, PORT_STR); - BIO_printf(bio_err, - " -unix path - connect over unix domain sockets\n"); - BIO_printf(bio_err, - " -verify arg - turn on peer certificate verification\n"); - BIO_printf(bio_err, - " -verify_return_error - return verification errors\n"); - BIO_printf(bio_err, - " -cert arg - certificate file to use, PEM format assumed\n"); - BIO_printf(bio_err, - " -certform arg - certificate format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -key arg - Private key file to use, in cert file if\n"); - BIO_printf(bio_err, " not specified but cert file is.\n"); - BIO_printf(bio_err, - " -keyform arg - key format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -pass arg - private key file pass phrase source\n"); - BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); - BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); - BIO_printf(bio_err, - " -trusted_first - Use local CA's first when building trust chain\n"); - BIO_printf(bio_err, - " -no_alt_chains - only ever use the first certificate chain found\n"); - BIO_printf(bio_err, - " -reconnect - Drop and re-make the connection with the same Session-ID\n"); - BIO_printf(bio_err, - " -pause - sleep(1) after each read(2) and write(2) system call\n"); - BIO_printf(bio_err, - " -prexit - print session information even on connection failure\n"); - BIO_printf(bio_err, - " -showcerts - show all certificates in the chain\n"); - BIO_printf(bio_err, " -debug - extra output\n"); -#ifdef WATT32 - BIO_printf(bio_err, " -wdebug - WATT-32 tcp debugging\n"); -#endif - BIO_printf(bio_err, " -msg - Show protocol messages\n"); - BIO_printf(bio_err, " -nbio_test - more ssl protocol testing\n"); - BIO_printf(bio_err, " -state - print the 'ssl' states\n"); -#ifdef FIONBIO - BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); -#endif - BIO_printf(bio_err, - " -crlf - convert LF from terminal into CRLF\n"); - BIO_printf(bio_err, " -quiet - no s_client output\n"); - BIO_printf(bio_err, - " -ign_eof - ignore input eof (default when -quiet)\n"); - BIO_printf(bio_err, " -no_ign_eof - don't ignore input eof\n"); -#ifndef OPENSSL_NO_PSK - BIO_printf(bio_err, " -psk_identity arg - PSK identity\n"); - BIO_printf(bio_err, " -psk arg - PSK in hex (without 0x)\n"); -# ifndef OPENSSL_NO_JPAKE - BIO_printf(bio_err, " -jpake arg - JPAKE secret to use\n"); -# endif -#endif -#ifndef OPENSSL_NO_SRP - BIO_printf(bio_err, - " -srpuser user - SRP authentification for 'user'\n"); - BIO_printf(bio_err, " -srppass arg - password for 'user'\n"); - BIO_printf(bio_err, - " -srp_lateuser - SRP username into second ClientHello message\n"); - BIO_printf(bio_err, - " -srp_moregroups - Tolerate other than the known g N values.\n"); - BIO_printf(bio_err, - " -srp_strength int - minimal length in bits for N (default %d).\n", - SRP_MINIMAL_N); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - BIO_printf(bio_err, " -ssl3 - just use SSLv3\n"); -#endif - BIO_printf(bio_err, " -tls1_2 - just use TLSv1.2\n"); - BIO_printf(bio_err, " -tls1_1 - just use TLSv1.1\n"); - BIO_printf(bio_err, " -tls1 - just use TLSv1\n"); - BIO_printf(bio_err, " -dtls1 - just use DTLSv1\n"); - BIO_printf(bio_err, " -fallback_scsv - send TLS_FALLBACK_SCSV\n"); - BIO_printf(bio_err, " -mtu - set the link layer MTU\n"); - BIO_printf(bio_err, - " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3 - turn off that protocol\n"); - BIO_printf(bio_err, - " -bugs - Switch on all SSL implementation bug workarounds\n"); - BIO_printf(bio_err, - " -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); - BIO_printf(bio_err, - " command to see what is available\n"); - BIO_printf(bio_err, - " -starttls prot - use the STARTTLS command before starting TLS\n"); - BIO_printf(bio_err, - " for those protocols that support it, where\n"); - BIO_printf(bio_err, - " 'prot' defines which one to assume. Currently,\n"); - BIO_printf(bio_err, - " only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); - BIO_printf(bio_err, " are supported.\n"); - BIO_printf(bio_err, - " -xmpphost host - When used with \"-starttls xmpp\" specifies the virtual host.\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine id - Initialise and use the specified engine\n"); -#endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n"); - BIO_printf(bio_err, " -sess_in arg - file to read SSL session from\n"); -#ifndef OPENSSL_NO_TLSEXT - BIO_printf(bio_err, - " -servername host - Set TLS extension servername in ClientHello\n"); - BIO_printf(bio_err, - " -tlsextdebug - hex dump of all TLS extensions received\n"); - BIO_printf(bio_err, - " -status - request certificate status from server\n"); - BIO_printf(bio_err, - " -no_ticket - disable use of RFC4507bis session tickets\n"); - BIO_printf(bio_err, - " -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n"); -# ifndef OPENSSL_NO_NEXTPROTONEG - BIO_printf(bio_err, - " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); -# endif - BIO_printf(bio_err, - " -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n"); -#endif - BIO_printf(bio_err, - " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); -#ifndef OPENSSL_NO_SRTP - BIO_printf(bio_err, - " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); -#endif - BIO_printf(bio_err, - " -keymatexport label - Export keying material using label\n"); - BIO_printf(bio_err, - " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); -} - #ifndef OPENSSL_NO_TLSEXT /* This is a context that we pass to callbacks */ @@ -551,10 +390,9 @@ static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) int l; if (!pass) { - BIO_printf(bio_err, "Malloc failure\n"); + BIO_printf(bio_err, "Out of memory\n"); return NULL; } - cb_tmp.password = (char *)srp_arg->srppassin; cb_tmp.prompt_info = "SRP user"; if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) { @@ -568,9 +406,8 @@ static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) } # endif -# ifndef OPENSSL_NO_SRTP + char *srtp_profiles = NULL; -# endif # ifndef OPENSSL_NO_NEXTPROTONEG /* This the context that we pass to next_proto_cb */ @@ -629,503 +466,586 @@ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, #endif -enum { - PROTO_OFF = 0, +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, OPT_VERIFY, + OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, + OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, + OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO, + OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF, + OPT_PAUSE, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG, + OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG, + OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE, + OPT_PSK_IDENTITY, OPT_PSK, OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, + OPT_SRP_LATEUSER, OPT_SRP_MOREGROUPS, OPT_SSL3, + OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, + OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, + OPT_CERT_CHAIN, OPT_CAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, + OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_KRB5SVC, + OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_JPAKE, + OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, + OPT_V_ENUM, + OPT_X_ENUM, + OPT_S_ENUM, + OPT_FALLBACKSCSV +} OPTION_CHOICE; + +OPTIONS s_client_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"host", OPT_HOST, 's', "Use -connect instead"}, + {"port", OPT_PORT, 'p', "Use -connect instead"}, + {"connect", OPT_CONNECT, 's', + "TCP/IP where to connect (default is " SSL_HOST_NAME ":" PORT_STR ")"}, + {"unix", OPT_UNIX, 's', "Connect over unix domain sockets"}, + {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, + {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, + {"certform", OPT_CERTFORM, 'F', + "Certificate format (PEM or DER) PEM default"}, + {"key", OPT_KEY, '<', "Private key file to use, if not in -cert file"}, + {"keyform", OPT_KEYFORM, 'F', "Key format (PEM or DER) PEM default"}, + {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"reconnect", OPT_RECONNECT, '-', + "Drop and re-make the connection with the same Session-ID"}, + {"pause", OPT_PAUSE, '-', "Sleep after each read and write system call"}, + {"showcerts", OPT_SHOWCERTS, '-', "Show all certificates in the chain"}, + {"debug", OPT_DEBUG, '-', "Extra output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>'}, + {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, + {"state", OPT_STATE, '-', "Print the ssl states"}, + {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, + {"quiet", OPT_QUIET, '-', "No s_client output"}, + {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"}, + {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Don't ignore input eof"}, +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, +#endif + {"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"}, + {"tls1_1", OPT_TLS1_1, '-', "Just use TLSv1.1"}, + {"tls1", OPT_TLS1, '-', "Just use TLSv1"}, + {"dtls", OPT_DTLS, '-'}, + {"dtls1", OPT_DTLS1, '-', "Just use DTLSv1"}, + {"dtls1_2", OPT_DTLS1_2, '-'}, + {"timeout", OPT_TIMEOUT, '-'}, + {"mtu", OPT_MTU, 'p', "Set the link layer MTU"}, + {"starttls", OPT_STARTTLS, 's', + "Use the STARTTLS command before starting TLS"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, + {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, + {"use_srtp", OPT_USE_SRTP, '<', + "Offer SRTP key management with a colon-separated profile list"}, + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, + {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, +#ifdef WATT32 + {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, +#endif +#ifdef FIONBIO + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, +#endif +#ifndef OPENSSL_NO_PSK + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, +# ifndef OPENSSL_NO_JPAKE + {"jpake", OPT_JPAKE, 's', "JPAKE secret to use"}, +# endif +#endif +#ifndef OPENSSL_NO_KRB5 + {"krb5svc", OPT_KRB5SVC, 's', "Kerberos service name"}, +#endif +#ifndef OPENSSL_NO_SRP + {"srpuser", OPT_SRPUSER, 's', "SRP authentification for 'user'"}, + {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, + {"srp_lateuser", OPT_SRP_LATEUSER, '-', + "SRP username into second ClientHello message"}, + {"srp_moregroups", OPT_SRP_MOREGROUPS, '-', + "Tolerate other than the known g N values."}, + {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal mength in bits for N"}, +#endif +#ifndef OPENSSL_NO_TLSEXT + {"servername", OPT_SERVERNAME, 's', + "Set TLS extension servername in ClientHello"}, + {"tlsextdebug", OPT_TLSEXTDEBUG, '-', + "Hex dump of all TLS extensions received"}, + {"status", OPT_STATUS, '-', "Request certificate status from server"}, + {"serverinfo", OPT_SERVERINFO, 's', + "types Send empty ClientHello extensions (comma-separated numbers)"}, + {"alpn", OPT_ALPN, 's', + "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, +# ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Enable NPN extension, considering named protocols supported (comma-separated list)"}, +# endif +#endif + {"CRL", OPT_CRL, '<'}, + {"crl_download", OPT_CRL_DOWNLOAD, '-'}, + {"CRLform", OPT_CRLFORM, 'F'}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-'}, + {"verify_quiet", OPT_VERIFY_QUIET, '-'}, + {"brief", OPT_BRIEF, '-'}, + {"prexit", OPT_PREXIT, '-'}, + {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's'}, + {"trace", OPT_TRACE, '-'}, + {"security_debug", OPT_SECURITY_DEBUG, '-'}, + {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'}, + {"cert_chain", OPT_CERT_CHAIN, '<'}, + {"chainCApath", OPT_CHAINCAPATH, '/'}, + {"verifyCApath", OPT_VERIFYCAPATH, '/'}, + {"build_chain", OPT_BUILD_CHAIN, '-'}, + {"chainCAfile", OPT_CHAINCAFILE, '<'}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + OPT_S_OPTIONS, + OPT_V_OPTIONS, + OPT_X_OPTIONS, + {NULL} +}; + +typedef enum PROTOCOL_choice { + PROTO_OFF, PROTO_SMTP, PROTO_POP3, PROTO_IMAP, PROTO_FTP, PROTO_XMPP +} PROTOCOL_CHOICE; + +static OPT_PAIR services[] = { + {"smtp", PROTO_SMTP}, + {"pop3", PROTO_POP3}, + {"imap", PROTO_IMAP}, + {"ftp", PROTO_FTP}, + {"xmpp", PROTO_XMPP}, + {NULL} }; -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int s_client_main(int argc, char **argv) { - int build_chain = 0; - SSL *con = NULL; -#ifndef OPENSSL_NO_KRB5 - KSSL_CTX *kctx; -#endif - int s, k, width, state = 0; - char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; - int cbuf_len, cbuf_off; - int sbuf_len, sbuf_off; - fd_set readfds, writefds; - short port = PORT; - int full_log = 1; - char *host = SSL_HOST_NAME; - const char *unix_path = NULL; - char *xmpphost = NULL; - char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; - int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; - char *passarg = NULL, *pass = NULL; - X509 *cert = NULL; + BIO *sbio; EVP_PKEY *key = NULL; - STACK_OF(X509) *chain = NULL; - char *CApath = NULL, *CAfile = NULL; - char *chCApath = NULL, *chCAfile = NULL; - char *vfyCApath = NULL, *vfyCAfile = NULL; - int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE; - int crlf = 0; - int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + SSL *con = NULL; SSL_CTX *ctx = NULL; - int ret = 1, in_init = 1, i, nbio_test = 0; - int starttls_proto = PROTO_OFF; - int prexit = 0; + STACK_OF(X509) *chain = NULL; + X509 *cert = NULL; X509_VERIFY_PARAM *vpm = NULL; - int badarg = 0; - const SSL_METHOD *meth = NULL; - int socket_type = SOCK_STREAM; - BIO *sbio; - char *inrand = NULL; - int mbuf_len = 0; + SSL_EXCERT *exc = NULL; + SSL_CONF_CTX *cctx = NULL; + STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + STACK_OF(X509_CRL) *crls = NULL; + const SSL_METHOD *meth = SSLv23_client_method(); + char *CApath = NULL, *CAfile = NULL, *cbuf = NULL, *sbuf = NULL, *mbuf = + NULL; + char *cert_file = NULL, *key_file = NULL, *chain_file = NULL, *prog; + char *chCApath = NULL, *chCAfile = NULL, *host = SSL_HOST_NAME, *inrand = + NULL; + char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p; + char *engine_id = NULL, *ssl_client_engine_id = NULL; + char *jpake_secret = NULL; + const char *unix_path = NULL; + struct sockaddr peer; struct timeval timeout, *timeoutp; + fd_set readfds, writefds; + int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; + int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; + int prexit = 0; + int enable_timeouts = 0, sdebug = 0, peerlen = sizeof peer; + int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; + int ret = 1, in_init = 1, i, nbio_test = 0, s, k, width, state = 0; + int sbuf_len, sbuf_off, socket_type = SOCK_STREAM; + int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; + int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + int fallback_scsv = 0; + long socket_mtu = 0, randamt = 0; + unsigned short port = PORT; + OPTION_CHOICE o; +#ifndef OPENSSL_NO_KRB5 + KSSL_CTX *kctx; + const char *krb5svc = NULL; +#endif #ifndef OPENSSL_NO_ENGINE - char *engine_id = NULL; - char *ssl_client_engine_id = NULL; ENGINE *ssl_client_engine = NULL; -#endif ENGINE *e = NULL; +#endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) struct timeval tv; #endif #ifndef OPENSSL_NO_TLSEXT char *servername = NULL; + const char *alpn_in = NULL; tlsextctx tlsextcbp = { NULL, 0 }; +# define MAX_SI_TYPES 100 + unsigned short serverinfo_types[MAX_SI_TYPES]; + int serverinfo_count = 0, start = 0, len; # ifndef OPENSSL_NO_NEXTPROTONEG const char *next_proto_neg_in = NULL; # endif - const char *alpn_in = NULL; -# define MAX_SI_TYPES 100 - unsigned short serverinfo_types[MAX_SI_TYPES]; - int serverinfo_types_count = 0; -#endif - char *sess_in = NULL; - char *sess_out = NULL; - struct sockaddr peer; - int peerlen = sizeof(peer); - int fallback_scsv = 0; - int enable_timeouts = 0; - long socket_mtu = 0; -#ifndef OPENSSL_NO_JPAKE - static char *jpake_secret = NULL; -# define no_jpake !jpake_secret -#else -# define no_jpake 1 #endif #ifndef OPENSSL_NO_SRP char *srppass = NULL; int srp_lateuser = 0; SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 }; #endif - SSL_EXCERT *exc = NULL; - - SSL_CONF_CTX *cctx = NULL; - STACK_OF(OPENSSL_STRING) *ssl_args = NULL; - - char *crl_file = NULL; - int crl_format = FORMAT_PEM; - int crl_download = 0; - STACK_OF(X509_CRL) *crls = NULL; - int sdebug = 0; - - meth = SSLv23_client_method(); - apps_startup(); + prog = opt_progname(argv[0]); c_Pause = 0; c_quiet = 0; c_ign_eof = 0; c_debug = 0; c_msg = 0; c_showcerts = 0; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; + c_nbio = 0; + verify_depth = 0; + verify_error = X509_V_OK; + vpm = X509_VERIFY_PARAM_new(); + cbuf = OPENSSL_malloc(BUFSIZZ); + sbuf = OPENSSL_malloc(BUFSIZZ); + mbuf = OPENSSL_malloc(BUFSIZZ); cctx = SSL_CONF_CTX_new(); - if (!cctx) - goto end; - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE); - if (((cbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) || - ((sbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) || - ((mbuf = OPENSSL_malloc(BUFSIZZ)) == NULL)) { - BIO_printf(bio_err, "out of memory\n"); + if (vpm == NULL || cctx == NULL + || cbuf == NULL || sbuf == NULL || mbuf == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", prog); goto end; } - verify_depth = 0; - verify_error = X509_V_OK; -#ifdef FIONBIO - c_nbio = 0; -#endif + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CMDLINE); - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-host") == 0) { - if (--argc < 1) - goto bad; - host = *(++argv); - } else if (strcmp(*argv, "-port") == 0) { - if (--argc < 1) - goto bad; - port = atoi(*(++argv)); - if (port == 0) - goto bad; - } else if (strcmp(*argv, "-connect") == 0) { - if (--argc < 1) - goto bad; - if (!extract_host_port(*(++argv), &host, NULL, &port)) - goto bad; - } else if (strcmp(*argv, "-unix") == 0) { - if (--argc < 1) - goto bad; - unix_path = *(++argv); - } else if (strcmp(*argv, "-xmpphost") == 0) { - if (--argc < 1) - goto bad; - xmpphost = *(++argv); - } else if (strcmp(*argv, "-verify") == 0) { + prog = opt_init(argc, argv, s_client_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { +#ifndef WATT32 + case OPT_WDEBUG: +#endif +#ifdef OPENSSL_NO_JPAKE + case OPT_JPAKE: +#endif +#ifdef OPENSSL_NO_SSL_TRACE + case OPT_TRACE: +#endif + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(s_client_options); + ret = 0; + goto end; + case OPT_HOST: + host = opt_arg(); + break; + case OPT_PORT: + port = atoi(opt_arg()); + break; + case OPT_CONNECT: + if (!extract_host_port(opt_arg(), &host, NULL, &port)) + goto end; + break; + case OPT_UNIX: + unix_path = opt_arg(); + break; + case OPT_VERIFY: verify = SSL_VERIFY_PEER; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); + verify_depth = atoi(opt_arg()); if (!c_quiet) BIO_printf(bio_err, "verify depth is %d\n", verify_depth); - } else if (strcmp(*argv, "-cert") == 0) { - if (--argc < 1) - goto bad; - cert_file = *(++argv); - } else if (strcmp(*argv, "-CRL") == 0) { - if (--argc < 1) - goto bad; - crl_file = *(++argv); - } else if (strcmp(*argv, "-crl_download") == 0) + break; + case OPT_CERT: + cert_file = opt_arg(); + break; + case OPT_CRL: + crl_file = opt_arg(); + break; + case OPT_CRL_DOWNLOAD: crl_download = 1; - else if (strcmp(*argv, "-sess_out") == 0) { - if (--argc < 1) - goto bad; - sess_out = *(++argv); - } else if (strcmp(*argv, "-sess_in") == 0) { - if (--argc < 1) - goto bad; - sess_in = *(++argv); - } else if (strcmp(*argv, "-certform") == 0) { - if (--argc < 1) - goto bad; - cert_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-CRLform") == 0) { - if (--argc < 1) - goto bad; - crl_format = str2fmt(*(++argv)); - } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { - if (badarg) - goto bad; - continue; - } else if (strcmp(*argv, "-verify_return_error") == 0) + break; + case OPT_SESS_OUT: + sess_out = opt_arg(); + break; + case OPT_SESS_IN: + sess_in = opt_arg(); + break; + case OPT_CERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &cert_format)) + goto opthelp; + break; + case OPT_CRLFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) + goto opthelp; + break; + case OPT_VERIFY_RET_ERROR: verify_return_error = 1; - else if (strcmp(*argv, "-verify_quiet") == 0) - verify_quiet = 1; - else if (strcmp(*argv, "-brief") == 0) { - c_brief = 1; + break; + case OPT_VERIFY_QUIET: verify_quiet = 1; - c_quiet = 1; - } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) { - if (badarg) - goto bad; - continue; - } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) { - if (badarg) - goto bad; - continue; - } else if (strcmp(*argv, "-prexit") == 0) + break; + case OPT_BRIEF: + c_brief = verify_quiet = c_quiet = 1; + break; + case OPT_S_CASES: + if (ssl_args == NULL) + ssl_args = sk_OPENSSL_STRING_new_null(); + if (ssl_args == NULL + || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) + || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { + BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); + goto end; + } + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto end; + vpmtouched++; + break; + case OPT_X_CASES: + if (!args_excert(o, &exc)) + goto end; + break; + case OPT_PREXIT: prexit = 1; - else if (strcmp(*argv, "-crlf") == 0) + break; + case OPT_CRLF: crlf = 1; - else if (strcmp(*argv, "-quiet") == 0) { - c_quiet = 1; - c_ign_eof = 1; - } else if (strcmp(*argv, "-ign_eof") == 0) + break; + case OPT_QUIET: + c_quiet = c_ign_eof = 1; + break; + case OPT_NBIO: + c_nbio = 1; + break; + case OPT_KRB5SVC: +#ifndef OPENSSL_NO_KRB5 + krb5svc = opt_arg(); +#endif + break; + case OPT_ENGINE: + engine_id = opt_arg(); + break; + case OPT_SSL_CLIENT_ENGINE: + ssl_client_engine_id = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_IGN_EOF: c_ign_eof = 1; - else if (strcmp(*argv, "-no_ign_eof") == 0) + break; + case OPT_NO_IGN_EOF: c_ign_eof = 0; - else if (strcmp(*argv, "-pause") == 0) + break; + case OPT_PAUSE: c_Pause = 1; - else if (strcmp(*argv, "-debug") == 0) + break; + case OPT_DEBUG: c_debug = 1; + break; #ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-tlsextdebug") == 0) + case OPT_TLSEXTDEBUG: c_tlsextdebug = 1; - else if (strcmp(*argv, "-status") == 0) + break; + case OPT_STATUS: c_status_req = 1; + break; #endif #ifdef WATT32 - else if (strcmp(*argv, "-wdebug") == 0) + case OPT_WDEBUG: dbug_init(); + break; #endif - else if (strcmp(*argv, "-msg") == 0) + case OPT_MSG: c_msg = 1; - else if (strcmp(*argv, "-msgfile") == 0) { - if (--argc < 1) - goto bad; - bio_c_msg = BIO_new_file(*(++argv), "w"); - } + break; + case OPT_MSGFILE: + bio_c_msg = BIO_new_file(opt_arg(), "w"); + break; #ifndef OPENSSL_NO_SSL_TRACE - else if (strcmp(*argv, "-trace") == 0) + case OPT_TRACE: c_msg = 2; + break; #endif - else if (strcmp(*argv, "-security_debug") == 0) { + case OPT_SECURITY_DEBUG: sdebug = 1; - } else if (strcmp(*argv, "-security_debug_verbose") == 0) { + break; + case OPT_SECURITY_DEBUG_VERBOSE: sdebug = 2; - } else if (strcmp(*argv, "-showcerts") == 0) + break; + case OPT_SHOWCERTS: c_showcerts = 1; - else if (strcmp(*argv, "-nbio_test") == 0) + break; + case OPT_NBIO_TEST: nbio_test = 1; - else if (strcmp(*argv, "-state") == 0) + break; + case OPT_STATE: state = 1; + break; #ifndef OPENSSL_NO_PSK - else if (strcmp(*argv, "-psk_identity") == 0) { - if (--argc < 1) - goto bad; - psk_identity = *(++argv); - } else if (strcmp(*argv, "-psk") == 0) { - size_t j; - - if (--argc < 1) - goto bad; - psk_key = *(++argv); - for (j = 0; j < strlen(psk_key); j++) { - if (isxdigit((unsigned char)psk_key[j])) + case OPT_PSK_IDENTITY: + psk_identity = opt_arg(); + break; + case OPT_PSK: + for (p = psk_key = opt_arg(); *p; p++) { + if (isxdigit(*p)) continue; - BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); - goto bad; + BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); + goto end; } - } + break; #endif #ifndef OPENSSL_NO_SRP - else if (strcmp(*argv, "-srpuser") == 0) { - if (--argc < 1) - goto bad; - srp_arg.srplogin = *(++argv); + case OPT_SRPUSER: + srp_arg.srplogin = opt_arg(); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srppass") == 0) { - if (--argc < 1) - goto bad; - srppass = *(++argv); + break; + case OPT_SRPPASS: + srppass = opt_arg(); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_strength") == 0) { - if (--argc < 1) - goto bad; - srp_arg.strength = atoi(*(++argv)); + break; + case OPT_SRP_STRENGTH: + srp_arg.strength = atoi(opt_arg()); BIO_printf(bio_err, "SRP minimal length for N is %d\n", srp_arg.strength); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_lateuser") == 0) { + break; + case OPT_SRP_LATEUSER: srp_lateuser = 1; meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_moregroups") == 0) { + break; + case OPT_SRP_MOREGROUPS: srp_arg.amp = 1; meth = TLSv1_client_method(); - } + break; #endif -#ifndef OPENSSL_NO_SSL3_METHOD - else if (strcmp(*argv, "-ssl3") == 0) +#ifndef OPENSSL_NO_SSL3 + case OPT_SSL3: meth = SSLv3_client_method(); + break; #endif - else if (strcmp(*argv, "-tls1_2") == 0) + case OPT_TLS1_2: meth = TLSv1_2_client_method(); - else if (strcmp(*argv, "-tls1_1") == 0) + break; + case OPT_TLS1_1: meth = TLSv1_1_client_method(); - else if (strcmp(*argv, "-tls1") == 0) + break; + case OPT_TLS1: meth = TLSv1_client_method(); + break; #ifndef OPENSSL_NO_DTLS1 - else if (strcmp(*argv, "-dtls") == 0) { + case OPT_DTLS: meth = DTLS_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1") == 0) { + break; + case OPT_DTLS1: meth = DTLSv1_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1_2") == 0) { + break; + case OPT_DTLS1_2: meth = DTLSv1_2_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-timeout") == 0) + break; + case OPT_TIMEOUT: enable_timeouts = 1; - else if (strcmp(*argv, "-mtu") == 0) { - if (--argc < 1) - goto bad; - socket_mtu = atol(*(++argv)); - } + break; + case OPT_MTU: + socket_mtu = atol(opt_arg()); + break; #endif - else if (strcmp(*argv, "-fallback_scsv") == 0) { + case OPT_FALLBACKSCSV: fallback_scsv = 1; - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - key_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-pass") == 0) { - if (--argc < 1) - goto bad; - passarg = *(++argv); - } else if (strcmp(*argv, "-cert_chain") == 0) { - if (--argc < 1) - goto bad; - chain_file = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - key_file = *(++argv); - } else if (strcmp(*argv, "-reconnect") == 0) { + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &key_format)) + goto opthelp; + break; + case OPT_PASS: + passarg = opt_arg(); + break; + case OPT_CERT_CHAIN: + chain_file = opt_arg(); + break; + case OPT_KEY: + key_file = opt_arg(); + break; + case OPT_RECONNECT: reconnect = 5; - } else if (strcmp(*argv, "-CApath") == 0) { - if (--argc < 1) - goto bad; - CApath = *(++argv); - } else if (strcmp(*argv, "-chainCApath") == 0) { - if (--argc < 1) - goto bad; - chCApath = *(++argv); - } else if (strcmp(*argv, "-verifyCApath") == 0) { - if (--argc < 1) - goto bad; - vfyCApath = *(++argv); - } else if (strcmp(*argv, "-build_chain") == 0) + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CHAINCAPATH: + chCApath = opt_arg(); + break; + case OPT_VERIFYCAPATH: + vfyCApath = opt_arg(); + break; + case OPT_BUILD_CHAIN: build_chain = 1; - else if (strcmp(*argv, "-CAfile") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); - } else if (strcmp(*argv, "-chainCAfile") == 0) { - if (--argc < 1) - goto bad; - chCAfile = *(++argv); - } else if (strcmp(*argv, "-verifyCAfile") == 0) { - if (--argc < 1) - goto bad; - vfyCAfile = *(++argv); - } + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CHAINCAFILE: + chCAfile = opt_arg(); + break; + case OPT_VERIFYCAFILE: + vfyCAfile = opt_arg(); + break; #ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (strcmp(*argv, "-nextprotoneg") == 0) { - if (--argc < 1) - goto bad; - next_proto_neg_in = *(++argv); - } -# endif - else if (strcmp(*argv, "-alpn") == 0) { - if (--argc < 1) - goto bad; - alpn_in = *(++argv); - } else if (strcmp(*argv, "-serverinfo") == 0) { - char *c; - int start = 0; - int len; - - if (--argc < 1) - goto bad; - c = *(++argv); - serverinfo_types_count = 0; - len = strlen(c); - for (i = 0; i <= len; ++i) { - if (i == len || c[i] == ',') { - serverinfo_types[serverinfo_types_count] - = atoi(c + start); - serverinfo_types_count++; + case OPT_NEXTPROTONEG: + next_proto_neg_in = opt_arg(); + break; + case OPT_ALPN: + alpn_in = opt_arg(); + break; + case OPT_SERVERINFO: + p = opt_arg(); + len = strlen(p); + for (start = 0, i = 0; i <= len; ++i) { + if (i == len || p[i] == ',') { + serverinfo_types[serverinfo_count] = atoi(p + start); + if (++serverinfo_count == MAX_SI_TYPES) + break; start = i + 1; } - if (serverinfo_types_count == MAX_SI_TYPES) - break; } - } -#endif -#ifdef FIONBIO - else if (strcmp(*argv, "-nbio") == 0) { - c_nbio = 1; - } -#endif - else if (strcmp(*argv, "-starttls") == 0) { - if (--argc < 1) - goto bad; - ++argv; - if (strcmp(*argv, "smtp") == 0) - starttls_proto = PROTO_SMTP; - else if (strcmp(*argv, "pop3") == 0) - starttls_proto = PROTO_POP3; - else if (strcmp(*argv, "imap") == 0) - starttls_proto = PROTO_IMAP; - else if (strcmp(*argv, "ftp") == 0) - starttls_proto = PROTO_FTP; - else if (strcmp(*argv, "xmpp") == 0) - starttls_proto = PROTO_XMPP; - else - goto bad; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine_id = *(++argv); - } else if (strcmp(*argv, "-ssl_client_engine") == 0) { - if (--argc < 1) - goto bad; - ssl_client_engine_id = *(++argv); - } + break; #endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } + case OPT_STARTTLS: + if (!opt_pair(opt_arg(), services, &starttls_proto)) + goto end; #ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-servername") == 0) { - if (--argc < 1) - goto bad; - servername = *(++argv); + case OPT_SERVERNAME: + servername = opt_arg(); /* meth=TLSv1_client_method(); */ - } + break; #endif #ifndef OPENSSL_NO_JPAKE - else if (strcmp(*argv, "-jpake") == 0) { - if (--argc < 1) - goto bad; - jpake_secret = *++argv; - } -#endif -#ifndef OPENSSL_NO_SRTP - else if (strcmp(*argv, "-use_srtp") == 0) { - if (--argc < 1) - goto bad; - srtp_profiles = *(++argv); - } + case OPT_JPAKE: + jpake_secret = opt_arg(); + break; #endif - else if (strcmp(*argv, "-keymatexport") == 0) { - if (--argc < 1) - goto bad; - keymatexportlabel = *(++argv); - } else if (strcmp(*argv, "-keymatexportlen") == 0) { - if (--argc < 1) - goto bad; - keymatexportlen = atoi(*(++argv)); - if (keymatexportlen == 0) - goto bad; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badop = 1; + case OPT_USE_SRTP: + srtp_profiles = opt_arg(); + break; + case OPT_KEYMATEXPORT: + keymatexportlabel = opt_arg(); + break; + case OPT_KEYMATEXPORTLEN: + keymatexportlen = atoi(opt_arg()); break; } - argc--; - argv++; - } - if (badop) { - bad: - sc_usage(); - goto end; } + argc = opt_num_rest(); + argv = opt_rest(); if (unix_path && (socket_type != SOCK_STREAM)) { BIO_printf(bio_err, @@ -1142,9 +1062,6 @@ int MAIN(int argc, char **argv) } #endif - OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) next_proto.status = -1; if (next_proto_neg_in) { @@ -1159,16 +1076,17 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine_id, 1); + e = setup_engine(engine_id, 1); if (ssl_client_engine_id) { ssl_client_engine = ENGINE_by_id(ssl_client_engine_id); - if (!ssl_client_engine) { + if (ssl_client_engine == NULL) { BIO_printf(bio_err, "Error getting client auth engine\n"); goto end; } } #endif - if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1177,28 +1095,25 @@ int MAIN(int argc, char **argv) key_file = cert_file; if (key_file) { - - key = load_key(bio_err, key_file, key_format, 0, pass, e, + key = load_key(key_file, key_format, 0, pass, e, "client certificate private key file"); - if (!key) { + if (key == NULL) { ERR_print_errors(bio_err); goto end; } - } if (cert_file) { - cert = load_cert(bio_err, cert_file, cert_format, + cert = load_cert(cert_file, cert_format, NULL, e, "client certificate file"); - - if (!cert) { + if (cert == NULL) { ERR_print_errors(bio_err); goto end; } } if (chain_file) { - chain = load_certs(bio_err, chain_file, FORMAT_PEM, + chain = load_certs(chain_file, FORMAT_PEM, NULL, e, "client certificate chain"); if (!chain) goto end; @@ -1207,13 +1122,13 @@ int MAIN(int argc, char **argv) if (crl_file) { X509_CRL *crl; crl = load_crl(crl_file, crl_format); - if (!crl) { + if (crl == NULL) { BIO_puts(bio_err, "Error loading CRL\n"); ERR_print_errors(bio_err); goto end; } crls = sk_X509_CRL_new_null(); - if (!crls || !sk_X509_CRL_push(crls, crl)) { + if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { BIO_puts(bio_err, "Error adding CRL\n"); ERR_print_errors(bio_err); X509_CRL_free(crl); @@ -1221,30 +1136,29 @@ int MAIN(int argc, char **argv) } } - if (!load_excert(&exc, bio_err)) + if (!load_excert(&exc)) goto end; - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL + if (!app_RAND_load_file(NULL, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } - if (inrand != NULL) - BIO_printf(bio_err, "%ld semi-random bytes loaded\n", - app_RAND_load_files(inrand)); + if (inrand != NULL) { + randamt = app_RAND_load_files(inrand); + BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt); + } if (bio_c_out == NULL) { if (c_quiet && !c_debug) { bio_c_out = BIO_new(BIO_s_null()); if (c_msg && !bio_c_msg) - bio_c_msg = BIO_new_fp(stdout, BIO_NOCLOSE); - } else { - if (bio_c_out == NULL) - bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE); - } + bio_c_msg = dup_bio_out(); + } else if (bio_c_out == NULL) + bio_c_out = dup_bio_out(); } #ifndef OPENSSL_NO_SRP - if (!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) { + if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1259,16 +1173,14 @@ int MAIN(int argc, char **argv) if (sdebug) ssl_ctx_security_debug(ctx, bio_err, sdebug); - if (vpm && !SSL_CTX_set1_param(ctx, vpm)) { + if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); goto end; } - if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake)) { - ERR_print_errors(bio_err); + if (!config_ctx(cctx, ssl_args, ctx, 1, jpake_secret == NULL)) goto end; - } if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls, crl_download)) { @@ -1289,12 +1201,7 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_PSK -# ifdef OPENSSL_NO_JPAKE - if (psk_key != NULL) -# else - if (psk_key != NULL || jpake_secret) -# endif - { + if (psk_key != NULL || jpake_secret) { if (c_debug) BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n"); @@ -1303,14 +1210,15 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_SRTP if (srtp_profiles != NULL) { - /* Returns 0 on success!! */ - if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles)) { + /* Returns 0 on success! */ + if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { BIO_printf(bio_err, "Error setting SRTP profile\n"); ERR_print_errors(bio_err); goto end; } } #endif + if (exc) ssl_ctx_set_excert(ctx, exc); @@ -1327,22 +1235,23 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Error parsing -alpn argument\n"); goto end; } - /* Returns 0 on success!! */ - if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len)) { - BIO_printf(bio_err, "Error setting ALPN\n"); + /* Returns 0 on success! */ + if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0) { + BIO_printf(bio_err, "Error setting ALPN\n"); goto end; } OPENSSL_free(alpn); } #endif #ifndef OPENSSL_NO_TLSEXT - for (i = 0; i < serverinfo_types_count; i++) { + for (i = 0; i < serverinfo_count; i++) { if (!SSL_CTX_add_client_custom_ext(ctx, - serverinfo_types[i], - NULL, NULL, NULL, - serverinfo_cli_parse_cb, NULL)) { - BIO_printf(bio_err, "Warning: Unable to add custom extension %u. " - "Skipping\n", serverinfo_types[i]); + serverinfo_types[i], + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL)) { + BIO_printf(bio_err, + "Warning: Unable to add custom extension %u, skipping\n", + serverinfo_types[i]); } } #endif @@ -1352,12 +1261,9 @@ int MAIN(int argc, char **argv) SSL_CTX_set_verify(ctx, verify, verify_callback); - if ((CAfile || CApath) - && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) { - ERR_print_errors(bio_err); - } - if (!SSL_CTX_set_default_verify_paths(ctx)) { + if (!ctx_set_verify_locations(ctx, CAfile, CApath)) { ERR_print_errors(bio_err); + goto end; } ssl_ctx_add_crls(ctx, crls, crl_download); @@ -1429,6 +1335,8 @@ int MAIN(int argc, char **argv) if (con && (kctx = kssl_ctx_new()) != NULL) { SSL_set0_kssl_ctx(con, kctx); kssl_ctx_setstring(kctx, KSSL_SERVER, host); + if (krb5svc) + kssl_ctx_setstring(kctx, KSSL_SERVICE, krb5svc); } #endif /* OPENSSL_NO_KRB5 */ @@ -1554,111 +1462,131 @@ int MAIN(int argc, char **argv) sbuf_len = 0; sbuf_off = 0; - /* This is an ugly hack that does a lot of assumptions */ - /* - * We do have to handle multi-line responses which may come in a single - * packet or not. We therefore have to use BIO_gets() which does need a - * buffering BIO. So during the initial chitchat we do push a buffering - * BIO into the chain that is removed again later on to not disturb the - * rest of the s_client operation. - */ - if (starttls_proto == PROTO_SMTP) { - int foundit = 0; - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - /* wait for multi-line response to end from SMTP */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + switch ((PROTOCOL_CHOICE) starttls_proto) { + case PROTO_OFF: + break; + case PROTO_SMTP: + { + /* + * This is an ugly hack that does a lot of assumptions. We do + * have to handle multi-line responses which may come in a single + * packet or not. We therefore have to use BIO_gets() which does + * need a buffering BIO. So during the initial chitchat we do + * push a buffering BIO into the chain that is removed again + * later on to not disturb the rest of the s_client operation. + */ + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from SMTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + BIO_printf(fbio, "EHLO openssl.client.net\r\n"); + (void)BIO_flush(fbio); + /* wait for multi-line response to end EHLO SMTP response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found starttls in server response," + " try anyway...\n"); + BIO_printf(sbio, "STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[3] == '-'); - /* STARTTLS command requires EHLO... */ - BIO_printf(fbio, "EHLO openssl.client.net\r\n"); - (void)BIO_flush(fbio); - /* wait for multi-line response to end EHLO SMTP response */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (strstr(mbuf, "STARTTLS")) - foundit = 1; + break; + case PROTO_POP3: + { + BIO_read(sbio, mbuf, BUFSIZZ); + BIO_printf(sbio, "STLS\r\n"); + mbuf_len = BIO_read(sbio, sbuf, BUFSIZZ); + if (mbuf_len < 0) { + BIO_printf(bio_err, "BIO_read failed\n"); + goto end; + } } - while (mbuf_len > 3 && mbuf[3] == '-'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (!foundit) - BIO_printf(bio_err, - "didn't found starttls in server response," - " try anyway...\n"); - BIO_printf(sbio, "STARTTLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_POP3) { - BIO_read(sbio, mbuf, BUFSIZZ); - BIO_printf(sbio, "STLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_IMAP) { - int foundit = 0; - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - BIO_gets(fbio, mbuf, BUFSIZZ); - /* STARTTLS command requires CAPABILITY... */ - BIO_printf(fbio, ". CAPABILITY\r\n"); - (void)BIO_flush(fbio); - /* wait for multi-line CAPABILITY response */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (strstr(mbuf, "STARTTLS")) - foundit = 1; + break; + case PROTO_IMAP: + { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + BIO_gets(fbio, mbuf, BUFSIZZ); + /* STARTTLS command requires CAPABILITY... */ + BIO_printf(fbio, ". CAPABILITY\r\n"); + (void)BIO_flush(fbio); + /* wait for multi-line CAPABILITY response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[0] != '.'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found STARTTLS in server response," + " try anyway...\n"); + BIO_printf(sbio, ". STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[0] != '.'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (!foundit) - BIO_printf(bio_err, - "didn't found STARTTLS in server response," - " try anyway...\n"); - BIO_printf(sbio, ". STARTTLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_FTP) { - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - /* wait for multi-line response to end from FTP */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + break; + case PROTO_FTP: + { + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from FTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + BIO_printf(sbio, "AUTH TLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[3] == '-'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - BIO_printf(sbio, "AUTH TLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } - if (starttls_proto == PROTO_XMPP) { - int seen = 0; - BIO_printf(sbio, "", xmpphost ? - xmpphost : host); - seen = BIO_read(sbio, mbuf, BUFSIZZ); - mbuf[seen] = 0; - while (!strstr - (mbuf, "", + host); seen = BIO_read(sbio, mbuf, BUFSIZZ); + mbuf[seen] = 0; + while (!strstr + (mbuf, ""); + seen = BIO_read(sbio, sbuf, BUFSIZZ); + sbuf[seen] = 0; + if (!strstr(sbuf, ""); - seen = BIO_read(sbio, sbuf, BUFSIZZ); - sbuf[seen] = 0; - if (!strstr(sbuf, " HTTP/1.0' with file ./\n"); - BIO_printf(bio_err, - " -HTTP - Respond to a 'GET / HTTP/1.0' with file ./\n"); - BIO_printf(bio_err, - " with the assumption it contains a complete HTTP response.\n"); #ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine id - Initialise and use the specified engine\n"); -#endif - BIO_printf(bio_err, - " -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); -#ifndef OPENSSL_NO_TLSEXT - BIO_printf(bio_err, - " -servername host - servername for HostName TLS extension\n"); - BIO_printf(bio_err, - " -servername_fatal - on mismatch send fatal alert (default warning alert)\n"); - BIO_printf(bio_err, - " -cert2 arg - certificate file to use for servername\n"); - BIO_printf(bio_err, " (default is %s)\n", TEST_CERT2); - BIO_printf(bio_err, - " -key2 arg - Private Key file to use for servername, in cert file if\n"); - BIO_printf(bio_err, " not specified (default is %s)\n", - TEST_CERT2); - BIO_printf(bio_err, - " -tlsextdebug - hex dump of all TLS extensions received\n"); - BIO_printf(bio_err, - " -no_ticket - disable use of RFC4507bis session tickets\n"); - BIO_printf(bio_err, - " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); -# ifndef OPENSSL_NO_NEXTPROTONEG - BIO_printf(bio_err, - " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n"); -# endif -# ifndef OPENSSL_NO_SRTP - BIO_printf(bio_err, - " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); -# endif - BIO_printf(bio_err, - " -alpn arg - set the advertised protocols for the ALPN extension (comma-separated list)\n"); + engine_id = NULL; #endif - BIO_printf(bio_err, - " -keymatexport label - Export keying material using label\n"); - BIO_printf(bio_err, - " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); - BIO_printf(bio_err, - " -status - respond to certificate status requests\n"); - BIO_printf(bio_err, - " -status_verbose - enable status request verbose printout\n"); - BIO_printf(bio_err, - " -status_timeout n - status request responder timeout\n"); - BIO_printf(bio_err, " -status_url URL - status request fallback URL\n"); } static int local_argc = 0; @@ -705,8 +514,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl) num = num + num; /* double the size */ if (num < inl) num = inl; - wbuf = - (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); + wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); if (!wbuf) return 0; OPENSSL_free(b->ptr); @@ -807,11 +615,10 @@ typedef struct tlsextstatusctx_st { char *host, *path, *port; int use_ssl; int timeout; - BIO *err; int verbose; } tlsextstatusctx; -static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 }; +static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, 0 }; /* * Certificate Status callback. This is called when a client includes a @@ -825,7 +632,6 @@ static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 }; static int cert_status_cb(SSL *s, void *arg) { tlsextstatusctx *srctx = arg; - BIO *err = srctx->err; char *host, *port, *path; int use_ssl; unsigned char *rspder = NULL; @@ -840,23 +646,24 @@ static int cert_status_cb(SSL *s, void *arg) STACK_OF(X509_EXTENSION) *exts; int ret = SSL_TLSEXT_ERR_NOACK; int i; + if (srctx->verbose) - BIO_puts(err, "cert_status: callback called\n"); + BIO_puts(bio_err, "cert_status: callback called\n"); /* Build up OCSP query from server certificate */ x = SSL_get_certificate(s); aia = X509_get1_ocsp(x); if (aia) { if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), &host, &port, &path, &use_ssl)) { - BIO_puts(err, "cert_status: can't parse AIA URL\n"); + BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); goto err; } if (srctx->verbose) - BIO_printf(err, "cert_status: AIA URL: %s\n", + BIO_printf(bio_err, "cert_status: AIA URL: %s\n", sk_OPENSSL_STRING_value(aia, 0)); } else { if (!srctx->host) { - BIO_puts(srctx->err, + BIO_puts(bio_err, "cert_status: no AIA and no default responder URL\n"); goto done; } @@ -872,7 +679,7 @@ static int cert_status_cb(SSL *s, void *arg) goto err; if (X509_STORE_get_by_subject(&inctx, X509_LU_X509, X509_get_issuer_name(x), &obj) <= 0) { - BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n"); + BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); X509_STORE_CTX_cleanup(&inctx); goto done; } @@ -894,10 +701,10 @@ static int cert_status_cb(SSL *s, void *arg) if (!OCSP_REQUEST_add_ext(req, ext, -1)) goto err; } - resp = process_responder(err, req, host, path, port, use_ssl, NULL, + resp = process_responder(req, host, path, port, use_ssl, NULL, srctx->timeout); if (!resp) { - BIO_puts(err, "cert_status: error querying responder\n"); + BIO_puts(bio_err, "cert_status: error querying responder\n"); goto done; } rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); @@ -905,13 +712,13 @@ static int cert_status_cb(SSL *s, void *arg) goto err; SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); if (srctx->verbose) { - BIO_puts(err, "cert_status: ocsp response sent:\n"); - OCSP_RESPONSE_print(err, resp, 2); + BIO_puts(bio_err, "cert_status: ocsp response sent:\n"); + OCSP_RESPONSE_print(bio_err, resp, 2); } ret = SSL_TLSEXT_ERR_OK; done: if (ret != SSL_TLSEXT_ERR_OK) - ERR_print_errors(err); + ERR_print_errors(bio_err); if (aia) { OPENSSL_free(host); OPENSSL_free(path); @@ -995,14 +802,7 @@ static int not_resumable_sess_cb(SSL *s, int is_forward_secure) return is_forward_secure; } -int MAIN(int, char **); - -#ifndef OPENSSL_NO_JPAKE static char *jpake_secret = NULL; -# define no_jpake !jpake_secret -#else -# define no_jpake 1 -#endif #ifndef OPENSSL_NO_SRP static srpsrvparm srp_callback_parm; #endif @@ -1010,41 +810,214 @@ static srpsrvparm srp_callback_parm; static char *srtp_profiles = NULL; #endif -int MAIN(int argc, char *argv[]) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, + OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, + OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, + OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT, + OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT, + OPT_CAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, + OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, + OPT_BUILD_CHAIN, OPT_CAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, + OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG, + OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, OPT_STATUS_TIMEOUT, + OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG, + OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, OPT_QUIET, + OPT_BRIEF, OPT_NO_TMP_RSA, OPT_NO_DHE, OPT_NO_ECDHE, + OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE, + OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, +#ifndef OPENSSL_NO_SSL3 + OPT_SSL3, +#endif + OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, + OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_CHAIN, + OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, + OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_JPAKE, + OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, + OPT_S_ENUM, + OPT_V_ENUM, + OPT_X_ENUM +} OPTION_CHOICE; + +OPTIONS s_server_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + + {"port", OPT_PORT, 'p'}, + {"accept", OPT_PORT, 'p', + "TCP/IP port to accept on (default is " PORT_STR ")"}, + {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, + {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, + {"context", OPT_CONTEXT, 's', "Set session ID context"}, + {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, + {"Verify", OPT_UPPER_V_VERIFY, 'n', + "Turn on peer certificate verification, must have a cert"}, + {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, + {"naccept", OPT_NACCEPT, 'p', "Terminate after pnum connections"}, +#ifndef OPENSSL_NO_TLSEXT + {"serverinfo", OPT_SERVERINFO, 's', + "PEM serverinfo file for certificate"}, +#endif + {"certform", OPT_CERTFORM, 'F', + "Certificate format (PEM or DER) PEM default"}, + {"key", OPT_KEY, '<', + "Private Key if not in -cert; default is " TEST_CERT}, + {"keyform", OPT_KEYFORM, 'f', + "Key format (PEM, DER or ENGINE) PEM default"}, + {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"dcert", OPT_DCERT, '<', + "Second certificate file to use (usually for DSA)"}, + {"dcertform", OPT_DCERTFORM, 'F', + "Second certificate format (PEM or DER) PEM default"}, + {"dkey", OPT_DKEY, '<', + "Second private key file to use (usually for DSA)"}, + {"dkeyform", OPT_DKEYFORM, 'F', + "Second key format (PEM, DER or ENGINE) PEM default"}, + {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, +#ifdef FIONBIO + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, +#endif + {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, + {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, + {"debug", OPT_DEBUG, '-', "Print more output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>'}, + {"state", OPT_STATE, '-', "Print the SSL states"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, + {"quiet", OPT_QUIET, '-', "No server output"}, + {"no_tmp_rsa", OPT_NO_TMP_RSA, '-', "Do not generate a tmp RSA key"}, +#ifndef OPENSSL_NO_PSK + {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, +# ifndef OPENSSL_NO_JPAKE + {"jpake", OPT_JPAKE, 's', "JPAKE secret to use"}, +# endif +#endif +#ifndef OPENSSL_NO_SRP + {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, + {"srpuserseed", OPT_SRPUSERSEED, 's', + "A seed string for a default user salt"}, +#endif +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, +#endif + {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"}, + {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"}, + {"tls1", OPT_TLS1, '-', "Just talk TLSv1"}, +#ifndef OPENSSL_NO_DTLS1 + {"dtls", OPT_DTLS, '-'}, + {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, + {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, + {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, + {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, + {"chain", OPT_CHAIN, '-', "Read a certificate chain"}, +#endif +#ifndef OPENSSL_NO_DH + {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, +#endif +#ifndef OPENSSL_NO_EC + {"no_ecdhe", OPT_NO_ECDHE, '-', "Disable ephemeral ECDH"}, +#endif + {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', + "Disable caching and tickets if ephemeral (EC)DH is used"}, + {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, + {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, + {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path incluedes HTTP headers"}, + {"id_prefix", OPT_ID_PREFIX, 's', + "Generate SSL/TLS session IDs prefixed by arg"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, +#ifndef OPENSSL_NO_TLSEXT + {"servername", OPT_SERVERNAME, 's', + "Servername for HostName TLS extension"}, + {"servername_fatal", OPT_SERVERNAME_FATAL, '-', + "mismatch send fatal alert (default warning alert)"}, + {"cert2", OPT_CERT2, '<', + "Certificate file to use for servername; default is" TEST_CERT2}, + {"key2", OPT_KEY2, '<', + "-Private Key file to use for servername if not in -cert2"}, + {"tlsextdebug", OPT_TLSEXTDEBUG, '-', + "Hex dump of all TLS extensions received"}, +# ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Set the advertised protocols for the NPN extension (comma-separated list)"}, +# endif + {"use_srtp", OPT_SRTP_PROFILES, '<', + "Offer SRTP key management with a colon-separated profile list"}, + {"alpn", OPT_ALPN, 's', + "Set the advertised protocols for the ALPN extension (comma-separated list)"}, +#endif + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, + {"CRL", OPT_CRL, '<'}, + {"crl_download", OPT_CRL_DOWNLOAD, '-'}, + {"cert_chain", OPT_CERT_CHAIN, '<'}, + {"dcert_chain", OPT_DCERT_CHAIN, '<'}, + {"chainCApath", OPT_CHAINCAPATH, '/'}, + {"verifyCApath", OPT_VERIFYCAPATH, '/'}, + {"no_cache", OPT_NO_CACHE, '-'}, + {"ext_cache", OPT_EXT_CACHE, '-'}, + {"CRLform", OPT_CRLFORM, 'F'}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-'}, + {"verify_quiet", OPT_VERIFY_QUIET, '-'}, + {"build_chain", OPT_BUILD_CHAIN, '-'}, + {"chainCAfile", OPT_CHAINCAFILE, '<'}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<'}, + {"ign_eof", OPT_IGN_EOF, '-'}, + {"no_ign_eof", OPT_NO_IGN_EOF, '-'}, + {"status", OPT_STATUS, '-'}, + {"status_verbose", OPT_STATUS_VERBOSE, '-'}, + {"status_timeout", OPT_STATUS_TIMEOUT, 'n'}, + {"status_url", OPT_STATUS_URL, 's'}, + {"trace", OPT_TRACE, '-'}, + {"security_debug", OPT_SECURITY_DEBUG, '-'}, + {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'}, + {"brief", OPT_BRIEF, '-'}, + {"rev", OPT_REV, '-'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's'}, +#endif + OPT_S_OPTIONS, + OPT_V_OPTIONS, + OPT_X_OPTIONS, + {NULL} +}; + +int s_server_main(int argc, char *argv[]) { + ENGINE *e = NULL; + EVP_PKEY *s_key = NULL, *s_dkey = NULL; + SSL_CONF_CTX *cctx = NULL; + const SSL_METHOD *meth = SSLv23_server_method(); + SSL_EXCERT *exc = NULL; + STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; + STACK_OF(X509_CRL) *crls = NULL; + X509 *s_cert = NULL, *s_dcert = NULL; X509_VERIFY_PARAM *vpm = NULL; - int badarg = 0; - short port = PORT; + char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; + char *dhfile = NULL, *dpassarg = NULL, *dpass = NULL, *inrand = NULL; + char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *crl_file = NULL, *prog, *p; const char *unix_path = NULL; #ifndef NO_SYS_UN_H int unlink_unix_path = 0; #endif int (*server_cb) (char *hostname, int s, int stype, unsigned char *context); - char *CApath = NULL, *CAfile = NULL; - char *chCApath = NULL, *chCAfile = NULL; - char *vfyCApath = NULL, *vfyCAfile = NULL; - unsigned char *context = NULL; - char *dhfile = NULL; - int badop = 0; - int ret = 1; - int build_chain = 0; - int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0; - int state = 0; - const SSL_METHOD *meth = NULL; - int socket_type = SOCK_STREAM; - ENGINE *e = NULL; - char *inrand = NULL; + int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0; + int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0, ret = 1; int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; - char *passarg = NULL, *pass = NULL; - char *dpassarg = NULL, *dpass = NULL; int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; - X509 *s_cert = NULL, *s_dcert = NULL; - STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; - EVP_PKEY *s_key = NULL, *s_dkey = NULL; - int no_cache = 0, ext_cache = 0; - int rev = 0, naccept = -1; - int sdebug = 0; + int rev = 0, naccept = -1, sdebug = 0, socket_type = SOCK_STREAM; + int state = 0, crl_format = FORMAT_PEM, crl_download = 0; + unsigned short port = PORT; + unsigned char *context = NULL; + OPTION_CHOICE o; #ifndef OPENSSL_NO_TLSEXT EVP_PKEY *s_key2 = NULL; X509 *s_cert2 = NULL; @@ -1064,449 +1037,394 @@ int MAIN(int argc, char *argv[]) char *srpuserseed = NULL; char *srp_verifier_file = NULL; #endif - SSL_EXCERT *exc = NULL; - SSL_CONF_CTX *cctx = NULL; - STACK_OF(OPENSSL_STRING) *ssl_args = NULL; - - char *crl_file = NULL; - int crl_format = FORMAT_PEM; - int crl_download = 0; - STACK_OF(X509_CRL) *crls = NULL; - - meth = SSLv23_server_method(); local_argc = argc; local_argv = argv; - apps_startup(); -#ifdef MONOLITH s_server_init(); -#endif - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - cctx = SSL_CONF_CTX_new(); - if (!cctx) + vpm = X509_VERIFY_PARAM_new(); + if (cctx == NULL || vpm == NULL) goto end; - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE); - - verify_depth = 0; -#ifdef FIONBIO - s_nbio = 0; -#endif - s_nbio_test = 0; - - argc--; - argv++; + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE); + + prog = opt_init(argc, argv, s_server_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(s_server_options); + ret = 0; + goto end; - while (argc >= 1) { - if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) { - if (--argc < 1) - goto bad; - if (!extract_port(*(++argv), &port)) - goto bad; - } else if (strcmp(*argv, "-unix") == 0) { + case OPT_PORT: + if (!extract_port(opt_arg(), &port)) + goto end; + break; + case OPT_UNIX: #ifdef NO_SYS_UN_H BIO_printf(bio_err, "unix domain sockets unsupported\n"); - goto bad; + goto end; #else - if (--argc < 1) - goto bad; - unix_path = *(++argv); + unix_path = opt_arg(); #endif - } else if (strcmp(*argv, "-unlink") == 0) { + break; + case OPT_UNLINK: #ifdef NO_SYS_UN_H BIO_printf(bio_err, "unix domain sockets unsupported\n"); - goto bad; + goto end; #else unlink_unix_path = 1; #endif - } else if (strcmp(*argv, "-naccept") == 0) { - if (--argc < 1) - goto bad; - naccept = atol(*(++argv)); - if (naccept <= 0) { - BIO_printf(bio_err, "bad accept value %s\n", *argv); - goto bad; - } - } else if (strcmp(*argv, "-verify") == 0) { + break; + case OPT_NACCEPT: + naccept = atol(opt_arg()); + break; + case OPT_VERIFY: s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); + verify_depth = atoi(opt_arg()); if (!s_quiet) BIO_printf(bio_err, "verify depth is %d\n", verify_depth); - } else if (strcmp(*argv, "-Verify") == 0) { + break; + case OPT_UPPER_V_VERIFY: s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); + verify_depth = atoi(opt_arg()); if (!s_quiet) BIO_printf(bio_err, "verify depth is %d, must return a certificate\n", verify_depth); - } else if (strcmp(*argv, "-context") == 0) { - if (--argc < 1) - goto bad; - context = (unsigned char *)*(++argv); - } else if (strcmp(*argv, "-cert") == 0) { - if (--argc < 1) - goto bad; - s_cert_file = *(++argv); - } else if (strcmp(*argv, "-CRL") == 0) { - if (--argc < 1) - goto bad; - crl_file = *(++argv); - } else if (strcmp(*argv, "-crl_download") == 0) + break; + case OPT_CONTEXT: + context = (unsigned char *)opt_arg(); + break; + case OPT_CERT: + s_cert_file = opt_arg(); + break; + case OPT_CRL: + crl_file = opt_arg(); + break; + case OPT_CRL_DOWNLOAD: crl_download = 1; + break; #ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-serverinfo") == 0) { - if (--argc < 1) - goto bad; - s_serverinfo_file = *(++argv); - } + case OPT_SERVERINFO: + s_serverinfo_file = opt_arg(); + break; #endif - else if (strcmp(*argv, "-certform") == 0) { - if (--argc < 1) - goto bad; - s_cert_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - s_key_file = *(++argv); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - s_key_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-pass") == 0) { - if (--argc < 1) - goto bad; - passarg = *(++argv); - } else if (strcmp(*argv, "-cert_chain") == 0) { - if (--argc < 1) - goto bad; - s_chain_file = *(++argv); - } else if (strcmp(*argv, "-dhparam") == 0) { - if (--argc < 1) - goto bad; - dhfile = *(++argv); - } else if (strcmp(*argv, "-dcertform") == 0) { - if (--argc < 1) - goto bad; - s_dcert_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-dcert") == 0) { - if (--argc < 1) - goto bad; - s_dcert_file = *(++argv); - } else if (strcmp(*argv, "-dkeyform") == 0) { - if (--argc < 1) - goto bad; - s_dkey_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-dpass") == 0) { - if (--argc < 1) - goto bad; - dpassarg = *(++argv); - } else if (strcmp(*argv, "-dkey") == 0) { - if (--argc < 1) - goto bad; - s_dkey_file = *(++argv); - } else if (strcmp(*argv, "-dcert_chain") == 0) { - if (--argc < 1) - goto bad; - s_dchain_file = *(++argv); - } else if (strcmp(*argv, "-nocert") == 0) { + case OPT_CERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format)) + goto opthelp; + break; + case OPT_KEY: + s_key_file = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format)) + goto opthelp; + break; + case OPT_PASS: + passarg = opt_arg(); + break; + case OPT_CERT_CHAIN: + s_chain_file = opt_arg(); + break; + case OPT_DHPARAM: + dhfile = opt_arg(); + break; + case OPT_DCERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format)) + goto opthelp; + break; + case OPT_DCERT: + s_dcert_file = opt_arg(); + break; + case OPT_DKEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format)) + goto opthelp; + break; + case OPT_DPASS: + dpassarg = opt_arg(); + break; + case OPT_DKEY: + s_dkey_file = opt_arg(); + break; + case OPT_DCERT_CHAIN: + s_dchain_file = opt_arg(); + break; + case OPT_NOCERT: nocert = 1; - } else if (strcmp(*argv, "-CApath") == 0) { - if (--argc < 1) - goto bad; - CApath = *(++argv); - } else if (strcmp(*argv, "-chainCApath") == 0) { - if (--argc < 1) - goto bad; - chCApath = *(++argv); - } else if (strcmp(*argv, "-verifyCApath") == 0) { - if (--argc < 1) - goto bad; - vfyCApath = *(++argv); - } else if (strcmp(*argv, "-no_cache") == 0) + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CHAINCAPATH: + chCApath = opt_arg(); + break; + case OPT_VERIFYCAPATH: + vfyCApath = opt_arg(); + break; + case OPT_NO_CACHE: no_cache = 1; - else if (strcmp(*argv, "-ext_cache") == 0) + break; + case OPT_EXT_CACHE: ext_cache = 1; - else if (strcmp(*argv, "-CRLform") == 0) { - if (--argc < 1) - goto bad; - crl_format = str2fmt(*(++argv)); - } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { - if (badarg) - goto bad; - continue; - } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) { - if (badarg) - goto bad; - continue; - } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) { - if (badarg) - goto bad; - continue; - } else if (strcmp(*argv, "-verify_return_error") == 0) + break; + case OPT_CRLFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) + goto opthelp; + break; + case OPT_S_CASES: + if (ssl_args == NULL) + ssl_args = sk_OPENSSL_STRING_new_null(); + if (ssl_args == NULL + || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) + || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { + BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); + goto end; + } + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto end; + vpmtouched++; + break; + case OPT_X_CASES: + if (!args_excert(o, &exc)) + goto end; + break; + case OPT_VERIFY_RET_ERROR: verify_return_error = 1; - else if (strcmp(*argv, "-verify_quiet") == 0) + break; + case OPT_VERIFY_QUIET: verify_quiet = 1; - else if (strcmp(*argv, "-build_chain") == 0) + break; + case OPT_BUILD_CHAIN: build_chain = 1; - else if (strcmp(*argv, "-CAfile") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); - } else if (strcmp(*argv, "-chainCAfile") == 0) { - if (--argc < 1) - goto bad; - chCAfile = *(++argv); - } else if (strcmp(*argv, "-verifyCAfile") == 0) { - if (--argc < 1) - goto bad; - vfyCAfile = *(++argv); - } -#ifdef FIONBIO - else if (strcmp(*argv, "-nbio") == 0) { - s_nbio = 1; - } -#endif - else if (strcmp(*argv, "-nbio_test") == 0) { -#ifdef FIONBIO + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CHAINCAFILE: + chCAfile = opt_arg(); + break; + case OPT_VERIFYCAFILE: + vfyCAfile = opt_arg(); + break; + case OPT_NBIO: s_nbio = 1; -#endif - s_nbio_test = 1; - } else if (strcmp(*argv, "-ign_eof") == 0) + break; + case OPT_NBIO_TEST: + s_nbio = s_nbio_test = 1; + break; + case OPT_IGN_EOF: s_ign_eof = 1; - else if (strcmp(*argv, "-no_ign_eof") == 0) + break; + case OPT_NO_IGN_EOF: s_ign_eof = 0; - else if (strcmp(*argv, "-debug") == 0) { + break; + case OPT_DEBUG: s_debug = 1; - } + break; #ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-tlsextdebug") == 0) + case OPT_TLSEXTDEBUG: s_tlsextdebug = 1; - else if (strcmp(*argv, "-status") == 0) - s_tlsextstatus = 1; - else if (strcmp(*argv, "-status_verbose") == 0) { + break; + case OPT_STATUS: s_tlsextstatus = 1; - tlscstatp.verbose = 1; - } else if (!strcmp(*argv, "-status_timeout")) { + break; + case OPT_STATUS_VERBOSE: + s_tlsextstatus = tlscstatp.verbose = 1; + break; + case OPT_STATUS_TIMEOUT: s_tlsextstatus = 1; - if (--argc < 1) - goto bad; - tlscstatp.timeout = atoi(*(++argv)); - } else if (!strcmp(*argv, "-status_url")) { + tlscstatp.timeout = atoi(opt_arg()); + break; + case OPT_STATUS_URL: s_tlsextstatus = 1; - if (--argc < 1) - goto bad; - if (!OCSP_parse_url(*(++argv), + if (!OCSP_parse_url(opt_arg(), &tlscstatp.host, &tlscstatp.port, &tlscstatp.path, &tlscstatp.use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); - goto bad; + goto end; } - } + break; #endif - else if (strcmp(*argv, "-msg") == 0) { + case OPT_MSG: s_msg = 1; - } else if (strcmp(*argv, "-msgfile") == 0) { - if (--argc < 1) - goto bad; - bio_s_msg = BIO_new_file(*(++argv), "w"); - } + break; + case OPT_MSGFILE: + bio_s_msg = BIO_new_file(opt_arg(), "w"); + break; #ifndef OPENSSL_NO_SSL_TRACE - else if (strcmp(*argv, "-trace") == 0) { + case OPT_TRACE: s_msg = 2; - } + break; +#else + case OPT_TRACE: + goto opthelp; #endif - else if (strcmp(*argv, "-security_debug") == 0) { + case OPT_SECURITY_DEBUG: sdebug = 1; - } else if (strcmp(*argv, "-security_debug_verbose") == 0) { + break; + case OPT_SECURITY_DEBUG_VERBOSE: sdebug = 2; - } else if (strcmp(*argv, "-state") == 0) { + break; + case OPT_STATE: state = 1; - } else if (strcmp(*argv, "-crlf") == 0) { + break; + case OPT_CRLF: s_crlf = 1; - } else if (strcmp(*argv, "-quiet") == 0) { - s_quiet = 1; - } else if (strcmp(*argv, "-brief") == 0) { + break; + case OPT_QUIET: s_quiet = 1; - s_brief = 1; - verify_quiet = 1; - } else if (strcmp(*argv, "-no_tmp_rsa") == 0) { + break; + case OPT_BRIEF: + s_quiet = s_brief = verify_quiet = 1; + break; + case OPT_NO_TMP_RSA: no_tmp_rsa = 1; - } else if (strcmp(*argv, "-no_dhe") == 0) { + break; + case OPT_NO_DHE: no_dhe = 1; - } else if (strcmp(*argv, "-no_ecdhe") == 0) { + break; + case OPT_NO_ECDHE: no_ecdhe = 1; - } else if (strcmp(*argv, "-no_resume_ephemeral") == 0) { + break; + case OPT_NO_RESUME_EPHEMERAL: no_resume_ephemeral = 1; - } + break; #ifndef OPENSSL_NO_PSK - else if (strcmp(*argv, "-psk_hint") == 0) { - if (--argc < 1) - goto bad; - psk_identity_hint = *(++argv); - } else if (strcmp(*argv, "-psk") == 0) { - size_t i; - - if (--argc < 1) - goto bad; - psk_key = *(++argv); - for (i = 0; i < strlen(psk_key); i++) { - if (isxdigit((unsigned char)psk_key[i])) + case OPT_PSK_HINT: + psk_identity_hint = opt_arg(); + break; + case OPT_PSK: + for (p = psk_key = opt_arg(); *p; p++) { + if (isxdigit(*p)) continue; BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); - goto bad; + goto end; } - } + break; #endif #ifndef OPENSSL_NO_SRP - else if (strcmp(*argv, "-srpvfile") == 0) { - if (--argc < 1) - goto bad; - srp_verifier_file = *(++argv); + case OPT_SRPVFILE: + srp_verifier_file = opt_arg(); meth = TLSv1_server_method(); - } else if (strcmp(*argv, "-srpuserseed") == 0) { - if (--argc < 1) - goto bad; - srpuserseed = *(++argv); + break; + case OPT_SRPUSERSEED: + srpuserseed = opt_arg(); meth = TLSv1_server_method(); - } + break; #endif - else if (strcmp(*argv, "-rev") == 0) { + case OPT_REV: rev = 1; - } else if (strcmp(*argv, "-www") == 0) { + break; + case OPT_WWW: www = 1; - } else if (strcmp(*argv, "-WWW") == 0) { + break; + case OPT_UPPER_WWW: www = 2; - } else if (strcmp(*argv, "-HTTP") == 0) { + break; + case OPT_HTTP: www = 3; - } -#ifndef OPENSSL_NO_SSL3_METHOD - else if (strcmp(*argv, "-ssl3") == 0) { - meth = SSLv3_server_method(); - } + break; +#ifndef OPENSSL_NO_SSL3 + case OPT_SSL3: + meth = SSLv3_client_method(); + break; #endif - else if (strcmp(*argv, "-tls1") == 0) { - meth = TLSv1_server_method(); - } else if (strcmp(*argv, "-tls1_1") == 0) { - meth = TLSv1_1_server_method(); - } else if (strcmp(*argv, "-tls1_2") == 0) { - meth = TLSv1_2_server_method(); - } + case OPT_TLS1_2: + meth = TLSv1_2_client_method(); + break; + case OPT_TLS1_1: + meth = TLSv1_1_client_method(); + break; + case OPT_TLS1: + meth = TLSv1_client_method(); + break; #ifndef OPENSSL_NO_DTLS1 - else if (strcmp(*argv, "-dtls") == 0) { - meth = DTLS_server_method(); + case OPT_DTLS: + meth = DTLS_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1") == 0) { - meth = DTLSv1_server_method(); + break; + case OPT_DTLS1: + meth = DTLSv1_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1_2") == 0) { - meth = DTLSv1_2_server_method(); + break; + case OPT_DTLS1_2: + meth = DTLSv1_2_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-timeout") == 0) + break; + case OPT_TIMEOUT: enable_timeouts = 1; - else if (strcmp(*argv, "-mtu") == 0) { - if (--argc < 1) - goto bad; - socket_mtu = atol(*(++argv)); - } else if (strcmp(*argv, "-chain") == 0) + break; + case OPT_MTU: + socket_mtu = atol(opt_arg()); + break; + case OPT_CHAIN: cert_chain = 1; + break; #endif - else if (strcmp(*argv, "-id_prefix") == 0) { - if (--argc < 1) - goto bad; - session_id_prefix = *(++argv); - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine_id = *(++argv); - } -#endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } + case OPT_ID_PREFIX: + session_id_prefix = opt_arg(); + break; + case OPT_ENGINE: + engine_id = opt_arg(); + break; + case OPT_RAND: + inrand = opt_arg(); + break; #ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-servername") == 0) { - if (--argc < 1) - goto bad; - tlsextcbp.servername = *(++argv); - } else if (strcmp(*argv, "-servername_fatal") == 0) { + case OPT_SERVERNAME: + tlsextcbp.servername = opt_arg(); + break; + case OPT_SERVERNAME_FATAL: tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; - } else if (strcmp(*argv, "-cert2") == 0) { - if (--argc < 1) - goto bad; - s_cert_file2 = *(++argv); - } else if (strcmp(*argv, "-key2") == 0) { - if (--argc < 1) - goto bad; - s_key_file2 = *(++argv); - } + break; + case OPT_CERT2: + s_cert_file2 = opt_arg(); + break; + case OPT_KEY2: + s_key_file2 = opt_arg(); + break; # ifndef OPENSSL_NO_NEXTPROTONEG - else if (strcmp(*argv, "-nextprotoneg") == 0) { - if (--argc < 1) - goto bad; - next_proto_neg_in = *(++argv); - } + case OPT_NEXTPROTONEG: + next_proto_neg_in = opt_arg(); + break; # endif - else if (strcmp(*argv, "-alpn") == 0) { - if (--argc < 1) - goto bad; - alpn_in = *(++argv); - } + case OPT_ALPN: + alpn_in = opt_arg(); + break; #endif #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) - else if (strcmp(*argv, "-jpake") == 0) { - if (--argc < 1) - goto bad; - jpake_secret = *(++argv); - } -#endif -#ifndef OPENSSL_NO_SRTP - else if (strcmp(*argv, "-use_srtp") == 0) { - if (--argc < 1) - goto bad; - srtp_profiles = *(++argv); - } + case OPT_JPAKE: + jpake_secret = opt_arg(); + break; +#else + case OPT_JPAKE: + goto opthelp; #endif - else if (strcmp(*argv, "-keymatexport") == 0) { - if (--argc < 1) - goto bad; - keymatexportlabel = *(++argv); - } else if (strcmp(*argv, "-keymatexportlen") == 0) { - if (--argc < 1) - goto bad; - keymatexportlen = atoi(*(++argv)); - if (keymatexportlen == 0) - goto bad; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badop = 1; + case OPT_SRTP_PROFILES: + srtp_profiles = opt_arg(); + break; + case OPT_KEYMATEXPORT: + keymatexportlabel = opt_arg(); + break; + case OPT_KEYMATEXPORTLEN: + keymatexportlen = atoi(opt_arg()); break; } - argc--; - argv++; - } - if (badop) { - bad: - sv_usage(); - goto end; } + argc = opt_num_rest(); + argv = opt_rest(); + #ifndef OPENSSL_NO_DTLS1 if (www && socket_type == SOCK_DGRAM) { BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n"); @@ -1529,14 +1447,11 @@ int MAIN(int argc, char *argv[]) } #endif - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); - #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine_id, 1); + e = setup_engine(engine_id, 1); #endif - if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) { + if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1548,18 +1463,18 @@ int MAIN(int argc, char *argv[]) s_key_file2 = s_cert_file2; #endif - if (!load_excert(&exc, bio_err)) + if (!load_excert(&exc)) goto end; if (nocert == 0) { - s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e, + s_key = load_key(s_key_file, s_key_format, 0, pass, e, "server certificate private key file"); if (!s_key) { ERR_print_errors(bio_err); goto end; } - s_cert = load_cert(bio_err, s_cert_file, s_cert_format, + s_cert = load_cert(s_cert_file, s_cert_format, NULL, e, "server certificate file"); if (!s_cert) { @@ -1567,21 +1482,21 @@ int MAIN(int argc, char *argv[]) goto end; } if (s_chain_file) { - s_chain = load_certs(bio_err, s_chain_file, FORMAT_PEM, + s_chain = load_certs(s_chain_file, FORMAT_PEM, NULL, e, "server certificate chain"); if (!s_chain) goto end; } #ifndef OPENSSL_NO_TLSEXT if (tlsextcbp.servername) { - s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e, + s_key2 = load_key(s_key_file2, s_key_format, 0, pass, e, "second server certificate private key file"); if (!s_key2) { ERR_print_errors(bio_err); goto end; } - s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format, + s_cert2 = load_cert(s_cert_file2, s_cert_format, NULL, e, "second server certificate file"); if (!s_cert2) { @@ -1635,14 +1550,14 @@ int MAIN(int argc, char *argv[]) if (s_dkey_file == NULL) s_dkey_file = s_dcert_file; - s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format, + s_dkey = load_key(s_dkey_file, s_dkey_format, 0, dpass, e, "second certificate private key file"); if (!s_dkey) { ERR_print_errors(bio_err); goto end; } - s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format, + s_dcert = load_cert(s_dcert_file, s_dcert_format, NULL, e, "second server certificate file"); if (!s_dcert) { @@ -1650,7 +1565,7 @@ int MAIN(int argc, char *argv[]) goto end; } if (s_dchain_file) { - s_dchain = load_certs(bio_err, s_dchain_file, FORMAT_PEM, + s_dchain = load_certs(s_dchain_file, FORMAT_PEM, NULL, e, "second server certificate chain"); if (!s_dchain) goto end; @@ -1658,7 +1573,7 @@ int MAIN(int argc, char *argv[]) } - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL + if (!app_RAND_load_file(NULL, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); @@ -1671,10 +1586,10 @@ int MAIN(int argc, char *argv[]) if (s_quiet && !s_debug) { bio_s_out = BIO_new(BIO_s_null()); if (s_msg && !bio_s_msg) - bio_s_msg = BIO_new_fp(stdout, BIO_NOCLOSE); + bio_s_msg = dup_bio_out(); } else { if (bio_s_out == NULL) - bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE); + bio_s_out = dup_bio_out(); } } #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) @@ -1724,8 +1639,8 @@ int MAIN(int argc, char *argv[]) #ifndef OPENSSL_NO_SRTP if (srtp_profiles != NULL) { - /* Returns 0 on success!! */ - if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles)) { + /* Returns 0 on success! */ + if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { BIO_printf(bio_err, "Error setting SRTP profile\n"); ERR_print_errors(bio_err); goto end; @@ -1733,20 +1648,18 @@ int MAIN(int argc, char *argv[]) } #endif - if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || - (!SSL_CTX_set_default_verify_paths(ctx))) { - /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ + if (!ctx_set_verify_locations(ctx, CAfile, CApath)) { ERR_print_errors(bio_err); - /* goto end; */ + goto end; } - if (vpm && !SSL_CTX_set1_param(ctx, vpm)) { - BIO_printf(bio_err, "Error setting X509 params\n"); + if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { + BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); goto end; } ssl_ctx_add_crls(ctx, crls, 0); - if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe, no_jpake)) + if (!config_ctx(cctx, ssl_args, ctx, no_ecdhe, jpake_secret == NULL)) goto end; if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, @@ -1799,14 +1712,14 @@ int MAIN(int argc, char *argv[]) (!SSL_CTX_set_default_verify_paths(ctx2))) { ERR_print_errors(bio_err); } - if (vpm && !SSL_CTX_set1_param(ctx2, vpm)) { - BIO_printf(bio_err, "Error setting X509 params\n"); + if (vpmtouched && !SSL_CTX_set1_param(ctx2, vpm)) { + BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); goto end; } ssl_ctx_add_crls(ctx2, crls, 0); - if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe, no_jpake)) + if (!config_ctx(cctx, ssl_args, ctx2, no_ecdhe, jpake_secret == NULL)) goto end; } # ifndef OPENSSL_NO_NEXTPROTONEG @@ -1926,8 +1839,8 @@ int MAIN(int argc, char *argv[]) SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); if (!SSL_CTX_set_session_id_context(ctx, - (void *)&s_server_session_id_context, - sizeof s_server_session_id_context)) { + (void *)&s_server_session_id_context, + sizeof s_server_session_id_context)) { BIO_printf(bio_err, "error setting session id context\n"); ERR_print_errors(bio_err); goto end; @@ -1941,13 +1854,12 @@ int MAIN(int argc, char *argv[]) if (ctx2) { SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); if (!SSL_CTX_set_session_id_context(ctx2, - (void *)&s_server_session_id_context, - sizeof s_server_session_id_context)) { + (void *)&s_server_session_id_context, + sizeof s_server_session_id_context)) { BIO_printf(bio_err, "error setting session id context\n"); ERR_print_errors(bio_err); goto end; } - tlsextcbp.biodebug = bio_s_out; SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); @@ -2043,8 +1955,7 @@ int MAIN(int argc, char *argv[]) OPENSSL_free(alpn_ctx.data); #endif ssl_excert_free(exc); - if (ssl_args) - sk_OPENSSL_STRING_free(ssl_args); + sk_OPENSSL_STRING_free(ssl_args); SSL_CONF_CTX_free(cctx); #ifndef OPENSSL_NO_JPAKE if (jpake_secret && psk_key) @@ -2054,8 +1965,7 @@ int MAIN(int argc, char *argv[]) bio_s_out = NULL; BIO_free(bio_s_msg); bio_s_msg = NULL; - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) @@ -2129,19 +2039,21 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) } if (s_tlsextstatus) { SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); - tlscstatp.err = bio_err; SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); } #endif #ifndef OPENSSL_NO_KRB5 if ((kctx = kssl_ctx_new()) != NULL) { SSL_set0_kssl_ctx(con, kctx); - kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC); - kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB); + kssl_ctx_setstring(kctx, KSSL_SERVICE, + krb5svc ? krb5svc : KRB5SVC); + if (krb5tab) + kssl_ctx_setstring(kctx, KSSL_KEYTAB, krb5tab); } #endif /* OPENSSL_NO_KRB5 */ - if (context && !SSL_set_session_id_context(con, context, - strlen((char *)context))) { + if (context + && !SSL_set_session_id_context(con, + context, strlen((char *)context))) { BIO_printf(bio_err, "Error setting session id context\n"); ret = -1; goto err; @@ -2308,6 +2220,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) if (!s_quiet && !s_brief) { if ((i <= 0) || (buf[0] == 'Q')) { BIO_printf(bio_s_out, "DONE\n"); + (void)BIO_flush(bio_s_out); SHUTDOWN(s); close_accept_socket(); ret = -11; @@ -2315,6 +2228,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) } if ((i <= 0) || (buf[0] == 'q')) { BIO_printf(bio_s_out, "DONE\n"); + (void)BIO_flush(bio_s_out); if (SSL_version(con) != DTLS1_VERSION) SHUTDOWN(s); /* @@ -2403,12 +2317,14 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf(bio_s_out, "ERROR\n"); + (void)BIO_flush(bio_s_out); ERR_print_errors(bio_err); ret = 1; goto err; /* break; */ case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_s_out, "DONE\n"); + (void)BIO_flush(bio_s_out); ret = 1; goto err; } @@ -2462,11 +2378,13 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf(bio_s_out, "ERROR\n"); + (void)BIO_flush(bio_s_out); ERR_print_errors(bio_err); ret = 1; goto err; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_s_out, "DONE\n"); + (void)BIO_flush(bio_s_out); ret = 1; goto err; } @@ -2547,6 +2465,7 @@ static int init_ssl_connection(SSL *con) } BIO_printf(bio_err, "ERROR\n"); + verify_error = SSL_get_verify_result(con); if (verify_error != X509_V_OK) { BIO_printf(bio_err, "verify error:%s\n", @@ -2666,6 +2585,9 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) #ifndef OPENSSL_NO_KRB5 KSSL_CTX *kctx; #endif +#ifdef RENEG + int total_bytes = 0; +#endif buf = OPENSSL_malloc(bufsize); if (buf == NULL) @@ -2705,9 +2627,8 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) } #endif /* OPENSSL_NO_KRB5 */ if (context && !SSL_set_session_id_context(con, context, - strlen((char *)context))) { + strlen((char *)context))) goto err; - } sbio = BIO_new_socket(s, BIO_NOCLOSE); if (s_nbio_test) { @@ -2821,7 +2742,7 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) j = sk_SSL_CIPHER_num(sk); for (i = 0; i < j; i++) { c = sk_SSL_CIPHER_value(sk, i); - BIO_printf(io, "%-11s:%-25s", + BIO_printf(io, "%-11s:%-25s ", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); if ((((i + 1) % 2) == 0) && (i + 1 != j)) BIO_puts(io, "\n"); @@ -3003,10 +2924,8 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); err: - if (ret >= 0) BIO_printf(bio_s_out, "ACCEPT\n"); - if (buf != NULL) OPENSSL_free(buf); BIO_free_all(io); @@ -3051,7 +2970,7 @@ static int rev_body(char *hostname, int s, int stype, unsigned char *context) } #endif /* OPENSSL_NO_KRB5 */ if (context && !SSL_set_session_id_context(con, context, - strlen((char *)context))) { + strlen((char *)context))) { ERR_print_errors(bio_err); goto err; } @@ -3228,19 +3147,21 @@ static int add_session(SSL *ssl, SSL_SESSION *session) sess = OPENSSL_malloc(sizeof(simple_ssl_session)); if (!sess) { - BIO_printf(bio_err, "Out of memory adding session to external cache\n"); + BIO_printf(bio_err, "Out of memory adding to external cache\n"); return 0; } SSL_SESSION_get_id(session, &sess->idlen); sess->derlen = i2d_SSL_SESSION(session, NULL); + if (sess->derlen < 0) { + BIO_printf(bio_err, "Error encoding session\n"); + return 0; + } sess->id = BUF_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen); - sess->der = OPENSSL_malloc(sess->derlen); if (!sess->id || !sess->der) { - BIO_printf(bio_err, "Out of memory adding session to external cache\n"); - + BIO_printf(bio_err, "Out of memory adding to external cache\n"); if (sess->id) OPENSSL_free(sess->id); if (sess->der) @@ -3249,7 +3170,9 @@ static int add_session(SSL *ssl, SSL_SESSION *session) return 0; } p = sess->der; - if (i2d_SSL_SESSION(session, &p) < 0) { + + /* Assume it still works. */ + if (i2d_SSL_SESSION(session, &p) != sess->derlen) { BIO_printf(bio_err, "Error encoding session\n"); return 0; } diff --git a/apps/s_socket.c b/apps/s_socket.c index 5bdfc6c8e0..4c440dc50a 100644 --- a/apps/s_socket.c +++ b/apps/s_socket.c @@ -1,6 +1,3 @@ -/* - * apps/s_socket.c - socket-related functions used by s_client and s_server - */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,7 +54,56 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 199-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 + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* socket-related functions used by s_client and s_server */ #include #include #include @@ -76,10 +122,8 @@ typedef unsigned int u_int; #endif #define USE_SOCKETS -#define NON_MAIN #include "apps.h" #undef USE_SOCKETS -#undef NON_MAIN #include "s_apps.h" #include @@ -185,7 +229,7 @@ static int ssl_sock_init(void) return (0); } } -# endif /* OPENSSL_SYS_WINDOWS */ +# endif return (1); } @@ -503,16 +547,6 @@ static int do_accept(int acc_sock, int *sock, char **host) return (0); } -/*- - ling.l_onoff=1; - ling.l_linger=0; - i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling)); - if (i < 0) { perror("linger"); return(0); } - i=0; - i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); - if (i < 0) { perror("keepalive"); return(0); } -*/ - if (host == NULL) goto end; # ifndef BIT_FIELD_LIMITS @@ -580,7 +614,7 @@ static int do_accept_unix(int acc_sock, int *sock) # endif int extract_host_port(char *str, char **host_ptr, unsigned char *ip, - short *port_ptr) + unsigned short *port_ptr) { char *h, *p; @@ -645,7 +679,7 @@ static int host_ip(const char *str, unsigned char ip[4]) return (0); } -int extract_port(const char *str, short *port_ptr) +int extract_port(const char *str, unsigned short *port_ptr) { int i; struct servent *s; diff --git a/apps/s_time.c b/apps/s_time.c index 8f4980b677..5bca72ba72 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -1,4 +1,3 @@ -/* apps/s_time.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -82,9 +81,6 @@ # include OPENSSL_UNISTD #endif -#undef PROG -#define PROG s_time_main - #undef ioctl #define ioctl ioctlsocket @@ -107,286 +103,171 @@ #undef SECONDS #define SECONDS 30 +#define SECONDSSTR "30" + extern int verify_depth; extern int verify_error; -static void s_time_usage(void); -static int parseArgs(int argc, char **argv); -static SSL *doConnection(SSL *scon); -static void s_time_init(void); - -/*********************************************************************** - * Static data declarations - */ +static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx); -/* static char *port=PORT_STR;*/ -static char *host = SSL_CONNECT_NAME; -static char *t_cert_file = NULL; -static char *t_key_file = NULL; -static char *CApath = NULL; -static char *CAfile = NULL; -static char *tm_cipher = NULL; -static int tm_verify = SSL_VERIFY_NONE; -static int maxTime = SECONDS; -static SSL_CTX *tm_ctx = NULL; -static const SSL_METHOD *s_time_meth = NULL; -static char *s_www_path = NULL; -static long bytes_read = 0; -static int st_bugs = 0; -static int perform = 0; -#ifdef FIONBIO -static int t_nbio = 0; +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_KEY, OPT_CAPATH, + OPT_CAFILE, OPT_NEW, OPT_REUSE, OPT_BUGS, OPT_VERIFY, OPT_TIME, +#ifndef OPENSSL_NO_SSL3 + OPT_SSL3, #endif -#ifdef OPENSSL_SYS_WIN32 -static int exitNow = 0; /* Set when it's time to exit main */ + OPT_WWW +} OPTION_CHOICE; + +OPTIONS s_time_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"connect", OPT_CONNECT, 's', + "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"}, + {"cipher", OPT_CIPHER, 's', "Cipher to use, see 'openssl ciphers'"}, + {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"}, + {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"new", OPT_NEW, '-', "Just time new connections"}, + {"reuse", OPT_REUSE, '-', "Just time connection reuse"}, + {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"}, + {"verify", OPT_VERIFY, 'p', + "Turn on peer certificate verification, set depth"}, + {"time", OPT_TIME, 'p', "Sf seconds to collect data, default" SECONDSSTR}, + {"www", OPT_WWW, 's', "Fetch specified page from the site"}, +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, #endif + {NULL} +}; -static void s_time_init(void) -{ - host = SSL_CONNECT_NAME; - t_cert_file = NULL; - t_key_file = NULL; - CApath = NULL; - CAfile = NULL; - tm_cipher = NULL; - tm_verify = SSL_VERIFY_NONE; - maxTime = SECONDS; - tm_ctx = NULL; - s_time_meth = NULL; - s_www_path = NULL; - bytes_read = 0; - st_bugs = 0; - perform = 0; - -#ifdef FIONBIO - t_nbio = 0; -#endif -#ifdef OPENSSL_SYS_WIN32 - exitNow = 0; /* Set when it's time to exit main */ -#endif -} +#define START 0 +#define STOP 1 -/*********************************************************************** - * usage - display usage message - */ -static void s_time_usage(void) +static double tm_Time_F(int s) { - static char umsg[] = "\ --time arg - max number of seconds to collect data, default %d\n\ --verify arg - turn on peer certificate verification, arg == depth\n\ --cert arg - certificate file to use, PEM format assumed\n\ --key arg - RSA file to use, PEM format assumed, key is in cert file\n\ - file if not specified by this option\n\ --CApath arg - PEM format directory of CA's\n\ --CAfile arg - PEM format file of CA's\n\ --cipher - preferred cipher to use, play with 'openssl ciphers'\n\n"; - - printf("usage: s_time \n\n"); - - printf("-connect host:port - host:port to connect to (default is %s)\n", - SSL_CONNECT_NAME); -#ifdef FIONBIO - printf("-nbio - Run with non-blocking IO\n"); - printf("-ssl3 - Just use SSLv3\n"); - printf("-bugs - Turn on SSL bug compatibility\n"); - printf("-new - Just time new connections\n"); - printf("-reuse - Just time connection reuse\n"); - printf("-www page - Retrieve 'page' from the site\n"); -#endif - printf(umsg, SECONDS); + return app_tminterval(s, 1); } -/*********************************************************************** - * parseArgs - Parse command line arguments and initialize data - * - * Returns 0 if ok, -1 on bad args - */ -static int parseArgs(int argc, char **argv) +int s_time_main(int argc, char **argv) { - int badop = 0; + char buf[1024 * 8]; + SSL *scon = NULL; + SSL_CTX *ctx = NULL; + const SSL_METHOD *meth = NULL; + char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *www_path = NULL; + char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; + double totalTime = 0.0; + int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = + 0, ver; + long bytes_read = 0, finishtime = 0; + OPTION_CHOICE o; +#ifdef OPENSSL_SYS_WIN32 + int exitNow = 0; /* Set when it's time to exit main */ +#endif + meth = SSLv23_client_method(); verify_depth = 0; verify_error = X509_V_OK; - argc--; - argv++; - - while (argc >= 1) { - if (strcmp(*argv, "-connect") == 0) { - if (--argc < 1) - goto bad; - host = *(++argv); - } - else if (strcmp(*argv, "-reuse") == 0) + prog = opt_init(argc, argv, s_time_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(s_time_options); + ret = 0; + goto end; + case OPT_CONNECT: + host = opt_arg(); + break; + case OPT_REUSE: perform = 2; - else if (strcmp(*argv, "-new") == 0) + break; + case OPT_NEW: perform = 1; - else if (strcmp(*argv, "-verify") == 0) { - - tm_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); - BIO_printf(bio_err, "verify depth is %d\n", verify_depth); - - } else if (strcmp(*argv, "-cert") == 0) { - - if (--argc < 1) - goto bad; - t_cert_file = *(++argv); - - } else if (strcmp(*argv, "-key") == 0) { - - if (--argc < 1) - goto bad; - t_key_file = *(++argv); - - } else if (strcmp(*argv, "-CApath") == 0) { - - if (--argc < 1) - goto bad; - CApath = *(++argv); - - } else if (strcmp(*argv, "-CAfile") == 0) { - - if (--argc < 1) - goto bad; - CAfile = *(++argv); - - } else if (strcmp(*argv, "-cipher") == 0) { - - if (--argc < 1) - goto bad; - tm_cipher = *(++argv); - } -#ifdef FIONBIO - else if (strcmp(*argv, "-nbio") == 0) { - t_nbio = 1; - } -#endif - else if (strcmp(*argv, "-www") == 0) { - if (--argc < 1) - goto bad; - s_www_path = *(++argv); - if (strlen(s_www_path) > MYBUFSIZ - 100) { - BIO_printf(bio_err, "-www option too long\n"); - badop = 1; - } - } else if (strcmp(*argv, "-bugs") == 0) + break; + case OPT_VERIFY: + if (!opt_int(opt_arg(), &verify_depth)) + goto opthelp; + BIO_printf(bio_err, "%s: verify depth is %d\n", + prog, verify_depth); + break; + case OPT_CERT: + certfile = opt_arg(); + break; + case OPT_KEY: + keyfile = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CIPHER: + cipher = opt_arg(); + break; + case OPT_BUGS: st_bugs = 1; -#ifndef OPENSSL_NO_SSL3 - else if (strcmp(*argv, "-ssl3") == 0) - s_time_meth = SSLv3_client_method(); -#endif - else if (strcmp(*argv, "-time") == 0) { - - if (--argc < 1) - goto bad; - maxTime = atoi(*(++argv)); - if (maxTime <= 0) { - BIO_printf(bio_err, "time must be > 0\n"); - badop = 1; + break; + case OPT_TIME: + if (!opt_int(opt_arg(), &maxtime)) + goto opthelp; + break; + case OPT_WWW: + www_path = opt_arg(); + if (strlen(www_path) > MYBUFSIZ - 100) { + BIO_printf(bio_err, "%s: -www option too long\n", prog); + goto end; } - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badop = 1; break; +#ifndef OPENSSL_NO_SSL3 + case OPT_SSL3: + meth = SSLv3_client_method(); + break; +#endif } - - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (perform == 0) - perform = 3; - - if (badop) { - bad: - s_time_usage(); - return -1; + if (cipher == NULL) + cipher = getenv("SSL_CIPHER"); + if (cipher == NULL) { + fprintf(stderr, "No CIPHER specified\n"); + goto end; } - return 0; /* Valid args */ -} - -/*********************************************************************** - * TIME - time functions - */ -#define START 0 -#define STOP 1 - -static double tm_Time_F(int s) -{ - return app_tminterval(s, 1); -} - -/*********************************************************************** - * MAIN - main processing area for client - * real name depends on MONOLITH - */ -int MAIN(int, char **); - -int MAIN(int argc, char **argv) -{ - double totalTime = 0.0; - int nConn = 0; - SSL *scon = NULL; - long finishtime = 0; - int ret = 1, i; - char buf[1024 * 8]; - int ver; - - apps_startup(); - s_time_init(); - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - s_time_meth = SSLv23_client_method(); - - /* parse the command line arguments */ - if (parseArgs(argc, argv) < 0) + if ((ctx = SSL_CTX_new(meth)) == NULL) goto end; - OpenSSL_add_ssl_algorithms(); - if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL) - return (1); - - SSL_CTX_set_quiet_shutdown(tm_ctx, 1); + SSL_CTX_set_quiet_shutdown(ctx, 1); if (st_bugs) - SSL_CTX_set_options(tm_ctx, SSL_OP_ALL); - if (!SSL_CTX_set_cipher_list(tm_ctx, tm_cipher)) + SSL_CTX_set_options(ctx, SSL_OP_ALL); + if (!SSL_CTX_set_cipher_list(ctx, cipher)) goto end; - if (!set_cert_stuff(tm_ctx, t_cert_file, t_key_file)) + if (!set_cert_stuff(ctx, certfile, keyfile)) goto end; - SSL_load_error_strings(); - - if ((!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) || - (!SSL_CTX_set_default_verify_paths(tm_ctx))) { - /* - * BIO_printf(bio_err,"error setting default verify locations\n"); - */ + if (!ctx_set_verify_locations(ctx, CAfile, CApath)) { ERR_print_errors(bio_err); - /* goto end; */ - } - - if (tm_cipher == NULL) - tm_cipher = getenv("SSL_CIPHER"); - - if (tm_cipher == NULL) { - fprintf(stderr, "No CIPHER specified\n"); + goto end; } - if (!(perform & 1)) goto next; - printf("Collecting connection statistics for %d seconds\n", maxTime); + printf("Collecting connection statistics for %d seconds\n", maxtime); /* Loop and time how long it takes to make connections */ bytes_read = 0; - finishtime = (long)time(NULL) + maxTime; + finishtime = (long)time(NULL) + maxtime; tm_Time_F(START); for (;;) { if (finishtime < (long)time(NULL)) @@ -400,12 +281,12 @@ int MAIN(int argc, char **argv) goto end; #endif - if ((scon = doConnection(NULL)) == NULL) + if ((scon = doConnection(NULL, host, ctx)) == NULL) goto end; - if (s_www_path != NULL) { + if (www_path != NULL) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", - s_www_path); + www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) @@ -438,13 +319,13 @@ int MAIN(int argc, char **argv) } totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ - i = (int)((long)time(NULL) - finishtime + maxTime); + i = (int)((long)time(NULL) - finishtime + maxtime); printf ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn / totalTime), bytes_read); printf ("%d connections in %ld real seconds, %ld bytes read per connection\n", - nConn, (long)time(NULL) - finishtime + maxTime, bytes_read / nConn); + nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); /* * Now loop and time connections using the same session id over and over @@ -456,16 +337,17 @@ int MAIN(int argc, char **argv) printf("\n\nNow timing with session id reuse.\n"); /* Get an SSL object so we can reuse the session id */ - if ((scon = doConnection(NULL)) == NULL) { + if ((scon = doConnection(NULL, host, ctx)) == NULL) { fprintf(stderr, "Unable to get connection\n"); goto end; } - if (s_www_path != NULL) { - BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path); + if (www_path != NULL) { + BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; - while (SSL_read(scon, buf, sizeof(buf)) > 0) ; + while (SSL_read(scon, buf, sizeof(buf)) > 0) + continue; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); @@ -477,7 +359,7 @@ int MAIN(int argc, char **argv) nConn = 0; totalTime = 0.0; - finishtime = (long)time(NULL) + maxTime; + finishtime = (long)time(NULL) + maxtime; printf("starting\n"); bytes_read = 0; @@ -495,12 +377,12 @@ int MAIN(int argc, char **argv) goto end; #endif - if ((doConnection(scon)) == NULL) + if ((doConnection(scon, host, ctx)) == NULL) goto end; - if (s_www_path) { + if (www_path) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", - s_www_path); + www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) @@ -535,27 +417,20 @@ int MAIN(int argc, char **argv) nConn, totalTime, ((double)nConn / totalTime), bytes_read); printf ("%d connections in %ld real seconds, %ld bytes read per connection\n", - nConn, (long)time(NULL) - finishtime + maxTime, - bytes_read / (nConn?nConn:1)); + nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); ret = 0; + end: SSL_free(scon); - - SSL_CTX_free(tm_ctx); - tm_ctx = NULL; - apps_shutdown(); - OPENSSL_EXIT(ret); + SSL_CTX_free(ctx); + return (ret); } /*- * doConnection - make a connection - * Args: - * scon = earlier ssl connection for session id, or NULL - * Returns: - * SSL * = the connection pointer. */ -static SSL *doConnection(SSL *scon) +static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) { BIO *conn; SSL *serverCon; @@ -565,11 +440,10 @@ static SSL *doConnection(SSL *scon) if ((conn = BIO_new(BIO_s_connect())) == NULL) return (NULL); -/* BIO_set_conn_port(conn,port);*/ BIO_set_conn_hostname(conn, host); if (scon == NULL) - serverCon = SSL_new(tm_ctx); + serverCon = SSL_new(ctx); else { serverCon = scon; SSL_set_connect_state(serverCon); diff --git a/apps/sess_id.c b/apps/sess_id.c index 9421e40842..cfecd86a50 100644 --- a/apps/sess_id.c +++ b/apps/sess_id.c @@ -1,4 +1,3 @@ -/* apps/sess_id.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,94 +65,81 @@ #include #include -#undef PROG -#define PROG sess_id_main - -static const char *sess_id_usage[] = { - "usage: sess_id args\n", - "\n", - " -inform arg - input format - default PEM (DER or PEM)\n", - " -outform arg - output format - default PEM (PEM, DER or NSS)\n", - " -in arg - input file - default stdin\n", - " -out arg - output file - default stdout\n", - " -text - print ssl session id details\n", - " -cert - output certificate \n", - " -noout - no output of encoded session info\n", - " -context arg - set the session ID context\n", - NULL +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, + OPT_TEXT, OPT_CERT, OPT_NOOUT, OPT_CONTEXT +} OPTION_CHOICE; + +OPTIONS sess_id_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, + {"outform", OPT_OUTFORM, 'F', + "Output format - default PEM (PEM, DER or NSS)"}, + {"in", OPT_IN, 's', "Input file - default stdin"}, + {"out", OPT_OUT, 's', "Output file - default stdout"}, + {"text", OPT_TEXT, '-', "Print ssl session id details"}, + {"cert", OPT_CERT, '-', "Output certificate "}, + {"noout", OPT_NOOUT, '-', "Don't output the encoded session info"}, + {"context", OPT_CONTEXT, 's', "Set the session ID context"}, + {NULL} }; static SSL_SESSION *load_sess_id(char *file, int format); -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int sess_id_main(int argc, char **argv) { SSL_SESSION *x = NULL; X509 *peer = NULL; - int ret = 1, i, num, badops = 0; BIO *out = NULL; - int informat, outformat; - char *infile = NULL, *outfile = NULL, *context = NULL; - int cert = 0, noout = 0, text = 0; - const char **pp; - - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - - argc--; - argv++; - num = 0; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-text") == 0) + char *infile = NULL, *outfile = NULL, *context = NULL, *prog; + int informat = FORMAT_PEM, outformat = FORMAT_PEM; + int cert = 0, noout = 0, text = 0, ret = 1, i, num = 0; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, sess_id_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(sess_id_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_TEXT: text = ++num; - else if (strcmp(*argv, "-cert") == 0) + break; + case OPT_CERT: cert = ++num; - else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = ++num; - else if (strcmp(*argv, "-context") == 0) { - if (--argc < 1) - goto bad; - context = *++argv; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; + break; + case OPT_CONTEXT: + context = opt_arg(); break; } - argc--; - argv++; } + argc = opt_num_rest(); + argv = opt_rest(); - if (badops) { - bad: - for (pp = sess_id_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); - goto end; - } - - ERR_load_crypto_strings(); x = load_sess_id(infile, informat); if (x == NULL) { goto end; @@ -166,33 +152,20 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Context too long\n"); goto end; } - if (!SSL_SESSION_set1_id_context(x, (unsigned char *)context, ctx_len)) { + if (!SSL_SESSION_set1_id_context(x, (unsigned char *)context, + ctx_len)) { BIO_printf(bio_err, "Error setting id context\n"); goto end; } } if (!noout || text) { - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); + const char* modeflag = "w"; + if (outformat == FORMAT_ASN1 || outformat == FORMAT_NSS) + modeflag = "wb"; + out = bio_open_default(outfile, modeflag); + if (out == NULL) goto end; - } - - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } } if (text) { @@ -240,8 +213,7 @@ int MAIN(int argc, char **argv) BIO_free_all(out); if (x != NULL) SSL_SESSION_free(x); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static SSL_SESSION *load_sess_id(char *infile, int format) @@ -249,28 +221,13 @@ static SSL_SESSION *load_sess_id(char *infile, int format) SSL_SESSION *x = NULL; BIO *in = NULL; - in = BIO_new(BIO_s_file()); - if (in == NULL) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, RB(format)); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - goto end; - } - } if (format == FORMAT_ASN1) x = d2i_SSL_SESSION_bio(in, NULL); - else if (format == FORMAT_PEM) + else x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); - else { - BIO_printf(bio_err, "bad input format specified for input crl\n"); - goto end; - } if (x == NULL) { BIO_printf(bio_err, "unable to load SSL_SESSION\n"); ERR_print_errors(bio_err); diff --git a/apps/smime.c b/apps/smime.c index 930978fd9b..532446f49f 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -1,4 +1,3 @@ -/* smime.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. @@ -68,8 +67,6 @@ #include #include -#undef PROG -#define PROG smime_main static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int smime_cb(int ok, X509_STORE_CTX *ctx); @@ -83,277 +80,315 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx); #define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP) #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENCRYPT, OPT_DECRYPT, OPT_SIGN, OPT_RESIGN, OPT_VERIFY, + OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN, + OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, + OPT_BINARY, OPT_NOSIGS, OPT_STREAM, OPT_INDEF, OPT_NOINDEF, + OPT_NOOLDMIME, OPT_CRLFEOL, OPT_RAND, OPT_ENGINE, OPT_PASSIN, + OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD, + OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE, + OPT_V_ENUM, + OPT_CAPATH, OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTFORM, OPT_CONTENT +} OPTION_CHOICE; + +OPTIONS smime_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, + {OPT_HELP_STR, 1, '-', + " cert.pem... recipient certs for encryption\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, + {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, + {"sign", OPT_SIGN, '-', "Sign message"}, + {"verify", OPT_VERIFY, '-', "Verify signed message"}, + {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"}, + {"nointern", OPT_NOINTERN, '-', + "Don't search certificates in message for signer"}, + {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, + {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, + {"nocerts", OPT_NOCERTS, '-', + "Don't include signers certificate when signing"}, + {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, + {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, + {"binary", OPT_BINARY, '-', "Don't translate message to text"}, + {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, + {"signer", OPT_SIGNER, '<', "Signer certificate file"}, + {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"}, + {"in", OPT_IN, '<', "Input file"}, + {"inform", OPT_INFORM, 'F', "Input format SMIME (default), PEM or DER"}, + {"inkey", OPT_INKEY, '<', + "Input private key (if not signer or recipient)"}, + {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', + "Output format SMIME (default), PEM or DER"}, + {"content", OPT_CONTENT, '<', + "Supply or override content for detached signature"}, + {"to", OPT_TO, 's', "To address"}, + {"from", OPT_FROM, 's', "From address"}, + {"subject", OPT_SUBJECT, 's', "Subject"}, + {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, + {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"}, + {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, + {"resign", OPT_RESIGN, '-'}, + {"nochain", OPT_NOCHAIN, '-'}, + {"nosmimecap", OPT_NOSMIMECAP, '-'}, + {"stream", OPT_STREAM, '-'}, + {"indef", OPT_INDEF, '-'}, + {"noindef", OPT_NOINDEF, '-'}, + {"nooldmime", OPT_NOOLDMIME, '-'}, + {"crlfeol", OPT_CRLFEOL, '-'}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"md", OPT_MD, 's'}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, + OPT_V_OPTIONS, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int smime_main(int argc, char **argv) { - ENGINE *e = NULL; - int operation = 0; - int ret = 0; - char **args; - const char *inmode = "r", *outmode = "w"; - char *infile = NULL, *outfile = NULL; - char *signerfile = NULL, *recipfile = NULL; - STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; - char *certfile = NULL, *keyfile = NULL, *contfile = NULL; - const EVP_CIPHER *cipher = NULL; - PKCS7 *p7 = NULL; - X509_STORE *store = NULL; - X509 *cert = NULL, *recip = NULL, *signer = NULL; + BIO *in = NULL, *out = NULL, *indata = NULL; EVP_PKEY *key = NULL; + PKCS7 *p7 = NULL; + STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; - BIO *in = NULL, *out = NULL, *indata = NULL; - int badarg = 0; - int flags = PKCS7_DETACHED; - char *to = NULL, *from = NULL, *subject = NULL; - char *CAfile = NULL, *CApath = NULL; - char *passargin = NULL, *passin = NULL; - char *inrand = NULL; - int need_rand = 0; - int indef = 0; + X509 *cert = NULL, *recip = NULL, *signer = NULL; + X509_STORE *store = NULL; + X509_VERIFY_PARAM *vpm = NULL; + const EVP_CIPHER *cipher = NULL; const EVP_MD *sign_md = NULL; - int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; - int keyform = FORMAT_PEM; + char *CAfile = NULL, *CApath = NULL, *inrand = NULL, *engine = NULL; + char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *prog; + char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = + NULL; + char *passinarg = NULL, *passin = NULL, *to = NULL, *from = + NULL, *subject = NULL; + const char *inmode = "r", *outmode = "w"; + OPTION_CHOICE o; + int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef = + 0; + int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform = + FORMAT_PEM; + int vpmtouched = 0, rv = 0; #ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + ENGINE *e = NULL; #endif - X509_VERIFY_PARAM *vpm = NULL; - - args = argv + 1; - ret = 1; - - apps_startup(); - - if (bio_err == NULL) { - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - } - - if (!load_config(bio_err, NULL)) - goto end; + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) + return 1; - while (!badarg && *args && *args[0] == '-') { - if (!strcmp(*args, "-encrypt")) + prog = opt_init(argc, argv, smime_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(smime_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_ENCRYPT: operation = SMIME_ENCRYPT; - else if (!strcmp(*args, "-decrypt")) + break; + case OPT_DECRYPT: operation = SMIME_DECRYPT; - else if (!strcmp(*args, "-sign")) + break; + case OPT_SIGN: operation = SMIME_SIGN; - else if (!strcmp(*args, "-resign")) + break; + case OPT_RESIGN: operation = SMIME_RESIGN; - else if (!strcmp(*args, "-verify")) + break; + case OPT_VERIFY: operation = SMIME_VERIFY; - else if (!strcmp(*args, "-pk7out")) + break; + case OPT_PK7OUT: operation = SMIME_PK7OUT; -#ifndef OPENSSL_NO_DES - else if (!strcmp(*args, "-des3")) - cipher = EVP_des_ede3_cbc(); - else if (!strcmp(*args, "-des")) - cipher = EVP_des_cbc(); -#endif -#ifndef OPENSSL_NO_SEED - else if (!strcmp(*args, "-seed")) - cipher = EVP_seed_cbc(); -#endif -#ifndef OPENSSL_NO_RC2 - else if (!strcmp(*args, "-rc2-40")) - cipher = EVP_rc2_40_cbc(); - else if (!strcmp(*args, "-rc2-128")) - cipher = EVP_rc2_cbc(); - else if (!strcmp(*args, "-rc2-64")) - cipher = EVP_rc2_64_cbc(); -#endif -#ifndef OPENSSL_NO_AES - else if (!strcmp(*args, "-aes128")) - cipher = EVP_aes_128_cbc(); - else if (!strcmp(*args, "-aes192")) - cipher = EVP_aes_192_cbc(); - else if (!strcmp(*args, "-aes256")) - cipher = EVP_aes_256_cbc(); -#endif -#ifndef OPENSSL_NO_CAMELLIA - else if (!strcmp(*args, "-camellia128")) - cipher = EVP_camellia_128_cbc(); - else if (!strcmp(*args, "-camellia192")) - cipher = EVP_camellia_192_cbc(); - else if (!strcmp(*args, "-camellia256")) - cipher = EVP_camellia_256_cbc(); -#endif - else if (!strcmp(*args, "-text")) + break; + case OPT_TEXT: flags |= PKCS7_TEXT; - else if (!strcmp(*args, "-nointern")) + break; + case OPT_NOINTERN: flags |= PKCS7_NOINTERN; - else if (!strcmp(*args, "-noverify")) + break; + case OPT_NOVERIFY: flags |= PKCS7_NOVERIFY; - else if (!strcmp(*args, "-nochain")) + break; + case OPT_NOCHAIN: flags |= PKCS7_NOCHAIN; - else if (!strcmp(*args, "-nocerts")) + break; + case OPT_NOCERTS: flags |= PKCS7_NOCERTS; - else if (!strcmp(*args, "-noattr")) + break; + case OPT_NOATTR: flags |= PKCS7_NOATTR; - else if (!strcmp(*args, "-nodetach")) + break; + case OPT_NODETACH: flags &= ~PKCS7_DETACHED; - else if (!strcmp(*args, "-nosmimecap")) + break; + case OPT_NOSMIMECAP: flags |= PKCS7_NOSMIMECAP; - else if (!strcmp(*args, "-binary")) + break; + case OPT_BINARY: flags |= PKCS7_BINARY; - else if (!strcmp(*args, "-nosigs")) + break; + case OPT_NOSIGS: flags |= PKCS7_NOSIGS; - else if (!strcmp(*args, "-stream")) + break; + case OPT_STREAM: + case OPT_INDEF: indef = 1; - else if (!strcmp(*args, "-indef")) - indef = 1; - else if (!strcmp(*args, "-noindef")) + break; + case OPT_NOINDEF: indef = 0; - else if (!strcmp(*args, "-nooldmime")) + break; + case OPT_NOOLDMIME: flags |= PKCS7_NOOLDMIMETYPE; - else if (!strcmp(*args, "-crlfeol")) + break; + case OPT_CRLFEOL: flags |= PKCS7_CRLFEOL; - else if (!strcmp(*args, "-rand")) { - if (!args[1]) - goto argerr; - args++; - inrand = *args; + break; + case OPT_RAND: + inrand = opt_arg(); need_rand = 1; - } -#ifndef OPENSSL_NO_ENGINE - else if (!strcmp(*args, "-engine")) { - if (!args[1]) - goto argerr; - engine = *++args; - } -#endif - else if (!strcmp(*args, "-passin")) { - if (!args[1]) - goto argerr; - passargin = *++args; - } else if (!strcmp(*args, "-to")) { - if (!args[1]) - goto argerr; - to = *++args; - } else if (!strcmp(*args, "-from")) { - if (!args[1]) - goto argerr; - from = *++args; - } else if (!strcmp(*args, "-subject")) { - if (!args[1]) - goto argerr; - subject = *++args; - } else if (!strcmp(*args, "-signer")) { - if (!args[1]) - goto argerr; + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_TO: + to = opt_arg(); + break; + case OPT_FROM: + from = opt_arg(); + break; + case OPT_SUBJECT: + subject = opt_arg(); + break; + case OPT_SIGNER: /* If previous -signer argument add signer to list */ - if (signerfile) { - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (sksigners == NULL + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); - if (!keyfile) + if (keyfile == NULL) keyfile = signerfile; - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (skkeys == NULL + && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } - signerfile = *++args; - } else if (!strcmp(*args, "-recip")) { - if (!args[1]) - goto argerr; - recipfile = *++args; - } else if (!strcmp(*args, "-md")) { - if (!args[1]) - goto argerr; - sign_md = EVP_get_digestbyname(*++args); - if (sign_md == NULL) { - BIO_printf(bio_err, "Unknown digest %s\n", *args); - goto argerr; - } - } else if (!strcmp(*args, "-inkey")) { - if (!args[1]) - goto argerr; + signerfile = opt_arg(); + break; + case OPT_RECIP: + recipfile = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_arg(), &sign_md)) + goto opthelp; + break; + case OPT_CIPHER: + if (!opt_cipher(opt_unknown(), &cipher)) + goto opthelp; + break; + case OPT_INKEY: /* If previous -inkey arument add signer to list */ if (keyfile) { - if (!signerfile) { - BIO_puts(bio_err, "Illegal -inkey without -signer\n"); - goto argerr; + if (signerfile == NULL) { + BIO_printf(bio_err, + "%s: Must have -signer before -inkey\n", prog); + goto opthelp; } - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (sksigners == NULL + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (skkeys == NULL + && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); } - keyfile = *++args; - } else if (!strcmp(*args, "-keyform")) { - if (!args[1]) - goto argerr; - keyform = str2fmt(*++args); - } else if (!strcmp(*args, "-certfile")) { - if (!args[1]) - goto argerr; - certfile = *++args; - } else if (!strcmp(*args, "-CAfile")) { - if (!args[1]) - goto argerr; - CAfile = *++args; - } else if (!strcmp(*args, "-CApath")) { - if (!args[1]) - goto argerr; - CApath = *++args; - } else if (!strcmp(*args, "-in")) { - if (!args[1]) - goto argerr; - infile = *++args; - } else if (!strcmp(*args, "-inform")) { - if (!args[1]) - goto argerr; - informat = str2fmt(*++args); - } else if (!strcmp(*args, "-outform")) { - if (!args[1]) - goto argerr; - outformat = str2fmt(*++args); - } else if (!strcmp(*args, "-out")) { - if (!args[1]) - goto argerr; - outfile = *++args; - } else if (!strcmp(*args, "-content")) { - if (!args[1]) - goto argerr; - contfile = *++args; - } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) - continue; - else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) - badarg = 1; - args++; + keyfile = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) + goto opthelp; + break; + case OPT_CERTFILE: + certfile = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CONTENT: + contfile = opt_arg(); + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto opthelp; + vpmtouched++; + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); - goto argerr; + goto opthelp; } if (operation & SMIME_SIGNERS) { /* Check to see if any final signer needs to be appended */ if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); - goto argerr; + goto opthelp; } if (signerfile) { - if (!sksigners) - sksigners = sk_OPENSSL_STRING_new_null(); + if (!sksigners + && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); - if (!skkeys) - skkeys = sk_OPENSSL_STRING_new_null(); + if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) + goto end; if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); - badarg = 1; + goto opthelp; } signerfile = NULL; keyfile = NULL; @@ -362,118 +397,28 @@ int MAIN(int argc, char **argv) if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); - badarg = 1; + goto opthelp; } } else if (operation == SMIME_ENCRYPT) { - if (!*args) { + if (argc == 0) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); - badarg = 1; + goto opthelp; } need_rand = 1; } else if (!operation) - badarg = 1; - - if (badarg) { - argerr: - BIO_printf(bio_err, "Usage smime [options] cert.pem ...\n"); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, "-encrypt encrypt message\n"); - BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); - BIO_printf(bio_err, "-sign sign message\n"); - BIO_printf(bio_err, "-verify verify signed message\n"); - BIO_printf(bio_err, "-pk7out output PKCS#7 structure\n"); -#ifndef OPENSSL_NO_DES - BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); - BIO_printf(bio_err, "-des encrypt with DES\n"); -#endif -#ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, "-seed encrypt with SEED\n"); -#endif -#ifndef OPENSSL_NO_RC2 - BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); - BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); - BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); -#endif -#ifndef OPENSSL_NO_AES - BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc aes\n"); -#endif -#ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); - BIO_printf(bio_err, - " encrypt PEM output with cbc camellia\n"); -#endif - BIO_printf(bio_err, - "-nointern don't search certificates in message for signer\n"); - BIO_printf(bio_err, - "-nosigs don't verify message signature\n"); - BIO_printf(bio_err, - "-noverify don't verify signers certificate\n"); - BIO_printf(bio_err, - "-nocerts don't include signers certificate when signing\n"); - BIO_printf(bio_err, "-nodetach use opaque signing\n"); - BIO_printf(bio_err, - "-noattr don't include any signed attributes\n"); - BIO_printf(bio_err, - "-binary don't translate message to text\n"); - BIO_printf(bio_err, "-certfile file other certificates file\n"); - BIO_printf(bio_err, "-signer file signer certificate file\n"); - BIO_printf(bio_err, - "-recip file recipient certificate file for decryption\n"); - BIO_printf(bio_err, "-in file input file\n"); - BIO_printf(bio_err, - "-inform arg input format SMIME (default), PEM or DER\n"); - BIO_printf(bio_err, - "-inkey file input private key (if not signer or recipient)\n"); - BIO_printf(bio_err, - "-keyform arg input private key format (PEM or ENGINE)\n"); - BIO_printf(bio_err, "-out file output file\n"); - BIO_printf(bio_err, - "-outform arg output format SMIME (default), PEM or DER\n"); - BIO_printf(bio_err, - "-content file supply or override content for detached signature\n"); - BIO_printf(bio_err, "-to addr to address\n"); - BIO_printf(bio_err, "-from ad from address\n"); - BIO_printf(bio_err, "-subject s subject\n"); - BIO_printf(bio_err, - "-text include or delete text MIME headers\n"); - BIO_printf(bio_err, - "-CApath dir trusted certificates directory\n"); - BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); - BIO_printf(bio_err, - "-trusted_first use locally trusted CA's first when building trust chain\n"); - BIO_printf(bio_err, - "-no_alt_chains only ever use the first certificate chain found\n"); - BIO_printf(bio_err, - "-crl_check check revocation status of signer's certificate using CRLs\n"); - BIO_printf(bio_err, - "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e use engine e, possibly a hardware device.\n"); -#endif - BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); - BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - BIO_printf(bio_err, - "cert.pem recipient certificate(s) for encryption\n"); - goto end; - } + goto opthelp; + #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { - app_RAND_load_file(NULL, bio_err, (inrand != NULL)); + app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); @@ -510,19 +455,21 @@ int MAIN(int argc, char **argv) #endif } encerts = sk_X509_new_null(); - while (*args) { - if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, - NULL, e, "recipient certificate file"))) { + if (!encerts) + goto end; + while (*argv) { + cert = load_cert(*argv, FORMAT_PEM, + NULL, e, "recipient certificate file"); + if (cert == NULL) goto end; - } sk_X509_push(encerts, cert); cert = NULL; - args++; + argv++; } } if (certfile) { - if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, + if (!(other = load_certs(certfile, FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; @@ -530,7 +477,7 @@ int MAIN(int argc, char **argv) } if (recipfile && (operation == SMIME_DECRYPT)) { - if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, + if (!(recip = load_cert(recipfile, FORMAT_PEM, NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; @@ -547,19 +494,14 @@ int MAIN(int argc, char **argv) keyfile = NULL; if (keyfile) { - key = load_key(bio_err, keyfile, keyform, 0, passin, e, - "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } - if (infile) { - if (!(in = BIO_new_file(infile, inmode))) { - BIO_printf(bio_err, "Can't open input file %s\n", infile); - goto end; - } - } else - in = BIO_new_fp(stdin, BIO_NOCLOSE); + in = bio_open_default(infile, inmode); + if (in == NULL) + goto end; if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) @@ -586,26 +528,15 @@ int MAIN(int argc, char **argv) } } - if (outfile) { - if (!(out = BIO_new_file(outfile, outmode))) { - BIO_printf(bio_err, "Can't open output file %s\n", outfile); - goto end; - } - } else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } + out = bio_open_default(outfile, outmode); + if (out == NULL) + goto end; if (operation == SMIME_VERIFY) { - if (!(store = setup_verify(bio_err, CAfile, CApath))) + if (!(store = setup_verify(CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, smime_cb); - if (vpm) + if (vpmtouched) X509_STORE_set1_param(store, vpm); } @@ -642,12 +573,11 @@ int MAIN(int argc, char **argv) for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); - signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, + signer = load_cert(signerfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; - key = load_key(bio_err, keyfile, keyform, 0, passin, e, - "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) @@ -701,22 +631,27 @@ int MAIN(int argc, char **argv) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) { if (operation == SMIME_RESIGN) - SMIME_write_PKCS7(out, p7, indata, flags); + rv = SMIME_write_PKCS7(out, p7, indata, flags); else - SMIME_write_PKCS7(out, p7, in, flags); + rv = SMIME_write_PKCS7(out, p7, in, flags); } else if (outformat == FORMAT_PEM) - PEM_write_bio_PKCS7_stream(out, p7, in, flags); + rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags); else if (outformat == FORMAT_ASN1) - i2d_PKCS7_bio_stream(out, p7, in, flags); + rv = i2d_PKCS7_bio_stream(out, p7, in, flags); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } + if (rv == 0) { + BIO_printf(bio_err, "Error writing output\n"); + ret = 3; + goto end; + } } ret = 0; end: if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); @@ -768,7 +703,7 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx) && ((error != X509_V_OK) || (ok != 2))) return ok; - policies_print(NULL, ctx); + policies_print(bio_err, ctx); return ok; diff --git a/apps/speed.c b/apps/speed.c index 71aa74a446..1a01d333b7 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -1,4 +1,3 @@ -/* apps/speed.c -*- mode:C; c-file-style: "eay" -*- */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -77,12 +76,8 @@ #define ECDSA_SECONDS 10 #define ECDH_SECONDS 10 -#undef PROG -#define PROG speed_main - #include #include - #include #include #include "apps.h" @@ -133,9 +128,9 @@ #ifndef OPENSSL_NO_MD5 # include #endif -# include +#include #include -# include +#include #ifndef OPENSSL_NO_RMD160 # include #endif @@ -220,6 +215,7 @@ static int do_multi(int multi); #define EC_NUM 16 #define MAX_ECDH_SIZE 256 +#define MISALIGN 64 static const char *names[ALGOR_NUM] = { "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4", @@ -232,7 +228,9 @@ static const char *names[ALGOR_NUM] = { }; static double results[ALGOR_NUM][SIZE_NUM]; -static int lengths[SIZE_NUM] = { 16, 64, 256, 1024, 8 * 1024 }; +static int lengths[SIZE_NUM] = { + 16, 64, 256, 1024, 8 * 1024 +}; #ifndef OPENSSL_NO_RSA static double rsa_results[RSA_NUM][2]; @@ -340,22 +338,253 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void *out, static void multiblock_speed(const EVP_CIPHER *evp_cipher); -int MAIN(int, char **); +static int found(const char *name, const OPT_PAIR * pairs, int *result) +{ + for (; pairs->name; pairs++) + if (strcmp(name, pairs->name) == 0) { + *result = pairs->retval; + return 1; + } + return 0; +} + +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, + OPT_MR, OPT_MB, OPT_MISALIGN +} OPTION_CHOICE; + +OPTIONS speed_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, +#if defined(TIMES) || defined(USE_TOD) + {"elapsed", OPT_ELAPSED, '-', + "Measure time in real time instead of CPU user time"}, +#endif + {"evp", OPT_EVP, 's', "Use specified EVP cipher"}, + {"decrypt", OPT_DECRYPT, '-', + "Time decryption instead of encryption (only EVP)"}, +#ifndef NO_FORK + {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"}, +#endif + {"mr", OPT_MR, '-', "Produce machine readable output"}, + {"mb", OPT_MB, '-'}, + {"misalign", OPT_MISALIGN, 'n', "Amount to mis-align buffers"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif +}; + +#define D_MD2 0 +#define D_MDC2 1 +#define D_MD4 2 +#define D_MD5 3 +#define D_HMAC 4 +#define D_SHA1 5 +#define D_RMD160 6 +#define D_RC4 7 +#define D_CBC_DES 8 +#define D_EDE3_DES 9 +#define D_CBC_IDEA 10 +#define D_CBC_SEED 11 +#define D_CBC_RC2 12 +#define D_CBC_RC5 13 +#define D_CBC_BF 14 +#define D_CBC_CAST 15 +#define D_CBC_128_AES 16 +#define D_CBC_192_AES 17 +#define D_CBC_256_AES 18 +#define D_CBC_128_CML 19 +#define D_CBC_192_CML 20 +#define D_CBC_256_CML 21 +#define D_EVP 22 +#define D_SHA256 23 +#define D_SHA512 24 +#define D_WHIRLPOOL 25 +#define D_IGE_128_AES 26 +#define D_IGE_192_AES 27 +#define D_IGE_256_AES 28 +#define D_GHASH 29 +OPT_PAIR doit_choices[] = { +#ifndef OPENSSL_NO_MD2 + {"md2", D_MD2}, +#endif +#ifndef OPENSSL_NO_MDC2 + {"mdc2", D_MDC2}, +#endif +#ifndef OPENSSL_NO_MD4 + {"md4", D_MD4}, +#endif +#ifndef OPENSSL_NO_MD5 + {"md5", D_MD5}, +#endif +#ifndef OPENSSL_NO_MD5 + {"hmac", D_HMAC}, +#endif + {"sha1", D_SHA1}, + {"sha256", D_SHA256}, + {"sha512", D_SHA512}, +#ifndef OPENSSL_NO_WHIRLPOOL + {"whirlpool", D_WHIRLPOOL}, +#endif +#ifndef OPENSSL_NO_RIPEMD + {"ripemd", D_RMD160}, + {"rmd160", D_RMD160}, + {"ripemd160", D_RMD160}, +#endif +#ifndef OPENSSL_NO_RC4 + {"rc4", D_RC4}, +#endif +#ifndef OPENSSL_NO_DES + {"des-cbc", D_CBC_DES}, + {"des-ede3", D_EDE3_DES}, +#endif +#ifndef OPENSSL_NO_AES + {"aes-128-cbc", D_CBC_128_AES}, + {"aes-192-cbc", D_CBC_192_AES}, + {"aes-256-cbc", D_CBC_256_AES}, + {"aes-128-ige", D_IGE_128_AES}, + {"aes-192-ige", D_IGE_192_AES}, + {"aes-256-ige", D_IGE_256_AES}, +#endif +#ifndef OPENSSL_NO_RC2 + {"rc2-cbc", D_CBC_RC2}, + {"rc2", D_CBC_RC2}, +#endif +#ifndef OPENSSL_NO_RC5 + {"rc5-cbc", D_CBC_RC5}, + {"rc5", D_CBC_RC5}, +#endif +#ifndef OPENSSL_NO_IDEA + {"idea-cbc", D_CBC_IDEA}, + {"idea", D_CBC_IDEA}, +#endif +#ifndef OPENSSL_NO_SEED + {"seed-cbc", D_CBC_SEED}, + {"seed", D_CBC_SEED}, +#endif +#ifndef OPENSSL_NO_BF + {"bf-cbc", D_CBC_BF}, + {"blowfish", D_CBC_BF}, + {"bf", D_CBC_BF}, +#endif +#ifndef OPENSSL_NO_CAST + {"cast-cbc", D_CBC_CAST}, + {"cast", D_CBC_CAST}, + {"cast5", D_CBC_CAST}, +#endif + {"ghash", D_GHASH}, + {NULL} +}; + +#define R_DSA_512 0 +#define R_DSA_1024 1 +#define R_DSA_2048 2 +static OPT_PAIR dsa_choices[] = { + {"dsa512", R_DSA_512}, + {"dsa1024", R_DSA_1024}, + {"dsa2048", R_DSA_2048}, + {NULL}, +}; -int MAIN(int argc, char **argv) +#define R_RSA_512 0 +#define R_RSA_1024 1 +#define R_RSA_2048 2 +#define R_RSA_3072 3 +#define R_RSA_4096 4 +#define R_RSA_7680 5 +#define R_RSA_15360 6 +static OPT_PAIR rsa_choices[] = { + {"rsa512", R_RSA_512}, + {"rsa1024", R_RSA_1024}, + {"rsa2048", R_RSA_2048}, + {"rsa3072", R_RSA_3072}, + {"rsa4096", R_RSA_4096}, + {"rsa7680", R_RSA_7680}, + {"rsa15360", R_RSA_15360}, + {NULL} +}; + +#define R_EC_P160 0 +#define R_EC_P192 1 +#define R_EC_P224 2 +#define R_EC_P256 3 +#define R_EC_P384 4 +#define R_EC_P521 5 +#define R_EC_K163 6 +#define R_EC_K233 7 +#define R_EC_K283 8 +#define R_EC_K409 9 +#define R_EC_K571 10 +#define R_EC_B163 11 +#define R_EC_B233 12 +#define R_EC_B283 13 +#define R_EC_B409 14 +#define R_EC_B571 15 +#ifndef OPENSSL_NO_ECA +static OPT_PAIR ecdsa_choices[] = { + {"ecdsap160", R_EC_P160}, + {"ecdsap192", R_EC_P192}, + {"ecdsap224", R_EC_P224}, + {"ecdsap256", R_EC_P256}, + {"ecdsap384", R_EC_P384}, + {"ecdsap521", R_EC_P521}, + {"ecdsak163", R_EC_K163}, + {"ecdsak233", R_EC_K233}, + {"ecdsak283", R_EC_K283}, + {"ecdsak409", R_EC_K409}, + {"ecdsak571", R_EC_K571}, + {"ecdsab163", R_EC_B163}, + {"ecdsab233", R_EC_B233}, + {"ecdsab283", R_EC_B283}, + {"ecdsab409", R_EC_B409}, + {"ecdsab571", R_EC_B571}, + {NULL} +}; +static OPT_PAIR ecdh_choices[] = { + {"ecdhp160", R_EC_P160}, + {"ecdhp192", R_EC_P192}, + {"ecdhp224", R_EC_P224}, + {"ecdhp256", R_EC_P256}, + {"ecdhp384", R_EC_P384}, + {"ecdhp521", R_EC_P521}, + {"ecdhk163", R_EC_K163}, + {"ecdhk233", R_EC_K233}, + {"ecdhk283", R_EC_K283}, + {"ecdhk409", R_EC_K409}, + {"ecdhk571", R_EC_K571}, + {"ecdhb163", R_EC_B163}, + {"ecdhb233", R_EC_B233}, + {"ecdhb283", R_EC_B283}, + {"ecdhb409", R_EC_B409}, + {"ecdhb571", R_EC_B571}, + {NULL} +}; +#endif + +int speed_main(int argc, char **argv) { + char *prog; + const EVP_CIPHER *evp_cipher = NULL; + const EVP_MD *evp_md = NULL; + double d = 0.0; + OPTION_CHOICE o; + int decrypt = 0, multiblock = 0, doit[ALGOR_NUM], pr_header = 0; + int dsa_doit[DSA_NUM], rsa_doit[RSA_NUM]; + int ret = 1, i, j, k, misalign = MAX_MISALIGNMENT + 1; + long c[ALGOR_NUM][SIZE_NUM], count = 0, save_count = 0; unsigned char *buf_malloc = NULL, *buf2_malloc = NULL; unsigned char *buf = NULL, *buf2 = NULL; - int mret = 1; - long count = 0, save_count = 0; - int i, j, k; + unsigned char *save_buf = NULL, *save_buf2 = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; +#ifndef NO_FORK + int multi = 0; +#endif + /* What follows are the buffers and key material. */ #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) long rsa_count; #endif -#ifndef OPENSSL_NO_RSA - unsigned rsa_num; -#endif - unsigned char md[EVP_MAX_MD_SIZE]; #ifndef OPENSSL_NO_MD2 unsigned char md2[MD2_DIGEST_LENGTH]; #endif @@ -375,7 +604,7 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_WHIRLPOOL unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH]; #endif -#ifndef OPENSSL_NO_RMD160 +#ifndef OPENSSL_NO_RIPEMD unsigned char rmd160[RIPEMD160_DIGEST_LENGTH]; #endif #ifndef OPENSSL_NO_RC4 @@ -428,6 +657,7 @@ int MAIN(int argc, char **argv) 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 }; + CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3; #endif #ifndef OPENSSL_NO_AES # define MAX_BLOCK_SIZE 128 @@ -437,12 +667,15 @@ int MAIN(int argc, char **argv) unsigned char DES_iv[8]; unsigned char iv[2 * MAX_BLOCK_SIZE / 8]; #ifndef OPENSSL_NO_DES - static DES_cblock key = - { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; - static DES_cblock key2 = - { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }; - static DES_cblock key3 = - { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 }; + static DES_cblock key = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 + }; + static DES_cblock key2 = { + 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 + }; + static DES_cblock key3 = { + 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 + }; DES_key_schedule sch; DES_key_schedule sch2; DES_key_schedule sch3; @@ -450,73 +683,8 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_AES AES_KEY aes_ks1, aes_ks2, aes_ks3; #endif -#ifndef OPENSSL_NO_CAMELLIA - CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3; -#endif -#define D_MD2 0 -#define D_MDC2 1 -#define D_MD4 2 -#define D_MD5 3 -#define D_HMAC 4 -#define D_SHA1 5 -#define D_RMD160 6 -#define D_RC4 7 -#define D_CBC_DES 8 -#define D_EDE3_DES 9 -#define D_CBC_IDEA 10 -#define D_CBC_SEED 11 -#define D_CBC_RC2 12 -#define D_CBC_RC5 13 -#define D_CBC_BF 14 -#define D_CBC_CAST 15 -#define D_CBC_128_AES 16 -#define D_CBC_192_AES 17 -#define D_CBC_256_AES 18 -#define D_CBC_128_CML 19 -#define D_CBC_192_CML 20 -#define D_CBC_256_CML 21 -#define D_EVP 22 -#define D_SHA256 23 -#define D_SHA512 24 -#define D_WHIRLPOOL 25 -#define D_IGE_128_AES 26 -#define D_IGE_192_AES 27 -#define D_IGE_256_AES 28 -#define D_GHASH 29 - double d = 0.0; - long c[ALGOR_NUM][SIZE_NUM]; - -#ifndef OPENSSL_SYS_WIN32 -#endif -#define R_DSA_512 0 -#define R_DSA_1024 1 -#define R_DSA_2048 2 -#define R_RSA_512 0 -#define R_RSA_1024 1 -#define R_RSA_2048 2 -#define R_RSA_3072 3 -#define R_RSA_4096 4 -#define R_RSA_7680 5 -#define R_RSA_15360 6 - -#define R_EC_P160 0 -#define R_EC_P192 1 -#define R_EC_P224 2 -#define R_EC_P256 3 -#define R_EC_P384 4 -#define R_EC_P521 5 -#define R_EC_K163 6 -#define R_EC_K233 7 -#define R_EC_K283 8 -#define R_EC_K409 9 -#define R_EC_K571 10 -#define R_EC_B163 11 -#define R_EC_B233 12 -#define R_EC_B283 13 -#define R_EC_B409 14 -#define R_EC_B571 15 - #ifndef OPENSSL_NO_RSA + unsigned rsa_num; RSA *rsa_key[RSA_NUM]; long rsa_c[RSA_NUM][2]; static unsigned int rsa_bits[RSA_NUM] = { @@ -545,85 +713,51 @@ int MAIN(int argc, char **argv) */ static unsigned int test_curves[EC_NUM] = { /* Prime Curves */ - NID_secp160r1, - NID_X9_62_prime192v1, - NID_secp224r1, - NID_X9_62_prime256v1, - NID_secp384r1, - NID_secp521r1, + NID_secp160r1, NID_X9_62_prime192v1, NID_secp224r1, + NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, /* Binary Curves */ - NID_sect163k1, - NID_sect233k1, - NID_sect283k1, - NID_sect409k1, - NID_sect571k1, - NID_sect163r2, - NID_sect233r1, - NID_sect283r1, - NID_sect409r1, + NID_sect163k1, NID_sect233k1, NID_sect283k1, + NID_sect409k1, NID_sect571k1, NID_sect163r2, + NID_sect233r1, NID_sect283r1, NID_sect409r1, NID_sect571r1 }; static const char *test_curves_names[EC_NUM] = { /* Prime Curves */ - "secp160r1", - "nistp192", - "nistp224", - "nistp256", - "nistp384", - "nistp521", + "secp160r1", "nistp192", "nistp224", + "nistp256", "nistp384", "nistp521", /* Binary Curves */ - "nistk163", - "nistk233", - "nistk283", - "nistk409", - "nistk571", - "nistb163", - "nistb233", - "nistb283", - "nistb409", + "nistk163", "nistk233", "nistk283", + "nistk409", "nistk571", "nistb163", + "nistb233", "nistb283", "nistb409", "nistb571" }; static int test_curves_bits[EC_NUM] = { - 160, 192, 224, 256, 384, 521, - 163, 233, 283, 409, 571, - 163, 233, 283, 409, 571 + 160, 192, 224, + 256, 384, 521, + 163, 233, 283, + 409, 571, 163, + 233, 283, 409, + 571 }; - #endif - #ifndef OPENSSL_NO_EC unsigned char ecdsasig[256]; unsigned int ecdsasiglen; EC_KEY *ecdsa[EC_NUM]; long ecdsa_c[EC_NUM][2]; + int ecdsa_doit[EC_NUM]; EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM]; unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE]; int secret_size_a, secret_size_b; int ecdh_checks = 0; int secret_idx = 0; long ecdh_c[EC_NUM][2]; - int ecdsa_doit[EC_NUM]; int ecdh_doit[EC_NUM]; #endif - - int rsa_doit[RSA_NUM]; - int dsa_doit[DSA_NUM]; - int doit[ALGOR_NUM]; - int pr_header = 0; - const EVP_CIPHER *evp_cipher = NULL; - const EVP_MD *evp_md = NULL; - int decrypt = 0; -#ifndef NO_FORK - int multi = 0; -#endif - int multiblock = 0; - int misalign = MAX_MISALIGNMENT + 1; - #ifndef TIMES usertime = -1; #endif - apps_startup(); memset(results, 0, sizeof(results)); #ifndef OPENSSL_NO_DSA memset(dsa_key, 0, sizeof(dsa_key)); @@ -631,41 +765,15 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_EC for (i = 0; i < EC_NUM; i++) ecdsa[i] = NULL; - for (i = 0; i < EC_NUM; i++) { - ecdh_a[i] = NULL; - ecdh_b[i] = NULL; - } + for (i = 0; i < EC_NUM; i++) + ecdh_a[i] = ecdh_b[i] = NULL; #endif - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; - #ifndef OPENSSL_NO_RSA memset(rsa_key, 0, sizeof(rsa_key)); for (i = 0; i < RSA_NUM; i++) rsa_key[i] = NULL; #endif - if ((buf_malloc = - (unsigned char *)OPENSSL_malloc(BUFSIZE + misalign)) == NULL) { - BIO_printf(bio_err, "out of memory\n"); - goto end; - } - if ((buf2_malloc = - (unsigned char *)OPENSSL_malloc(BUFSIZE + misalign)) == NULL) { - BIO_printf(bio_err, "out of memory\n"); - goto end; - } - - misalign = 0; /* set later and buf/buf2 are adjusted - * accordingly */ - buf = buf_malloc; - buf2 = buf2_malloc; - memset(c, 0, sizeof(c)); memset(DES_iv, 0, sizeof(DES_iv)); memset(iv, 0, sizeof(iv)); @@ -683,521 +791,164 @@ int MAIN(int argc, char **argv) ecdh_doit[i] = 0; #endif - j = 0; - argc--; - argv++; - while (argc) { - if ((argc > 0) && (strcmp(*argv, "-elapsed") == 0)) { + if ((buf_malloc = + (unsigned char *)OPENSSL_malloc((int)BUFSIZE + misalign)) == NULL) { + BIO_printf(bio_err, "out of memory\n"); + goto end; + } + if ((buf2_malloc = + (unsigned char *)OPENSSL_malloc((int)BUFSIZE + misalign)) == NULL) { + BIO_printf(bio_err, "out of memory\n"); + goto end; + } + misalign = 0; + buf = buf_malloc; + buf2 = buf2_malloc; + + prog = opt_init(argc, argv, speed_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opterr: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(speed_options); + ret = 0; + goto end; + case OPT_ELAPSED: usertime = 0; - j--; /* Otherwise, -elapsed gets confused with an - * algorithm. */ - } else if ((argc > 0) && (strcmp(*argv, "-evp") == 0)) { - argc--; - argv++; - if (argc == 0) { - BIO_printf(bio_err, "no EVP given\n"); - goto end; - } - evp_cipher = EVP_get_cipherbyname(*argv); - if (!evp_cipher) { - evp_md = EVP_get_digestbyname(*argv); - } - if (!evp_cipher && !evp_md) { - BIO_printf(bio_err, "%s is an unknown cipher or digest\n", - *argv); + break; + case OPT_EVP: + evp_cipher = EVP_get_cipherbyname(opt_arg()); + if (evp_cipher == NULL) + evp_md = EVP_get_digestbyname(opt_arg()); + if (evp_cipher == NULL && evp_md == NULL) { + BIO_printf(bio_err, + "%s: %s an unknown cipher or digest\n", + prog, opt_arg()); goto end; } doit[D_EVP] = 1; - } else if (argc > 0 && !strcmp(*argv, "-decrypt")) { + break; + case OPT_DECRYPT: decrypt = 1; - j--; /* Otherwise, -elapsed gets confused with an - * algorithm. */ - } + break; #ifndef OPENSSL_NO_ENGINE - else if ((argc > 0) && (strcmp(*argv, "-engine") == 0)) { - argc--; - argv++; - if (argc == 0) { - BIO_printf(bio_err, "no engine given\n"); - goto end; - } - setup_engine(bio_err, *argv, 0); - /* - * j will be increased again further down. We just don't want - * speed to confuse an engine with an algorithm, especially when - * none is given (which means all of them should be run) - */ - j--; - } + case OPT_ENGINE: + setup_engine(opt_arg(), 0); + break; #endif #ifndef NO_FORK - else if ((argc > 0) && (strcmp(*argv, "-multi") == 0)) { - argc--; - argv++; - if (argc == 0) { - BIO_printf(bio_err, "no multi count given\n"); - goto end; - } - multi = atoi(argv[0]); - if (multi <= 0) { - BIO_printf(bio_err, "bad multi count\n"); - goto end; - } - j--; /* Otherwise, -mr gets confused with an - * algorithm. */ - } + case OPT_MULTI: + multi = atoi(opt_arg()); + break; #endif - else if (argc > 0 && !strcmp(*argv, "-mr")) { - mr = 1; - j--; /* Otherwise, -mr gets confused with an - * algorithm. */ - } else if (argc > 0 && !strcmp(*argv, "-mb")) { - multiblock = 1; - j--; - } else if (argc > 0 && !strcmp(*argv, "-misalign")) { - argc--; - argv++; - if (argc == 0) { - BIO_printf(bio_err, "no misalignment given\n"); + case OPT_MISALIGN: + if (!opt_int(opt_arg(), &misalign)) goto end; - } - misalign = atoi(argv[0]); - if (misalign < 0 || misalign > MAX_MISALIGNMENT) { + if (misalign > MISALIGN) { BIO_printf(bio_err, - "misalignment is outsize permitted range 0-%d\n", - MAX_MISALIGNMENT); - goto end; + "%s: Maximum offset is %d\n", prog, MISALIGN); + goto opterr; } buf = buf_malloc + misalign; buf2 = buf2_malloc + misalign; - j--; - } else -#ifndef OPENSSL_NO_MD2 - if (strcmp(*argv, "md2") == 0) - doit[D_MD2] = 1; - else -#endif -#ifndef OPENSSL_NO_MDC2 - if (strcmp(*argv, "mdc2") == 0) - doit[D_MDC2] = 1; - else -#endif -#ifndef OPENSSL_NO_MD4 - if (strcmp(*argv, "md4") == 0) - doit[D_MD4] = 1; - else -#endif -#ifndef OPENSSL_NO_MD5 - if (strcmp(*argv, "md5") == 0) - doit[D_MD5] = 1; - else -#endif -#ifndef OPENSSL_NO_MD5 - if (strcmp(*argv, "hmac") == 0) - doit[D_HMAC] = 1; - else -#endif - if (strcmp(*argv, "sha1") == 0) - doit[D_SHA1] = 1; - else if (strcmp(*argv, "sha") == 0) - doit[D_SHA1] = 1, doit[D_SHA256] = 1, doit[D_SHA512] = 1; - else if (strcmp(*argv, "sha256") == 0) - doit[D_SHA256] = 1; - else if (strcmp(*argv, "sha512") == 0) - doit[D_SHA512] = 1; - else -#ifndef OPENSSL_NO_WHIRLPOOL - if (strcmp(*argv, "whirlpool") == 0) - doit[D_WHIRLPOOL] = 1; - else -#endif -#ifndef OPENSSL_NO_RMD160 - if (strcmp(*argv, "ripemd") == 0) - doit[D_RMD160] = 1; - else if (strcmp(*argv, "rmd160") == 0) - doit[D_RMD160] = 1; - else if (strcmp(*argv, "ripemd160") == 0) - doit[D_RMD160] = 1; - else -#endif -#ifndef OPENSSL_NO_RC4 - if (strcmp(*argv, "rc4") == 0) - doit[D_RC4] = 1; - else -#endif + break; + case OPT_MR: + mr = 1; + break; + case OPT_MB: + multiblock = 1; + break; + } + } + argc = opt_num_rest(); + argv = opt_rest(); + + /* Remaining arguments are algorithms. */ + for ( ; *argv; argv++) { + if (found(*argv, doit_choices, &i)) { + doit[i] = 1; + continue; + } #ifndef OPENSSL_NO_DES - if (strcmp(*argv, "des-cbc") == 0) - doit[D_CBC_DES] = 1; - else if (strcmp(*argv, "des-ede3") == 0) - doit[D_EDE3_DES] = 1; - else -#endif -#ifndef OPENSSL_NO_AES - if (strcmp(*argv, "aes-128-cbc") == 0) - doit[D_CBC_128_AES] = 1; - else if (strcmp(*argv, "aes-192-cbc") == 0) - doit[D_CBC_192_AES] = 1; - else if (strcmp(*argv, "aes-256-cbc") == 0) - doit[D_CBC_256_AES] = 1; - else if (strcmp(*argv, "aes-128-ige") == 0) - doit[D_IGE_128_AES] = 1; - else if (strcmp(*argv, "aes-192-ige") == 0) - doit[D_IGE_192_AES] = 1; - else if (strcmp(*argv, "aes-256-ige") == 0) - doit[D_IGE_256_AES] = 1; - else -#endif -#ifndef OPENSSL_NO_CAMELLIA - if (strcmp(*argv, "camellia-128-cbc") == 0) - doit[D_CBC_128_CML] = 1; - else if (strcmp(*argv, "camellia-192-cbc") == 0) - doit[D_CBC_192_CML] = 1; - else if (strcmp(*argv, "camellia-256-cbc") == 0) - doit[D_CBC_256_CML] = 1; - else + if (strcmp(*argv, "des") == 0) { + doit[D_CBC_DES] = doit[D_EDE3_DES] = 1; + continue; + } #endif + if (strcmp(*argv, "sha") == 0) { + doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1; + continue; + } #ifndef OPENSSL_NO_RSA # ifndef RSA_NULL if (strcmp(*argv, "openssl") == 0) { RSA_set_default_method(RSA_PKCS1_SSLeay()); - j--; - } else + continue; + } # endif -#endif /* !OPENSSL_NO_RSA */ - if (strcmp(*argv, "dsa512") == 0) - dsa_doit[R_DSA_512] = 2; - else if (strcmp(*argv, "dsa1024") == 0) - dsa_doit[R_DSA_1024] = 2; - else if (strcmp(*argv, "dsa2048") == 0) - dsa_doit[R_DSA_2048] = 2; - else if (strcmp(*argv, "rsa512") == 0) - rsa_doit[R_RSA_512] = 2; - else if (strcmp(*argv, "rsa1024") == 0) - rsa_doit[R_RSA_1024] = 2; - else if (strcmp(*argv, "rsa2048") == 0) - rsa_doit[R_RSA_2048] = 2; - else if (strcmp(*argv, "rsa3072") == 0) - rsa_doit[R_RSA_3072] = 2; - else if (strcmp(*argv, "rsa4096") == 0) - rsa_doit[R_RSA_4096] = 2; - else if (strcmp(*argv, "rsa7680") == 0) - rsa_doit[R_RSA_7680] = 2; - else if (strcmp(*argv, "rsa15360") == 0) - rsa_doit[R_RSA_15360] = 2; - else -#ifndef OPENSSL_NO_RC2 - if (strcmp(*argv, "rc2-cbc") == 0) - doit[D_CBC_RC2] = 1; - else if (strcmp(*argv, "rc2") == 0) - doit[D_CBC_RC2] = 1; - else -#endif -#ifndef OPENSSL_NO_RC5 - if (strcmp(*argv, "rc5-cbc") == 0) - doit[D_CBC_RC5] = 1; - else if (strcmp(*argv, "rc5") == 0) - doit[D_CBC_RC5] = 1; - else -#endif -#ifndef OPENSSL_NO_IDEA - if (strcmp(*argv, "idea-cbc") == 0) - doit[D_CBC_IDEA] = 1; - else if (strcmp(*argv, "idea") == 0) - doit[D_CBC_IDEA] = 1; - else -#endif -#ifndef OPENSSL_NO_SEED - if (strcmp(*argv, "seed-cbc") == 0) - doit[D_CBC_SEED] = 1; - else if (strcmp(*argv, "seed") == 0) - doit[D_CBC_SEED] = 1; - else -#endif -#ifndef OPENSSL_NO_BF - if (strcmp(*argv, "bf-cbc") == 0) - doit[D_CBC_BF] = 1; - else if (strcmp(*argv, "blowfish") == 0) - doit[D_CBC_BF] = 1; - else if (strcmp(*argv, "bf") == 0) - doit[D_CBC_BF] = 1; - else -#endif -#ifndef OPENSSL_NO_CAST - if (strcmp(*argv, "cast-cbc") == 0) - doit[D_CBC_CAST] = 1; - else if (strcmp(*argv, "cast") == 0) - doit[D_CBC_CAST] = 1; - else if (strcmp(*argv, "cast5") == 0) - doit[D_CBC_CAST] = 1; - else + if (strcmp(*argv, "rsa") == 0) { + rsa_doit[R_RSA_512] = rsa_doit[R_RSA_1024] = + rsa_doit[R_RSA_2048] = rsa_doit[R_RSA_3072] = + rsa_doit[R_RSA_4096] = rsa_doit[R_RSA_7680] = + rsa_doit[R_RSA_15360] = 1; + continue; + } + if (found(*argv, rsa_choices, &i)) { + rsa_doit[i] = 1; + continue; + } #endif -#ifndef OPENSSL_NO_DES - if (strcmp(*argv, "des") == 0) { - doit[D_CBC_DES] = 1; - doit[D_EDE3_DES] = 1; - } else +#ifndef OPENSSL_NO_DSA + if (strcmp(*argv, "dsa") == 0) { + dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] = + dsa_doit[R_DSA_2048] = 1; + continue; + } + if (found(*argv, dsa_choices, &i)) { + dsa_doit[i] = 2; + continue; + } #endif #ifndef OPENSSL_NO_AES if (strcmp(*argv, "aes") == 0) { - doit[D_CBC_128_AES] = 1; - doit[D_CBC_192_AES] = 1; - doit[D_CBC_256_AES] = 1; - } else if (strcmp(*argv, "ghash") == 0) { - doit[D_GHASH] = 1; - } else + doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = + doit[D_CBC_256_AES] = 1; + continue; + } #endif #ifndef OPENSSL_NO_CAMELLIA if (strcmp(*argv, "camellia") == 0) { - doit[D_CBC_128_CML] = 1; - doit[D_CBC_192_CML] = 1; - doit[D_CBC_256_CML] = 1; - } else -#endif -#ifndef OPENSSL_NO_RSA - if (strcmp(*argv, "rsa") == 0) { - rsa_doit[R_RSA_512] = 1; - rsa_doit[R_RSA_1024] = 1; - rsa_doit[R_RSA_2048] = 1; - rsa_doit[R_RSA_3072] = 1; - rsa_doit[R_RSA_4096] = 1; - rsa_doit[R_RSA_7680] = 1; - rsa_doit[R_RSA_15360] = 1; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (strcmp(*argv, "dsa") == 0) { - dsa_doit[R_DSA_512] = 1; - dsa_doit[R_DSA_1024] = 1; - dsa_doit[R_DSA_2048] = 1; - } else + doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = + doit[D_CBC_256_CML] = 1; + continue; + } #endif #ifndef OPENSSL_NO_EC - if (strcmp(*argv, "ecdsap160") == 0) - ecdsa_doit[R_EC_P160] = 2; - else if (strcmp(*argv, "ecdsap192") == 0) - ecdsa_doit[R_EC_P192] = 2; - else if (strcmp(*argv, "ecdsap224") == 0) - ecdsa_doit[R_EC_P224] = 2; - else if (strcmp(*argv, "ecdsap256") == 0) - ecdsa_doit[R_EC_P256] = 2; - else if (strcmp(*argv, "ecdsap384") == 0) - ecdsa_doit[R_EC_P384] = 2; - else if (strcmp(*argv, "ecdsap521") == 0) - ecdsa_doit[R_EC_P521] = 2; - else if (strcmp(*argv, "ecdsak163") == 0) - ecdsa_doit[R_EC_K163] = 2; - else if (strcmp(*argv, "ecdsak233") == 0) - ecdsa_doit[R_EC_K233] = 2; - else if (strcmp(*argv, "ecdsak283") == 0) - ecdsa_doit[R_EC_K283] = 2; - else if (strcmp(*argv, "ecdsak409") == 0) - ecdsa_doit[R_EC_K409] = 2; - else if (strcmp(*argv, "ecdsak571") == 0) - ecdsa_doit[R_EC_K571] = 2; - else if (strcmp(*argv, "ecdsab163") == 0) - ecdsa_doit[R_EC_B163] = 2; - else if (strcmp(*argv, "ecdsab233") == 0) - ecdsa_doit[R_EC_B233] = 2; - else if (strcmp(*argv, "ecdsab283") == 0) - ecdsa_doit[R_EC_B283] = 2; - else if (strcmp(*argv, "ecdsab409") == 0) - ecdsa_doit[R_EC_B409] = 2; - else if (strcmp(*argv, "ecdsab571") == 0) - ecdsa_doit[R_EC_B571] = 2; - else if (strcmp(*argv, "ecdsa") == 0) { + if (strcmp(*argv, "ecdsa") == 0) { for (i = 0; i < EC_NUM; i++) ecdsa_doit[i] = 1; - } else if (strcmp(*argv, "ecdhp160") == 0) - ecdh_doit[R_EC_P160] = 2; - else if (strcmp(*argv, "ecdhp192") == 0) - ecdh_doit[R_EC_P192] = 2; - else if (strcmp(*argv, "ecdhp224") == 0) - ecdh_doit[R_EC_P224] = 2; - else if (strcmp(*argv, "ecdhp256") == 0) - ecdh_doit[R_EC_P256] = 2; - else if (strcmp(*argv, "ecdhp384") == 0) - ecdh_doit[R_EC_P384] = 2; - else if (strcmp(*argv, "ecdhp521") == 0) - ecdh_doit[R_EC_P521] = 2; - else if (strcmp(*argv, "ecdhk163") == 0) - ecdh_doit[R_EC_K163] = 2; - else if (strcmp(*argv, "ecdhk233") == 0) - ecdh_doit[R_EC_K233] = 2; - else if (strcmp(*argv, "ecdhk283") == 0) - ecdh_doit[R_EC_K283] = 2; - else if (strcmp(*argv, "ecdhk409") == 0) - ecdh_doit[R_EC_K409] = 2; - else if (strcmp(*argv, "ecdhk571") == 0) - ecdh_doit[R_EC_K571] = 2; - else if (strcmp(*argv, "ecdhb163") == 0) - ecdh_doit[R_EC_B163] = 2; - else if (strcmp(*argv, "ecdhb233") == 0) - ecdh_doit[R_EC_B233] = 2; - else if (strcmp(*argv, "ecdhb283") == 0) - ecdh_doit[R_EC_B283] = 2; - else if (strcmp(*argv, "ecdhb409") == 0) - ecdh_doit[R_EC_B409] = 2; - else if (strcmp(*argv, "ecdhb571") == 0) - ecdh_doit[R_EC_B571] = 2; - else if (strcmp(*argv, "ecdh") == 0) { + continue; + } + if (found(*argv, ecdsa_choices, &i)) { + ecdsa_doit[i] = 2; + continue; + } + if (strcmp(*argv, "ecdh") == 0) { for (i = 0; i < EC_NUM; i++) ecdh_doit[i] = 1; - } else -#endif - { - BIO_printf(bio_err, "Error: bad option or value\n"); - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, "Available values:\n"); -#ifndef OPENSSL_NO_MD2 - BIO_printf(bio_err, "md2 "); -#endif -#ifndef OPENSSL_NO_MDC2 - BIO_printf(bio_err, "mdc2 "); -#endif -#ifndef OPENSSL_NO_MD4 - BIO_printf(bio_err, "md4 "); -#endif -#ifndef OPENSSL_NO_MD5 - BIO_printf(bio_err, "md5 "); - BIO_printf(bio_err, "hmac "); -#endif - BIO_printf(bio_err, "sha1 "); - BIO_printf(bio_err, "sha256 "); - BIO_printf(bio_err, "sha512 "); -#ifndef OPENSSL_NO_WHIRLPOOL - BIO_printf(bio_err, "whirlpool"); -#endif -#ifndef OPENSSL_NO_RMD160 - BIO_printf(bio_err, "rmd160"); -#endif - BIO_printf(bio_err, "\n"); - -#ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, "idea-cbc "); -#endif -#ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, "seed-cbc "); -#endif -#ifndef OPENSSL_NO_RC2 - BIO_printf(bio_err, "rc2-cbc "); -#endif -#ifndef OPENSSL_NO_RC5 - BIO_printf(bio_err, "rc5-cbc "); -#endif -#ifndef OPENSSL_NO_BF - BIO_printf(bio_err, "bf-cbc"); -#endif -#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \ - !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5) - BIO_printf(bio_err, "\n"); -#endif -#ifndef OPENSSL_NO_DES - BIO_printf(bio_err, "des-cbc des-ede3 "); -#endif -#ifndef OPENSSL_NO_AES - BIO_printf(bio_err, "aes-128-cbc aes-192-cbc aes-256-cbc "); - BIO_printf(bio_err, "aes-128-ige aes-192-ige aes-256-ige "); -#endif -#ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, - "camellia-128-cbc camellia-192-cbc camellia-256-cbc "); -#endif -#ifndef OPENSSL_NO_RC4 - BIO_printf(bio_err, "rc4"); -#endif - BIO_printf(bio_err, "\n"); - -#ifndef OPENSSL_NO_RSA - BIO_printf(bio_err, - "rsa512 rsa1024 rsa2048 rsa3072 rsa4096\n"); - BIO_printf(bio_err, "rsa7680 rsa15360\n"); -#endif - -#ifndef OPENSSL_NO_DSA - BIO_printf(bio_err, "dsa512 dsa1024 dsa2048\n"); -#endif -#ifndef OPENSSL_NO_EC - BIO_printf(bio_err, "ecdsap160 ecdsap192 ecdsap224 " - "ecdsap256 ecdsap384 ecdsap521\n"); - BIO_printf(bio_err, - "ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n"); - BIO_printf(bio_err, - "ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n"); - BIO_printf(bio_err, "ecdsa\n"); - BIO_printf(bio_err, "ecdhp160 ecdhp192 ecdhp224 " - "ecdhp256 ecdhp384 ecdhp521\n"); - BIO_printf(bio_err, - "ecdhk163 ecdhk233 ecdhk283 ecdhk409 ecdhk571\n"); - BIO_printf(bio_err, - "ecdhb163 ecdhb233 ecdhb283 ecdhb409 ecdhb571\n"); - BIO_printf(bio_err, "ecdh\n"); -#endif - -#ifndef OPENSSL_NO_IDEA - BIO_printf(bio_err, "idea "); -#endif -#ifndef OPENSSL_NO_SEED - BIO_printf(bio_err, "seed "); -#endif -#ifndef OPENSSL_NO_RC2 - BIO_printf(bio_err, "rc2 "); -#endif -#ifndef OPENSSL_NO_DES - BIO_printf(bio_err, "des "); -#endif -#ifndef OPENSSL_NO_AES - BIO_printf(bio_err, "aes "); -#endif -#ifndef OPENSSL_NO_CAMELLIA - BIO_printf(bio_err, "camellia "); -#endif -#ifndef OPENSSL_NO_RSA - BIO_printf(bio_err, "rsa "); -#endif -#ifndef OPENSSL_NO_BF - BIO_printf(bio_err, "blowfish"); -#endif -#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \ - !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \ - !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \ - !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA) - BIO_printf(bio_err, "\n"); -#endif - - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, "Available options:\n"); -#if defined(TIMES) || defined(USE_TOD) - BIO_printf(bio_err, "-elapsed " - "measure time in real time instead of CPU user time.\n"); -#endif -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - "-engine e " - "use engine e, possibly a hardware device.\n"); -#endif - BIO_printf(bio_err, "-evp e " "use EVP e.\n"); - BIO_printf(bio_err, - "-decrypt " - "time decryption instead of encryption (only EVP).\n"); - BIO_printf(bio_err, - "-mr " - "produce machine readable output.\n"); - BIO_printf(bio_err, - "-mb " - "perform multi-block benchmark (for specific ciphers)\n"); - BIO_printf(bio_err, - "-misalign n " - "perform benchmark with misaligned data\n"); -#ifndef NO_FORK - BIO_printf(bio_err, - "-multi n " "run n benchmarks in parallel.\n"); -#endif - goto end; + continue; } - argc--; - argv++; - j++; + if (found(*argv, ecdh_choices, &i)) { + ecdh_doit[i] = 2; + continue; + } +#endif + BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv); + goto end; } #ifndef NO_FORK @@ -1205,11 +956,11 @@ int MAIN(int argc, char **argv) goto show_res; #endif - if (j == 0) { - for (i = 0; i < ALGOR_NUM; i++) { + /* No parameters; turn on everything. */ + if (argc == 0) { + for (i = 0; i < ALGOR_NUM; i++) if (i != D_EVP) doit[i] = 1; - } for (i = 0; i < RSA_NUM; i++) rsa_doit[i] = 1; for (i = 0; i < DSA_NUM; i++) @@ -1449,6 +1200,7 @@ int MAIN(int argc, char **argv) } } } + ecdh_c[R_EC_P160][0] = count / 1000; ecdh_c[R_EC_P160][1] = count / 1000; for (i = R_EC_P192; i <= R_EC_P521; i++) { @@ -1910,7 +1662,7 @@ int MAIN(int argc, char **argv) goto end; } multiblock_speed(evp_cipher); - mret = 0; + ret = 0; goto end; } #endif @@ -1965,16 +1717,15 @@ int MAIN(int argc, char **argv) print_result(D_EVP, j, count, d); } } -#ifndef OPENSSL_SYS_WIN32 -#endif + RAND_bytes(buf, 36); #ifndef OPENSSL_NO_RSA for (j = 0; j < RSA_NUM; j++) { - int ret; + int st; if (!rsa_doit[j]) continue; - ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, &rsa_num, rsa_key[j]); - if (ret == 0) { + st = RSA_sign(NID_md5_sha1, buf, 36, buf2, &rsa_num, rsa_key[j]); + if (st == 0) { BIO_printf(bio_err, "RSA sign failure. No RSA sign will be done.\n"); ERR_print_errors(bio_err); @@ -1985,9 +1736,9 @@ int MAIN(int argc, char **argv) /* RSA_blinding_on(rsa_key[j],NULL); */ Time_F(START); for (count = 0, run = 1; COND(rsa_c[j][0]); count++) { - ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, - &rsa_num, rsa_key[j]); - if (ret == 0) { + st = RSA_sign(NID_md5_sha1, buf, 36, buf2, + &rsa_num, rsa_key[j]); + if (st == 0) { BIO_printf(bio_err, "RSA sign failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2003,8 +1754,8 @@ int MAIN(int argc, char **argv) rsa_count = count; } - ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[j]); - if (ret <= 0) { + st = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[j]); + if (st <= 0) { BIO_printf(bio_err, "RSA verify failure. No RSA verify will be done.\n"); ERR_print_errors(bio_err); @@ -2014,9 +1765,9 @@ int MAIN(int argc, char **argv) rsa_c[j][1], rsa_bits[j], RSA_SECONDS); Time_F(START); for (count = 0, run = 1; COND(rsa_c[j][1]); count++) { - ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, - rsa_num, rsa_key[j]); - if (ret <= 0) { + st = RSA_verify(NID_md5_sha1, buf, 36, buf2, + rsa_num, rsa_key[j]); + if (st <= 0) { BIO_printf(bio_err, "RSA verify failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2047,15 +1798,15 @@ int MAIN(int argc, char **argv) } for (j = 0; j < DSA_NUM; j++) { unsigned int kk; - int ret; + int st; if (!dsa_doit[j]) continue; /* DSA_generate_key(dsa_key[j]); */ /* DSA_sign_setup(dsa_key[j],NULL); */ - ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2, &kk, dsa_key[j]); - if (ret == 0) { + st = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2, &kk, dsa_key[j]); + if (st == 0) { BIO_printf(bio_err, "DSA sign failure. No DSA sign will be done.\n"); ERR_print_errors(bio_err); @@ -2065,8 +1816,8 @@ int MAIN(int argc, char **argv) dsa_c[j][0], dsa_bits[j], DSA_SECONDS); Time_F(START); for (count = 0, run = 1; COND(dsa_c[j][0]); count++) { - ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2, &kk, dsa_key[j]); - if (ret == 0) { + st = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2, &kk, dsa_key[j]); + if (st == 0) { BIO_printf(bio_err, "DSA sign failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2082,8 +1833,8 @@ int MAIN(int argc, char **argv) rsa_count = count; } - ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2, kk, dsa_key[j]); - if (ret <= 0) { + st = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2, kk, dsa_key[j]); + if (st <= 0) { BIO_printf(bio_err, "DSA verify failure. No DSA verify will be done.\n"); ERR_print_errors(bio_err); @@ -2093,8 +1844,8 @@ int MAIN(int argc, char **argv) dsa_c[j][1], dsa_bits[j], DSA_SECONDS); Time_F(START); for (count = 0, run = 1; COND(dsa_c[j][1]); count++) { - ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2, kk, dsa_key[j]); - if (ret <= 0) { + st = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2, kk, dsa_key[j]); + if (st <= 0) { BIO_printf(bio_err, "DSA verify failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2125,7 +1876,7 @@ int MAIN(int argc, char **argv) rnd_fake = 1; } for (j = 0; j < EC_NUM; j++) { - int ret; + int st; if (!ecdsa_doit[j]) continue; /* Ignore Curve */ @@ -2136,11 +1887,10 @@ int MAIN(int argc, char **argv) rsa_count = 1; } else { EC_KEY_precompute_mult(ecdsa[j], NULL); - /* Perform ECDSA signature test */ EC_KEY_generate_key(ecdsa[j]); - ret = ECDSA_sign(0, buf, 20, ecdsasig, &ecdsasiglen, ecdsa[j]); - if (ret == 0) { + st = ECDSA_sign(0, buf, 20, ecdsasig, &ecdsasiglen, ecdsa[j]); + if (st == 0) { BIO_printf(bio_err, "ECDSA sign failure. No ECDSA sign will be done.\n"); ERR_print_errors(bio_err); @@ -2152,9 +1902,9 @@ int MAIN(int argc, char **argv) Time_F(START); for (count = 0, run = 1; COND(ecdsa_c[j][0]); count++) { - ret = ECDSA_sign(0, buf, 20, - ecdsasig, &ecdsasiglen, ecdsa[j]); - if (ret == 0) { + st = ECDSA_sign(0, buf, 20, + ecdsasig, &ecdsasiglen, ecdsa[j]); + if (st == 0) { BIO_printf(bio_err, "ECDSA sign failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2172,8 +1922,8 @@ int MAIN(int argc, char **argv) } /* Perform ECDSA verification test */ - ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]); - if (ret != 1) { + st = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]); + if (st != 1) { BIO_printf(bio_err, "ECDSA verify failure. No ECDSA verify will be done.\n"); ERR_print_errors(bio_err); @@ -2184,10 +1934,9 @@ int MAIN(int argc, char **argv) test_curves_bits[j], ECDSA_SECONDS); Time_F(START); for (count = 0, run = 1; COND(ecdsa_c[j][1]); count++) { - ret = - ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, - ecdsa[j]); - if (ret != 1) { + st = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, + ecdsa[j]); + if (st != 1) { BIO_printf(bio_err, "ECDSA verify failure\n"); ERR_print_errors(bio_err); count = 1; @@ -2211,6 +1960,9 @@ int MAIN(int argc, char **argv) } if (rnd_fake) RAND_cleanup(); +#endif + +#ifndef OPENSSL_NO_EC if (RAND_status() != 1) { RAND_seed(rnd_seed, sizeof rnd_seed); rnd_fake = 1; @@ -2306,8 +2058,8 @@ int MAIN(int argc, char **argv) show_res: #endif if (!mr) { - fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_VERSION)); - fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_BUILT_ON)); + printf("%s\n", SSLeay_version(SSLEAY_VERSION)); + printf("%s\n", SSLeay_version(SSLEAY_BUILT_ON)); printf("options:"); printf("%s ", BN_options()); #ifndef OPENSSL_NO_MD2 @@ -2328,36 +2080,36 @@ int MAIN(int argc, char **argv) #ifndef OPENSSL_NO_BF printf("%s ", BF_options()); #endif - fprintf(stdout, "\n%s\n", SSLeay_version(SSLEAY_CFLAGS)); + printf("\n%s\n", SSLeay_version(SSLEAY_CFLAGS)); } if (pr_header) { if (mr) - fprintf(stdout, "+H"); + printf("+H"); else { - fprintf(stdout, - "The 'numbers' are in 1000s of bytes per second processed.\n"); - fprintf(stdout, "type "); + printf + ("The 'numbers' are in 1000s of bytes per second processed.\n"); + printf("type "); } for (j = 0; j < SIZE_NUM; j++) - fprintf(stdout, mr ? ":%d" : "%7d bytes", lengths[j]); - fprintf(stdout, "\n"); + printf(mr ? ":%d" : "%7d bytes", lengths[j]); + printf("\n"); } for (k = 0; k < ALGOR_NUM; k++) { if (!doit[k]) continue; if (mr) - fprintf(stdout, "+F:%d:%s", k, names[k]); + printf("+F:%d:%s", k, names[k]); else - fprintf(stdout, "%-13s", names[k]); + printf("%-13s", names[k]); for (j = 0; j < SIZE_NUM; j++) { if (results[k][j] > 10000 && !mr) - fprintf(stdout, " %11.2fk", results[k][j] / 1e3); + printf(" %11.2fk", results[k][j] / 1e3); else - fprintf(stdout, mr ? ":%.2f" : " %11.2f ", results[k][j]); + printf(mr ? ":%.2f" : " %11.2f ", results[k][j]); } - fprintf(stdout, "\n"); + printf("\n"); } #ifndef OPENSSL_NO_RSA j = 1; @@ -2369,12 +2121,12 @@ int MAIN(int argc, char **argv) j = 0; } if (mr) - fprintf(stdout, "+F2:%u:%u:%f:%f\n", - k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]); + printf("+F2:%u:%u:%f:%f\n", + k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]); else - fprintf(stdout, "rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", - rsa_bits[k], rsa_results[k][0], rsa_results[k][1], - 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]); + printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", + rsa_bits[k], rsa_results[k][0], rsa_results[k][1], + 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]); } #endif #ifndef OPENSSL_NO_DSA @@ -2387,12 +2139,12 @@ int MAIN(int argc, char **argv) j = 0; } if (mr) - fprintf(stdout, "+F3:%u:%u:%f:%f\n", - k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]); + printf("+F3:%u:%u:%f:%f\n", + k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]); else - fprintf(stdout, "dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", - dsa_bits[k], dsa_results[k][0], dsa_results[k][1], - 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]); + printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n", + dsa_bits[k], dsa_results[k][0], dsa_results[k][1], + 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]); } #endif #ifndef OPENSSL_NO_EC @@ -2406,17 +2158,19 @@ int MAIN(int argc, char **argv) } if (mr) - fprintf(stdout, "+F4:%u:%u:%f:%f\n", - k, test_curves_bits[k], - ecdsa_results[k][0], ecdsa_results[k][1]); + printf("+F4:%u:%u:%f:%f\n", + k, test_curves_bits[k], + ecdsa_results[k][0], ecdsa_results[k][1]); else - fprintf(stdout, - "%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_curves_bits[k], - test_curves_names[k], - ecdsa_results[k][0], ecdsa_results[k][1], - 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]); + printf("%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", + test_curves_bits[k], + test_curves_names[k], + ecdsa_results[k][0], ecdsa_results[k][1], + 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]); } +#endif + +#ifndef OPENSSL_NO_EC j = 1; for (k = 0; k < EC_NUM; k++) { if (!ecdh_doit[k]) @@ -2426,26 +2180,24 @@ int MAIN(int argc, char **argv) j = 0; } if (mr) - fprintf(stdout, "+F5:%u:%u:%f:%f\n", - k, test_curves_bits[k], - ecdh_results[k][0], 1.0 / ecdh_results[k][0]); + printf("+F5:%u:%u:%f:%f\n", + k, test_curves_bits[k], + ecdh_results[k][0], 1.0 / ecdh_results[k][0]); else - fprintf(stdout, "%4u bit ecdh (%s) %8.4fs %8.1f\n", - test_curves_bits[k], - test_curves_names[k], - ecdh_results[k][0], 1.0 / ecdh_results[k][0]); + printf("%4u bit ecdh (%s) %8.4fs %8.1f\n", + test_curves_bits[k], + test_curves_names[k], + ecdh_results[k][0], 1.0 / ecdh_results[k][0]); } #endif - mret = 0; + ret = 0; end: ERR_print_errors(bio_err); - if (buf_malloc != NULL) - OPENSSL_free(buf_malloc); - if (buf2_malloc != NULL) - OPENSSL_free(buf2_malloc); + OPENSSL_free(save_buf); + OPENSSL_free(save_buf2); #ifndef OPENSSL_NO_RSA for (i = 0; i < RSA_NUM; i++) RSA_free(rsa_key[i]); @@ -2456,16 +2208,14 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_EC - for (i = 0; i < EC_NUM; i++) - EC_KEY_free(ecdsa[i]); for (i = 0; i < EC_NUM; i++) { + EC_KEY_free(ecdsa[i]); EC_KEY_free(ecdh_a[i]); EC_KEY_free(ecdh_b[i]); } #endif - apps_shutdown(); - OPENSSL_EXIT(mret); + return (ret); } static void print_message(const char *s, long num, int length) @@ -2606,25 +2356,6 @@ static int do_multi(int multi) k = atoi(sstrsep(&p, sep)); sstrsep(&p, sep); - d = atof(sstrsep(&p, sep)); - if (n) - rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d); - else - rsa_results[k][0] = d; - - d = atof(sstrsep(&p, sep)); - if (n) - rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d); - else - rsa_results[k][1] = d; - } else if (!strncmp(buf, "+F2:", 4)) { - int k; - double d; - - p = buf + 4; - k = atoi(sstrsep(&p, sep)); - sstrsep(&p, sep); - d = atof(sstrsep(&p, sep)); if (n) rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d); @@ -2682,6 +2413,9 @@ static int do_multi(int multi) else ecdsa_results[k][1] = d; } +# endif + +# ifndef OPENSSL_NO_EC else if (!strncmp(buf, "+F5:", 4)) { int k; double d; @@ -2700,6 +2434,7 @@ static int do_multi(int multi) # endif else if (!strncmp(buf, "+H:", 3)) { + ; } else fprintf(stderr, "Unknown type '%s' from child %d\n", buf, n); } @@ -2724,11 +2459,10 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher) inp = OPENSSL_malloc(mblengths[num - 1]); out = OPENSSL_malloc(mblengths[num - 1] + 1024); if (!inp || !out) { - BIO_printf(bio_err,"Out of memory\n"); + BIO_printf(bio_err, "Out of memory\n"); goto end; } - EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, evp_cipher, NULL, no_key, no_iv); EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key), @@ -2779,8 +2513,7 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher) } } d = Time_F(STOP); - BIO_printf(bio_err, - mr ? "+R:%d:%s:%f\n" + BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" : "%d %s's in %.2fs\n", count, "evp", d); results[D_EVP][j] = ((double)count) / d * mblengths[j]; } diff --git a/apps/spkac.c b/apps/spkac.c index 8b06ec4d6e..ee2e5969f0 100644 --- a/apps/spkac.c +++ b/apps/spkac.c @@ -1,5 +1,3 @@ -/* apps/spkac.c */ - /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 1999. Based on an original idea by Massimiliano Pala (madwolf@openca.org). @@ -70,128 +68,105 @@ #include #include -#undef PROG -#define PROG spkac_main - -/*- - * -in arg - input file - default stdin - * -out arg - output file - default stdout - */ - -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_NOOUT, OPT_PUBKEY, OPT_VERIFY, OPT_IN, OPT_OUT, + OPT_ENGINE, OPT_KEY, OPT_CHALLENGE, OPT_PASSIN, OPT_SPKAC, + OPT_SPKSECT +} OPTION_CHOICE; + +OPTIONS spkac_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"in", OPT_IN, '<', "Input file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"key", OPT_KEY, '<', "Create SPKAC using private key"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"challenge", OPT_CHALLENGE, 's', "Challenge string"}, + {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"}, + {"noout", OPT_NOOUT, '-', "Don't print SPKAC"}, + {"pubkey", OPT_PUBKEY, '-', "Output public key"}, + {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"}, + {"spksect", OPT_SPKSECT, 's'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int spkac_main(int argc, char **argv) { - ENGINE *e = NULL; - int i, badops = 0, ret = 1; BIO *in = NULL, *out = NULL; - int verify = 0, noout = 0, pubkey = 0; - char *infile = NULL, *outfile = NULL, *prog; - char *passargin = NULL, *passin = NULL; - const char *spkac = "SPKAC", *spksect = "default"; - char *spkstr = NULL; - char *challenge = NULL, *keyfile = NULL; CONF *conf = NULL; - NETSCAPE_SPKI *spki = NULL; + ENGINE *e = NULL; EVP_PKEY *pkey = NULL; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - - apps_startup(); - - if (!bio_err) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); - } else if (strcmp(*argv, "-challenge") == 0) { - if (--argc < 1) - goto bad; - challenge = *(++argv); - } else if (strcmp(*argv, "-spkac") == 0) { - if (--argc < 1) - goto bad; - spkac = *(++argv); - } else if (strcmp(*argv, "-spksect") == 0) { - if (--argc < 1) - goto bad; - spksect = *(++argv); - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else if (strcmp(*argv, "-noout") == 0) + NETSCAPE_SPKI *spki = NULL; + char *challenge = NULL, *keyfile = NULL, *engine = NULL; + char *infile = NULL, *outfile = NULL, *passinarg = NULL, *passin = NULL; + char *spkstr = NULL, *prog; + const char *spkac = "SPKAC", *spksect = "default"; + int i, ret = 1, verify = 0, noout = 0, pubkey = 0; + OPTION_CHOICE o; + + prog = opt_init(argc, argv, spkac_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(spkac_options); + ret = 0; + goto end; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_NOOUT: noout = 1; - else if (strcmp(*argv, "-pubkey") == 0) + break; + case OPT_PUBKEY: pubkey = 1; - else if (strcmp(*argv, "-verify") == 0) + break; + case OPT_VERIFY: verify = 1; - else - badops = 1; - argc--; - argv++; - } + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_KEY: + keyfile = opt_arg(); + break; + case OPT_CHALLENGE: + challenge = opt_arg(); + break; + case OPT_SPKAC: + spkac = opt_arg(); + break; + case OPT_SPKSECT: + spksect = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; - if (badops) { - bad: - BIO_printf(bio_err, "%s [options]\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, - " -key arg create SPKAC using private key\n"); - BIO_printf(bio_err, - " -passin arg input file pass phrase source\n"); - BIO_printf(bio_err, " -challenge arg challenge string\n"); - BIO_printf(bio_err, " -spkac arg alternative SPKAC name\n"); - BIO_printf(bio_err, " -noout don't print SPKAC\n"); - BIO_printf(bio_err, " -pubkey output public key\n"); - BIO_printf(bio_err, " -verify verify SPKAC signature\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine e use engine e, possibly a hardware device.\n"); -#endif - goto end; + } } + argc = opt_num_rest(); + argv = opt_rest(); - ERR_load_crypto_strings(); - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif if (keyfile) { - pkey = load_key(bio_err, - strcmp(keyfile, "-") ? keyfile : NULL, + pkey = load_key(strcmp(keyfile, "-") ? keyfile : NULL, FORMAT_PEM, 1, passin, e, "private key"); if (!pkey) { goto end; @@ -204,39 +179,18 @@ int MAIN(int argc, char **argv) NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); - if (outfile) - out = BIO_new_file(outfile, "w"); - else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } - - if (!out) { - BIO_printf(bio_err, "Error opening output file\n"); - ERR_print_errors(bio_err); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } BIO_printf(out, "SPKAC=%s\n", spkstr); OPENSSL_free(spkstr); ret = 0; goto end; } - if (infile) - in = BIO_new_file(infile, "r"); - else - in = BIO_new_fp(stdin, BIO_NOCLOSE); - - if (!in) { - BIO_printf(bio_err, "Error opening input file\n"); - ERR_print_errors(bio_err); + in = bio_open_default(infile, "r"); + if (in == NULL) goto end; - } conf = NCONF_new(NULL); i = NCONF_load_bio(conf, in, NULL); @@ -263,23 +217,9 @@ int MAIN(int argc, char **argv) goto end; } - if (outfile) - out = BIO_new_file(outfile, "w"); - else { - out = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } - - if (!out) { - BIO_printf(bio_err, "Error opening output file\n"); - ERR_print_errors(bio_err); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } if (!noout) NETSCAPE_SPKI_print(out, spki); @@ -307,6 +247,5 @@ int MAIN(int argc, char **argv) EVP_PKEY_free(pkey); if (passin) OPENSSL_free(passin); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/srp.c b/apps/srp.c index 5acc7835d1..bacd670185 100644 --- a/apps/srp.c +++ b/apps/srp.c @@ -1,4 +1,3 @@ -/* apps/srp.c */ /* * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey * project and contributed to the OpenSSL project 2004. @@ -71,9 +70,6 @@ # include "apps.h" -# undef PROG -# define PROG srp_main - # define BASE_SECTION "srp" # define CONFIG_FILE "openssl.cnf" @@ -82,41 +78,12 @@ # define ENV_DATABASE "srpvfile" # define ENV_DEFAULT_SRP "default_srp" -static char *srp_usage[] = { - "usage: srp [args] [user] \n", - "\n", - " -verbose Talk a lot while doing things\n", - " -config file A config file\n", - " -name arg The particular srp definition to use\n", - " -srpvfile arg The srp verifier file name\n", - " -add add an user and srp verifier\n", - " -modify modify the srp verifier of an existing user\n", - " -delete delete user from verifier file\n", - " -list list user\n", - " -gn arg g and N values to be used for new verifier\n", - " -userinfo arg additional info to be set for user\n", - " -passin arg input file pass phrase source\n", - " -passout arg output file pass phrase source\n", -# ifndef OPENSSL_NO_ENGINE - " -engine e - use engine e, possibly a hardware device.\n", -# endif - NULL -}; - # ifdef EFENCE extern int EF_PROTECT_FREE; extern int EF_PROTECT_BELOW; extern int EF_ALIGNMENT; # endif -static CONF *conf = NULL; -static char *section = NULL; - -# define VERBOSE if (verbose) -# define VVERBOSE if (verbose>1) - -int MAIN(int, char **); - static int get_index(CA_DB *db, char *id, char type) { char **pp; @@ -216,18 +183,17 @@ static char *srp_verify_user(const char *user, const char *srp_verifier, cb_tmp.password = passin; if (password_callback(password, 1024, 0, &cb_tmp) > 0) { - VERBOSE BIO_printf(bio, - "Validating\n" - " user=\"%s\"\n" - " srp_verifier=\"%s\"\n" - " srp_usersalt=\"%s\"\n" - " g=\"%s\"\n N=\"%s\"\n", - user, srp_verifier, srp_usersalt, g, N); + if (verbose) + BIO_printf(bio, + "Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", + user, srp_verifier, srp_usersalt, g, N); BIO_printf(bio, "Pass %s\n", password); OPENSSL_assert(srp_usersalt != NULL); - if (!(gNid = SRP_create_verifier(user, password, &srp_usersalt, - &verifier, N, g))) { + if (! + (gNid = + SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, + g))) { BIO_printf(bio, "Internal error validating SRP verifier\n"); } else { if (strcmp(verifier, srp_verifier)) @@ -250,56 +216,66 @@ static char *srp_create_user(char *user, char **srp_verifier, cb_tmp.password = passout; if (password_callback(password, 1024, 1, &cb_tmp) > 0) { - VERBOSE BIO_printf(bio, - "Creating\n" - " user=\"%s\"\n" - " g=\"%s\"\n" " N=\"%s\"\n", user, g, N); - if (!(gNid = SRP_create_verifier(user, password, &salt, - srp_verifier, N, g))) { + if (verbose) + BIO_printf(bio, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", + user, g, N); + if (! + (gNid = + SRP_create_verifier(user, password, &salt, srp_verifier, N, + g))) { BIO_printf(bio, "Internal error creating SRP verifier\n"); } else *srp_usersalt = salt; - VVERBOSE BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", - gNid, salt, *srp_verifier); + if (verbose > 1) + BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid, + salt, *srp_verifier); } return gNid; } -int MAIN(int argc, char **argv) -{ - int add_user = 0; - int list_user = 0; - int delete_user = 0; - int modify_user = 0; - char *user = NULL; - - char *passargin = NULL, *passargout = NULL; - char *passin = NULL, *passout = NULL; - char *gN = NULL; - int gNindex = -1; - char **gNrow = NULL; - int maxgN = -1; - - char *userinfo = NULL; - - int badops = 0; - int ret = 1; - int errors = 0; - int verbose = 0; - int doupdatedb = 0; - char *configfile = NULL; - char *dbfile = NULL; - CA_DB *db = NULL; - char **pp; - int i; - long errorline = -1; - char *randfile = NULL; +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD, + OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO, + OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE +} OPTION_CHOICE; + +OPTIONS srp_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"}, + {"config", OPT_CONFIG, '<', "A config file"}, + {"name", OPT_NAME, 's', "The particular srp definition to use"}, + {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"}, + {"add", OPT_ADD, '-', "Add a user and srp verifier"}, + {"modify", OPT_MODIFY, '-', + "Modify the srp verifier of an existing user"}, + {"delete", OPT_DELETE, '-', "Delete user from verifier file"}, + {"list", OPT_LIST, '-', "List users"}, + {"gn", OPT_GN, 's', "Set g and N values to be used for new verifier"}, + {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, # ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif - char *tofree = NULL; + {NULL} +}; + +int srp_main(int argc, char **argv) +{ + CA_DB *db = NULL; DB_ATTR db_attr; + CONF *conf = NULL; + int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose = + 0, i, doupdatedb = 0; + int mode = OPT_ERR; + char *user = NULL, *passinarg = NULL, *passoutarg = NULL; + char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL; + char *randfile = NULL, *engine = NULL, *tofree = NULL, *section = NULL; + char **gNrow = NULL, *configfile = NULL, *dbfile = NULL, **pp, *prog; + long errorline = -1; + OPTION_CHOICE o; # ifdef EFENCE EF_PROTECT_FREE = 1; @@ -307,119 +283,89 @@ int MAIN(int argc, char **argv) EF_ALIGNMENT = 0; # endif - apps_startup(); - - conf = NULL; - section = NULL; - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - argc--; - argv++; - while (argc >= 1 && badops == 0) { - if (strcmp(*argv, "-verbose") == 0) + prog = opt_init(argc, argv, srp_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(srp_options); + ret = 0; + goto end; + case OPT_VERBOSE: verbose++; - else if (strcmp(*argv, "-config") == 0) { - if (--argc < 1) - goto bad; - configfile = *(++argv); - } else if (strcmp(*argv, "-name") == 0) { - if (--argc < 1) - goto bad; - section = *(++argv); - } else if (strcmp(*argv, "-srpvfile") == 0) { - if (--argc < 1) - goto bad; - dbfile = *(++argv); - } else if (strcmp(*argv, "-add") == 0) - add_user = 1; - else if (strcmp(*argv, "-delete") == 0) - delete_user = 1; - else if (strcmp(*argv, "-modify") == 0) - modify_user = 1; - else if (strcmp(*argv, "-list") == 0) - list_user = 1; - else if (strcmp(*argv, "-gn") == 0) { - if (--argc < 1) - goto bad; - gN = *(++argv); - } else if (strcmp(*argv, "-userinfo") == 0) { - if (--argc < 1) - goto bad; - userinfo = *(++argv); - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-passout") == 0) { - if (--argc < 1) - goto bad; - passargout = *(++argv); - } -# ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -# endif - - else if (**argv == '-') { - bad: - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; - } else + case OPT_CONFIG: + configfile = opt_arg(); break; - - argc--; - argv++; + case OPT_NAME: + section = opt_arg(); + break; + case OPT_SRPVFILE: + dbfile = opt_arg(); + break; + case OPT_ADD: + case OPT_DELETE: + case OPT_MODIFY: + case OPT_LIST: + if (mode != OPT_ERR) { + BIO_printf(bio_err, + "%s: Only one of -add/delete-modify/-list\n", + prog); + goto opthelp; + } + mode = o; + break; + case OPT_GN: + gN = opt_arg(); + break; + case OPT_USERINFO: + userinfo = opt_arg(); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_PASSOUT: + passoutarg = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); if (dbfile && configfile) { BIO_printf(bio_err, "-dbfile and -configfile cannot be specified together.\n"); - badops = 1; + goto end; } - if (add_user + delete_user + modify_user + list_user != 1) { - BIO_printf(bio_err, "Exactly one of the options " - "-add, -delete, -modify -list must be specified.\n"); - badops = 1; + if (mode == OPT_ERR) { + BIO_printf(bio_err, + "Exactly one of the options -add, -delete, -modify -list must be specified.\n"); + goto opthelp; } - if (delete_user + modify_user + delete_user == 1 && argc <= 0) { - BIO_printf(bio_err, "Need at least one user for options " - "-add, -delete, -modify. \n"); - badops = 1; + if ((mode == OPT_DELETE || mode == OPT_MODIFY || OPT_ADD) && argc < 1) { + BIO_printf(bio_err, + "Need at least one user for options -add, -delete, -modify. \n"); + goto opthelp; } if ((passin || passout) && argc != 1) { BIO_printf(bio_err, "-passin, -passout arguments only valid with one user.\n"); - badops = 1; + goto opthelp; } - - if (badops) { - for (pp = srp_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); - - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, - " load the file (or the files in the directory) into\n"); - BIO_printf(bio_err, " the random number generator\n"); - goto err; - } - - ERR_load_crypto_strings(); - # ifndef OPENSSL_NO_ENGINE - setup_engine(bio_err, engine, 0); + setup_engine(engine, 0); # endif - if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); - goto err; + goto end; } if (!dbfile) { @@ -439,7 +385,7 @@ int MAIN(int argc, char **argv) tofree = OPENSSL_malloc(len); if (!tofree) { BIO_printf(bio_err, "Out of memory\n"); - goto err; + goto end; } strcpy(tofree, s); # else @@ -447,7 +393,7 @@ int MAIN(int argc, char **argv) tofree = OPENSSL_malloc(len); if (!tofree) { BIO_printf(bio_err, "Out of memory\n"); - goto err; + goto end; } BUF_strlcpy(tofree, s, len); BUF_strlcat(tofree, "/", len); @@ -456,8 +402,8 @@ int MAIN(int argc, char **argv) configfile = tofree; } - VERBOSE BIO_printf(bio_err, "Using configuration from %s\n", - configfile); + if (verbose) + BIO_printf(bio_err, "Using configuration from %s\n", configfile); conf = NCONF_new(NULL); if (NCONF_load(conf, configfile, &errorline) <= 0) { if (errorline <= 0) @@ -466,53 +412,53 @@ int MAIN(int argc, char **argv) else BIO_printf(bio_err, "error on line %ld of config file '%s'\n", errorline, configfile); - goto err; + goto end; } if (tofree) { OPENSSL_free(tofree); tofree = NULL; } - if (!load_config(bio_err, conf)) - goto err; - /* Lets get the config section we are using */ if (section == NULL) { - VERBOSE BIO_printf(bio_err, - "trying to read " ENV_DEFAULT_SRP - " in \" BASE_SECTION \"\n"); + if (verbose) + BIO_printf(bio_err, + "trying to read " ENV_DEFAULT_SRP + " in \" BASE_SECTION \"\n"); section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_SRP); if (section == NULL) { lookup_fail(BASE_SECTION, ENV_DEFAULT_SRP); - goto err; + goto end; } } if (randfile == NULL && conf) randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); - VERBOSE BIO_printf(bio_err, - "trying to read " ENV_DATABASE - " in section \"%s\"\n", section); + if (verbose) + BIO_printf(bio_err, + "trying to read " ENV_DATABASE " in section \"%s\"\n", + section); if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { lookup_fail(section, ENV_DATABASE); - goto err; + goto end; } } if (randfile == NULL) ERR_clear_error(); else - app_RAND_load_file(randfile, bio_err, 0); + app_RAND_load_file(randfile, 0); - VERBOSE BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n", - dbfile); + if (verbose) + BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n", + dbfile); db = load_index(dbfile, &db_attr); if (db == NULL) - goto err; + goto end; /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { @@ -527,46 +473,50 @@ int MAIN(int argc, char **argv) } } - VERBOSE BIO_printf(bio_err, "Database initialised\n"); + if (verbose) + BIO_printf(bio_err, "Database initialised\n"); if (gNindex >= 0) { gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex); print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N"); } else if (maxgN > 0 && !SRP_get_default_gN(gN)) { BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN); - goto err; + goto end; } else { - VERBOSE BIO_printf(bio_err, "Database has no g N information.\n"); + if (verbose) + BIO_printf(bio_err, "Database has no g N information.\n"); gNrow = NULL; } - VVERBOSE BIO_printf(bio_err, "Starting user processing\n"); + if (verbose > 1) + BIO_printf(bio_err, "Starting user processing\n"); if (argc > 0) user = *(argv++); - while (list_user || user) { + while (mode == OPT_LIST || user) { int userindex = -1; if (user) - VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user); + if (verbose > 1) + BIO_printf(bio_err, "Processing user \"%s\"\n", user); if ((userindex = get_index(db, user, 'U')) >= 0) { - print_user(db, bio_err, userindex, (verbose > 0) || list_user); + print_user(db, bio_err, userindex, (verbose > 0) + || mode == OPT_LIST); } - if (list_user) { + if (mode == OPT_LIST) { if (user == NULL) { BIO_printf(bio_err, "List all users\n"); for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { print_user(db, bio_err, i, 1); } - list_user = 0; } else if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n", user); errors++; } - } else if (add_user) { + } else if (mode == OPT_ADD) { if (userindex >= 0) { /* reactivation of a new user */ char **row = @@ -581,26 +531,31 @@ int MAIN(int argc, char **argv) row[DB_srpverifier] = NULL; row[DB_srpsalt] = NULL; row[DB_srpinfo] = NULL; - if (!(gNid = srp_create_user(user, &(row[DB_srpverifier]), - &(row[DB_srpsalt]), - gNrow ? gNrow[DB_srpsalt] : gN, - gNrow ? gNrow[DB_srpverifier] : - NULL, passout, bio_err, - verbose))) { + if (! + (gNid = + srp_create_user(user, &(row[DB_srpverifier]), + &(row[DB_srpsalt]), + gNrow ? gNrow[DB_srpsalt] : gN, + gNrow ? gNrow[DB_srpverifier] : NULL, + passout, bio_err, verbose))) { BIO_printf(bio_err, - "Cannot create srp verifier for user \"%s\"," - " operation abandoned .\n", user); + "Cannot create srp verifier for user \"%s\", operation abandoned .\n", + user); errors++; - goto err; + goto end; } row[DB_srpid] = BUF_strdup(user); row[DB_srptype] = BUF_strdup("v"); row[DB_srpgN] = BUF_strdup(gNid); if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] - || !row[DB_srpverifier] || !row[DB_srpsalt] - || (userinfo - && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) + || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo + && + (!(row + [DB_srpinfo] + = + BUF_strdup + (userinfo)))) || !update_index(db, bio_err, row)) { if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]); @@ -614,11 +569,11 @@ int MAIN(int argc, char **argv) OPENSSL_free(row[DB_srpverifier]); if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]); - goto err; + goto end; } doupdatedb = 1; } - } else if (modify_user) { + } else if (mode == OPT_MODIFY) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored.\n", @@ -640,9 +595,10 @@ int MAIN(int argc, char **argv) if (row[DB_srptype][0] == 'V') { int user_gN; char **irow = NULL; - VERBOSE BIO_printf(bio_err, - "Verifying password for user \"%s\"\n", - user); + if (verbose) + BIO_printf(bio_err, + "Verifying password for user \"%s\"\n", + user); if ((user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0) irow = @@ -658,25 +614,25 @@ int MAIN(int argc, char **argv) "Invalid password for user \"%s\", operation abandoned.\n", user); errors++; - goto err; + goto end; } } - VERBOSE BIO_printf(bio_err, - "Password for user \"%s\" ok.\n", - user); - - if (!(gNid = srp_create_user(user, &(row[DB_srpverifier]), - &(row[DB_srpsalt]), - gNrow ? gNrow[DB_srpsalt] : - NULL, - gNrow ? gNrow[DB_srpverifier] - : NULL, passout, bio_err, - verbose))) { + if (verbose) + BIO_printf(bio_err, "Password for user \"%s\" ok.\n", + user); + + if (! + (gNid = + srp_create_user(user, &(row[DB_srpverifier]), + &(row[DB_srpsalt]), + gNrow ? gNrow[DB_srpsalt] : NULL, + gNrow ? gNrow[DB_srpverifier] : NULL, + passout, bio_err, verbose))) { BIO_printf(bio_err, - "Cannot create srp verifier for user \"%s\"," - " operation abandoned.\n", user); + "Cannot create srp verifier for user \"%s\", operation abandoned.\n", + user); errors++; - goto err; + goto end; } row[DB_srptype][0] = 'v'; @@ -686,12 +642,12 @@ int MAIN(int argc, char **argv) || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo))))) - goto err; + goto end; doupdatedb = 1; } } - } else if (delete_user) { + } else if (mode == OPT_DELETE) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", @@ -711,11 +667,11 @@ int MAIN(int argc, char **argv) user = *(argv++); else { user = NULL; - list_user = 0; } } - VERBOSE BIO_printf(bio_err, "User procession done.\n"); + if (verbose) + BIO_printf(bio_err, "User procession done.\n"); if (doupdatedb) { /* Lets check some fields */ @@ -728,37 +684,41 @@ int MAIN(int argc, char **argv) } } - VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n"); + if (verbose) + BIO_printf(bio_err, "Trying to update srpvfile.\n"); if (!save_index(dbfile, "new", db)) - goto err; + goto end; - VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n"); + if (verbose) + BIO_printf(bio_err, "Temporary srpvfile created.\n"); if (!rotate_index(dbfile, "new", "old")) - goto err; + goto end; - VERBOSE BIO_printf(bio_err, "srpvfile updated.\n"); + if (verbose) + BIO_printf(bio_err, "srpvfile updated.\n"); } ret = (errors != 0); - err: + end: if (errors != 0) - VERBOSE BIO_printf(bio_err, "User errors %d.\n", errors); + if (verbose) + BIO_printf(bio_err, "User errors %d.\n", errors); - VERBOSE BIO_printf(bio_err, "SRP terminating with code %d.\n", ret); + if (verbose) + BIO_printf(bio_err, "SRP terminating with code %d.\n", ret); if (tofree) OPENSSL_free(tofree); if (ret) ERR_print_errors(bio_err); if (randfile) - app_RAND_write_file(randfile, bio_err); + app_RAND_write_file(randfile); if (conf) NCONF_free(conf); if (db) free_index(db); OBJ_cleanup(); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } #endif diff --git a/apps/testdsa.h b/apps/testdsa.h index 550c6253e6..4eb13d14b2 100644 --- a/apps/testdsa.h +++ b/apps/testdsa.h @@ -1,8 +1,57 @@ -/* NOCW */ -/* used by apps/speed.c */ +/* ==================================================================== + * Copyright (c) 199-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 + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* used by speed.c */ DSA *get_dsa512(void); DSA *get_dsa1024(void); DSA *get_dsa2048(void); + static unsigned char dsa512_priv[] = { 0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c, 0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2, diff --git a/apps/ts.c b/apps/ts.c index 4c32ada410..e0f43130ca 100644 --- a/apps/ts.c +++ b/apps/ts.c @@ -1,4 +1,3 @@ -/* apps/ts.c */ /* * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project * 2002. @@ -68,9 +67,6 @@ #include #include -#undef PROG -#define PROG ts_main - /* Length of the nonce of the request in bits (must be a multiple of 8). */ #define NONCE_LENGTH 64 @@ -86,8 +82,6 @@ static CONF *load_config_file(const char *configfile); static int query_command(const char *data, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert, const char *in, const char *out, int text); -static BIO *BIO_open_with_default(const char *file, const char *mode, - FILE *default_fp); static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert); static int create_digest(BIO *input, char *digest, @@ -102,8 +96,8 @@ static int reply_command(CONF *conf, char *section, char *engine, int text); static TS_RESP *read_PKCS7(BIO *in_bio); static TS_RESP *create_response(CONF *conf, const char *section, char *engine, - char *queryfile, char *passin, char *inkey, - char *signer, char *chain, + char *queryfile, char *passin, + char *inkey, char *signer, char *chain, const char *policy); static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data); static ASN1_INTEGER *next_serial(const char *serialfile); @@ -112,163 +106,201 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial); /* Verify related functions. */ static int verify_command(char *data, char *digest, char *queryfile, char *in, int token_in, - char *ca_path, char *ca_file, char *untrusted); + char *CApath, char *CAfile, char *untrusted); static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, char *queryfile, - char *ca_path, char *ca_file, + char *CApath, char *CAfile, char *untrusted); -static X509_STORE *create_cert_store(char *ca_path, char *ca_file); +static X509_STORE *create_cert_store(char *CApath, char *CAfile); static int verify_cb(int ok, X509_STORE_CTX *ctx); -/* Main function definition. */ -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA, + OPT_DIGEST, OPT_RAND, OPT_POLICY, OPT_NO_NONCE, OPT_CERT, + OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT, + OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER, + OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED, + OPT_MD +} OPTION_CHOICE; + +OPTIONS ts_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"config", OPT_CONFIG, '<', "Configuration file"}, + {"section", OPT_SECTION, 's', "Section to use within config file"}, + {"query", OPT_QUERY, '-', "Generate a TS query"}, + {"data", OPT_DATA, '<', "File to hash"}, + {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"policy", OPT_POLICY, 's', "Policy OID to use"}, + {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"}, + {"cert", OPT_CERT, '-', "Put cert request into query"}, + {"in", OPT_IN, '<', "Input file"}, + {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"}, + {"out", OPT_OUT, '>', "Output file"}, + {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"}, + {"text", OPT_TEXT, '-', "Output text (not DER)"}, + {"reply", OPT_REPLY, '-', "Generate a TS reply"}, + {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"}, + {"passin", OPT_PASSIN, 's'}, + {"inkey", OPT_INKEY, '<', "File with private key for reply"}, + {"signer", OPT_SIGNER, 's'}, + {"chain", OPT_CHAIN, '<', "File with signer CA chain"}, + {"verify", OPT_VERIFY, '-', "Verify a TS response"}, + {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"}, + {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, + {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"", OPT_MD, '-', "Any supported digest"}, + {NULL} +}; -int MAIN(int argc, char **argv) +/* + * This comand is so complex, special help is needed. + */ +static char* opt_helplist[] = { + "Typical uses:", + "ts -query [-rand file...] [-config file] [-data file]", + " [-digest hexstring] [-policy oid] [-no_nonce] [-cert]", + " [-in file] [-out file] [-text]", + " or", + "ts -reply [-config file] [-section tsa_section]", + " [-queryfile file] [-passin password]", + " [-signer tsa_cert.pem] [-inkey private_key.pem]", + " [-chain certs_file.pem] [-policy oid]", + " [-in file] [-token_in] [-out file] [-token_out]", +#ifndef OPENSSL_NO_ENGINE + " [-text]", +#else + " [-text] [-engine id]", +#endif + " or", + "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem", + " [-data file] [-digest hexstring]", + " [-queryfile file] -in file [-token_in]", + NULL, +}; + +int ts_main(int argc, char **argv) { - int ret = 1; - char *configfile = NULL; - char *section = NULL; CONF *conf = NULL; - enum mode { - CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY - } mode = CMD_NONE; - char *data = NULL; - char *digest = NULL; + char *CAfile = NULL, *untrusted = NULL, *engine = NULL, *prog, **helpp; + char *configfile = NULL, *section = NULL, *password = NULL; + char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL; + char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL; + char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL; const EVP_MD *md = NULL; - char *rnd = NULL; - char *policy = NULL; - int no_nonce = 0; - int cert = 0; - char *in = NULL; - char *out = NULL; - int text = 0; - char *queryfile = NULL; - char *passin = NULL; /* Password source. */ - char *password = NULL; /* Password itself. */ - char *inkey = NULL; - char *signer = NULL; - char *chain = NULL; - char *ca_path = NULL; - char *ca_file = NULL; - char *untrusted = NULL; - char *engine = NULL; + OPTION_CHOICE o, mode = OPT_ERR; + int ret = 1, no_nonce = 0, cert = 0, text = 0; /* Input is ContentInfo instead of TimeStampResp. */ int token_in = 0; /* Output is ContentInfo instead of TimeStampResp. */ int token_out = 0; - int free_bio_err = 0; - ERR_load_crypto_strings(); - apps_startup(); - - if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL) { - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - free_bio_err = 1; - } - - if (!load_config(bio_err, NULL)) - goto cleanup; - - for (argc--, argv++; argc > 0; argc--, argv++) { - if (strcmp(*argv, "-config") == 0) { - if (argc-- < 1) - goto usage; - configfile = *++argv; - } else if (strcmp(*argv, "-section") == 0) { - if (argc-- < 1) - goto usage; - section = *++argv; - } else if (strcmp(*argv, "-query") == 0) { - if (mode != CMD_NONE) - goto usage; - mode = CMD_QUERY; - } else if (strcmp(*argv, "-data") == 0) { - if (argc-- < 1) - goto usage; - data = *++argv; - } else if (strcmp(*argv, "-digest") == 0) { - if (argc-- < 1) - goto usage; - digest = *++argv; - } else if (strcmp(*argv, "-rand") == 0) { - if (argc-- < 1) - goto usage; - rnd = *++argv; - } else if (strcmp(*argv, "-policy") == 0) { - if (argc-- < 1) - goto usage; - policy = *++argv; - } else if (strcmp(*argv, "-no_nonce") == 0) { + prog = opt_init(argc, argv, ts_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(ts_options); + for (helpp = opt_helplist; *helpp; ++helpp) + BIO_printf(bio_err, "%s\n", *helpp); + ret = 0; + goto end; + case OPT_CONFIG: + configfile = opt_arg(); + break; + case OPT_SECTION: + section = opt_arg(); + break; + case OPT_QUERY: + case OPT_REPLY: + case OPT_VERIFY: + if (mode != OPT_ERR) + goto opthelp; + mode = o; + break; + case OPT_DATA: + data = opt_arg(); + break; + case OPT_DIGEST: + digest = opt_arg(); + break; + case OPT_RAND: + rnd = opt_arg(); + break; + case OPT_POLICY: + policy = opt_arg(); + break; + case OPT_NO_NONCE: no_nonce = 1; - } else if (strcmp(*argv, "-cert") == 0) { + break; + case OPT_CERT: cert = 1; - } else if (strcmp(*argv, "-in") == 0) { - if (argc-- < 1) - goto usage; - in = *++argv; - } else if (strcmp(*argv, "-token_in") == 0) { + break; + case OPT_IN: + in = opt_arg(); + break; + case OPT_TOKEN_IN: token_in = 1; - } else if (strcmp(*argv, "-out") == 0) { - if (argc-- < 1) - goto usage; - out = *++argv; - } else if (strcmp(*argv, "-token_out") == 0) { + break; + case OPT_OUT: + out = opt_arg(); + break; + case OPT_TOKEN_OUT: token_out = 1; - } else if (strcmp(*argv, "-text") == 0) { + break; + case OPT_TEXT: text = 1; - } else if (strcmp(*argv, "-reply") == 0) { - if (mode != CMD_NONE) - goto usage; - mode = CMD_REPLY; - } else if (strcmp(*argv, "-queryfile") == 0) { - if (argc-- < 1) - goto usage; - queryfile = *++argv; - } else if (strcmp(*argv, "-passin") == 0) { - if (argc-- < 1) - goto usage; - passin = *++argv; - } else if (strcmp(*argv, "-inkey") == 0) { - if (argc-- < 1) - goto usage; - inkey = *++argv; - } else if (strcmp(*argv, "-signer") == 0) { - if (argc-- < 1) - goto usage; - signer = *++argv; - } else if (strcmp(*argv, "-chain") == 0) { - if (argc-- < 1) - goto usage; - chain = *++argv; - } else if (strcmp(*argv, "-verify") == 0) { - if (mode != CMD_NONE) - goto usage; - mode = CMD_VERIFY; - } else if (strcmp(*argv, "-CApath") == 0) { - if (argc-- < 1) - goto usage; - ca_path = *++argv; - } else if (strcmp(*argv, "-CAfile") == 0) { - if (argc-- < 1) - goto usage; - ca_file = *++argv; - } else if (strcmp(*argv, "-untrusted") == 0) { - if (argc-- < 1) - goto usage; - untrusted = *++argv; - } else if (strcmp(*argv, "-engine") == 0) { - if (argc-- < 1) - goto usage; - engine = *++argv; - } else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL) { - /* empty. */ - } else - goto usage; + break; + case OPT_QUERYFILE: + queryfile = opt_arg(); + break; + case OPT_PASSIN: + passin = opt_arg(); + break; + case OPT_INKEY: + inkey = opt_arg(); + break; + case OPT_SIGNER: + signer = opt_arg(); + break; + case OPT_CHAIN: + chain = opt_arg(); + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_UNTRUSTED: + untrusted = opt_arg(); + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_unknown(), &md)) + goto opthelp; + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); + if (mode == OPT_ERR || argc != 0) + goto opthelp; /* Seed the random number generator if it is going to be used. */ - if (mode == CMD_QUERY && !no_nonce) { - if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL) + if (mode == OPT_QUERY && !no_nonce) { + if (!app_RAND_load_file(NULL, 1) && rnd == NULL) BIO_printf(bio_err, "warning, not much extra random " "data, consider using the -rand option\n"); if (rnd != NULL) @@ -277,95 +309,68 @@ int MAIN(int argc, char **argv) } /* Get the password if required. */ - if (mode == CMD_REPLY && passin && - !app_passwd(bio_err, passin, NULL, &password, NULL)) { + if (mode == OPT_REPLY && passin && + !app_passwd(passin, NULL, &password, NULL)) { BIO_printf(bio_err, "Error getting password.\n"); - goto cleanup; + goto end; } /* * Check consistency of parameters and execute the appropriate function. */ switch (mode) { - case CMD_NONE: - goto usage; - case CMD_QUERY: + default: + case OPT_ERR: + goto opthelp; + case OPT_QUERY: /* * Data file and message imprint cannot be specified at the same * time. */ ret = data != NULL && digest != NULL; if (ret) - goto usage; + goto opthelp; /* Load the config file for possible policy OIDs. */ conf = load_config_file(configfile); ret = !query_command(data, digest, md, policy, no_nonce, cert, in, out, text); break; - case CMD_REPLY: + case OPT_REPLY: conf = load_config_file(configfile); if (in == NULL) { ret = !(queryfile != NULL && conf != NULL && !token_in); if (ret) - goto usage; + goto opthelp; } else { /* 'in' and 'queryfile' are exclusive. */ ret = !(queryfile == NULL); if (ret) - goto usage; + goto opthelp; } - ret = !reply_command(conf, section, engine, queryfile, password, inkey, signer, chain, policy, in, token_in, out, token_out, text); break; - case CMD_VERIFY: + case OPT_VERIFY: ret = !(((queryfile && !data && !digest) || (!queryfile && data && !digest) || (!queryfile && !data && digest)) && in != NULL); if (ret) - goto usage; + goto opthelp; ret = !verify_command(data, digest, queryfile, in, token_in, - ca_path, ca_file, untrusted); + CApath, CAfile, untrusted); } - goto cleanup; - - usage: - BIO_printf(bio_err, "usage:\n" - "ts -query [-rand file%cfile%c...] [-config configfile] " - "[-data file_to_hash] [-digest digest_bytes]" - "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] " - "[-policy object_id] [-no_nonce] [-cert] " - "[-in request.tsq] [-out request.tsq] [-text]\n", - LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, "or\n" - "ts -reply [-config configfile] [-section tsa_section] " - "[-queryfile request.tsq] [-passin password] " - "[-signer tsa_cert.pem] [-inkey private_key.pem] " - "[-chain certs_file.pem] [-policy object_id] " - "[-in response.tsr] [-token_in] " - "[-out response.tsr] [-token_out] [-text] [-engine id]\n"); - BIO_printf(bio_err, "or\n" - "ts -verify [-data file_to_hash] [-digest digest_bytes] " - "[-queryfile request.tsq] " - "-in response.tsr [-token_in] " - "-CApath ca_path -CAfile ca_file.pem " - "-untrusted cert_file.pem\n"); - cleanup: + end: /* Clean up. */ - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); NCONF_free(conf); OPENSSL_free(password); OBJ_cleanup(); - if (free_bio_err) { - BIO_free_all(bio_err); - bio_err = NULL; - } - OPENSSL_EXIT(ret); + return (ret); } /* @@ -418,7 +423,7 @@ static CONF *load_config_file(const char *configfile) } } else ERR_clear_error(); - if (!add_oid_section(bio_err, conf)) + if (!add_oid_section(conf)) ERR_print_errors(bio_err); } return conf; @@ -427,7 +432,6 @@ static CONF *load_config_file(const char *configfile) /* * Query-related method definitions. */ - static int query_command(const char *data, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert, const char *in, const char *out, int text) @@ -444,20 +448,16 @@ static int query_command(const char *data, char *digest, const EVP_MD *md, goto end; query = d2i_TS_REQ_bio(in_bio, NULL); } else { - /* - * Open the file if no explicit digest bytes were specified. - */ - if (!digest && !(data_bio = BIO_open_with_default(data, "rb", stdin))) + /* Open the file if no explicit digest bytes were specified. */ + if (!digest && !(data_bio = bio_open_default(data, "rb"))) goto end; - /* Creating the query object. */ query = create_query(data_bio, digest, md, policy, no_nonce, cert); - /* Saving the random number generator state. */ } if (query == NULL) goto end; /* Write query either in ASN.1 or in text format. */ - if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) + if ((out_bio = bio_open_default(out, "wb")) == NULL) goto end; if (text) { /* Text output. */ @@ -483,13 +483,6 @@ static int query_command(const char *data, char *digest, const EVP_MD *md, return ret; } -static BIO *BIO_open_with_default(const char *file, const char *mode, - FILE *default_fp) -{ - return file == NULL ? BIO_new_fp(default_fp, BIO_NOCLOSE) - : BIO_new_file(file, mode); -} - static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert) { @@ -686,7 +679,7 @@ static int reply_command(CONF *conf, char *section, char *engine, goto end; /* Write response either in ASN.1 or text format. */ - if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) + if ((out_bio = bio_open_default(out, "wb")) == NULL) goto end; if (text) { /* Text output. */ @@ -771,8 +764,9 @@ static TS_RESP *read_PKCS7(BIO *in_bio) } static TS_RESP *create_response(CONF *conf, const char *section, char *engine, - char *queryfile, char *passin, char *inkey, - char *signer, char *chain, const char *policy) + char *queryfile, char *passin, + char *inkey, char *signer, char *chain, + const char *policy) { int ret = 0; TS_RESP *response = NULL; @@ -944,7 +938,7 @@ static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial) static int verify_command(char *data, char *digest, char *queryfile, char *in, int token_in, - char *ca_path, char *ca_file, char *untrusted) + char *CApath, char *CAfile, char *untrusted) { BIO *in_bio = NULL; PKCS7 *token = NULL; @@ -964,7 +958,7 @@ static int verify_command(char *data, char *digest, char *queryfile, } if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, - ca_path, ca_file, untrusted))) + CApath, CAfile, untrusted))) goto end; /* Checking the token or response against the request. */ @@ -992,7 +986,7 @@ static int verify_command(char *data, char *digest, char *queryfile, static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, char *queryfile, - char *ca_path, char *ca_file, + char *CApath, char *CAfile, char *untrusted) { TS_VERIFY_CTX *ctx = NULL; @@ -1036,7 +1030,7 @@ static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, ctx->flags |= TS_VFY_SIGNATURE; /* Initialising the X509_STORE object. */ - if (!(ctx->store = create_cert_store(ca_path, ca_file))) + if (!(ctx->store = create_cert_store(CApath, CAfile))) goto err; /* Loading untrusted certificates. */ @@ -1054,7 +1048,7 @@ static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, return ctx; } -static X509_STORE *create_cert_store(char *ca_path, char *ca_file) +static X509_STORE *create_cert_store(char *CApath, char *CAfile) { X509_STORE *cert_ctx = NULL; X509_LOOKUP *lookup = NULL; @@ -1067,29 +1061,29 @@ static X509_STORE *create_cert_store(char *ca_path, char *ca_file) X509_STORE_set_verify_cb(cert_ctx, verify_cb); /* Adding a trusted certificate directory source. */ - if (ca_path) { + if (CApath) { lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); if (lookup == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM); + i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); if (!i) { - BIO_printf(bio_err, "Error loading directory %s\n", ca_path); + BIO_printf(bio_err, "Error loading directory %s\n", CApath); goto err; } } /* Adding a trusted certificate file source. */ - if (ca_file) { + if (CAfile) { lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); if (lookup == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); goto err; } - i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM); + i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM); if (!i) { - BIO_printf(bio_err, "Error loading file %s\n", ca_file); + BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto err; } } @@ -1102,19 +1096,5 @@ static X509_STORE *create_cert_store(char *ca_path, char *ca_file) static int verify_cb(int ok, X509_STORE_CTX *ctx) { - /*- - char buf[256]; - - if (!ok) - { - X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), - buf, sizeof(buf)); - printf("%s\n", buf); - printf("error %d at %d depth lookup: %s\n", - ctx->error, ctx->error_depth, - X509_verify_cert_error_string(ctx->error)); - } - */ - return ok; } diff --git a/apps/verify.c b/apps/verify.c index e771be22d2..61e85ce87e 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -1,4 +1,3 @@ -/* apps/verify.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -66,209 +65,173 @@ #include #include -#undef PROG -#define PROG verify_main - static int cb(int ok, X509_STORE_CTX *ctx); static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls, ENGINE *e, int show_chain); static int v_verbose = 0, vflags = 0; -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED, OPT_TRUSTED, + OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN, + OPT_V_ENUM, + OPT_VERBOSE +} OPTION_CHOICE; + +OPTIONS verify_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, + {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, + {"help", OPT_HELP, '-', "Display this summary"}, + {"verbose", OPT_VERBOSE, '-'}, + {"CApath", OPT_CAPATH, '/'}, + {"CAfile", OPT_CAFILE, '<'}, + {"untrusted", OPT_UNTRUSTED, '<'}, + {"trusted", OPT_TRUSTED, '<'}, + {"CRLfile", OPT_CRLFILE, '<'}, + {"crl_download", OPT_CRL_DOWNLOAD, '-'}, + {"show_chain", OPT_SHOW_CHAIN, '-'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + OPT_V_OPTIONS, + {NULL} +}; -int MAIN(int argc, char **argv) +int verify_main(int argc, char **argv) { ENGINE *e = NULL; - int i, ret = 1, badarg = 0; - char *CApath = NULL, *CAfile = NULL; - char *untfile = NULL, *trustfile = NULL, *crlfile = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; STACK_OF(X509_CRL) *crls = NULL; - X509_STORE *cert_ctx = NULL; - X509_LOOKUP *lookup = NULL; + X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; - int crl_download = 0, show_chain = 0; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif + char *prog, *CApath = NULL, *CAfile = NULL, *engine = NULL; + char *untfile = NULL, *trustfile = NULL, *crlfile = NULL; + int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; + OPTION_CHOICE o; - cert_ctx = X509_STORE_new(); - if (cert_ctx == NULL) + if ((vpm = X509_VERIFY_PARAM_new()) == NULL) goto end; - X509_STORE_set_verify_cb(cert_ctx, cb); - - ERR_load_crypto_strings(); - - apps_startup(); - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (!load_config(bio_err, NULL)) - goto end; + prog = opt_init(argc, argv, verify_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(verify_options); + BIO_printf(bio_err, "Recognized usages:\n"); + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + X509_PURPOSE *ptmp; + ptmp = X509_PURPOSE_get0(i); + BIO_printf(bio_err, "\t%-10s\t%s\n", + X509_PURPOSE_get0_sname(ptmp), + X509_PURPOSE_get0_name(ptmp)); + } - argc--; - argv++; - for (;;) { - if (argc >= 1) { - if (strcmp(*argv, "-CApath") == 0) { - if (argc-- < 1) - goto end; - CApath = *(++argv); - } else if (strcmp(*argv, "-CAfile") == 0) { - if (argc-- < 1) - goto end; - CAfile = *(++argv); - } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { - if (badarg) - goto end; - continue; - } else if (strcmp(*argv, "-untrusted") == 0) { - if (argc-- < 1) - goto end; - untfile = *(++argv); - } else if (strcmp(*argv, "-trusted") == 0) { - if (argc-- < 1) - goto end; - trustfile = *(++argv); - } else if (strcmp(*argv, "-CRLfile") == 0) { - if (argc-- < 1) - goto end; - crlfile = *(++argv); - } else if (strcmp(*argv, "-crl_download") == 0) - crl_download = 1; - else if (strcmp(*argv, "-show_chain") == 0) - show_chain = 1; -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto end; - engine = *(++argv); + BIO_printf(bio_err, "Recognized verify names:\n"); + for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) { + const X509_VERIFY_PARAM *vptmp; + vptmp = X509_VERIFY_PARAM_get0(i); + BIO_printf(bio_err, "\t%-10s\n", + X509_VERIFY_PARAM_get0_name(vptmp)); } -#endif - else if (strcmp(*argv, "-help") == 0) - goto end; - else if (strcmp(*argv, "-verbose") == 0) - v_verbose = 1; - else if (argv[0][0] == '-') + ret = 0; + goto end; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) goto end; - else - break; - argc--; - argv++; - } else + vpmtouched++; + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_UNTRUSTED: + untfile = opt_arg(); + break; + case OPT_TRUSTED: + trustfile = opt_arg(); + break; + case OPT_CRLFILE: + crlfile = opt_arg(); + break; + case OPT_CRL_DOWNLOAD: + crl_download = 1; break; + case OPT_SHOW_CHAIN: + show_chain = 1; + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_VERBOSE: + v_verbose = 1; + break; + } } + argc = opt_num_rest(); + argv = opt_rest(); #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif + if (!(store = setup_verify(CAfile, CApath))) + goto end; + X509_STORE_set_verify_cb(store, cb); - if (vpm) - X509_STORE_set1_param(cert_ctx, vpm); - - lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); - if (lookup == NULL) - abort(); - if (CAfile) { - i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM); - if (!i) { - BIO_printf(bio_err, "Error loading file %s\n", CAfile); - ERR_print_errors(bio_err); - goto end; - } - } else - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); - - lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - abort(); - if (CApath) { - i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); - if (!i) { - BIO_printf(bio_err, "Error loading directory %s\n", CApath); - ERR_print_errors(bio_err); - goto end; - } - } else - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + if (vpmtouched) + X509_STORE_set1_param(store, vpm); ERR_clear_error(); if (untfile) { - untrusted = load_certs(bio_err, untfile, FORMAT_PEM, + untrusted = load_certs(untfile, FORMAT_PEM, NULL, e, "untrusted certificates"); if (!untrusted) goto end; } if (trustfile) { - trusted = load_certs(bio_err, trustfile, FORMAT_PEM, + trusted = load_certs(trustfile, FORMAT_PEM, NULL, e, "trusted certificates"); if (!trusted) goto end; } if (crlfile) { - crls = load_crls(bio_err, crlfile, FORMAT_PEM, NULL, e, "other CRLs"); + crls = load_crls(crlfile, FORMAT_PEM, NULL, e, "other CRLs"); if (!crls) goto end; } if (crl_download) - store_setup_crl_download(cert_ctx); + store_setup_crl_download(store); ret = 0; if (argc < 1) { - if (1 != - check(cert_ctx, NULL, untrusted, trusted, crls, e, show_chain)) + if (check(store, NULL, untrusted, trusted, crls, e, show_chain) != 1) ret = -1; } else { for (i = 0; i < argc; i++) - if (1 != - check(cert_ctx, argv[i], untrusted, trusted, crls, e, - show_chain)) + if (check(store, argv[i], untrusted, trusted, crls, e, + show_chain) != 1) ret = -1; } end: - if (ret == 1) { - BIO_printf(bio_err, - "usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-purpose purpose] [-crl_check] [-no_alt_chains]"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, " [-engine e]"); -#endif - BIO_printf(bio_err, " cert1 cert2 ...\n"); - - BIO_printf(bio_err, "recognized usages:\n"); - for (i = 0; i < X509_PURPOSE_get_count(); i++) { - X509_PURPOSE *ptmp; - ptmp = X509_PURPOSE_get0(i); - BIO_printf(bio_err, "\t%-10s\t%s\n", - X509_PURPOSE_get0_sname(ptmp), - X509_PURPOSE_get0_name(ptmp)); - } - - BIO_printf(bio_err, "recognized verify names:\n"); - for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) { - const X509_VERIFY_PARAM *vptmp; - vptmp = X509_VERIFY_PARAM_get0(i); - BIO_printf(bio_err, "\t%-10s\n", - X509_VERIFY_PARAM_get0_name(vptmp)); - } - - } if (vpm) X509_VERIFY_PARAM_free(vpm); - if (cert_ctx != NULL) - X509_STORE_free(cert_ctx); + if (store != NULL) + X509_STORE_free(store); sk_X509_pop_free(untrusted, X509_free); sk_X509_pop_free(trusted, X509_free); sk_X509_CRL_pop_free(crls, X509_CRL_free); - apps_shutdown(); - OPENSSL_EXIT(ret < 0 ? 2 : ret); + return (ret < 0 ? 2 : ret); } static int check(X509_STORE *ctx, char *file, @@ -280,10 +243,10 @@ static int check(X509_STORE *ctx, char *file, X509_STORE_CTX *csc; STACK_OF(X509) *chain = NULL; - x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file"); + x = load_cert(file, FORMAT_PEM, NULL, e, "certificate file"); if (x == NULL) goto end; - fprintf(stdout, "%s: ", (file == NULL) ? "stdin" : file); + printf("%s: ", (file == NULL) ? "stdin" : file); csc = X509_STORE_CTX_new(); if (csc == NULL) { @@ -307,7 +270,7 @@ static int check(X509_STORE *ctx, char *file, ret = 0; end: if (i > 0) { - fprintf(stdout, "OK\n"); + printf("OK\n"); ret = 1; } else ERR_print_errors(bio_err); @@ -348,7 +311,7 @@ static int cb(int ok, X509_STORE_CTX *ctx) X509_verify_cert_error_string(cert_error)); switch (cert_error) { case X509_V_ERR_NO_EXPLICIT_POLICY: - policies_print(NULL, ctx); + policies_print(bio_err, ctx); case X509_V_ERR_CERT_HAS_EXPIRED: /* @@ -373,7 +336,7 @@ static int cb(int ok, X509_STORE_CTX *ctx) } if (cert_error == X509_V_OK && ok == 2) - policies_print(NULL, ctx); + policies_print(bio_out, ctx); if (!v_verbose) ERR_clear_error(); return (ok); diff --git a/apps/version.c b/apps/version.c index 8807d4c7b0..1fa7cfe536 100644 --- a/apps/version.c +++ b/apps/version.c @@ -1,4 +1,3 @@ -/* apps/version.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -132,45 +131,66 @@ # include #endif -#undef PROG -#define PROG version_main +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_B, OPT_D, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A +} OPTION_CHOICE; -int MAIN(int, char **); +OPTIONS version_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"a", OPT_A, '-', "Show all data"}, + {"b", OPT_B, '-', "Show build date"}, + {"d", OPT_D, '-', "Show configuration directory"}, + {"f", OPT_F, '-', "Show compiler flags used"}, + {"o", OPT_O, '-', "Show some internal datatype options"}, + {"p", OPT_P, '-', "Show target build platform"}, + {"v", OPT_V, '-', "Show library version"}, + {NULL} +}; -int MAIN(int argc, char **argv) +int version_main(int argc, char **argv) { - int i, ret = 0; + int ret = 1, dirty = 0; int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0; + char *prog; + OPTION_CHOICE o; - apps_startup(); - - if (bio_err == NULL) - if ((bio_err = BIO_new(BIO_s_file())) != NULL) - BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); - - if (argc == 1) - version = 1; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-v") == 0) - version = 1; - else if (strcmp(argv[i], "-b") == 0) - date = 1; - else if (strcmp(argv[i], "-f") == 0) - cflags = 1; - else if (strcmp(argv[i], "-o") == 0) - options = 1; - else if (strcmp(argv[i], "-p") == 0) - platform = 1; - else if (strcmp(argv[i], "-d") == 0) - dir = 1; - else if (strcmp(argv[i], "-a") == 0) - date = version = cflags = options = platform = dir = 1; - else { - BIO_printf(bio_err, "usage:version -[avbofpd]\n"); - ret = 1; + prog = opt_init(argc, argv, version_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; + case OPT_HELP: + opt_help(version_options); + ret = 0; + goto end; + case OPT_B: + dirty = date = 1; + break; + case OPT_D: + dirty = dir = 1; + break; + case OPT_F: + dirty = cflags = 1; + break; + case OPT_O: + dirty = options = 1; + break; + case OPT_P: + dirty = platform = 1; + break; + case OPT_V: + dirty = version = 1; + break; + case OPT_A: + cflags = version = date = platform = dir = 1; + break; } } + if (!dirty) + version = 1; if (version) { if (SSLeay() == SSLEAY_VERSION_NUMBER) { @@ -208,7 +228,7 @@ int MAIN(int argc, char **argv) printf("%s\n", SSLeay_version(SSLEAY_CFLAGS)); if (dir) printf("%s\n", SSLeay_version(SSLEAY_DIR)); + ret = 0; end: - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } diff --git a/apps/vms_decc_init.c b/apps/vms_decc_init.c index 3b6de11978..3c953aa361 100644 --- a/apps/vms_decc_init.c +++ b/apps/vms_decc_init.c @@ -1,3 +1,55 @@ +/* + * Written by sms and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + #if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \ defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000) # define USE_DECC_INIT 1 @@ -5,17 +57,11 @@ #ifdef USE_DECC_INIT -/*- - * 2010-04-26 SMS. - * - *---------------------------------------------------------------------- - * - * decc_init() - * - * On non-VAX systems, uses LIB$INITIALIZE to set a collection of C - * RTL features without using the DECC$* logical name method. - * - *---------------------------------------------------------------------- +/* + * ---------------------------------------------------------------------- + * decc_init() On non-VAX systems, uses LIB$INITIALIZE to set a collection + * of C RTL features without using the DECC$* logical name method. + * ---------------------------------------------------------------------- */ # include @@ -57,6 +103,42 @@ decc_feat_t decc_feat_array[] = { {(char *)NULL, 0} }; +char **copy_argv(int *argc, char *argv[]) +{ + /*- + * The note below is for historical purpose. On VMS now we always + * copy argv "safely." + * + * 2011-03-22 SMS. + * If we have 32-bit pointers everywhere, then we're safe, and + * we bypass this mess, as on non-VMS systems. + * Problem 1: Compaq/HP C before V7.3 always used 32-bit + * pointers for argv[]. + * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers + * everywhere else, we always allocate and use a 64-bit + * duplicate of argv[]. + * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed + * to NULL-terminate a 64-bit argv[]. (As this was written, the + * compiler ECO was available only on IA64.) + * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a + * 64-bit argv[argc] for NULL, and, if necessary, use a + * (properly) NULL-terminated (64-bit) duplicate of argv[]. + * The same code is used in either case to duplicate argv[]. + * Some of these decisions could be handled in preprocessing, + * but the code tends to get even uglier, and the penalty for + * deciding at compile- or run-time is tiny. + */ + + int i, count = *argc; + char **newargv = (char **)OPENSSL_malloc((count + 1) * sizeof *newargv); + + for (i = 0; i < count; i++) + newargv[i] = argv[i]; + newargv[i] = NULL; + *argc = i; + return newargv; +} + /* LIB$INITIALIZE initialization function. */ static void decc_init(void) diff --git a/apps/winrand.c b/apps/winrand.c index 44f57a38ba..a5fe791037 100644 --- a/apps/winrand.c +++ b/apps/winrand.c @@ -1,4 +1,3 @@ -/* apps/winrand.c */ /* ==================================================================== * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. * diff --git a/apps/x509.c b/apps/x509.c index 380f0f0be7..903e6b94b9 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -1,4 +1,3 @@ -/* apps/x509.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -77,82 +76,10 @@ # include #endif -#undef PROG -#define PROG x509_main - #undef POSTFIX #define POSTFIX ".srl" #define DEF_DAYS 30 -static const char *x509_usage[] = { - "usage: x509 args\n", - " -inform arg - input format - default PEM (one of DER, NET or PEM)\n", - " -outform arg - output format - default PEM (one of DER, NET or PEM)\n", - " -keyform arg - private key format - default PEM\n", - " -CAform arg - CA format - default PEM\n", - " -CAkeyform arg - CA key format - default PEM\n", - " -in arg - input file - default stdin\n", - " -out arg - output file - default stdout\n", - " -passin arg - private key password source\n", - " -serial - print serial number value\n", - " -subject_hash - print subject hash value\n", -#ifndef OPENSSL_NO_MD5 - " -subject_hash_old - print old-style (MD5) subject hash value\n", -#endif - " -issuer_hash - print issuer hash value\n", -#ifndef OPENSSL_NO_MD5 - " -issuer_hash_old - print old-style (MD5) issuer hash value\n", -#endif - " -hash - synonym for -subject_hash\n", - " -subject - print subject DN\n", - " -issuer - print issuer DN\n", - " -email - print email address(es)\n", - " -startdate - notBefore field\n", - " -enddate - notAfter field\n", - " -purpose - print out certificate purposes\n", - " -dates - both Before and After dates\n", - " -modulus - print the RSA key modulus\n", - " -pubkey - output the public key\n", - " -fingerprint - print the certificate fingerprint\n", - " -alias - output certificate alias\n", - " -noout - no certificate output\n", - " -ocspid - print OCSP hash values for the subject name and public key\n", - " -ocsp_uri - print OCSP Responder URL(s)\n", - " -trustout - output a \"trusted\" certificate\n", - " -clrtrust - clear all trusted purposes\n", - " -clrreject - clear all rejected purposes\n", - " -addtrust arg - trust certificate for a given purpose\n", - " -addreject arg - reject certificate for a given purpose\n", - " -setalias arg - set certificate alias\n", - " -days arg - How long till expiry of a signed certificate - def 30 days\n", - " -checkend arg - check whether the cert expires in the next arg seconds\n", - " exit 1 if so, 0 if not\n", - " -signkey arg - self sign cert with arg\n", - " -x509toreq - output a certification request object\n", - " -req - input is a certificate request, sign and output.\n", - " -CA arg - set the CA certificate, must be PEM format.\n", - " -CAkey arg - set the CA key, must be PEM format\n", - " missing, it is assumed to be in the CA file.\n", - " -CAcreateserial - create serial number file if it does not exist\n", - " -CAserial arg - serial file\n", - " -set_serial - serial number to use\n", - " -text - print the certificate in text form\n", - " -C - print out C code forms\n", - " -md2/-md5/-sha1/-mdc2 - digest to use\n", - " -extfile - configuration file with X509V3 extensions to add\n", - " -extensions - section from config file with X509V3 extensions to add\n", - " -clrext - delete extensions before signing and input certificate\n", - " -nameopt arg - various certificate name options\n", -#ifndef OPENSSL_NO_ENGINE - " -engine e - use engine e, possibly a hardware device.\n", -#endif - " -certopt arg - various certificate text options\n", - " -checkhost host - check certificate matches \"host\"\n", - " -checkemail email - check certificate matches \"email\"\n", - " -checkip ipaddr - check certificate matches \"ipaddr\"\n", - NULL -}; - static int callb(int ok, X509_STORE_CTX *ctx); static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, CONF *conf, char *section); @@ -160,347 +87,425 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, char *serial, int create, int days, int clrext, CONF *conf, - char *section, ASN1_INTEGER *sno); + char *section, ASN1_INTEGER *sno, int reqfile); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); -static int reqfile = 0; + #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL static int force_version = 2; #endif -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, + OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, + OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, + OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY, + OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT, + OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, + OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH, + OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES, + OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST, + OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST, + OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID, +#ifndef OPENSSL_NO_MD5 + OPT_SUBJECT_HASH_OLD, + OPT_ISSUER_HASH_OLD, +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + OPT_FORCE_VERSION, +#endif + OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT +} OPTION_CHOICE; + +OPTIONS x509_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'f', + "Input format - default PEM (one of DER, NET or PEM)"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"outform", OPT_OUTFORM, 'f', + "Output format - default PEM (one of DER, NET or PEM)"}, + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, + {"passin", OPT_PASSIN, 's', "Private key password source"}, + {"serial", OPT_SERIAL, '-', "Print serial number value"}, + {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, + {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, +#ifndef OPENSSL_NO_MD5 + {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', + "Print old-style (MD5) issuer hash value"}, + {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', + "Print old-style (MD5) subject hash value"}, +#endif + {"hash", OPT_HASH, '-', "Synonym for -subject_hash"}, + {"subject", OPT_SUBJECT, '-', "Print subject DN"}, + {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, + {"email", OPT_EMAIL, '-', "Print email address(es)"}, + {"startdate", OPT_STARTDATE, '-', "Set notBefore field"}, + {"enddate", OPT_ENDDATE, '-', "Set notAfter field"}, + {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"}, + {"dates", OPT_DATES, '-', "Both Before and After dates"}, + {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, + {"pubkey", OPT_PUBKEY, '-', "Output the public key"}, + {"fingerprint", OPT_FINGERPRINT, '-', + "Print the certificate fingerprint"}, + {"alias", OPT_ALIAS, '-', "Output certificate alias"}, + {"noout", OPT_NOOUT, '-', "No output, just status"}, + {"nocert", OPT_NOCERT, '-', "No certificate output"}, + {"ocspid", OPT_OCSPID, '-', + "Print OCSP hash values for the subject name and public key"}, + {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"}, + {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"}, + {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"}, + {"clrext", OPT_CLREXT, '-', "Clear all rejected purposes"}, + {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"}, + {"addreject", OPT_ADDREJECT, 's', + "Reject certificate for a given purpose"}, + {"setalias", OPT_SETALIAS, 's', "Set certificate alias"}, + {"days", OPT_DAYS, 'n', + "How long till expiry of a signed certificate - def 30 days"}, + {"checkend", OPT_CHECKEND, 'p', + "Check whether the cert expires in the next arg seconds"}, + {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, + {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"}, + {"x509toreq", OPT_X509TOREQ, '-', + "Output a certification request object"}, + {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, + {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, + {"CAkey", OPT_CAKEY, '<', + "The CA key, must be PEM format; if not in CAfile"}, + {"CAcreateserial", OPT_CACREATESERIAL, '-', + "Create serial number file if it does not exist"}, + {"CAserial", OPT_CASERIAL, '<', "Serial file"}, + {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, + {"text", OPT_TEXT, '-', "Print the certificate in text form"}, + {"C", OPT_C, '-', "Print out C code forms"}, + {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"}, + {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"}, + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"certopt", OPT_CERTOPT, 's', "Various certificate text options"}, + {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"}, + {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"}, + {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"}, + {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, + {"CAkeyform", OPT_CAKEYFORM, 'F', "CA key format - default PEM"}, + {"sigopt", OPT_SIGOPT, 's'}, + {"force_pubkey", OPT_FORCE_PUBKEY, '<'}, + {"next_serial", OPT_NEXT_SERIAL, '-'}, + {"clrreject", OPT_CLRREJECT, '-'}, + {"badsig", OPT_BADSIG, '-'}, + {"", OPT_MD, '-', "Any supported digest"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + {"force_version", OPT_FORCE_VERSION, 'p'}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int x509_main(int argc, char **argv) { - ENGINE *e = NULL; - int ret = 1; - X509_REQ *req = NULL; - X509 *x = NULL, *xca = NULL; - ASN1_OBJECT *objtmp; - STACK_OF(OPENSSL_STRING) *sigopts = NULL; - EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; ASN1_INTEGER *sno = NULL; - int i, num, badops = 0, badsig = 0; + ASN1_OBJECT *objtmp; BIO *out = NULL; - BIO *STDout = NULL; + CONF *extconf = NULL; + EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; - int informat, outformat, keyformat, CAformat, CAkeyformat; + STACK_OF(OPENSSL_STRING) *sigopts = NULL; + X509 *x = NULL, *xca = NULL; + X509_REQ *req = NULL, *rq = NULL; + X509_STORE *ctx = NULL; + const EVP_MD *digest = NULL; + char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; + char *checkhost = NULL, *checkemail = NULL, *checkip = NULL; + char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; - char *CAkeyfile = NULL, *CAserial = NULL; - char *fkeyfile = NULL; - char *alias = NULL; + char buf[256]; + char *engine = NULL, *prog; + int C = 0, x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = + 0; + int CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; + int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = + 0, checkoffset = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; + int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; + int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; + int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; + int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0, enddate = 0; - int next_serial = 0; - int subject_hash = 0, issuer_hash = 0, ocspid = 0; -#ifndef OPENSSL_NO_MD5 - int subject_hash_old = 0, issuer_hash_old = 0; -#endif - int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; - int ocsp_uri = 0; - int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0; - int C = 0; - int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0; - int pprint = 0; - const char **pp; - X509_STORE *ctx = NULL; - X509_REQ *rq = NULL; - int fingerprint = 0; - char buf[256]; - const EVP_MD *md_alg, *digest = NULL; - CONF *extconf = NULL; - char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; - int need_rand = 0; - int checkend = 0, checkoffset = 0; unsigned long nmflag = 0, certflag = 0; - char *checkhost = NULL; - char *checkemail = NULL; - char *checkip = NULL; + OPTION_CHOICE o; #ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + ENGINE *e = NULL; #endif - - reqfile = 0; - - apps_startup(); - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; - STDout = BIO_new_fp(stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - STDout = BIO_push(tmpbio, STDout); - } +#ifndef OPENSSL_NO_MD5 + int subject_hash_old = 0, issuer_hash_old = 0; #endif - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - keyformat = FORMAT_PEM; - CAformat = FORMAT_PEM; - CAkeyformat = FORMAT_PEM; - ctx = X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx, callb); - argc--; - argv++; - num = 0; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - keyformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-req") == 0) { - reqfile = 1; - need_rand = 1; - } else if (strcmp(*argv, "-CAform") == 0) { - if (--argc < 1) - goto bad; - CAformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-CAkeyform") == 0) { - if (--argc < 1) - goto bad; - CAkeyformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-sigopt") == 0) { - if (--argc < 1) - goto bad; + prog = opt_init(argc, argv, x509_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(x509_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) + goto opthelp; + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + goto opthelp; + break; + case OPT_CAFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) + goto opthelp; + break; + case OPT_CAKEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_REQ: + reqfile = need_rand = 1; + break; + + case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) - goto bad; - } + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto opthelp; + break; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - else if (strcmp(*argv, "-force_version") == 0) { - if (--argc < 1) - goto bad; - force_version = atoi(*(++argv)) - 1; - } + case OPT_FORCE_VERSION: + force_version = atoi(opt_arg()) - 1; + break; #endif - else if (strcmp(*argv, "-days") == 0) { - if (--argc < 1) - goto bad; - days = atoi(*(++argv)); - if (days == 0) { - BIO_printf(bio_err, "bad number of days\n"); - goto bad; - } - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-extfile") == 0) { - if (--argc < 1) - goto bad; - extfile = *(++argv); - } else if (strcmp(*argv, "-extensions") == 0) { - if (--argc < 1) - goto bad; - extsect = *(++argv); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-signkey") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); + case OPT_DAYS: + days = atoi(opt_arg()); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_EXTFILE: + extfile = opt_arg(); + break; + case OPT_EXTENSIONS: + extsect = opt_arg(); + break; + case OPT_SIGNKEY: + keyfile = opt_arg(); sign_flag = ++num; need_rand = 1; - } else if (strcmp(*argv, "-CA") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); + break; + case OPT_CA: + CAfile = opt_arg(); CA_flag = ++num; need_rand = 1; - } else if (strcmp(*argv, "-CAkey") == 0) { - if (--argc < 1) - goto bad; - CAkeyfile = *(++argv); - } else if (strcmp(*argv, "-CAserial") == 0) { - if (--argc < 1) - goto bad; - CAserial = *(++argv); - } else if (strcmp(*argv, "-set_serial") == 0) { - if (--argc < 1) - goto bad; - if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) - goto bad; - } else if (strcmp(*argv, "-force_pubkey") == 0) { - if (--argc < 1) - goto bad; - fkeyfile = *(++argv); - } else if (strcmp(*argv, "-addtrust") == 0) { - if (--argc < 1) - goto bad; - if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { - BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); - goto bad; + break; + case OPT_CAKEY: + CAkeyfile = opt_arg(); + break; + case OPT_CASERIAL: + CAserial = opt_arg(); + break; + case OPT_SET_SERIAL: + if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) + goto opthelp; + break; + case OPT_FORCE_PUBKEY: + fkeyfile = opt_arg(); + break; + case OPT_ADDTRUST: + if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { + BIO_printf(bio_err, + "%s: Invalid trust object value %s\n", + prog, opt_arg()); + goto opthelp; } - if (!trust) - trust = sk_ASN1_OBJECT_new_null(); + if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; - } else if (strcmp(*argv, "-addreject") == 0) { - if (--argc < 1) - goto bad; - if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { + break; + case OPT_ADDREJECT: + if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, - "Invalid reject object value %s\n", *argv); - goto bad; + "%s: Invalid reject object value %s\n", + prog, opt_arg()); + goto opthelp; } - if (!reject) - reject = sk_ASN1_OBJECT_new_null(); + if (reject == NULL + && (reject = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; - } else if (strcmp(*argv, "-setalias") == 0) { - if (--argc < 1) - goto bad; - alias = *(++argv); + break; + case OPT_SETALIAS: + alias = opt_arg(); trustout = 1; - } else if (strcmp(*argv, "-certopt") == 0) { - if (--argc < 1) - goto bad; - if (!set_cert_ex(&certflag, *(++argv))) - goto bad; - } else if (strcmp(*argv, "-nameopt") == 0) { - if (--argc < 1) - goto bad; - if (!set_name_ex(&nmflag, *(++argv))) - goto bad; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else if (strcmp(*argv, "-C") == 0) + break; + case OPT_CERTOPT: + if (!set_cert_ex(&certflag, opt_arg())) + goto opthelp; + break; + case OPT_NAMEOPT: + if (!set_name_ex(&nmflag, opt_arg())) + goto opthelp; + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_C: C = ++num; - else if (strcmp(*argv, "-email") == 0) + break; + case OPT_EMAIL: email = ++num; - else if (strcmp(*argv, "-ocsp_uri") == 0) + break; + case OPT_OCSP_URI: ocsp_uri = ++num; - else if (strcmp(*argv, "-serial") == 0) + break; + case OPT_SERIAL: serial = ++num; - else if (strcmp(*argv, "-next_serial") == 0) + break; + case OPT_NEXT_SERIAL: next_serial = ++num; - else if (strcmp(*argv, "-modulus") == 0) + break; + case OPT_MODULUS: modulus = ++num; - else if (strcmp(*argv, "-pubkey") == 0) + break; + case OPT_PUBKEY: pubkey = ++num; - else if (strcmp(*argv, "-x509toreq") == 0) + break; + case OPT_X509TOREQ: x509req = ++num; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = ++num; - else if (strcmp(*argv, "-hash") == 0 - || strcmp(*argv, "-subject_hash") == 0) - subject_hash = ++num; -#ifndef OPENSSL_NO_MD5 - else if (strcmp(*argv, "-subject_hash_old") == 0) - subject_hash_old = ++num; -#endif - else if (strcmp(*argv, "-issuer_hash") == 0) - issuer_hash = ++num; -#ifndef OPENSSL_NO_MD5 - else if (strcmp(*argv, "-issuer_hash_old") == 0) - issuer_hash_old = ++num; -#endif - else if (strcmp(*argv, "-subject") == 0) + break; + case OPT_SUBJECT: subject = ++num; - else if (strcmp(*argv, "-issuer") == 0) + break; + case OPT_ISSUER: issuer = ++num; - else if (strcmp(*argv, "-fingerprint") == 0) + break; + case OPT_FINGERPRINT: fingerprint = ++num; - else if (strcmp(*argv, "-dates") == 0) { - startdate = ++num; - enddate = ++num; - } else if (strcmp(*argv, "-purpose") == 0) + break; + case OPT_HASH: + subject_hash = ++num; + break; + case OPT_ISSUER_HASH: + issuer_hash = ++num; + break; + case OPT_PURPOSE: pprint = ++num; - else if (strcmp(*argv, "-startdate") == 0) + break; + case OPT_STARTDATE: startdate = ++num; - else if (strcmp(*argv, "-enddate") == 0) + break; + case OPT_ENDDATE: enddate = ++num; - else if (strcmp(*argv, "-checkend") == 0) { - if (--argc < 1) - goto bad; - checkoffset = atoi(*(++argv)); - checkend = 1; - } else if (strcmp(*argv, "-checkhost") == 0) { - if (--argc < 1) - goto bad; - checkhost = *(++argv); - } else if (strcmp(*argv, "-checkemail") == 0) { - if (--argc < 1) - goto bad; - checkemail = *(++argv); - } else if (strcmp(*argv, "-checkip") == 0) { - if (--argc < 1) - goto bad; - checkip = *(++argv); - } else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = ++num; - else if (strcmp(*argv, "-trustout") == 0) + break; + case OPT_NOCERT: + nocert = 1; + break; + case OPT_TRUSTOUT: trustout = 1; - else if (strcmp(*argv, "-clrtrust") == 0) + break; + case OPT_CLRTRUST: clrtrust = ++num; - else if (strcmp(*argv, "-clrreject") == 0) + break; + case OPT_CLRREJECT: clrreject = ++num; - else if (strcmp(*argv, "-alias") == 0) + break; + case OPT_ALIAS: aliasout = ++num; - else if (strcmp(*argv, "-CAcreateserial") == 0) + break; + case OPT_CACREATESERIAL: CA_createserial = ++num; - else if (strcmp(*argv, "-clrext") == 0) + break; + case OPT_CLREXT: clrext = 1; - else if (strcmp(*argv, "-ocspid") == 0) + break; + case OPT_OCSPID: ocspid = ++num; - else if (strcmp(*argv, "-badsig") == 0) + break; + case OPT_BADSIG: badsig = 1; - else if ((md_alg = EVP_get_digestbyname(*argv + 1))) { - /* ok */ - digest = md_alg; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; +#ifndef OPENSSL_NO_MD5 + case OPT_SUBJECT_HASH_OLD: + subject_hash_old = ++num; + break; + case OPT_ISSUER_HASH_OLD: + issuer_hash_old = ++num; + break; +#endif + case OPT_DATES: + startdate = ++num; + enddate = ++num; + break; + case OPT_CHECKEND: + checkoffset = atoi(opt_arg()); + checkend = 1; + break; + case OPT_CHECKHOST: + checkhost = opt_arg(); + break; + case OPT_CHECKEMAIL: + checkemail = opt_arg(); + break; + case OPT_CHECKIP: + checkip = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_unknown(), &digest)) + goto opthelp; } - argc--; - argv++; + } + argc = opt_num_rest(); + argv = opt_rest(); + if (argc != 0) { + BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); + goto opthelp; } - if (badops) { - bad: - for (pp = x509_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } + #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif if (need_rand) - app_RAND_load_file(NULL, bio_err, 0); - - ERR_load_crypto_strings(); + app_RAND_load_file(NULL, 0); - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -511,8 +516,7 @@ int MAIN(int argc, char **argv) } if (fkeyfile) { - fkey = load_pubkey(bio_err, fkeyfile, keyformat, 0, - NULL, e, "Forced key"); + fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); if (fkey == NULL) goto end; } @@ -564,21 +568,9 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } - in = BIO_new(BIO_s_file()); - if (in == NULL) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, "r"); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - BIO_free(in); - goto end; - } - } req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); @@ -646,12 +638,12 @@ int MAIN(int argc, char **argv) EVP_PKEY_free(pkey); } } else - x = load_cert(bio_err, infile, informat, NULL, e, "Certificate"); + x = load_cert(infile, informat, NULL, e, "Certificate"); if (x == NULL) goto end; if (CA_flag) { - xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate"); + xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate"); if (xca == NULL) goto end; } @@ -659,25 +651,6 @@ int MAIN(int argc, char **argv) if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); - goto end; - } - if (outfile == NULL) { - BIO_set_fp(out, stdout, BIO_NOCLOSE); -#ifdef OPENSSL_SYS_VMS - { - BIO *tmpbio = BIO_new(BIO_f_linebuffer()); - out = BIO_push(tmpbio, out); - } -#endif - } else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - goto end; - } - } } if (alias) @@ -705,15 +678,14 @@ int MAIN(int argc, char **argv) if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { - print_name(STDout, "issuer= ", - X509_get_issuer_name(x), nmflag); + print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { - print_name(STDout, "subject= ", + print_name(out, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { - BIO_printf(STDout, "serial="); - i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x)); - BIO_printf(STDout, "\n"); + BIO_printf(out, "serial="); + i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); + BIO_printf(out, "\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; @@ -738,39 +710,39 @@ int MAIN(int argc, char **argv) else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) - BIO_printf(STDout, "%s\n", + BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) - BIO_printf(STDout, "%s\n", alstr); + BIO_printf(out, "%s\n", alstr); else - BIO_puts(STDout, "\n"); + BIO_puts(out, "\n"); } else if (subject_hash == i) { - BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x)); + BIO_printf(out, "%08lx\n", X509_subject_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (subject_hash_old == i) { - BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x)); + BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { - BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x)); + BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x)); } #ifndef OPENSSL_NO_MD5 else if (issuer_hash_old == i) { - BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x)); + BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; - BIO_printf(STDout, "Certificate purposes:\n"); + BIO_printf(out, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); - purpose_print(STDout, x, ptmp); + purpose_print(out, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; @@ -781,19 +753,19 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - BIO_printf(STDout, "Modulus="); + BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) - BN_print(STDout, pkey->pkey.rsa->n); + BN_print(out, pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) - BN_print(STDout, pkey->pkey.dsa->pub_key); + BN_print(out, pkey->pkey.dsa->pub_key); else #endif - BIO_printf(STDout, "Wrong Algorithm type"); - BIO_printf(STDout, "\n"); + BIO_printf(out, "Wrong Algorithm type"); + BIO_printf(out, "\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; @@ -804,77 +776,48 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - PEM_write_bio_PUBKEY(STDout, pkey); + PEM_write_bio_PUBKEY(out, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; - int y, z; + int len; X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf); - BIO_printf(STDout, "/* subject:%s */\n", buf); - m = X509_NAME_oneline(X509_get_issuer_name(x), buf, - sizeof buf); - BIO_printf(STDout, "/* issuer :%s */\n", buf); + BIO_printf(out, "/*\n" + " * Subject: %s\n", buf); + + m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); + BIO_printf(out, " * Issuer: %s\n" + " */\n", buf); - z = i2d_X509(x, NULL); - m = OPENSSL_malloc(z); + len = i2d_X509(x, NULL); + m = OPENSSL_malloc(len); if (!m) { BIO_printf(bio_err, "Out of memory\n"); - ERR_print_errors(bio_err); goto end; } d = (unsigned char *)m; - z = i2d_X509_NAME(X509_get_subject_name(x), &d); - BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n", - z); - d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - - z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); - BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z); + len = i2d_X509_NAME(X509_get_subject_name(x), &d); + print_array(out, "the_subject_name", len, (unsigned char *)m); d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - - z = i2d_X509(x, &d); - BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n", - z); + len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); + print_array(out, "the_public_key", len, (unsigned char *)m); d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - + len = i2d_X509(x, &d); + print_array(out, "the_certificate", len, (unsigned char *)m); OPENSSL_free(m); } else if (text == i) { - X509_print_ex(STDout, x, nmflag, certflag); + X509_print_ex(out, x, nmflag, certflag); } else if (startdate == i) { - BIO_puts(STDout, "notBefore="); - ASN1_TIME_print(STDout, X509_get_notBefore(x)); - BIO_puts(STDout, "\n"); + BIO_puts(out, "notBefore="); + ASN1_TIME_print(out, X509_get_notBefore(x)); + BIO_puts(out, "\n"); } else if (enddate == i) { - BIO_puts(STDout, "notAfter="); - ASN1_TIME_print(STDout, X509_get_notAfter(x)); - BIO_puts(STDout, "\n"); + BIO_puts(out, "notAfter="); + ASN1_TIME_print(out, X509_get_notAfter(x)); + BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; unsigned int n; @@ -888,10 +831,10 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "out of memory\n"); goto end; } - BIO_printf(STDout, "%s Fingerprint=", + BIO_printf(out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j = 0; j < (int)n; j++) { - BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n) + BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } @@ -900,8 +843,7 @@ int MAIN(int argc, char **argv) else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { - Upkey = load_key(bio_err, - keyfile, keyformat, 0, + Upkey = load_key(keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; @@ -913,8 +855,7 @@ int MAIN(int argc, char **argv) } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { - CApkey = load_key(bio_err, - CAkeyfile, CAkeyformat, + CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; @@ -924,7 +865,7 @@ int MAIN(int argc, char **argv) if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, - extconf, extsect, sno)) + extconf, extsect, sno, reqfile)) goto end; } else if (x509req == i) { EVP_PKEY *pk; @@ -934,8 +875,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "no request key file specified\n"); goto end; } else { - pk = load_key(bio_err, - keyfile, keyformat, 0, + pk = load_key(keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; @@ -973,9 +913,9 @@ int MAIN(int argc, char **argv) goto end; } - print_cert_checks(STDout, x, checkhost, checkemail, checkip); + print_cert_checks(out, x, checkhost, checkemail, checkip); - if (noout) { + if (noout || nocert) { ret = 0; goto end; } @@ -1012,11 +952,10 @@ int MAIN(int argc, char **argv) ret = 0; end: if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); - BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); @@ -1032,8 +971,7 @@ int MAIN(int argc, char **argv) sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, @@ -1087,7 +1025,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, STACK_OF(OPENSSL_STRING) *sigopts, char *serialfile, int create, int days, int clrext, CONF *conf, char *section, - ASN1_INTEGER *sno) + ASN1_INTEGER *sno, int reqfile) { int ret = 0; ASN1_INTEGER *bs = NULL; @@ -1154,7 +1092,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; } - if (!do_X509_sign(bio_err, x, pkey, digest, sigopts)) + if (!do_X509_sign(x, pkey, digest, sigopts)) goto end; ret = 1; end: @@ -1204,22 +1142,11 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, CONF *conf, char *section) { - EVP_PKEY *pktmp; - - pktmp = X509_get_pubkey(x); - EVP_PKEY_copy_parameters(pktmp, pkey); - EVP_PKEY_save_parameters(pktmp, 1); - EVP_PKEY_free(pktmp); - if (!X509_set_issuer_name(x, X509_get_subject_name(x))) goto err; if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) goto err; - /* Lets just make it 12:00am GMT, Jan 1 1970 */ - /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */ - /* 28 days to be certified */ - if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) == NULL) goto err; diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index 7ae36d7da6..0a889ef263 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -94,6 +94,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_des_ede()); EVP_add_cipher(EVP_des_ede3()); EVP_add_cipher(EVP_des_ede3_wrap()); + EVP_add_cipher_alias(SN_id_smime_alg_CMS3DESwrap, "des3-wrap"); #endif #ifndef OPENSSL_NO_RC4 @@ -131,6 +132,9 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_rc2_64_cbc()); EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); + EVP_add_cipher_alias(SN_rc2_cbc, "rc2-128"); + EVP_add_cipher_alias(SN_rc2_64_cbc, "rc2-64"); + EVP_add_cipher_alias(SN_rc2_40_cbc, "rc2-40"); #endif #ifndef OPENSSL_NO_BF @@ -178,6 +182,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_128_xts()); EVP_add_cipher(EVP_aes_128_ccm()); EVP_add_cipher(EVP_aes_128_wrap()); + EVP_add_cipher_alias(SN_id_aes128_wrap, "aes128-wrap"); EVP_add_cipher(EVP_aes_128_wrap_pad()); EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); @@ -194,6 +199,7 @@ void OpenSSL_add_all_ciphers(void) # endif EVP_add_cipher(EVP_aes_192_ccm()); EVP_add_cipher(EVP_aes_192_wrap()); + EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap"); EVP_add_cipher(EVP_aes_192_wrap_pad()); EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); @@ -211,6 +217,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_256_xts()); EVP_add_cipher(EVP_aes_256_ccm()); EVP_add_cipher(EVP_aes_256_wrap()); + EVP_add_cipher_alias(SN_id_aes256_wrap, "aes256-wrap"); EVP_add_cipher(EVP_aes_256_wrap_pad()); EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 43821f6f37..97b4fb9414 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -192,6 +192,7 @@ static int ssl_set_option_list(const char *elem, int len, void *usr) /* Single command line switches with no argument e.g. -no_ssl3 */ static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) { + /* See apps/apps.h if you change this table. */ static const ssl_flag_tbl ssl_option_single[] = { SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1), @@ -457,6 +458,7 @@ typedef struct { #define SSL_CONF_CMD_STRING(name, cmdopt) \ SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING) +/* See apps/apps.h if you change this table. */ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"), SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"), diff --git a/util/indent.pro b/util/indent.pro index e8714310cc..c2427a3379 100644 --- a/util/indent.pro +++ b/util/indent.pro @@ -749,3 +749,5 @@ -T ssl_trace_tbl -T _stdcall -T tls12_lookup +-T OPTIONS +-T OPT_PAIR diff --git a/util/ssleay.num b/util/ssleay.num index 7ea4a8a56b..f5f85ab34f 100755 --- a/util/ssleay.num +++ b/util/ssleay.num @@ -393,3 +393,5 @@ SSL_set_wbio 427 EXIST::FUNCTION: SSL_SESSION_get0_ticket 428 EXIST::FUNCTION: SSL_SESSION_get_ticket_lifetime_hint 429 EXIST::FUNCTION: SSL_set_rbio 430 EXIST::FUNCTION: +SSL_CIPHER_get_digest_nid 431 EXIST::FUNCTION: +SSL_CIPHER_get_cipher_nid 432 EXIST::FUNCTION: