Big apps cleanup (option-parsing, etc)
authorRich Salz <rsalz@openssl.org>
Fri, 24 Apr 2015 19:26:15 +0000 (15:26 -0400)
committerRich Salz <rsalz@openssl.org>
Fri, 24 Apr 2015 19:26:15 +0000 (15:26 -0400)
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 <matt@openssl.org>
65 files changed:
apps/Makefile
apps/app_rand.c
apps/apps.c
apps/apps.h
apps/asn1pars.c
apps/ca.c
apps/ciphers.c
apps/cms.c
apps/crl.c
apps/crl2p7.c
apps/dgst.c
apps/dh.c [deleted file]
apps/dhparam.c
apps/dsa.c
apps/dsaparam.c
apps/ec.c
apps/ecparam.c
apps/enc.c
apps/engine.c
apps/errstr.c
apps/gendh.c [deleted file]
apps/gendsa.c
apps/genpkey.c
apps/genrsa.c
apps/makeapps.com
apps/nseq.c
apps/ocsp.c
apps/openssl.c
apps/opt.c [new file with mode: 0644]
apps/passwd.c
apps/pkcs12.c
apps/pkcs7.c
apps/pkcs8.c
apps/pkey.c
apps/pkeyparam.c
apps/pkeyutl.c
apps/prime.c
apps/progs.h
apps/progs.pl
apps/rand.c
apps/req.c
apps/rsa.c
apps/rsautl.c
apps/s_apps.h
apps/s_cb.c
apps/s_client.c
apps/s_server.c
apps/s_socket.c
apps/s_time.c
apps/sess_id.c
apps/smime.c
apps/speed.c
apps/spkac.c
apps/srp.c
apps/testdsa.h
apps/ts.c
apps/verify.c
apps/version.c
apps/vms_decc_init.c
apps/winrand.c
apps/x509.c
crypto/evp/c_allc.c
ssl/ssl_conf.c
util/indent.pro
util/ssleay.num

index c7a6094c309e1b53543f54d0f751e77c8800b1c4..b6f7b2c797bc31b4ee76256083068e06eb3aa44e 100644 (file)
@@ -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
index 595fc7821c85e6d3d0dcefe85a5d0bd993c38eff..906144bb6d718e1b819d341662b1dfdcba2d414b 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/app_rand.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
  *
  */
 
-#define NON_MAIN
 #include "apps.h"
-#undef NON_MAIN
 #include <openssl/bio.h>
 #include <openssl/rand.h>
 
 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;
index 76e0ee3c139bba1245a3207e3d3200945e04ced4..7440d392c4891722d11b3ec2c6f1c4db4d430bfb 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/apps.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #ifndef OPENSSL_NO_JPAKE
 # include <openssl/jpake.h>
 #endif
+#include <openssl/ssl.h>
 
-#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", &timestamp) != 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 <time.h>
 
 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 <time.h>
 
@@ -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)
index 2e346f9b66aa08619bb4a542d3846e003b35854c..ad17b1a82117dc37e3cf6c96ee26c2a12c78542c 100644 (file)
 #  include <openssl/ocsp.h>
 # endif
 # include <openssl/ossl_typ.h>
+# ifndef OPENSSL_SYS_NETWARE
+#  include <signal.h>
+# 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 <signal.h>
-# 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
index 1576f1cc050b052d8613f2a61a6d90ea4800010d..e96491a40cca7780a8e0ea9e36edc0f36f249077 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/asn1pars.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 
-/*-
- * -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] <infile\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, " -in arg       input file\n");
-        BIO_printf(bio_err,
-                   " -out arg      output file (output format is always DER\n");
-        BIO_printf(bio_err, " -noout arg    don't produce any output\n");
-        BIO_printf(bio_err, " -offset arg   offset into file\n");
-        BIO_printf(bio_err, " -length arg   length of section in file\n");
-        BIO_printf(bio_err, " -i            indent entries\n");
-        BIO_printf(bio_err, " -dump         dump unknown data in hex form\n");
-        BIO_printf(bio_err,
-                   " -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
-        BIO_printf(bio_err, " -oid file     file of extra oid definitions\n");
-        BIO_printf(bio_err, " -strparse offset\n");
-        BIO_printf(bio_err,
-                   "               a series of these can be used to 'dig' into multiple\n");
-        BIO_printf(bio_err, "               ASN1 blob wrappings\n");
-        BIO_printf(bio_err,
-                   " -genstr str   string to generate ASN1 structure from\n");
-        BIO_printf(bio_err,
-                   " -genconf file file to generate ASN1 structure from\n");
-        BIO_printf(bio_err,
-                   " -strictpem    do not attempt base64 decode outside PEM markers (-inform \n");
-        BIO_printf(bio_err, "               will be ignored)\n");
-        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;
-    }
-    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
+    argc = opt_num_rest();
+    argv = opt_rest();
 
     if (oidfile != NULL) {
-        if (BIO_read_filename(in, oidfile) <= 0) {
-            BIO_printf(bio_err, "problems opening %s\n", oidfile);
-            ERR_print_errors(bio_err);
+        in = bio_open_default(oidfile, "r");
+        if (in == NULL)
             goto end;
-        }
         OBJ_create_objects(in);
+        BIO_free(in);
     }
 
-    if (infile == NULL)
-        BIO_set_fp(in, stdin, BIO_NOCLOSE);
-    else {
-        if (BIO_read_filename(in, infile) <= 0) {
-            perror(infile);
-            goto end;
-        }
-    }
+    if ((in = bio_open_default(infile, "r")) == NULL)
+        goto end;
 
-    if (derfile) {
-        if (!(derout = BIO_new_file(derfile, "wb"))) {
-            BIO_printf(bio_err, "problems opening %s\n", derfile);
-            ERR_print_errors(bio_err);
-            goto end;
-        }
-    }
+    if (derfile && (derout = bio_open_default(derfile, "wb")) == NULL)
+        goto end;
 
     if (strictpem) {
         if (PEM_read_bio(in, &name, &header, (unsigned char **)&str, &num) !=
@@ -362,7 +307,7 @@ int MAIN(int argc, char **argv)
         }
     }
     if (!noout &&
-        !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length,
+        !ASN1_parse_dump(bio_out, (unsigned char *)&(str[offset]), length,
                          indent, dump)) {
         ERR_print_errors(bio_err);
         goto end;
@@ -371,7 +316,6 @@ int MAIN(int argc, char **argv)
  end:
     BIO_free(derout);
     BIO_free(in);
-    BIO_free_all(out);
     BIO_free(b64);
     if (ret != 0)
         ERR_print_errors(bio_err);
@@ -388,8 +332,7 @@ int MAIN(int argc, char **argv)
     if (osk != NULL)
         sk_OPENSSL_STRING_free(osk);
     OBJ_cleanup();
-    apps_shutdown();
-    OPENSSL_EXIT(ret);
+    return (ret);
 }
 
 static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
index e2eab910335d77a0b4011ba32baecbdef8557390..af3afaabda7d8bf124deba40fc6445d73e4a95ac 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1,4 +1,3 @@
-/* apps/ca.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -96,8 +95,8 @@
 # define R_OK 4
 #endif
 
-#undef PROG
-#define PROG ca_main
+#undef BSIZE
+#define BSIZE 256
 
 #define BASE_SECTION    "ca"
 #define CONFIG_FILE "openssl.cnf"
 #define ENV_CRL_DIR             "crl_dir"
 #define ENV_CA_DB               "CA_DB"
 #define ENV_NEW_CERTS_DIR       "new_certs_dir"
-#define ENV_CERTIFICATE         "certificate"
+#define ENV_CERTIFICATE "certificate"
 #define ENV_SERIAL              "serial"
 #define ENV_CRLNUMBER           "crlnumber"
 #define ENV_CRL                 "crl"
 #define REV_KEY_COMPROMISE      3 /* Value is cert key compromise time */
 #define REV_CA_COMPROMISE       4 /* Value is CA key compromise time */
 
-static const char *ca_usage[] = {
-    "usage: ca args\n",
-    "\n",
-    " -verbose        - Talk a lot while doing things\n",
-    " -config file    - A config file\n",
-    " -name arg       - The particular CA definition to use\n",
-    " -gencrl         - Generate a new CRL\n",
-    " -crldays days   - Days is when the next CRL is due\n",
-    " -crlhours hours - Hours is when the next CRL is due\n",
-    " -startdate YYMMDDHHMMSSZ  - certificate validity notBefore\n",
-    " -enddate YYMMDDHHMMSSZ    - certificate validity notAfter (overrides -days)\n",
-    " -days arg       - number of days to certify the certificate for\n",
-    " -md arg         - md to use, one of md2, md5, sha or sha1\n",
-    " -policy arg     - The CA 'policy' to support\n",
-    " -keyfile arg    - private key file\n",
-    " -keyform arg    - private key file format (PEM or ENGINE)\n",
-    " -key arg        - key to decode the private key if it is encrypted\n",
-    " -cert file      - The CA certificate\n",
-    " -selfsign       - sign a certificate with the key associated with it\n",
-    " -in file        - The input PEM encoded certificate request(s)\n",
-    " -out file       - Where to put the output file(s)\n",
-    " -outdir dir     - Where to put output certificates\n",
-    " -infiles ....   - The last argument, requests to process\n",
-    " -spkac file     - File contains DN and signed public key and challenge\n",
-    " -ss_cert file   - File contains a self signed cert to sign\n",
-    " -preserveDN     - Don't re-order the DN\n",
-    " -noemailDN      - Don't add the EMAIL field into certificate' subject\n",
-    " -batch          - Don't ask questions\n",
-    " -msie_hack      - msie modifications to handle all those universal strings\n",
-    " -revoke file    - Revoke a certificate (given in file)\n",
-    " -subj arg       - Use arg instead of request's subject\n",
-    " -utf8           - input characters are UTF8 (default ASCII)\n",
-    " -multivalue-rdn - enable support for multivalued RDNs\n",
-    " -extensions ..  - Extension section (override value in config file)\n",
-    " -extfile file   - Configuration file with X509v3 extensions to add\n",
-    " -crlexts ..     - CRL extension section (override value in config file)\n",
-#ifndef OPENSSL_NO_ENGINE
-    " -engine e       - use engine e, possibly a hardware device.\n",
-#endif
-    " -status serial  - Shows certificate status given the serial number\n",
-    " -updatedb       - Updates db for expired certificates\n",
-    NULL
-};
-
 #ifdef EFENCE
 extern int EF_PROTECT_FREE;
 extern int EF_PROTECT_BELOW;
@@ -239,97 +194,126 @@ static int check_time_format(const char *str);
 char *make_revocation_str(int rev_type, char *rev_arg);
 int make_revoked(X509_REVOKED *rev, const char *str);
 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
+
 static CONF *conf = NULL;
 static CONF *extconf = NULL;
 static char *section = NULL;
-
 static int preserve = 0;
 static int msie_hack = 0;
 
-int MAIN(int, char **);
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
+    OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
+    OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
+    OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
+    OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
+    OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
+    OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
+    OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
+    OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE,
+    OPT_CRL_CA_COMPROMISE
+} OPTION_CHOICE;
+
+OPTIONS ca_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
+    {"config", OPT_CONFIG, 's', "A config file"},
+    {"name", OPT_NAME, 's', "The particular CA definition to use"},
+    {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"},
+    {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
+    {"create_serial", OPT_CREATE_SERIAL, '-'},
+    {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
+     "Enable support for multivalued RDNs"},
+    {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
+    {"enddate", OPT_ENDDATE, 's',
+     "YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
+    {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
+    {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"},
+    {"policy", OPT_POLICY, 's', "The CA 'policy' to support"},
+    {"keyfile", OPT_KEYFILE, '<', "Private key file"},
+    {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"},
+    {"passin", OPT_PASSIN, 's'},
+    {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"},
+    {"cert", OPT_CERT, '<', "The CA cert"},
+    {"selfsign", OPT_SELFSIGN, '-',
+     "Sign a cert with the key associated with it"},
+    {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"},
+    {"out", OPT_OUT, '>', "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);
index 4b9a114666c027ee5edd3a2eef8a06709e2e4f8b..3d84a2b14e1ac7d07bbffb1c37f126022b7035a6 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/ciphers.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 
-#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);
 }
index 73f9037c041922dd23ea4036f76567594271b5f1..397071ca7f4985758e37f001880a07d8692d83a0 100644 (file)
@@ -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 <openssl/x509v3.h>
 # include <openssl/cms.h>
 
-# 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, &ltmp);
-            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(), &ltmp);
+            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, &ltmp);
-            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(), &ltmp);
+            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;
 
index 6819faa5b9b0fd65689180228250659f2277fedb..b8c592c6e266c6d624b4c6c9f6dbbed4e3c2a76d 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/crl.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
 
-#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);
 }
index 86b3a947606552b36a74524cc6065498bb05c8c6..d75b6674a590166d703008852e46d5b3723647e2 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/crl2p7.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/objects.h>
 
 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] <infile >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;
     }
index 700600011cd486df912469d12ad3a730adacdbdc..21b8c7fc66c7d319d4b012199ddbd1692e2967b4 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/dgst.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #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 (file)
index 1b653f5..0000000
--- 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 <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
-#ifndef OPENSSL_NO_DH
-# include <stdio.h>
-# include <stdlib.h>
-# include <time.h>
-# include <string.h>
-# include "apps.h"
-# include <openssl/bio.h>
-# include <openssl/err.h>
-# include <openssl/bn.h>
-# include <openssl/dh.h>
-# include <openssl/x509.h>
-# include <openssl/pem.h>
-
-# 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] <infile >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
index fc5962a7a1d46867f2257ab75483907af30559bb..e842ca5f20ed5cb5a99a5addba2ca1cbe9a5afac 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/dhparam.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #  include <openssl/dsa.h>
 # 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 <openssl/dh.h>\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 <openssl/dh.h>\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 = '*';
index 1ea0d7346d6fdaf9c67f6eb0e5a74574340f8b87..9d7c97f609a3a4864689557d129c3a18cb8766e6 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/dsa.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/pem.h>
 # include <openssl/bn.h>
 
-# 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] <infile >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 */
 
index f63ecb28ecb6c35e0ae208646313ace4c2d05d07..b3144097625aadce2efff1085efde42fd25347be 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/dsaparam.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/x509.h>
 # include <openssl/pem.h>
 
-# 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 <n> 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] <infile >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 <n> 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)
index aca28540dd4d1a8e6aacc209eb2fe7a46b5566fe..d6bce6d28ae029f00502079eeff6189687ac8975 100644 (file)
--- a/apps/ec.c
+++ b/apps/ec.c
@@ -1,4 +1,3 @@
-/* apps/ec.c */
 /*
  * Written by Nils Larsch for the OpenSSL project.
  */
 # include <openssl/evp.h>
 # include <openssl/pem.h>
 
-# 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] <infile >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 */
 
index c6a175146c1dec1f593a7a874b0a2ef3646e7191..167ef39f6d3d696ff276548943365f9c4b39e49f 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/ecparam.c */
 /*
  * Written by Nils Larsch for the OpenSSL project.
  */
 # include <openssl/x509.h>
 # include <openssl/pem.h>
 
-# 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] <infile >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
index b95a6a2031625c77ac65777d361fdffffb30774b..06b056b45d4cbe22b3b3344866173993d97b419e 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/enc.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #endif
 #include <ctype.h>
 
-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 <file>");
-            BIO_printf(bio_err, "%-14s output file\n", "-out <file>");
-            BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>");
-            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 <n>");
-            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;
index 53864650ac8ad79b1203a505dfb11a2f219fd660..7dcc1b0817ad809094644a7ac628b1d0427b595a 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
 /*
  * Written by Richard Levitte <richard@levitte.org> for the OpenSSL project
  * 2000.
 # include <openssl/engine.h>
 # include <openssl/ssl.h>
 
-# 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 <cmd>  - runs command 'cmd' against the ENGINE before any attempts\n",
-    "               to load it (if -t is used)\n",
-    " -post <cmd> - 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, "<no flags>\n");
+        BIO_printf(out, "<no flags>\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, "  <illegal flags!>");
-    BIO_printf(bio_out, "\n");
+        BIO_printf(out, "  <illegal flags!>");
+    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) ? "<no description>" : 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
 
index 668c5f3024390d0a11964e34984c5d80ecdaa279..960815da65f7101df046093f61913fedeb0e313f 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/errstr.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 
-#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] <errno> ...\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 (file)
index 904bcf3..0000000
+++ /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 <openssl/opensslconf.h>
-
-#ifndef OPENSSL_NO_DH
-# include <stdio.h>
-# include <string.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include "apps.h"
-# include <openssl/bio.h>
-# include <openssl/rand.h>
-# include <openssl/err.h>
-# include <openssl/bn.h>
-# include <openssl/dh.h>
-# include <openssl/x509.h>
-# include <openssl/pem.h>
-
-# 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
index 8288eb90ab01a74ce042ee07b5baecc651acfaac..1eaaa455049e1e96245c4c1ae0167ef036c645e1 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/gendsa.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/pem.h>
 
 # 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 */
 
index bd81d51a220e12afa2abdafa72a86b44b94d158e..5130b40a82cf00862f04eb86f91021af480e03fd 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/genpkey.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2006
 # include <openssl/engine.h>
 #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,
-                   "-<cipher>          use cipher <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 <opt>\n"
-                   "                   to value <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;
 
index cf60219642e622fc36ab4854cc14e11aa3384d35..b7275aef7a866f8bdae0bc62e671db1efd043e63 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/genrsa.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/rand.h>
 
 # 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)
index efc213c8eed0663605e16222734afc4cf73f62ea..2724cc605136f1fa9798bf684b5c91ceadfb8dc2 100644 (file)
@@ -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,"+-
index c3067385d2a0d0baa2388592855b671815133011..3fa496c488b867292bbd0695ddb5569c9b8e757b 100644 (file)
@@ -1,4 +1,3 @@
-/* nseq.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 1999.
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-#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);
 }
index 96f4c67421381010ea4b52af5f964fb68211ca5c..840e506a5cec1078c664caf371c9587e17ab6856 100644 (file)
@@ -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,
-                   "-<dgst alg>          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:
index e93aed702a02f3976f8147f65c2c11836b852716..de73fac7a9429c6b3a752bdce172490722e674c6 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/openssl.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#define OPENSSL_C               /* tells apps.h to use complete
-                                 * apps_startup() */
-#include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #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 <openssl/err.h>
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 #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
  * 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 = "<undefined>";
         if (!to)
             to = "<undefined>";
-        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 (file)
index 0000000..3706739
--- /dev/null
@@ -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 <assert.h>
+#include <string.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+# include OPENSSL_UNISTD
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <openssl/bio.h>
+
+#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 <sys/stat.h>
+
+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
index 2814b32c75e5a0a07c532163357cf757cb25dcdd..3c6fd5204e22afdf74fba18ce229aba587326343 100644 (file)
@@ -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 <openssl/md5.h>
 # 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
index 43892e57985b04b5c8a3e9a486eafe01a7675c01..a031c1ba25ee76154eea223134fb441f25bb8662 100644 (file)
@@ -1,4 +1,3 @@
-/* pkcs12.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
 # include <openssl/pem.h>
 # include <openssl/pkcs12.h>
 
-# 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 : "<stdin>");
-        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 : "<stdout>");
-        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;
index 4fcb089b2b490a72e08404771130c94825f06dba..ca052730ea0c8fd255ee0bcce3e64feebef7f450 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/pkcs7.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
  * 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 <stdio.h>
 #include <stdlib.h>
 #include <openssl/pkcs7.h>
 #include <openssl/pem.h>
 
-#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] <infile >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);
 }
index a56b9f42b13b22b4a69419b9bbfccd42daf1580b..7b361cfec6b823214cbf20a28376eb61e38cb1ec 100644 (file)
@@ -1,4 +1,3 @@
-/* pkcs8.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 1999-2004.
 #include <openssl/evp.h>
 #include <openssl/pkcs12.h>
 
-#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)
index e848049c3a12fa78d1e331d68f5c0fcff153a1c8..3597be0ee6afd83c4a2ce5cda71698c4bd364f6b 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/pkey.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2006
 #include <openssl/err.h>
 #include <openssl/evp.h>
 
-#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;
 
index a148a6621ad85df3323e4fc8ee0dc01cc36e09d7..5a5caf56bda8c58e6f4ca39334d84f4e9a6b9bc6 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/pkeyparam.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2006
 #include <openssl/err.h>
 #include <openssl/evp.h>
 
-#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");
index 10286867385f65acf537e54ae1e7af7744b65d48..942ba05ded03de93bc17f74ae93f3f3643fb5310 100644 (file)
 #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;
 }
 
index 1fb1c8d8455aa342f63a8c7acd21c5a8edd3d44e..04a83ab04ed5d844dd216a36ae3ffd6bc9e9bb91 100644 (file)
 #include "apps.h"
 #include <openssl/bn.h>
 
-#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 <n>");
-    return 1;
+ end:
+    return ret;
 }
index 9a8a1923eee36c9287c7704a01aa84e19dba45ee..33bdef7b27a35f4812ce516ce431449890bd6e9a 100644 (file)
-/* 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
index 09dd00b7ee282fd6b1f63d04270ce3d40081d846..38e091e26eddfd328cb1dc8ed81a3b3478b280ff 100644 (file)
@@ -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";
index 45f16b9094bbcc529901a2c49db4aaf0c5a1cfec..9a73935acc2d3c9793ddd69e8ab7c141777f2d8e 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/rand.c */
 /* ====================================================================
  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
  *
 #include <openssl/err.h>
 #include <openssl/rand.h>
 
-#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);
 }
index 3cedf2c8a666b484afa751ebe676e3f6a4829462..1237c33ec19d10e8b807ccdf6f016dafe4556eb8 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/req.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #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] <infile >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);
index 2f3f871a33378a4c71f03e2c6a053b6bf48bd486..7f7069c899623bf7c0613bb4e732e480ed475ba5 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/rsa.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
  * 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 <openssl/opensslconf.h>
 #ifndef OPENSSL_NO_RSA
 # include <openssl/pem.h>
 # include <openssl/bn.h>
 
-# 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] <infile >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 */
 
index d642f9ad97f3c1b99b404500d1b80a67b85f8085..04667469f6b59a8078f12114c448580c334a8a6a 100644 (file)
@@ -1,4 +1,3 @@
-/* rsautl.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2000.
 # 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
index b0aeeffebfb8ee11f1d7454253c47348b7321e1e..db8d039178490d43e89ab876e9099019a9016c2d 100644 (file)
@@ -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,
index 06050dbc7cbfbbf936722109064ab2048e74e405..ddd65a968db6e0bb405cae03f79581ddd34026f4 100644 (file)
@@ -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.
  *
  *
  */
 
+/* callback functions used by s_client, s_server, and s_time */
 #include <stdio.h>
 #include <stdlib.h>
+#include <assert.h>
 #define USE_SOCKETS
-#define NON_MAIN
 #include "apps.h"
-#undef NON_MAIN
 #undef USE_SOCKETS
 #include <openssl/err.h>
 #include <openssl/rand.h>
@@ -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;
index 761f352fe32c01390d26617c8ca605107039189f..900efe7c86e5a0ccec00fd54dc37164ed6ea91bd 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/s_client.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/e_os2.h>
+
 /*
  * 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, "<stream:stream "
-                   "xmlns:stream='http://etherx.jabber.org/streams' "
-                   "xmlns='jabber:client' to='%s' version='1.0'>", xmpphost ?
-                   xmpphost : host);
-        seen = BIO_read(sbio, mbuf, BUFSIZZ);
-        mbuf[seen] = 0;
-        while (!strstr
-               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
-               && !strstr(mbuf,
-                          "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\""))
+        break;
+    case PROTO_XMPP:
         {
+            int seen = 0;
+            BIO_printf(sbio, "<stream:stream "
+                       "xmlns:stream='http://etherx.jabber.org/streams' "
+                       "xmlns='jabber:client' to='%s' version='1.0'>",
+                       host);
             seen = BIO_read(sbio, mbuf, BUFSIZZ);
+            mbuf[seen] = 0;
+            while (!strstr
+                   (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
+                   && !strstr(mbuf,
+                              "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\""))
+            {
+                seen = BIO_read(sbio, mbuf, BUFSIZZ);
 
-            if (seen <= 0)
-                goto shut;
+                if (seen <= 0)
+                    goto shut;
 
-            mbuf[seen] = 0;
+                mbuf[seen] = 0;
+            }
+            BIO_printf(sbio,
+                       "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+            seen = BIO_read(sbio, sbuf, BUFSIZZ);
+            sbuf[seen] = 0;
+            if (!strstr(sbuf, "<proceed"))
+                goto shut;
+            mbuf[0] = 0;
         }
-        BIO_printf(sbio,
-                   "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
-        seen = BIO_read(sbio, sbuf, BUFSIZZ);
-        sbuf[seen] = 0;
-        if (!strstr(sbuf, "<proceed"))
-            goto shut;
-        mbuf[0] = 0;
+        break;
     }
 
     for (;;) {
@@ -1678,6 +1606,13 @@ int MAIN(int argc, char **argv)
             tty_on = 1;
             if (in_init) {
                 in_init = 0;
+#ifndef OPENSSL_NO_TLSEXT
+                if (servername != NULL && !SSL_session_reused(con)) {
+                    BIO_printf(bio_c_out,
+                               "Server did %sacknowledge servername extension.\n",
+                               tlsextcbp.ack ? "" : "not ");
+                }
+#endif
                 if (sess_out) {
                     BIO *stmp = BIO_new_file(sess_out, "w");
                     if (stmp) {
@@ -1697,9 +1632,10 @@ int MAIN(int argc, char **argv)
                     full_log--;
 
                 if (starttls_proto) {
-                    BIO_printf(bio_err, "%s", mbuf);
+                    BIO_write(bio_err, mbuf, mbuf_len);
                     /* We don't need to know any more */
-                    starttls_proto = PROTO_OFF;
+                    if (!reconnect)
+                        starttls_proto = PROTO_OFF;
                 }
 
                 if (reconnect) {
@@ -1736,8 +1672,6 @@ int MAIN(int argc, char **argv)
                     openssl_fdset(SSL_get_fd(con), &writefds);
             }
 #endif
-/*-         printf("mode tty(%d %d%d) ssl(%d%d)\n",
-                    tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
 
             /*
              * Note: under VMS with SOCKETSHR the second parameter is
@@ -2037,8 +1971,7 @@ int MAIN(int argc, char **argv)
     if (vpm)
         X509_VERIFY_PARAM_free(vpm);
     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)
@@ -2060,8 +1993,7 @@ int MAIN(int argc, char **argv)
     bio_c_out = NULL;
     BIO_free(bio_c_msg);
     bio_c_msg = NULL;
-    apps_shutdown();
-    OPENSSL_EXIT(ret);
+    return (ret);
 }
 
 static void print_stuff(BIO *bio, SSL *s, int full)
@@ -2083,7 +2015,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
 
         sk = SSL_get_peer_cert_chain(s);
         if (sk != NULL) {
-            got_a_chain = 1;    /* we don't have it for SSL2 (yet) */
+            got_a_chain = 1;
 
             BIO_printf(bio, "---\nCertificate chain\n");
             for (i = 0; i < sk_X509_num(sk); i++) {
index 8e350c89d8f6d3265bef39183a1da64d2671e41e..2aaa2cb7da0aa84f7805b6d289ea9a08943f84e0 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/s_server.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -199,7 +198,6 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context);
 static int www_body(char *hostname, int s, int stype, unsigned char *context);
 static int rev_body(char *hostname, int s, int stype, unsigned char *context);
 static void close_accept_socket(void);
-static void sv_usage(void);
 static int init_ssl_connection(SSL *s);
 static void print_stats(BIO *bp, SSL_CTX *ctx);
 static int generate_session_id(const SSL *ssl, unsigned char *id,
@@ -210,9 +208,7 @@ static void free_sessions(void);
 static DH *load_dh_param(const char *dhfile);
 #endif
 
-#ifdef MONOLITH
 static void s_server_init(void);
-#endif
 
 /* static int load_CA(SSL_CTX *ctx, char *file);*/
 
@@ -225,8 +221,6 @@ static int accept_socket = -1;
 #ifndef OPENSSL_NO_TLSEXT
 # define TEST_CERT2      "server2.pem"
 #endif
-#undef PROG
-#define PROG            s_server_main
 
 extern int verify_depth, verify_return_error, verify_quiet;
 
@@ -394,10 +388,10 @@ static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
 
 #endif
 
-#ifdef MONOLITH
 static void s_server_init(void)
 {
     accept_socket = -1;
+    verify_depth = 0;
     s_server_verify = SSL_VERIFY_NONE;
     s_dcert_file = NULL;
     s_dkey_file = NULL;
@@ -405,208 +399,23 @@ static void s_server_init(void)
     s_cert_file = TEST_CERT;
     s_key_file = NULL;
     s_chain_file = NULL;
-# ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_TLSEXT
     s_cert_file2 = TEST_CERT2;
     s_key_file2 = NULL;
     ctx2 = NULL;
-# endif
-# ifdef FIONBIO
+#endif
     s_nbio = 0;
-# endif
     s_nbio_test = 0;
     ctx = NULL;
     www = 0;
-
     bio_s_out = NULL;
     s_debug = 0;
     s_msg = 0;
     s_quiet = 0;
     s_brief = 0;
-# ifndef OPENSSL_NO_ENGINE
-    engine_id = NULL;
-# endif
-}
-#endif
-
-static void sv_usage(void)
-{
-    BIO_printf(bio_err, "usage: s_server [args ...]\n");
-    BIO_printf(bio_err, "\n");
-    BIO_printf(bio_err,
-               " -accept port  - TCP/IP port to accept on (default is %d)\n",
-               PORT);
-    BIO_printf(bio_err, " -unix path    - unix domain socket to accept on\n");
-    BIO_printf(bio_err,
-               " -unlink       - for -unix, unlink existing socket first\n");
-    BIO_printf(bio_err, " -context arg  - set session ID context\n");
-    BIO_printf(bio_err,
-               " -verify arg   - turn on peer certificate verification\n");
-    BIO_printf(bio_err,
-               " -Verify arg   - turn on peer certificate verification, must have a cert.\n");
-    BIO_printf(bio_err,
-               " -verify_return_error - return verification errors\n");
-    BIO_printf(bio_err, " -cert arg     - certificate file to use\n");
-    BIO_printf(bio_err, "                 (default is %s)\n", TEST_CERT);
-    BIO_printf(bio_err,
-               " -naccept arg  - terminate after 'arg' connections\n");
-#ifndef OPENSSL_NO_TLSEXT
-    BIO_printf(bio_err,
-               " -serverinfo arg - PEM serverinfo file for certificate\n");
-#endif
-    BIO_printf(bio_err,
-               " -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
-    BIO_printf(bio_err,
-               " -crl_check    - check the peer certificate has not been revoked by its CA.\n"
-               "                 The CRL(s) are appended to the certificate file\n");
-    BIO_printf(bio_err,
-               " -crl_check_all - check the peer certificate has not been revoked by its CA\n"
-               "                 or any other CRL in the CA chain. CRL(s) are appened to the\n"
-               "                 the certificate file.\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 (default is %s)\n",
-               TEST_CERT);
-    BIO_printf(bio_err,
-               " -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
-    BIO_printf(bio_err,
-               " -pass arg     - private key file pass phrase source\n");
-    BIO_printf(bio_err,
-               " -dcert arg    - second certificate file to use (usually for DSA)\n");
-    BIO_printf(bio_err,
-               " -dcertform x  - second certificate format (PEM or DER) PEM default\n");
-    BIO_printf(bio_err,
-               " -dkey arg     - second private key file to use (usually for DSA)\n");
-    BIO_printf(bio_err,
-               " -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
-    BIO_printf(bio_err,
-               " -dpass arg    - second private key file pass phrase source\n");
-    BIO_printf(bio_err,
-               " -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
-    BIO_printf(bio_err,
-               "                 or a default set of parameters is used\n");
-#ifndef OPENSSL_NO_EC
-    BIO_printf(bio_err,
-               " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n"
-               "                 Use \"openssl ecparam -list_curves\" for all names\n"
-               "                 (default is nistp256).\n");
-#endif
-#ifdef FIONBIO
-    BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
-#endif
-    BIO_printf(bio_err,
-               " -nbio_test    - test with the non-blocking test bio\n");
-    BIO_printf(bio_err,
-               " -crlf         - convert LF from terminal into CRLF\n");
-    BIO_printf(bio_err, " -debug        - Print more output\n");
-    BIO_printf(bio_err, " -msg          - Show protocol messages\n");
-    BIO_printf(bio_err, " -state        - Print the SSL states\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 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,
-               " -nocert       - Don't use any certificates (Anon-DH)\n");
-    BIO_printf(bio_err,
-               " -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
-    BIO_printf(bio_err, " -serverpref   - Use server's cipher preferences\n");
-    BIO_printf(bio_err, " -quiet        - No server output\n");
-    BIO_printf(bio_err, " -no_tmp_rsa   - Do not generate a tmp RSA key\n");
-#ifndef OPENSSL_NO_PSK
-    BIO_printf(bio_err, " -psk_hint arg - PSK identity hint to use\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, " -srpvfile file      - The verifier file for SRP\n");
-    BIO_printf(bio_err,
-               " -srpuserseed string - A seed string for a default user salt.\n");
-#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
-    BIO_printf(bio_err, " -ssl3         - Just talk SSLv3\n");
-#endif
-    BIO_printf(bio_err, " -tls1_2       - Just talk TLSv1.2\n");
-    BIO_printf(bio_err, " -tls1_1       - Just talk TLSv1.1\n");
-    BIO_printf(bio_err, " -tls1         - Just talk TLSv1\n");
-    BIO_printf(bio_err, " -dtls1        - Just talk DTLSv1\n");
-    BIO_printf(bio_err, " -dtls1_2      - Just talk DTLSv1.2\n");
-    BIO_printf(bio_err, " -timeout      - Enable timeouts\n");
-    BIO_printf(bio_err, " -mtu          - Set link layer MTU\n");
-    BIO_printf(bio_err, " -chain        - Read a certificate chain\n");
-    BIO_printf(bio_err, " -no_ssl3      - Just disable SSLv3\n");
-    BIO_printf(bio_err, " -no_tls1      - Just disable TLSv1\n");
-    BIO_printf(bio_err, " -no_tls1_1    - Just disable TLSv1.1\n");
-    BIO_printf(bio_err, " -no_tls1_2    - Just disable TLSv1.2\n");
-#ifndef OPENSSL_NO_DH
-    BIO_printf(bio_err, " -no_dhe       - Disable ephemeral DH\n");
-#endif
-#ifndef OPENSSL_NO_EC
-    BIO_printf(bio_err, " -no_ecdhe     - Disable ephemeral ECDH\n");
-#endif
-    BIO_printf(bio_err,
-               "-no_resume_ephemeral - Disable caching and tickets if ephemeral (EC)DH is used\n");
-    BIO_printf(bio_err, " -bugs         - Turn on SSL bug compatibility\n");
-    BIO_printf(bio_err,
-               " -www          - Respond to a 'GET /' with a status page\n");
-    BIO_printf(bio_err,
-               " -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
-    BIO_printf(bio_err,
-               " -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\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;
     }
index 5bdfc6c8e0abe6002c82a67dd068740eaa466b39..4c440dc50a7902edd12d8cc928db80e726ea8c23 100644 (file)
@@ -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.
  *
  * 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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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 <openssl/ssl.h>
 
@@ -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;
index 8f4980b6771e4b7cde311fee3d1bf8fd1a633d51..5bca72ba72bad4ea2d6857bf8641c970ede78cad 100644 (file)
@@ -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
 
 
 #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 <args>\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);
index 9421e408424252d9be8d8a67b45d4ab92510dd70..cfecd86a50030f3a3377944297d8f273ffa195a0 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/sess_id.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
 
-#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);
index 930978fd9b11ffcfab4d884b922e20b40d98e8b4..532446f49ff6778e30dcb69970f0ffe0e897e1e7 100644 (file)
@@ -1,4 +1,3 @@
-/* smime.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
@@ -68,8 +67,6 @@
 #include <openssl/x509_vfy.h>
 #include <openssl/x509v3.h>
 
-#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;
 
index 71aa74a44657cb87554b9d49a1bac824f87ab12b..1a01d333b7f8752f5f30f266e9b109a262b6afbc 100644 (file)
@@ -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.
  *
 #define ECDSA_SECONDS   10
 #define ECDH_SECONDS    10
 
-#undef PROG
-#define PROG speed_main
-
 #include <stdio.h>
 #include <stdlib.h>
-
 #include <string.h>
 #include <math.h>
 #include "apps.h"
 #ifndef OPENSSL_NO_MD5
 # include <openssl/md5.h>
 #endif
-# include <openssl/hmac.h>
+#include <openssl/hmac.h>
 #include <openssl/evp.h>
-# include <openssl/sha.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_RMD160
 # include <openssl/ripemd.h>
 #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];
     }
index 8b06ec4d6e7211eafe095f104c752385f6db0113..ee2e5969f01b01bd8c77ba328057653687dbfd45 100644 (file)
@@ -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).
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 
-#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);
 }
index 5acc7835d1442f34dfc2e5738d2e7f52ddbb3043..bacd6701855bc529cc19a94a5ba8da961cde1496 100644 (file)
@@ -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"
 
 # 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
index 550c6253e69e925aa2d99c7672cf5c14262c8db2..4eb13d14b2a862d72233647622e17623d76567c0 100644 (file)
@@ -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,
index 4c32ada41004547585d715c9877ec6e0f4e93c2e..e0f43130ca6c30021c514ec1a30c0f95de9d02b6 100644 (file)
--- 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 <openssl/ts.h>
 #include <openssl/bn.h>
 
-#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;
 }
index e771be22d2d9d64ef65d32e6b1f2f64a5e03dab4..61e85ce87e89de54a486af863a31cd57206b8fee 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/verify.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
 
-#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);
index 8807d4c7b0091367bd6f037526bbb50780791b77..1fa7cfe536600bb6380a00f7a82b8ac87b5b0d4a 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/version.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/blowfish.h>
 #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);
 }
index 3b6de11978a5f82b45b606491c4c373a86cdbacc..3c953aa3611ebc55cc801c33e2692a436c51ee57 100644 (file)
@@ -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
 
 #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 <stdio.h>
@@ -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)
index 44f57a38ba8a32830695b6842859db5c6dd5b0e4..a5fe791037712658dd655b4d267a78926046375d 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/winrand.c */
 /* ====================================================================
  * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
  *
index 380f0f0be7fe0e50c0b86e47b529d603ca803ee9..903e6b94b9dcc2404310745dc424de9a6e7257a8 100644 (file)
@@ -1,4 +1,3 @@
-/* apps/x509.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 # include <openssl/dsa.h>
 #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, "<No Alias>\n");
+                    BIO_puts(out, "<No Alias>\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;
index 7ae36d7da6a84c51e358ce2da5ab71a1bddf9f2b..0a889ef26336f4fb1fc29fa72adaa56264159229 100644 (file)
@@ -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");
index 43821f6f37c305ad6bda37a3659b84e0d7c02e8e..97b4fb9414f5c7d43cf156a1cefce887d1323945 100644 (file)
@@ -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"),
index e8714310cc4d1af0c95b1bc0cdc3357aad929e5c..c2427a33799b1232ab535aea743326f1ea07dcab 100644 (file)
 -T ssl_trace_tbl
 -T _stdcall
 -T tls12_lookup
+-T OPTIONS
+-T OPT_PAIR
index 7ea4a8a56b6a5226c8f977d112004650c5b67274..f5f85ab34f74fb40677add94ce967d6bff6f33ea 100755 (executable)
@@ -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: