diff options
Diffstat (limited to 'main/openssl/apps')
92 files changed, 41031 insertions, 0 deletions
diff --git a/main/openssl/apps/Android.mk b/main/openssl/apps/Android.mk new file mode 100644 index 00000000..1ad078de --- /dev/null +++ b/main/openssl/apps/Android.mk @@ -0,0 +1,78 @@ +# Copyright 2006 The Android Open Source Project + +LOCAL_PATH:= $(call my-dir) + +local_src_files:= \ +	app_rand.c \ +	apps.c \ +	asn1pars.c \ +	ca.c \ +	ciphers.c \ +	crl.c \ +	crl2p7.c \ +	dgst.c \ +	dh.c \ +	dhparam.c \ +	dsa.c \ +	dsaparam.c \ +	ecparam.c \ +	ec.c \ +	enc.c \ +	engine.c \ +	errstr.c \ +	gendh.c \ +	gendsa.c \ +	genpkey.c \ +	genrsa.c \ +	nseq.c \ +	ocsp.c \ +	openssl.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_cb.c \ +	s_client.c \ +	s_server.c \ +	s_socket.c \ +	s_time.c \ +	sess_id.c \ +	smime.c \ +	speed.c \ +	spkac.c \ +	verify.c \ +	version.c \ +	x509.c + +local_shared_libraries := \ +	libssl \ +	libcrypto + +local_c_includes := \ +	openssl \ +	openssl/include + +local_cflags := -DMONOLITH + +# These flags omit whole features from the commandline "openssl". +# However, portions of these features are actually turned on. +local_cflags += -DOPENSSL_NO_DTLS1 + +include $(CLEAR_VARS) +LOCAL_MODULE:= openssl +LOCAL_MODULE_TAGS := optional +LOCAL_SRC_FILES := $(local_src_files) +LOCAL_SHARED_LIBRARIES := $(local_shared_libraries) +LOCAL_C_INCLUDES := $(local_c_includes) +LOCAL_CFLAGS := $(local_cflags) +include $(LOCAL_PATH)/../android-config.mk +include $(BUILD_EXECUTABLE) + diff --git a/main/openssl/apps/CA.pl b/main/openssl/apps/CA.pl new file mode 100644 index 00000000..a3965ece --- /dev/null +++ b/main/openssl/apps/CA.pl @@ -0,0 +1,189 @@ +#!/usr/bin/perl +# +# CA - wrapper around ca to make it easier to use ... basically ca requires +#      some setup stuff to be done before you can use it and this makes +#      things easier between now and when Eric is convinced to fix it :-) +# +# CA -newca ... will setup the right stuff +# CA -newreq[-nodes] ... will generate a certificate request  +# CA -sign ... will sign the generated request and output  +# +# At the end of that grab newreq.pem and newcert.pem (one has the key  +# and the other the certificate) and cat them together and that is what +# you want/need ... I'll make even this a little cleaner later. +# +# +# 12-Jan-96 tjh    Added more things ... including CA -signcert which +#                  converts a certificate to a request and then signs it. +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG +#		   environment variable so this can be driven from +#		   a script. +# 25-Jul-96 eay    Cleaned up filenames some more. +# 11-Jun-96 eay    Fixed a few filename missmatches. +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'. +# 18-Apr-96 tjh    Original hacking +# +# Tim Hudson +# tjh@cryptsoft.com +# + +# 27-Apr-98 snh    Translation into perl, fix existing CA bug. +# +# +# Steve Henson +# shenson@bigfoot.com + +# default openssl.cnf file has setup as per the following +# demoCA ... where everything is stored + +my $openssl; +if(defined $ENV{OPENSSL}) { +	$openssl = $ENV{OPENSSL}; +} else { +	$openssl = "openssl"; +	$ENV{OPENSSL} = $openssl; +} + +$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; +$DAYS="-days 365";	# 1 year +$CADAYS="-days 1095";	# 3 years +$REQ="$openssl req $SSLEAY_CONFIG"; +$CA="$openssl ca $SSLEAY_CONFIG"; +$VERIFY="$openssl verify"; +$X509="$openssl x509"; +$PKCS12="$openssl pkcs12"; + +$CATOP="./demoCA"; +$CAKEY="cakey.pem"; +$CAREQ="careq.pem"; +$CACERT="cacert.pem"; + +$DIRMODE = 0777; + +$RET = 0; + +foreach (@ARGV) { +	if ( /^(-\?|-h|-help)$/ ) { +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; +	    exit 0; +	} elsif (/^-newcert$/) { +	    # create a certificate +	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); +	    $RET=$?; +	    print "Certificate is in newcert.pem, private key is in newkey.pem\n" +	} elsif (/^-newreq$/) { +	    # create a certificate request +	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); +	    $RET=$?; +	    print "Request is in newreq.pem, private key is in newkey.pem\n"; +	} elsif (/^-newreq-nodes$/) { +	    # create a certificate request +	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); +	    $RET=$?; +	    print "Request is in newreq.pem, private key is in newkey.pem\n"; +	} elsif (/^-newca$/) { +		# if explicitly asked for or it doesn't exist then setup the +		# directory structure that Eric likes to manage things  +	    $NEW="1"; +	    if ( "$NEW" || ! -f "${CATOP}/serial" ) { +		# create the directory hierarchy +		mkdir $CATOP, $DIRMODE; +		mkdir "${CATOP}/certs", $DIRMODE; +		mkdir "${CATOP}/crl", $DIRMODE ; +		mkdir "${CATOP}/newcerts", $DIRMODE; +		mkdir "${CATOP}/private", $DIRMODE; +		open OUT, ">${CATOP}/index.txt"; +		close OUT; +		open OUT, ">${CATOP}/crlnumber"; +		print OUT "01\n"; +		close OUT; +	    } +	    if ( ! -f "${CATOP}/private/$CAKEY" ) { +		print "CA certificate filename (or enter to create)\n"; +		$FILE = <STDIN>; + +		chop $FILE; + +		# ask user for existing CA certificate +		if ($FILE) { +		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); +		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); +		    $RET=$?; +		} else { +		    print "Making CA certificate ...\n"; +		    system ("$REQ -new -keyout " . +			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); +		    system ("$CA -create_serial " . +			"-out ${CATOP}/$CACERT $CADAYS -batch " .  +			"-keyfile ${CATOP}/private/$CAKEY -selfsign " . +			"-extensions v3_ca " . +			"-infiles ${CATOP}/$CAREQ "); +		    $RET=$?; +		} +	    } +	} elsif (/^-pkcs12$/) { +	    my $cname = $ARGV[1]; +	    $cname = "My Certificate" unless defined $cname; +	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . +			"-certfile ${CATOP}/$CACERT -out newcert.p12 " . +			"-export -name \"$cname\""); +	    $RET=$?; +	    print "PKCS #12 file is in newcert.p12\n"; +	    exit $RET; +	} elsif (/^-xsign$/) { +	    system ("$CA -policy policy_anything -infiles newreq.pem"); +	    $RET=$?; +	} elsif (/^(-sign|-signreq)$/) { +	    system ("$CA -policy policy_anything -out newcert.pem " . +							"-infiles newreq.pem"); +	    $RET=$?; +	    print "Signed certificate is in newcert.pem\n"; +	} elsif (/^(-signCA)$/) { +	    system ("$CA -policy policy_anything -out newcert.pem " . +					"-extensions v3_ca -infiles newreq.pem"); +	    $RET=$?; +	    print "Signed CA certificate is in newcert.pem\n"; +	} elsif (/^-signcert$/) { +	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . +								"-out tmp.pem"); +	    system ("$CA -policy policy_anything -out newcert.pem " . +							"-infiles tmp.pem"); +	    $RET = $?; +	    print "Signed certificate is in newcert.pem\n"; +	} elsif (/^-verify$/) { +	    if (shift) { +		foreach $j (@ARGV) { +		    system ("$VERIFY -CAfile $CATOP/$CACERT $j"); +		    $RET=$? if ($? != 0); +		} +		exit $RET; +	    } else { +		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); +		    $RET=$?; +	    	    exit 0; +	    } +	} else { +	    print STDERR "Unknown arg $_\n"; +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; +	    exit 1; +	} +} + +exit $RET; + +sub cp_pem { +my ($infile, $outfile, $bound) = @_; +open IN, $infile; +open OUT, ">$outfile"; +my $flag = 0; +while (<IN>) { +	$flag = 1 if (/^-----BEGIN.*$bound/) ; +	print OUT $_ if ($flag); +	if (/^-----END.*$bound/) { +		close IN; +		close OUT; +		return; +	} +} +} + diff --git a/main/openssl/apps/CA.pl.in b/main/openssl/apps/CA.pl.in new file mode 100644 index 00000000..c783a6e6 --- /dev/null +++ b/main/openssl/apps/CA.pl.in @@ -0,0 +1,189 @@ +#!/usr/local/bin/perl +# +# CA - wrapper around ca to make it easier to use ... basically ca requires +#      some setup stuff to be done before you can use it and this makes +#      things easier between now and when Eric is convinced to fix it :-) +# +# CA -newca ... will setup the right stuff +# CA -newreq[-nodes] ... will generate a certificate request  +# CA -sign ... will sign the generated request and output  +# +# At the end of that grab newreq.pem and newcert.pem (one has the key  +# and the other the certificate) and cat them together and that is what +# you want/need ... I'll make even this a little cleaner later. +# +# +# 12-Jan-96 tjh    Added more things ... including CA -signcert which +#                  converts a certificate to a request and then signs it. +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG +#		   environment variable so this can be driven from +#		   a script. +# 25-Jul-96 eay    Cleaned up filenames some more. +# 11-Jun-96 eay    Fixed a few filename missmatches. +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'. +# 18-Apr-96 tjh    Original hacking +# +# Tim Hudson +# tjh@cryptsoft.com +# + +# 27-Apr-98 snh    Translation into perl, fix existing CA bug. +# +# +# Steve Henson +# shenson@bigfoot.com + +# default openssl.cnf file has setup as per the following +# demoCA ... where everything is stored + +my $openssl; +if(defined $ENV{OPENSSL}) { +	$openssl = $ENV{OPENSSL}; +} else { +	$openssl = "openssl"; +	$ENV{OPENSSL} = $openssl; +} + +$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; +$DAYS="-days 365";	# 1 year +$CADAYS="-days 1095";	# 3 years +$REQ="$openssl req $SSLEAY_CONFIG"; +$CA="$openssl ca $SSLEAY_CONFIG"; +$VERIFY="$openssl verify"; +$X509="$openssl x509"; +$PKCS12="$openssl pkcs12"; + +$CATOP="./demoCA"; +$CAKEY="cakey.pem"; +$CAREQ="careq.pem"; +$CACERT="cacert.pem"; + +$DIRMODE = 0777; + +$RET = 0; + +foreach (@ARGV) { +	if ( /^(-\?|-h|-help)$/ ) { +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; +	    exit 0; +	} elsif (/^-newcert$/) { +	    # create a certificate +	    system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); +	    $RET=$?; +	    print "Certificate is in newcert.pem, private key is in newkey.pem\n" +	} elsif (/^-newreq$/) { +	    # create a certificate request +	    system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); +	    $RET=$?; +	    print "Request is in newreq.pem, private key is in newkey.pem\n"; +	} elsif (/^-newreq-nodes$/) { +	    # create a certificate request +	    system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); +	    $RET=$?; +	    print "Request is in newreq.pem, private key is in newkey.pem\n"; +	} elsif (/^-newca$/) { +		# if explicitly asked for or it doesn't exist then setup the +		# directory structure that Eric likes to manage things  +	    $NEW="1"; +	    if ( "$NEW" || ! -f "${CATOP}/serial" ) { +		# create the directory hierarchy +		mkdir $CATOP, $DIRMODE; +		mkdir "${CATOP}/certs", $DIRMODE; +		mkdir "${CATOP}/crl", $DIRMODE ; +		mkdir "${CATOP}/newcerts", $DIRMODE; +		mkdir "${CATOP}/private", $DIRMODE; +		open OUT, ">${CATOP}/index.txt"; +		close OUT; +		open OUT, ">${CATOP}/crlnumber"; +		print OUT "01\n"; +		close OUT; +	    } +	    if ( ! -f "${CATOP}/private/$CAKEY" ) { +		print "CA certificate filename (or enter to create)\n"; +		$FILE = <STDIN>; + +		chop $FILE; + +		# ask user for existing CA certificate +		if ($FILE) { +		    cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); +		    cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); +		    $RET=$?; +		} else { +		    print "Making CA certificate ...\n"; +		    system ("$REQ -new -keyout " . +			"${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); +		    system ("$CA -create_serial " . +			"-out ${CATOP}/$CACERT $CADAYS -batch " .  +			"-keyfile ${CATOP}/private/$CAKEY -selfsign " . +			"-extensions v3_ca " . +			"-infiles ${CATOP}/$CAREQ "); +		    $RET=$?; +		} +	    } +	} elsif (/^-pkcs12$/) { +	    my $cname = $ARGV[1]; +	    $cname = "My Certificate" unless defined $cname; +	    system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . +			"-certfile ${CATOP}/$CACERT -out newcert.p12 " . +			"-export -name \"$cname\""); +	    $RET=$?; +	    print "PKCS #12 file is in newcert.p12\n"; +	    exit $RET; +	} elsif (/^-xsign$/) { +	    system ("$CA -policy policy_anything -infiles newreq.pem"); +	    $RET=$?; +	} elsif (/^(-sign|-signreq)$/) { +	    system ("$CA -policy policy_anything -out newcert.pem " . +							"-infiles newreq.pem"); +	    $RET=$?; +	    print "Signed certificate is in newcert.pem\n"; +	} elsif (/^(-signCA)$/) { +	    system ("$CA -policy policy_anything -out newcert.pem " . +					"-extensions v3_ca -infiles newreq.pem"); +	    $RET=$?; +	    print "Signed CA certificate is in newcert.pem\n"; +	} elsif (/^-signcert$/) { +	    system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . +								"-out tmp.pem"); +	    system ("$CA -policy policy_anything -out newcert.pem " . +							"-infiles tmp.pem"); +	    $RET = $?; +	    print "Signed certificate is in newcert.pem\n"; +	} elsif (/^-verify$/) { +	    if (shift) { +		foreach $j (@ARGV) { +		    system ("$VERIFY -CAfile $CATOP/$CACERT $j"); +		    $RET=$? if ($? != 0); +		} +		exit $RET; +	    } else { +		    system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); +		    $RET=$?; +	    	    exit 0; +	    } +	} else { +	    print STDERR "Unknown arg $_\n"; +	    print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; +	    exit 1; +	} +} + +exit $RET; + +sub cp_pem { +my ($infile, $outfile, $bound) = @_; +open IN, $infile; +open OUT, ">$outfile"; +my $flag = 0; +while (<IN>) { +	$flag = 1 if (/^-----BEGIN.*$bound/) ; +	print OUT $_ if ($flag); +	if (/^-----END.*$bound/) { +		close IN; +		close OUT; +		return; +	} +} +} + diff --git a/main/openssl/apps/CA.sh b/main/openssl/apps/CA.sh new file mode 100644 index 00000000..7ad6b8c5 --- /dev/null +++ b/main/openssl/apps/CA.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# +# CA - wrapper around ca to make it easier to use ... basically ca requires +#      some setup stuff to be done before you can use it and this makes +#      things easier between now and when Eric is convinced to fix it :-) +# +# CA -newca ... will setup the right stuff +# CA -newreq ... will generate a certificate request +# CA -sign ... will sign the generated request and output +# +# At the end of that grab newreq.pem and newcert.pem (one has the key +# and the other the certificate) and cat them together and that is what +# you want/need ... I'll make even this a little cleaner later. +# +# +# 12-Jan-96 tjh    Added more things ... including CA -signcert which +#                  converts a certificate to a request and then signs it. +# 10-Jan-96 eay    Fixed a few more bugs and added the SSLEAY_CONFIG +#                  environment variable so this can be driven from +#                  a script. +# 25-Jul-96 eay    Cleaned up filenames some more. +# 11-Jun-96 eay    Fixed a few filename missmatches. +# 03-May-96 eay    Modified to use 'ssleay cmd' instead of 'cmd'. +# 18-Apr-96 tjh    Original hacking +# +# Tim Hudson +# tjh@cryptsoft.com +# + +# default openssl.cnf file has setup as per the following +# demoCA ... where everything is stored +cp_pem() { +    infile=$1 +    outfile=$2 +    bound=$3 +    flag=0 +    exec <$infile; +    while read line; do +	if [ $flag -eq 1 ]; then +		echo $line|grep "^-----END.*$bound"  2>/dev/null 1>/dev/null +		if [ $? -eq 0 ] ; then +			echo $line >>$outfile +			break +		else +			echo $line >>$outfile +		fi +	fi + +	echo $line|grep "^-----BEGIN.*$bound"  2>/dev/null 1>/dev/null +	if [ $? -eq 0 ]; then +		echo $line >$outfile +		flag=1 +	fi +    done +} + +usage() { + echo "usage: $0 -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify" >&2 +} + +if [ -z "$OPENSSL" ]; then OPENSSL=openssl; fi + +if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi	# 1 year +CADAYS="-days 1095"	# 3 years +REQ="$OPENSSL req $SSLEAY_CONFIG" +CA="$OPENSSL ca $SSLEAY_CONFIG" +VERIFY="$OPENSSL verify" +X509="$OPENSSL x509" +PKCS12="openssl pkcs12" + +if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi +CAKEY=./cakey.pem +CAREQ=./careq.pem +CACERT=./cacert.pem + +RET=0 + +while [ "$1" != "" ] ; do +case $1 in +-\?|-h|-help) +    usage +    exit 0 +    ;; +-newcert) +    # create a certificate +    $REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS +    RET=$? +    echo "Certificate is in newcert.pem, private key is in newkey.pem" +    ;; +-newreq) +    # create a certificate request +    $REQ -new -keyout newkey.pem -out newreq.pem $DAYS +    RET=$? +    echo "Request is in newreq.pem, private key is in newkey.pem" +    ;; +-newreq-nodes)  +    # create a certificate request +    $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS +    RET=$? +    echo "Request (and private key) is in newreq.pem" +    ;; +-newca) +    # if explicitly asked for or it doesn't exist then setup the directory +    # structure that Eric likes to manage things +    NEW="1" +    if [ "$NEW" -o ! -f ${CATOP}/serial ]; then +	# create the directory hierarchy +	mkdir -p ${CATOP} +	mkdir -p ${CATOP}/certs +	mkdir -p ${CATOP}/crl +	mkdir -p ${CATOP}/newcerts +	mkdir -p ${CATOP}/private +	touch ${CATOP}/index.txt +    fi +    if [ ! -f ${CATOP}/private/$CAKEY ]; then +	echo "CA certificate filename (or enter to create)" +	read FILE + +	# ask user for existing CA certificate +	if [ "$FILE" ]; then +	    cp_pem $FILE ${CATOP}/private/$CAKEY PRIVATE +	    cp_pem $FILE ${CATOP}/$CACERT CERTIFICATE +	    RET=$? +	    if [ ! -f "${CATOP}/serial" ]; then +		$X509 -in ${CATOP}/$CACERT -noout -next_serial \ +		      -out ${CATOP}/serial +	    fi +	else +	    echo "Making CA certificate ..." +	    $REQ -new -keyout ${CATOP}/private/$CAKEY \ +			   -out ${CATOP}/$CAREQ +	    $CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \ +			   -keyfile ${CATOP}/private/$CAKEY -selfsign \ +			   -extensions v3_ca \ +			   -infiles ${CATOP}/$CAREQ +	    RET=$? +	fi +    fi +    ;; +-xsign) +    $CA -policy policy_anything -infiles newreq.pem +    RET=$? +    ;; +-pkcs12) +    if [ -z "$2" ] ; then +	CNAME="My Certificate" +    else +	CNAME="$2" +    fi +    $PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \ +	    -out newcert.p12 -export -name "$CNAME" +    RET=$? +    exit $RET +    ;; +-sign|-signreq) +    $CA -policy policy_anything -out newcert.pem -infiles newreq.pem +    RET=$? +    cat newcert.pem +    echo "Signed certificate is in newcert.pem" +    ;; +-signCA) +    $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem +    RET=$? +    echo "Signed CA certificate is in newcert.pem" +    ;; +-signcert) +    echo "Cert passphrase will be requested twice - bug?" +    $X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem +    $CA -policy policy_anything -out newcert.pem -infiles tmp.pem +    RET=$? +    cat newcert.pem +    echo "Signed certificate is in newcert.pem" +    ;; +-verify) +    shift +    if [ -z "$1" ]; then +	    $VERIFY -CAfile $CATOP/$CACERT newcert.pem +	    RET=$? +    else +	for j +	do +	    $VERIFY -CAfile $CATOP/$CACERT $j +	    if [ $? != 0 ]; then +		    RET=$? +	    fi +	done +    fi +    exit $RET +    ;; +*) +    echo "Unknown arg $i" >&2 +    usage +    exit 1 +    ;; +esac +shift +done +exit $RET diff --git a/main/openssl/apps/app_rand.c b/main/openssl/apps/app_rand.c new file mode 100644 index 00000000..b7b6128c --- /dev/null +++ b/main/openssl/apps/app_rand.c @@ -0,0 +1,218 @@ +/* apps/app_rand.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#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 consider_randfile = (file == NULL); +	char buffer[200]; +	 +#ifdef OPENSSL_SYS_WINDOWS +	BIO_printf(bio_e,"Loading 'screen' into random state -"); +	BIO_flush(bio_e); +	RAND_screen(); +	BIO_printf(bio_e," done\n"); +#endif + +	if (file == NULL) +		file = RAND_file_name(buffer, sizeof buffer); +	else if (RAND_egd(file) > 0) +		{ +		/* we try if the given filename is an EGD socket. +		   if it is, we don't write anything back to the file. */ +		egdsocket = 1; +		return 1; +		} +	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,"This means that the random number generator has not been seeded\n"); +				BIO_printf(bio_e,"with much random data.\n"); +				if (consider_randfile) /* explanation does not apply when a file is explicitly named */ +					{ +					BIO_printf(bio_e,"Consider setting the RANDFILE environment variable to point at a file that\n"); +					BIO_printf(bio_e,"'random' data can be kept in (the file will be overwritten).\n"); +					} +				} +			return 0; +			} +		} +	seeded = 1; +	return 1; +	} + +long app_RAND_load_files(char *name) +	{ +	char *p,*n; +	int last; +	long tot=0; +	int egd; +	 +	for (;;) +		{ +		last=0; +		for (p=name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++); +		if (*p == '\0') last=1; +		*p='\0'; +		n=name; +		name=p+1; +		if (*n == '\0') break; + +		egd=RAND_egd(n); +		if (egd > 0) +			tot+=egd; +		else +			tot+=RAND_load_file(n,-1); +		if (last) break; +		} +	if (tot > 512) +		app_RAND_allow_write_file(); +	return(tot); +	} + +int app_RAND_write_file(const char *file, BIO *bio_e) +	{ +	char buffer[200]; +	 +	if (egdsocket || !seeded) +		/* If we did not manage to read the seed file, +		 * we should not write a low-entropy seed file back -- +		 * it would suppress a crucial warning the next time +		 * we want to use it. */ +		return 0; + +	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"); +		return 0; +		} +	return 1; +	} + +void app_RAND_allow_write_file(void) +	{ +	seeded = 1; +	} diff --git a/main/openssl/apps/apps.c b/main/openssl/apps/apps.c new file mode 100644 index 00000000..38e61970 --- /dev/null +++ b/main/openssl/apps/apps.c @@ -0,0 +1,3063 @@ +/* apps/apps.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 2	/* On VMS, you need to define this to get +				   the declaration of fileno().  The value +				   2 is to make sure no function defined +				   in POSIX-2 is left undefined. */ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if !defined(OPENSSL_SYSNAME_WIN32) && !defined(NETWARE_CLIB) +#include <strings.h> +#endif +#include <sys/types.h> +#include <ctype.h> +#include <errno.h> +#include <assert.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/pem.h> +#include <openssl/pkcs12.h> +#include <openssl/ui.h> +#include <openssl/safestack.h> +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#include <openssl/bn.h> +#ifndef OPENSSL_NO_JPAKE +#include <openssl/jpake.h> +#endif + +#define NON_MAIN +#include "apps.h" +#undef NON_MAIN + +#ifdef _WIN32 +static int WIN32_rename(const char *from, const char *to); +#define rename(from,to) WIN32_rename((from),(to)) +#endif + +typedef struct { +	const char *name; +	unsigned long flag; +	unsigned long mask; +} NAME_EX_TBL; + +static UI_METHOD *ui_method = NULL; + +static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); +static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); + +#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, +		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 ((*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 == '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_WIN16) || 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) +	{ +	char *p=in, *q; +	char *chars=":]>"; + +	while(*chars != '\0') +		{ +		q=strrchr(p,*chars); +		if (q > p) +			p = q + 1; +		chars++; +		} + +	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); +		} +	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'))) +			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) +				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; + +		/* 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)) +				p++; +			*p='\0'; +			} +		else +			{ +			while (*p && ((*p != ' ') && +				(*p != '\t') && (*p != '\n'))) +				p++; + +			if (*p == '\0') +				p--; +			else +				*p='\0'; +			} +		p++; +		} +	*argc=num; +	*argv=arg->data; +	return(1); +	} + +#ifndef APP_INIT +int app_init(long mesgwin) +	{ +	return(1); +	} +#endif + + +int dump_cert_text (BIO *out, X509 *x) +{ +	char *p; + +	p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0); +	BIO_puts(out,"subject="); +	BIO_puts(out,p); +	OPENSSL_free(p); + +	p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0); +	BIO_puts(out,"\nissuer="); +	BIO_puts(out,p); +	BIO_puts(out,"\n"); +	OPENSSL_free(p); + +	return 0; +} + +static int ui_open(UI *ui) +	{ +	return UI_method_get_opener(UI_OpenSSL())(ui); +	} +static int ui_read(UI *ui, UI_STRING *uis) +	{ +	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD +		&& UI_get0_user_data(ui)) +		{ +		switch(UI_get_string_type(uis)) +			{ +		case UIT_PROMPT: +		case UIT_VERIFY: +			{ +			const char *password = +				((PW_CB_DATA *)UI_get0_user_data(ui))->password; +			if (password && password[0] != '\0') +				{ +				UI_set_result(ui, uis, password); +				return 1; +				} +			} +		default: +			break; +			} +		} +	return UI_method_get_reader(UI_OpenSSL())(ui, uis); +	} +static int ui_write(UI *ui, UI_STRING *uis) +	{ +	if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD +		&& UI_get0_user_data(ui)) +		{ +		switch(UI_get_string_type(uis)) +			{ +		case UIT_PROMPT: +		case UIT_VERIFY: +			{ +			const char *password = +				((PW_CB_DATA *)UI_get0_user_data(ui))->password; +			if (password && password[0] != '\0') +				return 1; +			} +		default: +			break; +			} +		} +	return UI_method_get_writer(UI_OpenSSL())(ui, uis); +	} +static int ui_close(UI *ui) +	{ +	return UI_method_get_closer(UI_OpenSSL())(ui); +	} +int setup_ui_method(void) +	{ +	ui_method = UI_create_method("OpenSSL application user interface"); +	UI_method_set_opener(ui_method, ui_open); +	UI_method_set_reader(ui_method, ui_read); +	UI_method_set_writer(ui_method, ui_write); +	UI_method_set_closer(ui_method, ui_close); +	return 0; +	} +void destroy_ui_method(void) +	{ +	if(ui_method) +		{ +		UI_destroy_method(ui_method); +		ui_method = NULL; +		} +	} +int password_callback(char *buf, int bufsiz, int verify, +	PW_CB_DATA *cb_tmp) +	{ +	UI *ui = NULL; +	int res = 0; +	const char *prompt_info = NULL; +	const char *password = NULL; +	PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; + +	if (cb_data) +		{ +		if (cb_data->password) +			password = cb_data->password; +		if (cb_data->prompt_info) +			prompt_info = cb_data->prompt_info; +		} + +	if (password) +		{ +		res = strlen(password); +		if (res > bufsiz) +			res = bufsiz; +		memcpy(buf, password, res); +		return res; +		} + +	ui = UI_new_method(ui_method); +	if (ui) +		{ +		int ok = 0; +		char *buff = NULL; +		int ui_flags = 0; +		char *prompt = NULL; + +		prompt = UI_construct_prompt(ui, "pass phrase", +			prompt_info); + +		ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; +		UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + +		if (ok >= 0) +			ok = UI_add_input_string(ui,prompt,ui_flags,buf, +				PW_MIN_LENGTH,BUFSIZ-1); +		if (ok >= 0 && verify) +			{ +			buff = (char *)OPENSSL_malloc(bufsiz); +			ok = UI_add_verify_string(ui,prompt,ui_flags,buff, +				PW_MIN_LENGTH,BUFSIZ-1, buf); +			} +		if (ok >= 0) +			do +				{ +				ok = UI_process(ui); +				} +			while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + +		if (buff) +			{ +			OPENSSL_cleanse(buff,(unsigned int)bufsiz); +			OPENSSL_free(buff); +			} + +		if (ok >= 0) +			res = strlen(buf); +		if (ok == -1) +			{ +			BIO_printf(bio_err, "User interface error\n"); +			ERR_print_errors(bio_err); +			OPENSSL_cleanse(buf,(unsigned int)bufsiz); +			res = 0; +			} +		if (ok == -2) +			{ +			BIO_printf(bio_err,"aborted!\n"); +			OPENSSL_cleanse(buf,(unsigned int)bufsiz); +			res = 0; +			} +		UI_free(ui); +		OPENSSL_free(prompt); +		} +	return res; +	} + +static char *app_get_pass(BIO *err, char *arg, int keepbio); + +int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2) +{ +	int same; +	if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0; +	else same = 1; +	if(arg1) { +		*pass1 = app_get_pass(err, arg1, same); +		if(!*pass1) return 0; +	} else if(pass1) *pass1 = NULL; +	if(arg2) { +		*pass2 = app_get_pass(err, arg2, same ? 2 : 0); +		if(!*pass2) return 0; +	} else if(pass2) *pass2 = NULL; +	return 1; +} + +static char *app_get_pass(BIO *err, char *arg, int keepbio) +{ +	char *tmp, tpass[APP_PASS_LEN]; +	static BIO *pwdbio = NULL; +	int i; +	if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5); +	if(!strncmp(arg, "env:", 4)) { +		tmp = getenv(arg + 4); +		if(!tmp) { +			BIO_printf(err, "Can't read environment variable %s\n", arg + 4); +			return NULL; +		} +		return BUF_strdup(tmp); +	} +	if(!keepbio || !pwdbio) { +		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); +				return NULL; +			} +#if !defined(_WIN32) +		/* +		 * Under _WIN32, which covers even Win64 and CE, file +		 * descriptors referenced by BIO_s_fd are not inherited +		 * by child process and therefore below is not an option. +		 * It could have been an option if bss_fd.c was operating +		 * on real Windows descriptors, such as those obtained +		 * with CreateFile. +		 */ +		} else if(!strncmp(arg, "fd:", 3)) { +			BIO *btmp; +			i = atoi(arg + 3); +			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); +				return NULL; +			} +			/* Can't do BIO_gets on an fd BIO so add a buffering BIO */ +			btmp = BIO_new(BIO_f_buffer()); +			pwdbio = BIO_push(btmp, pwdbio); +#endif +		} else if(!strcmp(arg, "stdin")) { +			pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE); +			if(!pwdbio) { +				BIO_printf(err, "Can't open BIO for stdin\n"); +				return NULL; +			} +		} else { +			BIO_printf(err, "Invalid password argument \"%s\"\n", arg); +			return NULL; +		} +	} +	i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); +	if(keepbio != 1) { +		BIO_free_all(pwdbio); +		pwdbio = NULL; +	} +	if(i <= 0) { +		BIO_printf(err, "Error reading password from BIO\n"); +		return NULL; +	} +	tmp = strchr(tpass, '\n'); +	if(tmp) *tmp = 0; +	return BUF_strdup(tpass); +} + +int add_oid_section(BIO *err, CONF *conf) +{	 +	char *p; +	STACK_OF(CONF_VALUE) *sktmp; +	CONF_VALUE *cnf; +	int i; +	if(!(p=NCONF_get_string(conf,NULL,"oid_section"))) +		{ +		ERR_clear_error(); +		return 1; +		} +	if(!(sktmp = NCONF_get_section(conf, p))) { +		BIO_printf(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", +							 cnf->name, cnf->value); +			return 0; +		} +	} +	return 1; +} + +static int load_pkcs12(BIO *err, BIO *in, const char *desc, +		pem_password_cb *pem_cb,  void *cb_data, +		EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) +	{ + 	const char *pass; +	char tpass[PEM_BUFSIZE]; +	int len, ret = 0; +	PKCS12 *p12; +	p12 = d2i_PKCS12_bio(in, NULL); +	if (p12 == NULL) +		{ +		BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);	 +		goto die; +		} +	/* See if an empty password will do */ +	if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) +		pass = ""; +	else +		{ +		if (!pem_cb) +			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); +			goto die; +			} +		if (len < PEM_BUFSIZE) +			tpass[len] = 0; +		if (!PKCS12_verify_mac(p12, tpass, len)) +			{ +			BIO_printf(err, +	"Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);	 +			goto die; +			} +		pass = tpass; +		} +	ret = PKCS12_parse(p12, pass, pkey, cert, ca); +	die: +	if (p12) +		PKCS12_free(p12); +	return ret; +	} + +X509 *load_cert(BIO *err, const char *file, int format, +	const char *pass, ENGINE *e, const char *cert_descrip) +	{ +	X509 *x=NULL; +	BIO *cert; + +	if ((cert=BIO_new(BIO_s_file())) == NULL) +		{ +		ERR_print_errors(err); +		goto end; +		} + +	if (file == NULL) +		{ +#ifdef _IONBF +# ifndef OPENSSL_NO_SETVBUF_IONBF +		setvbuf(stdin, NULL, _IONBF, 0); +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ +#endif +		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; +			} +		} + +	if 	(format == FORMAT_ASN1) +		x=d2i_X509_bio(cert,NULL); +	else if (format == FORMAT_NETSCAPE) +		{ +		NETSCAPE_X509 *nx; +		nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL); +		if (nx == NULL) +				goto end; + +		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"); +			goto end; +			} +		x=nx->cert; +		nx->cert = NULL; +		NETSCAPE_X509_free(nx); +		} +	else if (format == FORMAT_PEM) +		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)) +			goto end; +		} +	else	{ +		BIO_printf(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); +		} +	if (cert != NULL) BIO_free(cert); +	return(x); +	} + +EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, +	const char *pass, ENGINE *e, const char *key_descrip) +	{ +	BIO *key=NULL; +	EVP_PKEY *pkey=NULL; +	PW_CB_DATA cb_data; + +	cb_data.password = pass; +	cb_data.prompt_info = file; + +	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) +		{ +		BIO_printf(err,"no keyfile specified\n"); +		goto end; +		} +#ifndef OPENSSL_NO_ENGINE +	if (format == FORMAT_ENGINE) +		{ +		if (!e) +			BIO_printf(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); +				}	 +			} +		goto end; +		} +#endif +	key=BIO_new(BIO_s_file()); +	if (key == NULL) +		{ +		ERR_print_errors(err); +		goto end; +		} +	if (file == NULL && maybe_stdin) +		{ +#ifdef _IONBF +# ifndef OPENSSL_NO_SETVBUF_IONBF +		setvbuf(stdin, NULL, _IONBF, 0); +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ +#endif +		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); +			goto end; +			} +	if (format == FORMAT_ASN1) +		{ +		pkey=d2i_PrivateKey_bio(key, NULL); +		} +	else if (format == FORMAT_PEM) +		{ +		pkey=PEM_read_bio_PrivateKey(key,NULL, +			(pem_password_cb *)password_callback, &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); +#endif +	else if (format == FORMAT_PKCS12) +		{ +		if (!load_pkcs12(err, key, key_descrip, +				(pem_password_cb *)password_callback, &cb_data, +				&pkey, NULL, NULL)) +			goto end; +		} +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) +	else if (format == FORMAT_MSBLOB) +		pkey = b2i_PrivateKey_bio(key); +	else if (format == FORMAT_PVK) +		pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, +								&cb_data); +#endif +	else +		{ +		BIO_printf(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); +		}	 +	return(pkey); +	} + +EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, +	const char *pass, ENGINE *e, const char *key_descrip) +	{ +	BIO *key=NULL; +	EVP_PKEY *pkey=NULL; +	PW_CB_DATA cb_data; + +	cb_data.password = pass; +	cb_data.prompt_info = file; + +	if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) +		{ +		BIO_printf(err,"no keyfile specified\n"); +		goto end; +		} +#ifndef OPENSSL_NO_ENGINE +	if (format == FORMAT_ENGINE) +		{ +		if (!e) +			BIO_printf(bio_err,"no engine specified\n"); +		else +			pkey = ENGINE_load_public_key(e, file, +				ui_method, &cb_data); +		goto end; +		} +#endif +	key=BIO_new(BIO_s_file()); +	if (key == NULL) +		{ +		ERR_print_errors(err); +		goto end; +		} +	if (file == NULL && maybe_stdin) +		{ +#ifdef _IONBF +# ifndef OPENSSL_NO_SETVBUF_IONBF +		setvbuf(stdin, NULL, _IONBF, 0); +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ +#endif +		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); +			goto end; +		} +	if (format == FORMAT_ASN1) +		{ +		pkey=d2i_PUBKEY_bio(key, NULL); +		} +#ifndef OPENSSL_NO_RSA +	else if (format == FORMAT_ASN1RSA) +		{ +		RSA *rsa; +		rsa = d2i_RSAPublicKey_bio(key, NULL); +		if (rsa) +			{ +			pkey = EVP_PKEY_new(); +			if (pkey) +				EVP_PKEY_set1_RSA(pkey, rsa); +			RSA_free(rsa); +			} +		else +			pkey = NULL; +		} +	else if (format == FORMAT_PEMRSA) +		{ +		RSA *rsa; +		rsa = PEM_read_bio_RSAPublicKey(key, NULL,  +			(pem_password_cb *)password_callback, &cb_data); +		if (rsa) +			{ +			pkey = EVP_PKEY_new(); +			if (pkey) +				EVP_PKEY_set1_RSA(pkey, rsa); +			RSA_free(rsa); +			} +		else +			pkey = NULL; +		} +#endif +	else if (format == FORMAT_PEM) +		{ +		pkey=PEM_read_bio_PUBKEY(key,NULL, +			(pem_password_cb *)password_callback, &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); +#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: +	if (key != NULL) BIO_free(key); +	if (pkey == NULL) +		BIO_printf(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, +		const char *key_descrip, int format) +	{ +	EVP_PKEY *pkey; +	BUF_MEM *buf; +	RSA	*rsa; +	const unsigned char *p; +	int size, i; + +	buf=BUF_MEM_new(); +	pkey = EVP_PKEY_new(); +	size = 0; +	if (buf == NULL || pkey == NULL) +		goto error; +	for (;;) +		{ +		if (!BUF_MEM_grow_clean(buf,size+1024*10)) +			goto error; +		i = BIO_read(key, &(buf->data[size]), 1024*10); +		size += i; +		if (i == 0) +			break; +		if (i < 0) +			{ +				BIO_printf(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)); +	if (rsa == NULL) +		goto error; +	BUF_MEM_free(buf); +	EVP_PKEY_set1_RSA(pkey, rsa); +	return pkey; +error: +	BUF_MEM_free(buf); +	EVP_PKEY_free(pkey); +	return NULL; +	} +#endif /* ndef OPENSSL_NO_RC4 */ + +static int load_certs_crls(BIO *err, const char *file, int format, +	const char *pass, ENGINE *e, const char *desc, +	STACK_OF(X509) **pcerts, STACK_OF(X509_CRL) **pcrls) +	{ +	int i; +	BIO *bio; +	STACK_OF(X509_INFO) *xis = NULL; +	X509_INFO *xi; +	PW_CB_DATA cb_data; +	int rv = 0; + +	cb_data.password = pass; +	cb_data.prompt_info = file; + +	if (format != FORMAT_PEM) +		{ +		BIO_printf(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); +		return 0; +		} + +	xis = PEM_X509_INFO_read_bio(bio, NULL, +				(pem_password_cb *)password_callback, &cb_data); + +	BIO_free(bio); + +	if (pcerts) +		{ +		*pcerts = sk_X509_new_null(); +		if (!*pcerts) +			goto end; +		} + +	if (pcrls) +		{ +		*pcrls = sk_X509_CRL_new_null(); +		if (!*pcrls) +			goto end; +		} + +	for(i = 0; i < sk_X509_INFO_num(xis); i++) +		{ +		xi = sk_X509_INFO_value (xis, i); +		if (xi->x509 && pcerts) +			{ +			if (!sk_X509_push(*pcerts, xi->x509)) +				goto end; +			xi->x509 = NULL; +			} +		if (xi->crl && pcrls) +			{ +			if (!sk_X509_CRL_push(*pcrls, xi->crl)) +				goto end; +			xi->crl = NULL; +			} +		} + +	if (pcerts && sk_X509_num(*pcerts) > 0) +		rv = 1; + +	if (pcrls && sk_X509_CRL_num(*pcrls) > 0) +		rv = 1; + +	end: + +	if (xis) +		sk_X509_INFO_pop_free(xis, X509_INFO_free); + +	if (rv == 0) +		{ +		if (pcerts) +			{ +			sk_X509_pop_free(*pcerts, X509_free); +			*pcerts = NULL; +			} +		if (pcrls) +			{ +			sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); +			*pcrls = NULL; +			} +		BIO_printf(err,"unable to load %s\n", +				pcerts ? "certificates" : "CRLs"); +		ERR_print_errors(err); +		} +	return rv; +	} + +STACK_OF(X509) *load_certs(BIO *err, const char *file, int format, +	const char *pass, ENGINE *e, const char *desc) +	{ +	STACK_OF(X509) *certs; +	load_certs_crls(err, file, format, pass, e, desc, &certs, NULL); +	return certs; +	}	 + +STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format, +	const char *pass, ENGINE *e, const char *desc) +	{ +	STACK_OF(X509_CRL) *crls; +	load_certs_crls(err, file, format, pass, e, desc, NULL, &crls); +	return crls; +	}	 + +#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16) +/* Return error for unknown extensions */ +#define X509V3_EXT_DEFAULT		0 +/* Print error for unknown extensions */ +#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16) +/* ASN1 parse unknown extensions */ +#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16) +/* BIO_dump unknown extensions */ +#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16) + +#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ +			 X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) + +int set_cert_ex(unsigned long *flags, const char *arg) +{ +	static const NAME_EX_TBL cert_tbl[] = { +		{ "compatible", X509_FLAG_COMPAT, 0xffffffffl}, +		{ "ca_default", X509_FLAG_CA, 0xffffffffl}, +		{ "no_header", X509_FLAG_NO_HEADER, 0}, +		{ "no_version", X509_FLAG_NO_VERSION, 0}, +		{ "no_serial", X509_FLAG_NO_SERIAL, 0}, +		{ "no_signame", X509_FLAG_NO_SIGNAME, 0}, +		{ "no_validity", X509_FLAG_NO_VALIDITY, 0}, +		{ "no_subject", X509_FLAG_NO_SUBJECT, 0}, +		{ "no_issuer", X509_FLAG_NO_ISSUER, 0}, +		{ "no_pubkey", X509_FLAG_NO_PUBKEY, 0}, +		{ "no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, +		{ "no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, +		{ "no_aux", X509_FLAG_NO_AUX, 0}, +		{ "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, +		{ "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, +		{ "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, +		{ "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, +		{ "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, +		{ NULL, 0, 0} +	}; +	return set_multi_opts(flags, arg, cert_tbl); +} + +int set_name_ex(unsigned long *flags, const char *arg) +{ +	static const NAME_EX_TBL ex_tbl[] = { +		{ "esc_2253", ASN1_STRFLGS_ESC_2253, 0}, +		{ "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, +		{ "esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, +		{ "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, +		{ "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, +		{ "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, +		{ "show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, +		{ "dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, +		{ "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, +		{ "dump_der", ASN1_STRFLGS_DUMP_DER, 0}, +		{ "compat", XN_FLAG_COMPAT, 0xffffffffL}, +		{ "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, +		{ "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, +		{ "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, +		{ "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, +		{ "dn_rev", XN_FLAG_DN_REV, 0}, +		{ "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, +		{ "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, +		{ "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, +		{ "align", XN_FLAG_FN_ALIGN, 0}, +		{ "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, +		{ "space_eq", XN_FLAG_SPC_EQ, 0}, +		{ "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, +		{ "RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, +		{ "oneline", XN_FLAG_ONELINE, 0xffffffffL}, +		{ "multiline", XN_FLAG_MULTILINE, 0xffffffffL}, +		{ "ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, +		{ NULL, 0, 0} +	}; +	return set_multi_opts(flags, arg, ex_tbl); +} + +int set_ext_copy(int *copy_type, const char *arg) +{ +	if (!strcasecmp(arg, "none")) +		*copy_type = EXT_COPY_NONE; +	else if (!strcasecmp(arg, "copy")) +		*copy_type = EXT_COPY_ADD; +	else if (!strcasecmp(arg, "copyall")) +		*copy_type = EXT_COPY_ALL; +	else +		return 0; +	return 1; +} + +int copy_extensions(X509 *x, X509_REQ *req, int copy_type) +{ +	STACK_OF(X509_EXTENSION) *exts = NULL; +	X509_EXTENSION *ext, *tmpext; +	ASN1_OBJECT *obj; +	int i, idx, ret = 0; +	if (!x || !req || (copy_type == EXT_COPY_NONE)) +		return 1; +	exts = X509_REQ_get_extensions(req); + +	for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) { +		ext = sk_X509_EXTENSION_value(exts, i); +		obj = X509_EXTENSION_get_object(ext); +		idx = X509_get_ext_by_OBJ(x, obj, -1); +		/* Does extension exist? */ +		if (idx != -1) { +			/* If normal copy don't override existing extension */ +			if (copy_type == EXT_COPY_ADD) +				continue; +			/* Delete all extensions of same type */ +			do { +				tmpext = X509_get_ext(x, idx); +				X509_delete_ext(x, idx); +				X509_EXTENSION_free(tmpext); +				idx = X509_get_ext_by_OBJ(x, obj, -1); +			} while (idx != -1); +		} +		if (!X509_add_ext(x, ext, -1)) +			goto end; +	} + +	ret = 1; + +	end: + +	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + +	return ret; +} +		 +		 +			 + +static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) +{ +	STACK_OF(CONF_VALUE) *vals; +	CONF_VALUE *val; +	int i, ret = 1; +	if(!arg) return 0; +	vals = X509V3_parse_list(arg); +	for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { +		val = sk_CONF_VALUE_value(vals, i); +		if (!set_table_opts(flags, val->name, in_tbl)) +			ret = 0; +	} +	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); +	return ret; +} + +static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl) +{ +	char c; +	const NAME_EX_TBL *ptbl; +	c = arg[0]; + +	if(c == '-') { +		c = 0; +		arg++; +	} else if (c == '+') { +		c = 1; +		arg++; +	} else c = 1; + +	for(ptbl = in_tbl; ptbl->name; ptbl++) { +		if(!strcasecmp(arg, ptbl->name)) { +			*flags &= ~ptbl->mask; +			if(c) *flags |= ptbl->flag; +			else *flags &= ~ptbl->flag; +			return 1; +		} +	} +	return 0; +} + +void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags) +{ +	char *buf; +	char mline = 0; +	int indent = 0; + +	if(title) BIO_puts(out, title); +	if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { +		mline = 1; +		indent = 4; +	} +	if(lflags == XN_FLAG_COMPAT) { +		buf = X509_NAME_oneline(nm, 0, 0); +		BIO_puts(out, buf); +		BIO_puts(out, "\n"); +		OPENSSL_free(buf); +	} else { +		if(mline) BIO_puts(out, "\n"); +		X509_NAME_print_ex(out, nm, indent, lflags); +		BIO_puts(out, "\n"); +	} +} + +X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath) +{ +	X509_STORE *store; +	X509_LOOKUP *lookup; +	if(!(store = X509_STORE_new())) 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); +			goto end; +		} +	} else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); +		 +	lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); +	if (lookup == NULL) goto end; +	if (CApath) { +		if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) { +			BIO_printf(bp, "Error loading directory %s\n", CApath); +			goto end; +		} +	} else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); + +	ERR_clear_error(); +	return store; +	end: +	X509_STORE_free(store); +	return NULL; +} + +#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) +	{ +	ENGINE *e = ENGINE_by_id("dynamic"); +	if (e) +		{ +		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) +			|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) +			{ +			ENGINE_free(e); +			e = NULL; +			} +		} +	return e; +	} + +ENGINE *setup_engine(BIO *err, const char *engine, int debug) +        { +        ENGINE *e = NULL; + +        if (engine) +                { +		if(strcmp(engine, "auto") == 0) +			{ +			BIO_printf(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); +			return NULL; +			} +		if (debug) +			{ +			ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, +				0, 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); +			ENGINE_free(e); +			return NULL; +			} + +		BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e)); + +		/* Free our "structural" reference. */ +		ENGINE_free(e); +		} +        return e; +        } +#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); +	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; + +	n=a[DB_serial]; +	while (*n == '0') n++; +	return(lh_strhash(n)); +	} + +static int index_serial_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) +	{ +	const char *aa,*bb; + +	for (aa=a[DB_serial]; *aa == '0'; aa++); +	for (bb=b[DB_serial]; *bb == '0'; bb++); +	return(strcmp(aa,bb)); +	} + +static int index_name_qual(char **a) +	{ return(a[0][0] == 'V'); } + +static unsigned long index_name_hash(const OPENSSL_CSTRING *a) +	{ return(lh_strhash(a[DB_name])); } + +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) +	{ return(strcmp(a[DB_name], b[DB_name])); } + +static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) +static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) + +#undef BSIZE +#define BSIZE 256 + +BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) +	{ +	BIO *in=NULL; +	BIGNUM *ret=NULL; +	MS_STATIC char buf[1024]; +	ASN1_INTEGER *ai=NULL; + +	ai=ASN1_INTEGER_new(); +	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) +		{ +		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"); +			} +		} +	else +		{ +		if (!a2i_ASN1_INTEGER(in,ai,buf,1024)) +			{ +			BIO_printf(bio_err,"unable to load number from %s\n", +				serialfile); +			goto err; +			} +		ret=ASN1_INTEGER_to_BN(ai,NULL); +		if (ret == NULL) +			{ +			BIO_printf(bio_err,"error converting number from bin to BIGNUM\n"); +			goto err; +			} +		} + +	if (ret && retai) +		{ +		*retai = ai; +		ai = NULL; +		} + err: +	if (in != NULL) BIO_free(in); +	if (ai != NULL) ASN1_INTEGER_free(ai); +	return(ret); +	} + +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai) +	{ +	char buf[1][BSIZE]; +	BIO *out = NULL; +	int ret=0; +	ASN1_INTEGER *ai=NULL; +	int j; + +	if (suffix == NULL) +		j = strlen(serialfile); +	else +		j = strlen(serialfile) + strlen(suffix) + 1; +	if (j >= BSIZE) +		{ +		BIO_printf(bio_err,"file name too long\n"); +		goto err; +		} + +	if (suffix == NULL) +		BUF_strlcpy(buf[0], serialfile, BSIZE); +	else +		{ +#ifndef OPENSSL_SYS_VMS +		j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); +#else +		j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); +#endif +		} +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); +#endif +	out=BIO_new(BIO_s_file()); +	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"); +		goto err; +		} +	i2a_ASN1_INTEGER(out,ai); +	BIO_puts(out,"\n"); +	ret=1; +	if (retai) +		{ +		*retai = ai; +		ai = NULL; +		} +err: +	if (out != NULL) BIO_free_all(out); +	if (ai != NULL) ASN1_INTEGER_free(ai); +	return(ret); +	} + +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) +	{ +	char buf[5][BSIZE]; +	int i,j; + +	i = strlen(serialfile) + strlen(old_suffix); +	j = strlen(serialfile) + strlen(new_suffix); +	if (i > j) j = i; +	if (j + 1 >= BSIZE) +		{ +		BIO_printf(bio_err,"file name too long\n"); +		goto err; +		} + +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", +		serialfile, new_suffix); +#else +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", +		serialfile, new_suffix); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", +		serialfile, old_suffix); +#else +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", +		serialfile, old_suffix); +#endif +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		serialfile, buf[1]); +#endif +	if (rename(serialfile,buf[1]) < 0 && errno != ENOENT +#ifdef ENOTDIR +			&& errno != ENOTDIR +#endif +	   )		{ +			BIO_printf(bio_err, +				"unable to rename %s to %s\n", +				serialfile, buf[1]); +			perror("reason"); +			goto err; +			} +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		buf[0],serialfile); +#endif +	if (rename(buf[0],serialfile) < 0) +		{ +		BIO_printf(bio_err, +			"unable to rename %s to %s\n", +			buf[0],serialfile); +		perror("reason"); +		rename(buf[1],serialfile); +		goto err; +		} +	return 1; + err: +	return 0; +	} + +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) +	{ +	BIGNUM *btmp; +	int ret = 0; +	if (b) +		btmp = b; +	else +		btmp = BN_new(); + +	if (!btmp) +		return 0; + +	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) +		goto error; +	if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) +		goto error; + +	ret = 1; +	 +	error: + +	if (!b) +		BN_free(btmp); +	 +	return ret; +	} + +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()); +	CONF *dbattr_conf = NULL; +	char buf[1][BSIZE]; +	long errorline= -1; + +	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; + +#ifndef OPENSSL_SYS_VMS +	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile); +#else +	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile); +#endif +	dbattr_conf = NCONF_new(NULL); +	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0) +		{ +		if (errorline > 0) +			{ +			BIO_printf(bio_err, +				"error on line %ld of db attribute file '%s'\n" +				,errorline,buf[0]); +			goto err; +			} +		else +			{ +			NCONF_free(dbattr_conf); +			dbattr_conf = NULL; +			} +		} + +	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) +		{ +		fprintf(stderr, "Out of memory\n"); +		goto err; +		} + +	retdb->db = tmpdb; +	tmpdb = NULL; +	if (db_attr) +		retdb->attributes = *db_attr; +	else +		{ +		retdb->attributes.unique_subject = 1; +		} + +	if (dbattr_conf) +		{ +		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject"); +		if (p) +			{ +#ifdef RL_DEBUG +			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p); +#endif +			retdb->attributes.unique_subject = parse_yesno(p,1); +			} +		} + + err: +	if (dbattr_conf) NCONF_free(dbattr_conf); +	if (tmpdb) TXT_DB_free(tmpdb); +	if (in) BIO_free_all(in); +	return retdb; +	} + +int index_index(CA_DB *db) +	{ +	if (!TXT_DB_create_index(db->db, DB_serial, NULL, +				LHASH_HASH_FN(index_serial), +				LHASH_COMP_FN(index_serial))) +		{ +		BIO_printf(bio_err, +		  "error creating serial number index:(%ld,%ld,%ld)\n", +		  			db->db->error,db->db->arg1,db->db->arg2); +			return 0; +		} + +	if (db->attributes.unique_subject +		&& !TXT_DB_create_index(db->db, DB_name, index_name_qual, +			LHASH_HASH_FN(index_name), +			LHASH_COMP_FN(index_name))) +		{ +		BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n", +			db->db->error,db->db->arg1,db->db->arg2); +		return 0; +		} +	return 1; +	} + +int save_index(const char *dbfile, const char *suffix, CA_DB *db) +	{ +	char buf[3][BSIZE]; +	BIO *out = BIO_new(BIO_s_file()); +	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"); +		goto err; +		} + +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); +#else +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); +#else +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); +#else +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); +#endif +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]); +#endif +	if (BIO_write_filename(out,buf[0]) <= 0) +		{ +		perror(dbfile); +		BIO_printf(bio_err,"unable to open '%s'\n", dbfile); +		goto err; +		} +	j=TXT_DB_write(out,db->db); +	if (j <= 0) goto err; +			 +	BIO_free(out); + +	out = BIO_new(BIO_s_file()); +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]); +#endif +	if (BIO_write_filename(out,buf[1]) <= 0) +		{ +		perror(buf[2]); +		BIO_printf(bio_err,"unable to open '%s'\n", buf[2]); +		goto err; +		} +	BIO_printf(out,"unique_subject = %s\n", +		db->attributes.unique_subject ? "yes" : "no"); +	BIO_free(out); + +	return 1; + err: +	return 0; +	} + +int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) +	{ +	char buf[5][BSIZE]; +	int i,j; + +	i = strlen(dbfile) + strlen(old_suffix); +	j = strlen(dbfile) + strlen(new_suffix); +	if (i > j) j = i; +	if (j + 6 >= BSIZE) +		{ +		BIO_printf(bio_err,"file name too long\n"); +		goto err; +		} + +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); +#else +	j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", +		dbfile, new_suffix); +#else +	j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", +		dbfile, new_suffix); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", +		dbfile, new_suffix); +#else +	j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", +		dbfile, new_suffix); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", +		dbfile, old_suffix); +#else +	j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", +		dbfile, old_suffix); +#endif +#ifndef OPENSSL_SYS_VMS +	j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", +		dbfile, old_suffix); +#else +	j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", +		dbfile, old_suffix); +#endif +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		dbfile, buf[1]); +#endif +	if (rename(dbfile,buf[1]) < 0 && errno != ENOENT +#ifdef ENOTDIR +		&& errno != ENOTDIR +#endif +	   )		{ +			BIO_printf(bio_err, +				"unable to rename %s to %s\n", +				dbfile, buf[1]); +			perror("reason"); +			goto err; +			} +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		buf[0],dbfile); +#endif +	if (rename(buf[0],dbfile) < 0) +		{ +		BIO_printf(bio_err, +			"unable to rename %s to %s\n", +			buf[0],dbfile); +		perror("reason"); +		rename(buf[1],dbfile); +		goto err; +		} +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		buf[4],buf[3]); +#endif +	if (rename(buf[4],buf[3]) < 0 && errno != ENOENT +#ifdef ENOTDIR +		&& errno != ENOTDIR +#endif +	   )		{ +			BIO_printf(bio_err, +				"unable to rename %s to %s\n", +				buf[4], buf[3]); +			perror("reason"); +			rename(dbfile,buf[0]); +			rename(buf[1],dbfile); +			goto err; +			} +#ifdef RL_DEBUG +	BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", +		buf[2],buf[4]); +#endif +	if (rename(buf[2],buf[4]) < 0) +		{ +		BIO_printf(bio_err, +			"unable to rename %s to %s\n", +			buf[2],buf[4]); +		perror("reason"); +		rename(buf[3],buf[4]); +		rename(dbfile,buf[0]); +		rename(buf[1],dbfile); +		goto err; +		} +	return 1; + err: +	return 0; +	} + +void free_index(CA_DB *db) +	{ +	if (db) +		{ +		if (db->db) TXT_DB_free(db->db); +		OPENSSL_free(db); +		} +	} + +int parse_yesno(const char *str, int def) +	{ +	int ret = def; +	if (str) +		{ +		switch (*str) +			{ +		case 'f': /* false */ +		case 'F': /* FALSE */ +		case 'n': /* no */ +		case 'N': /* NO */ +		case '0': /* 0 */ +			ret = 0; +			break; +		case 't': /* true */ +		case 'T': /* TRUE */ +		case 'y': /* yes */ +		case 'Y': /* YES */ +		case '1': /* 1 */ +			ret = 1; +			break; +		default: +			ret = def; +			break; +			} +		} +	return ret; +	} + +/* + * subject is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ +X509_NAME *parse_name(char *subject, long chtype, int multirdn) +	{ +	size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ +	char *buf = OPENSSL_malloc(buflen); +	size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ +	char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); +	char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); +	int *mval = OPENSSL_malloc (max_ne * sizeof (int)); + +	char *sp = subject, *bp = buf; +	int i, ne_num = 0; + +	X509_NAME *n = NULL; +	int nid; + +	if (!buf || !ne_types || !ne_values) +		{ +		BIO_printf(bio_err, "malloc error\n"); +		goto error; +		}	 + +	if (*subject != '/') +		{ +		BIO_printf(bio_err, "Subject does not start with '/'.\n"); +		goto error; +		} +	sp++; /* skip leading / */ + +	/* no multivalued RDN by default */ +	mval[ne_num] = 0; + +	while (*sp) +		{ +		/* collect type */ +		ne_types[ne_num] = bp; +		while (*sp) +			{ +			if (*sp == '\\') /* is there anything to escape in the type...? */ +				{ +				if (*++sp) +					*bp++ = *sp++; +				else	 +					{ +					BIO_printf(bio_err, "escape character at end of string\n"); +					goto error; +					} +				}	 +			else if (*sp == '=') +				{ +				sp++; +				*bp++ = '\0'; +				break; +				} +			else +				*bp++ = *sp++; +			} +		if (!*sp) +			{ +			BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num); +			goto error; +			} +		ne_values[ne_num] = bp; +		while (*sp) +			{ +			if (*sp == '\\') +				{ +				if (*++sp) +					*bp++ = *sp++; +				else +					{ +					BIO_printf(bio_err, "escape character at end of string\n"); +					goto error; +					} +				} +			else if (*sp == '/') +				{ +				sp++; +				/* no multivalued RDN by default */ +				mval[ne_num+1] = 0; +				break; +				} +			else if (*sp == '+' && multirdn) +				{ +				/* a not escaped + signals a mutlivalued RDN */ +				sp++; +				mval[ne_num+1] = -1; +				break; +				} +			else +				*bp++ = *sp++; +			} +		*bp++ = '\0'; +		ne_num++; +		}	 + +	if (!(n = X509_NAME_new())) +		goto error; + +	for (i = 0; i < ne_num; i++) +		{ +		if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef) +			{ +			BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]); +			continue; +			} + +		if (!*ne_values[i]) +			{ +			BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]); +			continue; +			} + +		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i])) +			goto error; +		} + +	OPENSSL_free(ne_values); +	OPENSSL_free(ne_types); +	OPENSSL_free(buf); +	return n; + +error: +	X509_NAME_free(n); +	if (ne_values) +		OPENSSL_free(ne_values); +	if (ne_types) +		OPENSSL_free(ne_types); +	if (buf) +		OPENSSL_free(buf); +	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]; +	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_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, "-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 +		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 (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); + +	end: + +	(*pargs)++; + +	if (pargc) +		*pargc -= *pargs - oldargs; + +	return 1; + +	} + +/* Read whole contents of a BIO into an allocated memory buffer and + * return it. + */ + +int bio_to_mem(unsigned char **out, int maxlen, BIO *in) +	{ +	BIO *mem; +	int len, ret; +	unsigned char tbuf[1024]; +	mem = BIO_new(BIO_s_mem()); +	if (!mem) +		return -1; +	for(;;) +		{ +		if ((maxlen != -1) && maxlen < 1024) +			len = maxlen; +		else +			len = 1024; +		len = BIO_read(in, tbuf, len); +		if (len <= 0) +			break; +		if (BIO_write(mem, tbuf, len) != len) +			{ +			BIO_free(mem); +			return -1; +			} +		maxlen -= len; + +		if (maxlen == 0) +			break; +		} +	ret = BIO_get_mem_data(mem, (char **)out); +	BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); +	BIO_free(mem); +	return ret; +	} + +int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value) +	{ +	int rv; +	char *stmp, *vtmp = NULL; +	stmp = BUF_strdup(value); +	if (!stmp) +		return -1; +	vtmp = strchr(stmp, ':'); +	if (vtmp) +		{ +		*vtmp = 0; +		vtmp++; +		} +	rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); +	OPENSSL_free(stmp); +	return rv; +	} + +static void nodes_print(BIO *out, const char *name, +	STACK_OF(X509_POLICY_NODE) *nodes) +	{ +	X509_POLICY_NODE *node; +	int i; +	BIO_printf(out, "%s Policies:", name); +	if (nodes) +		{ +		BIO_puts(out, "\n"); +		for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) +			{ +			node = sk_X509_POLICY_NODE_value(nodes, i); +			X509_POLICY_NODE_print(out, node, 2); +			} +		} +	else +		BIO_puts(out, " <empty>\n"); +	} + +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); + +	BIO_printf(out, "Require explicit Policy: %s\n", +				explicit_policy ? "True" : "False"); + +	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) + +static JPAKE_CTX *jpake_init(const char *us, const char *them, +							 const char *secret) +	{ +	BIGNUM *p = NULL; +	BIGNUM *g = NULL; +	BIGNUM *q = NULL; +	BIGNUM *bnsecret = BN_new(); +	JPAKE_CTX *ctx; + +	/* Use a safe prime for p (that we found earlier) */ +	BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F"); +	g = BN_new(); +	BN_set_word(g, 2); +	q = BN_new(); +	BN_rshift1(q, p); + +	BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret); + +	ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret); +	BN_free(bnsecret); +	BN_free(q); +	BN_free(g); +	BN_free(p); + +	return ctx; +	} + +static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p) +	{ +	BN_print(conn, p->gx); +	BIO_puts(conn, "\n"); +	BN_print(conn, p->zkpx.gr); +	BIO_puts(conn, "\n"); +	BN_print(conn, p->zkpx.b); +	BIO_puts(conn, "\n"); +	} + +static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx) +	{ +	JPAKE_STEP1 s1; + +	JPAKE_STEP1_init(&s1); +	JPAKE_STEP1_generate(&s1, ctx); +	jpake_send_part(bconn, &s1.p1); +	jpake_send_part(bconn, &s1.p2); +	(void)BIO_flush(bconn); +	JPAKE_STEP1_release(&s1); +	} + +static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx) +	{ +	JPAKE_STEP2 s2; + +	JPAKE_STEP2_init(&s2); +	JPAKE_STEP2_generate(&s2, ctx); +	jpake_send_part(bconn, &s2); +	(void)BIO_flush(bconn); +	JPAKE_STEP2_release(&s2); +	} + +static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx) +	{ +	JPAKE_STEP3A s3a; + +	JPAKE_STEP3A_init(&s3a); +	JPAKE_STEP3A_generate(&s3a, ctx); +	BIO_write(bconn, s3a.hhk, sizeof s3a.hhk); +	(void)BIO_flush(bconn); +	JPAKE_STEP3A_release(&s3a); +	} + +static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx) +	{ +	JPAKE_STEP3B s3b; + +	JPAKE_STEP3B_init(&s3b); +	JPAKE_STEP3B_generate(&s3b, ctx); +	BIO_write(bconn, s3b.hk, sizeof s3b.hk); +	(void)BIO_flush(bconn); +	JPAKE_STEP3B_release(&s3b); +	} + +static void readbn(BIGNUM **bn, BIO *bconn) +	{ +	char buf[10240]; +	int l; + +	l = BIO_gets(bconn, buf, sizeof buf); +	assert(l > 0); +	assert(buf[l-1] == '\n'); +	buf[l-1] = '\0'; +	BN_hex2bn(bn, buf); +	} + +static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn) +	{ +	readbn(&p->gx, bconn); +	readbn(&p->zkpx.gr, bconn); +	readbn(&p->zkpx.b, bconn); +	} + +static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn) +	{ +	JPAKE_STEP1 s1; + +	JPAKE_STEP1_init(&s1); +	jpake_receive_part(&s1.p1, bconn); +	jpake_receive_part(&s1.p2, bconn); +	if(!JPAKE_STEP1_process(ctx, &s1)) +		{ +		ERR_print_errors(bio_err); +		exit(1); +		} +	JPAKE_STEP1_release(&s1); +	} + +static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn) +	{ +	JPAKE_STEP2 s2; + +	JPAKE_STEP2_init(&s2); +	jpake_receive_part(&s2, bconn); +	if(!JPAKE_STEP2_process(ctx, &s2)) +		{ +		ERR_print_errors(bio_err); +		exit(1); +		} +	JPAKE_STEP2_release(&s2); +	} + +static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn) +	{ +	JPAKE_STEP3A s3a; +	int l; + +	JPAKE_STEP3A_init(&s3a); +	l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk); +	assert(l == sizeof s3a.hhk); +	if(!JPAKE_STEP3A_process(ctx, &s3a)) +		{ +		ERR_print_errors(bio_err); +		exit(1); +		} +	JPAKE_STEP3A_release(&s3a); +	} + +static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn) +	{ +	JPAKE_STEP3B s3b; +	int l; + +	JPAKE_STEP3B_init(&s3b); +	l = BIO_read(bconn, s3b.hk, sizeof s3b.hk); +	assert(l == sizeof s3b.hk); +	if(!JPAKE_STEP3B_process(ctx, &s3b)) +		{ +		ERR_print_errors(bio_err); +		exit(1); +		} +	JPAKE_STEP3B_release(&s3b); +	} + +void jpake_client_auth(BIO *out, BIO *conn, const char *secret) +	{ +	JPAKE_CTX *ctx; +	BIO *bconn; + +	BIO_puts(out, "Authenticating with JPAKE\n"); + +	ctx = jpake_init("client", "server", secret); + +	bconn = BIO_new(BIO_f_buffer()); +	BIO_push(bconn, conn); + +	jpake_send_step1(bconn, ctx); +	jpake_receive_step1(ctx, bconn); +	jpake_send_step2(bconn, ctx); +	jpake_receive_step2(ctx, bconn); +	jpake_send_step3a(bconn, ctx); +	jpake_receive_step3b(ctx, bconn); + +	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + +	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); + +	BIO_pop(bconn); +	BIO_free(bconn); + +	JPAKE_CTX_free(ctx); +	} + +void jpake_server_auth(BIO *out, BIO *conn, const char *secret) +	{ +	JPAKE_CTX *ctx; +	BIO *bconn; + +	BIO_puts(out, "Authenticating with JPAKE\n"); + +	ctx = jpake_init("server", "client", secret); + +	bconn = BIO_new(BIO_f_buffer()); +	BIO_push(bconn, conn); + +	jpake_receive_step1(ctx, bconn); +	jpake_send_step1(bconn, ctx); +	jpake_receive_step2(ctx, bconn); +	jpake_send_step2(bconn, ctx); +	jpake_receive_step3a(ctx, bconn); +	jpake_send_step3b(bconn, ctx); + +	BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n"); + +	psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx)); + +	BIO_pop(bconn); +	BIO_free(bconn); + +	JPAKE_CTX_free(ctx); +	} + +#endif + +/* + * Platform-specific sections + */ +#if defined(_WIN32) +# ifdef fileno +#  undef fileno +#  define fileno(a) (int)_fileno(a) +# endif + +# include <windows.h> +# include <tchar.h> + +static int WIN32_rename(const char *from, const char *to) +	{ +	TCHAR  *tfrom=NULL,*tto; +	DWORD	err; +	int	ret=0; + +	if (sizeof(TCHAR) == 1) +		{ +		tfrom = (TCHAR *)from; +		tto   = (TCHAR *)to; +		} +	else	/* UNICODE path */ +		{ +		size_t i,flen=strlen(from)+1,tlen=strlen(to)+1; +		tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen)); +		if (tfrom==NULL) goto err; +		tto=tfrom+flen; +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101 +		if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen)) +#endif +			for (i=0;i<flen;i++)	tfrom[i]=(TCHAR)from[i]; +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101 +		if (!MultiByteToWideChar(CP_ACP,0,to,  tlen,(WCHAR *)tto,  tlen)) +#endif +			for (i=0;i<tlen;i++)	tto[i]  =(TCHAR)to[i]; +		} + +	if (MoveFile(tfrom,tto))	goto ok; +	err=GetLastError(); +	if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS) +		{ +		if (DeleteFile(tto) && MoveFile(tfrom,tto)) +			goto ok; +		err=GetLastError(); +		} +	if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND) +		errno = ENOENT; +	else if (err==ERROR_ACCESS_DENIED) +		errno = EACCES; +	else +		errno = EINVAL;	/* we could map more codes... */ +err: +	ret=-1; +ok: +	if (tfrom!=NULL && tfrom!=(TCHAR *)from)	free(tfrom); +	return ret; +	} +#endif + +/* app_tminterval section */ +#if defined(_WIN32) +double app_tminterval(int stop,int usertime) +	{ +	FILETIME		now; +	double			ret=0; +	static ULARGE_INTEGER	tmstart; +	static int		warning=1; +#ifdef _WIN32_WINNT +	static HANDLE		proc=NULL; + +	if (proc==NULL) +		{ +		if (GetVersion() < 0x80000000) +			proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE, +						GetCurrentProcessId()); +		if (proc==NULL) proc = (HANDLE)-1; +		} + +	if (usertime && proc!=(HANDLE)-1) +		{ +		FILETIME junk; +		GetProcessTimes(proc,&junk,&junk,&junk,&now); +		} +	else +#endif +		{ +		SYSTEMTIME systime; + +		if (usertime && warning) +			{ +			BIO_printf(bio_err,"To get meaningful results, run " +					   "this program on idle system.\n"); +			warning=0; +			} +		GetSystemTime(&systime); +		SystemTimeToFileTime(&systime,&now); +		} + +	if (stop==TM_START) +		{ +		tmstart.u.LowPart  = now.dwLowDateTime; +		tmstart.u.HighPart = now.dwHighDateTime; +		} +	else	{ +		ULARGE_INTEGER tmstop; + +		tmstop.u.LowPart   = now.dwLowDateTime; +		tmstop.u.HighPart  = now.dwHighDateTime; + +		ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7; +		} + +	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; + +	if (usertime && warning) +		{ +		BIO_printf(bio_err,"To get meaningful results, run " +				   "this program on idle system.\n"); +		warning=0; +		} + +	if (stop==TM_START)	tmstart = clock(); +	else			ret     = (clock()-tmstart)/(double)CLOCKS_PER_SEC; + +	return (ret); +	} + +#elif defined(OPENSSL_SYSTEM_VXWORKS) +#include <time.h> + +double app_tminterval(int stop,int usertime) +	{ +	double ret=0; +#ifdef CLOCK_REALTIME +	static struct timespec	tmstart; +	struct timespec		now; +#else +	static unsigned long	tmstart; +	unsigned long		now; +#endif +	static int warning=1; + +	if (usertime && warning) +		{ +		BIO_printf(bio_err,"To get meaningful results, run " +				   "this program on idle system.\n"); +		warning=0; +		} + +#ifdef CLOCK_REALTIME +	clock_gettime(CLOCK_REALTIME,&now); +	if (stop==TM_START)	tmstart = now; +	else	ret = ( (now.tv_sec+now.tv_nsec*1e-9) +			- (tmstart.tv_sec+tmstart.tv_nsec*1e-9) ); +#else +	now = tickGet(); +	if (stop==TM_START)	tmstart = now; +	else			ret = (now - tmstart)/(double)sysClkRateGet(); +#endif +	return (ret); +	} + +#elif defined(OPENSSL_SYSTEM_VMS) +#include <time.h> +#include <times.h> + +double app_tminterval(int stop,int usertime) +	{ +	static clock_t	tmstart; +	double		ret = 0; +	clock_t		now; +#ifdef __TMS +	struct tms	rus; + +	now = times(&rus); +	if (usertime)	now = rus.tms_utime; +#else +	if (usertime) +		now = clock(); /* sum of user and kernel times */ +	else	{ +		struct timeval tv; +		gettimeofday(&tv,NULL); +		now = (clock_t)( +			(unsigned long long)tv.tv_sec*CLK_TCK + +			(unsigned long long)tv.tv_usec*(1000000/CLK_TCK) +			); +		} +#endif +	if (stop==TM_START)	tmstart = now; +	else			ret = (now - tmstart)/(double)(CLK_TCK); + +	return (ret); +	} + +#elif defined(_SC_CLK_TCK)	/* by means of unistd.h */ +#include <sys/times.h> + +double app_tminterval(int stop,int usertime) +	{ +	double		ret = 0; +	struct tms	rus; +	clock_t		now = times(&rus); +	static clock_t	tmstart; + +	if (usertime)		now = rus.tms_utime; + +	if (stop==TM_START)	tmstart = now; +	else +		{ +		long int tck = sysconf(_SC_CLK_TCK); +		ret = (now - tmstart)/(double)tck; +		} + +	return (ret); +	} + +#else +#include <sys/time.h> +#include <sys/resource.h> + +double app_tminterval(int stop,int usertime) +	{ +	double		ret = 0; +	struct rusage	rus; +	struct timeval	now; +	static struct timeval tmstart; + +	if (usertime)		getrusage(RUSAGE_SELF,&rus), now = rus.ru_utime; +	else			gettimeofday(&now,NULL); + +	if (stop==TM_START)	tmstart = now; +	else			ret = ( (now.tv_sec+now.tv_usec*1e-6) +					- (tmstart.tv_sec+tmstart.tv_usec*1e-6) ); + +	return ret; +	} +#endif + +/* app_isdir section */ +#ifdef _WIN32 +int app_isdir(const char *name) +	{ +	HANDLE		hList; +	WIN32_FIND_DATA	FileData; +#if defined(UNICODE) || defined(_UNICODE) +	size_t i, len_0 = strlen(name)+1; + +	if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0])) +		return -1; + +#if !defined(_WIN32_WCE) || _WIN32_WCE>=101 +	if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0)) +#endif +		for (i=0;i<len_0;i++) +			FileData.cFileName[i] = (WCHAR)name[i]; + +	hList = FindFirstFile(FileData.cFileName,&FileData); +#else +	hList = FindFirstFile(name,&FileData); +#endif +	if (hList == INVALID_HANDLE_VALUE)	return -1; +	FindClose(hList); +	return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0); +	} +#else +#include <sys/stat.h> +#ifndef S_ISDIR +# if defined(_S_IFMT) && defined(_S_IFDIR) +#  define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR) +# else  +#  define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR) +# endif  +#endif  + +int app_isdir(const char *name) +	{ +#if defined(S_ISDIR) +	struct stat st; + +	if (stat(name,&st)==0)	return S_ISDIR(st.st_mode); +	else			return -1; +#else +	return -1; +#endif +	} +#endif + +/* raw_read|write section */ +#if defined(_WIN32) && defined(STD_INPUT_HANDLE) +int raw_read_stdin(void *buf,int siz) +	{ +	DWORD n; +	if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL)) +		return (n); +	else	return (-1); +	} +#else +int raw_read_stdin(void *buf,int siz) +	{	return read(fileno(stdin),buf,siz);	} +#endif + +#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE) +int raw_write_stdout(const void *buf,int siz) +	{ +	DWORD n; +	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL)) +		return (n); +	else	return (-1); +	} +#else +int raw_write_stdout(const void *buf,int siz) +	{	return write(fileno(stdout),buf,siz);	} +#endif + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +/* next_protos_parse parses a comma separated list of strings into a string + * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. + *   outlen: (output) set to the length of the resulting buffer on success. + *   in: a NUL termianted string like "abc,def,ghi" + * + *   returns: a malloced buffer or NULL on failure. + */ +unsigned char *next_protos_parse(unsigned short *outlen, const char *in) +	{ +	size_t len; +	unsigned char *out; +	size_t i, start = 0; + +	len = strlen(in); +	if (len >= 65535) +		return NULL; + +	out = OPENSSL_malloc(strlen(in) + 1); +	if (!out) +		return NULL; + +	for (i = 0; i <= len; ++i) +		{ +		if (i == len || in[i] == ',') +			{ +			if (i - start > 255) +				{ +				OPENSSL_free(out); +				return NULL; +				} +			out[start] = i - start; +			start = i + 1; +			} +		else +			out[i+1] = in[i]; +		} + +	*outlen = len + 1; +	return out; +	} +#endif  /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */ diff --git a/main/openssl/apps/apps.h b/main/openssl/apps/apps.h new file mode 100644 index 00000000..42072ec4 --- /dev/null +++ b/main/openssl/apps/apps.h @@ -0,0 +1,364 @@ +/* apps/apps.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_APPS_H +#define HEADER_APPS_H + +#include "e_os.h" + +#include <openssl/bio.h> +#include <openssl/x509.h> +#include <openssl/lhash.h> +#include <openssl/conf.h> +#include <openssl/txt_db.h> +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif +#ifndef OPENSSL_NO_OCSP +#include <openssl/ocsp.h> +#endif +#include <openssl/ossl_typ.h> + +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); +/* When `file' is NULL, use defaults. + * `bio_e' is for error messages. */ +void app_RAND_allow_write_file(void); +long app_RAND_load_files(char *file); /* `file' is a list of files to read, +                                       * separated by LIST_SEPARATOR_CHAR +                                       * (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_err; + +#endif + +#ifndef OPENSSL_SYS_NETWARE +#include <signal.h> +#endif + +#ifdef SIGPIPE +#define do_pipe_sig()	signal(SIGPIPE,SIG_IGN) +#else +#define do_pipe_sig() +#endif + +#ifdef OPENSSL_NO_COMP +#define zlib_cleanup()  +#else +#define zlib_cleanup() COMP_zlib_cleanup() +#endif + +#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); \ +			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); \ +			ERR_free_strings(); zlib_cleanup(); } while(0) +#  endif +#endif + +#ifdef OPENSSL_SYSNAME_WIN32 +#  define openssl_fdset(a,b) FD_SET((unsigned int)a, b) +#else +#  define openssl_fdset(a,b) FD_SET(a, b) +#endif + + +typedef struct args_st +	{ +	char **data; +	int count; +	} ARGS; + +#define PW_MIN_LENGTH 4 +typedef struct pw_cb_data +	{ +	const void *password; +	const char *prompt_info; +	} PW_CB_DATA; + +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[]); +#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 +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, +	const char *pass, ENGINE *e, const char *cert_descrip); +EVP_PKEY *load_key(BIO *err, 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, +	const char *pass, ENGINE *e, const char *key_descrip); +STACK_OF(X509) *load_certs(BIO *err, 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, +	const char *pass, ENGINE *e, const char *cert_descrip); +X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath); +#ifndef OPENSSL_NO_ENGINE +ENGINE *setup_engine(BIO *err, const char *engine, int debug); +#endif + +#ifndef OPENSSL_NO_OCSP +OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, +			char *host, char *path, char *port, int use_ssl, +			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); + +#define DB_type         0 +#define DB_exp_date     1 +#define DB_rev_date     2 +#define DB_serial       3       /* index - unique */ +#define DB_file         4        +#define DB_name         5       /* index - unique when active and not disabled */ +#define DB_NUMBER       6 + +#define DB_TYPE_REV	'R' +#define DB_TYPE_EXP	'E' +#define DB_TYPE_VAL	'V' + +typedef struct db_attr_st +	{ +	int unique_subject; +	} DB_ATTR; +typedef struct ca_db_st +	{ +	DB_ATTR attributes; +	TXT_DB *db; +	} CA_DB; + +BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai); +int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai); +int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix); +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); +CA_DB *load_index(char *dbfile, DB_ATTR *dbattr); +int index_index(CA_DB *db); +int save_index(const char *dbfile, const char *suffix, CA_DB *db); +int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix); +void free_index(CA_DB *db); +#define index_name_cmp_noconst(a, b) \ +	index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ +	(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) +int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); +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); +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, +			const char *algname, ENGINE *e, int do_param); +#ifndef OPENSSL_NO_PSK +extern char *psk_key; +#endif +#ifndef OPENSSL_NO_JPAKE +void jpake_client_auth(BIO *out, BIO *conn, const char *secret); +void jpake_server_auth(BIO *out, BIO *conn, const char *secret); +#endif + +#define FORMAT_UNDEF    0 +#define FORMAT_ASN1     1 +#define FORMAT_TEXT     2 +#define FORMAT_PEM      3 +#define FORMAT_NETSCAPE 4 +#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 */ +#define FORMAT_PVK	12	/* MS PVK file format */ + +#define EXT_COPY_NONE	0 +#define EXT_COPY_ADD	1 +#define EXT_COPY_ALL	2 + +#define NETSCAPE_CERT_HDR	"certificate" + +#define APP_PASS_LEN	1024 + +#define SERIAL_RAND_BITS	64 + +int app_isdir(const char *); +int raw_read_stdin(void *,int); +int raw_write_stdout(const void *,int); + +#define TM_START	0 +#define TM_STOP		1 +double app_tminterval (int stop,int usertime); +#endif + +#ifndef OPENSSL_NO_NEXTPROTONEG +unsigned char *next_protos_parse(unsigned short *outlen, const char *in); +#endif diff --git a/main/openssl/apps/asn1pars.c b/main/openssl/apps/asn1pars.c new file mode 100644 index 00000000..0d660707 --- /dev/null +++ b/main/openssl/apps/asn1pars.c @@ -0,0 +1,445 @@ +/* apps/asn1pars.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.] + */ + +/* A nice addition from Dr Stephen Henson <steve@openssl.org> to  + * add the -strparse option which parses nested binary structures + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/err.h> +#include <openssl/evp.h> +#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 **); + +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf); + +int 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; +	char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL; +	char *genstr=NULL, *genconf=NULL; +	unsigned char *tmpbuf; +	const unsigned char *ctmpbuf; +	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); + +	if (!load_config(bio_err, NULL)) +		goto end; + +	prog=argv[0]; +	argc--; +	argv++; +	if ((osk=sk_OPENSSL_STRING_new_null()) == NULL) +		{ +		BIO_printf(bio_err,"Memory allocation failure\n"); +		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) +			{ +			indent=1; +			} +		else if (strcmp(*argv,"-noout") == 0) 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) +			{ +			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 +			{ +			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"); +		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 + +	if (oidfile != NULL) +		{ +		if (BIO_read_filename(in,oidfile) <= 0) +			{ +			BIO_printf(bio_err,"problems opening %s\n",oidfile); +			ERR_print_errors(bio_err); +			goto end; +			} +		OBJ_create_objects(in); +		} + +	if (infile == NULL) +		BIO_set_fp(in,stdin,BIO_NOCLOSE); +	else +		{ +		if (BIO_read_filename(in,infile) <= 0) +			{ +			perror(infile); +			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 ((buf=BUF_MEM_new()) == NULL) goto end; +	if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */ + +	if (genstr || genconf) +		{ +		num = do_generate(bio_err, genstr, genconf, buf); +		if (num < 0) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	else +		{ + +		if (informat == FORMAT_PEM) +			{ +			BIO *tmp; + +			if ((b64=BIO_new(BIO_f_base64())) == NULL) +				goto end; +			BIO_push(b64,in); +			tmp=in; +			in=b64; +			b64=tmp; +			} + +		num=0; +		for (;;) +			{ +			if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end; +			i=BIO_read(in,&(buf->data[num]),BUFSIZ); +			if (i <= 0) break; +			num+=i; +			} +		} +	str=buf->data; + +	/* If any structs to parse go through in sequence */ + +	if (sk_OPENSSL_STRING_num(osk)) +		{ +		tmpbuf=(unsigned char *)str; +		tmplen=num; +		for (i=0; i<sk_OPENSSL_STRING_num(osk); i++) +			{ +			ASN1_TYPE *atmp; +			int typ; +			j=atoi(sk_OPENSSL_STRING_value(osk,i)); +			if (j == 0) +				{ +				BIO_printf(bio_err,"'%s' is an invalid number\n",sk_OPENSSL_STRING_value(osk,i)); +				continue; +				} +			tmpbuf+=j; +			tmplen-=j; +			atmp = at; +			ctmpbuf = tmpbuf; +			at = d2i_ASN1_TYPE(NULL,&ctmpbuf,tmplen); +			ASN1_TYPE_free(atmp); +			if(!at) +				{ +				BIO_printf(bio_err,"Error parsing structure\n"); +				ERR_print_errors(bio_err); +				goto end; +				} +			typ = ASN1_TYPE_get(at); +			if ((typ == V_ASN1_OBJECT) +				|| (typ == V_ASN1_NULL)) +				{ +				BIO_printf(bio_err, "Can't parse %s type\n", +					typ == V_ASN1_NULL ? "NULL" : "OBJECT"); +				ERR_print_errors(bio_err); +				goto end; +				} +			/* hmm... this is a little evil but it works */ +			tmpbuf=at->value.asn1_string->data; +			tmplen=at->value.asn1_string->length; +			} +		str=(char *)tmpbuf; +		num=tmplen; +		} + +	if (offset >= num) +		{ +		BIO_printf(bio_err, "Error: offset too large\n"); +		goto end; +		} + +	num -= offset; + +	if ((length == 0) || ((long)length > num)) length=(unsigned int)num; +	if(derout) { +		if(BIO_write(derout, str + offset, length) != (int)length) { +			BIO_printf(bio_err, "Error writing output\n"); +			ERR_print_errors(bio_err); +			goto end; +		} +	} +	if (!noout && +	    !ASN1_parse_dump(out,(unsigned char *)&(str[offset]),length, +		    indent,dump)) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} +	ret=0; +end: +	BIO_free(derout); +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (b64 != NULL) BIO_free(b64); +	if (ret != 0) +		ERR_print_errors(bio_err); +	if (buf != NULL) BUF_MEM_free(buf); +	if (at != NULL) ASN1_TYPE_free(at); +	if (osk != NULL) sk_OPENSSL_STRING_free(osk); +	OBJ_cleanup(); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf) +	{ +	CONF *cnf = NULL; +	int len; +	long errline; +	unsigned char *p; +	ASN1_TYPE *atyp = NULL; + +	if (genconf) +		{ +		cnf = NCONF_new(NULL); +		if (!NCONF_load(cnf, genconf, &errline)) +			goto conferr; +		if (!genstr) +			genstr = NCONF_get_string(cnf, "default", "asn1"); +		if (!genstr) +			{ +			BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf); +			goto err; +			} +		} + +	atyp = ASN1_generate_nconf(genstr, cnf); +	NCONF_free(cnf); +	cnf = NULL; + +	if (!atyp) +		return -1; + +	len = i2d_ASN1_TYPE(atyp, NULL); + +	if (len <= 0) +		goto err; + +	if (!BUF_MEM_grow(buf,len)) +		goto err; + +	p=(unsigned char *)buf->data; + +	i2d_ASN1_TYPE(atyp, &p); + +	ASN1_TYPE_free(atyp); +	return len; + +	conferr: + +	if (errline > 0) +		BIO_printf(bio, "Error on line %ld of config file '%s'\n", +							errline, genconf); +	else +		BIO_printf(bio, "Error loading config file '%s'\n", genconf); + +	err: +	NCONF_free(cnf); +	ASN1_TYPE_free(atyp); + +	return -1; + +	} diff --git a/main/openssl/apps/ca-cert.srl b/main/openssl/apps/ca-cert.srl new file mode 100644 index 00000000..2c7456e3 --- /dev/null +++ b/main/openssl/apps/ca-cert.srl @@ -0,0 +1 @@ +07 diff --git a/main/openssl/apps/ca-key.pem b/main/openssl/apps/ca-key.pem new file mode 100644 index 00000000..3a520b23 --- /dev/null +++ b/main/openssl/apps/ca-key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425 +gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd +2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB +AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6 +hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2 +J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs +HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL +21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s +nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz +MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa +pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb +KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2 +XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/ca-req.pem b/main/openssl/apps/ca-req.pem new file mode 100644 index 00000000..77bf7ec3 --- /dev/null +++ b/main/openssl/apps/ca-req.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBmTCCAQICAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgx +MDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgy +bTsZDCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/d +FXSv1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUe +cQU2mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAKlk7 +cxu9gCJN3/iQFyJXQ6YphaiQAT5VBXTx9ftRrQIjA3vxlDzPWGDy+V5Tqa7h8PtR +5Bn00JShII2zf0hjyjKils6x/UkWmjEiwSiFp4hR70iE8XwSNEHY2P6j6nQEIpgW +kbfgmmUqk7dl2V+ossTJ80B8SBpEhrn81V/cHxA= +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/ca.c b/main/openssl/apps/ca.c new file mode 100644 index 00000000..6b8b0ef8 --- /dev/null +++ b/main/openssl/apps/ca.c @@ -0,0 +1,2985 @@ +/* apps/ca.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.] + */ + +/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <sys/types.h> +#include <openssl/conf.h> +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/txt_db.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/objects.h> +#include <openssl/ocsp.h> +#include <openssl/pem.h> + +#ifndef W_OK +#  ifdef OPENSSL_SYS_VMS +#    if defined(__DECC) +#      include <unistd.h> +#    else +#      include <unixlib.h> +#    endif +#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) +#    include <sys/file.h> +#  endif +#endif + +#include "apps.h" + +#ifndef W_OK +#  define F_OK 0 +#  define X_OK 1 +#  define W_OK 2 +#  define R_OK 4 +#endif + +#undef PROG +#define PROG ca_main + +#define BASE_SECTION	"ca" +#define CONFIG_FILE "openssl.cnf" + +#define ENV_DEFAULT_CA		"default_ca" + +#define STRING_MASK	"string_mask" +#define UTF8_IN			"utf8" + +#define ENV_DIR			"dir" +#define ENV_CERTS		"certs" +#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_SERIAL		"serial" +#define ENV_CRLNUMBER		"crlnumber" +#define ENV_CRL			"crl" +#define ENV_PRIVATE_KEY		"private_key" +#define ENV_RANDFILE		"RANDFILE" +#define ENV_DEFAULT_DAYS 	"default_days" +#define ENV_DEFAULT_STARTDATE 	"default_startdate" +#define ENV_DEFAULT_ENDDATE 	"default_enddate" +#define ENV_DEFAULT_CRL_DAYS 	"default_crl_days" +#define ENV_DEFAULT_CRL_HOURS 	"default_crl_hours" +#define ENV_DEFAULT_MD		"default_md" +#define ENV_DEFAULT_EMAIL_DN	"email_in_dn" +#define ENV_PRESERVE		"preserve" +#define ENV_POLICY      	"policy" +#define ENV_EXTENSIONS      	"x509_extensions" +#define ENV_CRLEXT      	"crl_extensions" +#define ENV_MSIE_HACK		"msie_hack" +#define ENV_NAMEOPT		"name_opt" +#define ENV_CERTOPT		"cert_opt" +#define ENV_EXTCOPY		"copy_extensions" +#define ENV_UNIQUE_SUBJECT	"unique_subject" + +#define ENV_DATABASE		"database" + +/* Additional revocation information types */ + +#define REV_NONE		0	/* No addditional information */ +#define REV_CRL_REASON		1	/* Value is CRL reason code */ +#define REV_HOLD		2	/* Value is hold instruction */ +#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 alot 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 extentions 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; +extern int EF_ALIGNMENT; +#endif + +static void lookup_fail(const char *name, const char *tag); +static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, +		   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db, +		   BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, +		   char *enddate, long days, int batch, char *ext_sect, CONF *conf, +		   int verbose, unsigned long certopt, unsigned long nameopt, +		   int default_op, int ext_copy, int selfsign); +static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, +			const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, +			CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, +			char *startdate, char *enddate, long days, int batch, +			char *ext_sect, CONF *conf,int verbose, unsigned long certopt, +			unsigned long nameopt, int default_op, int ext_copy, +			ENGINE *e); +static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, +			 const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, +			 CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn, +			 char *startdate, char *enddate, long days, char *ext_sect, +			 CONF *conf, int verbose, unsigned long certopt,  +			 unsigned long nameopt, int default_op, int ext_copy); +static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); +static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, +	STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, +	int email_dn, char *startdate, char *enddate, long days, int batch, +       	int verbose, X509_REQ *req, char *ext_sect, CONF *conf, +	unsigned long certopt, unsigned long nameopt, int default_op, +	int ext_copy, int selfsign); +static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval); +static int get_certificate_status(const char *ser_status, CA_DB *db); +static int do_updatedb(CA_DB *db); +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 **); + +int 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; +	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; +	STACK_OF(CONF_VALUE) *attribs=NULL; +	STACK_OF(X509) *cert_sk=NULL; +#undef BSIZE +#define BSIZE 256 +	MS_STATIC char buf[3][BSIZE]; +	char *randfile=NULL; +#ifndef OPENSSL_NO_ENGINE +	char *engine = NULL; +#endif +	char *tofree=NULL; +	DB_ATTR db_attr; + +#ifdef EFENCE +EF_PROTECT_FREE=1; +EF_PROTECT_BELOW=1; +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) +			create_ser = 1; +		else if (strcmp(*argv,"-multivalue-rdn") == 0) +			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) +			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,"-notext") == 0) +			notext=1; +		else if (strcmp(*argv,"-batch") == 0) +			batch=1; +		else if (strcmp(*argv,"-preserveDN") == 0) +			preserve=1; +		else if (strcmp(*argv,"-noemailDN") == 0) +			email_dn=0; +		else if (strcmp(*argv,"-gencrl") == 0) +			gencrl=1; +		else if (strcmp(*argv,"-msie_hack") == 0) +			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); +			req=1; +			} +		else if (strcmp(*argv, "-spkac") == 0) +			{ +			if (--argc < 1) goto bad; +			spkac_file = *(++argv); +			req=1; +			} +		else if (strcmp(*argv,"-revoke") == 0) +			{ +			if (--argc < 1) goto bad; +			infile= *(++argv); +			dorevoke=1; +			} +		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) +			{ +			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); +			rev_type = REV_CRL_REASON; +			} +		else if (strcmp(*argv,"-crl_hold") == 0) +			{ +			if (--argc < 1) goto bad; +			rev_arg = *(++argv); +			rev_type = REV_HOLD; +			} +		else if (strcmp(*argv,"-crl_compromise") == 0) +			{ +			if (--argc < 1) goto bad; +			rev_arg = *(++argv); +			rev_type = REV_KEY_COMPROMISE; +			} +		else if (strcmp(*argv,"-crl_CA_compromise") == 0) +			{ +			if (--argc < 1) goto bad; +			rev_arg = *(++argv); +			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; +			} +		argc--; +		argv++; +		} + +	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"); +	if (configfile == NULL) configfile = getenv("SSLEAY_CONF"); +	if (configfile == NULL) +		{ +		const char *s=X509_get_default_cert_area(); +		size_t len; + +#ifdef OPENSSL_SYS_VMS +		len = strlen(s)+sizeof(CONFIG_FILE); +		tofree=OPENSSL_malloc(len); +		strcpy(tofree,s); +#else +		len = strlen(s)+sizeof(CONFIG_FILE)+1; +		tofree=OPENSSL_malloc(len); +		BUF_strlcpy(tofree,s,len); +		BUF_strlcat(tofree,"/",len); +#endif +		BUF_strlcat(tofree,CONFIG_FILE,len); +		configfile=tofree; +		} + +	BIO_printf(bio_err,"Using configuration from %s\n",configfile); +	conf = NCONF_new(NULL); +	if (NCONF_load(conf,configfile,&errorline) <= 0) +		{ +		if (errorline <= 0) +			BIO_printf(bio_err,"error loading the config file '%s'\n", +				configfile); +		else +			BIO_printf(bio_err,"error on line %ld of config file '%s'\n" +				,errorline,configfile); +		goto err; +		} +	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); +#endif + +	/* Lets get the config section we are using */ +	if (section == NULL) +		{ +		section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA); +		if (section == NULL) +			{ +			lookup_fail(BASE_SECTION,ENV_DEFAULT_CA); +			goto err; +			} +		} + +	if (conf != NULL) +		{ +		p=NCONF_get_string(conf,NULL,"oid_file"); +		if (p == NULL) +			ERR_clear_error(); +		if (p != NULL) +			{ +			BIO *oid_bio; + +			oid_bio=BIO_new_file(p,"r"); +			if (oid_bio == NULL)  +				{ +				/* +				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); +				ERR_print_errors(bio_err); +				*/ +				ERR_clear_error(); +				} +			else +				{ +				OBJ_create_objects(oid_bio); +				BIO_free(oid_bio); +				} +			} +		if (!add_oid_section(bio_err,conf))  +			{ +			ERR_print_errors(bio_err); +			goto err; +			} +		} + +	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); +	if (randfile == NULL) +		ERR_clear_error(); +	app_RAND_load_file(randfile, bio_err, 0); + +	f = NCONF_get_string(conf, section, STRING_MASK); +	if (!f) +		ERR_clear_error(); + +	if(f && !ASN1_STRING_set_default_mask_asc(f)) { +		BIO_printf(bio_err, "Invalid global string mask setting %s\n", f); +		goto err; +	} + +	if (chtype != MBSTRING_UTF8){ +		f = NCONF_get_string(conf, section, UTF8_IN); +		if (!f) +			ERR_clear_error(); +		else if (!strcmp(f, "yes")) +			chtype = MBSTRING_UTF8; +	} + +	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", p); +#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; +			} +		db = load_index(dbfile,&db_attr); +		if (db == NULL) goto err; + +		if (!index_index(db)) goto err; + +		if (get_certificate_status(ser_status,db) != 1) +			BIO_printf(bio_err,"Error verifying serial %s!\n", +				 ser_status); +		goto err; +	} + +	/*****************************************************************/ +	/* we definitely need a private key, so let's get it */ + +	if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf, +		section,ENV_PRIVATE_KEY)) == NULL)) +		{ +		lookup_fail(section,ENV_PRIVATE_KEY); +		goto err; +		} +	if (!key) +		{ +		free_key = 1; +		if (!app_passwd(bio_err, passargin, NULL, &key, NULL)) +			{ +			BIO_printf(bio_err,"Error getting password\n"); +			goto err; +			} +		} +	pkey = load_key(bio_err, keyfile, keyform, 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; +		} + +	/*****************************************************************/ +	/* we need a certificate */ +	if (!selfsign || spkac_file || ss_cert_file || gencrl) +		{ +		if ((certfile == NULL) +			&& ((certfile=NCONF_get_string(conf, +				     section,ENV_CERTIFICATE)) == NULL)) +			{ +			lookup_fail(section,ENV_CERTIFICATE); +			goto err; +			} +		x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e, +			"CA certificate"); +		if (x509 == NULL) +			goto err; + +		if (!X509_check_private_key(x509,pkey)) +			{ +			BIO_printf(bio_err,"CA certificate and CA private key do not match\n"); +			goto err; +			} +		} +	if (!selfsign) x509p = x509; + +	f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE); +	if (f == NULL) +		ERR_clear_error(); +	if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) +		preserve=1; +	f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK); +	if (f == NULL) +		ERR_clear_error(); +	if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) +		msie_hack=1; + +	f=NCONF_get_string(conf,section,ENV_NAMEOPT); + +	if (f) +		{ +		if (!set_name_ex(&nameopt, f)) +			{ +			BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f); +			goto err; +			} +		default_op = 0; +		} +	else +		ERR_clear_error(); + +	f=NCONF_get_string(conf,section,ENV_CERTOPT); + +	if (f) +		{ +		if (!set_cert_ex(&certopt, f)) +			{ +			BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f); +			goto err; +			} +		default_op = 0; +		} +	else +		ERR_clear_error(); + +	f=NCONF_get_string(conf,section,ENV_EXTCOPY); + +	if (f) +		{ +		if (!set_ext_copy(&ext_copy, f)) +			{ +			BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f); +			goto err; +			} +		} +	else +		ERR_clear_error(); + +	/*****************************************************************/ +	/* lookup where to write new certificates */ +	if ((outdir == NULL) && (req)) +		{ + +		if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR)) +			== NULL) +			{ +			BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n"); +			goto err; +			} +#ifndef OPENSSL_SYS_VMS +	    /* outdir is a directory spec, but access() for VMS demands a +	       filename.  In any case, stat(), below, will catch the problem +	       if outdir is not a directory spec, and the fopen() or open() +	       will catch an error if there is no write access. + +	       Presumably, this problem could also be solved by using the DEC +	       C 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 +			{ +			BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir); +			perror(outdir); +			goto err; +			} + +		if (app_isdir(outdir)<=0) +			{ +			BIO_printf(bio_err,"%s need to be a directory\n",outdir); +			perror(outdir); +			goto err; +			} +#endif +		} + +	/*****************************************************************/ +	/* we need to load the database file */ +	if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL) +		{ +		lookup_fail(section,ENV_DATABASE); +		goto err; +		} +	db = load_index(dbfile, &db_attr); +	if (db == NULL) goto err; + +	/* Lets check some fields */ +	for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++) +		{ +		pp=sk_OPENSSL_PSTRING_value(db->db->data,i); +		if ((pp[DB_type][0] != DB_TYPE_REV) && +			(pp[DB_rev_date][0] != '\0')) +			{ +			BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1); +			goto err; +			} +		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; +			} +		if (!check_time_format((char *)pp[DB_exp_date])) +			{ +			BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1); +			goto err; +			} +		p=pp[DB_serial]; +		j=strlen(p); +		if (*p == '-') +			{ +			p++; +			j--; +			} +		if ((j&1) || (j < 2)) +			{ +			BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j); +			goto err; +			} +		while (*p) +			{ +			if (!(	((*p >= '0') && (*p <= '9')) || +				((*p >= 'A') && (*p <= 'F')) || +				((*p >= 'a') && (*p <= 'f')))  ) +				{ +				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; +				} +			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); +		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; + +	/*****************************************************************/ +	/* Update the db file for expired certificates */ +	if (doupdatedb) +		{ +		if (verbose) +			BIO_printf(bio_err, "Updating %s ...\n", +							dbfile); + +		i = do_updatedb(db); +		if (i == -1) +			{ +			BIO_printf(bio_err,"Malloc failure\n"); +			goto err; +			} +		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; +				 +			if (!rotate_index(dbfile,"new","old")) goto err; +				 +			if (verbose) BIO_printf(bio_err, +				"Done. %d entries marked as expired\n",i);  +	      		} +	  	} + + 	/*****************************************************************/ +	/* Read extentions config file                                   */ +	if (extfile) +		{ +		extconf = NCONF_new(NULL); +		if (NCONF_load(extconf,extfile,&errorline) <= 0) +			{ +			if (errorline <= 0) +				BIO_printf(bio_err, "ERROR: loading the config file '%s'\n", +					extfile); +			else +				BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n", +					errorline,extfile); +			ret = 1; +			goto err; +			} + +		if (verbose) +			BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile); + +		/* We can have sections in the ext file */ +		if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions"))) +			extensions = "default"; +		} + +	/*****************************************************************/ +	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 +			} +		} + +	if ((md == NULL) && ((md=NCONF_get_string(conf, +		section,ENV_DEFAULT_MD)) == NULL)) +		{ +		lookup_fail(section,ENV_DEFAULT_MD); +		goto err; +		} + +	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; +			} +		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 (req) +		{ +		if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf, +			section,ENV_DEFAULT_EMAIL_DN)) != NULL )) +			{ +			if(strcmp(tmp_email_dn,"no") == 0) +				email_dn=0; +			} +		if (verbose) +			BIO_printf(bio_err,"message digest is %s\n", +				OBJ_nid2ln(dgst->type)); +		if ((policy == NULL) && ((policy=NCONF_get_string(conf, +			section,ENV_POLICY)) == NULL)) +			{ +			lookup_fail(section,ENV_POLICY); +			goto err; +			} +		if (verbose) +			BIO_printf(bio_err,"policy is %s\n",policy); + +		if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL)) +			== NULL) +			{ +			lookup_fail(section,ENV_SERIAL); +			goto err; +			} + +		if (!extconf) +			{ +			/* no '-extfile' option, so we look for extensions +			 * in the main configuration file */ +			if (!extensions) +				{ +				extensions=NCONF_get_string(conf,section, +								ENV_EXTENSIONS); +				if (!extensions) +					ERR_clear_error(); +				} +			if (extensions) +				{ +				/* Check syntax of file */ +				X509V3_CTX ctx; +				X509V3_set_ctx_test(&ctx); +				X509V3_set_nconf(&ctx, conf); +				if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, +								NULL)) +					{ +					BIO_printf(bio_err, +				 	"Error Loading extension section %s\n", +								 extensions); +					ret = 1; +					goto err; +					} +				} +			} + +		if (startdate == NULL) +			{ +			startdate=NCONF_get_string(conf,section, +				ENV_DEFAULT_STARTDATE); +			if (startdate == NULL) +				ERR_clear_error(); +			} +		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; +			} +		if (startdate == NULL) startdate="today"; + +		if (enddate == NULL) +			{ +			enddate=NCONF_get_string(conf,section, +				ENV_DEFAULT_ENDDATE); +			if (enddate == NULL) +				ERR_clear_error(); +			} +		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; +			} + +		if (days == 0) +			{ +			if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days)) +				days = 0; +			} +		if (!enddate && (days == 0)) +			{ +			BIO_printf(bio_err,"cannot lookup how many days to certify for\n"); +			goto err; +			} + +		if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL) +			{ +			BIO_printf(bio_err,"error while loading serial number\n"); +			goto err; +			} +		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; +				BIO_printf(bio_err,"next serial number is %s\n",f); +				OPENSSL_free(f); +				} +			} + +		if ((attribs=NCONF_get_section(conf,policy)) == NULL) +			{ +			BIO_printf(bio_err,"unable to find 'section' for %s\n",policy); +			goto err; +			} + +		if ((cert_sk=sk_X509_new_null()) == NULL) +			{ +			BIO_printf(bio_err,"Memory allocation failure\n"); +			goto err; +			} +		if (spkac_file != NULL) +			{ +			total++; +			j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, +				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions, +				conf,verbose,certopt,nameopt,default_op,ext_copy); +			if (j < 0) goto err; +			if (j > 0) +				{ +				total_done++; +				BIO_printf(bio_err,"\n"); +				if (!BN_add_word(serial,1)) goto err; +				if (!sk_X509_push(cert_sk,x)) +					{ +					BIO_printf(bio_err,"Memory allocation failure\n"); +					goto err; +					} +				if (outfile) +					{ +					output_der = 1; +					batch = 1; +					} +				} +			} +		if (ss_cert_file != NULL) +			{ +			total++; +			j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, +				db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch, +				extensions,conf,verbose, certopt, nameopt, +				default_op, ext_copy, e); +			if (j < 0) goto err; +			if (j > 0) +				{ +				total_done++; +				BIO_printf(bio_err,"\n"); +				if (!BN_add_word(serial,1)) goto err; +				if (!sk_X509_push(cert_sk,x)) +					{ +					BIO_printf(bio_err,"Memory allocation failure\n"); +					goto err; +					} +				} +			} +		if (infile != NULL) +			{ +			total++; +			j=certify(&x,infile,pkey,x509p,dgst,attribs,db, +				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch, +				extensions,conf,verbose, certopt, nameopt, +				default_op, ext_copy, selfsign); +			if (j < 0) goto err; +			if (j > 0) +				{ +				total_done++; +				BIO_printf(bio_err,"\n"); +				if (!BN_add_word(serial,1)) goto err; +				if (!sk_X509_push(cert_sk,x)) +					{ +					BIO_printf(bio_err,"Memory allocation failure\n"); +					goto err; +					} +				} +			} +		for (i=0; i<argc; i++) +			{ +			total++; +			j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db, +				serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch, +				extensions,conf,verbose, certopt, nameopt, +				default_op, ext_copy, selfsign); +			if (j < 0) goto err; +			if (j > 0) +				{ +				total_done++; +				BIO_printf(bio_err,"\n"); +				if (!BN_add_word(serial,1)) goto err; +				if (!sk_X509_push(cert_sk,x)) +					{ +					BIO_printf(bio_err,"Memory allocation failure\n"); +					goto err; +					} +				} +			}	 +		/* we have a stack of newly certified certificates +		 * and a data base and serial number that need +		 * updating */ + +		if (sk_X509_num(cert_sk) > 0) +			{ +			if (!batch) +				{ +				BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total); +				(void)BIO_flush(bio_err); +				buf[0][0]='\0'; +				if (!fgets(buf[0],10,stdin)) +					{ +					BIO_printf(bio_err,"CERTIFICATION CANCELED: I/O error\n");  +					ret=0; +					goto err; +					} +				if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) +					{ +					BIO_printf(bio_err,"CERTIFICATION CANCELED\n");  +					ret=0; +					goto err; +					} +				} + +			BIO_printf(bio_err,"Write out database with %d new entries\n",sk_X509_num(cert_sk)); + +			if (!save_serial(serialfile,"new",serial,NULL)) goto err; + +			if (!save_index(dbfile, "new", db)) goto err; +			} +	 +		if (verbose) +			BIO_printf(bio_err,"writing new certificates\n"); +		for (i=0; i<sk_X509_num(cert_sk); i++) +			{ +			int k; +			char *n; + +			x=sk_X509_value(cert_sk,i); + +			j=x->cert_info->serialNumber->length; +			p=(const char *)x->cert_info->serialNumber->data; +			 +			if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8)) +				{ +				BIO_printf(bio_err,"certificate file name too long\n"); +				goto err; +				} + +			strcpy(buf[2],outdir); + +#ifndef OPENSSL_SYS_VMS +			BUF_strlcat(buf[2],"/",sizeof(buf[2])); +#endif + +			n=(char *)&(buf[2][strlen(buf[2])]); +			if (j > 0) +				{ +				for (k=0; k<j; k++) +					{ +					if (n >= &(buf[2][sizeof(buf[2])])) +						break; +					BIO_snprintf(n, +						     &buf[2][0] + sizeof(buf[2]) - n, +						     "%02X",(unsigned char)*(p++)); +					n+=2; +					} +				} +			else +				{ +				*(n++)='0'; +				*(n++)='0'; +				} +			*(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m'; +			*n='\0'; +			if (verbose) +				BIO_printf(bio_err,"writing %s\n",buf[2]); + +			if (BIO_write_filename(Cout,buf[2]) <= 0) +				{ +				perror(buf[2]); +				goto err; +				} +			write_new_certificate(Cout,x, 0, notext); +			write_new_certificate(Sout,x, output_der, notext); +			} + +		if (sk_X509_num(cert_sk)) +			{ +			/* Rename the database and the serial file */ +			if (!rotate_serial(serialfile,"new","old")) goto err; + +			if (!rotate_index(dbfile,"new","old")) goto err; + +			BIO_printf(bio_err,"Data Base Updated\n"); +			} +		} +	 +	/*****************************************************************/ +	if (gencrl) +		{ +		int crl_v2 = 0; +		if (!crl_ext) +			{ +			crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT); +			if (!crl_ext) +				ERR_clear_error(); +			} +		if (crl_ext) +			{ +			/* Check syntax of file */ +			X509V3_CTX ctx; +			X509V3_set_ctx_test(&ctx); +			X509V3_set_nconf(&ctx, conf); +			if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) +				{ +				BIO_printf(bio_err, +				 "Error Loading CRL extension section %s\n", +								 crl_ext); +				ret = 1; +				goto err; +				} +			} + +		if ((crlnumberfile=NCONF_get_string(conf,section,ENV_CRLNUMBER)) +			!= NULL) +			if ((crlnumber=load_serial(crlnumberfile,0,NULL)) == NULL) +				{ +				BIO_printf(bio_err,"error while loading CRL number\n"); +				goto err; +				} + +		if (!crldays && !crlhours && !crlsec) +			{ +			if (!NCONF_get_number(conf,section, +				ENV_DEFAULT_CRL_DAYS, &crldays)) +				crldays = 0; +			if (!NCONF_get_number(conf,section, +				ENV_DEFAULT_CRL_HOURS, &crlhours)) +				crlhours = 0; +			} +		if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) +			{ +			BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n"); +			goto err; +			} + +		if (verbose) BIO_printf(bio_err,"making CRL\n"); +		if ((crl=X509_CRL_new()) == NULL) goto err; +		if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err; + +		tmptm = ASN1_TIME_new(); +		if (!tmptm) goto err; +		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; +			} +		X509_CRL_set_nextUpdate(crl, tmptm);	 + +		ASN1_TIME_free(tmptm); + +		for (i=0; i<sk_OPENSSL_PSTRING_num(db->db->data); i++) +			{ +			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; +				j = make_revoked(r, pp[DB_rev_date]); +				if (!j) goto err; +				if (j == 2) crl_v2 = 1; +				if (!BN_hex2bn(&serial, pp[DB_serial])) +					goto err; +				tmpser = BN_to_ASN1_INTEGER(serial, NULL); +				BN_free(serial); +				serial = NULL; +				if (!tmpser) +					goto err; +				X509_REVOKED_set_serialNumber(r, tmpser); +				ASN1_INTEGER_free(tmpser); +				X509_CRL_add0_revoked(crl,r); +				} +			} + +		/* sort the data so it will be written in serial +		 * number order */ +		X509_CRL_sort(crl); + +		/* we now have a CRL */ +		if (verbose) BIO_printf(bio_err,"signing CRL\n"); + +		/* Add any extensions asked for */ + +		if (crl_ext || crlnumberfile != NULL) +			{ +			X509V3_CTX crlctx; +			X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); +			X509V3_set_nconf(&crlctx, conf); + +			if (crl_ext) +				if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, +					crl_ext, crl)) goto err; +			if (crlnumberfile != NULL) +				{ +				tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL); +				if (!tmpser) goto err; +				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; +				} +			} +		if (crl_ext || crl_v2) +			{ +			if (!X509_CRL_set_version(crl, 1)) +				goto err; /* version 2 CRL */ +			} + +		 +		if (crlnumberfile != NULL)	/* we have a CRL number that need updating */ +			if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err; + +		if (crlnumber) +			{ +			BN_free(crlnumber); +			crlnumber = NULL; +			} + +		if (!X509_CRL_sign(crl,pkey,dgst)) goto err; + +		PEM_write_bio_X509_CRL(Sout,crl); + +		if (crlnumberfile != NULL)	/* Rename the crlnumber file */ +			if (!rotate_serial(crlnumberfile,"new","old")) goto err; + +		} +	/*****************************************************************/ +	if (dorevoke) +		{ +		if (infile == NULL)  +			{ +			BIO_printf(bio_err,"no input files\n"); +			goto err; +			} +		else +			{ +			X509 *revcert; +			revcert=load_cert(bio_err, infile, FORMAT_PEM, +				NULL, e, infile); +			if (revcert == NULL) +				goto err; +			j=do_revoke(revcert,db, rev_type, rev_arg); +			if (j <= 0) goto err; +			X509_free(revcert); + +			if (!save_index(dbfile, "new", db)) goto err; + +			if (!rotate_index(dbfile, "new", "old")) goto err; + +			BIO_printf(bio_err,"Data Base Updated\n");  +			} +		} +	/*****************************************************************/ +	ret=0; +err: +	if(tofree) +		OPENSSL_free(tofree); +	BIO_free_all(Cout); +	BIO_free_all(Sout); +	BIO_free_all(out); +	BIO_free_all(in); + +	if (cert_sk) +		sk_X509_pop_free(cert_sk,X509_free); + +	if (ret) ERR_print_errors(bio_err); +	app_RAND_write_file(randfile, bio_err); +	if (free_key && key) +		OPENSSL_free(key); +	BN_free(serial); +	BN_free(crlnumber); +	free_index(db); +	EVP_PKEY_free(pkey); +	if (x509) X509_free(x509); +	X509_CRL_free(crl); +	NCONF_free(conf); +	NCONF_free(extconf); +	OBJ_cleanup(); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static void lookup_fail(const char *name, const char *tag) +	{ +	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); +	} + +static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, +	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, +	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate, +	     long days, int batch, char *ext_sect, CONF *lconf, int verbose, +	     unsigned long certopt, unsigned long nameopt, int default_op, +	     int ext_copy, int selfsign) +	{ +	X509_REQ *req=NULL; +	BIO *in=NULL; +	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; +		} +	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; +		} +	if (verbose) +		X509_REQ_print(bio_err,req); + +	BIO_printf(bio_err,"Check that the request matches the signature\n"); + +	if (selfsign && !X509_REQ_check_private_key(req,pkey)) +		{ +		BIO_printf(bio_err,"Certificate request and CA private key do not match\n"); +		ok=0; +		goto err; +		} +	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL) +		{ +		BIO_printf(bio_err,"error unpacking public key\n"); +		goto err; +		} +	i=X509_REQ_verify(req,pktmp); +	EVP_PKEY_free(pktmp); +	if (i < 0) +		{ +		ok=0; +		BIO_printf(bio_err,"Signature verification problems....\n"); +		goto err; +		} +	if (i == 0) +		{ +		ok=0; +		BIO_printf(bio_err,"Signature did not match the certificate request\n"); +		goto err; +		} +	else +		BIO_printf(bio_err,"Signature ok\n"); + +	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn, +		startdate,enddate,days,batch,verbose,req,ext_sect,lconf, +		certopt, nameopt, default_op, ext_copy, selfsign); + +err: +	if (req != NULL) X509_REQ_free(req); +	if (in != NULL) BIO_free(in); +	return(ok); +	} + +static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, +	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, +	     BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate, +	     long days, int batch, char *ext_sect, CONF *lconf, int verbose, +	     unsigned long certopt, unsigned long nameopt, int default_op, +	     int ext_copy, ENGINE *e) +	{ +	X509 *req=NULL; +	X509_REQ *rreq=NULL; +	EVP_PKEY *pktmp=NULL; +	int ok= -1,i; + +	if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL) +		goto err; +	if (verbose) +		X509_print(bio_err,req); + +	BIO_printf(bio_err,"Check that the request matches the signature\n"); + +	if ((pktmp=X509_get_pubkey(req)) == NULL) +		{ +		BIO_printf(bio_err,"error unpacking public key\n"); +		goto err; +		} +	i=X509_verify(req,pktmp); +	EVP_PKEY_free(pktmp); +	if (i < 0) +		{ +		ok=0; +		BIO_printf(bio_err,"Signature verification problems....\n"); +		goto err; +		} +	if (i == 0) +		{ +		ok=0; +		BIO_printf(bio_err,"Signature did not match the certificate\n"); +		goto err; +		} +	else +		BIO_printf(bio_err,"Signature ok\n"); + +	if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL) +		goto err; + +	ok=do_body(xret,pkey,x509,dgst,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: +	if (rreq != NULL) X509_REQ_free(rreq); +	if (req != NULL) X509_free(req); +	return(ok); +	} + +static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, +	     STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj, +	     unsigned long chtype, int multirdn, +	     int email_dn, char *startdate, char *enddate, long days, int batch, +	     int verbose, X509_REQ *req, char *ext_sect, CONF *lconf, +	     unsigned long certopt, unsigned long nameopt, int default_op, +	     int ext_copy, int selfsign) +	{ +	X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL; +	ASN1_UTCTIME *tm,*tmptm; +	ASN1_STRING *str,*str2; +	ASN1_OBJECT *obj; +	X509 *ret=NULL; +	X509_CINF *ci; +	X509_NAME_ENTRY *ne; +	X509_NAME_ENTRY *tne,*push; +	EVP_PKEY *pktmp; +	int ok= -1,i,j,last,nid; +	const char *p; +	CONF_VALUE *cv; +	OPENSSL_STRING row[DB_NUMBER]; +	OPENSSL_STRING *irow=NULL; +	OPENSSL_STRING *rrow=NULL; +	char buf[25]; + +	tmptm=ASN1_UTCTIME_new(); +	if (tmptm == NULL) +		{ +		BIO_printf(bio_err,"malloc error\n"); +		return(0); +		} + +	for (i=0; i<DB_NUMBER; i++) +		row[i]=NULL; + +	if (subj) +		{ +		X509_NAME *n = parse_name(subj, chtype, multirdn); + +		if (!n) +			{ +			ERR_print_errors(bio_err); +			goto err; +			} +		X509_REQ_set_subject_name(req,n); +		req->req_info->enc.modified = 1; +		X509_NAME_free(n); +		} + +	if (default_op) +		BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n"); + +	name=X509_REQ_get_subject_name(req); +	for (i=0; i<X509_NAME_entry_count(name); i++) +		{ +		ne= X509_NAME_get_entry(name,i); +		str=X509_NAME_ENTRY_get_data(ne); +		obj=X509_NAME_ENTRY_get_object(ne); + +		if (msie_hack) +			{ +			/* assume all type should be strings */ +			nid=OBJ_obj2nid(ne->object); + +			if (str->type == V_ASN1_UNIVERSALSTRING) +				ASN1_UNIVERSALSTRING_to_string(str); + +			if ((str->type == V_ASN1_IA5STRING) && +				(nid != NID_pkcs9_emailAddress)) +				str->type=V_ASN1_T61STRING; + +			if ((nid == NID_pkcs9_emailAddress) && +				(str->type == V_ASN1_PRINTABLESTRING)) +				str->type=V_ASN1_IA5STRING; +			} + +		/* If no EMAIL is wanted in the subject */ +		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) +			continue; + +		/* check some things */ +		if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && +			(str->type != V_ASN1_IA5STRING)) +			{ +			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n"); +			goto err; +			} +		if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING)) +			{ +			j=ASN1_PRINTABLE_type(str->data,str->length); +			if (	((j == V_ASN1_T61STRING) && +				 (str->type != V_ASN1_T61STRING)) || +				((j == V_ASN1_IA5STRING) && +				 (str->type == V_ASN1_PRINTABLESTRING))) +				{ +				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n"); +				goto err; +				} +			} + +		if (default_op) +			old_entry_print(bio_err, obj, str); +		} + +	/* Ok, now we check the 'policy' stuff. */ +	if ((subject=X509_NAME_new()) == NULL) +		{ +		BIO_printf(bio_err,"Memory allocation failure\n"); +		goto err; +		} + +	/* take a copy of the issuer name before we mess with it. */ +	if (selfsign) +		CAname=X509_NAME_dup(name); +	else +		CAname=X509_NAME_dup(x509->cert_info->subject); +	if (CAname == NULL) goto err; +	str=str2=NULL; + +	for (i=0; i<sk_CONF_VALUE_num(policy); i++) +		{ +		cv=sk_CONF_VALUE_value(policy,i); /* get the object id */ +		if ((j=OBJ_txt2nid(cv->name)) == NID_undef) +			{ +			BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name); +			goto err; +			} +		obj=OBJ_nid2obj(j); + +		last= -1; +		for (;;) +			{ +			/* lookup the object in the supplied name list */ +			j=X509_NAME_get_index_by_OBJ(name,obj,last); +			if (j < 0) +				{ +				if (last != -1) break; +				tne=NULL; +				} +			else +				{ +				tne=X509_NAME_get_entry(name,j); +				} +			last=j; + +			/* depending on the 'policy', decide what to do. */ +			push=NULL; +			if (strcmp(cv->value,"optional") == 0) +				{ +				if (tne != NULL) +					push=tne; +				} +			else if (strcmp(cv->value,"supplied") == 0) +				{ +				if (tne == NULL) +					{ +					BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name); +					goto err; +					} +				else +					push=tne; +				} +			else if (strcmp(cv->value,"match") == 0) +				{ +				int last2; + +				if (tne == NULL) +					{ +					BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name); +					goto err; +					} + +				last2= -1; + +again2: +				j=X509_NAME_get_index_by_OBJ(CAname,obj,last2); +				if ((j < 0) && (last2 == -1)) +					{ +					BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name); +					goto err; +					} +				if (j >= 0) +					{ +					push=X509_NAME_get_entry(CAname,j); +					str=X509_NAME_ENTRY_get_data(tne); +					str2=X509_NAME_ENTRY_get_data(push); +					last2=j; +					if (ASN1_STRING_cmp(str,str2) != 0) +						goto again2; +					} +				if (j < 0) +					{ +					BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data)); +					goto err; +					} +				} +			else +				{ +				BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value); +				goto err; +				} + +			if (push != NULL) +				{ +				if (!X509_NAME_add_entry(subject,push, -1, 0)) +					{ +					if (push != NULL) +						X509_NAME_ENTRY_free(push); +					BIO_printf(bio_err,"Memory allocation failure\n"); +					goto err; +					} +				} +			if (j < 0) break; +			} +		} + +	if (preserve) +		{ +		X509_NAME_free(subject); +		/* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ +		subject=X509_NAME_dup(name); +		if (subject == NULL) goto err; +		} + +	if (verbose) +		BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n"); + +	/* Build the correct Subject if no e-mail is wanted in the subject */ +	/* and add it later on because of the method extensions are added (altName) */ +	  +	if (email_dn) +		dn_subject = subject; +	else +		{ +		X509_NAME_ENTRY *tmpne; +		/* Its best to dup the subject DN and then delete any email +		 * addresses because this retains its structure. +		 */ +		if (!(dn_subject = X509_NAME_dup(subject))) +			{ +			BIO_printf(bio_err,"Memory allocation failure\n"); +			goto err; +			} +		while((i = X509_NAME_get_index_by_NID(dn_subject, +					NID_pkcs9_emailAddress, -1)) >= 0) +			{ +			tmpne = X509_NAME_get_entry(dn_subject, i); +			X509_NAME_delete_entry(dn_subject, i); +			X509_NAME_ENTRY_free(tmpne); +			} +		} + +	if (BN_is_zero(serial)) +		row[DB_serial]=BUF_strdup("00"); +	else +		row[DB_serial]=BN_bn2hex(serial); +	if (row[DB_serial] == NULL) +		{ +		BIO_printf(bio_err,"Memory allocation failure\n"); +		goto err; +		} + +	if (db->attributes.unique_subject) +		{ +		OPENSSL_STRING *crow=row; + +		rrow=TXT_DB_get_by_index(db->db,DB_name,crow); +		if (rrow != NULL) +			{ +			BIO_printf(bio_err, +				"ERROR:There is already a certificate for %s\n", +				row[DB_name]); +			} +		} +	if (rrow == NULL) +		{ +		rrow=TXT_DB_get_by_index(db->db,DB_serial,row); +		if (rrow != NULL) +			{ +			BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n", +				row[DB_serial]); +			BIO_printf(bio_err,"      check the database/serial_file for corruption\n"); +			} +		} + +	if (rrow != NULL) +		{ +		BIO_printf(bio_err, +			"The matching entry has the following details\n"); +		if (rrow[DB_type][0] == 'E') +			p="Expired"; +		else if (rrow[DB_type][0] == 'R') +			p="Revoked"; +		else if (rrow[DB_type][0] == 'V') +			p="Valid"; +		else +			p="\ninvalid type, Data base error\n"; +		BIO_printf(bio_err,"Type	  :%s\n",p);; +		if (rrow[DB_type][0] == 'R') +			{ +			p=rrow[DB_exp_date]; if (p == NULL) p="undef"; +			BIO_printf(bio_err,"Was revoked on:%s\n",p); +			} +		p=rrow[DB_exp_date]; if (p == NULL) p="undef"; +		BIO_printf(bio_err,"Expires on    :%s\n",p); +		p=rrow[DB_serial]; if (p == NULL) p="undef"; +		BIO_printf(bio_err,"Serial Number :%s\n",p); +		p=rrow[DB_file]; if (p == NULL) p="undef"; +		BIO_printf(bio_err,"File name     :%s\n",p); +		p=rrow[DB_name]; if (p == NULL) p="undef"; +		BIO_printf(bio_err,"Subject Name  :%s\n",p); +		ok= -1; /* This is now a 'bad' error. */ +		goto err; +		} + +	/* We are now totally happy, lets make and sign the certificate */ +	if (verbose) +		BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n"); + +	if ((ret=X509_new()) == NULL) goto err; +	ci=ret->cert_info; + +#ifdef X509_V3 +	/* Make it an X509 v3 certificate. */ +	if (!X509_set_version(ret,2)) goto err; +#endif + +	if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL) +		goto err; +	if (selfsign) +		{ +		if (!X509_set_issuer_name(ret,subject)) +			goto err; +		} +	else +		{ +		if (!X509_set_issuer_name(ret,X509_get_subject_name(x509))) +			goto err; +		} + +	if (strcmp(startdate,"today") == 0) +		X509_gmtime_adj(X509_get_notBefore(ret),0); +	else ASN1_TIME_set_string(X509_get_notBefore(ret),startdate); + +	if (enddate == NULL) +		X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL); +	else ASN1_TIME_set_string(X509_get_notAfter(ret),enddate); + +	if (!X509_set_subject_name(ret,subject)) goto err; + +	pktmp=X509_REQ_get_pubkey(req); +	i = X509_set_pubkey(ret,pktmp); +	EVP_PKEY_free(pktmp); +	if (!i) goto err; + +	/* 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; +		ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */ + +		/* Free the current entries if any, there should not +		 * be any I believe */ +		if (ci->extensions != NULL) +			sk_X509_EXTENSION_pop_free(ci->extensions, +						   X509_EXTENSION_free); + +		ci->extensions = NULL; + +		/* Initialize the context structure */ +		if (selfsign) +			X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0); +		else +			X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); + +		if (extconf) +			{ +			if (verbose) +				BIO_printf(bio_err, "Extra configuration file found\n"); +  +			/* Use the extconf configuration db LHASH */ +			X509V3_set_nconf(&ctx, extconf); +  +			/* Test the structure (needed?) */ +			/* X509V3_set_ctx_test(&ctx); */ + +			/* Adds exts contained in the configuration file */ +			if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret)) +				{ +				BIO_printf(bio_err, +				    "ERROR: adding extensions in section %s\n", +								ext_sect); +				ERR_print_errors(bio_err); +				goto err; +				} +			if (verbose) +				BIO_printf(bio_err, "Successfully added extensions from file.\n"); +			} +		else if (ext_sect) +			{ +			/* We found extensions to be set from config file */ +			X509V3_set_nconf(&ctx, lconf); + +			if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) +				{ +				BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect); +				ERR_print_errors(bio_err); +				goto err; +				} + +			if (verbose)  +				BIO_printf(bio_err, "Successfully added extensions from config\n"); +			} +		} + +	/* Copy extensions from request (if any) */ + +	if (!copy_extensions(ret, req, ext_copy)) +		{ +		BIO_printf(bio_err, "ERROR: adding extensions from request\n"); +		ERR_print_errors(bio_err); +		goto err; +		} + +	/* Set the right value for the noemailDN option */ +	if( email_dn == 0 ) +		{ +		if (!X509_set_subject_name(ret,dn_subject)) goto err; +		} + +	if (!default_op) +		{ +		BIO_printf(bio_err, "Certificate Details:\n"); +		/* Never print signature details because signature not present */ +		certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; +		X509_print_ex(bio_err, ret, nameopt, certopt);  +		} + +	BIO_printf(bio_err,"Certificate is to be certified until "); +	ASN1_TIME_print(bio_err,X509_get_notAfter(ret)); +	if (days) BIO_printf(bio_err," (%ld days)",days); +	BIO_printf(bio_err, "\n"); + +	if (!batch) +		{ + +		BIO_printf(bio_err,"Sign the certificate? [y/n]:"); +		(void)BIO_flush(bio_err); +		buf[0]='\0'; +		if (!fgets(buf,sizeof(buf)-1,stdin)) +			{ +			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n"); +			ok=0; +			goto err; +			} +		if (!((buf[0] == 'y') || (buf[0] == 'Y'))) +			{ +			BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n"); +			ok=0; +			goto err; +			} +		} + +	pktmp=X509_get_pubkey(ret); +	if (EVP_PKEY_missing_parameters(pktmp) && +		!EVP_PKEY_missing_parameters(pkey)) +		EVP_PKEY_copy_parameters(pktmp,pkey); +	EVP_PKEY_free(pktmp); + +	if (!X509_sign(ret,pkey,dgst)) +		goto err; + +	/* We now just add it to the database */ +	row[DB_type]=(char *)OPENSSL_malloc(2); + +	tm=X509_get_notAfter(ret); +	row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); +	memcpy(row[DB_exp_date],tm->data,tm->length); +	row[DB_exp_date][tm->length]='\0'; + +	row[DB_rev_date]=NULL; + +	/* row[DB_serial] done already */ +	row[DB_file]=(char *)OPENSSL_malloc(8); +	row[DB_name]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0); + +	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; +		} +	BUF_strlcpy(row[DB_file],"unknown",8); +	row[DB_type][0]='V'; +	row[DB_type][1]='\0'; + +	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) +		{ +		BIO_printf(bio_err,"Memory allocation failure\n"); +		goto err; +		} + +	for (i=0; i<DB_NUMBER; i++) +		{ +		irow[i]=row[i]; +		row[i]=NULL; +		} +	irow[DB_NUMBER]=NULL; + +	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; +		} +	ok=1; +err: +	for (i=0; i<DB_NUMBER; i++) +		if (row[i] != NULL) OPENSSL_free(row[i]); + +	if (CAname != NULL) +		X509_NAME_free(CAname); +	if (subject != NULL) +		X509_NAME_free(subject); +	if ((dn_subject != NULL) && !email_dn) +		X509_NAME_free(dn_subject); +	if (tmptm != NULL) +		ASN1_UTCTIME_free(tmptm); +	if (ok <= 0) +		{ +		if (ret != NULL) X509_free(ret); +		ret=NULL; +		} +	else +		*xret=ret; +	return(ok); +	} + +static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) +	{ + +	if (output_der) +		{ +		(void)i2d_X509_bio(bp,x); +		return; +		} +#if 0 +	/* ??? Not needed since X509_print prints all this stuff anyway */ +	f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256); +	BIO_printf(bp,"issuer :%s\n",f); + +	f=X509_NAME_oneline(X509_get_subject_name(x),buf,256); +	BIO_printf(bp,"subject:%s\n",f); + +	BIO_puts(bp,"serial :"); +	i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber); +	BIO_puts(bp,"\n\n"); +#endif +	if (!notext)X509_print(bp,x); +	PEM_write_bio_X509(bp,x); +	} + +static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, +	     const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db, +	     BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate, +	     long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, +	     unsigned long nameopt, int default_op, int ext_copy) +	{ +	STACK_OF(CONF_VALUE) *sk=NULL; +	LHASH_OF(CONF_VALUE) *parms=NULL; +	X509_REQ *req=NULL; +	CONF_VALUE *cv=NULL; +	NETSCAPE_SPKI *spki = NULL; +	X509_REQ_INFO *ri; +	char *type,*buf; +	EVP_PKEY *pktmp=NULL; +	X509_NAME *n=NULL; +	X509_NAME_ENTRY *ne=NULL; +	int ok= -1,i,j; +	long errline; +	int nid; + +	/* +	 * Load input file into a hash table.  (This is just an easy +	 * way to read and parse the file, then put it into a convenient +	 * STACK format). +	 */ +	parms=CONF_load(NULL,infile,&errline); +	if (parms == NULL) +		{ +		BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile); +		ERR_print_errors(bio_err); +		goto err; +		} + +	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; +		} + +	/* +	 * Now create a dummy X509 request structure.  We don't actually +	 * have an X509 request, but we have many of the components +	 * (a public key, various DN components).  The idea is that we +	 * put these components into the right X509 request structure +	 * and we can use the same code as if you had a real X509 request. +	 */ +	req=X509_REQ_new(); +	if (req == NULL) +		{ +		ERR_print_errors(bio_err); +		goto err; +		} + +	/* +	 * Build up the subject name set. +	 */ +	ri=req->req_info; +	n = ri->subject; + +	for (i = 0; ; i++) +		{ +		if (sk_CONF_VALUE_num(sk) <= i) break; + +		cv=sk_CONF_VALUE_value(sk,i); +		type=cv->name; +		/* Skip past any leading X. X: X, etc to allow for +		 * multiple instances +		 */ +		for (buf = cv->name; *buf ; buf++) +			if ((*buf == ':') || (*buf == ',') || (*buf == '.')) +				{ +				buf++; +				if (*buf) type = buf; +				break; +				} + +		buf=cv->value; +		if ((nid=OBJ_txt2nid(type)) == NID_undef) +			{ +			if (strcmp(type, "SPKAC") == 0) +				{ +				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); +				if (spki == NULL) +					{ +					BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n"); +					ERR_print_errors(bio_err); +					goto err; +					} +				} +			continue; +			} + +		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, +				(unsigned char *)buf, -1, -1, 0)) +			goto err; +		} +	if (spki == NULL) +		{ +		BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n", +			infile); +		goto err; +		} + +	/* +	 * Now extract the key from the SPKI structure. +	 */ + +	BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n"); + +	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL) +		{ +		BIO_printf(bio_err,"error unpacking SPKAC public key\n"); +		goto err; +		} + +	j = NETSCAPE_SPKI_verify(spki, pktmp); +	if (j <= 0) +		{ +		BIO_printf(bio_err,"signature verification failed on SPKAC public key\n"); +		goto err; +		} +	BIO_printf(bio_err,"Signature ok\n"); + +	X509_REQ_set_pubkey(req,pktmp); +	EVP_PKEY_free(pktmp); +	ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate, +		   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, +			ext_copy, 0); +err: +	if (req != NULL) X509_REQ_free(req); +	if (parms != NULL) CONF_free(parms); +	if (spki != NULL) NETSCAPE_SPKI_free(spki); +	if (ne != NULL) X509_NAME_ENTRY_free(ne); + +	return(ok); +	} + +static int check_time_format(const char *str) +	{ +	return ASN1_TIME_set_string(NULL, str); +	} + +static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) +	{ +	ASN1_UTCTIME *tm=NULL; +	char *row[DB_NUMBER],**rrow,**irow; +	char *rev_str = NULL; +	BIGNUM *bn = NULL; +	int ok=-1,i; + +	for (i=0; i<DB_NUMBER; i++) +		row[i]=NULL; +	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; +	if (BN_is_zero(bn)) +		row[DB_serial]=BUF_strdup("00"); +	else +		row[DB_serial]=BN_bn2hex(bn); +	BN_free(bn); +	if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) +		{ +		BIO_printf(bio_err,"Memory allocation failure\n"); +		goto err; +		} +	/* We have to lookup by serial number because name lookup +	 * skips revoked certs + 	 */ +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row); +	if (rrow == NULL) +		{ +		BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], row[DB_name]); + +		/* We now just add it to the database */ +		row[DB_type]=(char *)OPENSSL_malloc(2); + +		tm=X509_get_notAfter(x509); +		row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); +		memcpy(row[DB_exp_date],tm->data,tm->length); +		row[DB_exp_date][tm->length]='\0'; + +		row[DB_rev_date]=NULL; + +		/* row[DB_serial] done already */ +		row[DB_file]=(char *)OPENSSL_malloc(8); + +		/* row[DB_name] done already */ + +		if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || +			(row[DB_file] == NULL)) +			{ +			BIO_printf(bio_err,"Memory allocation failure\n"); +			goto err; +			} +		BUF_strlcpy(row[DB_file],"unknown",8); +		row[DB_type][0]='V'; +		row[DB_type][1]='\0'; + +		if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) +			{ +			BIO_printf(bio_err,"Memory allocation failure\n"); +			goto err; +			} + +		for (i=0; i<DB_NUMBER; i++) +			{ +			irow[i]=row[i]; +			row[i]=NULL; +			} +		irow[DB_NUMBER]=NULL; + +		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; +			} + +		/* Revoke Certificate */ +		ok = do_revoke(x509,db, type, value); + +		goto err; + +		} +	else if (index_name_cmp_noconst(row, rrow)) +		{ +		BIO_printf(bio_err,"ERROR:name does not match %s\n", +			   row[DB_name]); +		goto err; +		} +	else if (rrow[DB_type][0]=='R') +		{ +		BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n", +			   row[DB_serial]); +		goto err; +		} +	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; +			} +		rrow[DB_type][0]='R'; +		rrow[DB_type][1]='\0'; +		rrow[DB_rev_date] = rev_str; +		} +	ok=1; +err: +	for (i=0; i<DB_NUMBER; i++) +		{ +		if (row[i] != NULL)  +			OPENSSL_free(row[i]); +		} +	return(ok); +	} + +static int get_certificate_status(const char *serial, CA_DB *db) +	{ +	char *row[DB_NUMBER],**rrow; +	int ok=-1,i; + +	/* Free Resources */ +	for (i=0; i<DB_NUMBER; i++) +		row[i]=NULL; + +	/* Malloc needed char spaces */ +	row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2); +	if (row[DB_serial] == NULL) +		{ +		BIO_printf(bio_err,"Malloc failure\n"); +		goto err; +		} + +	if (strlen(serial) % 2) +		{ +		/* Set the first char to 0 */; +		row[DB_serial][0]='0'; + +		/* Copy String from serial to row[DB_serial] */ +		memcpy(row[DB_serial]+1, serial, strlen(serial)); +		row[DB_serial][strlen(serial)+1]='\0'; +		} +	else +		{ +		/* Copy String from serial to row[DB_serial] */ +		memcpy(row[DB_serial], serial, strlen(serial)); +		row[DB_serial][strlen(serial)]='\0'; +		} +			 +	/* Make it Upper Case */ +	for (i=0; row[DB_serial][i] != '\0'; i++) +		row[DB_serial][i] = toupper(row[DB_serial][i]); +	 + +	ok=1; + +	/* Search for the certificate */ +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row); +	if (rrow == NULL) +		{ +		BIO_printf(bio_err,"Serial %s not present in db.\n", +				 row[DB_serial]); +		ok=-1; +		goto err; +		} +	else if (rrow[DB_type][0]=='V') +		{ +		BIO_printf(bio_err,"%s=Valid (%c)\n", +			row[DB_serial], rrow[DB_type][0]); +		goto err; +		} +	else if (rrow[DB_type][0]=='R') +		{ +		BIO_printf(bio_err,"%s=Revoked (%c)\n", +			row[DB_serial], rrow[DB_type][0]); +		goto err; +		} +	else if (rrow[DB_type][0]=='E') +		{ +		BIO_printf(bio_err,"%s=Expired (%c)\n", +			row[DB_serial], rrow[DB_type][0]); +		goto err; +		} +	else if (rrow[DB_type][0]=='S') +		{ +		BIO_printf(bio_err,"%s=Suspended (%c)\n", +			row[DB_serial], rrow[DB_type][0]); +		goto err; +		} +	else +		{ +		BIO_printf(bio_err,"%s=Unknown (%c).\n", +			row[DB_serial], rrow[DB_type][0]); +		ok=-1; +		} +err: +	for (i=0; i<DB_NUMBER; i++) +		{ +		if (row[i] != NULL) +			OPENSSL_free(row[i]); +		} +	return(ok); +	} + +static int do_updatedb (CA_DB *db) +	{ +	ASN1_UTCTIME	*a_tm = NULL; +	int i, cnt = 0; +	int db_y2k, a_y2k;  /* flags = 1 if y >= 2000 */  +	char **rrow, *a_tm_s; + +	a_tm = ASN1_UTCTIME_new(); + +	/* get actual time and make a string */ +	a_tm = X509_gmtime_adj(a_tm, 0); +	a_tm_s = (char *) OPENSSL_malloc(a_tm->length+1); +	if (a_tm_s == NULL) +		{ +		cnt = -1; +		goto err; +		} + +	memcpy(a_tm_s, a_tm->data, a_tm->length); +	a_tm_s[a_tm->length] = '\0'; + +	if (strncmp(a_tm_s, "49", 2) <= 0) +		a_y2k = 1; +	else +		a_y2k = 0; + +	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) +		{ +		rrow = sk_OPENSSL_PSTRING_value(db->db->data, i); + +		if (rrow[DB_type][0] == 'V') +		 	{ +			/* ignore entries that are not valid */ +			if (strncmp(rrow[DB_exp_date], "49", 2) <= 0) +				db_y2k = 1; +			else +				db_y2k = 0; + +			if (db_y2k == a_y2k) +				{ +				/* all on the same y2k side */ +				if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) +				       	{ +				       	rrow[DB_type][0]  = 'E'; +				       	rrow[DB_type][1]  = '\0'; +	  				cnt++; + +					BIO_printf(bio_err, "%s=Expired\n", +							rrow[DB_serial]); +					} +				} +			else if (db_y2k < a_y2k) +				{ +		  		rrow[DB_type][0]  = 'E'; +		  		rrow[DB_type][1]  = '\0'; +	  			cnt++; + +				BIO_printf(bio_err, "%s=Expired\n", +							rrow[DB_serial]); +				} + +			} +    		} + +err: + +	ASN1_UTCTIME_free(a_tm); +	OPENSSL_free(a_tm_s); + +	return (cnt); +	} + +static const char *crl_reasons[] = { +	/* CRL reason strings */ +	"unspecified", +	"keyCompromise", +	"CACompromise", +	"affiliationChanged", +	"superseded",  +	"cessationOfOperation", +	"certificateHold", +	"removeFromCRL", +	/* Additional pseudo reasons */ +	"holdInstruction", +	"keyTime", +	"CAkeyTime" +}; + +#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *)) + +/* Given revocation information convert to a DB string. + * The format of the string is: + * revtime[,reason,extra]. Where 'revtime' is the + * revocation time (the current time). 'reason' is the + * optional CRL reason and 'extra' is any additional + * argument + */ + +char *make_revocation_str(int rev_type, char *rev_arg) +	{ +	char *other = NULL, *str; +	const char *reason = NULL; +	ASN1_OBJECT *otmp; +	ASN1_UTCTIME *revtm = NULL; +	int i; +	switch (rev_type) +		{ +	case REV_NONE: +		break; + +	case REV_CRL_REASON: +		for (i = 0; i < 8; i++) +			{ +			if (!strcasecmp(rev_arg, crl_reasons[i])) +				{ +				reason = crl_reasons[i]; +				break; +				} +			} +		if (reason == NULL) +			{ +			BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg); +			return NULL; +			} +		break; + +	case REV_HOLD: +		/* Argument is an OID */ + +		otmp = OBJ_txt2obj(rev_arg, 0); +		ASN1_OBJECT_free(otmp); + +		if (otmp == NULL) +			{ +			BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg); +			return NULL; +			} + +		reason = "holdInstruction"; +		other = rev_arg; +		break; +		 +	case REV_KEY_COMPROMISE: +	case REV_CA_COMPROMISE: + +		/* Argument is the key compromise time  */ +		if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) +			{	 +			BIO_printf(bio_err, "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", rev_arg); +			return NULL; +			} +		other = rev_arg; +		if (rev_type == REV_KEY_COMPROMISE) +			reason = "keyTime"; +		else  +			reason = "CAkeyTime"; + +		break; + +		} + +	revtm = X509_gmtime_adj(NULL, 0); + +	i = revtm->length + 1; + +	if (reason) i += strlen(reason) + 1; +	if (other) i += strlen(other) + 1; + +	str = OPENSSL_malloc(i); + +	if (!str) return NULL; + +	BUF_strlcpy(str, (char *)revtm->data, i); +	if (reason) +		{ +		BUF_strlcat(str, ",", i); +		BUF_strlcat(str, reason, i); +		} +	if (other) +		{ +		BUF_strlcat(str, ",", i); +		BUF_strlcat(str, other, i); +		} +	ASN1_UTCTIME_free(revtm); +	return str; +	} + +/* Convert revocation field to X509_REVOKED entry  + * return code: + * 0 error + * 1 OK + * 2 OK and some extensions added (i.e. V2 CRL) + */ + + +int make_revoked(X509_REVOKED *rev, const char *str) +	{ +	char *tmp = NULL; +	int reason_code = -1; +	int i, ret = 0; +	ASN1_OBJECT *hold = NULL; +	ASN1_GENERALIZEDTIME *comp_time = NULL; +	ASN1_ENUMERATED *rtmp = NULL; + +	ASN1_TIME *revDate = NULL; + +	i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str); + +	if (i == 0) +		goto err; + +	if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) +		goto err; + +	if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) +		{ +		rtmp = ASN1_ENUMERATED_new(); +		if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) +			goto err; +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) +			goto err; +		} + +	if (rev && comp_time) +		{ +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0)) +			goto err; +		} +	if (rev && hold) +		{ +		if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0)) +			goto err; +		} + +	if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) +		ret = 2; +	else ret = 1; + +	err: + +	if (tmp) OPENSSL_free(tmp); +	ASN1_OBJECT_free(hold); +	ASN1_GENERALIZEDTIME_free(comp_time); +	ASN1_ENUMERATED_free(rtmp); +	ASN1_TIME_free(revDate); + +	return ret; +	} + +int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) +	{ +	char buf[25],*pbuf, *p; +	int j; +	j=i2a_ASN1_OBJECT(bp,obj); +	pbuf=buf; +	for (j=22-j; j>0; j--) +		*(pbuf++)=' '; +	*(pbuf++)=':'; +	*(pbuf++)='\0'; +	BIO_puts(bp,buf); + +	if (str->type == V_ASN1_PRINTABLESTRING) +		BIO_printf(bp,"PRINTABLE:'"); +	else if (str->type == V_ASN1_T61STRING) +		BIO_printf(bp,"T61STRING:'"); +	else if (str->type == V_ASN1_IA5STRING) +		BIO_printf(bp,"IA5STRING:'"); +	else if (str->type == V_ASN1_UNIVERSALSTRING) +		BIO_printf(bp,"UNIVERSALSTRING:'"); +	else +		BIO_printf(bp,"ASN.1 %2d:'",str->type); +			 +	p=(char *)str->data; +	for (j=str->length; j>0; j--) +		{ +		if ((*p >= ' ') && (*p <= '~')) +			BIO_printf(bp,"%c",*p); +		else if (*p & 0x80) +			BIO_printf(bp,"\\0x%02X",*p); +		else if ((unsigned char)*p == 0xf7) +			BIO_printf(bp,"^?"); +		else	BIO_printf(bp,"^%c",*p+'@'); +		p++; +		} +	BIO_printf(bp,"'\n"); +	return 1; +	} + +int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str) +	{ +	char *tmp = NULL; +	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); + +	p = strchr(tmp, ','); + +	rtime_str = tmp; + +	if (p) +		{ +		*p = '\0'; +		p++; +		reason_str = p; +		p = strchr(p, ','); +		if (p) +			{ +			*p = '\0'; +			arg_str = p + 1; +			} +		} + +	if (prevtm) +		{ +		*prevtm = ASN1_UTCTIME_new(); +		if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) +			{ +			BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str); +			goto err; +			} +		} +	if (reason_str) +		{ +		for (i = 0; i < NUM_REASONS; i++) +			{ +			if(!strcasecmp(reason_str, crl_reasons[i])) +				{ +				reason_code = i; +				break; +				} +			} +		if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) +			{ +			BIO_printf(bio_err, "invalid reason code %s\n", reason_str); +			goto err; +			} + +		if (reason_code == 7) +			reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL; +		else if (reason_code == 8)		/* Hold instruction */ +			{ +			if (!arg_str) +				{	 +				BIO_printf(bio_err, "missing hold instruction\n"); +				goto err; +				} +			reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; +			hold = OBJ_txt2obj(arg_str, 0); + +			if (!hold) +				{ +				BIO_printf(bio_err, "invalid object identifier %s\n", arg_str); +				goto err; +				} +			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; +				} +			comp_time = ASN1_GENERALIZEDTIME_new(); +			if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) +				{	 +				BIO_printf(bio_err, "invalid compromised time %s\n", arg_str); +				goto err; +				} +			if (reason_code == 9) +				reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; +			else +				reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE; +			} +		} + +	if (preason) *preason = reason_code; +	if (pinvtm) *pinvtm = comp_time; +	else ASN1_GENERALIZEDTIME_free(comp_time); + +	ret = 1; + +	err: + +	if (tmp) OPENSSL_free(tmp); +	if (!phold) ASN1_OBJECT_free(hold); +	if (!pinvtm) ASN1_GENERALIZEDTIME_free(comp_time); + +	return ret; +	} diff --git a/main/openssl/apps/cert.pem b/main/openssl/apps/cert.pem new file mode 100644 index 00000000..de4a77ac --- /dev/null +++ b/main/openssl/apps/cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD +VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa +Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT +DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7 +tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q +sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO +19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3 +-----END CERTIFICATE----- diff --git a/main/openssl/apps/ciphers.c b/main/openssl/apps/ciphers.c new file mode 100644 index 00000000..3d4c60db --- /dev/null +++ b/main/openssl/apps/ciphers.c @@ -0,0 +1,231 @@ +/* apps/ciphers.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include "apps.h" +#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", +" -ssl2       - SSL2 mode\n", +" -ssl3       - SSL3 mode\n", +" -tls1       - TLS1 mode\n", +NULL +}; + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	int ret=1,i; +	int verbose=0,Verbose=0; +	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; +	char buf[512]; +	BIO *STDout=NULL; + +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +	meth=SSLv23_server_method(); +#elif !defined(OPENSSL_NO_SSL3) +	meth=SSLv3_server_method(); +#elif !defined(OPENSSL_NO_SSL2) +	meth=SSLv2_server_method(); +#endif + +	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) +			verbose=1; +		else if (strcmp(*argv,"-V") == 0) +			verbose=Verbose=1; +#ifndef OPENSSL_NO_SSL2 +		else if (strcmp(*argv,"-ssl2") == 0) +			meth=SSLv2_client_method(); +#endif +#ifndef OPENSSL_NO_SSL3 +		else if (strcmp(*argv,"-ssl3") == 0) +			meth=SSLv3_client_method(); +#endif +#ifndef OPENSSL_NO_TLS1 +		else if (strcmp(*argv,"-tls1") == 0) +			meth=TLSv1_client_method(); +#endif +		else if ((strncmp(*argv,"-h",2) == 0) || +			 (strcmp(*argv,"-?") == 0)) +			{ +			badops=1; +			break; +			} +		else +			{ +			ciphers= *argv; +			} +		argc--; +		argv++; +		} + +	if (badops) +		{ +		for (pp=ciphers_usage; (*pp != NULL); pp++) +			BIO_printf(bio_err,"%s",*pp); +		goto end; +		} + +	OpenSSL_add_ssl_algorithms(); + +	ctx=SSL_CTX_new(meth); +	if (ctx == NULL) goto err; +	if (ciphers != NULL) { +		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) { +			BIO_printf(bio_err, "Error in cipher list\n"); +			goto err; +		} +	} +	ssl=SSL_new(ctx); +	if (ssl == NULL) goto err; + + +	if (!verbose) +		{ +		for (i=0; ; i++) +			{ +			p=SSL_get_cipher_list(ssl,i); +			if (p == NULL) break; +			if (i != 0) BIO_printf(STDout,":"); +			BIO_printf(STDout,"%s",p); +			} +		BIO_printf(STDout,"\n"); +		} +	else /* verbose */ +		{ +		sk=SSL_get_ciphers(ssl); + +		for (i=0; i<sk_SSL_CIPHER_num(sk); i++) +			{ +			SSL_CIPHER *c; + +			c = sk_SSL_CIPHER_value(sk,i); +			 +			if (Verbose) +				{ +				unsigned long id = c->id; +				int id0 = (int)(id >> 24); +				int id1 = (int)((id >> 16) & 0xffL); +				int id2 = (int)((id >> 8) & 0xffL); +				int id3 = (int)(id & 0xffL); +				 +				if ((id & 0xff000000L) == 0x02000000L) +					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */ +				else if ((id & 0xff000000L) == 0x03000000L) +					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */ +				else +					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ +				} + +			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf)); +			} +		} + +	ret=0; +	if (0) +		{ +err: +		SSL_load_error_strings(); +		ERR_print_errors(bio_err); +		} +end: +	if (ctx != NULL) SSL_CTX_free(ctx); +	if (ssl != NULL) SSL_free(ssl); +	if (STDout != NULL) BIO_free_all(STDout); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + diff --git a/main/openssl/apps/client.pem b/main/openssl/apps/client.pem new file mode 100644 index 00000000..307910e5 --- /dev/null +++ b/main/openssl/apps/client.pem @@ -0,0 +1,24 @@ +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Client test cert (512 bit) +-----BEGIN CERTIFICATE----- +MIIB6TCCAVICAQIwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD +VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzU2WhcNOTgwNjA5 +MTM1NzU2WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG +A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGkNsaWVudCB0ZXN0IGNl +cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALtv55QyzG6i2Plw +Z1pah7++Gv8L5j6Hnyr/uTZE1NLG0ABDDexmq/R4KedLjFEIYjocDui+IXs62NNt +XrT8odkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBwtMmI7oGUG8nKmftQssATViH5 +NRRtoEw07DxJp/LfatHdrhqQB73eGdL5WILZJXk46Xz2e9WMSUjVCSYhdKxtflU3 +UR2Ajv1Oo0sTNdfz0wDqJNirLNtzyhhsaq8qMTrLwXrCP31VxBiigFSQSUFnZyTE +9TKwhS4GlwbtCfxSKQ== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBALtv55QyzG6i2PlwZ1pah7++Gv8L5j6Hnyr/uTZE1NLG0ABDDexm +q/R4KedLjFEIYjocDui+IXs62NNtXrT8odkCAwEAAQJAbwXq0vJ/+uyEvsNgxLko +/V86mGXQ/KrSkeKlL0r4ENxjcyeMAGoKu6J9yMY7+X9+Zm4nxShNfTsf/+Freoe1 +HQIhAPOSm5Q1YI+KIsII2GeVJx1U69+wnd71OasIPakS1L1XAiEAxQAW+J3/JWE0 +ftEYakbhUOKL8tD1OaFZS71/5GdG7E8CIQCefUMmySSvwd6kC0VlATSWbW+d+jp/ +nWmM1KvqnAo5uQIhALqEADu5U1Wvt8UN8UDGBRPQulHWNycuNV45d3nnskWPAiAw +ueTyr6WsZ5+SD8g/Hy3xuvF3nPmJRH+rwvVihlcFOg== +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/cms.c b/main/openssl/apps/cms.c new file mode 100644 index 00000000..d29a8849 --- /dev/null +++ b/main/openssl/apps/cms.c @@ -0,0 +1,1362 @@ +/* apps/cms.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* CMS utility function */ + +#include <stdio.h> +#include <string.h> +#include "apps.h" + +#ifndef OPENSSL_NO_CMS + +#include <openssl/crypto.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/x509_vfy.h> +#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); +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, +						int rr_allorfirst, +					STACK_OF(OPENSSL_STRING) *rr_from); + +#define SMIME_OP	0x10 +#define SMIME_IP	0x20 +#define SMIME_SIGNERS	0x40 +#define SMIME_ENCRYPT		(1 | SMIME_OP) +#define SMIME_DECRYPT		(2 | SMIME_IP) +#define SMIME_SIGN		(3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_VERIFY		(4 | SMIME_IP) +#define SMIME_CMSOUT		(5 | SMIME_IP | SMIME_OP) +#define SMIME_RESIGN		(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) +#define SMIME_DATAOUT		(7 | SMIME_IP) +#define SMIME_DATA_CREATE	(8 | SMIME_OP) +#define SMIME_DIGEST_VERIFY	(9 | SMIME_IP) +#define SMIME_DIGEST_CREATE	(10 | SMIME_OP) +#define SMIME_UNCOMPRESS	(11 | SMIME_IP) +#define SMIME_COMPRESS		(12 | SMIME_OP) +#define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP) +#define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP) +#define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP) +#define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP) + +int verify_err = 0; + +int MAIN(int, char **); + +int 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; +	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; +	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_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; +	const EVP_MD *sign_md = NULL; +	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; +	size_t secret_keylen = 0, secret_keyidlen = 0; + +	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; + +	while (!badarg && *args && *args[0] == '-') +		{ +		if (!strcmp (*args, "-encrypt")) +			operation = SMIME_ENCRYPT; +		else if (!strcmp (*args, "-decrypt")) +			operation = SMIME_DECRYPT; +		else if (!strcmp (*args, "-sign")) +			operation = SMIME_SIGN; +		else if (!strcmp (*args, "-sign_receipt")) +			operation = SMIME_SIGN_RECEIPT; +		else if (!strcmp (*args, "-resign")) +			operation = SMIME_RESIGN; +		else if (!strcmp (*args, "-verify")) +			operation = SMIME_VERIFY; +		else if (!strcmp (*args, "-verify_retcode")) +			verify_retcode = 1; +		else if (!strcmp(*args,"-verify_receipt")) +			{ +			operation = SMIME_VERIFY_RECEIPT; +			if (!args[1]) +				goto argerr; +			args++; +			rctfile = *args; +			} +		else if (!strcmp (*args, "-cmsout")) +			operation = SMIME_CMSOUT; +		else if (!strcmp (*args, "-data_out")) +			operation = SMIME_DATAOUT; +		else if (!strcmp (*args, "-data_create")) +			operation = SMIME_DATA_CREATE; +		else if (!strcmp (*args, "-digest_verify")) +			operation = SMIME_DIGEST_VERIFY; +		else if (!strcmp (*args, "-digest_create")) +			operation = SMIME_DIGEST_CREATE; +		else if (!strcmp (*args, "-compress")) +			operation = SMIME_COMPRESS; +		else if (!strcmp (*args, "-uncompress")) +			operation = SMIME_UNCOMPRESS; +		else if (!strcmp (*args, "-EncryptedData_decrypt")) +			operation = SMIME_ENCRYPTED_DECRYPT; +		else if (!strcmp (*args, "-EncryptedData_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(); +#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"))  +				flags |= CMS_TEXT; +		else if (!strcmp (*args, "-nointern"))  +				flags |= CMS_NOINTERN; +		else if (!strcmp (*args, "-noverify")  +			|| !strcmp (*args, "-no_signer_cert_verify"))  +				flags |= CMS_NO_SIGNER_CERT_VERIFY; +		else if (!strcmp (*args, "-nocerts"))  +				flags |= CMS_NOCERTS; +		else if (!strcmp (*args, "-noattr"))  +				flags |= CMS_NOATTR; +		else if (!strcmp (*args, "-nodetach"))  +				flags &= ~CMS_DETACHED; +		else if (!strcmp (*args, "-nosmimecap")) +				flags |= CMS_NOSMIMECAP; +		else if (!strcmp (*args, "-binary")) +				flags |= CMS_BINARY; +		else if (!strcmp (*args, "-keyid")) +				flags |= CMS_USE_KEYID; +		else if (!strcmp (*args, "-nosigs")) +				flags |= CMS_NOSIGS; +		else if (!strcmp (*args, "-no_content_verify")) +				flags |= CMS_NO_CONTENT_VERIFY; +		else if (!strcmp (*args, "-no_attr_verify")) +				flags |= CMS_NO_ATTR_VERIFY; +		else if (!strcmp (*args, "-stream")) +				flags |= CMS_STREAM; +		else if (!strcmp (*args, "-indef")) +				flags |= CMS_STREAM; +		else if (!strcmp (*args, "-noindef")) +				flags &= ~CMS_STREAM; +		else if (!strcmp (*args, "-nooldmime")) +				flags |= CMS_NOOLDMIMETYPE; +		else if (!strcmp (*args, "-crlfeol")) +				flags |= CMS_CRLFEOL; +		else if (!strcmp (*args, "-noout")) +				noout = 1; +		else if (!strcmp (*args, "-receipt_request_print")) +				rr_print = 1; +		else if (!strcmp (*args, "-receipt_request_all")) +				rr_allorfirst = 0; +		else if (!strcmp (*args, "-receipt_request_first")) +				rr_allorfirst = 1; +		else if (!strcmp(*args,"-receipt_request_from")) +			{ +			if (!args[1]) +				goto argerr; +			args++; +			if (!rr_from) +				rr_from = sk_OPENSSL_STRING_new_null(); +			sk_OPENSSL_STRING_push(rr_from, *args); +			} +		else if (!strcmp(*args,"-receipt_request_to")) +			{ +			if (!args[1]) +				goto argerr; +			args++; +			if (!rr_to) +				rr_to = sk_OPENSSL_STRING_new_null(); +			sk_OPENSSL_STRING_push(rr_to, *args); +			} +		else if (!strcmp (*args, "-print")) +				{ +				noout = 1; +				print = 1; +				} +		else if (!strcmp(*args,"-secretkey")) +			{ +			long ltmp; +			if (!args[1]) +				goto argerr; +			args++; +			secret_key = string_to_hex(*args, <mp); +			if (!secret_key) +				{ +				BIO_printf(bio_err, "Invalid key %s\n", *args); +				goto argerr; +				} +			secret_keylen = (size_t)ltmp; +			} +		else if (!strcmp(*args,"-secretkeyid")) +			{ +			long ltmp; +			if (!args[1]) +				goto argerr; +			args++; +			secret_keyid = string_to_hex(*args, <mp); +			if (!secret_keyid) +				{ +				BIO_printf(bio_err, "Invalid id %s\n", *args); +				goto argerr; +				} +			secret_keyidlen = (size_t)ltmp; +			} +		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; +				} +			} +		else if (!strcmp(*args,"-rand")) +			{ +			if (!args[1]) +				goto argerr; +			args++; +			inrand = *args; +			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; +			/* If previous -signer argument add signer to list */ + +			if (signerfile) +				{ +				if (!sksigners) +					sksigners = sk_OPENSSL_STRING_new_null(); +				sk_OPENSSL_STRING_push(sksigners, signerfile); +				if (!keyfile) +					keyfile = signerfile; +				if (!skkeys) +					skkeys = sk_OPENSSL_STRING_new_null(); +				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, "-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; +			/* If previous -inkey arument add signer to list */ +			if (keyfile) +				{ +				if (!signerfile) +					{ +					BIO_puts(bio_err, "Illegal -inkey without -signer\n"); +					goto argerr; +					} +				if (!sksigners) +					sksigners = sk_OPENSSL_STRING_new_null(); +				sk_OPENSSL_STRING_push(sksigners, signerfile); +				signerfile = NULL; +				if (!skkeys) +					skkeys = sk_OPENSSL_STRING_new_null(); +				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, "-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++; +		} + +	if (((rr_allorfirst != -1) || rr_from) && !rr_to) +		{ +		BIO_puts(bio_err, "No Signed Receipts Recipients\n"); +		goto argerr; +		} + +	if (!(operation & SMIME_SIGNERS)  && (rr_to || rr_from)) +		{ +		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); +		goto argerr; +		} +	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) +		{ +		BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); +		goto argerr; +		} + +	if (operation & SMIME_SIGNERS) +		{ +		if (keyfile && !signerfile) +			{ +			BIO_puts(bio_err, "Illegal -inkey without -signer\n"); +			goto argerr; +			} +		/* Check to see if any final signer needs to be appended */ +		if (signerfile) +			{ +			if (!sksigners) +				sksigners = sk_OPENSSL_STRING_new_null(); +			sk_OPENSSL_STRING_push(sksigners, signerfile); +			if (!skkeys) +				skkeys = sk_OPENSSL_STRING_new_null(); +			if (!keyfile) +				keyfile = signerfile; +			sk_OPENSSL_STRING_push(skkeys, keyfile); +			} +		if (!sksigners) +			{ +			BIO_printf(bio_err, "No signer certificate specified\n"); +			badarg = 1; +			} +		signerfile = NULL; +		keyfile = NULL; +		need_rand = 1; +		} + +	else if (operation == SMIME_DECRYPT) +		{ +		if (!recipfile && !keyfile && !secret_key) +			{ +			BIO_printf(bio_err, "No recipient certificate or key specified\n"); +			badarg = 1; +			} +		} +	else if (operation == SMIME_ENCRYPT) +		{ +		if (!*args && !secret_key) +			{ +			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); +			badarg = 1; +			} +		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, "-skeyid        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, "-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, "-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; +		} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	if (!app_passwd(bio_err, passargin, 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)); +		if (inrand != NULL) +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n", +				app_RAND_load_files(inrand)); +		} + +	ret = 2; + +	if (!(operation & SMIME_SIGNERS)) +		flags &= ~CMS_DETACHED; + +	if (operation & SMIME_OP) +		{ +		if (outformat == FORMAT_ASN1) +			outmode = "wb"; +		} +	else +		{ +		if (flags & CMS_BINARY) +			outmode = "wb"; +		} + +	if (operation & SMIME_IP) +		{ +		if (informat == FORMAT_ASN1) +			inmode = "rb"; +		} +	else +		{ +		if (flags & CMS_BINARY) +			inmode = "rb"; +		} + +	if (operation == SMIME_ENCRYPT) +		{ +		if (!cipher) +			{ +#ifndef OPENSSL_NO_DES			 +			cipher = EVP_des_ede3_cbc(); +#else +			BIO_printf(bio_err, "No cipher selected\n"); +			goto end; +#endif +			} + +		if (secret_key && !secret_keyid) +			{ +			BIO_printf(bio_err, "No secret key id\n"); +			goto end; +			} + +		if (*args) +			encerts = sk_X509_new_null(); +		while (*args) +			{ +			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, +				NULL, e, "recipient certificate file"))) +				goto end; +			sk_X509_push(encerts, cert); +			cert = NULL; +			args++; +			} +		} + +	if (certfile) +		{ +		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, +			e, "certificate file"))) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (recipfile && (operation == SMIME_DECRYPT)) +		{ +		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, +			e, "recipient certificate file"))) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (operation == SMIME_SIGN_RECEIPT) +		{ +		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL, +			e, "receipt signer certificate file"))) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (operation == SMIME_DECRYPT) +		{ +		if (!keyfile) +			keyfile = recipfile; +		} +	else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) +		{ +		if (!keyfile) +			keyfile = signerfile; +		} +	else keyfile = NULL; + +	if (keyfile) +		{ +		key = load_key(bio_err, 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); + +	if (operation & SMIME_IP) +		{ +		if (informat == FORMAT_SMIME)  +			cms = SMIME_read_CMS(in, &indata); +		else if (informat == FORMAT_PEM)  +			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); +		else if (informat == FORMAT_ASN1)  +			cms = d2i_CMS_bio(in, NULL); +		else +			{ +			BIO_printf(bio_err, "Bad input format for CMS file\n"); +			goto end; +			} + +		if (!cms) +			{ +			BIO_printf(bio_err, "Error reading S/MIME message\n"); +			goto end; +			} +		if (contfile) +			{ +			BIO_free(indata); +			if (!(indata = BIO_new_file(contfile, "rb"))) +				{ +				BIO_printf(bio_err, "Can't read content file %s\n", contfile); +				goto end; +				} +			} +		if (certsoutfile) +			{ +			STACK_OF(X509) *allcerts; +			allcerts = CMS_get1_certs(cms); +			if (!save_certs(certsoutfile, allcerts)) +				{ +				BIO_printf(bio_err, +						"Error writing certs to %s\n", +								certsoutfile); +				ret = 5; +				goto end; +				} +			sk_X509_pop_free(allcerts, X509_free); +			} +		} + +	if (rctfile) +		{ +		char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; +		if (!(rctin = BIO_new_file(rctfile, rctmode))) +			{ +			BIO_printf (bio_err, +				 "Can't open receipt file %s\n", rctfile); +			goto end; +			} +		 +		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)  +			rcms = d2i_CMS_bio(rctin, NULL); +		else +			{ +			BIO_printf(bio_err, "Bad input format for receipt\n"); +			goto end; +			} + +		if (!rcms) +			{ +			BIO_printf(bio_err, "Error reading receipt\n"); +			goto end; +			} +		} + +	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 +		} + +	if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) +		{ +		if (!(store = setup_verify(bio_err, CAfile, CApath))) +			goto end; +		X509_STORE_set_verify_cb(store, cms_cb); +		if (vpm) +			X509_STORE_set1_param(store, vpm); +		} + + +	ret = 3; + +	if (operation == SMIME_DATA_CREATE) +		{ +		cms = CMS_data_create(in, flags); +		} +	else if (operation == SMIME_DIGEST_CREATE) +		{ +		cms = CMS_digest_create(in, sign_md, flags); +		} +	else if (operation == SMIME_COMPRESS) +		{ +		cms = CMS_compress(in, -1, flags); +		} +	else if (operation == SMIME_ENCRYPT) +		{ +		flags |= CMS_PARTIAL; +		cms = CMS_encrypt(encerts, in, cipher, flags); +		if (!cms) +			goto end; +		if (secret_key) +			{ +			if (!CMS_add0_recipient_key(cms, NID_undef,  +						secret_key, secret_keylen, +						secret_keyid, secret_keyidlen, +						NULL, NULL, NULL)) +				goto end; +			/* NULL these because call absorbs them */ +			secret_key = NULL; +			secret_keyid = NULL; +			} +		if (!(flags & CMS_STREAM)) +			{ +			if (!CMS_final(cms, in, NULL, flags)) +				goto end; +			} +		} +	else if (operation == SMIME_ENCRYPTED_ENCRYPT) +		{ +		cms = CMS_EncryptedData_encrypt(in, cipher, +						secret_key, secret_keylen, +						flags); + +		} +	else if (operation == SMIME_SIGN_RECEIPT) +		{ +		CMS_ContentInfo *srcms = NULL; +		STACK_OF(CMS_SignerInfo) *sis; +		CMS_SignerInfo *si; +		sis = CMS_get0_SignerInfos(cms); +		if (!sis) +			goto end; +		si = sk_CMS_SignerInfo_value(sis, 0); +		srcms = CMS_sign_receipt(si, signer, key, other, flags); +		if (!srcms) +			goto end; +		CMS_ContentInfo_free(cms); +		cms = srcms; +		} +	else if (operation & SMIME_SIGNERS) +		{ +		int i; +		/* If detached data content we enable streaming if +		 * S/MIME output format. +		 */ +		if (operation == SMIME_SIGN) +			{ +				 +			if (flags & CMS_DETACHED) +				{ +				if (outformat == FORMAT_SMIME) +					flags |= CMS_STREAM; +				} +			flags |= CMS_PARTIAL; +			cms = CMS_sign(NULL, NULL, other, in, flags); +			if (!cms) +				goto end; +			if (econtent_type) +				CMS_set1_eContentType(cms, econtent_type); + +			if (rr_to) +				{ +				rr = make_receipt_request(rr_to, rr_allorfirst, +								rr_from); +				if (!rr) +					{ +					BIO_puts(bio_err, +				"Signed Receipt Request Creation Error\n"); +					goto end; +					} +				} +			} +		else +			flags |= CMS_REUSE_DIGEST; +		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) +			{ +			CMS_SignerInfo *si; +			signerfile = sk_OPENSSL_STRING_value(sksigners, i); +			keyfile = sk_OPENSSL_STRING_value(skkeys, i); +			signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, +					e, "signer certificate"); +			if (!signer) +				goto end; +			key = load_key(bio_err, keyfile, keyform, 0, passin, e, +			       "signing key file"); +			if (!key) +				goto end; +			si = CMS_add1_signer(cms, signer, key, sign_md, flags); +			if (!si) +				goto end; +			if (rr && !CMS_add1_ReceiptRequest(si, rr)) +				goto end; +			X509_free(signer); +			signer = NULL; +			EVP_PKEY_free(key); +			key = NULL; +			} +		/* If not streaming or resigning finalize structure */ +		if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) +			{ +			if (!CMS_final(cms, in, NULL, flags)) +				goto end; +			} +		} + +	if (!cms) +		{ +		BIO_printf(bio_err, "Error creating CMS structure\n"); +		goto end; +		} + +	ret = 4; +	if (operation == SMIME_DECRYPT) +		{ + +		if (secret_key) +			{ +			if (!CMS_decrypt_set1_key(cms, +						secret_key, secret_keylen, +						secret_keyid, secret_keyidlen)) +				{ +				BIO_puts(bio_err, +					"Error decrypting CMS using secret key\n"); +				goto end; +				} +			} + +		if (key) +			{ +			if (!CMS_decrypt_set1_pkey(cms, key, recip)) +				{ +				BIO_puts(bio_err, +					"Error decrypting CMS using private key\n"); +				goto end; +				} +			} + +		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) +			{ +			BIO_printf(bio_err, "Error decrypting CMS structure\n"); +			goto end; +			} +		} +	else if (operation == SMIME_DATAOUT) +		{ +		if (!CMS_data(cms, out, flags)) +			goto end; +		} +	else if (operation == SMIME_UNCOMPRESS) +		{ +		if (!CMS_uncompress(cms, indata, out, flags)) +			goto end; +		} +	else if (operation == SMIME_DIGEST_VERIFY) +		{ +		if (CMS_digest_verify(cms, indata, out, flags) > 0) +			BIO_printf(bio_err, "Verification successful\n"); +		else +			{ +			BIO_printf(bio_err, "Verification failure\n"); +			goto end; +			} +		} +	else if (operation == SMIME_ENCRYPTED_DECRYPT) +		{ +		if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, +						indata, out, flags)) +			goto end; +		} +	else if (operation == SMIME_VERIFY) +		{ +		if (CMS_verify(cms, other, store, indata, out, flags) > 0) +			BIO_printf(bio_err, "Verification successful\n"); +		else +			{ +			BIO_printf(bio_err, "Verification failure\n"); +			if (verify_retcode) +				ret = verify_err + 32; +			goto end; +			} +		if (signerfile) +			{ +			STACK_OF(X509) *signers; +			signers = CMS_get0_signers(cms); +			if (!save_certs(signerfile, signers)) +				{ +				BIO_printf(bio_err, +						"Error writing signers to %s\n", +								signerfile); +				ret = 5; +				goto end; +				} +			sk_X509_free(signers); +			} +		if (rr_print) +			receipt_request_print(bio_err, cms); +					 +		} +	else if (operation == SMIME_VERIFY_RECEIPT) +		{ +		if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) +			BIO_printf(bio_err, "Verification successful\n"); +		else +			{ +			BIO_printf(bio_err, "Verification failure\n"); +			goto end; +			} +		} +	else +		{ +		if (noout) +			{ +			if (print) +				CMS_ContentInfo_print_ctx(out, cms, 0, NULL); +			} +		else if (outformat == FORMAT_SMIME) +			{ +			if (to) +				BIO_printf(out, "To: %s\n", to); +			if (from) +				BIO_printf(out, "From: %s\n", from); +			if (subject) +				BIO_printf(out, "Subject: %s\n", subject); +			if (operation == SMIME_RESIGN) +				ret = SMIME_write_CMS(out, cms, indata, flags); +			else +				ret = SMIME_write_CMS(out, cms, in, flags); +			} +		else if (outformat == FORMAT_PEM)  +			ret = PEM_write_bio_CMS_stream(out, cms, in, flags); +		else if (outformat == FORMAT_ASN1)  +			ret = i2d_CMS_bio_stream(out,cms, in, flags); +		else +			{ +			BIO_printf(bio_err, "Bad output format for CMS file\n"); +			goto end; +			} +		if (ret <= 0) +			{ +			ret = 6; +			goto end; +			} +		} +	ret = 0; +end: +	if (ret) +		ERR_print_errors(bio_err); +	if (need_rand) +		app_RAND_write_file(NULL, bio_err); +	sk_X509_pop_free(encerts, X509_free); +	sk_X509_pop_free(other, X509_free); +	if (vpm) +		X509_VERIFY_PARAM_free(vpm); +	if (sksigners) +		sk_OPENSSL_STRING_free(sksigners); +	if (skkeys) +		sk_OPENSSL_STRING_free(skkeys); +	if (secret_key) +		OPENSSL_free(secret_key); +	if (secret_keyid) +		OPENSSL_free(secret_keyid); +	if (econtent_type) +		ASN1_OBJECT_free(econtent_type); +	if (rr) +		CMS_ReceiptRequest_free(rr); +	if (rr_to) +		sk_OPENSSL_STRING_free(rr_to); +	if (rr_from) +		sk_OPENSSL_STRING_free(rr_from); +	X509_STORE_free(store); +	X509_free(cert); +	X509_free(recip); +	X509_free(signer); +	EVP_PKEY_free(key); +	CMS_ContentInfo_free(cms); +	CMS_ContentInfo_free(rcms); +	BIO_free(rctin); +	BIO_free(in); +	BIO_free(indata); +	BIO_free_all(out); +	if (passin) OPENSSL_free(passin); +	return (ret); +} + +static int save_certs(char *signerfile, STACK_OF(X509) *signers) +	{ +	int i; +	BIO *tmp; +	if (!signerfile) +		return 1; +	tmp = BIO_new_file(signerfile, "w"); +	if (!tmp) return 0; +	for(i = 0; i < sk_X509_num(signers); i++) +		PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); +	BIO_free(tmp); +	return 1; +	} +	 + +/* Minimal callback just to output policy info (if any) */ + +static int cms_cb(int ok, X509_STORE_CTX *ctx) +	{ +	int error; + +	error = X509_STORE_CTX_get_error(ctx); + +	verify_err = error; + +	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) +		&& ((error != X509_V_OK) || (ok != 2))) +		return ok; + +	policies_print(NULL, ctx); + +	return ok; + +	} + +static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns) +	{ +	STACK_OF(GENERAL_NAME) *gens; +	GENERAL_NAME *gen; +	int i, j; +	for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) +		{ +		gens = sk_GENERAL_NAMES_value(gns, i); +		for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) +			{ +			gen = sk_GENERAL_NAME_value(gens, j); +			BIO_puts(out, "    "); +			GENERAL_NAME_print(out, gen); +			BIO_puts(out, "\n"); +			} +		} +	return; +	} + +static void receipt_request_print(BIO *out, CMS_ContentInfo *cms) +	{ +	STACK_OF(CMS_SignerInfo) *sis; +	CMS_SignerInfo *si; +	CMS_ReceiptRequest *rr; +	int allorfirst; +	STACK_OF(GENERAL_NAMES) *rto, *rlist; +	ASN1_STRING *scid; +	int i, rv; +	sis = CMS_get0_SignerInfos(cms); +	for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) +		{ +		si = sk_CMS_SignerInfo_value(sis, i); +		rv = CMS_get1_ReceiptRequest(si, &rr); +		BIO_printf(bio_err, "Signer %d:\n", i + 1); +		if (rv == 0) +			BIO_puts(bio_err, "  No Receipt Request\n"); +		else if (rv < 0) +			{ +			BIO_puts(bio_err, "  Receipt Request Parse Error\n"); +			ERR_print_errors(bio_err); +			} +		else +			{ +			char *id; +			int idlen; +			CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, +							&rlist, &rto); +			BIO_puts(out, "  Signed Content ID:\n"); +			idlen = ASN1_STRING_length(scid); +			id = (char *)ASN1_STRING_data(scid); +			BIO_dump_indent(out, id, idlen, 4); +			BIO_puts(out, "  Receipts From"); +			if (rlist) +				{ +				BIO_puts(out, " List:\n"); +				gnames_stack_print(out, rlist); +				} +			else if (allorfirst == 1) +				BIO_puts(out, ": First Tier\n"); +			else if (allorfirst == 0) +				BIO_puts(out, ": All\n"); +			else +				BIO_printf(out, " Unknown (%d)\n", allorfirst); +			BIO_puts(out, "  Receipts To:\n"); +			gnames_stack_print(out, rto); +			} +		if (rr) +			CMS_ReceiptRequest_free(rr); +		} +	} + +static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns) +	{ +	int i; +	STACK_OF(GENERAL_NAMES) *ret; +	GENERAL_NAMES *gens = NULL; +	GENERAL_NAME *gen = NULL; +	ret = sk_GENERAL_NAMES_new_null(); +	if (!ret) +		goto err; +	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) +		{ +		char *str = sk_OPENSSL_STRING_value(ns, i); +		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); +		if (!gen) +			goto err; +		gens = GENERAL_NAMES_new(); +		if (!gens) +			goto err; +		if (!sk_GENERAL_NAME_push(gens, gen)) +			goto err; +		gen = NULL; +		if (!sk_GENERAL_NAMES_push(ret, gens)) +			goto err; +		gens = NULL; +		} + +	return ret; + +	err: +	if (ret) +		sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free); +	if (gens) +		GENERAL_NAMES_free(gens); +	if (gen) +		GENERAL_NAME_free(gen); +	return NULL; +	} + + +static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, +						int rr_allorfirst, +						STACK_OF(OPENSSL_STRING) *rr_from) +	{ +	STACK_OF(GENERAL_NAMES) *rct_to, *rct_from; +	CMS_ReceiptRequest *rr; +	rct_to = make_names_stack(rr_to); +	if (!rct_to) +		goto err; +	if (rr_from) +		{ +		rct_from = make_names_stack(rr_from); +		if (!rct_from) +			goto err; +		} +	else +		rct_from = NULL; +	rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, +						rct_to); +	return rr; +	err: +	return NULL; +	} + +#endif diff --git a/main/openssl/apps/crl.c b/main/openssl/apps/crl.c new file mode 100644 index 00000000..c395b2af --- /dev/null +++ b/main/openssl/apps/crl.c @@ -0,0 +1,446 @@ +/* apps/crl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/pem.h> + +#undef PROG +#define PROG	crl_main + +#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", +" -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 +}; + +static X509_CRL *load_crl(char *file, int format); +static BIO *bio_out=NULL; + +int MAIN(int, char **); + +int 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; +	BIO *out=NULL; +	int informat,outformat; +	char *infile=NULL,*outfile=NULL; +	int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0; +	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); +			} +#endif +			} + +	informat=FORMAT_PEM; +	outformat=FORMAT_PEM; + +	argc--; +	argv++; +	num=0; +	while (argc >= 1) +		{ +#ifdef undef +		if	(strcmp(*argv,"-p") == 0) +			{ +			if (--argc < 1) goto bad; +			if (!args_from_file(++argv,Nargc,Nargv)) { goto end; }*/ +			} +#endif +		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,"-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); +			do_ver = 1; +			} +		else if (strcmp(*argv,"-verify") == 0) +			do_ver = 1; +		else if (strcmp(*argv,"-text") == 0) +			text = 1; +		else if (strcmp(*argv,"-hash") == 0) +			hash= ++num; +		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) +			issuer= ++num; +		else if (strcmp(*argv,"-lastupdate") == 0) +			lastupdate= ++num; +		else if (strcmp(*argv,"-nextupdate") == 0) +			nextupdate= ++num; +		else if (strcmp(*argv,"-noout") == 0) +			noout= ++num; +		else if (strcmp(*argv,"-fingerprint") == 0) +			fingerprint= ++num; +		else if (strcmp(*argv,"-crlnumber") == 0) +			crlnumber= ++num; +		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; +			} +		argc--; +		argv++; +		} + +	if (badops) +		{ +bad: +		for (pp=crl_usage; (*pp != NULL); pp++) +			BIO_printf(bio_err,"%s",*pp); +		goto end; +		} + +	ERR_load_crypto_strings(); +	x=load_crl(infile,informat); +	if (x == NULL) { goto end; } + +	if(do_ver) { +		store = X509_STORE_new(); +		lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file()); +		if (lookup == NULL) 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()); +		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; +		} + +		i = X509_STORE_get_by_subject(&ctx, X509_LU_X509,  +					X509_CRL_get_issuer(x), &xobj); +		if(i <= 0) { +			BIO_printf(bio_err, +				"Error getting CRL issuer certificate\n"); +			goto end; +		} +		pkey = X509_get_pubkey(xobj.data.x509); +		X509_OBJECT_free_contents(&xobj); +		if(!pkey) { +			BIO_printf(bio_err, +				"Error getting CRL issuer public key\n"); +			goto end; +		} +		i = X509_CRL_verify(x, pkey); +		EVP_PKEY_free(pkey); +		if(i < 0) goto end; +		if(i == 0) BIO_printf(bio_err, "verify failure\n"); +		else BIO_printf(bio_err, "verify OK\n"); +	} + +	if (num) +		{ +		for (i=1; i<=num; i++) +			{ +			if (issuer == i) +				{ +				print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); +				} +			if (crlnumber == i) +				{ +				ASN1_INTEGER *crlnum; +				crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, +							      NULL, NULL); +				BIO_printf(bio_out,"crlNumber="); +				if (crlnum) +					{ +					i2a_ASN1_INTEGER(bio_out, crlnum); +					ASN1_INTEGER_free(crlnum); +					} +				else +					BIO_puts(bio_out, "<NONE>"); +				BIO_printf(bio_out,"\n"); +				} +			if (hash == i) +				{ +				BIO_printf(bio_out,"%08lx\n", +					X509_NAME_hash(X509_CRL_get_issuer(x))); +				} +			if (lastupdate == i) +				{ +				BIO_printf(bio_out,"lastUpdate="); +				ASN1_TIME_print(bio_out, +						X509_CRL_get_lastUpdate(x)); +				BIO_printf(bio_out,"\n"); +				} +			if (nextupdate == i) +				{ +				BIO_printf(bio_out,"nextUpdate="); +				if (X509_CRL_get_nextUpdate(x))  +					ASN1_TIME_print(bio_out, +						X509_CRL_get_nextUpdate(x)); +				else +					BIO_printf(bio_out,"NONE"); +				BIO_printf(bio_out,"\n"); +				} +			if (fingerprint == i) +				{ +				int j; +				unsigned int n; +				unsigned char md[EVP_MAX_MD_SIZE]; + +				if (!X509_CRL_digest(x,digest,md,&n)) +					{ +					BIO_printf(bio_err,"out of memory\n"); +					goto end; +					} +				BIO_printf(bio_out,"%s Fingerprint=", +						OBJ_nid2sn(EVP_MD_type(digest))); +				for (j=0; j<(int)n; j++) +					{ +					BIO_printf(bio_out,"%02X%c",md[j], +						(j+1 == (int)n) +						?'\n':':'); +					} +				} +			} +		} + +	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 (text) X509_CRL_print(out, x); + +	if (noout)  +		{ +		ret = 0; +		goto end; +		} + +	if 	(outformat == FORMAT_ASN1) +		i=(int)i2d_X509_CRL_bio(out,x); +	else if (outformat == FORMAT_PEM) +		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: +	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); +	} + +static X509_CRL *load_crl(char *infile, int format) +	{ +	X509_CRL *x=NULL; +	BIO *in=NULL; + +	in=BIO_new(BIO_s_file()); +	if (in == 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 	(format == FORMAT_ASN1) +		x=d2i_X509_CRL_bio(in,NULL); +	else if (format == FORMAT_PEM) +		x=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 (x == NULL) +		{ +		BIO_printf(bio_err,"unable to load CRL\n"); +		ERR_print_errors(bio_err); +		goto end; +		} +	 +end: +	BIO_free(in); +	return(x); +	} + diff --git a/main/openssl/apps/crl2p7.c b/main/openssl/apps/crl2p7.c new file mode 100644 index 00000000..bbc83774 --- /dev/null +++ b/main/openssl/apps/crl2p7.c @@ -0,0 +1,337 @@ +/* apps/crl2p7.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.] + */ + +/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu> + * and donated 'to the cause' along with lots and lots of other fixes to + * the library. */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include "apps.h" +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/pkcs7.h> +#include <openssl/pem.h> +#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 + */ + +int MAIN(int, char **); + +int 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; + +	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) +			{ +			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(); +			sk_OPENSSL_STRING_push(certflst,*(++argv)); +			} +		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; +		} + +	if (!nocrl) +		{ +		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) +			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); +			goto end; +			} +		} +	 +	if ((p7=PKCS7_new()) == NULL) goto end; +	if ((p7s=PKCS7_SIGNED_new()) == NULL) goto end; +	p7->type=OBJ_nid2obj(NID_pkcs7_signed); +	p7->d.sign=p7s; +	p7s->contents->type=OBJ_nid2obj(NID_pkcs7_data); + +	if (!ASN1_INTEGER_set(p7s->version,1)) goto end; +	if ((crl_stack=sk_X509_CRL_new_null()) == NULL) goto end; +	p7s->crl=crl_stack; +	if (crl != NULL) +		{ +		sk_X509_CRL_push(crl_stack,crl); +		crl=NULL; /* now part of p7 for OPENSSL_freeing */ +		} + +	if ((cert_stack=sk_X509_new_null()) == NULL) goto end; +	p7s->cert=cert_stack; + +	if(certflst) for(i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { +		certfile = sk_OPENSSL_STRING_value(certflst, i); +		if (add_certs_from_file(cert_stack,certfile) < 0) +			{ +			BIO_printf(bio_err, "error loading certificates\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +	} + +	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; +			} +		} + +	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); +		goto end; +		} +	ret=0; +end: +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (p7 != NULL) PKCS7_free(p7); +	if (crl != NULL) X509_CRL_free(crl); + +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +/* + *---------------------------------------------------------------------- + * int add_certs_from_file + * + *	Read a list of certificates to be checked from a file. + * + * Results: + *	number of certs added if successful, -1 if not. + *---------------------------------------------------------------------- + */ +static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile) +	{ +	BIO *in=NULL; +	int count=0; +	int ret= -1; +	STACK_OF(X509_INFO) *sk=NULL; +	X509_INFO *xi; + +	in=BIO_new(BIO_s_file()); +	if ((in == NULL) || (BIO_read_filename(in,certfile) <= 0)) +		{ +		BIO_printf(bio_err,"error opening the file, %s\n",certfile); +		goto end; +		} + +	/* This loads from a file, a stack of x509/crl/pkey sets */ +	sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL); +	if (sk == NULL) { +		BIO_printf(bio_err,"error reading the file, %s\n",certfile); +		goto end; +	} + +	/* scan over it and pull out the CRL's */ +	while (sk_X509_INFO_num(sk)) +		{ +		xi=sk_X509_INFO_shift(sk); +		if (xi->x509 != NULL) +			{ +			sk_X509_push(stack,xi->x509); +			xi->x509=NULL; +			count++; +			} +		X509_INFO_free(xi); +		} + +	ret=count; +end: + 	/* never need to OPENSSL_free x */ +	if (in != NULL) BIO_free(in); +	if (sk != NULL) sk_X509_INFO_free(sk); +	return(ret); +	} + diff --git a/main/openssl/apps/dgst.c b/main/openssl/apps/dgst.c new file mode 100644 index 00000000..9bf38ce7 --- /dev/null +++ b/main/openssl/apps/dgst.c @@ -0,0 +1,632 @@ +/* apps/dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/hmac.h> + +#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) +	{ +	ENGINE *e = NULL; +	unsigned char *buf=NULL; +	int i,err=1; +	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 *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; +#ifndef OPENSSL_NO_ENGINE +	char *engine=NULL; +#endif +	char *hmac_key=NULL; +	char *mac_name=NULL; +	STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; + +	apps_startup(); + +	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		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) +			separator=1; +		else if (strcmp(*argv,"-r") == 0) +			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); +			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)); +			} +#ifndef OPENSSL_NO_ENGINE +		else if (strcmp(*argv,"-engine") == 0) +			{ +			if (--argc < 1) break; +			engine= *(++argv); +        		e = setup_engine(bio_err, engine, 0); +			} +#endif +		else if (strcmp(*argv,"-hex") == 0) +			out_bin = 0; +		else if (strcmp(*argv,"-binary") == 0) +			out_bin = 1; +		else if (strcmp(*argv,"-d") == 0) +			debug=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; +			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 (!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) +			md=m; +		else +			break; +		argc--; +		argv++; +		} + + +	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,"-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; +		} + +	in=BIO_new(BIO_s_file()); +	bmd=BIO_new(BIO_f_md()); +	if (debug) +		{ +		BIO_set_callback(in,BIO_debug_callback); +		/* needed for windows 3.1 */ +		BIO_set_callback_arg(in,(char *)bio_err); +		} + +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) +		{ +		BIO_printf(bio_err, "Error getting password\n"); +		goto end; +		} + +	if ((in == NULL) || (bmd == NULL)) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} + +	if(out_bin == -1) { +		if(keyfile) +			out_bin = 1; +		else +			out_bin = 0; +	} + +	if(randfile) +		app_RAND_load_file(randfile, bio_err, 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); +		goto end; +	} +	if ((!!mac_name + !!keyfile + !!hmac_key) > 1) +		{ +		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); +		goto end; +		} + +	if(keyfile) +		{ +		if (want_pub) +			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, +				e, "key file"); +		else +			sigkey = load_key(bio_err, keyfile, keyform, 0, passin, +				e, "key file"); +		if (!sigkey) +			{ +			/* load_[pub]key() has already printed an appropriate +			   message */ +			goto end; +			} +		} + +	if (mac_name) +		{ +		EVP_PKEY_CTX *mac_ctx = NULL; +		int r = 0; +		if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0)) +			goto mac_end; +		if (macopts) +			{ +			char *macopt; +			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) +				{ +				macopt = sk_OPENSSL_STRING_value(macopts, i); +				if (pkey_ctrl_string(mac_ctx, macopt) <= 0) +					{ +					BIO_printf(bio_err, +						"MAC parameter error \"%s\"\n", +						macopt); +					ERR_print_errors(bio_err); +					goto mac_end; +					} +				} +			} +		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) +			{ +			BIO_puts(bio_err, "Error generating key\n"); +			ERR_print_errors(bio_err); +			goto mac_end; +			} +		r = 1; +		mac_end: +		if (mac_ctx) +			EVP_PKEY_CTX_free(mac_ctx); +		if (r == 0) +			goto end; +		} + +	if (hmac_key) +		{ +		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, +					(unsigned char *)hmac_key, -1); +		if (!sigkey) +			goto end; +		} + +	if (sigkey) +		{ +		EVP_MD_CTX *mctx = NULL; +		EVP_PKEY_CTX *pctx = NULL; +		int r; +		if (!BIO_get_md_ctx(bmd, &mctx)) +			{ +			BIO_printf(bio_err, "Error getting context\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		if (do_verify) +			r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey); +		else +			r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey); +		if (!r) +			{ +			BIO_printf(bio_err, "Error setting context\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		if (sigopts) +			{ +			char *sigopt; +			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) +				{ +				sigopt = sk_OPENSSL_STRING_value(sigopts, i); +				if (pkey_ctrl_string(pctx, sigopt) <= 0) +					{ +					BIO_printf(bio_err, +						"parameter error \"%s\"\n", +						sigopt); +					ERR_print_errors(bio_err); +					goto end; +					} +				} +			} +		} +	/* we use md as a filter, reading from 'in' */ +	else +		{ +		if (md == NULL) +			md = EVP_md5();  +		if (!BIO_set_md(bmd,md)) +			{ +			BIO_printf(bio_err, "Error setting digest %s\n", pname); +			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); +		if(!sigbio) { +			BIO_printf(bio_err, "Error opening signature file %s\n", +								sigfile); +			ERR_print_errors(bio_err); +			goto end; +		} +		siglen = BIO_read(sigbio, sigbuf, siglen); +		BIO_free(sigbio); +		if(siglen <= 0) { +			BIO_printf(bio_err, "Error reading signature file %s\n", +								sigfile); +			ERR_print_errors(bio_err); +			goto end; +		} +	} +	inp=BIO_push(bmd,in); + +	if (md == NULL) +		{ +		EVP_MD_CTX *tctx; +		BIO_get_md_ctx(bmd, &tctx); +		md = EVP_MD_CTX_md(tctx); +		} + +	if (argc == 0) +		{ +		BIO_set_fp(in,stdin,BIO_NOCLOSE); +		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, +			  siglen,NULL,NULL,"stdin",bmd); +		} +	else +		{ +		const char *md_name = NULL, *sig_name = NULL; +		if(!out_bin) +			{ +			if (sigkey) +				{ +				const EVP_PKEY_ASN1_METHOD *ameth; +				ameth = EVP_PKEY_get0_asn1(sigkey); +				if (ameth) +					EVP_PKEY_asn1_get0_info(NULL, NULL, +						NULL, NULL, &sig_name, ameth); +				} +			md_name = EVP_MD_name(md); +			} +		err = 0; +		for (i=0; i<argc; i++) +			{ +			int r; +			if (BIO_read_filename(in,argv[i]) <= 0) +				{ +				perror(argv[i]); +				err++; +				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; +			(void)BIO_reset(bmd); +			} +		} +end: +	if (buf != NULL) +		{ +		OPENSSL_cleanse(buf,BUFSIZE); +		OPENSSL_free(buf); +		} +	if (in != NULL) BIO_free(in); +	if (passin) +		OPENSSL_free(passin); +	BIO_free_all(out); +	EVP_PKEY_free(sigkey); +	if (sigopts) +		sk_OPENSSL_STRING_free(sigopts); +	if (macopts) +		sk_OPENSSL_STRING_free(macopts); +	if(sigbuf) OPENSSL_free(sigbuf); +	if (bmd != NULL) BIO_free(bmd); +	apps_shutdown(); +	OPENSSL_EXIT(err); +	} + +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) +	{ +	size_t len; +	int i; + +	for (;;) +		{ +		i=BIO_read(bp,(char *)buf,BUFSIZE); +		if(i < 0) +			{ +			BIO_printf(bio_err, "Read Error in %s\n",file); +			ERR_print_errors(bio_err); +			return 1; +			} +		if (i == 0) break; +		} +	if(sigin) +		{ +		EVP_MD_CTX *ctx; +		BIO_get_md_ctx(bp, &ctx); +		i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);  +		if(i > 0) +			BIO_printf(out, "Verified OK\n"); +		else if(i == 0) +			{ +			BIO_printf(out, "Verification Failure\n"); +			return 1; +			} +		else +			{ +			BIO_printf(bio_err, "Error Verifying Data\n"); +			ERR_print_errors(bio_err); +			return 1; +			} +		return 0; +		} +	if(key) +		{ +		EVP_MD_CTX *ctx; +		BIO_get_md_ctx(bp, &ctx); +		len = BUFSIZE; +		if(!EVP_DigestSignFinal(ctx, buf, &len))  +			{ +			BIO_printf(bio_err, "Error Signing Data\n"); +			ERR_print_errors(bio_err); +			return 1; +			} +		} +	else +		{ +		len=BIO_gets(bp,(char *)buf,BUFSIZE); +		if ((int)len <0) +			{ +			ERR_print_errors(bio_err); +			return 1; +			} +		} + +	if(binout) BIO_write(out, buf, len); +	else if (sep == 2) +		{ +		for (i=0; i<(int)len; i++) +			BIO_printf(out, "%02x",buf[i]); +		BIO_printf(out, " *%s\n", file); +		} +	else  +		{ +		if (sig_name) +			BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); +		else if (md_name) +			BIO_printf(out, "%s(%s)= ", md_name, file); +		else +			BIO_printf(out, "(%s)= ", file); +		for (i=0; i<(int)len; i++) +			{ +			if (sep && (i != 0)) +				BIO_printf(out, ":"); +			BIO_printf(out, "%02x",buf[i]); +			} +		BIO_printf(out, "\n"); +		} +	return 0; +	} + diff --git a/main/openssl/apps/dh.c b/main/openssl/apps/dh.c new file mode 100644 index 00000000..dee9c01f --- /dev/null +++ b/main/openssl/apps/dh.c @@ -0,0 +1,355 @@ +/* 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); +#ifdef undef +		printf("p="); +		BN_print(stdout,dh->p); +		printf("\ng="); +		BN_print(stdout,dh->g); +		printf("\n"); +		if (dh->length != 0) +			printf("recommended private length=%ld\n",dh->length); +#endif +		} +	 +	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: +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (dh != NULL) DH_free(dh); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} +#else /* !OPENSSL_NO_DH */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/dh1024.pem b/main/openssl/apps/dh1024.pem new file mode 100644 index 00000000..6eaeca9b --- /dev/null +++ b/main/openssl/apps/dh1024.pem @@ -0,0 +1,10 @@ +-----BEGIN DH PARAMETERS----- +MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY +jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6 +ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC +-----END DH PARAMETERS----- + +These are the 1024 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. +Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/main/openssl/apps/dh2048.pem b/main/openssl/apps/dh2048.pem new file mode 100644 index 00000000..dcd0b8d0 --- /dev/null +++ b/main/openssl/apps/dh2048.pem @@ -0,0 +1,12 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV +89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50 +T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb +zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX +Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT +CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg== +-----END DH PARAMETERS----- + +These are the 2048 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. diff --git a/main/openssl/apps/dh4096.pem b/main/openssl/apps/dh4096.pem new file mode 100644 index 00000000..1b35ad8e --- /dev/null +++ b/main/openssl/apps/dh4096.pem @@ -0,0 +1,18 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ +l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt +Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS +Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98 +VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc +alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM +sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9 +ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte +OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH +AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL +KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI= +-----END DH PARAMETERS----- + +These are the 4096 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. +Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/main/openssl/apps/dh512.pem b/main/openssl/apps/dh512.pem new file mode 100644 index 00000000..200d16cd --- /dev/null +++ b/main/openssl/apps/dh512.pem @@ -0,0 +1,9 @@ +-----BEGIN DH PARAMETERS----- +MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak +XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC +-----END DH PARAMETERS----- + +These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. +Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/main/openssl/apps/dhparam.c b/main/openssl/apps/dhparam.c new file mode 100644 index 00000000..b47097cb --- /dev/null +++ b/main/openssl/apps/dhparam.c @@ -0,0 +1,560 @@ +/* apps/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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <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> + +#ifndef OPENSSL_NO_DSA +#include <openssl/dsa.h> +#endif + +#undef PROG +#define PROG	dhparam_main + +#define DEFBITS	512 + +/* -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 MS_CALLBACK 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; +#ifndef OPENSSL_NO_ENGINE +	char *engine=NULL; +#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); +			} +#endif +		else if (strcmp(*argv,"-check") == 0) +			check=1; +		else if (strcmp(*argv,"-text") == 0) +			text=1; +#ifndef OPENSSL_NO_DSA +		else if (strcmp(*argv,"-dsaparam") == 0) +			dsaparam=1; +#endif +		else if (strcmp(*argv,"-C") == 0) +			C=1; +		else if (strcmp(*argv,"-noout") == 0) +			noout=1; +		else if (strcmp(*argv,"-2") == 0) +			g=2; +		else if (strcmp(*argv,"-5") == 0) +			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--; +		} + +	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 512)\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"); +		goto end; +		} + +	ERR_load_crypto_strings(); + +#ifndef OPENSSL_NO_ENGINE +        setup_engine(bio_err, 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(num) { + +		BN_GENCB cb; +		BN_GENCB_set(&cb, dh_cb, bio_err); +		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)); + +#ifndef OPENSSL_NO_DSA +		if (dsaparam) +			{ +			DSA *dsa = DSA_new(); +			 +			BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num); +			if(!dsa || !DSA_generate_parameters_ex(dsa, num, +						NULL, 0, NULL, NULL, &cb)) +				{ +				if(dsa) DSA_free(dsa); +				ERR_print_errors(bio_err); +				goto end; +				} + +			dh = DSA_dup_DH(dsa); +			DSA_free(dsa); +			if (dh == NULL) +				{ +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		else +#endif +			{ +			dh = DH_new(); +			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_generate_parameters_ex(dh, num, g, &cb)) +				{ +				if(dh) DH_free(dh); +				ERR_print_errors(bio_err); +				goto end; +				} +			} + +		app_RAND_write_file(NULL, bio_err); +	} else { + +		in=BIO_new(BIO_s_file()); +		if (in == 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	(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; +			 +			if (informat == FORMAT_ASN1) +				dsa=d2i_DSAparams_bio(in,NULL); +			else /* informat == FORMAT_PEM */ +				dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL); +			 +			if (dsa == NULL) +				{ +				BIO_printf(bio_err,"unable to load DSA parameters\n"); +				ERR_print_errors(bio_err); +				goto end; +				} +			 +			dh = DSA_dup_DH(dsa); +			DSA_free(dsa); +			if (dh == NULL) +				{ +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		else +#endif +			{ +			if (informat == FORMAT_ASN1) +				dh=d2i_DHparams_bio(in,NULL); +			else /* informat == FORMAT_PEM */ +				dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL); +			 +			if (dh == NULL) +				{ +				BIO_printf(bio_err,"unable to load DH parameters\n"); +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		 +		/* dh != NULL */ +	} +	 +	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 (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; +			} +		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", +			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\t{ DH_free(dh); return(NULL); }\n"); +		if (dh->length) +			printf("\tdh->length = %ld;\n", dh->length); +		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: +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (dh != NULL) DH_free(dh); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +/* dh_cb is identical to dsa_cb in apps/dsaparam.c */ +static int MS_CALLBACK 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(cb->arg,&c,1); +	(void)BIO_flush(cb->arg); +#ifdef LINT +	p=n; +#endif +	return 1; +	} + +#else /* !OPENSSL_NO_DH */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/dsa-ca.pem b/main/openssl/apps/dsa-ca.pem new file mode 100644 index 00000000..cccc1420 --- /dev/null +++ b/main/openssl/apps/dsa-ca.pem @@ -0,0 +1,40 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBugIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ +PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel +u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH +Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso +hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu +SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y +Mu0OArgCgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuHvSLw9YUrJahcBHmbpvt4 +94lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUqAylOVFJJJXuirVJ+o+0T +tOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u3enxhqnDGQIUB78dhW77 +J6zsFbSEHaQGUmfSeoM= +-----END DSA PRIVATE KEY----- +-----BEGIN CERTIFICATE REQUEST----- +MIICUjCCAhECAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAxMCQ0Ew +ggG0MIIBKQYFKw4DAgwwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaW +sxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5m +rmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHk +cJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVo +bzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqR +CZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxB +F5WS6wG1c6Vqftgy7Q4CuAOBhAACgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuH +vSLw9YUrJahcBHmbpvt494lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUq +AylOVFJJJXuirVJ+o+0TtOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u +3enxhqnDGaAAMAkGBSsOAwIbBQADMAAwLQIVAJGVuFsG/0DBuSZ0jF7ypdU0/G0v +AhQfeF5BoMMDbX/kidUVpQ6gadPlZA== +-----END CERTIFICATE REQUEST----- +-----BEGIN CERTIFICATE----- +MIIBrjCCAWwCAQswCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww +CgYDVQQDEwNQQ0EwHhcNOTcwNjE1MDIxNDI5WhcNOTcwNzE1MDIxNDI5WjBSMQsw +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu +ZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDEwJDQTCBkjAJBgUrDgMCDAUAA4GE +AAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfsi4e9IvD1hSslqFwEeZum+3j3iUXi +ALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj25SoDKU5UUkkle6KtUn6j7RO04UMh +MQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17ry7d6fGGqcMZMAkGBSsOAwIbBQAD +MQAwLgIVAJ4wtQsANPxHo7Q4IQZYsL12SKdbAhUAjJ9n38zxT+iai2164xS+LIfa +C1Q= +-----END CERTIFICATE----- + diff --git a/main/openssl/apps/dsa-pca.pem b/main/openssl/apps/dsa-pca.pem new file mode 100644 index 00000000..d23774ed --- /dev/null +++ b/main/openssl/apps/dsa-pca.pem @@ -0,0 +1,46 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBvAIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ +PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel +u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH +Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso +hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu +SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y +Mu0OArgCgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk +umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A +29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUCFQDNvrBz +6TicfImU7UFRn9h00j0lJQ== +-----END DSA PRIVATE KEY----- +-----BEGIN CERTIFICATE REQUEST----- +MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENB +MIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2G +lrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7O +Zq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR +5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnl +aG8w42nh5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6 +kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15Als +QReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe +6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZ +yr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0 +z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNB +nSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w== +-----END CERTIFICATE REQUEST----- +-----BEGIN CERTIFICATE----- +MIIC0zCCApECAQAwCQYFKw4DAhsFADBTMQswCQYDVQQGEwJBVTETMBEGA1UECBMK +U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQww +CgYDVQQDEwNQQ0EwHhcNOTcwNjE0MjI1NDQ1WhcNOTcwNzE0MjI1NDQ1WjBTMQsw +CQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJu +ZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNQQ0EwggG1MIIBKQYFKw4DAgww +ggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7FPYaWsxXgUy6P4FmCc5A+dTGZ +R3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmIbs5mrmuINvvsKNzC16W75Sw5 +JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/NgBHkcJVbUM1JAhUA9wcx7fps +BgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYlmeVobzDjaeHls12YuyiGSPze +mQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEnqHqRCZ228U2cVA9YBu5JdAfO +VX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/XkCWxBF5WS6wG1c6Vqftgy7Q4C +uAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk +umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A +29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUwCQYFKw4D +AhsFAAMxADAuAhUAvtv6AkMolix1Jvy3UnVEIUqdCUICFQC+jq8P49mwrY9oJ24n +5rKUjNBhSg== +-----END CERTIFICATE----- + diff --git a/main/openssl/apps/dsa.c b/main/openssl/apps/dsa.c new file mode 100644 index 00000000..5222487a --- /dev/null +++ b/main/openssl/apps/dsa.c @@ -0,0 +1,376 @@ +/* apps/dsa.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_DSA */ +#ifndef OPENSSL_NO_DSA +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/dsa.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/bn.h> + +#undef PROG +#define PROG	dsa_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 + * -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 **); + +int MAIN(int argc, char **argv) +	{ +	ENGINE *e = NULL; +	int ret=1; +	DSA *dsa=NULL; +	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; +	char *infile,*outfile,*prog; +#ifndef OPENSSL_NO_ENGINE +	char *engine; +#endif +	char *passargin = NULL, *passargout = NULL; +	char *passin = NULL, *passout = NULL; +	int modulus=0; + +	int pvk_encr = 2; + +	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 +		else if (strcmp(*argv,"-pvk-strong") == 0) +			pvk_encr=2; +		else if (strcmp(*argv,"-pvk-weak") == 0) +			pvk_encr=1; +		else if (strcmp(*argv,"-pvk-none") == 0) +			pvk_encr=0; +		else if (strcmp(*argv,"-noout") == 0) +			noout=1; +		else if (strcmp(*argv,"-text") == 0) +			text=1; +		else if (strcmp(*argv,"-modulus") == 0) +			modulus=1; +		else if (strcmp(*argv,"-pubin") == 0) +			pubin=1; +		else if (strcmp(*argv,"-pubout") == 0) +			pubout=1; +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) +			{ +			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," -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(); + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	if(!app_passwd(bio_err, passargin, passargout, &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"); +		else +			pkey = load_key(bio_err, infile, informat, 1, +				passin, e, "Private Key"); + +		if (pkey) +			{ +			dsa = EVP_PKEY_get1_DSA(pkey); +			EVP_PKEY_free(pkey); +			} +		} +	if (dsa == NULL) +		{ +		BIO_printf(bio_err,"unable to load Key\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; +			} +		} + +	if (text)  +		if (!DSA_print(out,dsa,0)) +			{ +			perror(outfile); +			ERR_print_errors(bio_err); +			goto end; +			} + +	if (modulus) +		{ +		fprintf(stdout,"Public Key="); +		BN_print(out,dsa->pub_key); +		fprintf(stdout,"\n"); +		} + +	if (noout) goto end; +	BIO_printf(bio_err,"writing DSA key\n"); +	if 	(outformat == FORMAT_ASN1) { +		if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa); +		else i=i2d_DSAPrivateKey_bio(out,dsa); +	} else if (outformat == FORMAT_PEM) { +		if(pubin || pubout) +			i=PEM_write_bio_DSA_PUBKEY(out,dsa); +		else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc, +							NULL,0,NULL, passout); +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) +	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { +		EVP_PKEY *pk; +		pk = EVP_PKEY_new(); +		EVP_PKEY_set1_DSA(pk, dsa); +		if (outformat == FORMAT_PVK) +			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); +		else if (pubin || pubout) +			i = i2b_PublicKey_bio(out, pk); +		else +			i = i2b_PrivateKey_bio(out, pk); +		EVP_PKEY_free(pk); +#endif +	} else { +		BIO_printf(bio_err,"bad output format specified for outfile\n"); +		goto end; +		} +	if (i <= 0) +		{ +		BIO_printf(bio_err,"unable to write private key\n"); +		ERR_print_errors(bio_err); +		} +	else +		ret=0; +end: +	if(in != NULL) BIO_free(in); +	if(out != NULL) BIO_free_all(out); +	if(dsa != NULL) DSA_free(dsa); +	if(passin) OPENSSL_free(passin); +	if(passout) OPENSSL_free(passout); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} +#else /* !OPENSSL_NO_DSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/dsa1024.pem b/main/openssl/apps/dsa1024.pem new file mode 100644 index 00000000..082dec38 --- /dev/null +++ b/main/openssl/apps/dsa1024.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUx +mUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+Us +OSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36 +bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLsohkj8 +3pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbuSXQH +zlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7YMu0O +Arg= +-----END DSA PARAMETERS----- diff --git a/main/openssl/apps/dsa512.pem b/main/openssl/apps/dsa512.pem new file mode 100644 index 00000000..5f86d1a6 --- /dev/null +++ b/main/openssl/apps/dsa512.pem @@ -0,0 +1,6 @@ +-----BEGIN DSA PARAMETERS----- +MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97 +TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA +gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO +L8wka5B33qJoplISogOdIA== +-----END DSA PARAMETERS----- diff --git a/main/openssl/apps/dsap.pem b/main/openssl/apps/dsap.pem new file mode 100644 index 00000000..d4dfdb30 --- /dev/null +++ b/main/openssl/apps/dsap.pem @@ -0,0 +1,6 @@ +-----BEGIN DSA PARAMETERS----- +MIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZS4J1PHvPrm9MXj5ntVheDPkdmBDTncya +GAJcMjwsyB/GvLDGd6yGCw/8eF+09wIVAK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2 +t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjgtWiJc/tpvcuzeuAayH89UofjAGueKjXD +ADiRffvSdhrNw5dkqdql +-----END DSA PARAMETERS----- diff --git a/main/openssl/apps/dsaparam.c b/main/openssl/apps/dsaparam.c new file mode 100644 index 00000000..fe72c1d3 --- /dev/null +++ b/main/openssl/apps/dsaparam.c @@ -0,0 +1,479 @@ +/* apps/dsaparam.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_DSA */ +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#ifndef OPENSSL_NO_DSA +#include <assert.h> +#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/dsa.h> +#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; + +static void timebomb_sigalarm(int foo) +	{ +	stop_keygen_flag = 1; +	} + +#endif + +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb); + +int MAIN(int, char **); + +int 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; +#ifndef OPENSSL_NO_ENGINE +	char *engine=NULL; +#endif +#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 +#ifdef GENCB_TEST +		else if(strcmp(*argv, "-timebomb") == 0) +			{ +			if (--argc < 1) goto bad; +			timebomb = atoi(*(++argv)); +			} +#endif +		else if (strcmp(*argv,"-text") == 0) +			text=1; +		else if (strcmp(*argv,"-C") == 0) +			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); +			need_rand=1; +			} +		else if (strcmp(*argv,"-noout") == 0) +			noout=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++; +		} + +	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; +		} + +	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; +		} + +	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); +#endif + +	if (need_rand) +		{ +		app_RAND_load_file(NULL, bio_err, (inrand != NULL)); +		if (inrand != NULL) +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n", +				app_RAND_load_files(inrand)); +		} + +	if (numbits > 0) +		{ +		BN_GENCB cb; +		BN_GENCB_set(&cb, dsa_cb, bio_err); +		assert(need_rand); +		dsa = DSA_new(); +		if(!dsa) +			{ +			BIO_printf(bio_err,"Error allocating DSA object\n"); +			goto end; +			} +		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num); +	        BIO_printf(bio_err,"This could take some time\n"); +#ifdef GENCB_TEST +		if(timebomb > 0) +	{ +		struct sigaction act; +		act.sa_handler = timebomb_sigalarm; +		act.sa_flags = 0; +		BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n", +				timebomb); +		if(sigaction(SIGALRM, &act, NULL) != 0) +			{ +			BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n"); +			goto end; +			} +		alarm(timebomb); +	} +#endif +	        if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb)) +			{ +#ifdef GENCB_TEST +			if(stop_keygen_flag) +				{ +				BIO_printf(bio_err,"DSA key generation time-stopped\n"); +				/* This is an asked-for behaviour! */ +				ret = 0; +				goto end; +				} +#endif +			BIO_printf(bio_err,"Error, DSA key generation failed\n"); +			goto end; +			} +		} +	else if	(informat == FORMAT_ASN1) +		dsa=d2i_DSAparams_bio(in,NULL); +	else if (informat == FORMAT_PEM) +		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); +		goto end; +		} + +	if (text) +		{ +		DSAparams_print(out,dsa); +		} +	 +	if (C) +		{ +		unsigned char *data; +		int l,len,bits_p; + +		len=BN_num_bytes(dsa->p); +		bits_p=BN_num_bits(dsa->p); +		data=(unsigned char *)OPENSSL_malloc(len+20); +		if (data == NULL) +			{ +			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", +			bits_p,bits_p); +		printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n", +			bits_p,bits_p); +		printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),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"); +		} + + +	if (!noout) +		{ +		if 	(outformat == FORMAT_ASN1) +			i=i2d_DSAparams_bio(out,dsa); +		else if (outformat == FORMAT_PEM) +			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); +			goto end; +			} +		} +	if (genkey) +		{ +		DSA *dsakey; + +		assert(need_rand); +		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end; +		if (!DSA_generate_key(dsakey)) goto end; +		if 	(outformat == FORMAT_ASN1) +			i=i2d_DSAPrivateKey_bio(out,dsakey); +		else if (outformat == FORMAT_PEM) +			i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL); +		else	{ +			BIO_printf(bio_err,"bad output format specified for outfile\n"); +			goto end; +			} +		DSA_free(dsakey); +		} +	if (need_rand) +		app_RAND_write_file(NULL, bio_err); +	ret=0; +end: +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (dsa != NULL) DSA_free(dsa); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static int MS_CALLBACK dsa_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(cb->arg,&c,1); +	(void)BIO_flush(cb->arg); +#ifdef LINT +	p=n; +#endif +#ifdef GENCB_TEST +	if(stop_keygen_flag) +		return 0; +#endif +	return 1; +	} +#else /* !OPENSSL_NO_DSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/ec.c b/main/openssl/apps/ec.c new file mode 100644 index 00000000..896eabc1 --- /dev/null +++ b/main/openssl/apps/ec.c @@ -0,0 +1,406 @@ +/* apps/ec.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <openssl/opensslconf.h> +#ifndef OPENSSL_NO_EC +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/pem.h> + +#undef PROG +#define PROG	ec_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 + * -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 + */ + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +{ +	int 	ret = 1; +	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(); + +	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) +			noout = 1; +		else if (strcmp(*argv, "-text") == 0) +			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) +			param_out = 1; +		else if (strcmp(*argv, "-pubin") == 0) +			pubin=1; +		else if (strcmp(*argv, "-pubout") == 0) +			pubout=1; +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) +			{ +			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, " -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(); + +#ifndef OPENSSL_NO_ENGINE +        setup_engine(bio_err, engine, 0); +#endif + +	if(!app_passwd(bio_err, passargin, passargout, &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 EC key\n"); +	if (informat == FORMAT_ASN1)  +		{ +		if (pubin)  +			eckey = d2i_EC_PUBKEY_bio(in, NULL); +		else  +			eckey = d2i_ECPrivateKey_bio(in, NULL); +		}  +	else if (informat == FORMAT_PEM)  +		{ +		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"); +		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; +			} +		} + +	group = EC_KEY_get0_group(eckey); + +	if (new_form) +		EC_KEY_set_conv_form(eckey, form); + +	if (new_asn1_flag) +		EC_KEY_set_asn1_flag(eckey, asn1_flag); + +	if (text)  +		if (!EC_KEY_print(out, eckey, 0)) +			{ +			perror(outfile); +			ERR_print_errors(bio_err); +			goto end; +			} + +	if (noout)  +		{ +		ret = 0; +		goto end; +		} + +	BIO_printf(bio_err, "writing EC key\n"); +	if (outformat == FORMAT_ASN1)  +		{ +		if (param_out) +			i = i2d_ECPKParameters_bio(out, group); +		else if (pubin || pubout)  +			i = i2d_EC_PUBKEY_bio(out, eckey); +		else  +			i = i2d_ECPrivateKey_bio(out, eckey); +		}  +	else if (outformat == FORMAT_PEM)  +		{ +		if (param_out) +			i = PEM_write_bio_ECPKParameters(out, group); +		else if (pubin || pubout) +			i = PEM_write_bio_EC_PUBKEY(out, eckey); +		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) +		{ +		BIO_printf(bio_err, "unable to write private key\n"); +		ERR_print_errors(bio_err); +		} +	else +		ret=0; +end: +	if (in) +		BIO_free(in); +	if (out) +		BIO_free_all(out); +	if (eckey) +		EC_KEY_free(eckey); +	if (passin) +		OPENSSL_free(passin); +	if (passout) +		OPENSSL_free(passout); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +} +#else /* !OPENSSL_NO_EC */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/ecparam.c b/main/openssl/apps/ecparam.c new file mode 100644 index 00000000..465480be --- /dev/null +++ b/main/openssl/apps/ecparam.c @@ -0,0 +1,731 @@ +/* apps/ecparam.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by  + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by  + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include <openssl/opensslconf.h> +#ifndef OPENSSL_NO_EC +#include <assert.h> +#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/ec.h> +#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 choosen 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) +	{ +	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; +	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) +			text = 1; +		else if (strcmp(*argv,"-C") == 0) +			C = 1; +		else if (strcmp(*argv,"-check") == 0) +			check = 1; +		else if (strcmp (*argv, "-name") == 0) +			{ +			if (--argc < 1) +				goto bad; +			curve_name = *(++argv); +			} +		else if (strcmp(*argv, "-list_curves") == 0) +			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) +			no_seed = 1; +		else if (strcmp(*argv, "-noout") == 0) +			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); +			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; +			} +		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 - " +				"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 choosen 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"); +		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; +		} + +	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); +#endif + +	if (list_curves) +		{ +		EC_builtin_curve *curves = NULL; +		size_t crv_len = 0; +		size_t n = 0; + +		crv_len = EC_get_builtin_curves(NULL, 0); + +		curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len)); + +		if (curves == NULL) +			goto end; + +		if (!EC_get_builtin_curves(curves, crv_len)) +			{ +			OPENSSL_free(curves); +			goto end; +			} + +		 +		for (n = 0; n < crv_len; n++) +			{ +			const char *comment; +			const char *sname; +			comment = curves[n].comment; +			sname   = OBJ_nid2sn(curves[n].nid); +			if (comment == NULL) +				comment = "CURVE DESCRIPTION NOT AVAILABLE"; +			if (sname == NULL) +				sname = ""; + +			BIO_printf(out, "  %-10s: ", sname); +			BIO_printf(out, "%s\n", comment); +			}  + +		OPENSSL_free(curves); +		ret = 0; +		goto end; +		} + +	if (curve_name != NULL) +		{ +		int nid; + +		/* workaround for the SECG curve names secp192r1 +		 * and secp256r1 (which are the same as the curves +		 * prime192v1 and prime256v1 defined in X9.62) +		 */ +		if (!strcmp(curve_name, "secp192r1")) +			{ +			BIO_printf(bio_err, "using curve name prime192v1 " +				"instead of secp192r1\n"); +			nid = NID_X9_62_prime192v1; +			} +		else if (!strcmp(curve_name, "secp256r1")) +			{ +			BIO_printf(bio_err, "using curve name prime256v1 " +				"instead of secp256r1\n"); +			nid = NID_X9_62_prime256v1; +			} +		else +			nid = OBJ_sn2nid(curve_name); +	 +		if (nid == 0) +			{ +			BIO_printf(bio_err, "unknown curve name (%s)\n",  +				curve_name); +			goto end; +			} + +		group = EC_GROUP_new_by_curve_name(nid); +		if (group == NULL) +			{ +			BIO_printf(bio_err, "unable to create curve (%s)\n",  +				curve_name); +			goto end; +			} +		EC_GROUP_set_asn1_flag(group, asn1_flag); +		EC_GROUP_set_point_conversion_form(group, form); +		} +	else if (informat == FORMAT_ASN1) +		{ +		group = d2i_ECPKParameters_bio(in, NULL); +		} +	else if (informat == FORMAT_PEM) +		{ +		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); +		goto end; +		} + +	if (new_form) +		EC_GROUP_set_point_conversion_form(group, form); + +	if (new_asn1_flag) +		EC_GROUP_set_asn1_flag(group, asn1_flag); + +	if (no_seed) +		{ +		EC_GROUP_set_seed(group, NULL, 0); +		} + +	if (text) +		{ +		if (!ECPKParameters_print(out, group, 0)) +			goto end; +		} + +	if (check) +		{ +		if (group == NULL) +			BIO_printf(bio_err, "no elliptic curve parameters\n"); +		BIO_printf(bio_err, "checking elliptic curve parameters: "); +		if (!EC_GROUP_check(group, NULL)) +			{ +			BIO_printf(bio_err, "failed\n"); +			ERR_print_errors(bio_err); +			} +		else +			BIO_printf(bio_err, "ok\n"); +			 +		} + +	if (C) +		{ +		size_t	buf_len = 0, tmp_len = 0; +		const EC_POINT *point; +		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 ) +			{ +			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 */ +			goto end; +			} + +		if ((point = EC_GROUP_get0_generator(group)) == NULL) +			goto end; +		if (!EC_POINT_point2bn(group, point,  +			EC_GROUP_get_point_conversion_form(group), ec_gen,  +			NULL)) +			goto end; +		if (!EC_GROUP_get_order(group, ec_order, NULL)) +			goto end; +		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) +			goto end; + +		if (!ec_p || !ec_a || !ec_b || !ec_gen ||  +			!ec_order || !ec_cofactor) +			goto end; + +		len = BN_num_bits(ec_order); + +		if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len) +			buf_len = tmp_len; +		if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len) +			buf_len = tmp_len; +		if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len) +			buf_len = tmp_len; +		if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len) +			buf_len = tmp_len; +		if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len) +			buf_len = tmp_len; +		if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len) +			buf_len = tmp_len; + +		buffer = (unsigned char *)OPENSSL_malloc(buf_len); + +		if (buffer == NULL) +			{ +			perror("OPENSSL_malloc"); +			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"); +	} + +	if (!noout) +		{ +		if (outformat == FORMAT_ASN1) +			i = i2d_ECPKParameters_bio(out, group); +		else if (outformat == FORMAT_PEM) +			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"); +			ERR_print_errors(bio_err); +			goto end; +			} +		} +	 +	if (need_rand) +		{ +		app_RAND_load_file(NULL, bio_err, (inrand != NULL)); +		if (inrand != NULL) +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n", +				app_RAND_load_files(inrand)); +		} + +	if (genkey) +		{ +		EC_KEY *eckey = EC_KEY_new(); + +		if (eckey == NULL) +			goto end; + +		assert(need_rand); + +		if (EC_KEY_set_group(eckey, group) == 0) +			goto end; +		 +		if (!EC_KEY_generate_key(eckey)) +			{ +			EC_KEY_free(eckey); +			goto end; +			} +		if (outformat == FORMAT_ASN1) +			i = i2d_ECPrivateKey_bio(out, eckey); +		else if (outformat == FORMAT_PEM) +			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); + +	ret=0; +end: +	if (ec_p) +		BN_free(ec_p); +	if (ec_a) +		BN_free(ec_a); +	if (ec_b) +		BN_free(ec_b); +	if (ec_gen) +		BN_free(ec_gen); +	if (ec_order) +		BN_free(ec_order); +	if (ec_cofactor) +		BN_free(ec_cofactor); +	if (buffer) +		OPENSSL_free(buffer); +	if (in != NULL) +		BIO_free(in); +	if (out != NULL) +		BIO_free_all(out); +	if (group != NULL) +		EC_GROUP_free(group); +	apps_shutdown(); +	OPENSSL_EXIT(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 +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/enc.c b/main/openssl/apps/enc.c new file mode 100644 index 00000000..076225c4 --- /dev/null +++ b/main/openssl/apps/enc.c @@ -0,0 +1,724 @@ +/* apps/enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/x509.h> +#include <openssl/rand.h> +#include <openssl/pem.h> +#include <openssl/comp.h> +#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 const char magic[]="Salted__"; +	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; +	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; +#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; + +	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) +		base64=1; +#ifdef ZLIB +	if (strcmp(pname,"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; +		} + +	argc--; +	argv++; +	while (argc >= 1) +		{ +		if	(strcmp(*argv,"-e") == 0) +			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) +			enc=0; +		else if	(strcmp(*argv,"-p") == 0) +			printkey=1; +		else if	(strcmp(*argv,"-v") == 0) +			verbose=1; +		else if	(strcmp(*argv,"-nopad") == 0) +			nopad=1; +		else if	(strcmp(*argv,"-salt") == 0) +			nosalt=0; +		else if	(strcmp(*argv,"-nosalt") == 0) +			nosalt=1; +		else if	(strcmp(*argv,"-debug") == 0) +			debug=1; +		else if	(strcmp(*argv,"-P") == 0) +			printkey=2; +		else if	(strcmp(*argv,"-A") == 0) +			olb64=1; +		else if	(strcmp(*argv,"-a") == 0) +			base64=1; +		else if	(strcmp(*argv,"-base64") == 0) +			base64=1; +#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; +				} +			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; +				} +			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	((argv[0][0] == '-') && +			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) +			{ +			cipher=c; +			} +		else if (strcmp(*argv,"-none") == 0) +			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; +			} +		argc--; +		argv++; +		} + +#ifndef OPENSSL_NO_ENGINE +        setup_engine(bio_err, engine, 0); +#endif + +	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) +		{ +		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); +		} + +	strbuf=OPENSSL_malloc(SIZE); +	buff=(unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize)); +	if ((buff == NULL) || (strbuf == NULL)) +		{ +		BIO_printf(bio_err,"OPENSSL_malloc failure %ld\n",(long)EVP_ENCODE_LENGTH(bsize)); +		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); +		BIO_set_callback_arg(in,(char *)bio_err); +		BIO_set_callback_arg(out,(char *)bio_err); +		} + +	if (inf == NULL) +	        { +#ifndef OPENSSL_NO_SETVBUF_IONBF +		if (bufsize != NULL) +			setvbuf(stdin, (char *)NULL, _IONBF, 0); +#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ +		BIO_set_fp(in,stdin,BIO_NOCLOSE); +	        } +	else +		{ +		if (BIO_read_filename(in,inf) <= 0) +			{ +			perror(inf); +			goto end; +			} +		} + +	if(!str && passarg) { +		if(!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { +			BIO_printf(bio_err, "Error getting password\n"); +			goto end; +		} +		str = pass; +	} + +	if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) +		{ +		for (;;) +			{ +			char buf[200]; + +			BIO_snprintf(buf,sizeof buf,"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); +			if (i == 0) +				{ +				if (strbuf[0] == '\0') +					{ +					ret=1; +					goto end; +					} +				str=strbuf; +				break; +				} +			if (i < 0) +				{ +				BIO_printf(bio_err,"bad password read\n"); +				goto end; +				} +			} +		} + + +	if (outf == NULL) +		{ +		BIO_set_fp(out,stdout,BIO_NOCLOSE); +#ifndef OPENSSL_NO_SETVBUF_IONBF +		if (bufsize != NULL) +			setvbuf(stdout, (char *)NULL, _IONBF, 0); +#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ +#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; +			} +		} + +	rbio=in; +	wbio=out; + +#ifdef ZLIB + +	if (do_zlib) +		{ +		if ((bzl=BIO_new(BIO_f_zlib())) == NULL) +			goto end; +		if (enc) +			wbio=BIO_push(bzl,wbio); +		else +			rbio=BIO_push(bzl,rbio); +		} +#endif + +	if (base64) +		{ +		if ((b64=BIO_new(BIO_f_base64())) == NULL) +			goto end; +		if (debug) +			{ +			BIO_set_callback(b64,BIO_debug_callback); +			BIO_set_callback_arg(b64,(char *)bio_err); +			} +		if (olb64) +			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL); +		if (enc) +			wbio=BIO_push(b64,wbio); +		else +			rbio=BIO_push(b64,rbio); +		} + +	if (cipher != NULL) +		{ +		/* Note that str is NULL if a key was passed on the command +		 * line, so we get no salt in that case. Is this a bug? +		 */ +		if (str != NULL) +			{ +			/* Salt handling: if encrypting generate a salt and +			 * write to output BIO. If decrypting read salt from +			 * input BIO. +			 */ +			unsigned char *sptr; +			if(nosalt) sptr = NULL; +			else { +				if(enc) { +					if(hsalt) { +						if(!set_hex(hsalt,salt,sizeof salt)) { +							BIO_printf(bio_err, +								"invalid hex salt value\n"); +							goto end; +						} +					} else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) +						goto end; +					/* If -P option then don't bother writing */ +					if((printkey != 2) +					   && (BIO_write(wbio,magic, +							 sizeof magic-1) != sizeof magic-1 +					       || BIO_write(wbio, +							    (char *)salt, +							    sizeof salt) != sizeof salt)) { +						BIO_printf(bio_err,"error writing output file\n"); +						goto end; +					} +				} else if(BIO_read(rbio,mbuf,sizeof mbuf) != sizeof mbuf +					  || BIO_read(rbio, +						      (unsigned char *)salt, +				    sizeof salt) != sizeof salt) { +					BIO_printf(bio_err,"error reading input file\n"); +					goto end; +				} else if(memcmp(mbuf,magic,sizeof magic-1)) { +				    BIO_printf(bio_err,"bad magic number\n"); +				    goto end; +				} + +				sptr = salt; +			} + +			EVP_BytesToKey(cipher,dgst,sptr, +				(unsigned char *)str, +				strlen(str),1,key,iv); +			/* zero the complete buffer or the string +			 * passed from the command line +			 * bug picked up by +			 * Larry J. Hughes Jr. <hughes@indiana.edu> */ +			if (str == strbuf) +				OPENSSL_cleanse(str,SIZE); +			else +				OPENSSL_cleanse(str,strlen(str)); +			} +		if ((hiv != NULL) && !set_hex(hiv,iv,sizeof iv)) +			{ +			BIO_printf(bio_err,"invalid hex iv value\n"); +			goto end; +			} +		if ((hiv == NULL) && (str == NULL) +		    && EVP_CIPHER_iv_length(cipher) != 0) +			{ +			/* No IV was explicitly set and no IV was generated +			 * during EVP_BytesToKey. Hence the IV is undefined, +			 * making correct decryption impossible. */ +			BIO_printf(bio_err, "iv undefined\n"); +			goto end; +			} +		if ((hkey != NULL) && !set_hex(hkey,key,sizeof key)) +			{ +			BIO_printf(bio_err,"invalid hex key value\n"); +			goto end; +			} + +		if ((benc=BIO_new(BIO_f_cipher())) == NULL) +			goto end; + +		/* Since we may be changing parameters work on the encryption +		 * context rather than calling BIO_set_cipher(). +		 */ + +		BIO_get_cipher_ctx(benc, &ctx); +		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) +			{ +			BIO_printf(bio_err, "Error setting cipher %s\n", +				EVP_CIPHER_name(cipher)); +			ERR_print_errors(bio_err); +			goto end; +			} + +		if (nopad) +			EVP_CIPHER_CTX_set_padding(ctx, 0); + +		if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) +			{ +			BIO_printf(bio_err, "Error setting cipher %s\n", +				EVP_CIPHER_name(cipher)); +			ERR_print_errors(bio_err); +			goto end; +			} + +		if (debug) +			{ +			BIO_set_callback(benc,BIO_debug_callback); +			BIO_set_callback_arg(benc,(char *)bio_err); +			} + +		if (printkey) +			{ +			if (!nosalt) +				{ +				printf("salt="); +				for (i=0; i<(int)sizeof(salt); i++) +					printf("%02X",salt[i]); +				printf("\n"); +				} +			if (cipher->key_len > 0) +				{ +				printf("key="); +				for (i=0; i<cipher->key_len; i++) +					printf("%02X",key[i]); +				printf("\n"); +				} +			if (cipher->iv_len > 0) +				{ +				printf("iv ="); +				for (i=0; i<cipher->iv_len; i++) +					printf("%02X",iv[i]); +				printf("\n"); +				} +			if (printkey == 2) +				{ +				ret=0; +				goto end; +				} +			} +		} + +	/* Only encrypt/decrypt as we write the file */ +	if (benc != NULL) +		wbio=BIO_push(benc,wbio); + +	for (;;) +		{ +		inl=BIO_read(rbio,(char *)buff,bsize); +		if (inl <= 0) break; +		if (BIO_write(wbio,(char *)buff,inl) != inl) +			{ +			BIO_printf(bio_err,"error writing output file\n"); +			goto end; +			} +		} +	if (!BIO_flush(wbio)) +		{ +		BIO_printf(bio_err,"bad decrypt\n"); +		goto end; +		} + +	ret=0; +	if (verbose) +		{ +		BIO_printf(bio_err,"bytes read   :%8ld\n",BIO_number_read(in)); +		BIO_printf(bio_err,"bytes written:%8ld\n",BIO_number_written(out)); +		} +end: +	ERR_print_errors(bio_err); +	if (strbuf != NULL) OPENSSL_free(strbuf); +	if (buff != NULL) OPENSSL_free(buff); +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (benc != NULL) BIO_free(benc); +	if (b64 != NULL) BIO_free(b64); +#ifdef ZLIB +	if (bzl != NULL) BIO_free(bzl); +#endif +	if(pass) OPENSSL_free(pass); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +int set_hex(char *in, unsigned char *out, int size) +	{ +	int i,n; +	unsigned char j; + +	n=strlen(in); +	if (n > (size*2)) +		{ +		BIO_printf(bio_err,"hex string is too long\n"); +		return(0); +		} +	memset(out,0,size); +	for (i=0; i<n; i++) +		{ +		j=(unsigned char)*in; +		*(in++)='\0'; +		if (j == 0) break; +		if ((j >= '0') && (j <= '9')) +			j-='0'; +		else if ((j >= 'A') && (j <= 'F')) +			j=j-'A'+10; +		else if ((j >= 'a') && (j <= 'f')) +			j=j-'a'+10; +		else +			{ +			BIO_printf(bio_err,"non-hex digit\n"); +			return(0); +			} +		if (i&1) +			out[i/2]|=j; +		else +			out[i/2]=(j<<4); +		} +	return(1); +	} diff --git a/main/openssl/apps/engine.c b/main/openssl/apps/engine.c new file mode 100644 index 00000000..9a029439 --- /dev/null +++ b/main/openssl/apps/engine.c @@ -0,0 +1,549 @@ +/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */ +/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include "apps.h" +#include <openssl/err.h> +#ifndef OPENSSL_NO_ENGINE +#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 +}; + +static void identity(char *ptr) +	{ +	return; +	} + +static int append_buf(char **buf, const char *s, int *size, int step) +	{ +	int l = strlen(s); + +	if (*buf == NULL) +		{ +		*size = step; +		*buf = OPENSSL_malloc(*size); +		if (*buf == NULL) +			return 0; +		**buf = '\0'; +		} + +	if (**buf != '\0') +		l += 2;		/* ", " */ + +	if (strlen(*buf) + strlen(s) >= (unsigned int)*size) +		{ +		*size += step; +		*buf = OPENSSL_realloc(*buf, *size); +		} + +	if (*buf == NULL) +		return 0; + +	if (**buf != '\0') +		BUF_strlcat(*buf, ", ", *size); +	BUF_strlcat(*buf, s, *size); + +	return 1; +	} + +static int util_flags(BIO *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); +	if(flags == 0) +		{ +		BIO_printf(bio_out, "<no flags>\n"); +		return 1; +		} +        /* If the object is internal, mark it in a way that shows instead of +         * having it part of all the other flags, even if it really is. */ +	if(flags & ENGINE_CMD_FLAG_INTERNAL) +		{ +		BIO_printf(bio_out, "[Internal] "); +		} + +	if(flags & ENGINE_CMD_FLAG_NUMERIC) +		{ +		BIO_printf(bio_out, "NUMERIC"); +		started = 1; +		} +	/* Now we check that no combinations of the mutually exclusive NUMERIC, +	 * STRING, and NO_INPUT flags have been used. Future flags that can be +	 * OR'd together with these would need to added after these to preserve +	 * the testing logic. */ +	if(flags & ENGINE_CMD_FLAG_STRING) +		{ +		if(started) +			{ +			BIO_printf(bio_out, "|"); +			err = 1; +			} +		BIO_printf(bio_out, "STRING"); +		started = 1; +		} +	if(flags & ENGINE_CMD_FLAG_NO_INPUT) +		{ +		if(started) +			{ +			BIO_printf(bio_out, "|"); +			err = 1; +			} +		BIO_printf(bio_out, "NO_INPUT"); +		started = 1; +		} +	/* Check for unknown flags */ +	flags = flags & ~ENGINE_CMD_FLAG_NUMERIC & +			~ENGINE_CMD_FLAG_STRING & +			~ENGINE_CMD_FLAG_NO_INPUT & +			~ENGINE_CMD_FLAG_INTERNAL; +	if(flags) +		{ +		if(started) BIO_printf(bio_out, "|"); +		BIO_printf(bio_out, "<0x%04X>", flags); +		} +	if(err) +		BIO_printf(bio_out, "  <illegal flags!>"); +	BIO_printf(bio_out, "\n"); +	return 1; +	} + +static int util_verbose(ENGINE *e, int verbose, BIO *bio_out, const char *indent) +	{ +	static const int line_wrap = 78; +	int num; +	int ret = 0; +	char *name = NULL; +	char *desc = NULL; +	int flags; +	int xpos = 0; +	STACK_OF(OPENSSL_STRING) *cmds = NULL; +	if(!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) || +			((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE, +					0, NULL, NULL)) <= 0)) +		{ +#if 0 +		BIO_printf(bio_out, "%s<no control commands>\n", indent); +#endif +		return 1; +		} + +	cmds = sk_OPENSSL_STRING_new_null(); + +	if(!cmds) +		goto err; +	do { +		int len; +		/* Get the command input flags */ +		if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, +					NULL, NULL)) < 0) +			goto err; +                if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) +                        { +                        /* Get the command name */ +                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num, +                                NULL, NULL)) <= 0) +                                goto err; +                        if((name = OPENSSL_malloc(len + 1)) == NULL) +                                goto err; +                        if(ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name, +                                NULL) <= 0) +                                goto err; +                        /* Get the command description */ +                        if((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num, +                                NULL, NULL)) < 0) +                                goto err; +                        if(len > 0) +                                { +                                if((desc = OPENSSL_malloc(len + 1)) == NULL) +                                        goto err; +                                if(ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc, +                                        NULL) <= 0) +                                        goto err; +                                } +                        /* Now decide on the output */ +                        if(xpos == 0) +                                /* Do an indent */ +                                xpos = BIO_puts(bio_out, indent); +                        else +                                /* Otherwise prepend a ", " */ +                                xpos += BIO_printf(bio_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); +                                        } +                                xpos += BIO_printf(bio_out, "%s", name); +                                } +                        else +                                { +                                /* We're listing names plus descriptions */ +                                BIO_printf(bio_out, "%s: %s\n", name, +                                        (desc == NULL) ? "<no description>" : desc); +                                /* ... and sometimes input flags */ +                                if((verbose >= 3) && !util_flags(bio_out, flags, +                                        indent)) +                                        goto err; +                                xpos = 0; +                                } +                        } +		OPENSSL_free(name); name = NULL; +		if(desc) { OPENSSL_free(desc); desc = NULL; } +		/* Move to the next command */ +		num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, +					num, NULL, NULL); +		} while(num > 0); +	if(xpos > 0) +		BIO_printf(bio_out, "\n"); +	ret = 1; +err: +	if(cmds) sk_OPENSSL_STRING_pop_free(cmds, identity); +	if(name) OPENSSL_free(name); +	if(desc) OPENSSL_free(desc); +	return ret; +	} + +static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, +			BIO *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"); +		return; +		} +	for(loop = 0; loop < num; loop++) +		{ +		char buf[256]; +		const char *cmd, *arg; +		cmd = sk_OPENSSL_STRING_value(cmds, loop); +		res = 1; /* assume success */ +		/* Check if this command has no ":arg" */ +		if((arg = strstr(cmd, ":")) == NULL) +			{ +			if(!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0)) +				res = 0; +			} +		else +			{ +			if((int)(arg - cmd) > 254) +				{ +				BIO_printf(bio_out,"[Error]: command name too long\n"); +				return; +				} +			memcpy(buf, cmd, (int)(arg - cmd)); +			buf[arg-cmd] = '\0'; +			arg++; /* Move past the ":" */ +			/* Call the command with the argument */ +			if(!ENGINE_ctrl_cmd_string(e, buf, arg, 0)) +				res = 0; +			} +		if(res) +			BIO_printf(bio_out, "[Success]: %s\n", cmd); +		else +			{ +			BIO_printf(bio_out, "[Failure]: %s\n", cmd); +			ERR_print_errors(bio_out); +			} +		} +	} + +int MAIN(int, char **); + +int 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; +	const char *indent = "     "; + +	apps_startup(); +	SSL_load_error_strings(); + +	if (bio_err == NULL) +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); + +	if (!load_config(bio_err, NULL)) +		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) +			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; +		} + +	if (sk_OPENSSL_STRING_num(engines) == 0) +		{ +		for(e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) +			{ +			sk_OPENSSL_STRING_push(engines,(char *)ENGINE_get_id(e)); +			} +		} + +	for (i=0; i<sk_OPENSSL_STRING_num(engines); i++) +		{ +		const char *id = sk_OPENSSL_STRING_value(engines,i); +		if ((e = ENGINE_by_id(id)) != NULL) +			{ +			const char *name = ENGINE_get_name(e); +			/* 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); +			if (strcmp(ENGINE_get_id(e), id) != 0) +				{ +				BIO_printf(bio_out, "Loaded: (%s) %s\n", +					ENGINE_get_id(e), ENGINE_get_name(e)); +				} +			if (list_cap) +				{ +				int cap_size = 256; +				char *cap_buf = NULL; +				int k,n; +				const int *nids; +				ENGINE_CIPHERS_PTR fn_c; +				ENGINE_DIGESTS_PTR fn_d; +				ENGINE_PKEY_METHS_PTR fn_pk; + +				if (ENGINE_get_RSA(e) != NULL +					&& !append_buf(&cap_buf, "RSA", +						&cap_size, 256)) +					goto end; +				if (ENGINE_get_DSA(e) != NULL +					&& !append_buf(&cap_buf, "DSA", +						&cap_size, 256)) +					goto end; +				if (ENGINE_get_DH(e) != NULL +					&& !append_buf(&cap_buf, "DH", +						&cap_size, 256)) +					goto end; +				if (ENGINE_get_RAND(e) != NULL +					&& !append_buf(&cap_buf, "RAND", +						&cap_size, 256)) +					goto end; + +				fn_c = ENGINE_get_ciphers(e); +				if(!fn_c) goto skip_ciphers; +				n = fn_c(e, NULL, &nids, 0); +				for(k=0 ; k < n ; ++k) +					if(!append_buf(&cap_buf, +						       OBJ_nid2sn(nids[k]), +						       &cap_size, 256)) +						goto end; + +skip_ciphers: +				fn_d = ENGINE_get_digests(e); +				if(!fn_d) goto skip_digests; +				n = fn_d(e, NULL, &nids, 0); +				for(k=0 ; k < n ; ++k) +					if(!append_buf(&cap_buf, +						       OBJ_nid2sn(nids[k]), +						       &cap_size, 256)) +						goto end; + +skip_digests: +				fn_pk = ENGINE_get_pkey_meths(e); +				if(!fn_pk) goto skip_pmeths; +				n = fn_pk(e, NULL, &nids, 0); +				for(k=0 ; k < n ; ++k) +					if(!append_buf(&cap_buf, +						       OBJ_nid2sn(nids[k]), +						       &cap_size, 256)) +						goto end; +skip_pmeths: +				if (cap_buf && (*cap_buf != '\0')) +					BIO_printf(bio_out, " [%s]\n", cap_buf); + +				OPENSSL_free(cap_buf); +				} +			if(test_avail) +				{ +				BIO_printf(bio_out, "%s", indent); +				if (ENGINE_init(e)) +					{ +					BIO_printf(bio_out, "[ available ]\n"); +					util_do_cmds(e, post_cmds, bio_out, indent); +					ENGINE_finish(e); +					} +				else +					{ +					BIO_printf(bio_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)) +				goto end; +			ENGINE_free(e); +			} +		else +			ERR_print_errors(bio_err); +		} + +	ret=0; +end: + +	ERR_print_errors(bio_err); +	sk_OPENSSL_STRING_pop_free(engines, identity); +	sk_OPENSSL_STRING_pop_free(pre_cmds, identity); +	sk_OPENSSL_STRING_pop_free(post_cmds, identity); +	if (bio_out != NULL) BIO_free_all(bio_out); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} +#else + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/errstr.c b/main/openssl/apps/errstr.c new file mode 100644 index 00000000..fe3b9807 --- /dev/null +++ b/main/openssl/apps/errstr.c @@ -0,0 +1,128 @@ +/* apps/errstr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/lhash.h> +#include <openssl/err.h> +#include <openssl/ssl.h> + +#undef PROG +#define PROG	errstr_main + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	int i,ret=0; +	char buf[256]; +	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); +			lh_ERR_STRING_DATA_node_usage_stats_bio( +						    ERR_get_string_table(),out); +			} +		if (out != NULL) BIO_free_all(out); +		argc--; +		argv++; +		} + +	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++; +			} +		} +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} diff --git a/main/openssl/apps/gendh.c b/main/openssl/apps/gendh.c new file mode 100644 index 00000000..4ec776ba --- /dev/null +++ b/main/openssl/apps/gendh.c @@ -0,0 +1,241 @@ +/* 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> +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#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	512 +#undef PROG +#define PROG gendh_main + +static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb); + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	BN_GENCB cb; +	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(); + +	BN_GENCB_set(&cb, dh_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 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); +	if (out != NULL) BIO_free_all(out); +	if (dh != NULL) DH_free(dh); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static int MS_CALLBACK 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(cb->arg,&c,1); +	(void)BIO_flush(cb->arg); +#ifdef LINT +	p=n; +#endif +	return 1; +	} +#else /* !OPENSSL_NO_DH */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/gendsa.c b/main/openssl/apps/gendsa.c new file mode 100644 index 00000000..62ea9779 --- /dev/null +++ b/main/openssl/apps/gendsa.c @@ -0,0 +1,285 @@ +/* apps/gendsa.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_DSA */ +#ifndef OPENSSL_NO_DSA +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/x509.h> +#include <openssl/pem.h> + +#define DEFBITS	512 +#undef PROG +#define PROG gendsa_main + +int MAIN(int, char **); + +int 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; +	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; + +	argv++; +	argc--; +	for (;;) +		{ +		if (argc <= 0) 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--; +		} + +	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); +#endif + +	if(!app_passwd(bio_err, NULL, passargout, 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; +		} + +	if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL) +		{ +		BIO_printf(bio_err,"unable to load DSA parameter file\n"); +		goto end; +		} +	BIO_free(in); +	in = NULL; +		 +	out=BIO_new(BIO_s_file()); +	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 (!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 DSA key, %d bits\n", +							BN_num_bits(dsa->p)); +	if (!DSA_generate_key(dsa)) goto end; + +	app_RAND_write_file(NULL, bio_err); + +	if (!PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL, passout)) +		goto end; +	ret=0; +end: +	if (ret != 0) +		ERR_print_errors(bio_err); +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	if (dsa != NULL) DSA_free(dsa); +	if(passout) OPENSSL_free(passout); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} +#else /* !OPENSSL_NO_DSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/genpkey.c b/main/openssl/apps/genpkey.c new file mode 100644 index 00000000..6dfda08b --- /dev/null +++ b/main/openssl/apps/genpkey.c @@ -0,0 +1,440 @@ +/* apps/genpkey.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif + +static int init_keygen_file(BIO *err, 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 **); + +int 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; +	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); +			} +#ifndef OPENSSL_NO_ENGINE +		else if (strcmp(*args,"-engine") == 0) +			{ +			if (!args[1]) +				goto bad; +        		e = setup_engine(bio_err, *(++args), 0); +			} +#endif +		else if (!strcmp (*args, "-paramfile")) +			{ +			if (!args[1]) +				goto bad; +			args++; +			if (do_param == 1) +				goto bad; +			if (!init_keygen_file(bio_err, &ctx, *args, 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)) +				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"); +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		else if (strcmp(*args,"-genparam") == 0) +			{ +			if (ctx) +				goto bad; +			do_param = 1; +			} +		else if (strcmp(*args,"-text") == 0) +			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; +			} +		args++; +		} + +	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 (!app_passwd(bio_err, 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 +		} + +	EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); +	EVP_PKEY_CTX_set_app_data(ctx, bio_err); + +	if (do_param) +		{ +		if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) +			{ +			BIO_puts(bio_err, "Error generating parameters\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		} +	else +		{ +		if (EVP_PKEY_keygen(ctx, &pkey) <= 0) +			{ +			BIO_puts(bio_err, "Error generating key\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (do_param) +		rv = PEM_write_bio_Parameters(out, pkey); +	else if (outformat == FORMAT_PEM)  +		rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, +								NULL, pass); +	else if (outformat == FORMAT_ASN1) +		rv = i2d_PrivateKey_bio(out, pkey); +	else +		{ +		BIO_printf(bio_err, "Bad format specified for key\n"); +		goto end; +		} + +	if (rv <= 0) +		{ +		BIO_puts(bio_err, "Error writing key\n"); +		ERR_print_errors(bio_err); +		} + +	if (text) +		{ +		if (do_param) +			rv = EVP_PKEY_print_params(out, pkey, 0, NULL); +		else +			rv = EVP_PKEY_print_private(out, pkey, 0, NULL); + +		if (rv <= 0) +			{ +			BIO_puts(bio_err, "Error printing key\n"); +			ERR_print_errors(bio_err); +			} +		} + +	ret = 0; + +	end: +	if (pkey) +		EVP_PKEY_free(pkey); +	if (ctx) +		EVP_PKEY_CTX_free(ctx); +	if (out) +		BIO_free_all(out); +	BIO_free(in); +	if (pass) +		OPENSSL_free(pass); + +	return ret; +	} + +static int init_keygen_file(BIO *err, 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"); +		return 0; +		} + +	pbio = BIO_new_file(file, "r"); +	if (!pbio) +		{ +		BIO_printf(err, "Can't open parameter file %s\n", file); +		return 0; +		} + +	pkey = PEM_read_bio_Parameters(pbio, NULL); +	BIO_free(pbio); + +	if (!pkey) +		{ +		BIO_printf(bio_err, "Error reading parameter file %s\n", file); +		return 0; +		} + +	ctx = EVP_PKEY_CTX_new(pkey, e); +	if (!ctx) +		goto err; +	if (EVP_PKEY_keygen_init(ctx) <= 0) +		goto err; +	EVP_PKEY_free(pkey); +	*pctx = ctx; +	return 1; + +	err: +	BIO_puts(err, "Error initializing context\n"); +	ERR_print_errors(err); +	if (ctx) +		EVP_PKEY_CTX_free(ctx); +	if (pkey) +		EVP_PKEY_free(pkey); +	return 0; + +	} + +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, +			const char *algname, ENGINE *e, int do_param) +	{ +	EVP_PKEY_CTX *ctx = NULL; +	const EVP_PKEY_ASN1_METHOD *ameth; +	ENGINE *tmpeng = NULL; +	int pkey_id; + +	if (*pctx) +		{ +		BIO_puts(err, "Algorithm already set!\n"); +		return 0; +		} + +	ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); + +#ifndef OPENSSL_NO_ENGINE +	if (!ameth && e) +		ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); +#endif + +	if (!ameth) +		{ +		BIO_printf(bio_err, "Algorithm %s not found\n", algname); +		return 0; +		} + +	ERR_clear_error(); + +	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); +#ifndef OPENSSL_NO_ENGINE +	if (tmpeng) +		ENGINE_finish(tmpeng); +#endif +	ctx = EVP_PKEY_CTX_new_id(pkey_id, e); + +	if (!ctx) +		goto err; +	if (do_param) +		{ +		if (EVP_PKEY_paramgen_init(ctx) <= 0) +			goto err; +		} +	else +		{ +		if (EVP_PKEY_keygen_init(ctx) <= 0) +			goto err; +		} + +	*pctx = ctx; +	return 1; + +	err: +	BIO_printf(err, "Error initializing %s context\n", algname); +	ERR_print_errors(err); +	if (ctx) +		EVP_PKEY_CTX_free(ctx); +	return 0; + +	} + +static int genpkey_cb(EVP_PKEY_CTX *ctx) +	{ +	char c='*'; +	BIO *b = EVP_PKEY_CTX_get_app_data(ctx); +	int p; +	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); +	if (p == 0) c='.'; +	if (p == 1) c='+'; +	if (p == 2) c='*'; +	if (p == 3) c='\n'; +	BIO_write(b,&c,1); +	(void)BIO_flush(b); +#ifdef LINT +	p=n; +#endif +	return 1; +	} diff --git a/main/openssl/apps/genrsa.c b/main/openssl/apps/genrsa.c new file mode 100644 index 00000000..37e93109 --- /dev/null +++ b/main/openssl/apps/genrsa.c @@ -0,0 +1,335 @@ +/* apps/genrsa.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> +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#ifndef OPENSSL_NO_RSA +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/rand.h> + +#define DEFBITS	512 +#undef PROG +#define PROG genrsa_main + +static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb); + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	BN_GENCB cb; +#ifndef OPENSSL_NO_ENGINE +	ENGINE *e = NULL; +#endif +	int ret=1; +	int i,num=DEFBITS; +	long l; +	const EVP_CIPHER *enc=NULL; +	unsigned long f4=RSA_F4; +	char *outfile=NULL; +	char *passargout = NULL, *passout = NULL; +#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; + +	apps_startup(); +	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) +			f4=3; +		else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0) +			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 +			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; +		} +		 +	ERR_load_crypto_strings(); + +	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) { +		BIO_printf(bio_err, "Error getting password\n"); +		goto err; +	} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, 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; +			} +		} + +	if (!app_RAND_load_file(NULL, bio_err, 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)); + +	BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n", +		num); +#ifdef OPENSSL_NO_ENGINE +	rsa = RSA_new(); +#else +	rsa = RSA_new_method(e); +#endif +	if (!rsa) +		goto err; + +	if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) +		goto err; +		 +	app_RAND_write_file(NULL, bio_err); + +	/* We need to do the following for when the base number size is < +	 * long, esp windows 3.1 :-(. */ +	l=0L; +	for (i=0; i<rsa->e->top; i++) +		{ +#ifndef SIXTY_FOUR_BIT +		l<<=BN_BITS4; +		l<<=BN_BITS4; +#endif +		l+=rsa->e->d[i]; +		} +	BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l); +	{ +	PW_CB_DATA cb_data; +	cb_data.password = passout; +	cb_data.prompt_info = outfile; +	if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0, +		(pem_password_cb *)password_callback,&cb_data)) +		goto err; +	} + +	ret=0; +err: +	if (bn) BN_free(bn); +	if (rsa) RSA_free(rsa); +	if (out) BIO_free_all(out); +	if(passout) OPENSSL_free(passout); +	if (ret != 0) +		ERR_print_errors(bio_err); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static int MS_CALLBACK genrsa_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(cb->arg,&c,1); +	(void)BIO_flush(cb->arg); +#ifdef LINT +	p=n; +#endif +	return 1; +	} +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/md4.c b/main/openssl/apps/md4.c new file mode 100644 index 00000000..141415ad --- /dev/null +++ b/main/openssl/apps/md4.c @@ -0,0 +1,127 @@ +/* crypto/md4/md4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/md4.h> + +#define BUFSIZE	1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#if !defined(_OSD_POSIX) && !defined(__DJGPP__) +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) +	{ +	int i,err=0; +	FILE *IN; + +	if (argc == 1) +		{ +		do_fp(stdin); +		} +	else +		{ +		for (i=1; i<argc; i++) +			{ +			IN=fopen(argv[i],"r"); +			if (IN == NULL) +				{ +				perror(argv[i]); +				err++; +				continue; +				} +			printf("MD4(%s)= ",argv[i]); +			do_fp(IN); +			fclose(IN); +			} +		} +	exit(err); +	} + +void do_fp(FILE *f) +	{ +	MD4_CTX c; +	unsigned char md[MD4_DIGEST_LENGTH]; +	int fd; +	int i; +	static unsigned char buf[BUFSIZE]; + +	fd=fileno(f); +	MD4_Init(&c); +	for (;;) +		{ +		i=read(fd,buf,sizeof buf); +		if (i <= 0) break; +		MD4_Update(&c,buf,(unsigned long)i); +		} +	MD4_Final(&(md[0]),&c); +	pt(md); +	} + +void pt(unsigned char *md) +	{ +	int i; + +	for (i=0; i<MD4_DIGEST_LENGTH; i++) +		printf("%02x",md[i]); +	printf("\n"); +	} + diff --git a/main/openssl/apps/nseq.c b/main/openssl/apps/nseq.c new file mode 100644 index 00000000..e3c4dba5 --- /dev/null +++ b/main/openssl/apps/nseq.c @@ -0,0 +1,167 @@ +/* nseq.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/pem.h> +#include <openssl/err.h> + +#undef PROG +#define PROG nseq_main + +int MAIN(int, char **); + +int 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); +	} + +	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 +	} +	if (toseq) { +		seq = NETSCAPE_CERT_SEQUENCE_new(); +		seq->certs = sk_X509_new_null(); +		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); +			ERR_print_errors(bio_err); +			goto end; +		} +		PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); +		ret = 0; +		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); +		ERR_print_errors(bio_err); +		goto end; +	} + +	for(i = 0; i < sk_X509_num(seq->certs); i++) { +		x509 = sk_X509_value(seq->certs, i); +		dump_cert_text(out, x509); +		PEM_write_bio_X509(out, x509); +	} +	ret = 0; +end: +	BIO_free(in); +	BIO_free_all(out); +	NETSCAPE_CERT_SEQUENCE_free(seq); + +	OPENSSL_EXIT(ret); +} + diff --git a/main/openssl/apps/ocsp.c b/main/openssl/apps/ocsp.c new file mode 100644 index 00000000..01847dfa --- /dev/null +++ b/main/openssl/apps/ocsp.c @@ -0,0 +1,1421 @@ +/* ocsp.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_OCSP + +#ifdef OPENSSL_SYS_VMS +#define _XOPEN_SOURCE_EXTENDED	/* So fd_set and friends get properly defined +				   on OpenVMS */ +#endif + +#define USE_SOCKETS + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "apps.h" /* needs to be included before the openssl headers! */ +#include <openssl/e_os2.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/ssl.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/x509v3.h> + +#if defined(NETWARE_CLIB) +#  ifdef NETWARE_BSDSOCK +#    include <sys/socket.h> +#    include <sys/bsdskt.h> +#  else +#    include <novsock2.h> +#  endif +#elif defined(NETWARE_LIBC) +#  ifdef NETWARE_BSDSOCK +#    include <sys/select.h> +#  else +#    include <novsock2.h> +#  endif +#endif +   +/* Maximum leeway in validity period: default 5 minutes */ +#define MAX_VALIDITY_PERIOD	(5 * 60) + +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, +				STACK_OF(OCSP_CERTID) *ids); +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, +			      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, CA_DB *db, +			X509 *ca, X509 *rcert, EVP_PKEY *rkey, +			STACK_OF(X509) *rother, unsigned long flags, +			int nmin, int ndays); + +static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); +static BIO *init_responder(char *port); +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); +static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, +				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) +	{ +	ENGINE *e = NULL; +	char **args; +	char *host = NULL, *port = NULL, *path = "/"; +	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; +	OCSP_REQUEST *req = NULL; +	OCSP_RESPONSE *resp = NULL; +	OCSP_BASICRESP *bs = NULL; +	X509 *issuer = NULL, *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; +	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; +	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; +	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; +	int ret = 1; +	int accept_count = -1; +	int badarg = 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; + +	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(); +	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 (args[1]) +				{ +				args++; +				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) +					{ +					BIO_printf(bio_err, "Error parsing URL\n"); +					badarg = 1; +					} +				} +			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")) +			ignore_err = 1; +		else if (!strcmp(*args, "-noverify")) +			noverify = 1; +		else if (!strcmp(*args, "-nonce")) +			add_nonce = 2; +		else if (!strcmp(*args, "-no_nonce")) +			add_nonce = 0; +		else if (!strcmp(*args, "-resp_no_certs")) +			rflags |= OCSP_NOCERTS; +		else if (!strcmp(*args, "-resp_key_id")) +			rflags |= OCSP_RESPID_KEY; +		else if (!strcmp(*args, "-no_certs")) +			sign_flags |= OCSP_NOCERTS; +		else if (!strcmp(*args, "-no_signature_verify")) +			verify_flags |= OCSP_NOSIGS; +		else if (!strcmp(*args, "-no_cert_verify")) +			verify_flags |= OCSP_NOVERIFY; +		else if (!strcmp(*args, "-no_chain")) +			verify_flags |= OCSP_NOCHAIN; +		else if (!strcmp(*args, "-no_cert_checks")) +			verify_flags |= OCSP_NOCHECKS; +		else if (!strcmp(*args, "-no_explicit")) +			verify_flags |= OCSP_NOEXPLICIT; +		else if (!strcmp(*args, "-trust_other")) +			verify_flags |= OCSP_TRUSTOTHER; +		else if (!strcmp(*args, "-no_intern")) +			verify_flags |= OCSP_NOINTERN; +		else if (!strcmp(*args, "-text")) +			{ +			req_text = 1; +			resp_text = 1; +			} +		else if (!strcmp(*args, "-req_text")) +			req_text = 1; +		else if (!strcmp(*args, "-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 (!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; +					} +				} +				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 ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL) +			{ +			badarg = 1; +			} +		args++; +		} + +	/* 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, "-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"); +		goto end; +		} + +	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"); +		goto end; +		} + +	if (!req && (add_nonce != 2)) add_nonce = 0; + +	if (!req && reqin) +		{ +		derbio = BIO_new_file(reqin, "rb"); +		if (!derbio) +			{ +			BIO_printf(bio_err, "Error Opening OCSP request file\n"); +			goto end; +			} +		req = d2i_OCSP_REQUEST_bio(derbio, NULL); +		BIO_free(derbio); +		if(!req) +			{ +			BIO_printf(bio_err, "Error reading OCSP request\n"); +			goto end; +			} +		} + +	if (!req && port) +		{ +		acbio = init_responder(port); +		if (!acbio) +			goto end; +		} + +	if (rsignfile && !rdb) +		{ +		if (!rkeyfile) rkeyfile = rsignfile; +		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM, +			NULL, e, "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"); +		if (rcertfile) +			{ +			rother = load_certs(bio_err, rcertfile, FORMAT_PEM, +				NULL, e, "responder other certificates"); +			if (!rother) goto end; +			} +		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL, +			"responder private key"); +		if (!rkey) +			goto end; +		} +	if(acbio) +		BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); + +	redo_accept: + +	if (acbio) +		{ +		if (!do_responder(&req, &cbio, acbio, port)) +			goto end; +		if (!req) +			{ +			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); +			send_ocsp_response(cbio, resp); +			goto done_resp; +			} +		} + +	if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) +		{ +		BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); +		goto end; +		} + +	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); + +	if (signfile) +		{ +		if (!keyfile) keyfile = signfile; +		signer = load_cert(bio_err, signfile, FORMAT_PEM, +			NULL, e, "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"); +			if (!sign_other) goto end; +			} +		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL, +			"signer private key"); +		if (!key) +			goto end; + +		if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags)) +			{ +			BIO_printf(bio_err, "Error signing OCSP request\n"); +			goto end; +			} +		} + +	if (req_text && req) OCSP_REQUEST_print(out, req, 0); + +	if (reqout) +		{ +		derbio = BIO_new_file(reqout, "wb"); +		if(!derbio) +			{ +			BIO_printf(bio_err, "Error opening file %s\n", reqout); +			goto end; +			} +		i2d_OCSP_REQUEST_bio(derbio, req); +		BIO_free(derbio); +		} + +	if (ridx_filename && (!rkey || !rsigner || !rca_cert)) +		{ +		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); +		goto end; +		} + +	if (ridx_filename && !rdb) +		{ +		rdb = load_index(ridx_filename, NULL); +		if (!rdb) goto end; +		if (!index_index(rdb)) goto end; +		} + +	if (rdb) +		{ +		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); +		if (cbio) +			send_ocsp_response(cbio, resp); +		} +	else if (host) +		{ +#ifndef OPENSSL_NO_SOCK +		resp = process_responder(bio_err, req, host, path, +					port, use_ssl, headers, req_timeout); +		if (!resp) +			goto end; +#else +		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); +		goto end; +#endif +		} +	else if (respin) +		{ +		derbio = BIO_new_file(respin, "rb"); +		if (!derbio) +			{ +			BIO_printf(bio_err, "Error Opening OCSP response file\n"); +			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; +		} + +	done_resp: + +	if (respout) +		{ +		derbio = BIO_new_file(respout, "wb"); +		if(!derbio) +			{ +			BIO_printf(bio_err, "Error opening file %s\n", respout); +			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); +		if (ignore_err) +			goto redo_accept; +		ret = 0; +		goto end; +		} + +	if (resp_text) OCSP_RESPONSE_print(out, resp, 0); + +	/* 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; +			} +		goto end; +		} + +	if (!store) +		store = setup_verify(bio_err, CAfile, CApath); +	if (!store) +		goto end; +	if (verify_certfile) +		{ +		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, +			NULL, e, "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; +		} + +	if (!noverify) +		{ +		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) +			{ +			if (i == -1) +				BIO_printf(bio_err, "WARNING: no nonce in response\n"); +			else +				{ +				BIO_printf(bio_err, "Nonce Verify error\n"); +				goto end; +				} +			} + +		i = OCSP_basic_verify(bs, verify_other, store, verify_flags); +                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); + +		if(i <= 0) +			{ +			BIO_printf(bio_err, "Response Verify Failure\n"); +			ERR_print_errors(bio_err); +			} +		else +			BIO_printf(bio_err, "Response verify OK\n"); + +		} + +	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) +		goto end; + +	ret = 0; + +end: +	ERR_print_errors(bio_err); +	X509_free(signer); +	X509_STORE_free(store); +	EVP_PKEY_free(key); +	EVP_PKEY_free(rkey); +	X509_free(issuer); +	X509_free(cert); +	X509_free(rsigner); +	X509_free(rca_cert); +	free_index(rdb); +	BIO_free_all(cbio); +	BIO_free_all(acbio); +	BIO_free(out); +	OCSP_REQUEST_free(req); +	OCSP_RESPONSE_free(resp); +	OCSP_BASICRESP_free(bs); +	sk_OPENSSL_STRING_free(reqnames); +	sk_OCSP_CERTID_free(ids); +	sk_X509_pop_free(sign_other, X509_free); +	sk_X509_pop_free(verify_other, X509_free); +	sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); + +	if (use_ssl != -1) +		{ +		OPENSSL_free(host); +		OPENSSL_free(port); +		OPENSSL_free(path); +		} + +	OPENSSL_EXIT(ret); +} + +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer, +				STACK_OF(OCSP_CERTID) *ids) +	{ +	OCSP_CERTID *id; +	if(!issuer) +		{ +		BIO_printf(bio_err, "No issuer certificate specified\n"); +		return 0; +		} +	if(!*req) *req = OCSP_REQUEST_new(); +	if(!*req) goto err; +	id = OCSP_cert_to_id(cert_id_md, cert, issuer); +	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; +	if(!OCSP_request_add0_id(*req, id)) goto err; +	return 1; + +	err: +	BIO_printf(bio_err, "Error Creating OCSP request\n"); +	return 0; +	} + +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer, +				STACK_OF(OCSP_CERTID) *ids) +	{ +	OCSP_CERTID *id; +	X509_NAME *iname; +	ASN1_BIT_STRING *ikey; +	ASN1_INTEGER *sno; +	if(!issuer) +		{ +		BIO_printf(bio_err, "No issuer certificate specified\n"); +		return 0; +		} +	if(!*req) *req = OCSP_REQUEST_new(); +	if(!*req) goto err; +	iname = X509_get_subject_name(issuer); +	ikey = X509_get0_pubkey_bitstr(issuer); +	sno = s2i_ASN1_INTEGER(NULL, serial); +	if(!sno) +		{ +		BIO_printf(bio_err, "Error converting serial number %s\n", serial); +		return 0; +		} +	id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); +	ASN1_INTEGER_free(sno); +	if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err; +	if(!OCSP_request_add0_id(*req, id)) goto err; +	return 1; + +	err: +	BIO_printf(bio_err, "Error Creating OCSP request\n"); +	return 0; +	} + +static int 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; + +	ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + +	if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids)) +		return 1; + +	for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) +		{ +		id = sk_OCSP_CERTID_value(ids, i); +		name = sk_OPENSSL_STRING_value(names, i); +		BIO_printf(out, "%s: ", name); + +		if(!OCSP_resp_find_status(bs, id, &status, &reason, +					&rev, &thisupd, &nextupd)) +			{ +			BIO_puts(out, "ERROR: No Status found.\n"); +			continue; +			} + +		/* Check validity: if invalid write to output BIO so we +		 * know which response this refers to. +		 */ +		if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) +			{ +			BIO_puts(out, "WARNING: Status times invalid.\n"); +			ERR_print_errors(out); +			} +		BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); + +		BIO_puts(out, "\tThis Update: "); +		ASN1_GENERALIZEDTIME_print(out, thisupd); +		BIO_puts(out, "\n"); + +		if(nextupd) +			{ +			BIO_puts(out, "\tNext Update: "); +			ASN1_GENERALIZEDTIME_print(out, nextupd); +			BIO_puts(out, "\n"); +			} + +		if (status != V_OCSP_CERTSTATUS_REVOKED) +			continue; + +		if (reason != -1) +			BIO_printf(out, "\tReason: %s\n", +				OCSP_crl_reason_str(reason)); + +		BIO_puts(out, "\tRevocation Time: "); +		ASN1_GENERALIZEDTIME_print(out, rev); +		BIO_puts(out, "\n"); +		} + +	return 1; +	} + + +static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db, +			X509 *ca, X509 *rcert, EVP_PKEY *rkey, +			STACK_OF(X509) *rother, unsigned long flags, +			int nmin, int ndays) +	{ +	ASN1_TIME *thisupd = NULL, *nextupd = NULL; +	OCSP_CERTID *cid, *ca_id = NULL; +	OCSP_BASICRESP *bs = NULL; +	int i, id_count, ret = 1; + +	id_count = OCSP_request_onereq_count(req); + +	if (id_count <= 0) +		{ +		*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); +		goto end; +		} + + +	bs = OCSP_BASICRESP_new(); +	thisupd = X509_gmtime_adj(NULL, 0); +	if (ndays != -1) +		nextupd = X509_gmtime_adj(NULL, nmin * 60 + ndays * 3600 * 24 ); + +	/* Examine each certificate id in the request */ +	for (i = 0; i < id_count; i++) +		{ +		OCSP_ONEREQ *one; +		ASN1_INTEGER *serial; +		char **inf; +		ASN1_OBJECT *cert_id_md_oid; +		const EVP_MD *cert_id_md; +		one = OCSP_request_onereq_get0(req, i); +		cid = OCSP_onereq_get0_id(one); + +		OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid); + +		cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);	 +		if (! cert_id_md)  +			{ +			*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, +				NULL); +				goto end; +			}	 +		if (ca_id) OCSP_CERTID_free(ca_id); +		ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca); + +		/* Is this request about our CA? */ +		if (OCSP_id_issuer_cmp(ca_id, cid)) +			{ +			OCSP_basic_add1_status(bs, cid, +						V_OCSP_CERTSTATUS_UNKNOWN, +						0, NULL, +						thisupd, nextupd); +			continue; +			} +		OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); +		inf = lookup_serial(db, serial); +		if (!inf) +			OCSP_basic_add1_status(bs, cid, +						V_OCSP_CERTSTATUS_UNKNOWN, +						0, NULL, +						thisupd, nextupd); +		else if (inf[DB_type][0] == DB_TYPE_VAL) +			OCSP_basic_add1_status(bs, cid, +						V_OCSP_CERTSTATUS_GOOD, +						0, NULL, +						thisupd, nextupd); +		else if (inf[DB_type][0] == DB_TYPE_REV) +			{ +			ASN1_OBJECT *inst = NULL; +			ASN1_TIME *revtm = NULL; +			ASN1_GENERALIZEDTIME *invtm = NULL; +			OCSP_SINGLERESP *single; +			int reason = -1; +			unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); +			single = OCSP_basic_add1_status(bs, cid, +						V_OCSP_CERTSTATUS_REVOKED, +						reason, revtm, +						thisupd, nextupd); +			if (invtm) +				OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, invtm, 0, 0); +			else if (inst) +				OCSP_SINGLERESP_add1_ext_i2d(single, NID_hold_instruction_code, inst, 0, 0); +			ASN1_OBJECT_free(inst); +			ASN1_TIME_free(revtm); +			ASN1_GENERALIZEDTIME_free(invtm); +			} +		} + +	OCSP_copy_nonce(bs, req); +	 +	OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags); + +	*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); + +	end: +	ASN1_TIME_free(thisupd); +	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) +	{ +	int i; +	BIGNUM *bn = NULL; +	char *itmp, *row[DB_NUMBER],**rrow; +	for (i = 0; i < DB_NUMBER; i++) row[i] = NULL; +	bn = ASN1_INTEGER_to_BN(ser,NULL); +	OPENSSL_assert(bn); /* FIXME: should report an error at this point and abort */ +	if (BN_is_zero(bn)) +		itmp = BUF_strdup("00"); +	else +		itmp = BN_bn2hex(bn); +	row[DB_serial] = itmp; +	BN_free(bn); +	rrow=TXT_DB_get_by_index(db->db,DB_serial,row); +	OPENSSL_free(itmp); +	return rrow; +	} + +/* Quick and dirty OCSP server: read in and parse input request */ + +static BIO *init_responder(char *port) +	{ +	BIO *acbio = NULL, *bufbio = NULL; +	bufbio = BIO_new(BIO_f_buffer()); +	if (!bufbio)  +		goto err; +#ifndef OPENSSL_NO_SOCK +	acbio = BIO_new_accept(port); +#else +	BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n"); +#endif +	if (!acbio) +		goto err; +	BIO_set_accept_bios(acbio, bufbio); +	bufbio = NULL; + +	if (BIO_do_accept(acbio) <= 0) +		{ +			BIO_printf(bio_err, "Error setting up accept BIO\n"); +			ERR_print_errors(bio_err); +			goto err; +		} + +	return acbio; + +	err: +	BIO_free_all(acbio); +	BIO_free(bufbio); +	return NULL; +	} + +static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port) +	{ +	int have_post = 0, len; +	OCSP_REQUEST *req = NULL; +	char inbuf[1024]; +	BIO *cbio = NULL; + +	if (BIO_do_accept(acbio) <= 0) +		{ +			BIO_printf(bio_err, "Error accepting connection\n"); +			ERR_print_errors(bio_err); +			return 0; +		} + +	cbio = BIO_pop(acbio); +	*pcbio = cbio; + +	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) +		{ +		BIO_printf(bio_err, "Error parsing OCSP request\n"); +		ERR_print_errors(bio_err); +		} + +	*preq = req; + +	return 1; + +	} + +static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) +	{ +	char http_resp[] =  +		"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" +		"Content-Length: %d\r\n\r\n"; +	if (!cbio) +		return 0; +	BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); +	i2d_OCSP_RESPONSE_bio(cbio, resp); +	(void)BIO_flush(cbio); +	return 1; +	} + +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, +				STACK_OF(CONF_VALUE) *headers, +				OCSP_REQUEST *req, int req_timeout) +	{ +	int fd; +	int rv; +	int i; +	OCSP_REQ_CTX *ctx = NULL; +	OCSP_RESPONSE *rsp = NULL; +	fd_set confds; +	struct timeval tv; + +	if (req_timeout != -1) +		BIO_set_nbio(cbio, 1); + +	rv = BIO_do_connect(cbio); + +	if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) +		{ +		BIO_puts(err, "Error connecting BIO\n"); +		return NULL; +		} + +	if (BIO_get_fd(cbio, &fd) <= 0) +		{ +		BIO_puts(err, "Can't get connection fd\n"); +		goto err; +		} + +	if (req_timeout != -1 && rv <= 0) +		{ +		FD_ZERO(&confds); +		openssl_fdset(fd, &confds); +		tv.tv_usec = 0; +		tv.tv_sec = req_timeout; +		rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); +		if (rv == 0) +			{ +			BIO_puts(err, "Timeout on connect\n"); +			return NULL; +			} +		} + + +	ctx = OCSP_sendreq_new(cbio, path, NULL, -1); +	if (!ctx) +		return NULL; + +	for (i = 0; i < sk_CONF_VALUE_num(headers); i++) +		{ +		CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); +		if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) +			goto err; +		} + +	if (!OCSP_REQ_CTX_set1_req(ctx, req)) +		goto err; +	 +	for (;;) +		{ +		rv = OCSP_sendreq_nbio(&rsp, ctx); +		if (rv != -1) +			break; +		if (req_timeout == -1) +			continue; +		FD_ZERO(&confds); +		openssl_fdset(fd, &confds); +		tv.tv_usec = 0; +		tv.tv_sec = req_timeout; +		if (BIO_should_read(cbio)) +			rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); +		else if (BIO_should_write(cbio)) +			rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); +		else +			{ +			BIO_puts(err, "Unexpected retry condition\n"); +			goto err; +			} +		if (rv == 0) +			{ +			BIO_puts(err, "Timeout on request\n"); +			break; +			} +		if (rv == -1) +			{ +			BIO_puts(err, "Select error\n"); +			break; +			} + +		} +	err: +	if (ctx) +		OCSP_REQ_CTX_free(ctx); + +	return rsp; +	} + +OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req, +			char *host, char *path, char *port, int use_ssl, +			STACK_OF(CONF_VALUE) *headers, +			int req_timeout) +	{ +	BIO *cbio = NULL; +	SSL_CTX *ctx = NULL; +	OCSP_RESPONSE *resp = NULL; +	cbio = BIO_new_connect(host); +	if (!cbio) +		{ +		BIO_printf(err, "Error creating connect BIO\n"); +		goto end; +		} +	if (port) BIO_set_conn_port(cbio, port); +	if (use_ssl == 1) +		{ +		BIO *sbio; +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +		ctx = SSL_CTX_new(SSLv23_client_method()); +#elif !defined(OPENSSL_NO_SSL3) +		ctx = SSL_CTX_new(SSLv3_client_method()); +#elif !defined(OPENSSL_NO_SSL2) +		ctx = SSL_CTX_new(SSLv2_client_method()); +#else +		BIO_printf(err, "SSL is disabled\n"); +			goto end; +#endif +		if (ctx == NULL) +			{ +			BIO_printf(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); +	if (!resp) +		BIO_printf(bio_err, "Error querying OCSP responsder\n"); +	end: +	if (cbio) +		BIO_free_all(cbio); +	if (ctx) +		SSL_CTX_free(ctx); +	return resp; +	} + +#endif diff --git a/main/openssl/apps/oid.cnf b/main/openssl/apps/oid.cnf new file mode 100644 index 00000000..faf425a1 --- /dev/null +++ b/main/openssl/apps/oid.cnf @@ -0,0 +1,6 @@ +2.99999.1       SET.ex1         SET x509v3 extension 1 +2.99999.2       SET.ex2         SET x509v3 extension 2 +2.99999.3       SET.ex3         SET x509v3 extension 3 +2.99999.4       SET.ex4         SET x509v3 extension 4 +2.99999.5       SET.ex5         SET x509v3 extension 5 +2.99999.6       SET.ex6         SET x509v3 extension 6 diff --git a/main/openssl/apps/openssl.c b/main/openssl/apps/openssl.c new file mode 100644 index 00000000..10689573 --- /dev/null +++ b/main/openssl/apps/openssl.c @@ -0,0 +1,714 @@ +/* apps/openssl.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include <stdio.h> +#include <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/lhash.h> +#include <openssl/conf.h> +#include <openssl/x509.h> +#include <openssl/pem.h> +#include <openssl/ssl.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" +#include "s_apps.h" +#include <openssl/err.h> + +/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the + * base prototypes (we cast each variable inside the function to the required + * type of "FUNCTION*"). This removes the necessity for macro-generated wrapper + * functions. */ + +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); +char *default_config_file=NULL; + +/* Make sure there is only one when MONOLITH is defined */ +#ifdef MONOLITH +CONF *config=NULL; +BIO *bio_err=NULL; +#endif + + +static void lock_dbg_cb(int mode, int type, const char *file, int line) +	{ +	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ +	const char *errstr = NULL; +	int rw; +	 +	rw = mode & (CRYPTO_READ|CRYPTO_WRITE); +	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) +		{ +		errstr = "invalid mode"; +		goto err; +		} + +	if (type < 0 || type >= CRYPTO_NUM_LOCKS) +		{ +		errstr = "type out of bounds"; +		goto err; +		} + +	if (mode & CRYPTO_LOCK) +		{ +		if (modes[type]) +			{ +			errstr = "already locked"; +			/* must not happen in a single-threaded program +			 * (would deadlock) */ +			goto err; +			} + +		modes[type] = rw; +		} +	else if (mode & CRYPTO_UNLOCK) +		{ +		if (!modes[type]) +			{ +			errstr = "not locked"; +			goto err; +			} +		 +		if (modes[type] != rw) +			{ +			errstr = (rw == CRYPTO_READ) ? +				"CRYPTO_r_unlock on write lock" : +				"CRYPTO_w_unlock on read lock"; +			} + +		modes[type] = 0; +		} +	else +		{ +		errstr = "invalid mode"; +		goto err; +		} + + err: +	if (errstr) +		{ +		/* we cannot use bio_err here */ +		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", +			errstr, mode, type, file, line); +		} +	} + +#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) +# define ARGV _Argv +#else +# define ARGV Argv +#endif + +int main(int Argc, char *ARGV[]) +	{ +	ARGS arg; +#define PROG_NAME_SIZE	39 +	char pname[PROG_NAME_SIZE+1]; +	FUNCTION f,*fp; +	MS_STATIC const char *prompt; +	MS_STATIC char buf[1024]; +	char *to_free=NULL; +	int n,i,ret=0; +	int argc; +	char **argv,*p; +	LHASH_OF(FUNCTION) *prog=NULL; +	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; +		} +	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_mem_ctrl(CRYPTO_MEM_CHECK_ON); + +#if 0 +	if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) +#endif +		{ +		CRYPTO_set_locking_callback(lock_dbg_cb); +		} + +	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; + +	config=NCONF_new(NULL); +	i=NCONF_load(config,p,&errline); +	if (i == 0) +		{ +		if (ERR_GET_REASON(ERR_peek_last_error()) +		    == CONF_R_NO_SUCH_FILE) +			{ +#if 0 /* ANDROID */ +			BIO_printf(bio_err, +				   "WARNING: can't open config file: %s\n",p); +#endif +			ERR_clear_error(); +			NCONF_free(config); +			config = NULL; +			} +		else +			{ +			ERR_print_errors(bio_err); +			NCONF_free(config); +			exit(1); +			} +		} + +	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); +		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 (ret < 0) ret=0; +		goto end; +		} + +	/* ok, lets enter the old 'OpenSSL>' mode */ +	 +	for (;;) +		{ +		ret=0; +		p=buf; +		n=sizeof buf; +		i=0; +		for (;;) +			{ +			p[0]='\0'; +			if (i++) +				prompt=">"; +			else	prompt="OpenSSL> "; +			fputs(prompt,stdout); +			fflush(stdout); +			if (!fgets(p,n,stdin)) +				goto end; +			if (p[0] == '\0') goto end; +			i=strlen(p); +			if (i <= 1) break; +			if (p[i-2] != '\\') break; +			i-=2; +			p+=i; +			n-=i; +			} +		if (!chopup_args(&arg,buf,&argc,&argv)) break; + +		ret=do_cmd(prog,argc,argv); +		if (ret < 0) +			{ +			ret=0; +			goto end; +			} +		if (ret != 0) +			BIO_printf(bio_err,"error in %s\n",argv[0]); +		(void)BIO_flush(bio_err); +		} +	BIO_printf(bio_err,"bad exit\n"); +	ret=1; +end: +	if (to_free) +		OPENSSL_free(to_free); +	if (config != NULL) +		{ +		NCONF_free(config); +		config=NULL; +		} +	if (prog != NULL) lh_FUNCTION_free(prog); +	if (arg.data != NULL) OPENSSL_free(arg.data); + +	apps_shutdown(); + +	CRYPTO_mem_leaks(bio_err); +	if (bio_err != NULL) +		{ +		BIO_free(bio_err); +		bio_err=NULL; +		} +#if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) +	/* Free any duplicate Argv[] storage. */ +	if (free_Argv) +		{ +		OPENSSL_free(Argv); +		} +#endif +	OPENSSL_EXIT(ret); +	} + +#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 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; } +	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.func = dgst_main; +			fp = &f; +			} +		else if (EVP_get_cipherbyname(argv[0])) +			{ +			f.type = FUNC_TYPE_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 +		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); +		} +#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; +		} +end: +	return(ret); +	} + +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 void list_pkey(BIO *out) +	{ +	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; +		const char *pinfo, *pem_str; +		ameth = EVP_PKEY_asn1_get0(i); +		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", +					OBJ_nid2ln(pkey_base_id)); +			} +		else +			{ +			BIO_printf(out, "Name: %s\n", pinfo); +			BIO_printf(out, "\tType: %s Algorithm\n",  +				pkey_flags & ASN1_PKEY_DYNAMIC ? +					"External" : "Builtin"); +			BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); +			if (pem_str == NULL) +				pem_str = "(none)"; +			BIO_printf(out, "\tPEM string: %s\n", pem_str); +			} +					 +		} +	} + +static void list_cipher_fn(const EVP_CIPHER *c, +			const char *from, const char *to, void *arg) +	{ +	if (c) +		BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); +	else +		{ +		if (!from) +			from = "<undefined>"; +		if (!to) +			to = "<undefined>"; +		BIO_printf(arg, "%s => %s\n", from, to); +		} +	} + +static void list_cipher(BIO *out) +	{ +	EVP_CIPHER_do_all_sorted(list_cipher_fn, out); +	} + +static void list_md_fn(const EVP_MD *m, +			const char *from, const char *to, void *arg) +	{ +	if (m) +		BIO_printf(arg, "%s\n", EVP_MD_name(m)); +	else +		{ +		if (!from) +			from = "<undefined>"; +		if (!to) +			to = "<undefined>"; +		BIO_printf(arg, "%s => %s\n", from, to); +		} +	} + +static void list_md(BIO *out) +	{ +	EVP_MD_do_all_sorted(list_md_fn, out); +	} + +static int MS_CALLBACK function_cmp(const FUNCTION *a, const FUNCTION *b) +	{ +	return strncmp(a->name,b->name,8); +	} +static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION) + +static unsigned long MS_CALLBACK function_hash(const FUNCTION *a) +	{ +	return lh_strhash(a->name); +	}	 +static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION) + +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 ? */ +	for(i=0,f=functions ; f->name != NULL ; ++f,++i) +	    ; +	qsort(functions,i,sizeof *functions,SortFnByName); + +	if ((ret=lh_FUNCTION_new()) == NULL) +		return(NULL); + +	for (f=functions; f->name != NULL; f++) +		(void)lh_FUNCTION_insert(ret,f); +	return(ret); +	} + diff --git a/main/openssl/apps/openssl.cnf b/main/openssl/apps/openssl.cnf new file mode 100644 index 00000000..9d2cd5bf --- /dev/null +++ b/main/openssl/apps/openssl.cnf @@ -0,0 +1,350 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME			= . +RANDFILE		= $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file		= $ENV::HOME/.oid +oid_section		= new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions		=  +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca	= CA_default		# The default ca section + +#################################################################### +[ CA_default ] + +dir		= ./demoCA		# Where everything is kept +certs		= $dir/certs		# Where the issued certs are kept +crl_dir		= $dir/crl		# Where the issued crl are kept +database	= $dir/index.txt	# database index file. +#unique_subject	= no			# Set to 'no' to allow creation of +					# several ctificates with same subject. +new_certs_dir	= $dir/newcerts		# default place for new certs. + +certificate	= $dir/cacert.pem 	# The CA certificate +serial		= $dir/serial 		# The current serial number +crlnumber	= $dir/crlnumber	# the current crl number +					# must be commented out to leave a V1 CRL +crl		= $dir/crl.pem 		# The current CRL +private_key	= $dir/private/cakey.pem# The private key +RANDFILE	= $dir/private/.rand	# private random number file + +x509_extensions	= usr_cert		# The extentions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt 	= ca_default		# Subject Name options +cert_opt 	= ca_default		# Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions	= crl_ext + +default_days	= 365			# how long to certify for +default_crl_days= 30			# how long before next CRL +default_md	= default		# use public key default MD +preserve	= no			# keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy		= policy_match + +# For the CA policy +[ policy_match ] +countryName		= match +stateOrProvinceName	= match +organizationName	= match +organizationalUnitName	= optional +commonName		= supplied +emailAddress		= optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName		= optional +stateOrProvinceName	= optional +localityName		= optional +organizationName	= optional +organizationalUnitName	= optional +commonName		= supplied +emailAddress		= optional + +#################################################################### +[ req ] +default_bits		= 1024 +default_keyfile 	= privkey.pem +distinguished_name	= req_distinguished_name +attributes		= req_attributes +x509_extensions	= v3_ca	# The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options.  +# default: PrintableString, T61String, BMPString. +# pkix	 : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName			= Country Name (2 letter code) +countryName_default		= AU +countryName_min			= 2 +countryName_max			= 2 + +stateOrProvinceName		= State or Province Name (full name) +stateOrProvinceName_default	= Some-State + +localityName			= Locality Name (eg, city) + +0.organizationName		= Organization Name (eg, company) +0.organizationName_default	= Internet Widgits Pty Ltd + +# we can do this but it is not needed normally :-) +#1.organizationName		= Second Organization Name (eg, company) +#1.organizationName_default	= World Wide Web Pty Ltd + +organizationalUnitName		= Organizational Unit Name (eg, section) +#organizationalUnitName_default	= + +commonName			= Common Name (eg, YOUR name) +commonName_max			= 64 + +emailAddress			= Email Address +emailAddress_max		= 64 + +# SET-ex3			= SET extension number 3 + +[ req_attributes ] +challengePassword		= A challenge password +challengePassword_min		= 4 +challengePassword_max		= 20 + +unstructuredName		= An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType			= server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment			= "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType			= server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment			= "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1	# the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir		= ./demoCA		# TSA root directory +serial		= $dir/tsaserial	# The current serial number (mandatory) +crypto_device	= builtin		# OpenSSL engine to use for signing +signer_cert	= $dir/tsacert.pem 	# The TSA signing certificate +					# (optional) +certs		= $dir/cacert.pem	# Certificate chain to include in reply +					# (optional) +signer_key	= $dir/private/tsakey.pem # The TSA private key (optional) + +default_policy	= tsa_policy1		# Policy if request did not specify it +					# (optional) +other_policies	= tsa_policy2, tsa_policy3	# acceptable policies (optional) +digests		= md5, sha1		# Acceptable message digests (mandatory) +accuracy	= secs:1, millisecs:500, microsecs:100	# (optional) +clock_precision_digits  = 0	# number of digits after dot. (optional) +ordering		= yes	# Is ordering defined for timestamps? +				# (optional, default: no) +tsa_name		= yes	# Must the TSA name be included in the reply? +				# (optional, default: no) +ess_cert_id_chain	= no	# Must the ESS cert id chain be included? +				# (optional, default: no) diff --git a/main/openssl/apps/passwd.c b/main/openssl/apps/passwd.c new file mode 100644 index 00000000..9ca25dd1 --- /dev/null +++ b/main/openssl/apps/passwd.c @@ -0,0 +1,512 @@ +/* apps/passwd.c */ + +#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC +# define NO_MD5CRYPT_1 +#endif + +#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1) + +#include <assert.h> +#include <string.h> + +#include "apps.h" + +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/rand.h> +#ifndef OPENSSL_NO_DES +# include <openssl/des.h> +#endif +#ifndef NO_MD5CRYPT_1 +# 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, +	0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, +	0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, +	0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, +	0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, +	0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, +	0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, +	0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A +}; + +static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, +	char *passwd, BIO *out, int quiet, int table, 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 **); + +int 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; +	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) +			in_noverify = 1; +		else if (strcmp(argv[i], "-quiet") == 0) +			quiet = 1; +		else if (strcmp(argv[i], "-table") == 0) +			table = 1; +		else if (strcmp(argv[i], "-reverse") == 0) +			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; +		} + +	if (!usecrypt && !use1 && !useapr1) /* use default */ +		usecrypt = 1; +	if (usecrypt + use1 + useapr1 > 1) /* conflict */ +		badopt = 1; + +	/* reject unsupported algorithms */ +#ifdef OPENSSL_NO_DES +	if (usecrypt) badopt = 1; +#endif +#ifdef NO_MD5CRYPT_1 +	if (use1 || useapr1) badopt = 1; +#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 != 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); +			} +		} +	 +	if (usecrypt) +		pw_maxlen = 8; +	else if (use1 || useapr1) +		pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */ + +	if (passwds == NULL) +		{ +		/* no passwords on the command line */ + +		passwd_malloc_size = pw_maxlen + 2; +		/* longer than necessary so that we can warn about truncation */ +		passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size); +		if (passwd_malloc == NULL) +			goto err; +		} + +	if ((in == NULL) && (passwds == NULL)) +		{ +		/* build a null-terminated list */ +		static char *passwds_static[2] = {NULL, NULL}; +		 +		passwds = passwds_static; +		if (in == NULL) +			if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ", !(passed_salt || in_noverify)) != 0) +				goto err; +		passwds[0] = passwd_malloc; +		} + +	if (in == NULL) +		{ +		assert(passwds != NULL); +		assert(*passwds != NULL); +		 +		do /* loop over list of passwords */ +			{ +			passwd = *passwds++; +			if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out, +				quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1)) +				goto err; +			} +		while (*passwds != NULL); +		} +	else +		/* in != NULL */ +		{ +		int done; + +		assert (passwd != NULL); +		do +			{ +			int r = BIO_gets(in, passwd, pw_maxlen + 1); +			if (r > 0) +				{ +				char *c = (strchr(passwd, '\n')) ; +				if (c != NULL) +					*c = 0; /* truncate at newline */ +				else +					{ +					/* ignore rest of line */ +					char trash[BUFSIZ]; +					do +						r = BIO_gets(in, trash, sizeof trash); +					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; +				} +			done = (r <= 0); +			} +		while (!done); +		} +	ret = 0; + +err: +	ERR_print_errors(bio_err); +	if (salt_malloc) +		OPENSSL_free(salt_malloc); +	if (passwd_malloc) +		OPENSSL_free(passwd_malloc); +	if (in) +		BIO_free(in); +	if (out) +		BIO_free_all(out); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + + +#ifndef NO_MD5CRYPT_1 +/* MD5-based password algorithm (should probably be available as a library + * function; then the static buffer would not be acceptable). + * For magic string "1", this should be compatible to the MD5-based BSD + * password algorithm. + * For 'magic' string "apr1", this is compatible to the MD5-based Apache + * password algorithm. + * (Apparently, the Apache password algorithm is identical except that the + * 'magic' string was changed -- the laziest application of the NIH principle + * I've ever encountered.) + */ +static char *md5crypt(const char *passwd, const char *magic, const char *salt) +	{ +	static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */ +	unsigned char buf[MD5_DIGEST_LENGTH]; +	char *salt_out; +	int n; +	unsigned int i; +	EVP_MD_CTX md,md2; +	size_t passwd_len, salt_len; + +	passwd_len = strlen(passwd); +	out_buf[0] = '$'; +	out_buf[1] = 0; +	assert(strlen(magic) <= 4); /* "1" or "apr1" */ +	strncat(out_buf, magic, 4); +	strncat(out_buf, "$", 1); +	strncat(out_buf, salt, 8); +	assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */ +	salt_out = out_buf + 2 + strlen(magic); +	salt_len = strlen(salt_out); +	assert(salt_len <= 8); +	 +	EVP_MD_CTX_init(&md); +	EVP_DigestInit_ex(&md,EVP_md5(), NULL); +	EVP_DigestUpdate(&md, passwd, passwd_len); +	EVP_DigestUpdate(&md, "$", 1); +	EVP_DigestUpdate(&md, magic, strlen(magic)); +	EVP_DigestUpdate(&md, "$", 1); +	EVP_DigestUpdate(&md, salt_out, salt_len); +	 +	EVP_MD_CTX_init(&md2); +	EVP_DigestInit_ex(&md2,EVP_md5(), NULL); +	EVP_DigestUpdate(&md2, passwd, passwd_len); +	EVP_DigestUpdate(&md2, salt_out, salt_len); +	EVP_DigestUpdate(&md2, passwd, passwd_len); +	EVP_DigestFinal_ex(&md2, buf, NULL); + +	for (i = passwd_len; i > sizeof buf; i -= sizeof buf) +		EVP_DigestUpdate(&md, buf, sizeof buf); +	EVP_DigestUpdate(&md, buf, i); +	 +	n = passwd_len; +	while (n) +		{ +		EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1); +		n >>= 1; +		} +	EVP_DigestFinal_ex(&md, buf, NULL); + +	for (i = 0; i < 1000; i++) +		{ +		EVP_DigestInit_ex(&md2,EVP_md5(), NULL); +		EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *) passwd : buf, +		                       (i & 1) ? passwd_len : sizeof buf); +		if (i % 3) +			EVP_DigestUpdate(&md2, salt_out, salt_len); +		if (i % 7) +			EVP_DigestUpdate(&md2, passwd, passwd_len); +		EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *) passwd, +		                       (i & 1) ? sizeof buf : passwd_len); +		EVP_DigestFinal_ex(&md2, buf, NULL); +		} +	EVP_MD_CTX_cleanup(&md2); +	 +	 { +		/* transform buf into output string */ +	 +		unsigned char buf_perm[sizeof buf]; +		int dest, source; +		char *output; + +		/* silly output permutation */ +		for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17) +			buf_perm[dest] = buf[source]; +		buf_perm[14] = buf[5]; +		buf_perm[15] = buf[11]; +#ifndef PEDANTIC /* Unfortunately, this generates a "no effect" warning */ +		assert(16 == sizeof buf_perm); +#endif +		 +		output = salt_out + salt_len; +		assert(output == out_buf + strlen(out_buf)); +		 +		*output++ = '$'; + +		for (i = 0; i < 15; i += 3) +			{ +			*output++ = cov_2char[buf_perm[i+2] & 0x3f]; +			*output++ = cov_2char[((buf_perm[i+1] & 0xf) << 2) | +				                  (buf_perm[i+2] >> 6)]; +			*output++ = cov_2char[((buf_perm[i] & 3) << 4) | +				                  (buf_perm[i+1] >> 4)]; +			*output++ = cov_2char[buf_perm[i] >> 2]; +			} +		assert(i == 15); +		*output++ = cov_2char[buf_perm[i] & 0x3f]; +		*output++ = cov_2char[buf_perm[i] >> 6]; +		*output = 0; +		assert(strlen(out_buf) < sizeof(out_buf)); +	 } +	EVP_MD_CTX_cleanup(&md); + +	return out_buf; +	} +#endif + + +static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, +	char *passwd, BIO *out,	int quiet, int table, int reverse, +	size_t pw_maxlen, int usecrypt, int use1, int useapr1) +	{ +	char *hash = NULL; + +	assert(salt_p != NULL); +	assert(salt_malloc_p != NULL); + +	/* first make sure we have a salt */ +	if (!passed_salt) +		{ +#ifndef OPENSSL_NO_DES +		if (usecrypt) +			{ +			if (*salt_malloc_p == NULL) +				{ +				*salt_p = *salt_malloc_p = OPENSSL_malloc(3); +				if (*salt_malloc_p == NULL) +					goto err; +				} +			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0) +				goto err; +			(*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; +#ifdef CHARSET_EBCDIC +			ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert +			                                    * back to ASCII */ +#endif +			} +#endif /* !OPENSSL_NO_DES */ + +#ifndef NO_MD5CRYPT_1 +		if (use1 || useapr1) +			{ +			int i; +			 +			if (*salt_malloc_p == NULL) +				{ +				*salt_p = *salt_malloc_p = OPENSSL_malloc(9); +				if (*salt_malloc_p == NULL) +					goto err; +				} +			if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0) +				goto err; +			 +			for (i = 0; i < 8; i++) +				(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ +			(*salt_p)[8] = 0; +			} +#endif /* !NO_MD5CRYPT_1 */ +		} +	 +	assert(*salt_p != NULL); +	 +	/* truncate password if necessary */ +	if ((strlen(passwd) > pw_maxlen)) +		{ +		if (!quiet) +			/* XXX: really we should know how to print a size_t, not cast it */ +			BIO_printf(bio_err, "Warning: truncating password to %u characters\n", (unsigned)pw_maxlen); +		passwd[pw_maxlen] = 0; +		} +	assert(strlen(passwd) <= pw_maxlen); +	 +	/* now compute password hash */ +#ifndef OPENSSL_NO_DES +	if (usecrypt) +		hash = DES_crypt(passwd, *salt_p); +#endif +#ifndef NO_MD5CRYPT_1 +	if (use1 || useapr1) +		hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p); +#endif +	assert(hash != NULL); + +	if (table && !reverse) +		BIO_printf(out, "%s\t%s\n", passwd, hash); +	else if (table && reverse) +		BIO_printf(out, "%s\t%s\n", hash, passwd); +	else +		BIO_printf(out, "%s\n", hash); +	return 1; +	 +err: +	return 0; +	} +#else + +int MAIN(int argc, char **argv) +	{ +	fputs("Program not available.\n", stderr) +	OPENSSL_EXIT(1); +	} +#endif diff --git a/main/openssl/apps/pca-cert.srl b/main/openssl/apps/pca-cert.srl new file mode 100644 index 00000000..2c7456e3 --- /dev/null +++ b/main/openssl/apps/pca-cert.srl @@ -0,0 +1 @@ +07 diff --git a/main/openssl/apps/pca-key.pem b/main/openssl/apps/pca-key.pem new file mode 100644 index 00000000..20029ab7 --- /dev/null +++ b/main/openssl/apps/pca-key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7 +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc= +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/pca-req.pem b/main/openssl/apps/pca-req.pem new file mode 100644 index 00000000..33f15533 --- /dev/null +++ b/main/openssl/apps/pca-req.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBmjCCAQMCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAo +MTAyNCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfj +Irkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUX +MRsp22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3 +vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAEzz +IG8NnfpnPTQSCN5zJhOfy6p9AcDyQzuJirYv1HR/qoYWalPh/U2uiK0lAim7qMcv +wOlK3I7A8B7/4dLqvIqgtUj9b1WT8zIrnwdvJI4osLI2BY+c1pVlp174DHLMol1L +Cl1e3N5BTm7lCitTYjuUhsw6hiA8IcdNKDo6sktV +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/pkcs12.c b/main/openssl/apps/pkcs12.c new file mode 100644 index 00000000..b54c6f84 --- /dev/null +++ b/main/openssl/apps/pkcs12.c @@ -0,0 +1,977 @@ +/* pkcs12.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <openssl/opensslconf.h> +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/crypto.h> +#include <openssl/err.h> +#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 +#define CLCERTS		0x8 +#define CACERTS		0x10 + +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 dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass, +			  int passlen, int options, char *pempass); +int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); +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 **); + +int 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 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 cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; +    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +    int ret = 1; +    int macver = 1; +    int noprompt = 0; +    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++; +    } + +    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); +#endif + +    if(passarg) { +	if(export_cert) passargout = passarg; +	else passargin = passarg; +    } + +    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { +	BIO_printf(bio_err, "Error getting passwords\n"); +	goto end; +    } + +    if(!cpass) { +    	if(export_cert) cpass = passout; +    	else cpass = passin; +    } + +    if(cpass) { +	mpass = cpass; +	noprompt = 1; +    } else { +	cpass = pass; +	mpass = macpass; +    } + +    if(export_cert || inrand) { +    	app_RAND_load_file(NULL, bio_err, (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); +	    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); +	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) { +	EVP_PKEY *key = NULL; +	X509 *ucert = NULL, *x = NULL; +	STACK_OF(X509) *certs=NULL; +	const EVP_MD *macmd = NULL; +	unsigned char *catmp = NULL; +	int i; + +	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS)) +		{	 +		BIO_printf(bio_err, "Nothing to do!\n"); +		goto export_end; +		} + +	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, +				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, +							"certificates"); +		if (!certs) +			goto export_end; + +		if (key) +			{ +			/* Look for matching private key */ +			for(i = 0; i < sk_X509_num(certs); i++) +				{ +				x = sk_X509_value(certs, i); +				if(X509_check_private_key(x, key)) +					{ +					ucert = x; +					/* Zero keyid and alias */ +					X509_keyid_set1(ucert, NULL, 0); +					X509_alias_set1(ucert, NULL, 0); +					/* Remove from list */ +					(void)sk_X509_delete(certs, i); +					break; +					} +				} +			if (!ucert) +				{ +				BIO_printf(bio_err, "No certificate matches private key\n"); +				goto export_end; +				} +			} + +		} + +#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, +					    "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"); +			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); + +		if (!vret) { +		    /* Exclude verified certificate */ +		    for (i = 1; i < sk_X509_num (chain2) ; i++)  +			sk_X509_push(certs, sk_X509_value (chain2, i)); +		    /* Free first certificate */ +		    X509_free(sk_X509_value(chain2, 0)); +		    sk_X509_free(chain2); +		} else { +			if (vret >= 0) +				BIO_printf (bio_err, "Error %s getting chain.\n", +					X509_verify_cert_error_string(vret)); +			else +				ERR_print_errors(bio_err); +			goto export_end; +		}			 +    	} + +	/* Add any CA names */ + +	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) +		{ +		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); +		X509_alias_set1(sk_X509_value(certs, i), catmp, -1); +		} + +	if (csp_name && key) +		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, +				MBSTRING_ASC, (unsigned char *)csp_name, -1); + +	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)) +		{ +	    	BIO_printf (bio_err, "Can't read Password\n"); +	    	goto export_end; +        	} +	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); + +	if (!p12) +		{ +	    	ERR_print_errors (bio_err); +		goto export_end; +		} + +	if (macalg) +		{ +		macmd = EVP_get_digestbyname(macalg); +		if (!macmd) +			{ +			BIO_printf(bio_err, "Unknown digest algorithm %s\n",  +						macalg); +			} +		} + +	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 + +	if (key) EVP_PKEY_free(key); +	if (certs) sk_X509_pop_free(certs, X509_free); +	if (ucert) X509_free(ucert); + +#ifdef CRYPTO_MDEBUG +	CRYPTO_pop_info(); +#endif +	goto end; +	 +    } + +    if (!(p12 = d2i_PKCS12_bio (in, NULL))) { +	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); + +    if ((options & INFO) && p12->mac) 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 */ +		if(!twopass) cpass = NULL; +	} else if (!PKCS12_verify_mac(p12, mpass, -1)) { +	    BIO_printf (bio_err, "Mac verify error: invalid password?\n"); +	    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)) { +	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: +    if (p12) PKCS12_free(p12); +    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); +#ifdef CRYPTO_MDEBUG +    CRYPTO_remove_all_info(); +#endif +    BIO_free(in); +    BIO_free_all(out); +    if (canames) sk_OPENSSL_STRING_free(canames); +    if(passin) OPENSSL_free(passin); +    if(passout) OPENSSL_free(passout); +    apps_shutdown(); +    OPENSSL_EXIT(ret); +} + +int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, +	     int passlen, int options, char *pempass) +{ +	STACK_OF(PKCS7) *asafes = NULL; +	STACK_OF(PKCS12_SAFEBAG) *bags; +	int i, bagnid; +	int ret = 0; +	PKCS7 *p7; + +	if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0; +	for (i = 0; i < sk_PKCS7_num (asafes); i++) { +		p7 = sk_PKCS7_value (asafes, i); +		bagnid = OBJ_obj2nid (p7->type); +		if (bagnid == NID_pkcs7_data) { +			bags = PKCS12_unpack_p7data(p7); +			if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n"); +		} else if (bagnid == NID_pkcs7_encrypted) { +			if (options & INFO) { +				BIO_printf(bio_err, "PKCS7 Encrypted data: "); +				alg_print(bio_err,  +					p7->d.encrypted->enc_data->algorithm); +			} +			bags = PKCS12_unpack_p7encdata(p7, pass, passlen); +		} else continue; +		if (!bags) goto err; +	    	if (!dump_certs_pkeys_bags (out, bags, pass, passlen,  +						 options, pempass)) { +			sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); +			goto err; +		} +		sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free); +		bags = NULL; +	} +	ret = 1; + +	err: + +	if (asafes) +		sk_PKCS7_pop_free (asafes, PKCS7_free); +	return ret; +} + +int dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, +			   char *pass, int passlen, int options, char *pempass) +{ +	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)) +		    return 0; +	} +	return 1; +} + +int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass, +	     int passlen, int options, char *pempass) +{ +	EVP_PKEY *pkey; +	PKCS8_PRIV_KEY_INFO *p8; +	X509 *x509; +	 +	switch (M_PKCS12_bag_type(bag)) +	{ +	case NID_keyBag: +		if (options & INFO) BIO_printf (bio_err, "Key bag\n"); +		if (options & NOKEYS) return 1; +		print_attribs (out, bag->attrib, "Bag Attributes"); +		p8 = bag->value.keybag; +		if (!(pkey = EVP_PKCS82PKEY (p8))) return 0; +		print_attribs (out, p8->attributes, "Key Attributes"); +		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); +		EVP_PKEY_free(pkey); +	break; + +	case NID_pkcs8ShroudedKeyBag: +		if (options & INFO) { +			BIO_printf (bio_err, "Shrouded Keybag: "); +			alg_print (bio_err, bag->value.shkeybag->algor); +		} +		if (options & NOKEYS) return 1; +		print_attribs (out, bag->attrib, "Bag Attributes"); +		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) +				return 0; +		if (!(pkey = EVP_PKCS82PKEY (p8))) { +			PKCS8_PRIV_KEY_INFO_free(p8); +			return 0; +		} +		print_attribs (out, p8->attributes, "Key Attributes"); +		PKCS8_PRIV_KEY_INFO_free(p8); +		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass); +		EVP_PKEY_free(pkey); +	break; + +	case NID_certBag: +		if (options & INFO) BIO_printf (bio_err, "Certificate bag\n"); +		if (options & NOCERTS) return 1; +                if (PKCS12_get_attr(bag, NID_localKeyID)) { +			if (options & CACERTS) return 1; +		} else if (options & CLCERTS) return 1; +		print_attribs (out, bag->attrib, "Bag Attributes"); +		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) +								 return 1; +		if (!(x509 = PKCS12_certbag2x509(bag))) return 0; +		dump_cert_text (out, x509); +		PEM_write_bio_X509 (out, x509); +		X509_free(x509); +	break; + +	case NID_safeContentsBag: +		if (options & INFO) 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); +					 +	default: +		BIO_printf (bio_err, "Warning unsupported bag type: "); +		i2a_ASN1_OBJECT (bio_err, bag->type); +		BIO_printf (bio_err, "\n"); +		return 1; +	break; +	} +	return 1; +} + +/* Given a single certificate return a verified chain or NULL if error */ + +/* Hope this is OK .... */ + +int get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) +{ +	X509_STORE_CTX store_ctx; +	STACK_OF(X509) *chn; +	int i = 0; + +	/* FIXME: Should really check the return status of X509_STORE_CTX_init +	 * for an error, but how that fits into the return value of this +	 * function is less obvious. */ +	X509_STORE_CTX_init(&store_ctx, store, cert, NULL); +	if (X509_verify_cert(&store_ctx) <= 0) { +		i = X509_STORE_CTX_get_error (&store_ctx); +		if (i == 0) +			/* avoid returning 0 if X509_verify_cert() did not +			 * set an appropriate error value in the context */ +			i = -1; +		chn = NULL; +		goto err; +	} else +		chn = X509_STORE_CTX_get1_chain(&store_ctx); +err: +	X509_STORE_CTX_cleanup(&store_ctx); +	*chain = chn; +	 +	return i; +}	 + +int alg_print (BIO *x, X509_ALGOR *alg) +{ +	PBEPARAM *pbe; +	const unsigned char *p; +	p = alg->parameter->value.sequence->data; +	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); +	if (!pbe) +		return 1; +	BIO_printf (bio_err, "%s, Iteration %ld\n",  +		OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), +		ASN1_INTEGER_get(pbe->iter)); +	PBEPARAM_free (pbe); +	return 1; +} + +/* Load all certificates from a given file */ + +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; +} + +/* Generalised attribute print: handle PKCS#8 and bag attributes */ + +int print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name) +{ +	X509_ATTRIBUTE *attr; +	ASN1_TYPE *av; +	char *value; +	int i, attr_nid; +	if(!attrlst) { +		BIO_printf(out, "%s: <No Attributes>\n", name); +		return 1; +	} +	if(!sk_X509_ATTRIBUTE_num(attrlst)) { +		BIO_printf(out, "%s: <Empty Attributes>\n", name); +		return 1; +	} +	BIO_printf(out, "%s\n", name); +	for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { +		attr = sk_X509_ATTRIBUTE_value(attrlst, i); +		attr_nid = OBJ_obj2nid(attr->object); +		BIO_printf(out, "    "); +		if(attr_nid == NID_undef) { +			i2a_ASN1_OBJECT (out, attr->object); +			BIO_printf(out, ": "); +		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); + +		if(sk_ASN1_TYPE_num(attr->value.set)) { +			av = sk_ASN1_TYPE_value(attr->value.set, 0); +			switch(av->type) { +				case V_ASN1_BMPSTRING: +        			value = OPENSSL_uni2asc(av->value.bmpstring->data, +                                	       av->value.bmpstring->length); +				BIO_printf(out, "%s\n", value); +				OPENSSL_free(value); +				break; + +				case V_ASN1_OCTET_STRING: +				hex_prin(out, av->value.octet_string->data, +					av->value.octet_string->length); +				BIO_printf(out, "\n");	 +				break; + +				case V_ASN1_BIT_STRING: +				hex_prin(out, av->value.bit_string->data, +					av->value.bit_string->length); +				BIO_printf(out, "\n");	 +				break; + +				default: +					BIO_printf(out, "<Unsupported tag %d>\n", av->type); +				break; +			} +		} else BIO_printf(out, "<No Values>\n"); +	} +	return 1; +} + +void hex_prin(BIO *out, unsigned char *buf, int len) +{ +	int i; +	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]); +} + +static int set_pbe(BIO *err, int *ppbe, const char *str) +	{ +	if (!str) +		return 0; +	if (!strcmp(str, "NONE")) +		{ +		*ppbe = -1; +		return 1; +		} +	*ppbe=OBJ_txt2nid(str); +	if (*ppbe == NID_undef) +		{ +		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); +		return 0; +		} +	return 1; +	} +			 +#endif diff --git a/main/openssl/apps/pkcs7.c b/main/openssl/apps/pkcs7.c new file mode 100644 index 00000000..ae6cd33f --- /dev/null +++ b/main/openssl/apps/pkcs7.c @@ -0,0 +1,320 @@ +/* apps/pkcs7.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "apps.h" +#include <openssl/err.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/x509.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 + */ + +int MAIN(int, char **); + +int 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; + +	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) +			noout=1; +		else if (strcmp(*argv,"-text") == 0) +			text=1; +		else if (strcmp(*argv,"-print") == 0) +			p7_print=1; +		else if (strcmp(*argv,"-print_certs") == 0) +			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; +			} +		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," -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"); +#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); +                goto end; +                } + +	if (infile == NULL) +		BIO_set_fp(in,stdin,BIO_NOCLOSE); +	else +		{ +		if (BIO_read_filename(in,infile) <= 0) +		if (in == NULL) +			{ +			perror(infile); +			goto end; +			} +		} + +	if	(informat == FORMAT_ASN1) +		p7=d2i_PKCS7_bio(in,NULL); +	else if (informat == FORMAT_PEM) +		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; +			} +		} + +	if (p7_print) +		PKCS7_print_ctx(out, p7, 0, NULL); + +	if (print_certs) +		{ +		STACK_OF(X509) *certs=NULL; +		STACK_OF(X509_CRL) *crls=NULL; + +		i=OBJ_obj2nid(p7->type); +		switch (i) +			{ +		case NID_pkcs7_signed: +			certs=p7->d.sign->cert; +			crls=p7->d.sign->crl; +			break; +		case NID_pkcs7_signedAndEnveloped: +			certs=p7->d.signed_and_enveloped->cert; +			crls=p7->d.signed_and_enveloped->crl; +			break; +		default: +			break; +			} + +		if (certs != NULL) +			{ +			X509 *x; + +			for (i=0; i<sk_X509_num(certs); i++) +				{ +				x=sk_X509_value(certs,i); +				if(text) X509_print(out, x); +				else dump_cert_text(out, x); + +				if(!noout) PEM_write_bio_X509(out,x); +				BIO_puts(out,"\n"); +				} +			} +		if (crls != NULL) +			{ +			X509_CRL *crl; + +			for (i=0; i<sk_X509_CRL_num(crls); i++) +				{ +				crl=sk_X509_CRL_value(crls,i); + +				X509_CRL_print(out, crl); + +				if(!noout)PEM_write_bio_X509_CRL(out,crl); +				BIO_puts(out,"\n"); +				} +			} + +		ret=0; +		goto end; +		} + +	if(!noout) { +		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); +			goto end; +			} +	} +	ret=0; +end: +	if (p7 != NULL) PKCS7_free(p7); +	if (in != NULL) BIO_free(in); +	if (out != NULL) BIO_free_all(out); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} diff --git a/main/openssl/apps/pkcs8.c b/main/openssl/apps/pkcs8.c new file mode 100644 index 00000000..7edeb179 --- /dev/null +++ b/main/openssl/apps/pkcs8.c @@ -0,0 +1,439 @@ +/* pkcs8.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999-2004. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/pkcs12.h> + +#define PROG pkcs8_main + +int MAIN(int, char **); + +int 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; +	EVP_PKEY *pkey=NULL; +	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; + +	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,"-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")) +			topk8 = 1; +		else if (!strcmp (*args, "-noiter")) +			iter = 1; +		else if (!strcmp (*args, "-nocrypt")) +			nocrypt = 1; +		else if (!strcmp (*args, "-nooct")) +			p8_broken = PKCS8_NO_OCTET; +		else if (!strcmp (*args, "-nsdb")) +			p8_broken = PKCS8_NS_DB; +		else if (!strcmp (*args, "-embed")) +			p8_broken = PKCS8_EMBEDDED_PARAM; +		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 badarg = 1; +		args++; +		} + +	if (badarg) +		{ +		bad: +		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, "-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); +#endif + +	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) +		{ +		BIO_printf(bio_err, "Error getting passwords\n"); +		goto end; +		} + +	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 +		} +	if (topk8) +		{ +		pkey = load_key(bio_err, infile, informat, 1, +			passin, e, "key"); +		if (!pkey) +			goto end; +		if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken))) +			{ +			BIO_printf(bio_err, "Error converting key\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		if (nocrypt) +			{ +			if (outformat == FORMAT_PEM)  +				PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); +			else if (outformat == FORMAT_ASN1) +				i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); +			else +				{ +				BIO_printf(bio_err, "Bad format specified for key\n"); +				goto end; +				} +			} +		else +			{ +			if (passout) +				p8pass = passout; +			else +				{ +				p8pass = pass; +				if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1)) +					goto end; +				} +			app_RAND_load_file(NULL, bio_err, 0); +			if (!(p8 = PKCS8_encrypt(pbe_nid, cipher, +					p8pass, strlen(p8pass), +					NULL, 0, iter, p8inf))) +				{ +				BIO_printf(bio_err, "Error encrypting key\n"); +				ERR_print_errors(bio_err); +				goto end; +				} +			app_RAND_write_file(NULL, bio_err); +			if (outformat == FORMAT_PEM)  +				PEM_write_bio_PKCS8(out, p8); +			else if (outformat == FORMAT_ASN1) +				i2d_PKCS8_bio(out, p8); +			else +				{ +				BIO_printf(bio_err, "Bad format specified for key\n"); +				goto end; +				} +			} + +		ret = 0; +		goto end; +		} + +	if (nocrypt) +		{ +		if (informat == FORMAT_PEM)  +			p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL); +		else if (informat == FORMAT_ASN1) +			p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); +		else +			{ +			BIO_printf(bio_err, "Bad format specified for key\n"); +			goto end; +			} +		} +	else +		{ +		if (informat == FORMAT_PEM)  +			p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); +		else if (informat == FORMAT_ASN1) +			p8 = d2i_PKCS8_bio(in, NULL); +		else +			{ +			BIO_printf(bio_err, "Bad format specified for key\n"); +			goto end; +			} + +		if (!p8) +			{ +			BIO_printf (bio_err, "Error reading key\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		if (passin) +			p8pass = passin; +		else +			{ +			p8pass = pass; +			EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0); +			} +		p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); +		} + +	if (!p8inf) +		{ +		BIO_printf(bio_err, "Error decrypting key\n"); +		ERR_print_errors(bio_err); +		goto end; +		} + +	if (!(pkey = EVP_PKCS82PKEY(p8inf))) +		{ +		BIO_printf(bio_err, "Error converting key\n"); +		ERR_print_errors(bio_err); +		goto end; +		} +	 +	if (p8inf->broken) +		{ +		BIO_printf(bio_err, "Warning: broken key encoding: "); +		switch (p8inf->broken) +			{ +			case PKCS8_NO_OCTET: +			BIO_printf(bio_err, "No Octet String in PrivateKey\n"); +			break; + +			case PKCS8_EMBEDDED_PARAM: +			BIO_printf(bio_err, "DSA parameters included in PrivateKey\n"); +			break; + +			case PKCS8_NS_DB: +			BIO_printf(bio_err, "DSA public key include in PrivateKey\n"); +			break; + +			case PKCS8_NEG_PRIVKEY: +			BIO_printf(bio_err, "DSA private key value is negative\n"); +			break; + +			default: +			BIO_printf(bio_err, "Unknown broken type\n"); +			break; +		} +	} +	 +	if (outformat == FORMAT_PEM)  +		PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); +	else if (outformat == FORMAT_ASN1) +		i2d_PrivateKey_bio(out, pkey); +	else +		{ +		BIO_printf(bio_err, "Bad format specified for key\n"); +			goto end; +		} +	ret = 0; + +	end: +	X509_SIG_free(p8); +	PKCS8_PRIV_KEY_INFO_free(p8inf); +	EVP_PKEY_free(pkey); +	BIO_free_all(out); +	BIO_free(in); +	if (passin) +		OPENSSL_free(passin); +	if (passout) +		OPENSSL_free(passout); + +	return ret; +	} diff --git a/main/openssl/apps/pkey.c b/main/openssl/apps/pkey.c new file mode 100644 index 00000000..17e6702f --- /dev/null +++ b/main/openssl/apps/pkey.c @@ -0,0 +1,284 @@ +/* apps/pkey.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/evp.h> + +#define PROG pkey_main + +int MAIN(int, char **); + +int 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; +	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) +			pubout=1; +		else if (strcmp(*args,"-text_pub") == 0) +			{ +			pubtext=1; +			text=1; +			} +		else if (strcmp(*args,"-text") == 0) +			text=1; +		else if (strcmp(*args,"-noout") == 0) +			noout=1; +		else +			{ +			cipher = EVP_get_cipherbyname(*args + 1); +			if (!cipher) +				{ +				BIO_printf(bio_err, "Unknown cipher %s\n", +								*args + 1); +				badarg = 1; +				} +			} +		args++; +		} + +	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); +#endif + +	if (!app_passwd(bio_err, passargin, passargout, &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 +		} + +	if (pubin) +		pkey = load_pubkey(bio_err, infile, informat, 1, +			passin, e, "Public Key"); +	else +		pkey = load_key(bio_err, infile, informat, 1, +			passin, e, "key"); +	if (!pkey) +		goto end; + +	if (!noout) +		{ +		if (outformat == FORMAT_PEM)  +			{ +			if (pubout) +				PEM_write_bio_PUBKEY(out,pkey); +			else +				PEM_write_bio_PrivateKey(out, pkey, cipher, +							NULL, 0, NULL, passout); +			} +		else if (outformat == FORMAT_ASN1) +			{ +			if (pubout) +				i2d_PUBKEY_bio(out, pkey); +			else +				i2d_PrivateKey_bio(out, pkey); +			} +		else +			{ +			BIO_printf(bio_err, "Bad format specified for key\n"); +			goto end; +			} + +		} + +	if (text) +		{ +		if (pubtext) +			EVP_PKEY_print_public(out, pkey, 0, NULL); +		else +			EVP_PKEY_print_private(out, pkey, 0, NULL); +		} + +	ret = 0; + +	end: +	EVP_PKEY_free(pkey); +	BIO_free_all(out); +	BIO_free(in); +	if (passin) +		OPENSSL_free(passin); +	if (passout) +		OPENSSL_free(passout); + +	return ret; +	} diff --git a/main/openssl/apps/pkeyparam.c b/main/openssl/apps/pkeyparam.c new file mode 100644 index 00000000..6f7a357a --- /dev/null +++ b/main/openssl/apps/pkeyparam.c @@ -0,0 +1,200 @@ +/* apps/pkeyparam.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006 + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/evp.h> + +#define PROG pkeyparam_main + +int MAIN(int, char **); + +int 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) +			text=1; +		else if (strcmp(*args,"-noout") == 0) +			noout=1; +		args++; +		} + +	if (badarg) +		{ +#ifndef OPENSSL_NO_ENGINE +		bad: +#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 +		} + +	pkey = PEM_read_bio_Parameters(in, NULL); +	if (!pkey) +		{ +		BIO_printf(bio_err, "Error reading parameters\n"); +		ERR_print_errors(bio_err); +		goto end; +		} + +	if (!noout) +		PEM_write_bio_Parameters(out,pkey); + +	if (text) +		EVP_PKEY_print_params(out, pkey, 0, NULL); + +	ret = 0; + +	end: +	EVP_PKEY_free(pkey); +	BIO_free_all(out); +	BIO_free(in); + +	return ret; +	} diff --git a/main/openssl/apps/pkeyutl.c b/main/openssl/apps/pkeyutl.c new file mode 100644 index 00000000..7eb3f5c5 --- /dev/null +++ b/main/openssl/apps/pkeyutl.c @@ -0,0 +1,570 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + +#include "apps.h" +#include <string.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/evp.h> + +#define KEY_PRIVKEY	1 +#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); + +static int setup_peer(BIO *err, 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 **); + +int 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; + +	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; +	size_t buf_outlen; +	int buf_inlen = 0, siglen = -1; + +	int ret = 1, rv = -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(); +	 +	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; +					} +				} +			} +		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)); +			} +#ifndef OPENSSL_NO_ENGINE +		else if(!strcmp(*argv, "-engine")) +			{ +			if (--argc < 1) +				badarg = 1; +			else +				e = setup_engine(bio_err, *(++argv), 0); +			} +#endif +		else if(!strcmp(*argv, "-pubin")) +			key_type = KEY_PUBKEY; +		else if(!strcmp(*argv, "-certin")) +			key_type = KEY_CERT; +		else if(!strcmp(*argv, "-asn1parse")) +			asn1parse = 1; +		else if(!strcmp(*argv, "-hexdump")) +			hexdump = 1; +		else if(!strcmp(*argv, "-sign")) +			pkey_op = EVP_PKEY_OP_SIGN; +		else if(!strcmp(*argv, "-verify")) +			pkey_op = EVP_PKEY_OP_VERIFY; +		else if(!strcmp(*argv, "-verifyrecover")) +			pkey_op = EVP_PKEY_OP_VERIFYRECOVER; +		else if(!strcmp(*argv, "-rev")) +			rev = 1; +		else if(!strcmp(*argv, "-encrypt")) +			pkey_op = EVP_PKEY_OP_ENCRYPT; +		else if(!strcmp(*argv, "-decrypt")) +			pkey_op = EVP_PKEY_OP_DECRYPT; +		else if(!strcmp(*argv, "-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"); +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		else badarg = 1; +		if(badarg) +			{ +			usage(); +			goto end; +			} +		argc--; +		argv++; +		} + +	if (!ctx) +		{ +		usage(); +		goto end; +		} + +	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) +		{ +		BIO_puts(bio_err, "Signature file specified for non verify\n"); +		goto end; +		} + +	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) +		{ +		BIO_puts(bio_err, "No signature file specified for verify\n"); +		goto end; +		} + +/* FIXME: seed PRNG only if needed */ +	app_RAND_load_file(NULL, bio_err, 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);	 +			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 +	} + +	if (sigfile) +		{ +		BIO *sigbio = BIO_new_file(sigfile, "rb"); +		if (!sigbio) +			{ +			BIO_printf(bio_err, "Can't open signature file %s\n", +								sigfile); +			goto end; +			} +		siglen = bio_to_mem(&sig, keysize * 10, sigbio); +		BIO_free(sigbio); +		if (siglen <= 0) +			{ +			BIO_printf(bio_err, "Error reading signature data\n"); +			goto end; +			} +		} +	 +	if (in) +		{ +		/* Read the input data */ +		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); +		if(buf_inlen <= 0) +			{ +			BIO_printf(bio_err, "Error reading input Data\n"); +			exit(1); +			} +		if(rev) +			{ +			size_t i; +			unsigned char ctmp; +			size_t l = (size_t)buf_inlen; +			for(i = 0; i < l/2; i++) +				{ +				ctmp = buf_in[i]; +				buf_in[i] = buf_in[l - 1 - i]; +				buf_in[l - 1 - i] = ctmp; +				} +			} +		} + +	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) +			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); +			} +		} + +	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); +		} +	else if(hexdump) +		BIO_dump(out, (char *)buf_out, buf_outlen); +	else +		BIO_write(out, buf_out, buf_outlen); + +	end: +	if (ctx) +		EVP_PKEY_CTX_free(ctx); +	BIO_free(in); +	BIO_free_all(out); +	if (buf_in) +		OPENSSL_free(buf_in); +	if (buf_out) +		OPENSSL_free(buf_out); +	if (sig) +		OPENSSL_free(sig); +	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) +	{ +	EVP_PKEY *pkey = NULL; +	EVP_PKEY_CTX *ctx = NULL; +	char *passin = NULL; +	int rv = -1; +	X509 *x; +	if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)  +		|| (pkey_op == EVP_PKEY_OP_DERIVE)) +		&& (key_type != KEY_PRIVKEY)) +		{ +		BIO_printf(bio_err, "A private key is needed for this operation\n"); +		goto end; +		} +	if(!app_passwd(bio_err, passargin, 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"); +		break; + +		case KEY_PUBKEY: +		pkey = load_pubkey(bio_err, keyfile, keyform, 0, +			NULL, e, "Public Key"); +		break; + +		case KEY_CERT: +		x = load_cert(bio_err, keyfile, keyform, +			NULL, e, "Certificate"); +		if(x) +			{ +			pkey = X509_get_pubkey(x); +			X509_free(x); +			} +		break; + +		} + +	*pkeysize = EVP_PKEY_size(pkey); + +	if (!pkey) +		goto end; + +	ctx = EVP_PKEY_CTX_new(pkey, e); + +	EVP_PKEY_free(pkey); + +	if (!ctx) +		goto end; + +	switch(pkey_op) +		{ +		case EVP_PKEY_OP_SIGN: +		rv = EVP_PKEY_sign_init(ctx); +		break; + +		case EVP_PKEY_OP_VERIFY: +		rv = EVP_PKEY_verify_init(ctx); +		break; + +		case EVP_PKEY_OP_VERIFYRECOVER: +		rv = EVP_PKEY_verify_recover_init(ctx); +		break; + +		case EVP_PKEY_OP_ENCRYPT: +		rv = EVP_PKEY_encrypt_init(ctx); +		break; + +		case EVP_PKEY_OP_DECRYPT: +		rv = EVP_PKEY_decrypt_init(ctx); +		break; + +		case EVP_PKEY_OP_DERIVE: +		rv = EVP_PKEY_derive_init(ctx); +		break; +		} + +	if (rv <= 0) +		{ +		EVP_PKEY_CTX_free(ctx); +		ctx = NULL; +		} + +	end: + +	if (passin) +		OPENSSL_free(passin); + +	return ctx; + + +	} + +static int setup_peer(BIO *err, 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"); +		return 0; +		} +		 +	peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key"); + +	if (!peer) +		{ +		BIO_printf(bio_err, "Error reading peer key %s\n", file); +		ERR_print_errors(err); +		return 0; +		} + +	ret = EVP_PKEY_derive_set_peer(ctx, peer); + +	EVP_PKEY_free(peer); +	if (ret <= 0) +		ERR_print_errors(err); +	return ret; +	} + +static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, +		unsigned char *out, size_t *poutlen, +		unsigned char *in, size_t inlen) +	{ +	int rv = 0; +	switch(pkey_op) +		{ +		case EVP_PKEY_OP_VERIFYRECOVER: +		rv  = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); +		break; + +		case EVP_PKEY_OP_SIGN: +		rv  = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); +		break; + +		case EVP_PKEY_OP_ENCRYPT: +		rv  = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); +		break; + +		case EVP_PKEY_OP_DECRYPT: +		rv  = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); +		break;  + +		case EVP_PKEY_OP_DERIVE: +		rv  = EVP_PKEY_derive(ctx, out, poutlen); +		break; + +		} +	return rv; +	} diff --git a/main/openssl/apps/prime.c b/main/openssl/apps/prime.c new file mode 100644 index 00000000..f1aaef87 --- /dev/null +++ b/main/openssl/apps/prime.c @@ -0,0 +1,160 @@ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <string.h> + +#include "apps.h" +#include <openssl/bn.h> + + +#undef PROG +#define PROG prime_main + +int MAIN(int, char **); + +int 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")) +	    hex=1; +	else if(!strcmp(*argv,"-generate")) +	    generate=1; +	else if(!strcmp(*argv,"-bits")) +	    if(--argc < 1) +		goto bad; +	    else +		bits=atoi(*++argv); +	else if(!strcmp(*argv,"-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; +	    } +	--argc; +	++argv; +	} + +    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(generate) +	{ +	char *s; + +	if(!bits) +	    { +	    BIO_printf(bio_err,"Specifiy the number of bits.\n"); +	    return 1; +	    } +	bn=BN_new(); +	BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL); +	s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn); +	BIO_printf(bio_out,"%s\n",s); +	OPENSSL_free(s); +	} +    else +	{ +	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_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; +    } diff --git a/main/openssl/apps/privkey.pem b/main/openssl/apps/privkey.pem new file mode 100644 index 00000000..0af46474 --- /dev/null +++ b/main/openssl/apps/privkey.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,BA26229A1653B7FF + +6nhWG8PKhTPO/s3ZvjUa6226NlKdvPDZFsNXOOoSUs9ejxpb/aj5huhs6qRYzsz9 +Year47uaAZYhGD0vAagnNiBnYmjWEpN9G/wQxG7pgZThK1ZxDi63qn8aQ8UjuGHo +F6RpnnBQIAnWTWqr/Qsybtc5EoNkrj/Cpx0OfbSr6gZsFBCxwX1R1hT3/mhJ45f3 +XMofY32Vdfx9/vtw1O7HmlHXQnXaqnbd9/nn1EpvFJG9+UjPoW7gV4jCOLuR4deE +jS8hm+cpkwXmFtk3VGjT9tQXPpMv3JpYfBqgGQoMAJ5Toq0DWcHi6Wg08PsD8lgy +vmTioPsRg+JGkJkJ8GnusgLpQdlQJbjzd7wGE6ElUFLfOxLo8bLlRHoriHNdWYhh +JjY0LyeTkovcmWxVjImc6ZyBz5Ly4t0BYf1gq3OkjsV91Q1taBxnhiavfizqMCAf +PPB3sLQnlXG77TOXkNxpqbZfEYrVZW2Nsqqdn8s07Uj4IMONZyq2odYKWFPMJBiM +POYwXjMAOcmFMTHYsVlhcUJuV6LOuipw/FEbTtPH/MYMxLe4zx65dYo1rb4iLKLS +gMtB0o/Wl4Xno3ZXh1ucicYnV2J7NpVcjVq+3SFiCRu2SrSkZHZ23EPS13Ec6fcz +8X/YGA2vTJ8MAOozAzQUwHQYvLk7bIoQVekqDq4p0AZQbhdspHpArCk0Ifqqzg/v +Uyky/zZiQYanzDenTSRVI/8wac3olxpU8QvbySxYqmbkgq6bTpXJfYFQfnAttEsC +dA4S5UFgyOPZluxCAM4yaJF3Ft6neutNwftuJQMbgCUi9vYg2tGdSw== +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/progs.h b/main/openssl/apps/progs.h new file mode 100644 index 00000000..728bb6dd --- /dev/null +++ b/main/openssl/apps/progs.h @@ -0,0 +1,364 @@ +/* apps/progs.h */ +/* automatically generated by progs.pl for openssl.c */ + +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 crl_main(int argc,char *argv[]); +extern int rsa_main(int argc,char *argv[]); +extern int rsautl_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 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 nseq_main(int argc,char *argv[]); +extern int pkcs12_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[]); + +#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); + +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}, +#endif +#ifndef OPENSSL_NO_DH +	{FUNC_TYPE_GENERAL,"dhparam",dhparam_main}, +#endif +	{FUNC_TYPE_GENERAL,"enc",enc_main}, +	{FUNC_TYPE_GENERAL,"passwd",passwd_main}, +#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}, +#endif +#ifndef OPENSSL_NO_DSA +	{FUNC_TYPE_GENERAL,"dsa",dsa_main}, +#endif +#ifndef OPENSSL_NO_DSA +	{FUNC_TYPE_GENERAL,"dsaparam",dsaparam_main}, +#endif +#ifndef OPENSSL_NO_EC +	{FUNC_TYPE_GENERAL,"ec",ec_main}, +#endif +#ifndef OPENSSL_NO_EC +	{FUNC_TYPE_GENERAL,"ecparam",ecparam_main}, +#endif +	{FUNC_TYPE_GENERAL,"x509",x509_main}, +#ifndef OPENSSL_NO_RSA +	{FUNC_TYPE_GENERAL,"genrsa",genrsa_main}, +#endif +#ifndef OPENSSL_NO_DSA +	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main}, +#endif +	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main}, +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3)) +	{FUNC_TYPE_GENERAL,"s_server",s_server_main}, +#endif +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3)) +	{FUNC_TYPE_GENERAL,"s_client",s_client_main}, +#endif +#ifndef OPENSSL_NO_SPEED +	{FUNC_TYPE_GENERAL,"speed",speed_main}, +#endif +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3)) +	{FUNC_TYPE_GENERAL,"s_time",s_time_main}, +#endif +	{FUNC_TYPE_GENERAL,"version",version_main}, +	{FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main}, +#ifndef OPENSSL_NO_CMS +	{FUNC_TYPE_GENERAL,"cms",cms_main}, +#endif +	{FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main}, +	{FUNC_TYPE_GENERAL,"sess_id",sess_id_main}, +#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3)) +	{FUNC_TYPE_GENERAL,"ciphers",ciphers_main}, +#endif +	{FUNC_TYPE_GENERAL,"nseq",nseq_main}, +#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1) +	{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}, +#endif +#ifndef OPENSSL_NO_OCSP +	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main}, +#endif +	{FUNC_TYPE_GENERAL,"prime",prime_main}, +#if 0 /* ANDROID */ +	{FUNC_TYPE_GENERAL,"ts",ts_main}, +#endif +#ifndef OPENSSL_NO_MD2 +	{FUNC_TYPE_MD,"md2",dgst_main}, +#endif +#ifndef OPENSSL_NO_MD4 +	{FUNC_TYPE_MD,"md4",dgst_main}, +#endif +#ifndef OPENSSL_NO_MD5 +	{FUNC_TYPE_MD,"md5",dgst_main}, +#endif +#ifndef OPENSSL_NO_SHA +	{FUNC_TYPE_MD,"sha",dgst_main}, +#endif +#ifndef OPENSSL_NO_SHA1 +	{FUNC_TYPE_MD,"sha1",dgst_main}, +#endif +#ifndef OPENSSL_NO_MDC2 +	{FUNC_TYPE_MD,"mdc2",dgst_main}, +#endif +#ifndef OPENSSL_NO_RMD160 +	{FUNC_TYPE_MD,"rmd160",dgst_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-128-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-128-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-192-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-192-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-256-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_AES +	{FUNC_TYPE_CIPHER,"aes-256-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-128-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-128-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-192-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-192-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-256-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_CAMELLIA +	{FUNC_TYPE_CIPHER,"camellia-256-ecb",enc_main}, +#endif +	{FUNC_TYPE_CIPHER,"base64",enc_main}, +#ifdef ZLIB +	{FUNC_TYPE_CIPHER,"zlib",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des3",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"desx",enc_main}, +#endif +#ifndef OPENSSL_NO_IDEA +	{FUNC_TYPE_CIPHER,"idea",enc_main}, +#endif +#ifndef OPENSSL_NO_SEED +	{FUNC_TYPE_CIPHER,"seed",enc_main}, +#endif +#ifndef OPENSSL_NO_RC4 +	{FUNC_TYPE_CIPHER,"rc4",enc_main}, +#endif +#ifndef OPENSSL_NO_RC4 +	{FUNC_TYPE_CIPHER,"rc4-40",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2",enc_main}, +#endif +#ifndef OPENSSL_NO_BF +	{FUNC_TYPE_CIPHER,"bf",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast",enc_main}, +#endif +#ifndef OPENSSL_NO_RC5 +	{FUNC_TYPE_CIPHER,"rc5",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede3",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede3-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede3-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_DES +	{FUNC_TYPE_CIPHER,"des-ede3-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_IDEA +	{FUNC_TYPE_CIPHER,"idea-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_IDEA +	{FUNC_TYPE_CIPHER,"idea-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_IDEA +	{FUNC_TYPE_CIPHER,"idea-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_IDEA +	{FUNC_TYPE_CIPHER,"idea-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_SEED +	{FUNC_TYPE_CIPHER,"seed-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_SEED +	{FUNC_TYPE_CIPHER,"seed-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_SEED +	{FUNC_TYPE_CIPHER,"seed-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_SEED +	{FUNC_TYPE_CIPHER,"seed-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-64-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_RC2 +	{FUNC_TYPE_CIPHER,"rc2-40-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_BF +	{FUNC_TYPE_CIPHER,"bf-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_BF +	{FUNC_TYPE_CIPHER,"bf-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_BF +	{FUNC_TYPE_CIPHER,"bf-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_BF +	{FUNC_TYPE_CIPHER,"bf-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast5-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast5-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast5-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast5-ofb",enc_main}, +#endif +#ifndef OPENSSL_NO_CAST +	{FUNC_TYPE_CIPHER,"cast-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_RC5 +	{FUNC_TYPE_CIPHER,"rc5-cbc",enc_main}, +#endif +#ifndef OPENSSL_NO_RC5 +	{FUNC_TYPE_CIPHER,"rc5-ecb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC5 +	{FUNC_TYPE_CIPHER,"rc5-cfb",enc_main}, +#endif +#ifndef OPENSSL_NO_RC5 +	{FUNC_TYPE_CIPHER,"rc5-ofb",enc_main}, +#endif +	{0,NULL,NULL} +	}; diff --git a/main/openssl/apps/progs.pl b/main/openssl/apps/progs.pl new file mode 100644 index 00000000..de6fdeab --- /dev/null +++ b/main/openssl/apps/progs.pl @@ -0,0 +1,102 @@ +#!/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",$_; } + +print <<'EOF'; + +#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); + +FUNCTION functions[] = { +EOF + +foreach (@ARGV) +	{ +	push(@files,$_); +	$str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n"; +	if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/)) +		{ print "#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))\n${str}#endif\n"; }  +	elsif ( ($_ =~ /^speed$/)) +		{ print "#ifndef OPENSSL_NO_SPEED\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) && !defined(OPENSSL_NO_SHA1)\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"; } +	else +		{ print $str; } +	} + +foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160") +	{ +	push(@files,$_); +	printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n"; +	} + +foreach ( +	"aes-128-cbc", "aes-128-ecb", +	"aes-192-cbc", "aes-192-ecb", +	"aes-256-cbc", "aes-256-ecb", +	"camellia-128-cbc", "camellia-128-ecb", +	"camellia-192-cbc", "camellia-192-ecb", +	"camellia-256-cbc", "camellia-256-ecb", +	"base64", "zlib", +	"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", +	"rc2", "bf", "cast", "rc5", +	"des-ecb", "des-ede",    "des-ede3", +	"des-cbc", "des-ede-cbc","des-ede3-cbc", +	"des-cfb", "des-ede-cfb","des-ede3-cfb", +	"des-ofb", "des-ede-ofb","des-ede3-ofb", +	"idea-cbc","idea-ecb",    "idea-cfb", "idea-ofb", +	"seed-cbc","seed-ecb",    "seed-cfb", "seed-ofb", +	"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("\t{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; +	} + +print "\t{0,NULL,NULL}\n\t};\n"; diff --git a/main/openssl/apps/rand.c b/main/openssl/apps/rand.c new file mode 100644 index 00000000..790e7959 --- /dev/null +++ b/main/openssl/apps/rand.c @@ -0,0 +1,245 @@ +/* apps/rand.c */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "apps.h" + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include <openssl/bio.h> +#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; +#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 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; +			} +#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; +		} + +	if (hex && base64) +		badopt = 1; + +	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); +#endif + +	app_RAND_load_file(NULL, bio_err, (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()); +	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; + +	if (base64) +		{ +		BIO *b64 = BIO_new(BIO_f_base64()); +		if (b64 == NULL) +			goto err; +		out = BIO_push(b64, out); +		} +	 +	while (num > 0)  +		{ +		unsigned char buf[4096]; +		int chunk; + +		chunk = num; +		if (chunk > (int)sizeof(buf)) +			chunk = sizeof buf; +		r = RAND_bytes(buf, chunk); +		if (r <= 0) +			goto err; +		if (!hex)  +			BIO_write(out, buf, chunk); +		else +			{ +			for (i = 0; i < chunk; i++) +				BIO_printf(out, "%02x", buf[i]); +			} +		num -= chunk; +		} +	if (hex) +		BIO_puts(out, "\n"); +	(void)BIO_flush(out); + +	app_RAND_write_file(NULL, bio_err); +	ret = 0; +	 +err: +	ERR_print_errors(bio_err); +	if (out) +		BIO_free_all(out); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} diff --git a/main/openssl/apps/req.c b/main/openssl/apps/req.c new file mode 100644 index 00000000..820cd18f --- /dev/null +++ b/main/openssl/apps/req.c @@ -0,0 +1,1758 @@ +/* apps/req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/conf.h> +#include <openssl/err.h> +#include <openssl/asn1.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/objects.h> +#include <openssl/pem.h> +#include <openssl/bn.h> +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#ifndef OPENSSL_NO_DSA +#include <openssl/dsa.h> +#endif + +#define SECTION		"req" + +#define BITS		"default_bits" +#define KEYFILE		"default_keyfile" +#define PROMPT		"prompt" +#define DISTINGUISHED_NAME	"distinguished_name" +#define ATTRIBUTES	"attributes" +#define V3_EXTENSIONS	"x509_extensions" +#define REQ_EXTENSIONS	"req_extensions" +#define STRING_MASK	"string_mask" +#define UTF8_IN		"utf8" + +#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, +		int multirdn); +static int prompt_info(X509_REQ *req, +		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, +		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs, +		unsigned long chtype); +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, +				STACK_OF(CONF_VALUE) *attr, int attribs, +				unsigned long chtype); +static int add_attribute_object(X509_REQ *req, char *text, const char *def, +				char *value, int nid, int n_min, +				int n_max, unsigned long chtype); +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, +	int nid,int n_min,int n_max, unsigned long chtype, int mval); +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, 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 **); + +int MAIN(int argc, char **argv) +	{ +	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_CTX *genctx = NULL; +	const char *keyalg = NULL; +	char *keyalgstr = NULL; +	STACK_OF(OPENSSL_STRING) *pkeyopts = 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; +	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 + +	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)); +			} +#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)); +			if (gen_eng == NULL) +				{ +				BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); +				goto end; +				} +			} +#endif +		else if (strcmp(*argv,"-key") == 0) +			{ +			if (--argc < 1) goto bad; +			keyfile= *(++argv); +			} +		else if (strcmp(*argv,"-pubkey") == 0) +			{ +			pubkey=1; +			} +		else if (strcmp(*argv,"-new") == 0) +			{ +			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); +			newreq=1; +			} +		else if (strcmp(*argv,"-pkeyopt") == 0) +			{ +			if (--argc < 1) +				goto bad; +			if (!pkeyopts) +				pkeyopts = sk_OPENSSL_STRING_new_null(); +			if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv))) +				goto bad; +			} +		else if (strcmp(*argv,"-batch") == 0) +			batch=1; +		else if (strcmp(*argv,"-newhdr") == 0) +			newhdr=1; +		else if (strcmp(*argv,"-modulus") == 0) +			modulus=1; +		else if (strcmp(*argv,"-verify") == 0) +			verify=1; +		else if (strcmp(*argv,"-nodes") == 0) +			nodes=1; +		else if (strcmp(*argv,"-noout") == 0) +			noout=1; +		else if (strcmp(*argv,"-verbose") == 0) +			verbose=1; +		else if (strcmp(*argv,"-utf8") == 0) +			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) +			text=1; +		else if (strcmp(*argv,"-x509") == 0) +			x509=1; +		else if (strcmp(*argv,"-asn1-kludge") == 0) +			kludge=1; +		else if (strcmp(*argv,"-no-asn1-kludge") == 0) +			kludge=0; +		else if (strcmp(*argv,"-subj") == 0) +			{ +			if (--argc < 1) goto bad; +			subj= *(++argv); +			} +		else if (strcmp(*argv,"-multivalue-rdn") == 0) +			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 */ +			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_ECDSA +		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; +		} + +	ERR_load_crypto_strings(); +	if(!app_passwd(bio_err, 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; + +		if( verbose ) +			BIO_printf(bio_err,"Using configuration from %s\n",template); +		req_conf=NCONF_new(NULL); +		i=NCONF_load(req_conf,template,&errline); +		if (i == 0) +			{ +			BIO_printf(bio_err,"error on line %ld of %s\n",errline,template); +			goto end; +			} +		} +	else +		{ +		req_conf=config; + +		if (req_conf == NULL) +			{ +			BIO_printf(bio_err,"Unable to load config info from %s\n", default_config_file); +			if (newreq) +				goto end; +			} +		else if( verbose ) +			BIO_printf(bio_err,"Using configuration from %s\n", +			default_config_file); +		} + +	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(); +		if (p != NULL) +			{ +			BIO *oid_bio; + +			oid_bio=BIO_new_file(p,"r"); +			if (oid_bio == NULL)  +				{ +				/* +				BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); +				ERR_print_errors(bio_err); +				*/ +				} +			else +				{ +				OBJ_create_objects(oid_bio); +				BIO_free(oid_bio); +				} +			} +		} +	if(!add_oid_section(bio_err, 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; +			} +		} + +	if (!extensions) +		{ +		extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); +		if (!extensions) +			ERR_clear_error(); +		} +	if (extensions) { +		/* Check syntax of file */ +		X509V3_CTX ctx; +		X509V3_set_ctx_test(&ctx); +		X509V3_set_nconf(&ctx, req_conf); +		if(!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { +			BIO_printf(bio_err, +			 "Error Loading extension section %s\n", extensions); +			goto end; +		} +	} + +	if(!passin) +		{ +		passin = NCONF_get_string(req_conf, SECTION, "input_password"); +		if (!passin) +			ERR_clear_error(); +		} +	 +	if(!passout) +		{ +		passout = NCONF_get_string(req_conf, SECTION, "output_password"); +		if (!passout) +			ERR_clear_error(); +		} + +	p = NCONF_get_string(req_conf, SECTION, STRING_MASK); +	if (!p) +		ERR_clear_error(); + +	if(p && !ASN1_STRING_set_default_mask_asc(p)) { +		BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); +		goto end; +	} + +	if (chtype != MBSTRING_UTF8) +		{ +		p = NCONF_get_string(req_conf, SECTION, UTF8_IN); +		if (!p) +			ERR_clear_error(); +		else if (!strcmp(p, "yes")) +			chtype = MBSTRING_UTF8; +		} + + +	if(!req_exts) +		{ +		req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); +		if (!req_exts) +			ERR_clear_error(); +		} +	if(req_exts) { +		/* Check syntax of file */ +		X509V3_CTX ctx; +		X509V3_set_ctx_test(&ctx); +		X509V3_set_nconf(&ctx, req_conf); +		if(!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { +			BIO_printf(bio_err, +			 "Error Loading request extension section %s\n", +								req_exts); +			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); +#endif + +	if (keyfile != NULL) +		{ +		pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, +			"Private Key"); +		if (!pkey) +			{ +			/* 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); +			} +		} + +	if (newreq && (pkey == NULL)) +		{ +		char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE"); +		if (randfile == NULL) +			ERR_clear_error(); +		app_RAND_load_file(randfile, bio_err, 0); +		if (inrand) +			app_RAND_load_files(inrand); + +		if (keyalg) +			{ +			genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, +							&keyalgstr, gen_eng); +			if (!genctx) +				goto end; +			} +	 +		if (newkey <= 0) +			{ +			if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey)) +				newkey=DEFAULT_KEY_LENGTH; +			} + +		if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) +			{ +			BIO_printf(bio_err,"private key length is too short,\n"); +			BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey); +			goto end; +			} + +		if (!genctx) +			{ +			genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey, +							&keyalgstr, gen_eng); +			if (!genctx) +				goto end; +			} + +		if (pkeyopts) +			{ +			char *genopt; +			for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) +				{ +				genopt = sk_OPENSSL_STRING_value(pkeyopts, i); +				if (pkey_ctrl_string(genctx, genopt) <= 0) +					{ +					BIO_printf(bio_err, +						"parameter error \"%s\"\n", +						genopt); +					ERR_print_errors(bio_err); +					goto end; +					} +				} +			} + +		BIO_printf(bio_err,"Generating a %ld bit %s private key\n", +				newkey, keyalgstr); + +		EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); +		EVP_PKEY_CTX_set_app_data(genctx, bio_err); + +		if (EVP_PKEY_keygen(genctx, &pkey) <= 0) +			{ +			BIO_puts(bio_err, "Error Generating Key\n"); +			goto end; +			} + +		EVP_PKEY_CTX_free(genctx); +		genctx = NULL; + +		app_RAND_write_file(randfile, bio_err); + +		if (keyout == NULL) +			{ +			keyout=NCONF_get_string(req_conf,SECTION,KEYFILE); +			if (keyout == NULL) +				ERR_clear_error(); +			} +		 +		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 +			{ +			BIO_printf(bio_err,"writing new private key to '%s'\n",keyout); +			if (BIO_write_filename(out,keyout) <= 0) +				{ +				perror(keyout); +				goto end; +				} +			} + +		p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key"); +		if (p == NULL) +			{ +			ERR_clear_error(); +			p=NCONF_get_string(req_conf,SECTION,"encrypt_key"); +			if (p == NULL) +				ERR_clear_error(); +			} +		if ((p != NULL) && (strcmp(p,"no") == 0)) +			cipher=NULL; +		if (nodes) cipher=NULL; +		 +		i=0; +loop: +		if (!PEM_write_bio_PrivateKey(out,pkey,cipher, +			NULL,0,NULL,passout)) +			{ +			if ((ERR_GET_REASON(ERR_peek_error()) == +				PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) +				{ +				ERR_clear_error(); +				i++; +				goto loop; +				} +			goto end; +			} +		BIO_printf(bio_err,"-----\n"); +		} + +	if (!newreq) +		{ +		/* Since we are using a pre-existing certificate +		 * request, the kludge '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; +				} +			} + +		if	(informat == FORMAT_ASN1) +			req=d2i_X509_REQ_bio(in,NULL); +		else if (informat == FORMAT_PEM) +			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; +			} +		} + +	if (newreq || x509) +		{ +		if (pkey == NULL) +			{ +			BIO_printf(bio_err,"you need to specify a private key\n"); +			goto end; +			} + +		if (req == NULL) +			{ +			req=X509_REQ_new(); +			if (req == NULL) +				{ +				goto end; +				} + +			i=make_REQ(req,pkey,subj,multirdn,!x509, chtype); +			subj=NULL; /* done processing '-subj' option */ +			if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) +				{ +				sk_X509_ATTRIBUTE_free(req->req_info->attributes); +				req->req_info->attributes = NULL; +				} +			if (!i) +				{ +				BIO_printf(bio_err,"problems making Certificate Request\n"); +				goto end; +				} +			} +		if (x509) +			{ +			EVP_PKEY *tmppkey; +			X509V3_CTX ext_ctx; +			if ((x509ss=X509_new()) == NULL) goto end; + +			/* Set version to V3 */ +			if(extensions && !X509_set_version(x509ss, 2)) goto end; +			if (serial) +				{ +				if (!X509_set_serialNumber(x509ss, serial)) goto end; +				} +			else +				{ +				if (!rand_serial(NULL, +					X509_get_serialNumber(x509ss))) +						goto end; +				} + +			if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end; +			if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end; +			if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end; +			if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end; +			tmppkey = X509_REQ_get_pubkey(req); +			if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end; +			EVP_PKEY_free(tmppkey); + +			/* Set up V3 context struct */ + +			X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); +			X509V3_set_nconf(&ext_ctx, req_conf); + +			/* Add extensions */ +			if(extensions && !X509V3_EXT_add_nconf(req_conf,  +				 	&ext_ctx, extensions, x509ss)) +				{ +				BIO_printf(bio_err, +					"Error Loading extension section %s\n", +					extensions); +				goto end; +				} +			 +			if (!(i=X509_sign(x509ss,pkey,digest))) +				{ +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		else +			{ +			X509V3_CTX ext_ctx; + +			/* Set up V3 context struct */ + +			X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); +			X509V3_set_nconf(&ext_ctx, req_conf); + +			/* Add extensions */ +			if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,  +				 	&ext_ctx, req_exts, req)) +				{ +				BIO_printf(bio_err, +					"Error Loading extension section %s\n", +					req_exts); +				goto end; +				} +			if (!(i=X509_REQ_sign(req,pkey,digest))) +				{ +				ERR_print_errors(bio_err); +				goto end; +				} +			} +		} + +	if (subj && x509) +		{ +		BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); +		goto end; +		} + +	if (subj && !x509) +		{ +		if (verbose) +			{ +			BIO_printf(bio_err, "Modifying Request's Subject\n"); +			print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag); +			} + +		if (build_subject(req, subj, chtype, multirdn) == 0) +			{ +			BIO_printf(bio_err, "ERROR: cannot modify subject\n"); +			ex=1; +			goto end; +			} + +		req->req_info->enc.modified = 1; + +		if (verbose) +			{ +			print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag); +			} +		} + +	if (verify && !x509) +		{ +		int tmp=0; + +		if (pkey == NULL) +			{ +			pkey=X509_REQ_get_pubkey(req); +			tmp=1; +			if (pkey == NULL) goto end; +			} + +		i=X509_REQ_verify(req,pkey); +		if (tmp) { +			EVP_PKEY_free(pkey); +			pkey=NULL; +		} + +		if (i < 0) +			{ +			goto end; +			} +		else if (i == 0) +			{ +			BIO_printf(bio_err,"verify failure\n"); +			ERR_print_errors(bio_err); +			} +		else /* if (i > 0) */ +			BIO_printf(bio_err,"verify OK\n"); +		} + +	if (noout && !text && !modulus && !subject && !pubkey) +		{ +		ex=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; +			} +		} + +	if (pubkey) +		{ +		EVP_PKEY *tpubkey;  +		tpubkey=X509_REQ_get_pubkey(req); +		if (tpubkey == NULL) +			{ +			BIO_printf(bio_err,"Error getting public key\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		PEM_write_bio_PUBKEY(out, tpubkey); +		EVP_PKEY_free(tpubkey); +		} + +	if (text) +		{ +		if (x509) +			X509_print_ex(out, x509ss, nmflag, reqflag); +		else	 +			X509_REQ_print_ex(out, req, nmflag, reqflag); +		} + +	if(subject)  +		{ +		if(x509) +			print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag); +		else +			print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag); +		} + +	if (modulus) +		{ +		EVP_PKEY *tpubkey; + +		if (x509) +			tpubkey=X509_get_pubkey(x509ss); +		else +			tpubkey=X509_REQ_get_pubkey(req); +		if (tpubkey == NULL) +			{ +			fprintf(stdout,"Modulus=unavailable\n"); +			goto end;  +			} +		fprintf(stdout,"Modulus="); +#ifndef OPENSSL_NO_RSA +		if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) +			BN_print(out,tpubkey->pkey.rsa->n); +		else +#endif +			fprintf(stdout,"Wrong Algorithm type"); +		EVP_PKEY_free(tpubkey); +		fprintf(stdout,"\n"); +		} + +	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; +			} +		if (!i) +			{ +			BIO_printf(bio_err,"unable to write X509 request\n"); +			goto end; +			} +		} +	if (!noout && x509 && (x509ss != NULL)) +		{ +		if 	(outformat == FORMAT_ASN1) +			i=i2d_X509_bio(out,x509ss); +		else if (outformat == FORMAT_PEM) +			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; +end: +#ifndef MONOLITH +	if(to_free) +		OPENSSL_free(to_free); +#endif +	if (ex) +		{ +		ERR_print_errors(bio_err); +		} +	if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf); +	BIO_free(in); +	BIO_free_all(out); +	EVP_PKEY_free(pkey); +	if (genctx) +		EVP_PKEY_CTX_free(genctx); +	if (pkeyopts) +		sk_OPENSSL_STRING_free(pkeyopts); +#ifndef OPENSSL_NO_ENGINE +	if (gen_eng) +		ENGINE_free(gen_eng); +#endif +	if (keyalgstr) +		OPENSSL_free(keyalgstr); +	X509_REQ_free(req); +	X509_free(x509ss); +	ASN1_INTEGER_free(serial); +	if(passargin && passin) OPENSSL_free(passin); +	if(passargout && passout) OPENSSL_free(passout); +	OBJ_cleanup(); +	apps_shutdown(); +	OPENSSL_EXIT(ex); +	} + +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, +			int attribs, unsigned long chtype) +	{ +	int ret=0,i; +	char no_prompt = 0; +	STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; +	char *tmp, *dn_sect,*attr_sect; + +	tmp=NCONF_get_string(req_conf,SECTION,PROMPT); +	if (tmp == NULL) +		ERR_clear_error(); +	if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1; + +	dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME); +	if (dn_sect == NULL) +		{ +		BIO_printf(bio_err,"unable to find '%s' in config\n", +			DISTINGUISHED_NAME); +		goto err; +		} +	dn_sk=NCONF_get_section(req_conf,dn_sect); +	if (dn_sk == NULL) +		{ +		BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect); +		goto err; +		} + +	attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES); +	if (attr_sect == NULL) +		{ +		ERR_clear_error();		 +		attr_sk=NULL; +		} +	else +		{ +		attr_sk=NCONF_get_section(req_conf,attr_sect); +		if (attr_sk == NULL) +			{ +			BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect); +			goto err; +			} +		} + +	/* setup version number */ +	if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */ + +	if (no_prompt)  +		i = auto_info(req, dn_sk, attr_sk, attribs, chtype); +	else  +		{ +		if (subj) +			i = build_subject(req, subj, chtype, multirdn); +		else +			i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype); +		} +	if(!i) goto err; + +	if (!X509_REQ_set_pubkey(req,pkey)) goto err; + +	ret=1; +err: +	return(ret); +	} + +/* + * subject is expected to be in the format /type0=value0/type1=value1/type2=... + * where characters may be escaped by \ + */ +static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn) +	{ +	X509_NAME *n; + +	if (!(n = parse_name(subject, chtype, multirdn))) +		return 0; + +	if (!X509_REQ_set_subject_name(req, n)) +		{ +		X509_NAME_free(n); +		return 0; +		} +	X509_NAME_free(n); +	return 1; +} + + +static int prompt_info(X509_REQ *req, +		STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, +		STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs, +		unsigned long chtype) +	{ +	int i; +	char *p,*q; +	char buf[100]; +	int nid, mval; +	long n_min,n_max; +	char *type, *value; +	const char *def; +	CONF_VALUE *v; +	X509_NAME *subj; +	subj = X509_REQ_get_subject_name(req); + +	if(!batch) +		{ +		BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n"); +		BIO_printf(bio_err,"into your certificate request.\n"); +		BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n"); +		BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n"); +		BIO_printf(bio_err,"For some fields there will be a default value,\n"); +		BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n"); +		BIO_printf(bio_err,"-----\n"); +		} + + +	if (sk_CONF_VALUE_num(dn_sk)) +		{ +		i= -1; +start:		for (;;) +			{ +			i++; +			if (sk_CONF_VALUE_num(dn_sk) <= i) break; + +			v=sk_CONF_VALUE_value(dn_sk,i); +			p=q=NULL; +			type=v->name; +			if(!check_end(type,"_min") || !check_end(type,"_max") || +				!check_end(type,"_default") || +					 !check_end(type,"_value")) continue; +			/* Skip past any leading X. X: X, etc to allow for +			 * multiple instances  +			 */ +			for(p = v->name; *p ; p++)  +				if ((*p == ':') || (*p == ',') || +							 (*p == '.')) { +					p++; +					if(*p) type = p; +					break; +				} +			if (*type == '+') +				{ +				mval = -1; +				type++; +				} +			else +				mval = 0; +			/* If OBJ not recognised ignore it */ +			if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start; +			if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name) +				>= (int)sizeof(buf)) +			   { +			   BIO_printf(bio_err,"Name '%s' too long\n",v->name); +			   return 0; +			   } + +			if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL) +				{ +				ERR_clear_error(); +				def=""; +				} +				 +			BIO_snprintf(buf,sizeof buf,"%s_value",v->name); +			if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL) +				{ +				ERR_clear_error(); +				value=NULL; +				} + +			BIO_snprintf(buf,sizeof buf,"%s_min",v->name); +			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min)) +				{ +				ERR_clear_error(); +				n_min = -1; +				} + +			BIO_snprintf(buf,sizeof buf,"%s_max",v->name); +			if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max)) +				{ +				ERR_clear_error(); +				n_max = -1; +				} + +			if (!add_DN_object(subj,v->value,def,value,nid, +				n_min,n_max, chtype, mval)) +				return 0; +			} +		if (X509_NAME_entry_count(subj) == 0) +			{ +			BIO_printf(bio_err,"error, no objects specified in config file\n"); +			return 0; +			} + +		if (attribs) +			{ +			if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch)) +				{ +				BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n"); +				BIO_printf(bio_err,"to be sent with your certificate request\n"); +				} + +			i= -1; +start2:			for (;;) +				{ +				i++; +				if ((attr_sk == NULL) || +					    (sk_CONF_VALUE_num(attr_sk) <= i)) +					break; + +				v=sk_CONF_VALUE_value(attr_sk,i); +				type=v->name; +				if ((nid=OBJ_txt2nid(type)) == NID_undef) +					goto start2; + +				if (BIO_snprintf(buf,sizeof buf,"%s_default",type) +					>= (int)sizeof(buf)) +				   { +				   BIO_printf(bio_err,"Name '%s' too long\n",v->name); +				   return 0; +				   } + +				if ((def=NCONF_get_string(req_conf,attr_sect,buf)) +					== NULL) +					{ +					ERR_clear_error(); +					def=""; +					} +				 +				 +				BIO_snprintf(buf,sizeof buf,"%s_value",type); +				if ((value=NCONF_get_string(req_conf,attr_sect,buf)) +					== NULL) +					{ +					ERR_clear_error(); +					value=NULL; +					} + +				BIO_snprintf(buf,sizeof buf,"%s_min",type); +				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min)) +					{ +					ERR_clear_error(); +					n_min = -1; +					} + +				BIO_snprintf(buf,sizeof buf,"%s_max",type); +				if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max)) +					{ +					ERR_clear_error(); +					n_max = -1; +					} + +				if (!add_attribute_object(req, +					v->value,def,value,nid,n_min,n_max, chtype)) +					return 0; +				} +			} +		} +	else +		{ +		BIO_printf(bio_err,"No template, please set one up.\n"); +		return 0; +		} + +	return 1; + +	} + +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, +			STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype) +	{ +	int i; +	char *p,*q; +	char *type; +	CONF_VALUE *v; +	X509_NAME *subj; + +	subj = X509_REQ_get_subject_name(req); + +	for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) +		{ +		int mval; +		v=sk_CONF_VALUE_value(dn_sk,i); +		p=q=NULL; +		type=v->name; +		/* Skip past any leading X. X: X, etc to allow for +		 * multiple instances  +		 */ +		for(p = v->name; *p ; p++)  +#ifndef CHARSET_EBCDIC +			if ((*p == ':') || (*p == ',') || (*p == '.')) { +#else +			if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) { +#endif +				p++; +				if(*p) type = p; +				break; +			} +#ifndef CHARSET_EBCDIC +		if (*p == '+') +#else +		if (*p == os_toascii['+']) +#endif +			{ +			p++; +			mval = -1; +			} +		else +			mval = 0; +		if (!X509_NAME_add_entry_by_txt(subj,type, chtype, +				(unsigned char *) v->value,-1,-1,mval)) return 0; + +		} + +		if (!X509_NAME_entry_count(subj)) +			{ +			BIO_printf(bio_err,"error, no objects specified in config file\n"); +			return 0; +			} +		if (attribs) +			{ +			for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) +				{ +				v=sk_CONF_VALUE_value(attr_sk,i); +				if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype, +					(unsigned char *)v->value, -1)) return 0; +				} +			} +	return 1; +	} + + +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value, +	     int nid, int n_min, int n_max, unsigned long chtype, int mval) +	{ +	int i,ret=0; +	MS_STATIC char buf[1024]; +start: +	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); +	(void)BIO_flush(bio_err); +	if(value != NULL) +		{ +		BUF_strlcpy(buf,value,sizeof buf); +		BUF_strlcat(buf,"\n",sizeof buf); +		BIO_printf(bio_err,"%s\n",value); +		} +	else +		{ +		buf[0]='\0'; +		if (!batch) +			{ +			if (!fgets(buf,sizeof buf,stdin)) +				return 0; +			} +		else +			{ +			buf[0] = '\n'; +			buf[1] = '\0'; +			} +		} + +	if (buf[0] == '\0') return(0); +	else if (buf[0] == '\n') +		{ +		if ((def == NULL) || (def[0] == '\0')) +			return(1); +		BUF_strlcpy(buf,def,sizeof buf); +		BUF_strlcat(buf,"\n",sizeof buf); +		} +	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1); + +	i=strlen(buf); +	if (buf[i-1] != '\n') +		{ +		BIO_printf(bio_err,"weird input :-(\n"); +		return(0); +		} +	buf[--i]='\0'; +#ifdef CHARSET_EBCDIC +	ebcdic2ascii(buf, buf, i); +#endif +	if(!req_check_len(i, n_min, n_max)) goto start; +	if (!X509_NAME_add_entry_by_NID(n,nid, chtype, +				(unsigned char *) buf, -1,-1,mval)) goto err; +	ret=1; +err: +	return(ret); +	} + +static int add_attribute_object(X509_REQ *req, char *text, const char *def, +				char *value, int nid, int n_min, +				int n_max, unsigned long chtype) +	{ +	int i; +	static char buf[1024]; + +start: +	if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def); +	(void)BIO_flush(bio_err); +	if (value != NULL) +		{ +		BUF_strlcpy(buf,value,sizeof buf); +		BUF_strlcat(buf,"\n",sizeof buf); +		BIO_printf(bio_err,"%s\n",value); +		} +	else +		{ +		buf[0]='\0'; +		if (!batch) +			{ +			if (!fgets(buf,sizeof buf,stdin)) +				return 0; +			} +		else +			{ +			buf[0] = '\n'; +			buf[1] = '\0'; +			} +		} + +	if (buf[0] == '\0') return(0); +	else if (buf[0] == '\n') +		{ +		if ((def == NULL) || (def[0] == '\0')) +			return(1); +		BUF_strlcpy(buf,def,sizeof buf); +		BUF_strlcat(buf,"\n",sizeof buf); +		} +	else if ((buf[0] == '.') && (buf[1] == '\n')) return(1); + +	i=strlen(buf); +	if (buf[i-1] != '\n') +		{ +		BIO_printf(bio_err,"weird input :-(\n"); +		return(0); +		} +	buf[--i]='\0'; +#ifdef CHARSET_EBCDIC +	ebcdic2ascii(buf, buf, i); +#endif +	if(!req_check_len(i, n_min, n_max)) goto start; + +	if(!X509_REQ_add1_attr_by_NID(req, nid, chtype, +					(unsigned char *)buf, -1)) { +		BIO_printf(bio_err, "Error adding attribute\n"); +		ERR_print_errors(bio_err); +		goto err; +	} + +	return(1); +err: +	return(0); +	} + +static int req_check_len(int len, int n_min, int n_max) +	{ +	if ((n_min > 0) && (len < n_min)) +		{ +		BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min); +		return(0); +		} +	if ((n_max >= 0) && (len > n_max)) +		{ +		BIO_printf(bio_err,"string is too long, it needs to be less than  %d bytes long\n",n_max); +		return(0); +		} +	return(1); +	} + +/* Check if the end of a string matches 'end' */ +static int check_end(const char *str, const char *end) +{ +	int elen, slen;	 +	const char *tmp; +	elen = strlen(end); +	slen = strlen(str); +	if(elen > slen) return 1; +	tmp = str + slen - elen; +	return strcmp(tmp, end); +} + +static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type, +					long *pkeylen, char **palgnam, +					ENGINE *keygen_engine) +	{ +	EVP_PKEY_CTX *gctx = NULL; +	EVP_PKEY *param = NULL; +	long keylen = -1; +	BIO *pbio = NULL; +	const char *paramfile = NULL; + +	if (gstr == NULL) +		{ +		*pkey_type = EVP_PKEY_RSA; +		keylen = *pkeylen; +		} +	else if (gstr[0] >= '0' && gstr[0] <= '9') +		{ +		*pkey_type = EVP_PKEY_RSA; +		keylen = atol(gstr); +		*pkeylen = keylen; +		} +	else if (!strncmp(gstr, "param:", 6)) +		paramfile = gstr + 6; +	else +		{ +		const char *p = strchr(gstr, ':'); +		int len; +		ENGINE *tmpeng; +		const EVP_PKEY_ASN1_METHOD *ameth; + +		if (p) +			len = p - gstr; +		else +			len = strlen(gstr); +		/* The lookup of a the string will cover all engines so +		 * keep a note of the implementation. +		 */ + +		ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); + +		if (!ameth) +			{ +			BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr); +			return NULL; +			} + +		EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, +									ameth); +#ifndef OPENSSL_NO_ENGINE +		if (tmpeng) +			ENGINE_finish(tmpeng); +#endif +		if (*pkey_type == EVP_PKEY_RSA) +			{ +			if (p) +				{ +				keylen = atol(p + 1); +				*pkeylen = keylen; +				} +			} +		else if (p) +			paramfile = p + 1; +		} + +	if (paramfile) +		{ +		pbio = BIO_new_file(paramfile, "r"); +		if (!pbio) +			{ +			BIO_printf(err, "Can't open parameter file %s\n", +					paramfile); +			return NULL; +			} +		param = PEM_read_bio_Parameters(pbio, NULL); + +		if (!param) +			{ +			X509 *x; +			(void)BIO_reset(pbio); +			x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); +			if (x) +				{ +				param = X509_get_pubkey(x); +				X509_free(x); +				} +			} + +		BIO_free(pbio); + +		if (!param) +			{ +			BIO_printf(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"); +			EVP_PKEY_free(param); +			return NULL; +			} +		} + +	if (palgnam) +		{ +		const EVP_PKEY_ASN1_METHOD *ameth; +		ENGINE *tmpeng; +		const char *anam; +		ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); +		if (!ameth) +			{ +			BIO_puts(err, "Internal error: can't find key algorithm\n"); +			return NULL; +			} +		EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); +		*palgnam = BUF_strdup(anam); +#ifndef OPENSSL_NO_ENGINE +		if (tmpeng) +			ENGINE_finish(tmpeng); +#endif +		} + +	if (param) +		{ +		gctx = EVP_PKEY_CTX_new(param, keygen_engine); +		*pkeylen = EVP_PKEY_bits(param); +		EVP_PKEY_free(param); +		} +	else +		gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); + +	if (!gctx) +		{ +		BIO_puts(err, "Error allocating keygen context\n"); +		ERR_print_errors(err); +		return NULL; +		} + +	if (EVP_PKEY_keygen_init(gctx) <= 0) +		{ +		BIO_puts(err, "Error initializing keygen context\n"); +		ERR_print_errors(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); +			EVP_PKEY_CTX_free(gctx); +			return NULL; +			} +		} +#endif + +	return gctx; +	} + +static int genpkey_cb(EVP_PKEY_CTX *ctx) +	{ +	char c='*'; +	BIO *b = EVP_PKEY_CTX_get_app_data(ctx); +	int p; +	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); +	if (p == 0) c='.'; +	if (p == 1) c='+'; +	if (p == 2) c='*'; +	if (p == 3) c='\n'; +	BIO_write(b,&c,1); +	(void)BIO_flush(b); +#ifdef LINT +	p=n; +#endif +	return 1; +	} diff --git a/main/openssl/apps/req.pem b/main/openssl/apps/req.pem new file mode 100644 index 00000000..5537df60 --- /dev/null +++ b/main/openssl/apps/req.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBlzCCAVcCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMORXJp +YyB0aGUgWW91bmcwge8wgaYGBSsOAwIMMIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZ +S4J1PHvPrm9MXj5ntVheDPkdmBDTncyaGAJcMjwsyB/GvLDGd6yGCw/8eF+09wIV +AK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjg +tWiJc/tpvcuzeuAayH89UofjAGueKjXDADiRffvSdhrNw5dkqdqlA0QAAkEAtUSo +84OekjitKGVjxLu0HvXck29pu+foad53vPKXAsuJdACj88BPqZ91Y9PIJf1GUh38 +CuiHWi7z3cEDfZCyCKAAMAkGBSsOAwIbBQADLwAwLAIUTg8amKVBE9oqC5B75dDQ +Chy3LdQCFHKodGEj3LjuTzdm/RTe2KZL9Uzf +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/rsa.c b/main/openssl/apps/rsa.c new file mode 100644 index 00000000..a17708fe --- /dev/null +++ b/main/openssl/apps/rsa.c @@ -0,0 +1,450 @@ +/* apps/rsa.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_RSA +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#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 **); + +int MAIN(int argc, char **argv) +	{ +	ENGINE *e = NULL; +	int ret=1; +	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; + +	int pvk_encr = 2; + +	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) +			pubin=1; +		else if (strcmp(*argv,"-pubout") == 0) +			pubout=1; +		else if (strcmp(*argv,"-RSAPublicKey_in") == 0) +			pubin = 2; +		else if (strcmp(*argv,"-RSAPublicKey_out") == 0) +			pubout = 2; +		else if (strcmp(*argv,"-pvk-strong") == 0) +			pvk_encr=2; +		else if (strcmp(*argv,"-pvk-weak") == 0) +			pvk_encr=1; +		else if (strcmp(*argv,"-pvk-none") == 0) +			pvk_encr=0; +		else if (strcmp(*argv,"-noout") == 0) +			noout=1; +		else if (strcmp(*argv,"-text") == 0) +			text=1; +		else if (strcmp(*argv,"-modulus") == 0) +			modulus=1; +		else if (strcmp(*argv,"-check") == 0) +			check=1; +		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) +			{ +			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 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"); +#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)) { +		BIO_printf(bio_err, "Error getting passwords\n"); +		goto end; +	} + +	if(check && pubin) { +		BIO_printf(bio_err, "Only private keys can be checked\n"); +		goto end; +	} + +	out=BIO_new(BIO_s_file()); + +	{ +		EVP_PKEY	*pkey; + +		if (pubin) +			{ +			int tmpformat=-1; +			if (pubin == 2) +				{ +				if (informat == FORMAT_PEM) +					tmpformat = FORMAT_PEMRSA; +				else if (informat == FORMAT_ASN1) +					tmpformat = FORMAT_ASN1RSA; +				} +			else if (informat == FORMAT_NETSCAPE && sgckey) +				tmpformat = FORMAT_IISSGC; +			else +				tmpformat = informat; +					 +			pkey = load_pubkey(bio_err, 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"); + +		if (pkey != NULL) +			rsa = EVP_PKEY_get1_RSA(pkey); +		EVP_PKEY_free(pkey); +	} + +	if (rsa == 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 (text)  +		if (!RSA_print(out,rsa,0)) +			{ +			perror(outfile); +			ERR_print_errors(bio_err); +			goto end; +			} + +	if (modulus) +		{ +		BIO_printf(out,"Modulus="); +		BN_print(out,rsa->n); +		BIO_printf(out,"\n"); +		} + +	if (check) +		{ +		int r = RSA_check_key(rsa); + +		if (r == 1) +			BIO_printf(out,"RSA key ok\n"); +		else if (r == 0) +			{ +			unsigned long err; + +			while ((err = ERR_peek_error()) != 0 && +				ERR_GET_LIB(err) == ERR_LIB_RSA && +				ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && +				ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) +				{ +				BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); +				ERR_get_error(); /* remove e from error stack */ +				} +			} +		 +		if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */ +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} +		 +	if (noout) +		{ +		ret = 0; +		goto end; +		} +	BIO_printf(bio_err,"writing RSA key\n"); +	if 	(outformat == FORMAT_ASN1) { +		if(pubout || pubin)  +			{ +			if (pubout == 2) +				i=i2d_RSAPublicKey_bio(out,rsa); +			else +				i=i2d_RSA_PUBKEY_bio(out,rsa); +			} +		else i=i2d_RSAPrivateKey_bio(out,rsa); +	} +#ifndef OPENSSL_NO_RC4 +	else if (outformat == FORMAT_NETSCAPE) +		{ +		unsigned char *p,*pp; +		int size; + +		i=1; +		size=i2d_RSA_NET(rsa,NULL,NULL, sgckey); +		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); +		BIO_write(out,(char *)pp,size); +		OPENSSL_free(pp); +		} +#endif +	else if (outformat == FORMAT_PEM) { +		if(pubout || pubin) +			{ +			if (pubout == 2) +		    		i=PEM_write_bio_RSAPublicKey(out,rsa); +			else +		    		i=PEM_write_bio_RSA_PUBKEY(out,rsa); +			} +		else i=PEM_write_bio_RSAPrivateKey(out,rsa, +						enc,NULL,0,NULL,passout); +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) +	} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { +		EVP_PKEY *pk; +		pk = EVP_PKEY_new(); +		EVP_PKEY_set1_RSA(pk, rsa); +		if (outformat == FORMAT_PVK) +			i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); +		else if (pubin || pubout) +			i = i2b_PublicKey_bio(out, pk); +		else +			i = i2b_PrivateKey_bio(out, pk); +		EVP_PKEY_free(pk); +#endif +	} else	{ +		BIO_printf(bio_err,"bad output format specified for outfile\n"); +		goto end; +		} +	if (i <= 0) +		{ +		BIO_printf(bio_err,"unable to write key\n"); +		ERR_print_errors(bio_err); +		} +	else +		ret=0; +end: +	if(out != NULL) BIO_free_all(out); +	if(rsa != NULL) RSA_free(rsa); +	if(passin) OPENSSL_free(passin); +	if(passout) OPENSSL_free(passout); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/rsa8192.pem b/main/openssl/apps/rsa8192.pem new file mode 100644 index 00000000..946a6e54 --- /dev/null +++ b/main/openssl/apps/rsa8192.pem @@ -0,0 +1,101 @@ +-----BEGIN RSA PRIVATE KEY----- + +MIISKAIBAAKCBAEAiQ2f1X6Bte1DKD0OoCBKEikzPW+5w3oXk3WwnE97Wxzy6wJZ +ebbZC3CZKKBnJeBMrysPf+lK+9+fP6Vm8bp1wvbcSIA59BDrX6irFSuM/bdnkbuF +MFlDjt+uVrxwoyqfPi2IPot1HQg3l5mdyBqcTWvbOnU2L9HZxJfPUCjfzdTMPrMY +55/A20XL7tlV2opEfwhy3uVlveQBM0DnZ3MUQfrk+lRRNWv7yE4ScbOfER9fjvOm +yJc3ZbOa3e+AMGGU9OqJ/fyOl0SGYyP2k23omy/idBV4uOs8QWdnAvq8UOzDdua3 +tuf5Tn17XBurPJ8juwyPBNispkwwn8BjxAZVPhwUIcxFBg339IxJ9cW0WdVy4nNA +LWo/8Ahlf+kZNnFNGCPFytU9gGMLMhab9w/rLrwa9qNe4L8Fmu1JxONn1WfhMOKE +aFmycf2olJsYLgUIGYZrjnYu0p/7P3yhTOv8JIhmK+SzmA/I0xiQoF84rpaQzH2d +PvxICOA9oQSowou0gLuBSZWm6LiXirg1DZCziU46v33ErQlWM1dSyNaUSzihcV59 +mVD0nmzboXH75lGiyiZlp8cLbozzoCwvk9rYqpUGSBzbAy0ECCpabGpzO2Ug+oDi +71e5z4WMpeoR4IS8MaOG/GsJnwaXhiB/gNYfK+8pRADVk5StEAZDE2alSuCbDs0z +d9zYr4/em5T9VZsLetxRE7pm/Es9yELuViz8/Tm0/8MVdmNYc/xZU1t6qYYFdyQ2 +wlGDTiNPsjR8yXCkmBjKwqnuleu1X6LaZu3VPhEkXGcyFAquQUkSiMv0Yu74qAe0 +bQ2v+jjZzP6AM9LUo89cW4Kd8SGD96BdNlAVPNMXoBcIOsZBwsOtETBd4KAyvkXE +Ob17u+PLl4UPnSxm9ypKZunUNFRPxtKUyjySYnvlGL+kTjAXrIrZwKJqIn0uhnfa +Ck3o7bU6yVMK22ODxy2/Vi3E0P6k5JLwnrF0VIOBqGhts66qo6mWDP8l6MZHARFd +pU+nofssVmr8tLKmMmjYGMM5GmKIXRNBs0ksTwFnKRs9AmpE5owC8tTSVdTAkGuS +os7QwLvyvNzq7BGJiVr0Iy3Dhsl1vzR35acNOrCsDl3DcCQONKJ2sVXV4pD3dBah +mG3sR/jHgjasffJJ35uiGoAua9dbT7HG/+D0z1SHYaVqH8zO4VZSOnGJh/P9rtxx +cckFDbiag/JMWig2lbnCjebTtp/BcUsK3TNaDOb7vb0LvbAeRJadd1EFu6PSlH3K +LykSUPm4UedvUU3cWjqkSY5lITFJkVaIYOv/EljYtK7p7kFZFTaEwMAWxgsXU3pQ +tTzVmq1gZ4vXPwcUq0zK50Frq0F7SQc21ZsunwIDAQABAoIEADuQAkDEpBausJsS +PgL1RXuzECPJJJCBxTE+2qx0FoY4hJICCWTORHGmU8nGPE3Ht0wBiNDsULw6KXl9 +psmzYW6D3qRbpdQebky6fu/KZ5H0XTyGpJGomaXELH5hkwo2gdKB805LSXB+m7p0 +9o96kSdMkpBLVGtf5iZ8W4rY2LsZmlI9f7taQHSLVt/M8HTz1mTnBRU92QO3zZW6 +xVa+OrWaFl18u3ZeIaSh2X40tBK68cqstXVD0r2OWuXNKobcQeJW8/XABzBShZ0c +ihL0lzyqiN4uXrLu+Nbr22b+FU2OODy6dGk3U6/69NvI4piMCPlHsfhHOnFjd1ZW +RIVywyUlCtLNdcn11CchuRro+0J3c2Ba+i9Cl9r3qzT11xFEGF8/XLyUBBCB+uGf +1dR/xJQhCA7cXWWLXyI/semxcvTaGpImP6kiIl1MAjHjXZTSdvyw4JmfXyYGhSjI +P0mw3Xn7FXxJ/os9gOfNKz2nZHjr0q4sgWRYO+4vllkeL0GteZrg4oVaVpmZb7LH +77afhodLylhijlEtV5skfkPujbBLQk6E5Ez3U/huEt2NLg6guADmwxMxfBRliZO4 +4Ex/td4cuggpEj3FGJV74qRvdvj/MF/uF7IxC/3WapPIsFBFH4zrJsUYt6u3L68I +/KC/bfioDeUR/8ANw1DNh+UsnPV3GJIwDkIJKdppi2uXPahJyJQQ8Inps53nn8Gg +GifS+HnOXNgMoKOJnZ9IDGjXpfjIs8dJNrGfDHF0mH30N2WARq2v/a3cNUC+f8Bq +HSKQ9YrZopktMunsut8u7ZYbTmjIqJpXCaM0CCrSlzSMTDHFSj2tzLk6+qnxeGxB +ZwIdShbdeK+0ETG91lE1e9RPQs/uXQP9+uCHJV0YpqQcA6pkCLYJfYpoSMu/Bafy +AgfVZz6l5tyEnV0wCcbopsQShc1k9xtTbYNF1h9AQHknj6zeDW4iZMvmVeh3RovT +52OA2R8oLyauF+QaG6x2wUjEx13SJlaBarJZ4seZIOJ+a8+oNzKsbgokXc2cyC9p +5FAZz1OsOb68o93qD1Xvl7bY97fq2q55L7G1XHPPLtZE5lGiLGDtnAuwY8UPrdpr +7Mv2yIxB7xVGurXyHb5PvusR88XED6HMPfLBG/55ENHTal7G5mRix+IWSBAIkxA5 +KZ0j8r5Ng4+wELZhqFQai39799bIAyiV6CEz4kyDXlo0kSSexp8o4iz5sPq5vp6h +cCb7rdRw7uRnbXrHmXahxoB+ibXaurgV/6B2yurrU/UFoxEp2sHp8LXZGfF6ztY1 +dMhSQAACK2vGy5yNagbkTHLgVaHicG5zavJBqzCE+lbPlCqhOUQPdOIwvjHNjdS/ +DL3WV/ECggIBAMbW65wPk/i43nSyeZeYwcHtR1SUJqDXavYfBPC0VRhKz+7DVMFw +Nwnocn6gITABc445W1yl7U3uww+LGuDlSlFnd8WuiXpVYud9/jeNu6Mu4wvNsnWr +f4f4ua8CcS03GmqmcbROD2Z6by1AblCZ2UL1kv9cUX1FLVjPP1ESAGKoePt3BmZQ +J1uJfK8HilNT8dcUlj/5CBi2uHxttDhoG0sxXE/SVsG9OD/Pjme0mj7gdzc6Ztd+ +TALuvpNQR4pRzfo5XWDZBcEYntcEE3PxYJB1+vnZ8509ew5/yLHTbLjFxIcx71zY +fhH0gM36Sz7mz37r0+E/QkRkc5bVIDC4LDnWmjpAde6QUx0d218ShNx6sJo4kt5c +Dd7tEVx8nuX8AIZYgwsOb382anLyFRkkmEdK3gRvwQ6SWR36Ez5L7/mHWODpLAX5 +mVBKSG4/ccFbc633/g0xHw0Nwajir/klckdakuYPlwF0yAxJSKDLhmNctDhRmxjC +YP+fISkl5oTvFRzJH6HEyNu8M3ybRvmpPIjM5J5JpnB2IYbohYBR+T6/97C1DKrd +mzL5PjlrWm0c1/d7LlDoP65fOShDMmj2zCiBAHHOM0Alokx+v5LmMd8NJumZIwGJ +Rt5OpeMOhowz6j1AjYxYgV7PmJL6Ovpfb775od/aLaUbbwHz2uWIvfF7AoICAQCw +c7NaO7oJVLJClhYw6OCvjT6oqtgNVWaennnDiJgzY9lv5HEgV0MAG0eYuB3hvj+w +Y1P9DJxP1D+R+cshYrAFg8yU/3kaYVNI0Bl3ygX0eW1b/0HZTdocs+8kM/9PZQDR +WrKQoU5lHvqRt99dXlD4NWGI2YQtzdZ8iet9QLqnjwRZabgE96mF01qKisMnFcsh +KjT7ieheU4J15TZj/mdZRNK126d7e3q/rNj73e5EJ9tkYLcolSr4gpknUMJULSEi +JH1/Qx7C/mTAMRsN5SkOthnGq0djCNWfPv/3JV0H67Uf5krFlnwLebrgfTYoPPdo +yO7iBUNJzv6Qh22malLp4P8gzACkD7DGlSTnoB5cLwcjmDGg+i9WrUBbOiVTeQfZ +kOj1o+Tz35ndpq/DDUVlqliB9krcxva+QHeJPH53EGI+YVg1nD+s/vUDZ3mQMGX9 +DQou2L8uU6RnWNv/BihGcL8QvS4Ty6QyPOUPpD3zc70JQAEcQk9BxQNaELgJX0IN +22cYn22tYvElew9G41OpDqzBRcfbdJmKXQ2HcroShutYJQRGUpAXHk24fy6JVkIU +ojF5U6cwextMja1ZIIZgh9eugIRUeIE7319nQNDzuXWjRCcoBLA25P7wnpHWDRpz +D9ovXCIvdja74lL5psqobV6L5+fbLPkSgXoImKR0LQKCAgAIC9Jk8kxumCyIVGCP +PeM5Uby9M3GMuKrfYsn0Y5e97+kSJF1dpojTodBgR2KQar6eVrvXt+8uZCcIjfx8 +dUrYmHNEUJfHl4T1ESgkX1vkcpVFeQFruZDjk7EP3+1sgvpSroGTZkVBRFsTXbQZ +FuCv0Pgt1TKG+zGmklxhj3TsiRy8MEjWAxBUp++ftZJnZNI4feDGnfEx7tLwVhAg +6DWSiWDO6hgQpvOLwX5lu+0x9itc1MQsnDO/OqIDnBAJDN5k7cVVkfKlqbVjxgpz +eqUJs3yAd81f44kDQTCB4ahYocgeIGsrOqd/WoGL1EEPPo/O9wQP7VtlIRt8UwuG +bS18+a4sBUfAa56xYu/pnPo7YcubsgZfcSIujzFQqMpVTClJRnOnEuJ4J1+PXzRz +XAO9fs4VJ+CMEmgAyonUz4Xadxulnknlw//sO9VKgM69oFHCDHL/XamAAbqAdwvf +7R/+uy+Ol7romC0wMhb6SsIZazrvvH2mNtduAKZ638nAP1x/WbQp+6iVG7yJok7w +82Q7tO7baOePTXh12Rrt4mNPor0HLYxhra4GFgfqkumJ2Mz0esuZAozxJXFOq8ly +beo9CVtXP5zbT6qNpeNismX6PLICaev8t+1iOZSE56WSLtefuuj/cOVrTMNDz1Rr +pUkEVV2zjUSjlcScM538A9iL2QKCAgBLbBk0r6T0ihRsK9UucMxhnYEz/Vq+UEu9 +70Vi1AciqEJv9nh4d3Q3HnH7EHANZxG4Jqzm1DYYVUQa9GfkTFeq88xFv/GW2hUM +YY8RSfRDrIeXNEOETCe37x2AHw25dRXlZtw+wARPau91y9+Y/FCl18NqCHfcUEin +ERjsf/eI2bPlODAlR2tZvZ7M60VBdqpN8cmV3zvI3e88z43xLfQlDyr1+v7a5Evy +lEJnXlSTI2o+vKxtl103vjMSwA1gh63K90gBVsJWXQDZueOzi8mB9UqNRfcMmOEe +4YHttTXPxeu0x+4cCRfam9zKShsVFgI28vRQ/ijl6qmbQ5gV8wqf18GV1j1L4z0P +lP6iVynDA4MMrug/w9DqPsHsfK0pwekeETfSj4y0xVXyjWZBfHG2ZBrS6mDTf+RG +LC4sJgR0hjdILLnUqIX7PzuhieBHRrjBcopwvcryVWRHnI7kslAS0+yHjiWc5oW3 +x5mtlum4HzelNYuD9cAE/95P6CeSMfp9CyIE/KSX4VvsRm6gQVkoQRKMxnQIFQ3w +O5gl1l88vhjoo2HxYScgCp70BsDwiUNTqIR3NM+ZBHYFweVf3Gwz5LzHZT2rEZtD +6VXRP75Q/2wOLnqCO4bK4BUs6sqxcQZmOldruPkPynrY0oPfHHExjxZDvQu4/r80 +Ls3n0L8yvQKCAgEAnYWS6EikwaQNpJEfiUnOlglgFz4EE1eVkrDbBY4J3oPU+doz +DrqmsvgpSZIAfd2MUbkN4pOMsMTjbeIYWDnZDa1RoctKs3FhwFPHwAjQpznab4mn +Bp81FMHM40qyb0NaNuFRwghdXvoQvBBX1p8oEnFzDRvTiuS/vTPTA8KDY8IeRp8R +oGzKHpfziNwq/URpqj7pwi9odNjGZvR2IwYw9jCLPIqaEbMoSOdI0mg4MoYyqP4q +nm7d4wqSDwrYxiXZ6f3nYpkhEY1lb0Wbksp1ig8sKSF4nDZRGK1RSfE+6gjBp94H +X/Wog6Zb6NC9ZpusTiDLvuIUXcyUJvmHiWjSNqiTv8jurlwEsgSwhziEQfqLrtdV +QI3PRMolBkD1iCk+HFE53r05LMf1bp3r4MS+naaQrLbIrl1kgDNGwVdgS+SCM7Bg +TwEgE67iOb2iIoUpon/NyP4LesMzvdpsu2JFlfz13PmmQ34mFI7tWvOb3NA5DP3c +46C6SaWI0TD9B11nJbHGTYN3Si9n0EBgoDJEXUKeh3km9O47dgvkSug4WzhYsvrE +rMlMLtKfp2w8HlMZpsUlToNCx6CI+tJrohzcs3BAVAbjFAXRKWGijB1rxwyDdHPv +I+/wJTNaRNPQ1M0SwtEL/zJd21y3KSPn4eL+GP3efhlDSjtlDvZqkdAUsU8= +-----END RSA PRIVATE KEY----- + diff --git a/main/openssl/apps/rsautl.c b/main/openssl/apps/rsautl.c new file mode 100644 index 00000000..b01f004e --- /dev/null +++ b/main/openssl/apps/rsautl.c @@ -0,0 +1,351 @@ +/* rsautl.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <openssl/opensslconf.h> +#ifndef OPENSSL_NO_RSA + +#include "apps.h" +#include <string.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/rsa.h> + +#define RSA_SIGN 	1 +#define RSA_VERIFY 	2 +#define RSA_ENCRYPT 	3 +#define RSA_DECRYPT 	4 + +#define KEY_PRIVKEY	1 +#define KEY_PUBKEY	2 +#define KEY_CERT	3 + +static void usage(void); + +#undef PROG + +#define PROG rsautl_main + +int MAIN(int argc, char **); + +int 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; +	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")) asn1parse = 1; +		else if(!strcmp(*argv, "-hexdump")) hexdump = 1; +		else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; +		else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; +		else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; +		else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; +		else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING; +		else if(!strcmp(*argv, "-sign")) { +			rsa_mode = RSA_SIGN; +			need_priv = 1; +		} else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; +		else if(!strcmp(*argv, "-rev")) rev = 1; +		else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; +		else if(!strcmp(*argv, "-decrypt")) { +			rsa_mode = RSA_DECRYPT; +			need_priv = 1; +		} else badarg = 1; +		if(badarg) { +			usage(); +			goto end; +		} +		argc--; +		argv++; +	} + +	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); +#endif +	if(!app_passwd(bio_err, passargin, 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); +	 +	switch(key_type) { +		case KEY_PRIVKEY: +		pkey = load_key(bio_err, keyfile, keyform, 0, +			passin, e, "Private Key"); +		break; + +		case KEY_PUBKEY: +		pkey = load_pubkey(bio_err, keyfile, keyform, 0, +			NULL, e, "Public Key"); +		break; + +		case KEY_CERT: +		x = load_cert(bio_err, keyfile, keyform, +			NULL, e, "Certificate"); +		if(x) { +			pkey = X509_get_pubkey(x); +			X509_free(x); +		} +		break; +	} + +	if(!pkey) { +		return 1; +	} + +	rsa = EVP_PKEY_get1_RSA(pkey); +	EVP_PKEY_free(pkey); + +	if(!rsa) { +		BIO_printf(bio_err, "Error getting RSA key\n"); +		ERR_print_errors(bio_err); +		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 +	} + +	keysize = RSA_size(rsa); + +	rsa_in = OPENSSL_malloc(keysize * 2); +	rsa_out = OPENSSL_malloc(keysize); + +	/* Read the input data */ +	rsa_inlen = BIO_read(in, rsa_in, keysize * 2); +	if(rsa_inlen <= 0) { +		BIO_printf(bio_err, "Error reading input Data\n"); +		exit(1); +	} +	if(rev) { +		int i; +		unsigned char ctmp; +		for(i = 0; i < rsa_inlen/2; i++) { +			ctmp = rsa_in[i]; +			rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; +			rsa_in[rsa_inlen - 1 - i] = ctmp; +		} +	} +	switch(rsa_mode) { + +		case RSA_VERIFY: +			rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); +		break; + +		case RSA_SIGN: +			rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); +		break; + +		case RSA_ENCRYPT: +			rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); +		break; + +		case RSA_DECRYPT: +			rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); +		break; + +	} + +	if(rsa_outlen <= 0) { +		BIO_printf(bio_err, "RSA operation error\n"); +		ERR_print_errors(bio_err); +		goto end; +	} +	ret = 0; +	if(asn1parse) { +		if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { +			ERR_print_errors(bio_err); +		} +	} else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); +	else BIO_write(out, rsa_out, rsa_outlen); +	end: +	RSA_free(rsa); +	BIO_free(in); +	BIO_free_all(out); +	if(rsa_in) OPENSSL_free(rsa_in); +	if(rsa_out) OPENSSL_free(rsa_out); +	if(passin) OPENSSL_free(passin); +	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 +static void *dummy=&dummy; +# endif + +#endif diff --git a/main/openssl/apps/s1024key.pem b/main/openssl/apps/s1024key.pem new file mode 100644 index 00000000..19e04035 --- /dev/null +++ b/main/openssl/apps/s1024key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV +S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP +pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB +AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0 +dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY +bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E +Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq +zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM +6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf +QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD +dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M +0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv +nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA== +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/s1024req.pem b/main/openssl/apps/s1024req.pem new file mode 100644 index 00000000..bb75e7ee --- /dev/null +++ b/main/openssl/apps/s1024req.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBojCCAQsCAQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx +GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSQwIgYDVQQDExtTZXJ2ZXIgdGVz +dCBjZXJ0ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALMR +9TwT5kZMa0ddXleG8zYuDfZ9dQiPJ1dvfgEZU9fqg3v5o1VL15ZrK9b/73+9RvRo +KqKUmukV6yAi1XZPxWGGM4T75dTPjq42lwxTvAcwQBdS58+nO2kWbxkSTa0Uq9p2 +RJKg3yVvXWO69lWRKQ+UHrmkWFJ7hApKnongeuRjAgMBAAEwDQYJKoZIhvcNAQEE +BQADgYEAStHlk4pBbwiNeQ2/PKTPPXzITYC8Gn0XMbrU94e/6JIKiO7aArq9Espq +nrBSvC14dHcNl6NNvnkEKdQ7hAkcACfBbnOXA/oQvMBd4GD78cH3k0jVDoVUEjil +frLfWlckW6WzpTktt0ZPDdAjJCmKVh0ABHimi7Bo9FC3wIGIe5M= +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/s512-key.pem b/main/openssl/apps/s512-key.pem new file mode 100644 index 00000000..0e3ff2d3 --- /dev/null +++ b/main/openssl/apps/s512-key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD +TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu +OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj +gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz +rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b +PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA +vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU= +-----END RSA PRIVATE KEY----- diff --git a/main/openssl/apps/s512-req.pem b/main/openssl/apps/s512-req.pem new file mode 100644 index 00000000..ea314be5 --- /dev/null +++ b/main/openssl/apps/s512-req.pem @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBGzCBxgIBADBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEa +MBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0 +IGNlcnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8S +MVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8E +y2//Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAANBAAB+uQi+qwn6qRSHB8EUTvsm +5TNTHzYDeN39nyIbZNX2s0se3Srn2Bxft5YCwD3moFZ9QoyDHxE0h6qLX5yjD+8= +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/s_apps.h b/main/openssl/apps/s_apps.h new file mode 100644 index 00000000..820e5c58 --- /dev/null +++ b/main/openssl/apps/s_apps.h @@ -0,0 +1,176 @@ +/* apps/s_apps.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */ +#include <sys/types.h> +#endif +#include <openssl/opensslconf.h> + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) +#include <conio.h> +#endif + +#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) +#define _kbhit kbhit +#endif + +#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET) +/* VAX C does not defined fd_set and friends, but it's actually quite simple */ +/* These definitions are borrowed from SOCKETSHR.	/Richard Levitte */ +#define MAX_NOFILE	32 +#define	NBBY		 8		/* number of bits in a byte	*/ + +#ifndef	FD_SETSIZE +#define	FD_SETSIZE	MAX_NOFILE +#endif	/* FD_SETSIZE */ + +/* How many things we'll allow select to use. 0 if unlimited */ +#define MAXSELFD	MAX_NOFILE +typedef int	fd_mask;	/* int here! VMS prototypes int, not long */ +#define NFDBITS	(sizeof(fd_mask) * NBBY)	/* bits per mask (power of 2!)*/ +#define NFDSHIFT 5				/* Shift based on above */ + +typedef fd_mask fd_set; +#define	FD_SET(n, p)	(*(p) |= (1 << ((n) % NFDBITS))) +#define	FD_CLR(n, p)	(*(p) &= ~(1 << ((n) % NFDBITS))) +#define	FD_ISSET(n, p)	(*(p) & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p)	memset((char *)(p), 0, sizeof(*(p))) +#endif + +#define PORT            4433 +#define PORT_STR        "4433" +#define PROTOCOL        "tcp" + +int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); +#ifdef HEADER_X509_H +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); +#endif +#ifdef HEADER_SSL_H +int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); +int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); +#endif +int init_client(int *sock, char *server, int port, int type); +int should_retry(int i); +int extract_port(char *str, short *port_ptr); +int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); + +long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, +				   int argi, long argl, long ret); + +#ifdef HEADER_SSL_H +void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret); +void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, +					unsigned char *data, int len, +					void *arg); +#endif + +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len); +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len); diff --git a/main/openssl/apps/s_cb.c b/main/openssl/apps/s_cb.c new file mode 100644 index 00000000..c4f55122 --- /dev/null +++ b/main/openssl/apps/s_cb.c @@ -0,0 +1,862 @@ +/* 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. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <stdlib.h> +#define USE_SOCKETS +#define NON_MAIN +#include "apps.h" +#undef NON_MAIN +#undef USE_SOCKETS +#include <openssl/err.h> +#include <openssl/rand.h> +#include <openssl/x509.h> +#include <openssl/ssl.h> +#include "s_apps.h" + +#define	COOKIE_SECRET_LENGTH	16 + +int verify_depth=0; +int verify_error=X509_V_OK; +int verify_return_error=0; +unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; +int cookie_initialized=0; + +int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) +	{ +	X509 *err_cert; +	int err,depth; + +	err_cert=X509_STORE_CTX_get_current_cert(ctx); +	err=	X509_STORE_CTX_get_error(ctx); +	depth=	X509_STORE_CTX_get_error_depth(ctx); + +	BIO_printf(bio_err,"depth=%d ",depth); +	if (err_cert) +		{ +		X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), +					0, XN_FLAG_ONELINE); +		BIO_puts(bio_err, "\n"); +		} +	else +		BIO_puts(bio_err, "<no cert>\n"); +	if (!ok) +		{ +		BIO_printf(bio_err,"verify error:num=%d:%s\n",err, +			X509_verify_cert_error_string(err)); +		if (verify_depth >= depth) +			{ +			if (!verify_return_error) +				ok=1; +			verify_error=X509_V_OK; +			} +		else +			{ +			ok=0; +			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; +			} +		} +	switch (err) +		{ +	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: +		BIO_puts(bio_err,"issuer= "); +		X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), +					0, XN_FLAG_ONELINE); +		BIO_puts(bio_err, "\n"); +		break; +	case X509_V_ERR_CERT_NOT_YET_VALID: +	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: +		BIO_printf(bio_err,"notBefore="); +		ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); +		BIO_printf(bio_err,"\n"); +		break; +	case X509_V_ERR_CERT_HAS_EXPIRED: +	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: +		BIO_printf(bio_err,"notAfter="); +		ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); +		BIO_printf(bio_err,"\n"); +		break; +	case X509_V_ERR_NO_EXPLICIT_POLICY: +		policies_print(bio_err, ctx); +		break; +		} +	if (err == X509_V_OK && ok == 2) +		policies_print(bio_err, ctx); + +	BIO_printf(bio_err,"verify return:%d\n",ok); +	return(ok); +	} + +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",cert_file); +			ERR_print_errors(bio_err); +			return(0); +			} +		if (key_file == NULL) key_file=cert_file; +		if (SSL_CTX_use_PrivateKey_file(ctx,key_file, +			SSL_FILETYPE_PEM) <= 0) +			{ +			BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file); +			ERR_print_errors(bio_err); +			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 */ +		 +		 +		/* Now we know that a key and cert have been set against +		 * the SSL context */ +		if (!SSL_CTX_check_private_key(ctx)) +			{ +			BIO_printf(bio_err,"Private key does not match the certificate public key\n"); +			return(0); +			} +		} +	return(1); +	} + +int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) +	{ +	if (cert ==  NULL) +		return 1; +	if (SSL_CTX_use_certificate(ctx,cert) <= 0) +		{ +		BIO_printf(bio_err,"error setting certificate\n"); +		ERR_print_errors(bio_err); +		return 0; +		} +	if (SSL_CTX_use_PrivateKey(ctx,key) <= 0) +		{ +		BIO_printf(bio_err,"error setting private key\n"); +		ERR_print_errors(bio_err); +		return 0; +		} + +		 +		/* Now we know that a key and cert have been set against +		 * the SSL context */ +	if (!SSL_CTX_check_private_key(ctx)) +		{ +		BIO_printf(bio_err,"Private key does not match the certificate public key\n"); +		return 0; +		} +	return 1; +	} + +long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, +				   int argi, long argl, long ret) +	{ +	BIO *out; + +	out=(BIO *)BIO_get_callback_arg(bio); +	if (out == NULL) return(ret); + +	if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) +		{ +		BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n", + 			(void *)bio,argp,(unsigned long)argi,ret,ret); +		BIO_dump(out,argp,(int)ret); +		return(ret); +		} +	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) +		{ +		BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n", +			(void *)bio,argp,(unsigned long)argi,ret,ret); +		BIO_dump(out,argp,(int)ret); +		} +	return(ret); +	} + +void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) +	{ +	const char *str; +	int w; + +	w=where& ~SSL_ST_MASK; + +	if (w & SSL_ST_CONNECT) str="SSL_connect"; +	else if (w & SSL_ST_ACCEPT) str="SSL_accept"; +	else str="undefined"; + +	if (where & SSL_CB_LOOP) +		{ +		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s)); +		} +	else if (where & SSL_CB_ALERT) +		{ +		str=(where & SSL_CB_READ)?"read":"write"; +		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n", +			str, +			SSL_alert_type_string_long(ret), +			SSL_alert_desc_string_long(ret)); +		} +	else if (where & SSL_CB_EXIT) +		{ +		if (ret == 0) +			BIO_printf(bio_err,"%s:failed in %s\n", +				str,SSL_state_string_long(s)); +		else if (ret < 0) +			{ +			BIO_printf(bio_err,"%s:error in %s\n", +				str,SSL_state_string_long(s)); +			} +		} +	} + + +void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) +	{ +	BIO *bio = arg; +	const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= ""; +	 +	str_write_p = write_p ? ">>>" : "<<<"; + +	switch (version) +		{ +	case SSL2_VERSION: +		str_version = "SSL 2.0"; +		break; +	case SSL3_VERSION: +		str_version = "SSL 3.0 "; +		break; +	case TLS1_VERSION: +		str_version = "TLS 1.0 "; +		break; +	case DTLS1_VERSION: +		str_version = "DTLS 1.0 "; +		break; +	case DTLS1_BAD_VER: +		str_version = "DTLS 1.0 (bad) "; +		break; +	default: +		str_version = "???"; +		} + +	if (version == SSL2_VERSION) +		{ +		str_details1 = "???"; + +		if (len > 0) +			{ +			switch (((const unsigned char*)buf)[0]) +				{ +				case 0: +					str_details1 = ", ERROR:"; +					str_details2 = " ???"; +					if (len >= 3) +						{ +						unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2]; +						 +						switch (err) +							{ +						case 0x0001: +							str_details2 = " NO-CIPHER-ERROR"; +							break; +						case 0x0002: +							str_details2 = " NO-CERTIFICATE-ERROR"; +							break; +						case 0x0004: +							str_details2 = " BAD-CERTIFICATE-ERROR"; +							break; +						case 0x0006: +							str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; +							break; +							} +						} + +					break; +				case 1: +					str_details1 = ", CLIENT-HELLO"; +					break; +				case 2: +					str_details1 = ", CLIENT-MASTER-KEY"; +					break; +				case 3: +					str_details1 = ", CLIENT-FINISHED"; +					break; +				case 4: +					str_details1 = ", SERVER-HELLO"; +					break; +				case 5: +					str_details1 = ", SERVER-VERIFY"; +					break; +				case 6: +					str_details1 = ", SERVER-FINISHED"; +					break; +				case 7: +					str_details1 = ", REQUEST-CERTIFICATE"; +					break; +				case 8: +					str_details1 = ", CLIENT-CERTIFICATE"; +					break; +				} +			} +		} + +	if (version == SSL3_VERSION || +	    version == TLS1_VERSION || +	    version == DTLS1_VERSION || +	    version == DTLS1_BAD_VER) +		{ +		switch (content_type) +			{ +		case 20: +			str_content_type = "ChangeCipherSpec"; +			break; +		case 21: +			str_content_type = "Alert"; +			break; +		case 22: +			str_content_type = "Handshake"; +			break; +			} + +		if (content_type == 21) /* Alert */ +			{ +			str_details1 = ", ???"; +			 +			if (len == 2) +				{ +				switch (((const unsigned char*)buf)[0]) +					{ +				case 1: +					str_details1 = ", warning"; +					break; +				case 2: +					str_details1 = ", fatal"; +					break; +					} + +				str_details2 = " ???"; +				switch (((const unsigned char*)buf)[1]) +					{ +				case 0: +					str_details2 = " close_notify"; +					break; +				case 10: +					str_details2 = " unexpected_message"; +					break; +				case 20: +					str_details2 = " bad_record_mac"; +					break; +				case 21: +					str_details2 = " decryption_failed"; +					break; +				case 22: +					str_details2 = " record_overflow"; +					break; +				case 30: +					str_details2 = " decompression_failure"; +					break; +				case 40: +					str_details2 = " handshake_failure"; +					break; +				case 42: +					str_details2 = " bad_certificate"; +					break; +				case 43: +					str_details2 = " unsupported_certificate"; +					break; +				case 44: +					str_details2 = " certificate_revoked"; +					break; +				case 45: +					str_details2 = " certificate_expired"; +					break; +				case 46: +					str_details2 = " certificate_unknown"; +					break; +				case 47: +					str_details2 = " illegal_parameter"; +					break; +				case 48: +					str_details2 = " unknown_ca"; +					break; +				case 49: +					str_details2 = " access_denied"; +					break; +				case 50: +					str_details2 = " decode_error"; +					break; +				case 51: +					str_details2 = " decrypt_error"; +					break; +				case 60: +					str_details2 = " export_restriction"; +					break; +				case 70: +					str_details2 = " protocol_version"; +					break; +				case 71: +					str_details2 = " insufficient_security"; +					break; +				case 80: +					str_details2 = " internal_error"; +					break; +				case 90: +					str_details2 = " user_canceled"; +					break; +				case 100: +					str_details2 = " no_renegotiation"; +					break; +				case 110: +					str_details2 = " unsupported_extension"; +					break; +				case 111: +					str_details2 = " certificate_unobtainable"; +					break; +				case 112: +					str_details2 = " unrecognized_name"; +					break; +				case 113: +					str_details2 = " bad_certificate_status_response"; +					break; +				case 114: +					str_details2 = " bad_certificate_hash_value"; +					break; +					} +				} +			} +		 +		if (content_type == 22) /* Handshake */ +			{ +			str_details1 = "???"; + +			if (len > 0) +				{ +				switch (((const unsigned char*)buf)[0]) +					{ +				case 0: +					str_details1 = ", HelloRequest"; +					break; +				case 1: +					str_details1 = ", ClientHello"; +					break; +				case 2: +					str_details1 = ", ServerHello"; +					break; +				case 3: +					str_details1 = ", HelloVerifyRequest"; +					break; +				case 11: +					str_details1 = ", Certificate"; +					break; +				case 12: +					str_details1 = ", ServerKeyExchange"; +					break; +				case 13: +					str_details1 = ", CertificateRequest"; +					break; +				case 14: +					str_details1 = ", ServerHelloDone"; +					break; +				case 15: +					str_details1 = ", CertificateVerify"; +					break; +				case 16: +					str_details1 = ", ClientKeyExchange"; +					break; +				case 20: +					str_details1 = ", Finished"; +					break; +					} +				} +			} +		} + +	BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, str_content_type, (unsigned long)len, str_details1, str_details2); + +	if (len > 0) +		{ +		size_t num, i; +		 +		BIO_printf(bio, "   "); +		num = len; +#if 0 +		if (num > 16) +			num = 16; +#endif +		for (i = 0; i < num; i++) +			{ +			if (i % 16 == 0 && i > 0) +				BIO_printf(bio, "\n   "); +			BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]); +			} +		if (i < len) +			BIO_printf(bio, " ..."); +		BIO_printf(bio, "\n"); +		} +	(void)BIO_flush(bio); +	} + +void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, +					unsigned char *data, int len, +					void *arg) +	{ +	BIO *bio = arg; +	char *extname; + +	switch(type) +		{ +		case TLSEXT_TYPE_server_name: +		extname = "server name"; +		break; + +		case TLSEXT_TYPE_max_fragment_length: +		extname = "max fragment length"; +		break; + +		case TLSEXT_TYPE_client_certificate_url: +		extname = "client certificate URL"; +		break; + +		case TLSEXT_TYPE_trusted_ca_keys: +		extname = "trusted CA keys"; +		break; + +		case TLSEXT_TYPE_truncated_hmac: +		extname = "truncated HMAC"; +		break; + +		case TLSEXT_TYPE_status_request: +		extname = "status request"; +		break; + +		case TLSEXT_TYPE_elliptic_curves: +		extname = "elliptic curves"; +		break; + +		case TLSEXT_TYPE_ec_point_formats: +		extname = "EC point formats"; +		break; + +		case TLSEXT_TYPE_session_ticket: +		extname = "server ticket"; +		break; + +		case TLSEXT_TYPE_renegotiate: +		extname = "renegotiate"; +		break; + +#ifdef TLSEXT_TYPE_opaque_prf_input +		case TLSEXT_TYPE_opaque_prf_input: +		extname = "opaque PRF input"; +		break; +#endif + +		default: +		extname = "unknown"; +		break; + +		} +	 +	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", +			client_server ? "server": "client", +			extname, type, len); +	BIO_dump(bio, (char *)data, len); +	(void)BIO_flush(bio); +	} + +int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) +	{ +	unsigned char *buffer, result[EVP_MAX_MD_SIZE]; +	unsigned int length, resultlength; +	union { +		struct sockaddr sa; +		struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 +		struct sockaddr_in6 s6; +#endif +	} peer; + +	/* Initialize a random secret */ +	if (!cookie_initialized) +		{ +		if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) +			{ +			BIO_printf(bio_err,"error setting random cookie secret\n"); +			return 0; +			} +		cookie_initialized = 1; +		} + +	/* Read peer information */ +	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + +	/* Create buffer with peer's address and port */ +	length = 0; +	switch (peer.sa.sa_family) +		{ +	case AF_INET: +		length += sizeof(struct in_addr); +		length += sizeof(peer.s4.sin_port); +		break; +#if OPENSSL_USE_IPV6 +	case AF_INET6: +		length += sizeof(struct in6_addr); +		length += sizeof(peer.s6.sin6_port); +		break; +#endif +	default: +		OPENSSL_assert(0); +		break; +		} +	buffer = OPENSSL_malloc(length); + +	if (buffer == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		return 0; +		} + +	switch (peer.sa.sa_family) +		{ +	case AF_INET: +		memcpy(buffer, +		       &peer.s4.sin_port, +		       sizeof(peer.s4.sin_port)); +		memcpy(buffer + sizeof(peer.s4.sin_port), +		       &peer.s4.sin_addr, +		       sizeof(struct in_addr)); +		break; +#if OPENSSL_USE_IPV6 +	case AF_INET6: +		memcpy(buffer, +		       &peer.s6.sin6_port, +		       sizeof(peer.s6.sin6_port)); +		memcpy(buffer + sizeof(peer.s6.sin6_port), +		       &peer.s6.sin6_addr, +		       sizeof(struct in6_addr)); +		break; +#endif +	default: +		OPENSSL_assert(0); +		break; +		} + +	/* Calculate HMAC of buffer using the secret */ +	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, +	     buffer, length, result, &resultlength); +	OPENSSL_free(buffer); + +	memcpy(cookie, result, resultlength); +	*cookie_len = resultlength; + +	return 1; +	} + +int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) +	{ +	unsigned char *buffer, result[EVP_MAX_MD_SIZE]; +	unsigned int length, resultlength; +	union { +		struct sockaddr sa; +		struct sockaddr_in s4; +#if OPENSSL_USE_IPV6 +		struct sockaddr_in6 s6; +#endif +	} peer; + +	/* If secret isn't initialized yet, the cookie can't be valid */ +	if (!cookie_initialized) +		return 0; + +	/* Read peer information */ +	(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + +	/* Create buffer with peer's address and port */ +	length = 0; +	switch (peer.sa.sa_family) +		{ +	case AF_INET: +		length += sizeof(struct in_addr); +		length += sizeof(peer.s4.sin_port); +		break; +#if OPENSSL_USE_IPV6 +	case AF_INET6: +		length += sizeof(struct in6_addr); +		length += sizeof(peer.s6.sin6_port); +		break; +#endif +	default: +		OPENSSL_assert(0); +		break; +		} +	buffer = OPENSSL_malloc(length); +	 +	if (buffer == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		return 0; +		} + +	switch (peer.sa.sa_family) +		{ +	case AF_INET: +		memcpy(buffer, +		       &peer.s4.sin_port, +		       sizeof(peer.s4.sin_port)); +		memcpy(buffer + sizeof(peer.s4.sin_port), +		       &peer.s4.sin_addr, +		       sizeof(struct in_addr)); +		break; +#if OPENSSL_USE_IPV6 +	case AF_INET6: +		memcpy(buffer, +		       &peer.s6.sin6_port, +		       sizeof(peer.s6.sin6_port)); +		memcpy(buffer + sizeof(peer.s6.sin6_port), +		       &peer.s6.sin6_addr, +		       sizeof(struct in6_addr)); +		break; +#endif +	default: +		OPENSSL_assert(0); +		break; +		} + +	/* Calculate HMAC of buffer using the secret */ +	HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, +	     buffer, length, result, &resultlength); +	OPENSSL_free(buffer); + +	if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) +		return 1; + +	return 0; +	} diff --git a/main/openssl/apps/s_client.c b/main/openssl/apps/s_client.c new file mode 100644 index 00000000..b951513d --- /dev/null +++ b/main/openssl/apps/s_client.c @@ -0,0 +1,1873 @@ +/* apps/s_client.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/e_os2.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif + +/* With IPv6, it looks like Digital has mixed up the proper order of +   recursive header file inclusion, resulting in the compiler complaining +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which +   is needed to have fileno() declared correctly...  So let's define u_int */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) +#define __U_INT +typedef unsigned int u_int; +#endif + +#define USE_SOCKETS +#include "apps.h" +#include <openssl/x509.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/rand.h> +#include <openssl/ocsp.h> +#include <openssl/bn.h> +#include "s_apps.h" +#include "timeouts.h" + +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +#undef FIONBIO +#endif + +#if defined(OPENSSL_SYS_BEOS_R5) +#include <fcntl.h> +#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" + +/*#define TEST_CERT "client.pem" */ /* no default cert. */ + +#undef BUFSIZZ +#define BUFSIZZ 1024*8 + +extern int verify_depth; +extern int verify_error; +extern int verify_return_error; + +#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_msg=0; +static int c_showcerts=0; + +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 int c_quiet=0; +static int c_ign_eof=0; + +#ifndef OPENSSL_NO_PSK +/* Default PSK identity and key */ +static char *psk_identity="Client_identity"; +/*char *psk_key=NULL;  by default PSK is not used */ + +static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, +	unsigned int max_identity_len, unsigned char *psk, +	unsigned int max_psk_len) +	{ +	unsigned int psk_len = 0; +	int ret; +        BIGNUM *bn=NULL; + +	if (c_debug) +		BIO_printf(bio_c_out, "psk_client_cb\n"); +	if (!hint) +                { +                /* no ServerKeyExchange message*/ +		if (c_debug) +			BIO_printf(bio_c_out,"NULL received PSK identity hint, continuing anyway\n"); +                } +        else if (c_debug) +		BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint); + +	/* lookup PSK identity and PSK key based on the given identity hint here */ +	ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity); +	if (ret < 0 || (unsigned int)ret > max_identity_len) +		goto out_err; +	if (c_debug) +		BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret); +        ret=BN_hex2bn(&bn, psk_key); +        if (!ret) +                { +                BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key); +                if (bn) +                        BN_free(bn); +                return 0; +                } + +        if ((unsigned int)BN_num_bytes(bn) > max_psk_len) +                { +                BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n", +                        max_psk_len, BN_num_bytes(bn)); +                BN_free(bn); +                return 0; +                } + +        psk_len=BN_bn2bin(bn, psk); +        BN_free(bn); +        if (psk_len == 0) +                goto out_err; + +	if (c_debug) +		BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len); + +        return psk_len; + out_err: +	if (c_debug) +		BIO_printf(bio_err, "Error in PSK client callback\n"); +        return 0; +	} +#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 - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); + +	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\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," -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," -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 +	BIO_printf(bio_err," -ssl2         - just use SSLv2\n"); +	BIO_printf(bio_err," -ssl3         - just use SSLv3\n"); +	BIO_printf(bio_err," -tls1         - just use TLSv1\n"); +	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");     +	BIO_printf(bio_err," -mtu          - set the link layer MTU\n"); +	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); +	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n"); +	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\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"); +#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"); +# 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," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n"); +#endif +	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); +	} + +#ifndef OPENSSL_NO_TLSEXT + +/* This is a context that we pass to callbacks */ +typedef struct tlsextctx_st { +   BIO * biodebug; +   int ack; +} tlsextctx; + + +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) +	{ +	tlsextctx * p = (tlsextctx *) arg; +	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); +	if (SSL_get_servername_type(s) != -1)  + 	        p->ack = !SSL_session_reused(s) && hn != NULL; +	else  +		BIO_printf(bio_err,"Can't use SSL_get_servername\n"); +	 +	return SSL_TLSEXT_ERR_OK; +	} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This the context that we pass to next_proto_cb */ +typedef struct tlsextnextprotoctx_st { +	unsigned char *data; +	unsigned short len; +	int status; +} tlsextnextprotoctx; + +static tlsextnextprotoctx next_proto; + +static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +	{ +	tlsextnextprotoctx *ctx = arg; + +	if (!c_quiet) +		{ +		/* We can assume that |in| is syntactically valid. */ +		unsigned i; +		BIO_printf(bio_c_out, "Protocols advertised by server: "); +		for (i = 0; i < inlen; ) +			{ +			if (i) +				BIO_write(bio_c_out, ", ", 2); +			BIO_write(bio_c_out, &in[i + 1], in[i]); +			i += in[i] + 1; +			} +		BIO_write(bio_c_out, "\n", 1); +		} + +	ctx->status = SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len); +	return SSL_TLSEXT_ERR_OK; +	} +# endif  /* ndef OPENSSL_NO_NEXTPROTONEG */ +#endif + +enum +{ +	PROTO_OFF	= 0, +	PROTO_SMTP, +	PROTO_POP3, +	PROTO_IMAP, +	PROTO_FTP, +	PROTO_XMPP +}; + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	unsigned int off=0, clr=0; +	SSL *con=NULL; +	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; +	char *cert_file=NULL,*key_file=NULL; +	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; +	char *passarg = NULL, *pass = NULL; +	X509 *cert = NULL; +	EVP_PKEY *key = NULL; +	char *CApath=NULL,*CAfile=NULL,*cipher=NULL; +	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0; +	int cutthrough=0; +	int crlf=0; +	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; +	SSL_CTX *ctx=NULL; +	int ret=1,in_init=1,i,nbio_test=0; +	int starttls_proto = PROTO_OFF; +	int prexit = 0; +	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; +	struct timeval timeout, *timeoutp; +#ifndef OPENSSL_NO_ENGINE +	char *engine_id=NULL; +	char *ssl_client_engine_id=NULL; +	ENGINE *ssl_client_engine=NULL; +#endif +	ENGINE *e=NULL; +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) +	struct timeval tv; +#if defined(OPENSSL_SYS_BEOS_R5) +	int stdin_set = 0; +#endif +#endif +#ifndef OPENSSL_NO_TLSEXT +	char *servername = NULL;  +        tlsextctx tlsextcbp =  +        {NULL,0}; +# ifndef OPENSSL_NO_NEXTPROTONEG +	const char *next_proto_neg_in = NULL; +# endif +#endif +	char *sess_in = NULL; +	char *sess_out = NULL; +	struct sockaddr peer; +	int peerlen = sizeof(peer); +	int enable_timeouts = 0 ; +	long socket_mtu = 0; +#ifndef OPENSSL_NO_JPAKE +	char *jpake_secret = NULL; +#endif + +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +	meth=SSLv23_client_method(); +#elif !defined(OPENSSL_NO_SSL3) +	meth=SSLv3_client_method(); +#elif !defined(OPENSSL_NO_SSL2) +	meth=SSLv2_client_method(); +#endif + +	apps_startup(); +	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; + +	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || +		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || +		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL)) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		goto end; +		} + +	verify_depth=0; +	verify_error=X509_V_OK; +#ifdef FIONBIO +	c_nbio=0; +#endif + +	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,"-verify") == 0) +			{ +			verify=SSL_VERIFY_PEER; +			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; +			cert_file= *(++argv); +			} +		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 (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) +			{ +			if (badarg) +				goto bad; +			continue; +			} +		else if (strcmp(*argv,"-verify_return_error") == 0) +			verify_return_error = 1; +		else if	(strcmp(*argv,"-prexit") == 0) +			prexit=1; +		else if	(strcmp(*argv,"-crlf") == 0) +			crlf=1; +		else if	(strcmp(*argv,"-quiet") == 0) +			{ +			c_quiet=1; +			c_ign_eof=1; +			} +		else if	(strcmp(*argv,"-ign_eof") == 0) +			c_ign_eof=1; +		else if	(strcmp(*argv,"-no_ign_eof") == 0) +			c_ign_eof=0; +		else if	(strcmp(*argv,"-pause") == 0) +			c_Pause=1; +		else if	(strcmp(*argv,"-debug") == 0) +			c_debug=1; +#ifndef OPENSSL_NO_TLSEXT +		else if	(strcmp(*argv,"-tlsextdebug") == 0) +			c_tlsextdebug=1; +		else if	(strcmp(*argv,"-status") == 0) +			c_status_req=1; +#endif +#ifdef WATT32 +		else if (strcmp(*argv,"-wdebug") == 0) +			dbug_init(); +#endif +		else if	(strcmp(*argv,"-msg") == 0) +			c_msg=1; +		else if	(strcmp(*argv,"-showcerts") == 0) +			c_showcerts=1; +		else if	(strcmp(*argv,"-nbio_test") == 0) +			nbio_test=1; +		else if	(strcmp(*argv,"-state") == 0) +			state=1; +#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((int)psk_key[j])) +                                        continue; +                                BIO_printf(bio_err,"Not a hex number '%s'\n",*argv); +                                goto bad; +                                } +			} +#endif +#ifndef OPENSSL_NO_SSL2 +		else if	(strcmp(*argv,"-ssl2") == 0) +			meth=SSLv2_client_method(); +#endif +#ifndef OPENSSL_NO_SSL3 +		else if	(strcmp(*argv,"-ssl3") == 0) +			meth=SSLv3_client_method(); +#endif +#ifndef OPENSSL_NO_TLS1 +		else if	(strcmp(*argv,"-tls1") == 0) +			meth=TLSv1_client_method(); +#endif +#ifndef OPENSSL_NO_DTLS1 +		else if	(strcmp(*argv,"-dtls1") == 0) +			{ +			meth=DTLSv1_client_method(); +			socket_type=SOCK_DGRAM; +			} +		else if (strcmp(*argv,"-timeout") == 0) +			enable_timeouts=1; +		else if (strcmp(*argv,"-mtu") == 0) +			{ +			if (--argc < 1) goto bad; +			socket_mtu = atol(*(++argv)); +			} +#endif +		else if (strcmp(*argv,"-bugs") == 0) +			bugs=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,"-key") == 0) +			{ +			if (--argc < 1) goto bad; +			key_file= *(++argv); +			} +		else if	(strcmp(*argv,"-reconnect") == 0) +			{ +			reconnect=5; +			} +		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,"-no_tls1") == 0) +			off|=SSL_OP_NO_TLSv1; +		else if (strcmp(*argv,"-no_ssl3") == 0) +			off|=SSL_OP_NO_SSLv3; +		else if (strcmp(*argv,"-no_ssl2") == 0) +			off|=SSL_OP_NO_SSLv2; +		else if	(strcmp(*argv,"-no_comp") == 0) +			{ off|=SSL_OP_NO_COMPRESSION; } +#ifndef OPENSSL_NO_TLSEXT +		else if	(strcmp(*argv,"-no_ticket") == 0) +			{ off|=SSL_OP_NO_TICKET; } +# ifndef OPENSSL_NO_NEXTPROTONEG +		else if (strcmp(*argv,"-nextprotoneg") == 0) +			{ +			if (--argc < 1) goto bad; +			next_proto_neg_in = *(++argv); +			} +# endif +#endif +		else if (strcmp(*argv,"-cutthrough") == 0) +			cutthrough=1; +		else if (strcmp(*argv,"-serverpref") == 0) +			off|=SSL_OP_CIPHER_SERVER_PREFERENCE; +		else if (strcmp(*argv,"-legacy_renegotiation") == 0) +			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; +		else if	(strcmp(*argv,"-legacy_server_connect") == 0) +			{ off|=SSL_OP_LEGACY_SERVER_CONNECT; } +		else if	(strcmp(*argv,"-no_legacy_server_connect") == 0) +			{ clr|=SSL_OP_LEGACY_SERVER_CONNECT; } +		else if	(strcmp(*argv,"-cipher") == 0) +			{ +			if (--argc < 1) goto bad; +			cipher= *(++argv); +			} +#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); +			} +#endif +		else if (strcmp(*argv,"-rand") == 0) +			{ +			if (--argc < 1) goto bad; +			inrand= *(++argv); +			} +#ifndef OPENSSL_NO_TLSEXT +		else if (strcmp(*argv,"-servername") == 0) +			{ +			if (--argc < 1) goto bad; +			servername= *(++argv); +			/* meth=TLSv1_client_method(); */ +			} +#endif +#ifndef OPENSSL_NO_JPAKE +		else if (strcmp(*argv,"-jpake") == 0) +			{ +			if (--argc < 1) goto bad; +			jpake_secret = *++argv; +			} +#endif +		else +			{ +			BIO_printf(bio_err,"unknown option %s\n",*argv); +			badop=1; +			break; +			} +		argc--; +		argv++; +		} +	if (badop) +		{ +bad: +		sc_usage(); +		goto end; +		} + +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) +	if (jpake_secret) +		{ +		if (psk_key) +			{ +			BIO_printf(bio_err, +				   "Can't use JPAKE and PSK together\n"); +			goto end; +			} +		psk_identity = "JPAKE"; +		} + +	if (cipher) +		{ +		BIO_printf(bio_err, "JPAKE sets cipher to PSK\n"); +		goto end; +		} +	cipher = "PSK"; +#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) +		{ +		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in); +		if (next_proto.data == NULL) +			{ +			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n"); +			goto end; +			} +		} +	else +		next_proto.data = NULL; +#endif + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine_id, 1); +	if (ssl_client_engine_id) +		{ +		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id); +		if (!ssl_client_engine) +			{ +			BIO_printf(bio_err, +					"Error getting client auth engine\n"); +			goto end; +			} +		} + +#endif +	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) +		{ +		BIO_printf(bio_err, "Error getting password\n"); +		goto end; +		} + +	if (key_file == NULL) +		key_file = cert_file; + + +	if (key_file) + +		{ + +		key = load_key(bio_err, key_file, key_format, 0, pass, e, +			       "client certificate private key file"); +		if (!key) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} + +		} + +	if (cert_file) + +		{ +		cert = load_cert(bio_err,cert_file,cert_format, +				NULL, e, "client certificate file"); + +		if (!cert) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (!app_RAND_load_file(NULL, bio_err, 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 (bio_c_out == NULL) +		{ +		if (c_quiet && !c_debug && !c_msg) +			{ +			bio_c_out=BIO_new(BIO_s_null()); +			} +		else +			{ +			if (bio_c_out == NULL) +				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE); +			} +		} + +	ctx=SSL_CTX_new(meth); +	if (ctx == NULL) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} + +	if (vpm) +		SSL_CTX_set1_param(ctx, vpm); + +#ifndef OPENSSL_NO_ENGINE +	if (ssl_client_engine) +		{ +		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) +			{ +			BIO_puts(bio_err, "Error setting client auth engine\n"); +			ERR_print_errors(bio_err); +			ENGINE_free(ssl_client_engine); +			goto end; +			} +		ENGINE_free(ssl_client_engine); +		} +#endif + +#ifndef OPENSSL_NO_PSK +#ifdef OPENSSL_NO_JPAKE +	if (psk_key != NULL) +#else +	if (psk_key != NULL || jpake_secret) +#endif +		{ +		if (c_debug) +			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n"); +		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb); +		} +#endif +	if (bugs) +		SSL_CTX_set_options(ctx,SSL_OP_ALL|off); +	else +		SSL_CTX_set_options(ctx,off); + +	if (clr) +		SSL_CTX_clear_options(ctx, clr); +	/* DTLS: partial reads end up discarding unread UDP bytes :-(  +	 * Setting read ahead solves this problem. +	 */ +	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); + +	/* Enable handshake cutthrough for client connections using +	 * strong ciphers. */ +	if (cutthrough) +		{ +		int ssl_mode = SSL_CTX_get_mode(ctx); +		ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; +		SSL_CTX_set_mode(ctx, ssl_mode); +		} + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +	if (next_proto.data) +		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); +#endif + +	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); +	if (cipher != NULL) +		if(!SSL_CTX_set_cipher_list(ctx,cipher)) { +		BIO_printf(bio_err,"error setting cipher list\n"); +		ERR_print_errors(bio_err); +		goto end; +	} +#if 0 +	else +		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER")); +#endif + +	SSL_CTX_set_verify(ctx,verify,verify_callback); +	if (!set_cert_key_stuff(ctx,cert,key)) +		goto end; + +	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || +		(!SSL_CTX_set_default_verify_paths(ctx))) +		{ +		/* BIO_printf(bio_err,"error setting default verify locations\n"); */ +		ERR_print_errors(bio_err); +		/* goto end; */ +		} + +#ifndef OPENSSL_NO_TLSEXT +	if (servername != NULL) +		{ +		tlsextcbp.biodebug = bio_err; +		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); +		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); +		} +#endif + +	con=SSL_new(ctx); +	if (sess_in) +		{ +		SSL_SESSION *sess; +		BIO *stmp = BIO_new_file(sess_in, "r"); +		if (!stmp) +			{ +			BIO_printf(bio_err, "Can't open session file %s\n", +						sess_in); +			ERR_print_errors(bio_err); +			goto end; +			} +		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); +		BIO_free(stmp); +		if (!sess) +			{ +			BIO_printf(bio_err, "Can't open session file %s\n", +						sess_in); +			ERR_print_errors(bio_err); +			goto end; +			} +		SSL_set_session(con, sess); +		SSL_SESSION_free(sess); +		} +#ifndef OPENSSL_NO_TLSEXT +	if (servername != NULL) +		{ +		if (!SSL_set_tlsext_host_name(con,servername)) +			{ +			BIO_printf(bio_err,"Unable to set TLS servername extension.\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		} +#endif +#ifndef OPENSSL_NO_KRB5 +	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL) +                { +                kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host); +		} +#endif	/* OPENSSL_NO_KRB5  */ +/*	SSL_set_cipher_list(con,"RC4-MD5"); */ +#if 0 +#ifdef TLSEXT_TYPE_opaque_prf_input +	SSL_set_tlsext_opaque_prf_input(con, "Test client", 11); +#endif +#endif + +re_start: + +	if (init_client(&s,host,port,socket_type) == 0) +		{ +		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); +		SHUTDOWN(s); +		goto end; +		} +	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); + +#ifdef FIONBIO +	if (c_nbio) +		{ +		unsigned long l=1; +		BIO_printf(bio_c_out,"turning on non blocking io\n"); +		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} +#endif                                               +	if (c_Pause & 0x01) con->debug=1; + +	if ( SSL_version(con) == DTLS1_VERSION) +		{ + +		sbio=BIO_new_dgram(s,BIO_NOCLOSE); +		if (getsockname(s, &peer, (void *)&peerlen) < 0) +			{ +			BIO_printf(bio_err, "getsockname:errno=%d\n", +				get_last_socket_error()); +			SHUTDOWN(s); +			goto end; +			} + +		(void)BIO_ctrl_set_connected(sbio, 1, &peer); + +		if (enable_timeouts) +			{ +			timeout.tv_sec = 0; +			timeout.tv_usec = DGRAM_RCV_TIMEOUT; +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); +			 +			timeout.tv_sec = 0; +			timeout.tv_usec = DGRAM_SND_TIMEOUT; +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); +			} + +		if (socket_mtu > 28) +			{ +			SSL_set_options(con, SSL_OP_NO_QUERY_MTU); +			SSL_set_mtu(con, socket_mtu - 28); +			} +		else +			/* want to do MTU discovery */ +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); +		} +	else +		sbio=BIO_new_socket(s,BIO_NOCLOSE); + +	if (nbio_test) +		{ +		BIO *test; + +		test=BIO_new(BIO_f_nbio_test()); +		sbio=BIO_push(test,sbio); +		} + +	if (c_debug) +		{ +		con->debug=1; +		BIO_set_callback(sbio,bio_dump_callback); +		BIO_set_callback_arg(sbio,(char *)bio_c_out); +		} +	if (c_msg) +		{ +		SSL_set_msg_callback(con, msg_cb); +		SSL_set_msg_callback_arg(con, bio_c_out); +		} +#ifndef OPENSSL_NO_TLSEXT +	if (c_tlsextdebug) +		{ +		SSL_set_tlsext_debug_callback(con, tlsext_cb); +		SSL_set_tlsext_debug_arg(con, bio_c_out); +		} +	if (c_status_req) +		{ +		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); +		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); +		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); +#if 0 +{ +STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null(); +OCSP_RESPID *id = OCSP_RESPID_new(); +id->value.byKey = ASN1_OCTET_STRING_new(); +id->type = V_OCSP_RESPID_KEY; +ASN1_STRING_set(id->value.byKey, "Hello World", -1); +sk_OCSP_RESPID_push(ids, id); +SSL_set_tlsext_status_ids(con, ids); +} +#endif +		} +#endif +#ifndef OPENSSL_NO_JPAKE +	if (jpake_secret) +		jpake_client_auth(bio_c_out, sbio, jpake_secret); +#endif + +	SSL_set_bio(con,sbio,sbio); +	SSL_set_connect_state(con); + +	/* ok, lets connect */ +	width=SSL_get_fd(con)+1; + +	read_tty=1; +	write_tty=0; +	tty_on=0; +	read_ssl=1; +	write_ssl=1; +	 +	cbuf_len=0; +	cbuf_off=0; +	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); +			} +		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; +			} +		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; +			} +		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); +			} +		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'>", host); +		seen = BIO_read(sbio,mbuf,BUFSIZZ); +		mbuf[seen] = 0; +		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) +			{ +			if (strstr(mbuf, "/stream:features>")) +				goto shut; +			seen = BIO_read(sbio,mbuf,BUFSIZZ); +			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; +		} + +	for (;;) +		{ +		FD_ZERO(&readfds); +		FD_ZERO(&writefds); + +		if ((SSL_version(con) == DTLS1_VERSION) && +			DTLSv1_get_timeout(con, &timeout)) +			timeoutp = &timeout; +		else +			timeoutp = NULL; + +		if (SSL_in_init(con) && !SSL_total_renegotiations(con)) +			{ +			in_init=1; +			tty_on=0; +			} +		else +			{ +			tty_on=1; +			if (in_init) +				{ +				in_init=0; +#if 0 /* This test doesn't really work as intended (needs to be fixed) */ +#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 +#endif +				if (sess_out) +					{ +					BIO *stmp = BIO_new_file(sess_out, "w"); +					if (stmp) +						{ +						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); +						BIO_free(stmp); +						} +					else  +						BIO_printf(bio_err, "Error writing session file %s\n", sess_out); +					} +				print_stuff(bio_c_out,con,full_log); +				if (full_log > 0) full_log--; + +				if (starttls_proto) +					{ +					BIO_printf(bio_err,"%s",mbuf); +					/* We don't need to know any more */ +					starttls_proto = PROTO_OFF; +					} + +				if (reconnect) +					{ +					reconnect--; +					BIO_printf(bio_c_out,"drop connection and then reconnect\n"); +					SSL_shutdown(con); +					SSL_set_connect_state(con); +					SHUTDOWN(SSL_get_fd(con)); +					goto re_start; +					} +				} +			} + +		ssl_pending = read_ssl && SSL_pending(con); + +		if (!ssl_pending) +			{ +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5) +			if (tty_on) +				{ +				if (read_tty)  openssl_fdset(fileno(stdin),&readfds); +				if (write_tty) openssl_fdset(fileno(stdout),&writefds); +				} +			if (read_ssl) +				openssl_fdset(SSL_get_fd(con),&readfds); +			if (write_ssl) +				openssl_fdset(SSL_get_fd(con),&writefds); +#else +			if(!tty_on || !write_tty) { +				if (read_ssl) +					openssl_fdset(SSL_get_fd(con),&readfds); +				if (write_ssl) +					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 currently of type (int *) whereas under other +			 * systems it is (void *) if you don't have a cast it +			 * will choke the compiler: if you do have a cast then +			 * you can either go for (int *) or (void *). +			 */ +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) +                        /* Under Windows/DOS we make the assumption that we can +			 * always write to the tty: therefore if we need to +			 * write to the tty we just fall through. Otherwise +			 * we timeout the select every second and see if there +			 * are any keypresses. Note: this is a hack, in a proper +			 * Windows application we wouldn't do this. +			 */ +			i=0; +			if(!write_tty) { +				if(read_tty) { +					tv.tv_sec = 1; +					tv.tv_usec = 0; +					i=select(width,(void *)&readfds,(void *)&writefds, +						 NULL,&tv); +#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) +					if(!i && (!_kbhit() || !read_tty) ) continue; +#else +					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue; +#endif +				} else 	i=select(width,(void *)&readfds,(void *)&writefds, +					 NULL,timeoutp); +			} +#elif defined(OPENSSL_SYS_NETWARE) +			if(!write_tty) { +				if(read_tty) { +					tv.tv_sec = 1; +					tv.tv_usec = 0; +					i=select(width,(void *)&readfds,(void *)&writefds, +						NULL,&tv); +				} else 	i=select(width,(void *)&readfds,(void *)&writefds, +					NULL,timeoutp); +			} +#elif defined(OPENSSL_SYS_BEOS_R5) +			/* Under BeOS-R5 the situation is similar to DOS */ +			i=0; +			stdin_set = 0; +			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); +			if(!write_tty) { +				if(read_tty) { +					tv.tv_sec = 1; +					tv.tv_usec = 0; +					i=select(width,(void *)&readfds,(void *)&writefds, +						 NULL,&tv); +					if (read(fileno(stdin), sbuf, 0) >= 0) +						stdin_set = 1; +					if (!i && (stdin_set != 1 || !read_tty)) +						continue; +				} else 	i=select(width,(void *)&readfds,(void *)&writefds, +					 NULL,timeoutp); +			} +			(void)fcntl(fileno(stdin), F_SETFL, 0); +#else +			i=select(width,(void *)&readfds,(void *)&writefds, +				 NULL,timeoutp); +#endif +			if ( i < 0) +				{ +				BIO_printf(bio_err,"bad select %d\n", +				get_last_socket_error()); +				goto shut; +				/* goto end; */ +				} +			} + +		if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) +			{ +			BIO_printf(bio_err,"TIMEOUT occured\n"); +			} + +		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds)) +			{ +			k=SSL_write(con,&(cbuf[cbuf_off]), +				(unsigned int)cbuf_len); +			switch (SSL_get_error(con,k)) +				{ +			case SSL_ERROR_NONE: +				cbuf_off+=k; +				cbuf_len-=k; +				if (k <= 0) goto end; +				/* we have done a  write(con,NULL,0); */ +				if (cbuf_len <= 0) +					{ +					read_tty=1; +					write_ssl=0; +					} +				else /* if (cbuf_len > 0) */ +					{ +					read_tty=0; +					write_ssl=1; +					} +				break; +			case SSL_ERROR_WANT_WRITE: +				BIO_printf(bio_c_out,"write W BLOCK\n"); +				write_ssl=1; +				read_tty=0; +				break; +			case SSL_ERROR_WANT_READ: +				BIO_printf(bio_c_out,"write R BLOCK\n"); +				write_tty=0; +				read_ssl=1; +				write_ssl=0; +				break; +			case SSL_ERROR_WANT_X509_LOOKUP: +				BIO_printf(bio_c_out,"write X BLOCK\n"); +				break; +			case SSL_ERROR_ZERO_RETURN: +				if (cbuf_len != 0) +					{ +					BIO_printf(bio_c_out,"shutdown\n"); +					ret = 0; +					goto shut; +					} +				else +					{ +					read_tty=1; +					write_ssl=0; +					break; +					} +				 +			case SSL_ERROR_SYSCALL: +				if ((k != 0) || (cbuf_len != 0)) +					{ +					BIO_printf(bio_err,"write:errno=%d\n", +						get_last_socket_error()); +					goto shut; +					} +				else +					{ +					read_tty=1; +					write_ssl=0; +					} +				break; +			case SSL_ERROR_SSL: +				ERR_print_errors(bio_err); +				goto shut; +				} +			} +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) +		/* Assume Windows/DOS/BeOS can always write */ +		else if (!ssl_pending && write_tty) +#else +		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds)) +#endif +			{ +#ifdef CHARSET_EBCDIC +			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len); +#endif +			i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len); + +			if (i <= 0) +				{ +				BIO_printf(bio_c_out,"DONE\n"); +				ret = 0; +				goto shut; +				/* goto end; */ +				} + +			sbuf_len-=i;; +			sbuf_off+=i; +			if (sbuf_len <= 0) +				{ +				read_ssl=1; +				write_tty=0; +				} +			} +		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds)) +			{ +#ifdef RENEG +{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } } +#endif +#if 1 +			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ ); +#else +/* Demo for pending and peek :-) */ +			k=SSL_read(con,sbuf,16); +{ char zbuf[10240];  +printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240)); +} +#endif + +			switch (SSL_get_error(con,k)) +				{ +			case SSL_ERROR_NONE: +				if (k <= 0) +					goto end; +				sbuf_off=0; +				sbuf_len=k; + +				read_ssl=0; +				write_tty=1; +				break; +			case SSL_ERROR_WANT_WRITE: +				BIO_printf(bio_c_out,"read W BLOCK\n"); +				write_ssl=1; +				read_tty=0; +				break; +			case SSL_ERROR_WANT_READ: +				BIO_printf(bio_c_out,"read R BLOCK\n"); +				write_tty=0; +				read_ssl=1; +				if ((read_tty == 0) && (write_ssl == 0)) +					write_ssl=1; +				break; +			case SSL_ERROR_WANT_X509_LOOKUP: +				BIO_printf(bio_c_out,"read X BLOCK\n"); +				break; +			case SSL_ERROR_SYSCALL: +				ret=get_last_socket_error(); +				BIO_printf(bio_err,"read:errno=%d\n",ret); +				goto shut; +			case SSL_ERROR_ZERO_RETURN: +				BIO_printf(bio_c_out,"closed\n"); +				ret=0; +				goto shut; +			case SSL_ERROR_SSL: +				ERR_print_errors(bio_err); +				goto shut; +				/* break; */ +				} +			} + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) +#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) +		else if (_kbhit()) +#else +		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) +#endif +#elif defined (OPENSSL_SYS_NETWARE) +		else if (_kbhit()) +#elif defined(OPENSSL_SYS_BEOS_R5) +		else if (stdin_set) +#else +		else if (FD_ISSET(fileno(stdin),&readfds)) +#endif +			{ +			if (crlf) +				{ +				int j, lf_num; + +				i=raw_read_stdin(cbuf,BUFSIZZ/2); +				lf_num = 0; +				/* both loops are skipped when i <= 0 */ +				for (j = 0; j < i; j++) +					if (cbuf[j] == '\n') +						lf_num++; +				for (j = i-1; j >= 0; j--) +					{ +					cbuf[j+lf_num] = cbuf[j]; +					if (cbuf[j] == '\n') +						{ +						lf_num--; +						i++; +						cbuf[j+lf_num] = '\r'; +						} +					} +				assert(lf_num == 0); +				} +			else +				i=raw_read_stdin(cbuf,BUFSIZZ); + +			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) +				{ +				BIO_printf(bio_err,"DONE\n"); +				ret=0; +				goto shut; +				} + +			if ((!c_ign_eof) && (cbuf[0] == 'R')) +				{ +				BIO_printf(bio_err,"RENEGOTIATING\n"); +				SSL_renegotiate(con); +				cbuf_len=0; +				} +			else +				{ +				cbuf_len=i; +				cbuf_off=0; +#ifdef CHARSET_EBCDIC +				ebcdic2ascii(cbuf, cbuf, i); +#endif +				} + +			write_ssl=1; +			read_tty=0; +			} +		} + +	ret=0; +shut: +	if (in_init) +		print_stuff(bio_c_out,con,full_log); +	SSL_shutdown(con); +	SHUTDOWN(SSL_get_fd(con)); +end: +	if (con != NULL) +		{ +		if (prexit != 0) +			print_stuff(bio_c_out,con,1); +		SSL_free(con); +		} +	if (ctx != NULL) SSL_CTX_free(ctx); +	if (cert) +		X509_free(cert); +	if (key) +		EVP_PKEY_free(key); +	if (pass) +		OPENSSL_free(pass); +	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); } +	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); } +	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); } +	if (bio_c_out != NULL) +		{ +		BIO_free(bio_c_out); +		bio_c_out=NULL; +		} +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + + +static void print_stuff(BIO *bio, SSL *s, int full) +	{ +	X509 *peer=NULL; +	char *p; +	static const char *space="                "; +	char buf[BUFSIZ]; +	STACK_OF(X509) *sk; +	STACK_OF(X509_NAME) *sk2; +	const SSL_CIPHER *c; +	X509_NAME *xn; +	int j,i; +#ifndef OPENSSL_NO_COMP +	const COMP_METHOD *comp, *expansion; +#endif + +	if (full) +		{ +		int got_a_chain = 0; + +		sk=SSL_get_peer_cert_chain(s); +		if (sk != NULL) +			{ +			got_a_chain = 1; /* we don't have it for SSL2 (yet) */ + +			BIO_printf(bio,"---\nCertificate chain\n"); +			for (i=0; i<sk_X509_num(sk); i++) +				{ +				X509_NAME_oneline(X509_get_subject_name( +					sk_X509_value(sk,i)),buf,sizeof buf); +				BIO_printf(bio,"%2d s:%s\n",i,buf); +				X509_NAME_oneline(X509_get_issuer_name( +					sk_X509_value(sk,i)),buf,sizeof buf); +				BIO_printf(bio,"   i:%s\n",buf); +				if (c_showcerts) +					PEM_write_bio_X509(bio,sk_X509_value(sk,i)); +				} +			} + +		BIO_printf(bio,"---\n"); +		peer=SSL_get_peer_certificate(s); +		if (peer != NULL) +			{ +			BIO_printf(bio,"Server certificate\n"); +			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */ +				PEM_write_bio_X509(bio,peer); +			X509_NAME_oneline(X509_get_subject_name(peer), +				buf,sizeof buf); +			BIO_printf(bio,"subject=%s\n",buf); +			X509_NAME_oneline(X509_get_issuer_name(peer), +				buf,sizeof buf); +			BIO_printf(bio,"issuer=%s\n",buf); +			} +		else +			BIO_printf(bio,"no peer certificate available\n"); + +		sk2=SSL_get_client_CA_list(s); +		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) +			{ +			BIO_printf(bio,"---\nAcceptable client certificate CA names\n"); +			for (i=0; i<sk_X509_NAME_num(sk2); i++) +				{ +				xn=sk_X509_NAME_value(sk2,i); +				X509_NAME_oneline(xn,buf,sizeof(buf)); +				BIO_write(bio,buf,strlen(buf)); +				BIO_write(bio,"\n",1); +				} +			} +		else +			{ +			BIO_printf(bio,"---\nNo client certificate CA names sent\n"); +			} +		p=SSL_get_shared_ciphers(s,buf,sizeof buf); +		if (p != NULL) +			{ +			/* This works only for SSL 2.  In later protocol +			 * versions, the client does not know what other +			 * ciphers (in addition to the one to be used +			 * in the current connection) the server supports. */ + +			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n"); +			j=i=0; +			while (*p) +				{ +				if (*p == ':') +					{ +					BIO_write(bio,space,15-j%25); +					i++; +					j=0; +					BIO_write(bio,((i%3)?" ":"\n"),1); +					} +				else +					{ +					BIO_write(bio,p,1); +					j++; +					} +				p++; +				} +			BIO_write(bio,"\n",1); +			} + +		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", +			BIO_number_read(SSL_get_rbio(s)), +			BIO_number_written(SSL_get_wbio(s))); +		} +	BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, ")); +	c=SSL_get_current_cipher(s); +	BIO_printf(bio,"%s, Cipher is %s\n", +		SSL_CIPHER_get_version(c), +		SSL_CIPHER_get_name(c)); +	if (peer != NULL) { +		EVP_PKEY *pktmp; +		pktmp = X509_get_pubkey(peer); +		BIO_printf(bio,"Server public key is %d bit\n", +							 EVP_PKEY_bits(pktmp)); +		EVP_PKEY_free(pktmp); +	} +	BIO_printf(bio, "Secure Renegotiation IS%s supported\n", +			SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); +#ifndef OPENSSL_NO_COMP +	comp=SSL_get_current_compression(s); +	expansion=SSL_get_current_expansion(s); +	BIO_printf(bio,"Compression: %s\n", +		comp ? SSL_COMP_get_name(comp) : "NONE"); +	BIO_printf(bio,"Expansion: %s\n", +		expansion ? SSL_COMP_get_name(expansion) : "NONE"); +#endif + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +	if (next_proto.status != -1) { +		const unsigned char *proto; +		unsigned int proto_len; +		SSL_get0_next_proto_negotiated(s, &proto, &proto_len); +		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status); +		BIO_write(bio, proto, proto_len); +		BIO_write(bio, "\n", 1); +	} +#endif + +	SSL_SESSION_print(bio,SSL_get_session(s)); +	BIO_printf(bio,"---\n"); +	if (peer != NULL) +		X509_free(peer); +	/* flush, or debugging output gets mixed with http response */ +	(void)BIO_flush(bio); +	} + +#ifndef OPENSSL_NO_TLSEXT + +static int ocsp_resp_cb(SSL *s, void *arg) +	{ +	const unsigned char *p; +	int len; +	OCSP_RESPONSE *rsp; +	len = SSL_get_tlsext_status_ocsp_resp(s, &p); +	BIO_puts(arg, "OCSP response: "); +	if (!p) +		{ +		BIO_puts(arg, "no response sent\n"); +		return 1; +		} +	rsp = d2i_OCSP_RESPONSE(NULL, &p, len); +	if (!rsp) +		{ +		BIO_puts(arg, "response parse error\n"); +		BIO_dump_indent(arg, (char *)p, len, 4); +		return 0; +		} +	BIO_puts(arg, "\n======================================\n"); +	OCSP_RESPONSE_print(arg, rsp, 0); +	BIO_puts(arg, "======================================\n"); +	OCSP_RESPONSE_free(rsp); +	return 1; +	} + +#endif diff --git a/main/openssl/apps/s_server.c b/main/openssl/apps/s_server.c new file mode 100644 index 00000000..a8e057ce --- /dev/null +++ b/main/openssl/apps/s_server.c @@ -0,0 +1,2752 @@ +/* apps/s_server.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by  + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +/* Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code */ +#ifdef OPENSSL_NO_DEPRECATED +#undef OPENSSL_NO_DEPRECATED +#endif + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/e_os2.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif + +#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */ +#include <sys/types.h> +#endif + +/* With IPv6, it looks like Digital has mixed up the proper order of +   recursive header file inclusion, resulting in the compiler complaining +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which +   is needed to have fileno() declared correctly...  So let's define u_int */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) +#define __U_INT +typedef unsigned int u_int; +#endif + +#include <openssl/lhash.h> +#include <openssl/bn.h> +#define USE_SOCKETS +#include "apps.h" +#include <openssl/err.h> +#include <openssl/pem.h> +#include <openssl/x509.h> +#include <openssl/ssl.h> +#include <openssl/rand.h> +#include <openssl/ocsp.h> +#ifndef OPENSSL_NO_DH +#include <openssl/dh.h> +#endif +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#include "s_apps.h" +#include "timeouts.h" + +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +#undef FIONBIO +#endif + +#if defined(OPENSSL_SYS_BEOS_R5) +#include <fcntl.h> +#endif + +#ifndef OPENSSL_NO_RSA +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); +#endif +static int sv_body(char *hostname, int s, unsigned char *context); +static int www_body(char *hostname, int s, 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, +				unsigned int *id_len); +#ifndef OPENSSL_NO_DH +static DH *load_dh_param(const char *dhfile); +static DH *get_dh512(void); +#endif + +#ifdef MONOLITH +static void s_server_init(void); +#endif + +#ifndef OPENSSL_NO_DH +static unsigned char dh512_p[]={ +	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, +	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, +	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, +	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, +	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, +	0x47,0x74,0xE8,0x33, +	}; +static unsigned char dh512_g[]={ +	0x02, +	}; + +static DH *get_dh512(void) +	{ +	DH *dh=NULL; + +	if ((dh=DH_new()) == NULL) return(NULL); +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); +	if ((dh->p == NULL) || (dh->g == NULL)) +		return(NULL); +	return(dh); +	} +#endif + + +/* static int load_CA(SSL_CTX *ctx, char *file);*/ + +#undef BUFSIZZ +#define BUFSIZZ	16*1024 +static int bufsize=BUFSIZZ; +static int accept_socket= -1; + +#define TEST_CERT	"server.pem" +#ifndef OPENSSL_NO_TLSEXT +#define TEST_CERT2	"server2.pem" +#endif +#undef PROG +#define PROG		s_server_main + +extern int verify_depth, verify_return_error; + +static char *cipher=NULL; +static int s_server_verify=SSL_VERIFY_NONE; +static int s_server_session_id_context = 1; /* anything will do */ +static const char *s_cert_file=TEST_CERT,*s_key_file=NULL; +#ifndef OPENSSL_NO_TLSEXT +static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL; +#endif +static char *s_dcert_file=NULL,*s_dkey_file=NULL; +#ifdef FIONBIO +static int s_nbio=0; +#endif +static int s_nbio_test=0; +int s_crlf=0; +static SSL_CTX *ctx=NULL; +#ifndef OPENSSL_NO_TLSEXT +static SSL_CTX *ctx2=NULL; +#endif +static int www=0; + +static BIO *bio_s_out=NULL; +static int s_debug=0; +#ifndef OPENSSL_NO_TLSEXT +static int s_tlsextdebug=0; +static int s_tlsextstatus=0; +static int cert_status_cb(SSL *s, void *arg); +#endif +static int s_msg=0; +static int s_quiet=0; + +static int hack=0; +#ifndef OPENSSL_NO_ENGINE +static char *engine_id=NULL; +#endif +static const char *session_id_prefix=NULL; + +static int enable_timeouts = 0; +static long socket_mtu; +#ifndef OPENSSL_NO_DTLS1 +static int cert_chain = 0; +#endif + +#ifndef OPENSSL_NO_PSK +static char *psk_identity="Client_identity"; +char *psk_key=NULL; /* by default PSK is not used */ + +static unsigned int psk_server_cb(SSL *ssl, const char *identity, +	unsigned char *psk, unsigned int max_psk_len) +	{ +	unsigned int psk_len = 0; +	int ret; +	BIGNUM *bn = NULL; + +	if (s_debug) +		BIO_printf(bio_s_out,"psk_server_cb\n"); +	if (!identity) +		{ +		BIO_printf(bio_err,"Error: client did not send PSK identity\n"); +		goto out_err; +		} +	if (s_debug) +		BIO_printf(bio_s_out,"identity_len=%d identity=%s\n", +			identity ? (int)strlen(identity) : 0, identity); + +	/* here we could lookup the given identity e.g. from a database */ +  	if (strcmp(identity, psk_identity) != 0) +		{ +                BIO_printf(bio_s_out, "PSK error: client identity not found" +			   " (got '%s' expected '%s')\n", identity, +			   psk_identity); +		goto out_err; +                } +	if (s_debug) +		BIO_printf(bio_s_out, "PSK client identity found\n"); + +	/* convert the PSK key to binary */ +	ret = BN_hex2bn(&bn, psk_key); +	if (!ret) +		{ +		BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key); +		if (bn) +			BN_free(bn); +		return 0; +		} +	if (BN_num_bytes(bn) > (int)max_psk_len) +		{ +		BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n", +			max_psk_len, BN_num_bytes(bn)); +		BN_free(bn); +		return 0; +		} + +	ret = BN_bn2bin(bn, psk); +	BN_free(bn); + +	if (ret < 0) +		goto out_err; +	psk_len = (unsigned int)ret; + +	if (s_debug) +		BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len); +        return psk_len; + out_err: +	if (s_debug) +		BIO_printf(bio_err, "Error in PSK server callback\n"); +	return 0; +        } +#endif + +#ifdef MONOLITH +static void s_server_init(void) +	{ +	accept_socket=-1; +	cipher=NULL; +	s_server_verify=SSL_VERIFY_NONE; +	s_dcert_file=NULL; +	s_dkey_file=NULL; +	s_cert_file=TEST_CERT; +	s_key_file=NULL; +#ifndef OPENSSL_NO_TLSEXT +	s_cert_file2=TEST_CERT2; +	s_key_file2=NULL; +	ctx2=NULL; +#endif +#ifdef FIONBIO +	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; +	hack=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 arg   - port to accept on (default is %d)\n",PORT); +	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," -cert arg     - certificate file to use\n"); +	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT); +	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_ECDH +	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," -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 +	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n"); +	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n"); +	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n"); +	BIO_printf(bio_err," -dtls1        - Just talk DTLSv1\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_ssl2      - Just disable SSLv2\n"); +	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n"); +	BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n"); +#ifndef OPENSSL_NO_DH +	BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n"); +#endif +#ifndef OPENSSL_NO_ECDH +	BIO_printf(bio_err," -no_ecdhe     - Disable ephemeral ECDH\n"); +#endif +	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 +#endif +	} + +static int local_argc=0; +static char **local_argv; + +#ifdef CHARSET_EBCDIC +static int ebcdic_new(BIO *bi); +static int ebcdic_free(BIO *a); +static int ebcdic_read(BIO *b, char *out, int outl); +static int ebcdic_write(BIO *b, const char *in, int inl); +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); +static int ebcdic_gets(BIO *bp, char *buf, int size); +static int ebcdic_puts(BIO *bp, const char *str); + +#define BIO_TYPE_EBCDIC_FILTER	(18|0x0200) +static BIO_METHOD methods_ebcdic= +	{ +	BIO_TYPE_EBCDIC_FILTER, +	"EBCDIC/ASCII filter", +	ebcdic_write, +	ebcdic_read, +	ebcdic_puts, +	ebcdic_gets, +	ebcdic_ctrl, +	ebcdic_new, +	ebcdic_free, +	}; + +typedef struct +{ +	size_t	alloced; +	char	buff[1]; +} EBCDIC_OUTBUFF; + +BIO_METHOD *BIO_f_ebcdic_filter() +{ +	return(&methods_ebcdic); +} + +static int ebcdic_new(BIO *bi) +{ +	EBCDIC_OUTBUFF *wbuf; + +	wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024); +	wbuf->alloced = 1024; +	wbuf->buff[0] = '\0'; + +	bi->ptr=(char *)wbuf; +	bi->init=1; +	bi->flags=0; +	return(1); +} + +static int ebcdic_free(BIO *a) +{ +	if (a == NULL) return(0); +	if (a->ptr != NULL) +		OPENSSL_free(a->ptr); +	a->ptr=NULL; +	a->init=0; +	a->flags=0; +	return(1); +} +	 +static int ebcdic_read(BIO *b, char *out, int outl) +{ +	int ret=0; + +	if (out == NULL || outl == 0) return(0); +	if (b->next_bio == NULL) return(0); + +	ret=BIO_read(b->next_bio,out,outl); +	if (ret > 0) +		ascii2ebcdic(out,out,ret); +	return(ret); +} + +static int ebcdic_write(BIO *b, const char *in, int inl) +{ +	EBCDIC_OUTBUFF *wbuf; +	int ret=0; +	int num; +	unsigned char n; + +	if ((in == NULL) || (inl <= 0)) return(0); +	if (b->next_bio == NULL) return(0); + +	wbuf=(EBCDIC_OUTBUFF *)b->ptr; + +	if (inl > (num = wbuf->alloced)) +	{ +		num = num + num;  /* double the size */ +		if (num < inl) +			num = inl; +		OPENSSL_free(wbuf); +		wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); + +		wbuf->alloced = num; +		wbuf->buff[0] = '\0'; + +		b->ptr=(char *)wbuf; +	} + +	ebcdic2ascii(wbuf->buff, in, inl); + +	ret=BIO_write(b->next_bio, wbuf->buff, inl); + +	return(ret); +} + +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) +{ +	long ret; + +	if (b->next_bio == NULL) return(0); +	switch (cmd) +	{ +	case BIO_CTRL_DUP: +		ret=0L; +		break; +	default: +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr); +		break; +	} +	return(ret); +} + +static int ebcdic_gets(BIO *bp, char *buf, int size) +{ +	int i, ret=0; +	if (bp->next_bio == NULL) return(0); +/*	return(BIO_gets(bp->next_bio,buf,size));*/ +	for (i=0; i<size-1; ++i) +	{ +		ret = ebcdic_read(bp,&buf[i],1); +		if (ret <= 0) +			break; +		else if (buf[i] == '\n') +		{ +			++i; +			break; +		} +	} +	if (i < size) +		buf[i] = '\0'; +	return (ret < 0 && i == 0) ? ret : i; +} + +static int ebcdic_puts(BIO *bp, const char *str) +{ +	if (bp->next_bio == NULL) return(0); +	return ebcdic_write(bp, str, strlen(str)); +} +#endif + +#ifndef OPENSSL_NO_TLSEXT + +/* This is a context that we pass to callbacks */ +typedef struct tlsextctx_st { +   char * servername; +   BIO * biodebug; +   int extension_error; +} tlsextctx; + + +static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) +	{ +	tlsextctx * p = (tlsextctx *) arg; +	const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); +        if (servername && p->biodebug)  +		BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername); +         +	if (!p->servername) +		return SSL_TLSEXT_ERR_NOACK; +	 +	if (servername) +		{ +    		if (strcmp(servername,p->servername))  +			return p->extension_error; +		if (ctx2) +			{ +			BIO_printf(p->biodebug,"Switching server context.\n"); +			SSL_set_SSL_CTX(s,ctx2); +			}      +		} +	return SSL_TLSEXT_ERR_OK; +} + +/* Structure passed to cert status callback */ + +typedef struct tlsextstatusctx_st { +   /* Default responder to use */ +   char *host, *path, *port; +   int use_ssl; +   int timeout; +   BIO *err; +   int verbose; +} tlsextstatusctx; + +static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0}; + +/* Certificate Status callback. This is called when a client includes a + * certificate status request extension. + * + * This is a simplified version. It examines certificates each time and + * makes one OCSP responder query for each request. + * + * A full version would store details such as the OCSP certificate IDs and + * minimise the number of OCSP responses by caching them until they were + * considered "expired". + */ + +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; +	int rspderlen; +	STACK_OF(OPENSSL_STRING) *aia = NULL; +	X509 *x = NULL; +	X509_STORE_CTX inctx; +	X509_OBJECT obj; +	OCSP_REQUEST *req = NULL; +	OCSP_RESPONSE *resp = NULL; +	OCSP_CERTID *id = NULL; +	STACK_OF(X509_EXTENSION) *exts; +	int ret = SSL_TLSEXT_ERR_NOACK; +	int i; +#if 0 +STACK_OF(OCSP_RESPID) *ids; +SSL_get_tlsext_status_ids(s, &ids); +BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids)); +#endif +	if (srctx->verbose) +		BIO_puts(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"); +			goto err; +			} +		if (srctx->verbose) +			BIO_printf(err, "cert_status: AIA URL: %s\n", +					sk_OPENSSL_STRING_value(aia, 0)); +		} +	else +		{ +		if (!srctx->host) +			{ +			BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n"); +			goto done; +			} +		host = srctx->host; +		path = srctx->path; +		port = srctx->port; +		use_ssl = srctx->use_ssl; +		} +		 +	if (!X509_STORE_CTX_init(&inctx, +				SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), +				NULL, NULL)) +		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"); +		X509_STORE_CTX_cleanup(&inctx); +		goto done; +		} +	req = OCSP_REQUEST_new(); +	if (!req) +		goto err; +	id = OCSP_cert_to_id(NULL, x, obj.data.x509); +	X509_free(obj.data.x509); +	X509_STORE_CTX_cleanup(&inctx); +	if (!id) +		goto err; +	if (!OCSP_request_add0_id(req, id)) +		goto err; +	id = NULL; +	/* Add any extensions to the request */ +	SSL_get_tlsext_status_exts(s, &exts); +	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) +		{ +		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); +		if (!OCSP_REQUEST_add_ext(req, ext, -1)) +			goto err; +		} +	resp = process_responder(err, req, host, path, port, use_ssl, NULL, +					srctx->timeout); +	if (!resp) +		{ +		BIO_puts(err, "cert_status: error querying responder\n"); +		goto done; +		} +	rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); +	if (rspderlen <= 0) +		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); +		} +	ret = SSL_TLSEXT_ERR_OK; +	done: +	if (ret != SSL_TLSEXT_ERR_OK) +		ERR_print_errors(err); +	if (aia) +		{ +		OPENSSL_free(host); +		OPENSSL_free(path); +		OPENSSL_free(port); +		X509_email_free(aia); +		} +	if (id) +		OCSP_CERTID_free(id); +	if (req) +		OCSP_REQUEST_free(req); +	if (resp) +		OCSP_RESPONSE_free(resp); +	return ret; +	err: +	ret = SSL_TLSEXT_ERR_ALERT_FATAL; +	goto done; +	} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is the context that we pass to next_proto_cb */ +typedef struct tlsextnextprotoctx_st { +	unsigned char *data; +	unsigned int len; +} tlsextnextprotoctx; + +static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, void *arg) +	{ +	tlsextnextprotoctx *next_proto = arg; + +	*data = next_proto->data; +	*len = next_proto->len; + +	return SSL_TLSEXT_ERR_OK; +	} +# endif  /* ndef OPENSSL_NO_NPN */ +#endif + +int MAIN(int, char **); + +#ifndef OPENSSL_NO_JPAKE +static char *jpake_secret = NULL; +#endif + +int MAIN(int argc, char *argv[]) +	{ +	X509_VERIFY_PARAM *vpm = NULL; +	int badarg = 0; +	short port=PORT; +	char *CApath=NULL,*CAfile=NULL; +	unsigned char *context = NULL; +	char *dhfile = NULL; +#ifndef OPENSSL_NO_ECDH +	char *named_curve = NULL; +#endif +	int badop=0,bugs=0; +	int ret=1; +	int off=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 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; +	EVP_PKEY *s_key = NULL, *s_dkey = NULL; +	int no_cache = 0; +#ifndef OPENSSL_NO_TLSEXT +	EVP_PKEY *s_key2 = NULL; +	X509 *s_cert2 = NULL; +#endif +#ifndef OPENSSL_NO_TLSEXT +        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; +# ifndef OPENSSL_NO_NEXTPROTONEG +	const char *next_proto_neg_in = NULL; +	tlsextnextprotoctx next_proto; +# endif +#endif +#ifndef OPENSSL_NO_PSK +	/* by default do not send a PSK identity hint */ +	static char *psk_identity_hint=NULL; +#endif +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +	meth=SSLv23_server_method(); +#elif !defined(OPENSSL_NO_SSL3) +	meth=SSLv3_server_method(); +#elif !defined(OPENSSL_NO_SSL2) +	meth=SSLv2_server_method(); +#endif + +	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; + +	verify_depth=0; +#ifdef FIONBIO +	s_nbio=0; +#endif +	s_nbio_test=0; + +	argc--; +	argv++; + +	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,"-verify") == 0) +			{ +			s_server_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,"-Verify") == 0) +			{ +			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)); +			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,"-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,"-dhparam") == 0) +			{ +			if (--argc < 1) goto bad; +			dhfile = *(++argv); +			} +#ifndef OPENSSL_NO_ECDH		 +		else if	(strcmp(*argv,"-named_curve") == 0) +			{ +			if (--argc < 1) goto bad; +			named_curve = *(++argv); +			} +#endif +		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,"-nocert") == 0) +			{ +			nocert=1; +			} +		else if	(strcmp(*argv,"-CApath") == 0) +			{ +			if (--argc < 1) goto bad; +			CApath= *(++argv); +			} +		else if (strcmp(*argv,"-no_cache") == 0) +			no_cache = 1; +		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) +			{ +			if (badarg) +				goto bad; +			continue; +			} +		else if (strcmp(*argv,"-verify_return_error") == 0) +			verify_return_error = 1; +		else if	(strcmp(*argv,"-serverpref") == 0) +			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } +		else if (strcmp(*argv,"-legacy_renegotiation") == 0) +			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; +		else if	(strcmp(*argv,"-cipher") == 0) +			{ +			if (--argc < 1) goto bad; +			cipher= *(++argv); +			} +		else if	(strcmp(*argv,"-CAfile") == 0) +			{ +			if (--argc < 1) goto bad; +			CAfile= *(++argv); +			} +#ifdef FIONBIO	 +		else if	(strcmp(*argv,"-nbio") == 0) +			{ s_nbio=1; } +#endif +		else if	(strcmp(*argv,"-nbio_test") == 0) +			{ +#ifdef FIONBIO	 +			s_nbio=1; +#endif +			s_nbio_test=1; +			} +		else if	(strcmp(*argv,"-debug") == 0) +			{ s_debug=1; } +#ifndef OPENSSL_NO_TLSEXT +		else if	(strcmp(*argv,"-tlsextdebug") == 0) +			s_tlsextdebug=1; +		else if	(strcmp(*argv,"-status") == 0) +			s_tlsextstatus=1; +		else if	(strcmp(*argv,"-status_verbose") == 0) +			{ +			s_tlsextstatus=1; +			tlscstatp.verbose = 1; +			} +		else if (!strcmp(*argv, "-status_timeout")) +			{ +			s_tlsextstatus=1; +                        if (--argc < 1) goto bad; +			tlscstatp.timeout = atoi(*(++argv)); +			} +		else if (!strcmp(*argv, "-status_url")) +			{ +			s_tlsextstatus=1; +                        if (--argc < 1) goto bad; +			if (!OCSP_parse_url(*(++argv), +					&tlscstatp.host, +					&tlscstatp.port, +					&tlscstatp.path, +					&tlscstatp.use_ssl)) +				{ +				BIO_printf(bio_err, "Error parsing URL\n"); +				goto bad; +				} +			} +#endif +		else if	(strcmp(*argv,"-msg") == 0) +			{ s_msg=1; } +		else if	(strcmp(*argv,"-hack") == 0) +			{ hack=1; } +		else if	(strcmp(*argv,"-state") == 0) +			{ state=1; } +		else if	(strcmp(*argv,"-crlf") == 0) +			{ s_crlf=1; } +		else if	(strcmp(*argv,"-quiet") == 0) +			{ s_quiet=1; } +		else if	(strcmp(*argv,"-bugs") == 0) +			{ bugs=1; } +		else if	(strcmp(*argv,"-no_tmp_rsa") == 0) +			{ no_tmp_rsa=1; } +		else if	(strcmp(*argv,"-no_dhe") == 0) +			{ no_dhe=1; } +		else if	(strcmp(*argv,"-no_ecdhe") == 0) +			{ no_ecdhe=1; } +#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((int)psk_key[i])) +					continue; +				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv); +				goto bad; +				} +			} +#endif +		else if	(strcmp(*argv,"-www") == 0) +			{ www=1; } +		else if	(strcmp(*argv,"-WWW") == 0) +			{ www=2; } +		else if	(strcmp(*argv,"-HTTP") == 0) +			{ www=3; } +		else if	(strcmp(*argv,"-no_ssl2") == 0) +			{ off|=SSL_OP_NO_SSLv2; } +		else if	(strcmp(*argv,"-no_ssl3") == 0) +			{ off|=SSL_OP_NO_SSLv3; } +		else if	(strcmp(*argv,"-no_tls1") == 0) +			{ off|=SSL_OP_NO_TLSv1; } +		else if	(strcmp(*argv,"-no_comp") == 0) +			{ off|=SSL_OP_NO_COMPRESSION; } +#ifndef OPENSSL_NO_TLSEXT +		else if	(strcmp(*argv,"-no_ticket") == 0) +			{ off|=SSL_OP_NO_TICKET; } +#endif +#ifndef OPENSSL_NO_SSL2 +		else if	(strcmp(*argv,"-ssl2") == 0) +			{ meth=SSLv2_server_method(); } +#endif +#ifndef OPENSSL_NO_SSL3 +		else if	(strcmp(*argv,"-ssl3") == 0) +			{ meth=SSLv3_server_method(); } +#endif +#ifndef OPENSSL_NO_TLS1 +		else if	(strcmp(*argv,"-tls1") == 0) +			{ meth=TLSv1_server_method(); } +#endif +#ifndef OPENSSL_NO_DTLS1 +		else if	(strcmp(*argv,"-dtls1") == 0) +			{  +			meth=DTLSv1_server_method(); +			socket_type = SOCK_DGRAM; +			} +		else if (strcmp(*argv,"-timeout") == 0) +			enable_timeouts = 1; +		else if (strcmp(*argv,"-mtu") == 0) +			{ +			if (--argc < 1) goto bad; +			socket_mtu = atol(*(++argv)); +			} +		else if (strcmp(*argv, "-chain") == 0) +			cert_chain = 1; +#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); +			} +#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) +			{ 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); +			} +# ifndef OPENSSL_NO_NEXTPROTONEG +		else if	(strcmp(*argv,"-nextprotoneg") == 0) +			{ +			if (--argc < 1) goto bad; +			next_proto_neg_in = *(++argv); +			} +# endif +#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 +		else +			{ +			BIO_printf(bio_err,"unknown option %s\n",*argv); +			badop=1; +			break; +			} +		argc--; +		argv++; +		} +	if (badop) +		{ +bad: +		sv_usage(); +		goto end; +		} + +#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK) +	if (jpake_secret) +		{ +		if (psk_key) +			{ +			BIO_printf(bio_err, +				   "Can't use JPAKE and PSK together\n"); +			goto end; +			} +		psk_identity = "JPAKE"; +		if (cipher) +			{ +			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n"); +			goto end; +			} +		cipher = "PSK"; +		} + +#endif + +	SSL_load_error_strings(); +	OpenSSL_add_ssl_algorithms(); + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine_id, 1); +#endif + +	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) +		{ +		BIO_printf(bio_err, "Error getting password\n"); +		goto end; +		} + + +	if (s_key_file == NULL) +		s_key_file = s_cert_file; +#ifndef OPENSSL_NO_TLSEXT +	if (s_key_file2 == NULL) +		s_key_file2 = s_cert_file2; +#endif + +	if (nocert == 0) +		{ +		s_key = load_key(bio_err, 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, +			NULL, e, "server certificate file"); + +		if (!s_cert) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} + +#ifndef OPENSSL_NO_TLSEXT +		if (tlsextcbp.servername)  +			{ +			s_key2 = load_key(bio_err, 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, +				NULL, e, "second server certificate file"); +			 +			if (!s_cert2) +				{ +				ERR_print_errors(bio_err); +				goto end; +				} +			} +#endif +		} + + +	if (s_dcert_file) +		{ + +		if (s_dkey_file == NULL) +			s_dkey_file = s_dcert_file; + +		s_dkey = load_key(bio_err, 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, +				NULL, e, "second server certificate file"); + +		if (!s_dcert) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} + +		} + +	if (!app_RAND_load_file(NULL, bio_err, 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 (bio_s_out == NULL) +		{ +		if (s_quiet && !s_debug && !s_msg) +			{ +			bio_s_out=BIO_new(BIO_s_null()); +			} +		else +			{ +			if (bio_s_out == NULL) +				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE); +			} +		} + +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) +	if (nocert) +#endif +		{ +		s_cert_file=NULL; +		s_key_file=NULL; +		s_dcert_file=NULL; +		s_dkey_file=NULL; +#ifndef OPENSSL_NO_TLSEXT +		s_cert_file2=NULL; +		s_key_file2=NULL; +#endif +		} + +	ctx=SSL_CTX_new(meth); +	if (ctx == NULL) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} +	if (session_id_prefix) +		{ +		if(strlen(session_id_prefix) >= 32) +			BIO_printf(bio_err, +"warning: id_prefix is too long, only one new session will be possible\n"); +		else if(strlen(session_id_prefix) >= 16) +			BIO_printf(bio_err, +"warning: id_prefix is too long if you use SSLv2\n"); +		if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) +			{ +			BIO_printf(bio_err,"error setting 'id_prefix'\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +		BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); +		} +	SSL_CTX_set_quiet_shutdown(ctx,1); +	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL); +	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); +	SSL_CTX_set_options(ctx,off); +	/* DTLS: partial reads end up discarding unread UDP bytes :-(  +	 * Setting read ahead solves this problem. +	 */ +	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); + +	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); +	if (no_cache) +		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); +	else +		SSL_CTX_sess_set_cache_size(ctx,128); + +#if 0 +	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); +#endif + +#if 0 +	if (s_cert_file == NULL) +		{ +		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n"); +		goto end; +		} +#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"); */ +		ERR_print_errors(bio_err); +		/* goto end; */ +		} +	if (vpm) +		SSL_CTX_set1_param(ctx, vpm); + +#ifndef OPENSSL_NO_TLSEXT +	if (s_cert2) +		{ +		ctx2=SSL_CTX_new(meth); +		if (ctx2 == NULL) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} +	 +	if (ctx2) +		{ +		BIO_printf(bio_s_out,"Setting secondary ctx parameters\n"); + +		if (session_id_prefix) +			{ +			if(strlen(session_id_prefix) >= 32) +				BIO_printf(bio_err, +					"warning: id_prefix is too long, only one new session will be possible\n"); +			else if(strlen(session_id_prefix) >= 16) +				BIO_printf(bio_err, +					"warning: id_prefix is too long if you use SSLv2\n"); +			if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) +				{ +				BIO_printf(bio_err,"error setting 'id_prefix'\n"); +				ERR_print_errors(bio_err); +				goto end; +				} +			BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); +			} +		SSL_CTX_set_quiet_shutdown(ctx2,1); +		if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL); +		if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); +		SSL_CTX_set_options(ctx2,off); +		/* DTLS: partial reads end up discarding unread UDP bytes :-(  +		 * Setting read ahead solves this problem. +		 */ +		if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1); + +		if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback); + +		if (no_cache) +			SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF); +		else +			SSL_CTX_sess_set_cache_size(ctx2,128); + +		if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) || +			(!SSL_CTX_set_default_verify_paths(ctx2))) +			{ +			ERR_print_errors(bio_err); +			} +		if (vpm) +			SSL_CTX_set1_param(ctx2, vpm); +		} + +# ifndef OPENSSL_NO_NEXTPROTONEG +	if (next_proto.data) +		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto); +# endif +#endif  + +#ifndef OPENSSL_NO_DH +	if (!no_dhe) +		{ +		DH *dh=NULL; + +		if (dhfile) +			dh = load_dh_param(dhfile); +		else if (s_cert_file) +			dh = load_dh_param(s_cert_file); + +		if (dh != NULL) +			{ +			BIO_printf(bio_s_out,"Setting temp DH parameters\n"); +			} +		else +			{ +			BIO_printf(bio_s_out,"Using default temp DH parameters\n"); +			dh=get_dh512(); +			} +		(void)BIO_flush(bio_s_out); + +		SSL_CTX_set_tmp_dh(ctx,dh); +#ifndef OPENSSL_NO_TLSEXT +		if (ctx2) +			{ +			if (!dhfile) +				{  +				DH *dh2=load_dh_param(s_cert_file2); +				if (dh2 != NULL) +					{ +					BIO_printf(bio_s_out,"Setting temp DH parameters\n"); +					(void)BIO_flush(bio_s_out); + +					DH_free(dh); +					dh = dh2; +					} +				} +			SSL_CTX_set_tmp_dh(ctx2,dh); +			} +#endif +		DH_free(dh); +		} +#endif + +#ifndef OPENSSL_NO_ECDH +	if (!no_ecdhe) +		{ +		EC_KEY *ecdh=NULL; + +		if (named_curve) +			{ +			int nid = OBJ_sn2nid(named_curve); + +			if (nid == 0) +				{ +				BIO_printf(bio_err, "unknown curve name (%s)\n",  +					named_curve); +				goto end; +				} +			ecdh = EC_KEY_new_by_curve_name(nid); +			if (ecdh == NULL) +				{ +				BIO_printf(bio_err, "unable to create curve (%s)\n",  +					named_curve); +				goto end; +				} +			} + +		if (ecdh != NULL) +			{ +			BIO_printf(bio_s_out,"Setting temp ECDH parameters\n"); +			} +		else +			{ +			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n"); +			ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); +			if (ecdh == NULL)  +				{ +				BIO_printf(bio_err, "unable to create curve (nistp256)\n"); +				goto end; +				} +			} +		(void)BIO_flush(bio_s_out); + +		SSL_CTX_set_tmp_ecdh(ctx,ecdh); +#ifndef OPENSSL_NO_TLSEXT +		if (ctx2)  +			SSL_CTX_set_tmp_ecdh(ctx2,ecdh); +#endif +		EC_KEY_free(ecdh); +		} +#endif +	 +	if (!set_cert_key_stuff(ctx,s_cert,s_key)) +		goto end; +#ifndef OPENSSL_NO_TLSEXT +	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2)) +		goto end;  +#endif +	if (s_dcert != NULL) +		{ +		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey)) +			goto end; +		} + +#ifndef OPENSSL_NO_RSA +#if 1 +	if (!no_tmp_rsa) +		{ +		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); +#ifndef OPENSSL_NO_TLSEXT +		if (ctx2)  +			SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb); +#endif		 +		} +#else +	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) +		{ +		RSA *rsa; + +		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key..."); +		BIO_flush(bio_s_out); + +		rsa=RSA_generate_key(512,RSA_F4,NULL); + +		if (!SSL_CTX_set_tmp_rsa(ctx,rsa)) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +#ifndef OPENSSL_NO_TLSEXT +			if (ctx2) +				{ +				if (!SSL_CTX_set_tmp_rsa(ctx2,rsa)) +					{ +					ERR_print_errors(bio_err); +					goto end; +					} +				} +# ifndef OPENSSL_NO_NEXTPROTONEG +		if (next_proto_neg_in) +			{ +			unsigned short len; +			next_proto.data = next_protos_parse(&len, +				next_proto_neg_in); +			if (next_proto.data == NULL) +				goto end; +			next_proto.len = len; +			} +		else +			{ +			next_proto.data = NULL; +			} +# endif +#endif +		RSA_free(rsa); +		BIO_printf(bio_s_out,"\n"); +		} +#endif +#endif + +#ifndef OPENSSL_NO_PSK +#ifdef OPENSSL_NO_JPAKE +	if (psk_key != NULL) +#else +	if (psk_key != NULL || jpake_secret) +#endif +		{ +		if (s_debug) +			BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n"); +		SSL_CTX_set_psk_server_callback(ctx, psk_server_cb); +		} + +	if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) +		{ +		BIO_printf(bio_err,"error setting PSK identity hint to context\n"); +		ERR_print_errors(bio_err); +		goto end; +		} +#endif + +	if (cipher != NULL) +		{ +		if(!SSL_CTX_set_cipher_list(ctx,cipher)) +			{ +			BIO_printf(bio_err,"error setting cipher list\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +#ifndef OPENSSL_NO_TLSEXT +		if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher)) +			{ +			BIO_printf(bio_err,"error setting cipher list\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +#endif +		} +	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); +	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, +		sizeof s_server_session_id_context); + +	/* Set DTLS cookie generation and verification callbacks */ +	SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); +	SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); + +#ifndef OPENSSL_NO_TLSEXT +	if (ctx2) +		{ +		SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback); +		SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context, +			sizeof s_server_session_id_context); + +		tlsextcbp.biodebug = bio_s_out; +		SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); +		SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); +		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); +		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); +		} +#endif + +	if (CAfile != NULL) +		{ +		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); +#ifndef OPENSSL_NO_TLSEXT +		if (ctx2)  +			SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile)); +#endif +		} + +	BIO_printf(bio_s_out,"ACCEPT\n"); +	(void)BIO_flush(bio_s_out); +	if (www) +		do_server(port,socket_type,&accept_socket,www_body, context); +	else +		do_server(port,socket_type,&accept_socket,sv_body, context); +	print_stats(bio_s_out,ctx); +	ret=0; +end: +	if (ctx != NULL) SSL_CTX_free(ctx); +	if (s_cert) +		X509_free(s_cert); +	if (s_dcert) +		X509_free(s_dcert); +	if (s_key) +		EVP_PKEY_free(s_key); +	if (s_dkey) +		EVP_PKEY_free(s_dkey); +	if (pass) +		OPENSSL_free(pass); +	if (dpass) +		OPENSSL_free(dpass); +#ifndef OPENSSL_NO_TLSEXT +	if (ctx2 != NULL) SSL_CTX_free(ctx2); +	if (s_cert2) +		X509_free(s_cert2); +	if (s_key2) +		EVP_PKEY_free(s_key2); +#endif +	if (bio_s_out != NULL) +		{ +        BIO_free(bio_s_out); +		bio_s_out=NULL; +		} +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) +	{ +	BIO_printf(bio,"%4ld items in the session cache\n", +		SSL_CTX_sess_number(ssl_ctx)); +	BIO_printf(bio,"%4ld client connects (SSL_connect())\n", +		SSL_CTX_sess_connect(ssl_ctx)); +	BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n", +		SSL_CTX_sess_connect_renegotiate(ssl_ctx)); +	BIO_printf(bio,"%4ld client connects that finished\n", +		SSL_CTX_sess_connect_good(ssl_ctx)); +	BIO_printf(bio,"%4ld server accepts (SSL_accept())\n", +		SSL_CTX_sess_accept(ssl_ctx)); +	BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n", +		SSL_CTX_sess_accept_renegotiate(ssl_ctx)); +	BIO_printf(bio,"%4ld server accepts that finished\n", +		SSL_CTX_sess_accept_good(ssl_ctx)); +	BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx)); +	BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx)); +	BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx)); +	BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx)); +	BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n", +		SSL_CTX_sess_cache_full(ssl_ctx), +		SSL_CTX_sess_get_cache_size(ssl_ctx)); +	} + +static int sv_body(char *hostname, int s, unsigned char *context) +	{ +	char *buf=NULL; +	fd_set readfds; +	int ret=1,width; +	int k,i; +	unsigned long l; +	SSL *con=NULL; +	BIO *sbio; +	struct timeval timeout; +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) +	struct timeval tv; +#else +	struct timeval *timeoutp; +#endif + +	if ((buf=OPENSSL_malloc(bufsize)) == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		goto err; +		} +#ifdef FIONBIO	 +	if (s_nbio) +		{ +		unsigned long sl=1; + +		if (!s_quiet) +			BIO_printf(bio_err,"turning on non blocking io\n"); +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) +			ERR_print_errors(bio_err); +		} +#endif + +	if (con == NULL) { +		con=SSL_new(ctx); +#ifndef OPENSSL_NO_TLSEXT +	if (s_tlsextdebug) +		{ +		SSL_set_tlsext_debug_callback(con, tlsext_cb); +		SSL_set_tlsext_debug_arg(con, bio_s_out); +		} +	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 ((con->kssl_ctx = kssl_ctx_new()) != NULL) +                        { +                        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, +								KRB5SVC); +                        kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, +								KRB5KEYTAB); +                        } +#endif	/* OPENSSL_NO_KRB5 */ +		if(context) +		      SSL_set_session_id_context(con, context, +						 strlen((char *)context)); +	} +	SSL_clear(con); +#if 0 +#ifdef TLSEXT_TYPE_opaque_prf_input +	SSL_set_tlsext_opaque_prf_input(con, "Test server", 11); +#endif +#endif + +	if (SSL_version(con) == DTLS1_VERSION) +		{ + +		sbio=BIO_new_dgram(s,BIO_NOCLOSE); + +		if (enable_timeouts) +			{ +			timeout.tv_sec = 0; +			timeout.tv_usec = DGRAM_RCV_TIMEOUT; +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); +			 +			timeout.tv_sec = 0; +			timeout.tv_usec = DGRAM_SND_TIMEOUT; +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); +			} + +		if (socket_mtu > 28) +			{ +			SSL_set_options(con, SSL_OP_NO_QUERY_MTU); +			SSL_set_mtu(con, socket_mtu - 28); +			} +		else +			/* want to do MTU discovery */ +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); + +        /* turn on cookie exchange */ +        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); +		} +	else +		sbio=BIO_new_socket(s,BIO_NOCLOSE); + +	if (s_nbio_test) +		{ +		BIO *test; + +		test=BIO_new(BIO_f_nbio_test()); +		sbio=BIO_push(test,sbio); +		} +#ifndef OPENSSL_NO_JPAKE +	if(jpake_secret) +		jpake_server_auth(bio_s_out, sbio, jpake_secret); +#endif + +	SSL_set_bio(con,sbio,sbio); +	SSL_set_accept_state(con); +	/* SSL_set_fd(con,s); */ + +	if (s_debug) +		{ +		con->debug=1; +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); +		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); +		} +	if (s_msg) +		{ +		SSL_set_msg_callback(con, msg_cb); +		SSL_set_msg_callback_arg(con, bio_s_out); +		} +#ifndef OPENSSL_NO_TLSEXT +	if (s_tlsextdebug) +		{ +		SSL_set_tlsext_debug_callback(con, tlsext_cb); +		SSL_set_tlsext_debug_arg(con, bio_s_out); +		} +#endif + +	width=s+1; +	for (;;) +		{ +		int read_from_terminal; +		int read_from_sslcon; + +		read_from_terminal = 0; +		read_from_sslcon = SSL_pending(con); + +		if (!read_from_sslcon) +			{ +			FD_ZERO(&readfds); +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5) +			openssl_fdset(fileno(stdin),&readfds); +#endif +			openssl_fdset(s,&readfds); +			/* Note: under VMS with SOCKETSHR the second parameter is +			 * currently of type (int *) whereas under other systems +			 * it is (void *) if you don't have a cast it will choke +			 * the compiler: if you do have a cast then you can either +			 * go for (int *) or (void *). +			 */ +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) +                        /* Under DOS (non-djgpp) and Windows we can't select on stdin: only +			 * on sockets. As a workaround we timeout the select every +			 * second and check for any keypress. In a proper Windows +			 * application we wouldn't do this because it is inefficient. +			 */ +			tv.tv_sec = 1; +			tv.tv_usec = 0; +			i=select(width,(void *)&readfds,NULL,NULL,&tv); +			if((i < 0) || (!i && !_kbhit() ) )continue; +			if(_kbhit()) +				read_from_terminal = 1; +#elif defined(OPENSSL_SYS_BEOS_R5) +			/* Under BeOS-R5 the situation is similar to DOS */ +			tv.tv_sec = 1; +			tv.tv_usec = 0; +			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); +			i=select(width,(void *)&readfds,NULL,NULL,&tv); +			if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0)) +				continue; +			if (read(fileno(stdin), buf, 0) >= 0) +				read_from_terminal = 1; +			(void)fcntl(fileno(stdin), F_SETFL, 0); +#else +			if ((SSL_version(con) == DTLS1_VERSION) && +				DTLSv1_get_timeout(con, &timeout)) +				timeoutp = &timeout; +			else +				timeoutp = NULL; + +			i=select(width,(void *)&readfds,NULL,NULL,timeoutp); + +			if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) +				{ +				BIO_printf(bio_err,"TIMEOUT occured\n"); +				} + +			if (i <= 0) continue; +			if (FD_ISSET(fileno(stdin),&readfds)) +				read_from_terminal = 1; +#endif +			if (FD_ISSET(s,&readfds)) +				read_from_sslcon = 1; +			} +		if (read_from_terminal) +			{ +			if (s_crlf) +				{ +				int j, lf_num; + +				i=raw_read_stdin(buf, bufsize/2); +				lf_num = 0; +				/* both loops are skipped when i <= 0 */ +				for (j = 0; j < i; j++) +					if (buf[j] == '\n') +						lf_num++; +				for (j = i-1; j >= 0; j--) +					{ +					buf[j+lf_num] = buf[j]; +					if (buf[j] == '\n') +						{ +						lf_num--; +						i++; +						buf[j+lf_num] = '\r'; +						} +					} +				assert(lf_num == 0); +				} +			else +				i=raw_read_stdin(buf,bufsize); +			if (!s_quiet) +				{ +				if ((i <= 0) || (buf[0] == 'Q')) +					{ +					BIO_printf(bio_s_out,"DONE\n"); +					SHUTDOWN(s); +					close_accept_socket(); +					ret= -11; +					goto err; +					} +				if ((i <= 0) || (buf[0] == 'q')) +					{ +					BIO_printf(bio_s_out,"DONE\n"); +					if (SSL_version(con) != DTLS1_VERSION) +                        SHUTDOWN(s); +	/*				close_accept_socket(); +					ret= -11;*/ +					goto err; +					} + +				if ((buf[0] == 'r') &&  +					((buf[1] == '\n') || (buf[1] == '\r'))) +					{ +					SSL_renegotiate(con); +					i=SSL_do_handshake(con); +					printf("SSL_do_handshake -> %d\n",i); +					i=0; /*13; */ +					continue; +					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */ +					} +				if ((buf[0] == 'R') && +					((buf[1] == '\n') || (buf[1] == '\r'))) +					{ +					SSL_set_verify(con, +						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL); +					SSL_renegotiate(con); +					i=SSL_do_handshake(con); +					printf("SSL_do_handshake -> %d\n",i); +					i=0; /* 13; */ +					continue; +					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */ +					} +				if (buf[0] == 'P') +					{ +					static const char *str="Lets print some clear text\n"; +					BIO_write(SSL_get_wbio(con),str,strlen(str)); +					} +				if (buf[0] == 'S') +					{ +					print_stats(bio_s_out,SSL_get_SSL_CTX(con)); +					} +				} +#ifdef CHARSET_EBCDIC +			ebcdic2ascii(buf,buf,i); +#endif +			l=k=0; +			for (;;) +				{ +				/* should do a select for the write */ +#ifdef RENEG +{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } } +#endif +				k=SSL_write(con,&(buf[l]),(unsigned int)i); +				switch (SSL_get_error(con,k)) +					{ +				case SSL_ERROR_NONE: +					break; +				case SSL_ERROR_WANT_WRITE: +				case SSL_ERROR_WANT_READ: +				case SSL_ERROR_WANT_X509_LOOKUP: +					BIO_printf(bio_s_out,"Write BLOCK\n"); +					break; +				case SSL_ERROR_SYSCALL: +				case SSL_ERROR_SSL: +					BIO_printf(bio_s_out,"ERROR\n"); +					ERR_print_errors(bio_err); +					ret=1; +					goto err; +					/* break; */ +				case SSL_ERROR_ZERO_RETURN: +					BIO_printf(bio_s_out,"DONE\n"); +					ret=1; +					goto err; +					} +				l+=k; +				i-=k; +				if (i <= 0) break; +				} +			} +		if (read_from_sslcon) +			{ +			if (!SSL_is_init_finished(con)) +				{ +				i=init_ssl_connection(con); +				 +				if (i < 0) +					{ +					ret=0; +					goto err; +					} +				else if (i == 0) +					{ +					ret=1; +					goto err; +					} +				} +			else +				{ +again:	 +				i=SSL_read(con,(char *)buf,bufsize); +				switch (SSL_get_error(con,i)) +					{ +				case SSL_ERROR_NONE: +#ifdef CHARSET_EBCDIC +					ascii2ebcdic(buf,buf,i); +#endif +					raw_write_stdout(buf, +						(unsigned int)i); +					if (SSL_pending(con)) goto again; +					break; +				case SSL_ERROR_WANT_WRITE: +				case SSL_ERROR_WANT_READ: +				case SSL_ERROR_WANT_X509_LOOKUP: +					BIO_printf(bio_s_out,"Read BLOCK\n"); +					break; +				case SSL_ERROR_SYSCALL: +				case SSL_ERROR_SSL: +					BIO_printf(bio_s_out,"ERROR\n"); +					ERR_print_errors(bio_err); +					ret=1; +					goto err; +				case SSL_ERROR_ZERO_RETURN: +					BIO_printf(bio_s_out,"DONE\n"); +					ret=1; +					goto err; +					} +				} +			} +		} +err: +	if (con != NULL) +		{ +		BIO_printf(bio_s_out,"shutting down SSL\n"); +#if 1 +		SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +#else +		SSL_shutdown(con); +#endif +		SSL_free(con); +		} +	BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); +	if (buf != NULL) +		{ +		OPENSSL_cleanse(buf,bufsize); +		OPENSSL_free(buf); +		} +	if (ret >= 0) +		BIO_printf(bio_s_out,"ACCEPT\n"); +	return(ret); +	} + +static void close_accept_socket(void) +	{ +	BIO_printf(bio_err,"shutdown accept socket\n"); +	if (accept_socket >= 0) +		{ +		SHUTDOWN2(accept_socket); +		} +	} + +static int init_ssl_connection(SSL *con) +	{ +	int i; +	const char *str; +	X509 *peer; +	long verify_error; +	MS_STATIC char buf[BUFSIZ]; +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +	const unsigned char *next_proto_neg; +	unsigned next_proto_neg_len; +#endif + +	if ((i=SSL_accept(con)) <= 0) +		{ +		if (BIO_sock_should_retry(i)) +			{ +			BIO_printf(bio_s_out,"DELAY\n"); +			return(1); +			} + +		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", +				X509_verify_cert_error_string(verify_error)); +			} +		else +			ERR_print_errors(bio_err); +		return(0); +		} + +	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); + +	peer=SSL_get_peer_certificate(con); +	if (peer != NULL) +		{ +		BIO_printf(bio_s_out,"Client certificate\n"); +		PEM_write_bio_X509(bio_s_out,peer); +		X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf); +		BIO_printf(bio_s_out,"subject=%s\n",buf); +		X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf); +		BIO_printf(bio_s_out,"issuer=%s\n",buf); +		X509_free(peer); +		} + +	if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL) +		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); +	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); +	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +	SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); +	if (next_proto_neg) +		{ +		BIO_printf(bio_s_out,"NEXTPROTO is "); +		BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); +		BIO_printf(bio_s_out, "\n"); +		} +#endif +	if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); +	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & +		TLS1_FLAGS_TLS_PADDING_BUG) +		BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n"); +#ifndef OPENSSL_NO_KRB5 +	if (con->kssl_ctx->client_princ != NULL) +		{ +		BIO_printf(bio_s_out,"Kerberos peer principal is %s\n", +			con->kssl_ctx->client_princ); +		} +#endif /* OPENSSL_NO_KRB5 */ +	BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", +		      SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); +	return(1); +	} + +#ifndef OPENSSL_NO_DH +static DH *load_dh_param(const char *dhfile) +	{ +	DH *ret=NULL; +	BIO *bio; + +	if ((bio=BIO_new_file(dhfile,"r")) == NULL) +		goto err; +	ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL); +err: +	if (bio != NULL) BIO_free(bio); +	return(ret); +	} +#endif + +#if 0 +static int load_CA(SSL_CTX *ctx, char *file) +	{ +	FILE *in; +	X509 *x=NULL; + +	if ((in=fopen(file,"r")) == NULL) +		return(0); + +	for (;;) +		{ +		if (PEM_read_X509(in,&x,NULL) == NULL) +			break; +		SSL_CTX_add_client_CA(ctx,x); +		} +	if (x != NULL) X509_free(x); +	fclose(in); +	return(1); +	} +#endif + +static int www_body(char *hostname, int s, unsigned char *context) +	{ +	char *buf=NULL; +	int ret=1; +	int i,j,k,dot; +	SSL *con; +	const SSL_CIPHER *c; +	BIO *io,*ssl_bio,*sbio; + +	buf=OPENSSL_malloc(bufsize); +	if (buf == NULL) return(0); +	io=BIO_new(BIO_f_buffer()); +	ssl_bio=BIO_new(BIO_f_ssl()); +	if ((io == NULL) || (ssl_bio == NULL)) goto err; + +#ifdef FIONBIO	 +	if (s_nbio) +		{ +		unsigned long sl=1; + +		if (!s_quiet) +			BIO_printf(bio_err,"turning on non blocking io\n"); +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) +			ERR_print_errors(bio_err); +		} +#endif + +	/* lets make the output buffer a reasonable size */ +	if (!BIO_set_write_buffer_size(io,bufsize)) goto err; + +	if ((con=SSL_new(ctx)) == NULL) goto err; +#ifndef OPENSSL_NO_TLSEXT +		if (s_tlsextdebug) +			{ +			SSL_set_tlsext_debug_callback(con, tlsext_cb); +			SSL_set_tlsext_debug_arg(con, bio_s_out); +			} +#endif +#ifndef OPENSSL_NO_KRB5 +	if ((con->kssl_ctx = kssl_ctx_new()) != NULL) +		{ +		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC); +		kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB); +		} +#endif	/* OPENSSL_NO_KRB5 */ +	if(context) SSL_set_session_id_context(con, context, +					       strlen((char *)context)); + +	sbio=BIO_new_socket(s,BIO_NOCLOSE); +	if (s_nbio_test) +		{ +		BIO *test; + +		test=BIO_new(BIO_f_nbio_test()); +		sbio=BIO_push(test,sbio); +		} +	SSL_set_bio(con,sbio,sbio); +	SSL_set_accept_state(con); + +	/* SSL_set_fd(con,s); */ +	BIO_set_ssl(ssl_bio,con,BIO_CLOSE); +	BIO_push(io,ssl_bio); +#ifdef CHARSET_EBCDIC +	io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io); +#endif + +	if (s_debug) +		{ +		con->debug=1; +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); +		BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); +		} +	if (s_msg) +		{ +		SSL_set_msg_callback(con, msg_cb); +		SSL_set_msg_callback_arg(con, bio_s_out); +		} + +	for (;;) +		{ +		if (hack) +			{ +			i=SSL_accept(con); + +			switch (SSL_get_error(con,i)) +				{ +			case SSL_ERROR_NONE: +				break; +			case SSL_ERROR_WANT_WRITE: +			case SSL_ERROR_WANT_READ: +			case SSL_ERROR_WANT_X509_LOOKUP: +				continue; +			case SSL_ERROR_SYSCALL: +			case SSL_ERROR_SSL: +			case SSL_ERROR_ZERO_RETURN: +				ret=1; +				goto err; +				/* break; */ +				} + +			SSL_renegotiate(con); +			SSL_write(con,NULL,0); +			} + +		i=BIO_gets(io,buf,bufsize-1); +		if (i < 0) /* error */ +			{ +			if (!BIO_should_retry(io)) +				{ +				if (!s_quiet) +					ERR_print_errors(bio_err); +				goto err; +				} +			else +				{ +				BIO_printf(bio_s_out,"read R BLOCK\n"); +#if defined(OPENSSL_SYS_NETWARE) +            delay(1000); +#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__) +				sleep(1); +#endif +				continue; +				} +			} +		else if (i == 0) /* end of input */ +			{ +			ret=1; +			goto end; +			} + +		/* else we have data */ +		if (	((www == 1) && (strncmp("GET ",buf,4) == 0)) || +			((www == 2) && (strncmp("GET /stats ",buf,10) == 0))) +			{ +			char *p; +			X509 *peer; +			STACK_OF(SSL_CIPHER) *sk; +			static const char *space="                          "; + +			BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); +			BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n"); +			BIO_puts(io,"<pre>\n"); +/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ +			BIO_puts(io,"\n"); +			for (i=0; i<local_argc; i++) +				{ +				BIO_puts(io,local_argv[i]); +				BIO_write(io," ",1); +				} +			BIO_puts(io,"\n"); + +			/* The following is evil and should not really +			 * be done */ +			BIO_printf(io,"Ciphers supported in s_server binary\n"); +			sk=SSL_get_ciphers(con); +			j=sk_SSL_CIPHER_num(sk); +			for (i=0; i<j; i++) +				{ +				c=sk_SSL_CIPHER_value(sk,i); +				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"); +				} +			BIO_puts(io,"\n"); +			p=SSL_get_shared_ciphers(con,buf,bufsize); +			if (p != NULL) +				{ +				BIO_printf(io,"---\nCiphers common between both SSL end points:\n"); +				j=i=0; +				while (*p) +					{ +					if (*p == ':') +						{ +						BIO_write(io,space,26-j); +						i++; +						j=0; +						BIO_write(io,((i%3)?" ":"\n"),1); +						} +					else +						{ +						BIO_write(io,p,1); +						j++; +						} +					p++; +					} +				BIO_puts(io,"\n"); +				} +			BIO_printf(io,((con->hit) +				?"---\nReused, " +				:"---\nNew, ")); +			c=SSL_get_current_cipher(con); +			BIO_printf(io,"%s, Cipher is %s\n", +				SSL_CIPHER_get_version(c), +				SSL_CIPHER_get_name(c)); +			SSL_SESSION_print(io,SSL_get_session(con)); +			BIO_printf(io,"---\n"); +			print_stats(io,SSL_get_SSL_CTX(con)); +			BIO_printf(io,"---\n"); +			peer=SSL_get_peer_certificate(con); +			if (peer != NULL) +				{ +				BIO_printf(io,"Client certificate\n"); +				X509_print(io,peer); +				PEM_write_bio_X509(io,peer); +				} +			else +				BIO_puts(io,"no client certificate available\n"); +			BIO_puts(io,"</BODY></HTML>\r\n\r\n"); +			break; +			} +		else if ((www == 2 || www == 3) +                         && (strncmp("GET /",buf,5) == 0)) +			{ +			BIO *file; +			char *p,*e; +			static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; + +			/* skip the '/' */ +			p= &(buf[5]); + +			dot = 1; +			for (e=p; *e != '\0'; e++) +				{ +				if (e[0] == ' ') +					break; + +				switch (dot) +					{ +				case 1: +					dot = (e[0] == '.') ? 2 : 0; +					break; +				case 2: +					dot = (e[0] == '.') ? 3 : 0; +					break; +				case 3: +					dot = (e[0] == '/') ? -1 : 0; +					break; +					} +				if (dot == 0) +					dot = (e[0] == '/') ? 1 : 0; +				} +			dot = (dot == 3) || (dot == -1); /* filename contains ".." component */ + +			if (*e == '\0') +				{ +				BIO_puts(io,text); +				BIO_printf(io,"'%s' is an invalid file name\r\n",p); +				break; +				} +			*e='\0'; + +			if (dot) +				{ +				BIO_puts(io,text); +				BIO_printf(io,"'%s' contains '..' reference\r\n",p); +				break; +				} + +			if (*p == '/') +				{ +				BIO_puts(io,text); +				BIO_printf(io,"'%s' is an invalid path\r\n",p); +				break; +				} + +#if 0 +			/* append if a directory lookup */ +			if (e[-1] == '/') +				strcat(p,"index.html"); +#endif + +			/* if a directory, do the index thang */ +			if (app_isdir(p)>0) +				{ +#if 0 /* must check buffer size */ +				strcat(p,"/index.html"); +#else +				BIO_puts(io,text); +				BIO_printf(io,"'%s' is a directory\r\n",p); +				break; +#endif +				} + +			if ((file=BIO_new_file(p,"r")) == NULL) +				{ +				BIO_puts(io,text); +				BIO_printf(io,"Error opening '%s'\r\n",p); +				ERR_print_errors(io); +				break; +				} + +			if (!s_quiet) +				BIO_printf(bio_err,"FILE:%s\n",p); + +                        if (www == 2) +                                { +                                i=strlen(p); +                                if (	((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) || +                                        ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) || +                                        ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0))) +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); +                                else +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); +                                } +			/* send the file */ +			for (;;) +				{ +				i=BIO_read(file,buf,bufsize); +				if (i <= 0) break; + +#ifdef RENEG +				total_bytes+=i; +				fprintf(stderr,"%d\n",i); +				if (total_bytes > 3*1024) +					{ +					total_bytes=0; +					fprintf(stderr,"RENEGOTIATE\n"); +					SSL_renegotiate(con); +					} +#endif + +				for (j=0; j<i; ) +					{ +#ifdef RENEG +{ static count=0; if (++count == 13) { SSL_renegotiate(con); } } +#endif +					k=BIO_write(io,&(buf[j]),i-j); +					if (k <= 0) +						{ +						if (!BIO_should_retry(io)) +							goto write_error; +						else +							{ +							BIO_printf(bio_s_out,"rwrite W BLOCK\n"); +							} +						} +					else +						{ +						j+=k; +						} +					} +				} +write_error: +			BIO_free(file); +			break; +			} +		} + +	for (;;) +		{ +		i=(int)BIO_flush(io); +		if (i <= 0) +			{ +			if (!BIO_should_retry(io)) +				break; +			} +		else +			break; +		} +end: +#if 1 +	/* make sure we re-use sessions */ +	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +#else +	/* This kills performance */ +/*	SSL_shutdown(con); A shutdown gets sent in the + *	BIO_free_all(io) procession */ +#endif + +err: + +	if (ret >= 0) +		BIO_printf(bio_s_out,"ACCEPT\n"); + +	if (buf != NULL) OPENSSL_free(buf); +	if (io != NULL) BIO_free_all(io); +/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/ +	return(ret); +	} + +#ifndef OPENSSL_NO_RSA +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) +	{ +	BIGNUM *bn = NULL; +	static RSA *rsa_tmp=NULL; + +	if (!rsa_tmp && ((bn = BN_new()) == NULL)) +		BIO_printf(bio_err,"Allocation error in generating RSA key\n"); +	if (!rsa_tmp && bn) +		{ +		if (!s_quiet) +			{ +			BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); +			(void)BIO_flush(bio_err); +			} +		if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) || +				!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) +			{ +			if(rsa_tmp) RSA_free(rsa_tmp); +			rsa_tmp = NULL; +			} +		if (!s_quiet) +			{ +			BIO_printf(bio_err,"\n"); +			(void)BIO_flush(bio_err); +			} +		BN_free(bn); +		} +	return(rsa_tmp); +	} +#endif + +#define MAX_SESSION_ID_ATTEMPTS 10 +static int generate_session_id(const SSL *ssl, unsigned char *id, +				unsigned int *id_len) +	{ +	unsigned int count = 0; +	do	{ +		RAND_pseudo_bytes(id, *id_len); +		/* Prefix the session_id with the required prefix. NB: If our +		 * prefix is too long, clip it - but there will be worse effects +		 * anyway, eg. the server could only possibly create 1 session +		 * ID (ie. the prefix!) so all future session negotiations will +		 * fail due to conflicts. */ +		memcpy(id, session_id_prefix, +			(strlen(session_id_prefix) < *id_len) ? +			strlen(session_id_prefix) : *id_len); +		} +	while(SSL_has_matching_session_id(ssl, id, *id_len) && +		(++count < MAX_SESSION_ID_ATTEMPTS)); +	if(count >= MAX_SESSION_ID_ATTEMPTS) +		return 0; +	return 1; +	} diff --git a/main/openssl/apps/s_socket.c b/main/openssl/apps/s_socket.c new file mode 100644 index 00000000..c08544a1 --- /dev/null +++ b/main/openssl/apps/s_socket.c @@ -0,0 +1,620 @@ +/* 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. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <signal.h> + +#ifdef FLAT_INC +#include "e_os2.h" +#else +#include "../e_os2.h" +#endif + +/* With IPv6, it looks like Digital has mixed up the proper order of +   recursive header file inclusion, resulting in the compiler complaining +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which +   is needed to have fileno() declared correctly...  So let's define u_int */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) +#define __U_INT +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> + +#ifdef FLAT_INC +#include "e_os.h" +#else +#include "../e_os.h" +#endif + +#ifndef OPENSSL_NO_SOCK + +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) +#include "netdb.h" +#endif + +static struct hostent *GetHostByName(char *name); +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) +static void ssl_sock_cleanup(void); +#endif +static int ssl_sock_init(void); +static int init_client_ip(int *sock,unsigned char ip[4], int port, int type); +static int init_server(int *sock, int port, int type); +static int init_server_long(int *sock, int port,char *ip, int type); +static int do_accept(int acc_sock, int *sock, char **host); +static int host_ip(char *str, unsigned char ip[4]); + +#ifdef OPENSSL_SYS_WIN16 +#define SOCKET_PROTOCOL	0 /* more microsoft stupidity */ +#else +#define SOCKET_PROTOCOL	IPPROTO_TCP +#endif + +#if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) +static int wsa_init_done=0; +#endif + +#ifdef OPENSSL_SYS_WINDOWS +static struct WSAData wsa_state; +static int wsa_init_done=0; + +#ifdef OPENSSL_SYS_WIN16 +static HWND topWnd=0; +static FARPROC lpTopWndProc=NULL; +static FARPROC lpTopHookProc=NULL; +extern HINSTANCE _hInstance;  /* nice global CRT provides */ + +static LONG FAR PASCAL topHookProc(HWND hwnd, UINT message, WPARAM wParam, +	     LPARAM lParam) +	{ +	if (hwnd == topWnd) +		{ +		switch(message) +			{ +		case WM_DESTROY: +		case WM_CLOSE: +			SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopWndProc); +			ssl_sock_cleanup(); +			break; +			} +		} +	return CallWindowProc(lpTopWndProc,hwnd,message,wParam,lParam); +	} + +static BOOL CALLBACK enumproc(HWND hwnd,LPARAM lParam) +	{ +	topWnd=hwnd; +	return(FALSE); +	} + +#endif /* OPENSSL_SYS_WIN32 */ +#endif /* OPENSSL_SYS_WINDOWS */ + +#ifdef OPENSSL_SYS_WINDOWS +static void ssl_sock_cleanup(void) +	{ +	if (wsa_init_done) +		{ +		wsa_init_done=0; +#ifndef OPENSSL_SYS_WINCE +		WSACancelBlockingCall(); +#endif +		WSACleanup(); +		} +	} +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) +static void sock_cleanup(void) +    { +    if (wsa_init_done) +        { +        wsa_init_done=0; +		WSACleanup(); +		} +	} +#endif + +static int ssl_sock_init(void) +	{ +#ifdef WATT32 +	extern int _watt_do_exit; +	_watt_do_exit = 0; +	if (sock_init()) +		return (0); +#elif defined(OPENSSL_SYS_WINDOWS) +	if (!wsa_init_done) +		{ +		int err; +	   +#ifdef SIGINT +		signal(SIGINT,(void (*)(int))ssl_sock_cleanup); +#endif +		wsa_init_done=1; +		memset(&wsa_state,0,sizeof(wsa_state)); +		if (WSAStartup(0x0101,&wsa_state)!=0) +			{ +			err=WSAGetLastError(); +			BIO_printf(bio_err,"unable to start WINSOCK, error code=%d\n",err); +			return(0); +			} + +#ifdef OPENSSL_SYS_WIN16 +		EnumTaskWindows(GetCurrentTask(),enumproc,0L); +		lpTopWndProc=(FARPROC)GetWindowLong(topWnd,GWL_WNDPROC); +		lpTopHookProc=MakeProcInstance((FARPROC)topHookProc,_hInstance); + +		SetWindowLong(topWnd,GWL_WNDPROC,(LONG)lpTopHookProc); +#endif /* OPENSSL_SYS_WIN16 */ +		} +#elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) +   WORD wVerReq; +   WSADATA wsaData; +   int err; + +   if (!wsa_init_done) +      { +    +# ifdef SIGINT +      signal(SIGINT,(void (*)(int))sock_cleanup); +# endif + +      wsa_init_done=1; +      wVerReq = MAKEWORD( 2, 0 ); +      err = WSAStartup(wVerReq,&wsaData); +      if (err != 0) +         { +         BIO_printf(bio_err,"unable to start WINSOCK2, error code=%d\n",err); +         return(0); +         } +      } +#endif /* OPENSSL_SYS_WINDOWS */ +	return(1); +	} + +int init_client(int *sock, char *host, int port, int type) +	{ +	unsigned char ip[4]; + +	if (!host_ip(host,&(ip[0]))) +		{ +		return(0); +		} +	return(init_client_ip(sock,ip,port,type)); +	} + +static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) +	{ +	unsigned long addr; +	struct sockaddr_in them; +	int s,i; + +	if (!ssl_sock_init()) return(0); + +	memset((char *)&them,0,sizeof(them)); +	them.sin_family=AF_INET; +	them.sin_port=htons((unsigned short)port); +	addr=(unsigned long) +		((unsigned long)ip[0]<<24L)| +		((unsigned long)ip[1]<<16L)| +		((unsigned long)ip[2]<< 8L)| +		((unsigned long)ip[3]); +	them.sin_addr.s_addr=htonl(addr); + +	if (type == SOCK_STREAM) +		s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); +	else /* ( type == SOCK_DGRAM) */ +		s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); +			 +	if (s == INVALID_SOCKET) { perror("socket"); return(0); } + +#if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) +	if (type == SOCK_STREAM) +		{ +		i=0; +		i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); +		if (i < 0) { perror("keepalive"); return(0); } +		} +#endif + +	if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) +		{ closesocket(s); perror("connect"); return(0); } +	*sock=s; +	return(1); +	} + +int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) +	{ +	int sock; +	char *name = NULL; +	int accept_socket = 0; +	int i; + +	if (!init_server(&accept_socket,port,type)) return(0); + +	if (ret != NULL) +		{ +		*ret=accept_socket; +		/* return(1);*/ +		} +  	for (;;) +  		{ +		if (type==SOCK_STREAM) +			{ +			if (do_accept(accept_socket,&sock,&name) == 0) +				{ +				SHUTDOWN(accept_socket); +				return(0); +				} +			} +		else +			sock = accept_socket; +		i=(*cb)(name,sock, context); +		if (name != NULL) OPENSSL_free(name); +		if (type==SOCK_STREAM) +			SHUTDOWN2(sock); +		if (i < 0) +			{ +			SHUTDOWN2(accept_socket); +			return(i); +			} +		} +	} + +static int init_server_long(int *sock, int port, char *ip, int type) +	{ +	int ret=0; +	struct sockaddr_in server; +	int s= -1; + +	if (!ssl_sock_init()) return(0); + +	memset((char *)&server,0,sizeof(server)); +	server.sin_family=AF_INET; +	server.sin_port=htons((unsigned short)port); +	if (ip == NULL) +		server.sin_addr.s_addr=INADDR_ANY; +	else +/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ +#ifndef BIT_FIELD_LIMITS +		memcpy(&server.sin_addr.s_addr,ip,4); +#else +		memcpy(&server.sin_addr,ip,4); +#endif +	 +		if (type == SOCK_STREAM) +			s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); +		else /* type == SOCK_DGRAM */ +			s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP); + +	if (s == INVALID_SOCKET) goto err; +#if defined SOL_SOCKET && defined SO_REUSEADDR +		{ +		int j = 1; +		setsockopt(s, SOL_SOCKET, SO_REUSEADDR, +			   (void *) &j, sizeof j); +		} +#endif +	if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) +		{ +#ifndef OPENSSL_SYS_WINDOWS +		perror("bind"); +#endif +		goto err; +		} +	/* Make it 128 for linux */ +	if (type==SOCK_STREAM && listen(s,128) == -1) goto err; +	*sock=s; +	ret=1; +err: +	if ((ret == 0) && (s != -1)) +		{ +		SHUTDOWN(s); +		} +	return(ret); +	} + +static int init_server(int *sock, int port, int type) +	{ +	return(init_server_long(sock, port, NULL, type)); +	} + +static int do_accept(int acc_sock, int *sock, char **host) +	{ +	int ret; +	struct hostent *h1,*h2; +	static struct sockaddr_in from; +	int len; +/*	struct linger ling; */ + +	if (!ssl_sock_init()) return(0); + +#ifndef OPENSSL_SYS_WINDOWS +redoit: +#endif + +	memset((char *)&from,0,sizeof(from)); +	len=sizeof(from); +	/* Note: under VMS with SOCKETSHR the fourth parameter is currently +	 * of type (int *) whereas under other systems it is (void *) if +	 * you don't have a cast it will choke the compiler: if you do +	 * have a cast then you can either go for (int *) or (void *). +	 */ +	ret=accept(acc_sock,(struct sockaddr *)&from,(void *)&len); +	if (ret == INVALID_SOCKET) +		{ +#if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) +		int i; +		i=WSAGetLastError(); +		BIO_printf(bio_err,"accept error %d\n",i); +#else +		if (errno == EINTR) +			{ +			/*check_timeout(); */ +			goto redoit; +			} +		fprintf(stderr,"errno=%d ",errno); +		perror("accept"); +#endif +		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 +	/* I should use WSAAsyncGetHostByName() under windows */ +	h1=gethostbyaddr((char *)&from.sin_addr.s_addr, +		sizeof(from.sin_addr.s_addr),AF_INET); +#else +	h1=gethostbyaddr((char *)&from.sin_addr, +		sizeof(struct in_addr),AF_INET); +#endif +	if (h1 == NULL) +		{ +		BIO_printf(bio_err,"bad gethostbyaddr\n"); +		*host=NULL; +		/* return(0); */ +		} +	else +		{ +		if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL) +			{ +			perror("OPENSSL_malloc"); +			return(0); +			} +		BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1); + +		h2=GetHostByName(*host); +		if (h2 == NULL) +			{ +			BIO_printf(bio_err,"gethostbyname failure\n"); +			return(0); +			} +		if (h2->h_addrtype != AF_INET) +			{ +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); +			return(0); +			} +		} +end: +	*sock=ret; +	return(1); +	} + +int extract_host_port(char *str, char **host_ptr, unsigned char *ip, +	     short *port_ptr) +	{ +	char *h,*p; + +	h=str; +	p=strchr(str,':'); +	if (p == NULL) +		{ +		BIO_printf(bio_err,"no port defined\n"); +		return(0); +		} +	*(p++)='\0'; + +	if ((ip != NULL) && !host_ip(str,ip)) +		goto err; +	if (host_ptr != NULL) *host_ptr=h; + +	if (!extract_port(p,port_ptr)) +		goto err; +	return(1); +err: +	return(0); +	} + +static int host_ip(char *str, unsigned char ip[4]) +	{ +	unsigned int in[4];  +	int i; + +	if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4) +		{ +		for (i=0; i<4; i++) +			if (in[i] > 255) +				{ +				BIO_printf(bio_err,"invalid IP address\n"); +				goto err; +				} +		ip[0]=in[0]; +		ip[1]=in[1]; +		ip[2]=in[2]; +		ip[3]=in[3]; +		} +	else +		{ /* do a gethostbyname */ +		struct hostent *he; + +		if (!ssl_sock_init()) return(0); + +		he=GetHostByName(str); +		if (he == NULL) +			{ +			BIO_printf(bio_err,"gethostbyname failure\n"); +			goto err; +			} +		/* cast to short because of win16 winsock definition */ +		if ((short)he->h_addrtype != AF_INET) +			{ +			BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); +			return(0); +			} +		ip[0]=he->h_addr_list[0][0]; +		ip[1]=he->h_addr_list[0][1]; +		ip[2]=he->h_addr_list[0][2]; +		ip[3]=he->h_addr_list[0][3]; +		} +	return(1); +err: +	return(0); +	} + +int extract_port(char *str, short *port_ptr) +	{ +	int i; +	struct servent *s; + +	i=atoi(str); +	if (i != 0) +		*port_ptr=(unsigned short)i; +	else +		{ +		s=getservbyname(str,"tcp"); +		if (s == NULL) +			{ +			BIO_printf(bio_err,"getservbyname failure for %s\n",str); +			return(0); +			} +		*port_ptr=ntohs((unsigned short)s->s_port); +		} +	return(1); +	} + +#define GHBN_NUM	4 +static struct ghbn_cache_st +	{ +	char name[128]; +	struct hostent ent; +	unsigned long order; +	} ghbn_cache[GHBN_NUM]; + +static unsigned long ghbn_hits=0L; +static unsigned long ghbn_miss=0L; + +static struct hostent *GetHostByName(char *name) +	{ +	struct hostent *ret; +	int i,lowi=0; +	unsigned long low= (unsigned long)-1; + +	for (i=0; i<GHBN_NUM; i++) +		{ +		if (low > ghbn_cache[i].order) +			{ +			low=ghbn_cache[i].order; +			lowi=i; +			} +		if (ghbn_cache[i].order > 0) +			{ +			if (strncmp(name,ghbn_cache[i].name,128) == 0) +				break; +			} +		} +	if (i == GHBN_NUM) /* no hit*/ +		{ +		ghbn_miss++; +		ret=gethostbyname(name); +		if (ret == NULL) return(NULL); +		/* else add to cache */ +		if(strlen(name) < sizeof ghbn_cache[0].name) +			{ +			strcpy(ghbn_cache[lowi].name,name); +			memcpy((char *)&(ghbn_cache[lowi].ent),ret,sizeof(struct hostent)); +			ghbn_cache[lowi].order=ghbn_miss+ghbn_hits; +			} +		return(ret); +		} +	else +		{ +		ghbn_hits++; +		ret= &(ghbn_cache[i].ent); +		ghbn_cache[i].order=ghbn_miss+ghbn_hits; +		return(ret); +		} +	} + +#endif diff --git a/main/openssl/apps/s_time.c b/main/openssl/apps/s_time.c new file mode 100644 index 00000000..b823c33c --- /dev/null +++ b/main/openssl/apps/s_time.c @@ -0,0 +1,632 @@ +/* apps/s_time.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.] + */ + +#define NO_SHUTDOWN + +/*----------------------------------------- +   s_time - SSL client connection timer program +   Written and donated by Larry Streepy <streepy@healthcare.com> +  -----------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define USE_SOCKETS +#include "apps.h" +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include <openssl/x509.h> +#include <openssl/ssl.h> +#include <openssl/pem.h> +#include "s_apps.h" +#include <openssl/err.h> +#ifdef WIN32_STUFF +#include "winmain.h" +#include "wintext.h" +#endif +#if !defined(OPENSSL_SYS_MSDOS) +#include OPENSSL_UNISTD +#endif + +#undef PROG +#define PROG s_time_main + +#undef ioctl +#define ioctl ioctlsocket + +#define SSL_CONNECT_NAME	"localhost:4433" + +/*#define TEST_CERT "client.pem" */ /* no default cert. */ + +#undef BUFSIZZ +#define BUFSIZZ 1024*10 + +#define MYBUFSIZ 1024*8 + +#undef min +#undef max +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) + +#undef SECONDS +#define SECONDS	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 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; +#endif +#ifdef OPENSSL_SYS_WIN32 +static int exitNow = 0;		/* Set when it's time to exit main */ +#endif + +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 +	} + +/*********************************************************************** + * usage - display usage message + */ +static void s_time_usage(void) +{ +	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("-ssl2         - Just use SSLv2\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 ); +} + +/*********************************************************************** + * parseArgs - Parse command line arguments and initialize data + * + * Returns 0 if ok, -1 on bad args + */ +static int parseArgs(int argc, char **argv) +{ +    int badop = 0; + +    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); +		} +#if 0 +	else if( strcmp(*argv,"-host") == 0) +		{ +		if (--argc < 1) goto bad; +		host= *(++argv); +		} +	else if( strcmp(*argv,"-port") == 0) +		{ +		if (--argc < 1) goto bad; +		port= *(++argv); +		} +#endif +	else if (strcmp(*argv,"-reuse") == 0) +		perform=2; +	else if (strcmp(*argv,"-new") == 0) +		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) +	    st_bugs=1; +#ifndef OPENSSL_NO_SSL2 +	else if(strcmp(*argv,"-ssl2") == 0) +	    s_time_meth=SSLv2_client_method(); +#endif +#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)); +	} +	else { +	    BIO_printf(bio_err,"unknown option %s\n",*argv); +	    badop=1; +	    break; +	} + +	argc--; +	argv++; +    } + +    if (perform == 0) perform=3; + +    if(badop) { +bad: +		s_time_usage(); +		return -1; +    } + +	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; +	MS_STATIC char buf[1024*8]; +	int ver; + +	apps_startup(); +	s_time_init(); + +	if (bio_err == NULL) +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); + +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +	s_time_meth=SSLv23_client_method(); +#elif !defined(OPENSSL_NO_SSL3) +	s_time_meth=SSLv3_client_method(); +#elif !defined(OPENSSL_NO_SSL2) +	s_time_meth=SSLv2_client_method(); +#endif + +	/* parse the command line arguments */ +	if( parseArgs( argc, argv ) < 0 ) +		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); + +	if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL); +	SSL_CTX_set_cipher_list(tm_ctx,tm_cipher); +	if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file))  +		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"); */ +		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" ); +	} + +	if (!(perform & 1)) goto next; +	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; +	tm_Time_F(START); +	for (;;) +		{ +		if (finishtime < (long)time(NULL)) break; +#ifdef WIN32_STUFF + +		if( flushWinMsgs(0) == -1 ) +			goto end; + +		if( waitingToDie || exitNow )		/* we're dead */ +			goto end; +#endif + +		if( (scon = doConnection( NULL )) == NULL ) +			goto end; + +		if (s_www_path != NULL) +			{ +			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path); +			SSL_write(scon,buf,strlen(buf)); +			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0) +				bytes_read+=i; +			} + +#ifdef NO_SHUTDOWN +		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +#else +		SSL_shutdown(scon); +#endif +		SHUTDOWN2(SSL_get_fd(scon)); + +		nConn += 1; +		if (SSL_session_reused(scon)) +			ver='r'; +		else +			{ +			ver=SSL_version(scon); +			if (ver == TLS1_VERSION) +				ver='t'; +			else if (ver == SSL3_VERSION) +				ver='3'; +			else if (ver == SSL2_VERSION) +				ver='2'; +			else +				ver='*'; +			} +		fputc(ver,stdout); +		fflush(stdout); + +		SSL_free( scon ); +		scon=NULL; +		} +	totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ + +	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); + +	/* Now loop and time connections using the same session id over and over */ + +next: +	if (!(perform & 2)) goto end; +	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 ) +		{ +		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); +		SSL_write(scon,buf,strlen(buf)); +		while (SSL_read(scon,buf,sizeof(buf)) > 0) +			; +		} +#ifdef NO_SHUTDOWN +	SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +#else +	SSL_shutdown(scon); +#endif +	SHUTDOWN2(SSL_get_fd(scon)); + +	nConn = 0; +	totalTime = 0.0; + +	finishtime=(long)time(NULL)+maxTime; + +	printf( "starting\n" ); +	bytes_read=0; +	tm_Time_F(START); +		 +	for (;;) +		{ +		if (finishtime < (long)time(NULL)) break; + +#ifdef WIN32_STUFF +		if( flushWinMsgs(0) == -1 ) +			goto end; + +		if( waitingToDie || exitNow )	/* we're dead */ +			goto end; +#endif + +	 	if( (doConnection( scon )) == NULL ) +			goto end; + +		if (s_www_path) +			{ +			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path); +			SSL_write(scon,buf,strlen(buf)); +			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0) +				bytes_read+=i; +			} + +#ifdef NO_SHUTDOWN +		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); +#else +		SSL_shutdown(scon); +#endif +		SHUTDOWN2(SSL_get_fd(scon)); +	 +		nConn += 1; +		if (SSL_session_reused(scon)) +			ver='r'; +		else +			{ +			ver=SSL_version(scon); +			if (ver == TLS1_VERSION) +				ver='t'; +			else if (ver == SSL3_VERSION) +				ver='3'; +			else if (ver == SSL2_VERSION) +				ver='2'; +			else +				ver='*'; +			} +		fputc(ver,stdout); +		fflush(stdout); +		} +	totalTime += tm_Time_F(STOP); /* Add the time for this iteration*/ + + +	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); + +	ret=0; +end: +	if (scon != NULL) SSL_free(scon); + +	if (tm_ctx != NULL) +		{ +		SSL_CTX_free(tm_ctx); +		tm_ctx=NULL; +		} +	apps_shutdown(); +	OPENSSL_EXIT(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) +	{ +	BIO *conn; +	SSL *serverCon; +	int width, i; +	fd_set readfds; + +	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); +	else +		{ +		serverCon=scon; +		SSL_set_connect_state(serverCon); +		} + +	SSL_set_bio(serverCon,conn,conn); + +#if 0 +	if( scon != NULL ) +		SSL_set_session(serverCon,SSL_get_session(scon)); +#endif + +	/* ok, lets connect */ +	for(;;) { +		i=SSL_connect(serverCon); +		if (BIO_sock_should_retry(i)) +			{ +			BIO_printf(bio_err,"DELAY\n"); + +			i=SSL_get_fd(serverCon); +			width=i+1; +			FD_ZERO(&readfds); +			openssl_fdset(i,&readfds); +			/* Note: under VMS with SOCKETSHR the 2nd parameter +			 * is currently of type (int *) whereas under other +			 * systems it is (void *) if you don't have a cast it +			 * will choke the compiler: if you do have a cast then +			 * you can either go for (int *) or (void *). +			 */ +			select(width,(void *)&readfds,NULL,NULL,NULL); +			continue; +			} +		break; +		} +	if(i <= 0) +		{ +		BIO_printf(bio_err,"ERROR\n"); +		if (verify_error != X509_V_OK) +			BIO_printf(bio_err,"verify error:%s\n", +				X509_verify_cert_error_string(verify_error)); +		else +			ERR_print_errors(bio_err); +		if (scon == NULL) +			SSL_free(serverCon); +		return NULL; +		} + +	return serverCon; +	} + + diff --git a/main/openssl/apps/server.pem b/main/openssl/apps/server.pem new file mode 100644 index 00000000..56248e57 --- /dev/null +++ b/main/openssl/apps/server.pem @@ -0,0 +1,369 @@ +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit) +subject= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (512 bit) +-----BEGIN CERTIFICATE----- +MIIB6TCCAVICAQYwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD +VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNMDAxMDE2MjIzMTAzWhcNMDMwMTE0 +MjIzMTAzWjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG +A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl +cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP +Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2// +Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCT0grFQeZaqYb5EYfk20XixZV4 +GmyAbXMftG1Eo7qGiMhYzRwGNWxEYojf5PZkYZXvSqZ/ZXHXa4g59jK/rJNnaVGM +k+xIX8mxQvlV0n5O9PIha5BX5teZnkHKgL8aKKLKW1BK7YTngsfSzzaeame5iKfz +itAE+OjGF+PFKbwX8Q== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD +TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu +OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj +gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz +rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b +PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA +vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU= +-----END RSA PRIVATE KEY----- +subject=/C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA +issuer= /C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA +notBefore=950413210656Z +notAfter =970412210656Z +-----BEGIN X509 CERTIFICATE----- + +MIICCDCCAXECAQAwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV +BAoUFkFUJlQgQmVsbCBMYWJvcmF0b3JpZXMxHjAcBgNVBAsUFVByb3RvdHlwZSBS +ZXNlYXJjaCBDQTAeFw05NTA0MTMyMTA2NTZaFw05NzA0MTIyMTA2NTZaME4xCzAJ +BgNVBAYTAlVTMR8wHQYDVQQKFBZBVCZUIEJlbGwgTGFib3JhdG9yaWVzMR4wHAYD +VQQLFBVQcm90b3R5cGUgUmVzZWFyY2ggQ0EwgZwwDQYJKoZIhvcNAQEBBQADgYoA +MIGGAoGAebOmgtSCl+wCYZc86UGYeTLY8cjmW2P0FN8ToT/u2pECCoFdrlycX0OR +3wt0ZhpFXLVNeDnHwEE9veNUih7pCL2ZBFqoIoQkB1lZmXRiVtjGonz8BLm/qrFM +YHb0lme/Ol+s118mwKVxnn6bSAeI/OXKhLaVdYZWk+aEaxEDkVkCAQ8wDQYJKoZI +hvcNAQEEBQADgYEAAZMG14lZmZ8bahkaHaTV9dQf4p2FZiQTFwHP9ZyGsXPC+LT5 +dG5iTaRmyjNIJdPWohZDl97kAci79aBndvuEvRKOjLHs3WRGBIwERnAcnY9Mz8u/ +zIHK23PjYVxGGaZd669OJwD0CYyqH22HH9nFUGaoJdsv39ChW0NRdLE9+y8= +-----END X509 CERTIFICATE----- +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit) +-----BEGIN CERTIFICATE----- +MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD +VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw +OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0 +IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ +DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv +1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2 +mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v +hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4 +YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA +q30KIqGM/uoM60INq97qjDmCJapagcNBGQs= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425 +gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd +2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB +AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6 +hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2 +J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs +HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL +21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s +nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz +MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa +pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb +KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2 +XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ +-----END RSA PRIVATE KEY----- +-----BEGIN X509 CERTIFICATE----- +MIICYDCCAiACAgEoMAkGBSsOAwINBQAwfDELMAkGA1UEBhMCVVMxNjA0BgNVBAoT +LU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZ +MBcGA1UECxMQVGVzdCBFbnZpcm9ubWVudDEaMBgGA1UECxMRRFNTLU5BU0EtUGls +b3QtQ0EwHhcNOTYwMjI2MTYzMjQ1WhcNOTcwMjI1MTYzMjQ1WjB8MQswCQYDVQQG +EwJVUzE2MDQGA1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFk +bWluaXN0cmF0aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MRowGAYDVQQL +ExFEU1MtTkFTQS1QaWxvdC1DQTCB8jAJBgUrDgMCDAUAA4HkADCB4AJBAMA/ssKb +hPNUG7ZlASfVwEJU21O5OyF/iyBzgHI1O8eOhJGUYO8cc8wDMjR508Mr9cp6Uhl/ +ZB7FV5GkLNEnRHYCQQDUEaSg45P2qrDwixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLb +bn3QK74T2IxY1yY+kCNq8XrIqf5fJJzIH0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3 +fVd0geUCQQCzCFUQAh+ZkEmp5804cs6ZWBhrUAfnra8lJItYo9xPcXgdIfLfibcX +R71UsyO77MRD7B0+Ag2tq794IleCVcEEMAkGBSsOAwINBQADLwAwLAIUUayDfreR +Yh2WeU86/pHNdkUC1IgCFEfxe1f0oMpxJyrJ5XIxTi7vGdoK +-----END X509 CERTIFICATE----- +-----BEGIN X509 CERTIFICATE----- + +MIICGTCCAdgCAwCqTDAJBgUrDgMCDQUAMHwxCzAJBgNVBAYTAlVTMTYwNAYDVQQK +Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x +GTAXBgNVBAsTEFRlc3QgRW52aXJvbm1lbnQxGjAYBgNVBAsTEURTUy1OQVNBLVBp +bG90LUNBMB4XDTk2MDUxNDE3MDE0MVoXDTk3MDUxNDE3MDE0MVowMzELMAkGA1UE +BhMCQVUxDzANBgNVBAoTBk1pbmNvbTETMBEGA1UEAxMKRXJpYyBZb3VuZzCB8jAJ +BgUrDgMCDAUAA4HkADCB4AJBAKbfHz6vE6pXXMTpswtGUec2tvnfLJUsoxE9qs4+ +ObZX7LmLvragNPUeiTJx7UOWZ5DfBj6bXLc8eYne0lP1g3ACQQDUEaSg45P2qrDw +ixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLbbn3QK74T2IxY1yY+kCNq8XrIqf5fJJzI +H0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3fVd0geUCQQCzCFUQAh+ZkEmp5804cs6Z +WBhrUAfnra8lJItYo9xPcXgdIfLfibcXR71UsyO77MRD7B0+Ag2tq794IleCVcEE +MAkGBSsOAwINBQADMAAwLQIUWsuuJRE3VT4ueWkWMAJMJaZjj1ECFQCYY0zX4bzM +LC7obsrHD8XAHG+ZRG== +-----END X509 CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICTTCCAbagAwIBAgIBADANBgkqhkiG9w0BAQQFADBMMQswCQYDVQQGEwJHQjEM +MAoGA1UEChMDVUNMMRgwFgYDVQQLEw9JQ0UtVEVMIFByb2plY3QxFTATBgNVBAMT +DFRydXN0RmFjdG9yeTAeFw05NzA0MjIxNDM5MTRaFw05ODA0MjIxNDM5MTRaMEwx +CzAJBgNVBAYTAkdCMQwwCgYDVQQKEwNVQ0wxGDAWBgNVBAsTD0lDRS1URUwgUHJv +amVjdDEVMBMGA1UEAxMMVHJ1c3RGYWN0b3J5MIGcMAoGBFUIAQECAgQAA4GNADCB +iQKBgQCEieR8NcXkUW1f0G6aC6u0i8q/98JqS6RxK5YmHIGKCkuTWAUjzLfUa4dt +U9igGCjTuxaDqlzEim+t/02pmiBZT9HaX++35MjQPUWmsChcYU5WyzGErXi+rQaw +zlwS73zM8qiPj/97lXYycWhgL0VaiDSPxRXEUdWoaGruom4mNQIDAQABo0IwQDAd +BgNVHQ4EFgQUHal1LZr7oVg5z6lYzrhTgZRCmcUwDgYDVR0PAQH/BAQDAgH2MA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAfaggfl6FZoioecjv0dq8 +/DXo/u11iMZvXn08gjX/zl2b4wtPbShOSY5FhkSm8GeySasz+/Nwb/uzfnIhokWi +lfPZHtlCWtXbIy/TN51eJyq04ceDCQDWvLC2enVg9KB+GJ34b5c5VaPRzq8MBxsA +S7ELuYGtmYgYm9NZOIr7yU0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB6jCCAZQCAgEtMA0GCSqGSIb3DQEBBAUAMIGAMQswCQYDVQQGEwJVUzE2MDQG +A1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFkbWluaXN0cmF0 +aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MR4wHAYDVQQLExVNRDUtUlNB +LU5BU0EtUGlsb3QtQ0EwHhcNOTYwNDMwMjIwNTAwWhcNOTcwNDMwMjIwNTAwWjCB +gDELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu +ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZMBcGA1UECxMQVGVzdCBFbnZpcm9ubWVu +dDEeMBwGA1UECxMVTUQ1LVJTQS1OQVNBLVBpbG90LUNBMFkwCgYEVQgBAQICAgAD +SwAwSAJBALmmX5+GqAvcrWK13rfDrNX9UfeA7f+ijyBgeFQjYUoDpFqapw4nzQBL +bAXug8pKkRwa2Zh8YODhXsRWu2F/UckCAwEAATANBgkqhkiG9w0BAQQFAANBAH9a +OBA+QCsjxXgnSqHx04gcU8S49DVUb1f2XVoLnHlIb8RnX0k5O6mpHT5eti9bLkiW +GJNMJ4L0AJ/ac+SmHZc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICajCCAdMCBDGA0QUwDQYJKoZIhvcNAQEEBQAwfTELMAkGA1UEBhMCQ2ExDzAN +BgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmlsaXR5IEFjY2VwdGVkMR8w +HQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRwwGgYDVQQDExNFbnRydXN0 +IERlbW8gV2ViIENBMB4XDTk2MDQyNjEzMzUwMVoXDTA2MDQyNjEzMzUwMVowfTEL +MAkGA1UEBhMCQ2ExDzANBgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmls +aXR5IEFjY2VwdGVkMR8wHQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRww +GgYDVQQDExNFbnRydXN0IERlbW8gV2ViIENBMIGdMA0GCSqGSIb3DQEBAQUAA4GL +ADCBhwKBgQCaroS7O1DA0hm4IefNYU1cx/nqOmzEnk291d1XqznDeF4wEgakbkCc +zTKxK791yNpXG5RmngqH7cygDRTHZJ6mfCRn0wGC+AI00F2vYTGqPGRQL1N3lZT0 +YDKFC0SQeMMjFIZ1aeQigroFQnHo0VB3zWIMpNkka8PY9lxHZAmWwQIBAzANBgkq +hkiG9w0BAQQFAAOBgQBAx0UMVA1s54lMQyXjMX5kj99FJN5itb8bK1Rk+cegPQPF +cWO9SEWyEjjBjIkjjzAwBkaEszFsNGxemxtXvwjIm1xEUMTVlPEWTs2qnDvAUA9W +YqhWbhH0toGT36236QAsqCZ76rbTRVSSX2BHyJwJMG2tCRv7kRJ//NIgxj3H4w== +-----END CERTIFICATE----- + +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +-----BEGIN CERTIFICATE----- +MIICJzCCAZACAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD +VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTczN1oXDTAxMDYw +OTEzNTczN1owXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy +NCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfjIrkg +40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp +22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3vR1Y +BEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABNA1u/S +Cg/LJZWb7GliiKJsvuhxlE4E5JxQF2zMub/CSNbF97//tYSyj96sxeFQxZXbcjm9 +xt6mr/xNLA4szNQMJ4P+L7b5e/jC5DSqlwS+CUYJgaFs/SP+qJoCSu1bR3IM9XWO +cRBpDmcBbYLkSyB92WURvsZ1LtjEcn+cdQVI +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7 +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc= +-----END RSA PRIVATE KEY----- +subject=/C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority +issuer= /C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority +notBefore=941104185834Z +notAfter =991103185834Z +-----BEGIN X509 CERTIFICATE----- + +MIICIzCCAZACBQJBAAAWMA0GCSqGSIb3DQEBAgUAMFwxCzAJBgNVBAYTAlVTMSAw +HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVy +Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDQxODU4MzRaFw05 +OTExMDMxODU4MzRaMFwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBT +ZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVyY2lhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCk+4Fie84QJ93o +975sbsZwmdu41QUDaSiCnHJ/lj+O7Kwpkj+KFPhCdr69XQO5kNTQvAayUTNfxMK/ +touPmbZiImDd298ggrTKoi8tUO2UMt7gVY3UaOLgTNLNBRYulWZcYVI4HlGogqHE +7yXpCuaLK44xZtn42f29O2nZ6wIDAQABMA0GCSqGSIb3DQEBAgUAA34AdrW2EP4j +9/dZYkuwX5zBaLxJu7NJbyFHXSudVMQAKD+YufKKg5tgf+tQx6sFEC097TgCwaVI +0v5loMC86qYjFmZsGySp8+x5NRhPJsjjr1BKx6cxa9B8GJ1Qv6km+iYrRpwUqbtb +MJhCKLVLU7tDCZJAuqiqWqTGtotXTcU= +-----END X509 CERTIFICATE----- +subject=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority +issuer= /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority +notBefore=941109235417Z +notAfter =991231235417Z +-----BEGIN X509 CERTIFICATE----- + +MIICKTCCAZYCBQJBAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw +HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl +IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDkyMzU0MTda +Fw05OTEyMzEyMzU0MTdaMF8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0 +YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJlIFNlcnZlciBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCSznrB +roM+WqqJg1esJQF2DK2ujiw3zus1eGRUA+WEQFHJv48I4oqCCNIWhjdV6bEhAq12 +aIGaBaJLyUslZiJWbIgHj/eBWW2EB2VwE3F2Ppt3TONQiVaYSLkdpykaEy5KEVmc +HhXVSVQsczppgrGXOZxtcGdI5d0t1sgeewIDAQABMA0GCSqGSIb3DQEBAgUAA34A +iNHReSHO4ovo+MF9NFM/YYPZtgs4F7boviGNjwC4i1N+RGceIr2XJ+CchcxK9oU7 +suK+ktPlDemvXA4MRpX/oRxePug2WHpzpgr4IhFrwwk4fia7c+8AvQKk8xQNMD9h +cHsg/jKjn7P0Z1LctO6EjJY2IN6BCINxIYoPnqk= +-----END X509 CERTIFICATE----- +subject=/C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc +	/OU=Certification Services Division/CN=Thawte Server CA +	/Email=server-certs@thawte.com +issuer= /C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc +	/OU=Certification Services Division/CN=Thawte Server CA +	/Email=server-certs@thawte.com +-----BEGIN CERTIFICATE----- +MIIC+TCCAmICAQAwDQYJKoZIhvcNAQEEBQAwgcQxCzAJBgNVBAYTAlpBMRUwEwYD +VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkq +hkiG9w0BCQEWF3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMB4XDTk2MDcyNzE4MDc1 +N1oXDTk4MDcyNzE4MDc1N1owgcQxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0 +ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENv +bnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 +aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkqhkiG9w0BCQEW +F3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDTpFBuyP9Wa+bPXbbqDGh1R6KqwtqEJfyo9EdR2oW1IHSUhh4PdcnpCGH1 +Bm0wbhUZAulSwGLbTZme4moMRDjN/r7jZAlwxf6xaym2L0nIO9QnBCUQly/nkG3A +KEKZ10xD3sP1IW1Un13DWOHA5NlbsLjctHvfNjrCtWYiEtaHDQIDAQABMA0GCSqG +SIb3DQEBBAUAA4GBAIsvn7ifX3RUIrvYXtpI4DOfARkTogwm6o7OwVdl93yFhDcX +7h5t0XZ11MUAMziKdde3rmTvzUYIUCYoY5b032IwGMTvdiclK+STN6NP2m5nvFAM +qJT5gC5O+j/jBuZRQ4i0AMYQr5F4lT8oBJnhgafw6PL8aDY2vMHGSPl9+7uf +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDDTCCAnYCAQAwDQYJKoZIhvcNAQEEBQAwgc4xCzAJBgNVBAYTAlpBMRUwEwYD +VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBD +QTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTAeFw05 +NjA3MjcxODA3MTRaFw05ODA3MjcxODA3MTRaMIHOMQswCQYDVQQGEwJaQTEVMBMG +A1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNVBAoT +FFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIg +Q0ExKDAmBgkqhkiG9w0BCQEWGXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANI2NmqL18JbntqBQWKPOO5JBFXW0O8c +G5UWR+8YSDU6UvQragaPOy/qVuOvho2eF/eetGV1Ak3vywmiIVHYm9Bn0LoNkgYU +c9STy5cqAJxcTgy8+hVS/PJEbtoRSm4Iny8t4/mqOoZztkZTWMiJBb2DEbhzP6oH +jfRCTedAnRw3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAutFIgTRZVYerIZfL9lvR +w9Eifvvo5KTZ3h+Bj+VzNnyw4Qc/IyXkPOu6SIiH9LQ3sCmWBdxpe+qr4l77rLj2 +GYuMtESFfn1XVALzkYgC7JcPuTOjMfIiMByt+uFf8AV8x0IW/Qkuv+hEQcyM9vxK +3VZdLbCVIhNoEsysrxCpxcI= +-----END CERTIFICATE----- +Tims test GCI CA + +-----BEGIN CERTIFICATE----- +MIIB8DCCAZoCAQAwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAkFVMRMwEQYD +VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5 +cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBD +cnlwdFNvZnQgRGV2IENBMB4XDTk3MDMyMjEzMzQwNFoXDTk4MDMyMjEzMzQwNFow +gYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhC +cmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2Rl +dmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQgRGV2IENBMFwwDQYJKoZIhvcN +AQEBBQADSwAwSAJBAOAOAqogG5QwAmLhzyO4CoRnx/wVy4NZP4dxJy83O1EnL0rw +OdsamJKvPOLHgSXo3gDu9uVyvCf/QJmZAmC5ml8CAwEAATANBgkqhkiG9w0BAQQF +AANBADRRS/GVdd7rAqRW6SdmgLJduOU2yq3avBu99kRqbp9A/dLu6r6jU+eP4oOA +TfdbFZtAAD2Hx9jUtY3tfdrJOb8=  +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICVjCCAgACAQAwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAkFVMRMwEQYD +VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5 +cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsTI1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9O +IEFVVEhPUklUSUVTMTQwMgYDVQQDEytaRVJPIFZBTFVFIENBIC0gREVNT05TVFJB +VElPTiBQVVJQT1NFUyBPTkxZMB4XDTk3MDQwMzEzMjI1NFoXDTk4MDQwMzEzMjI1 +NFowgbUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH +EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsT +I1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9OIEFVVEhPUklUSUVTMTQwMgYDVQQDEyta +RVJPIFZBTFVFIENBIC0gREVNT05TVFJBVElPTiBQVVJQT1NFUyBPTkxZMFwwDQYJ +KoZIhvcNAQEBBQADSwAwSAJBAOZ7T7yqP/tyspcko3yPY1y0Cm2EmwNvzW4QgVXR +Fjs3HmJ4xtSpXdo6mwcGezL3Abt/aQXaxv9PU8xt+Jr0OFUCAwEAATANBgkqhkiG +9w0BAQQFAANBAOQpYmGgyCqCy1OljgJhCqQOu627oVlHzK1L+t9vBaMfn40AVUR4 +WzQVWO31KTgi5vTK1U+3h46fgUWqQ0h+6rU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIAwgKADAgECAgEAMA0GCSqGSIb3DQEBBAUAMGIxETAPBgNVBAcTCEludGVybmV0 +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh +c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjAeFw05NjA0MDgxMDIwMjda +Fw05NzA0MDgxMDIwMjdaMGIxETAPBgNVBAcTCEludGVybmV0MRcwFQYDVQQKEw5W +ZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xhc3MgMSBDQSAtIElu +ZGl2aWR1YWwgU3Vic2NyaWJlcjCAMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2 +FKbPTdAFDdjKI9BvqrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7j +W80GqLd5HUQq7XPysVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cari +QPJUObwW7s987LrbP2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABAAAAADANBgkqhkiG +9w0BAQQFAAOBgQA+1nJryNt8VBRjRr07ArDAV/3jAH7GjDc9jsrxZS68ost9v06C +TvTNKGL+LISNmFLXl+JXhgGB0JZ9fvyYzNgHQ46HBUng1H6voalfJgS2KdEo50wW +8EFZYMDkT1k4uynwJqkVN2QJK/2q4/A/VCov5h6SlM8Affg2W+1TLqvqkwAA +-----END CERTIFICATE----- + + subject=/L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber + issuer= /L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber + +-----BEGIN CERTIFICATE----- +MIIEkzCCA/ygAwIBAgIRANDTUpSRL3nTFeMrMayFSPAwDQYJKoZIhvcNAQECBQAw +YjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQw +MgYDVQQLEytWZXJpU2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3Jp +YmVyMB4XDTk2MDYwNDAwMDAwMFoXDTk4MDYwNDIzNTk1OVowYjERMA8GA1UEBxMI +SW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJp +U2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQC6A+2czKGRcYMfm8gdnk+0de99TDDzsqo0v5nb +RsbUmMcdRQ7nsMbRWe0SAb/9QoLTZ/cJ0iOBqdrkz7UpqqKarVoTSdlSMVM92tWp +3bJncZHQD1t4xd6lQVdI1/T6R+5J0T1ukOdsI9Jmf+F28S6g3R3L1SFwiHKeZKZv +z+793wIDAQABo4ICRzCCAkMwggIpBgNVHQMBAf8EggIdMIICGTCCAhUwggIRBgtg +hkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0ZXMg +YnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0IHRv +LCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQg +KENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL0NQ +Uy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29tOyBv +ciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4sIE1v +dW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04ODMw +IENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0cyBS +ZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJQUJJ +TElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQECMC8w +LRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMDAU +BglghkgBhvhCAQEBAf8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEApRJRkNBqLLgs +53IR/d18ODdLOWMTZ+QOOxBrq460iBEdUwgF8vmPRX1ku7UiDeNzaLlurE6eFqHq +2zPyK5j60zfTLVJMWKcQWwTJLjHtXrW8pxhNtFc6Fdvy5ZkHnC/9NIl7/t4U6WqB +p4y+p7SdMIkEwIZfds0VbnQyX5MRUJY= +-----END CERTIFICATE----- + + subject=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority + issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority +-----BEGIN CERTIFICATE----- +MIICMTCCAZoCBQKhAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa +Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln +biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyVxZ +nvIbigEUtBDfBEDb41evakVAj4QMC9Ez2dkRz+4CWB8l9yqoRAWq7AMfeH+ek7ma +AKojfdashaJjRcdyJ8z0TMZ1cdI5709C8HXfCpDGjiBvmA/4rCNfcCk2pMmG57Ga +IMtTpYXnPb59mv4kRTPcdhXtD6JxZExlLoFoRacCAwEAATANBgkqhkiG9w0BAQIF +AAOBgQB1Zmw+0c2B27X4LzZRtvdCvM1Cr9wO+hVs+GeTVzrrtpLotgHKjLeOQ7RJ +Zfk+7r11Ri7J/CVdqMcvi5uPaM+0nJcYwE3vH9mvgrPmZLiEXIqaB1JDYft0nls6 +NvxMsvwaPxUupVs8G5DsiCnkWRb5zget7Ond2tIxik/W2O8XjQ== +-----END CERTIFICATE----- + subject=/C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority + issuer= /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority +-----BEGIN CERTIFICATE----- +MIICMTCCAZoCBQKmAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa +Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln +biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LJ1 +9njQrlpQ9OlQqZ+M1++RlHDo0iSQdomF1t+s5gEXMoDwnZNHvJplnR+Xrr/phnVj +IIm9gFidBAydqMEk6QvlMXi9/C0MN2qeeIDpRnX57aP7E3vIwUzSo+/1PLBij0pd +O92VZ48TucE81qcmm+zDO3rZTbxtm+gVAePwR6kCAwEAATANBgkqhkiG9w0BAQIF +AAOBgQBT3dPwnCR+QKri/AAa19oM/DJhuBUNlvP6Vxt/M3yv6ZiaYch6s7f/sdyZ +g9ysEvxwyR84Qu1E9oAuW2szaayc01znX1oYx7EteQSWQZGZQbE8DbqEOcY7l/Am +yY7uvcxClf8exwI/VAx49byqYHwCaejcrOICdmHEPgPq0ook0Q== +-----END CERTIFICATE----- diff --git a/main/openssl/apps/server.srl b/main/openssl/apps/server.srl new file mode 100644 index 00000000..8a0f05e1 --- /dev/null +++ b/main/openssl/apps/server.srl @@ -0,0 +1 @@ +01 diff --git a/main/openssl/apps/server2.pem b/main/openssl/apps/server2.pem new file mode 100644 index 00000000..8bb66419 --- /dev/null +++ b/main/openssl/apps/server2.pem @@ -0,0 +1,376 @@ +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (1024 bit) +-----BEGIN CERTIFICATE----- +MIICLjCCAZcCAQEwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD +VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzU0WhcNOTgwNjA5 +MTM1NzU0WjBkMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG +A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxJDAiBgNVBAMTG1NlcnZlciB0ZXN0IGNl +cnQgKDEwMjQgYml0KTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsxH1PBPm +RkxrR11eV4bzNi4N9n11CI8nV29+ARlT1+qDe/mjVUvXlmsr1v/vf71G9GgqopSa +6RXrICLVdk/FYYYzhPvl1M+OrjaXDFO8BzBAF1Lnz6c7aRZvGRJNrRSr2nZEkqDf +JW9dY7r2VZEpD5QeuaRYUnuECkqeieB65GMCAwEAATANBgkqhkiG9w0BAQQFAAOB +gQCWsOta6C0wiVzXz8wPmJKyTrurMlgUss2iSuW9366iwofZddsNg7FXniMzkIf6 +dp7jnmWZwKZ9cXsNUS2o4OL07qOk2HOywC0YsNZQsOBu1CBTYYkIefDiKFL1zQHh +8lwwNd4NP+OE3NzUNkCfh4DnFfg9WHkXUlD5UpxNRJ4gJA== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV +S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP +pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB +AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0 +dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY +bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E +Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq +zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM +6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf +QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD +dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M +0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv +nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA== +-----END RSA PRIVATE KEY----- +subject=/C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA +issuer= /C=US/O=AT&T Bell Laboratories/OU=Prototype Research CA +notBefore=950413210656Z +notAfter =970412210656Z +-----BEGIN X509 CERTIFICATE----- + +MIICCDCCAXECAQAwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCVVMxHzAdBgNV +BAoUFkFUJlQgQmVsbCBMYWJvcmF0b3JpZXMxHjAcBgNVBAsUFVByb3RvdHlwZSBS +ZXNlYXJjaCBDQTAeFw05NTA0MTMyMTA2NTZaFw05NzA0MTIyMTA2NTZaME4xCzAJ +BgNVBAYTAlVTMR8wHQYDVQQKFBZBVCZUIEJlbGwgTGFib3JhdG9yaWVzMR4wHAYD +VQQLFBVQcm90b3R5cGUgUmVzZWFyY2ggQ0EwgZwwDQYJKoZIhvcNAQEBBQADgYoA +MIGGAoGAebOmgtSCl+wCYZc86UGYeTLY8cjmW2P0FN8ToT/u2pECCoFdrlycX0OR +3wt0ZhpFXLVNeDnHwEE9veNUih7pCL2ZBFqoIoQkB1lZmXRiVtjGonz8BLm/qrFM +YHb0lme/Ol+s118mwKVxnn6bSAeI/OXKhLaVdYZWk+aEaxEDkVkCAQ8wDQYJKoZI +hvcNAQEEBQADgYEAAZMG14lZmZ8bahkaHaTV9dQf4p2FZiQTFwHP9ZyGsXPC+LT5 +dG5iTaRmyjNIJdPWohZDl97kAci79aBndvuEvRKOjLHs3WRGBIwERnAcnY9Mz8u/ +zIHK23PjYVxGGaZd669OJwD0CYyqH22HH9nFUGaoJdsv39ChW0NRdLE9+y8= +-----END X509 CERTIFICATE----- +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit) +-----BEGIN CERTIFICATE----- +MIICJjCCAY8CAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD +VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0M1oXDTAxMDYw +OTEzNTc0M1owWzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDExJUZXN0IENBICgxMDI0 +IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKO7o8t116VP6cgybTsZ +DCZhr95nYlZuya3aCi1IKoztqwWnjbmDFIriOqGFPrZQ+moMETC9D59iRW/dFXSv +1F65ka/XY2hLh9exCCo7XuUcDs53Qp3bI3AmMqHjgzE8oO3ajyJAzJkTTOUecQU2 +mw/gI4tMM0LqWMQS7luTy4+xAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAM7achv3v +hLQJcv/65eGEpBXM40ZDVoFQFFJWaY5p883HTqLB1x4FdzsXHH0QKBTcKpWwqyu4 +YDm3fb8oDugw72bCzfyZK/zVZPR/hVlqI/fvU109Qoc+7oPvIXWky71HfcK6ZBCA +q30KIqGM/uoM60INq97qjDmCJapagcNBGQs= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCju6PLddelT+nIMm07GQwmYa/eZ2JWbsmt2gotSCqM7asFp425 +gxSK4jqhhT62UPpqDBEwvQ+fYkVv3RV0r9ReuZGv12NoS4fXsQgqO17lHA7Od0Kd +2yNwJjKh44MxPKDt2o8iQMyZE0zlHnEFNpsP4COLTDNC6ljEEu5bk8uPsQIDAQAB +AoGAVZmpFZsDZfr0l2S9tLLwpjRWNOlKATQkno6q2WesT0eGLQufTciY+c8ypfU6 +hyio8r5iUl/VhhdjhAtKx1mRpiotftHo/eYf8rtsrnprOnWG0bWjLjtIoMbcxGn2 +J3bN6LJmbJMjDs0eJ3KnTu646F3nDUw2oGAwmpzKXA1KAP0CQQDRvQhxk2D3Pehs +HvG665u2pB5ipYQngEFlZO7RHJZzJOZEWSLuuMqaF/7pTfA5jiBvWqCgJeCRRInL +21ru4dlPAkEAx9jj7BgKn5TYnMoBSSe0afjsV9oApVpN1Nacb1YDtCwy+scp3++s +nFxlv98wxIlSdpwMUn+AUWfjiWR7Tu/G/wJBAJ/KjwZIrFVxewP0x2ILYsTRYLzz +MS4PDsO7FB+I0i7DbBOifXS2oNSpd3I0CNMwrxFnUHzynpbOStVfN3ZL5w0CQQCa +pwFahxBRhkJKsxhjoFJBX9yl75JoY4Wvm5Tbo9ih6UJaRx3kqfkN14L2BKYcsZgb +KY9vmDOYy6iNfjDeWTfJAkBkfPUb8oTJ/nSP5zN6sqGxSY4krc4xLxpRmxoJ8HL2 +XfhqXkTzbU13RX9JJ/NZ8vQN9Vm2NhxRGJocQkmcdVtJ +-----END RSA PRIVATE KEY----- +-----BEGIN X509 CERTIFICATE----- +MIICYDCCAiACAgEoMAkGBSsOAwINBQAwfDELMAkGA1UEBhMCVVMxNjA0BgNVBAoT +LU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZ +MBcGA1UECxMQVGVzdCBFbnZpcm9ubWVudDEaMBgGA1UECxMRRFNTLU5BU0EtUGls +b3QtQ0EwHhcNOTYwMjI2MTYzMjQ1WhcNOTcwMjI1MTYzMjQ1WjB8MQswCQYDVQQG +EwJVUzE2MDQGA1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFk +bWluaXN0cmF0aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MRowGAYDVQQL +ExFEU1MtTkFTQS1QaWxvdC1DQTCB8jAJBgUrDgMCDAUAA4HkADCB4AJBAMA/ssKb +hPNUG7ZlASfVwEJU21O5OyF/iyBzgHI1O8eOhJGUYO8cc8wDMjR508Mr9cp6Uhl/ +ZB7FV5GkLNEnRHYCQQDUEaSg45P2qrDwixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLb +bn3QK74T2IxY1yY+kCNq8XrIqf5fJJzIH0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3 +fVd0geUCQQCzCFUQAh+ZkEmp5804cs6ZWBhrUAfnra8lJItYo9xPcXgdIfLfibcX +R71UsyO77MRD7B0+Ag2tq794IleCVcEEMAkGBSsOAwINBQADLwAwLAIUUayDfreR +Yh2WeU86/pHNdkUC1IgCFEfxe1f0oMpxJyrJ5XIxTi7vGdoK +-----END X509 CERTIFICATE----- +-----BEGIN X509 CERTIFICATE----- + +MIICGTCCAdgCAwCqTDAJBgUrDgMCDQUAMHwxCzAJBgNVBAYTAlVTMTYwNAYDVQQK +Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x +GTAXBgNVBAsTEFRlc3QgRW52aXJvbm1lbnQxGjAYBgNVBAsTEURTUy1OQVNBLVBp +bG90LUNBMB4XDTk2MDUxNDE3MDE0MVoXDTk3MDUxNDE3MDE0MVowMzELMAkGA1UE +BhMCQVUxDzANBgNVBAoTBk1pbmNvbTETMBEGA1UEAxMKRXJpYyBZb3VuZzCB8jAJ +BgUrDgMCDAUAA4HkADCB4AJBAKbfHz6vE6pXXMTpswtGUec2tvnfLJUsoxE9qs4+ +ObZX7LmLvragNPUeiTJx7UOWZ5DfBj6bXLc8eYne0lP1g3ACQQDUEaSg45P2qrDw +ixTRhFhmWz5Nvc4lRFQ/42XPcchiJBLbbn3QK74T2IxY1yY+kCNq8XrIqf5fJJzI +H0J/xUP3AhUAsg2wsQHfDGYk/BOSulX3fVd0geUCQQCzCFUQAh+ZkEmp5804cs6Z +WBhrUAfnra8lJItYo9xPcXgdIfLfibcXR71UsyO77MRD7B0+Ag2tq794IleCVcEE +MAkGBSsOAwINBQADMAAwLQIUWsuuJRE3VT4ueWkWMAJMJaZjj1ECFQCYY0zX4bzM +LC7obsrHD8XAHG+ZRG== +-----END X509 CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICTTCCAbagAwIBAgIBADANBgkqhkiG9w0BAQQFADBMMQswCQYDVQQGEwJHQjEM +MAoGA1UEChMDVUNMMRgwFgYDVQQLEw9JQ0UtVEVMIFByb2plY3QxFTATBgNVBAMT +DFRydXN0RmFjdG9yeTAeFw05NzA0MjIxNDM5MTRaFw05ODA0MjIxNDM5MTRaMEwx +CzAJBgNVBAYTAkdCMQwwCgYDVQQKEwNVQ0wxGDAWBgNVBAsTD0lDRS1URUwgUHJv +amVjdDEVMBMGA1UEAxMMVHJ1c3RGYWN0b3J5MIGcMAoGBFUIAQECAgQAA4GNADCB +iQKBgQCEieR8NcXkUW1f0G6aC6u0i8q/98JqS6RxK5YmHIGKCkuTWAUjzLfUa4dt +U9igGCjTuxaDqlzEim+t/02pmiBZT9HaX++35MjQPUWmsChcYU5WyzGErXi+rQaw +zlwS73zM8qiPj/97lXYycWhgL0VaiDSPxRXEUdWoaGruom4mNQIDAQABo0IwQDAd +BgNVHQ4EFgQUHal1LZr7oVg5z6lYzrhTgZRCmcUwDgYDVR0PAQH/BAQDAgH2MA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAfaggfl6FZoioecjv0dq8 +/DXo/u11iMZvXn08gjX/zl2b4wtPbShOSY5FhkSm8GeySasz+/Nwb/uzfnIhokWi +lfPZHtlCWtXbIy/TN51eJyq04ceDCQDWvLC2enVg9KB+GJ34b5c5VaPRzq8MBxsA +S7ELuYGtmYgYm9NZOIr7yU0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB6jCCAZQCAgEtMA0GCSqGSIb3DQEBBAUAMIGAMQswCQYDVQQGEwJVUzE2MDQG +A1UEChMtTmF0aW9uYWwgQWVyb25hdXRpY3MgYW5kIFNwYWNlIEFkbWluaXN0cmF0 +aW9uMRkwFwYDVQQLExBUZXN0IEVudmlyb25tZW50MR4wHAYDVQQLExVNRDUtUlNB +LU5BU0EtUGlsb3QtQ0EwHhcNOTYwNDMwMjIwNTAwWhcNOTcwNDMwMjIwNTAwWjCB +gDELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu +ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEZMBcGA1UECxMQVGVzdCBFbnZpcm9ubWVu +dDEeMBwGA1UECxMVTUQ1LVJTQS1OQVNBLVBpbG90LUNBMFkwCgYEVQgBAQICAgAD +SwAwSAJBALmmX5+GqAvcrWK13rfDrNX9UfeA7f+ijyBgeFQjYUoDpFqapw4nzQBL +bAXug8pKkRwa2Zh8YODhXsRWu2F/UckCAwEAATANBgkqhkiG9w0BAQQFAANBAH9a +OBA+QCsjxXgnSqHx04gcU8S49DVUb1f2XVoLnHlIb8RnX0k5O6mpHT5eti9bLkiW +GJNMJ4L0AJ/ac+SmHZc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICajCCAdMCBDGA0QUwDQYJKoZIhvcNAQEEBQAwfTELMAkGA1UEBhMCQ2ExDzAN +BgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmlsaXR5IEFjY2VwdGVkMR8w +HQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRwwGgYDVQQDExNFbnRydXN0 +IERlbW8gV2ViIENBMB4XDTk2MDQyNjEzMzUwMVoXDTA2MDQyNjEzMzUwMVowfTEL +MAkGA1UEBhMCQ2ExDzANBgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmls +aXR5IEFjY2VwdGVkMR8wHQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRww +GgYDVQQDExNFbnRydXN0IERlbW8gV2ViIENBMIGdMA0GCSqGSIb3DQEBAQUAA4GL +ADCBhwKBgQCaroS7O1DA0hm4IefNYU1cx/nqOmzEnk291d1XqznDeF4wEgakbkCc +zTKxK791yNpXG5RmngqH7cygDRTHZJ6mfCRn0wGC+AI00F2vYTGqPGRQL1N3lZT0 +YDKFC0SQeMMjFIZ1aeQigroFQnHo0VB3zWIMpNkka8PY9lxHZAmWwQIBAzANBgkq +hkiG9w0BAQQFAAOBgQBAx0UMVA1s54lMQyXjMX5kj99FJN5itb8bK1Rk+cegPQPF +cWO9SEWyEjjBjIkjjzAwBkaEszFsNGxemxtXvwjIm1xEUMTVlPEWTs2qnDvAUA9W +YqhWbhH0toGT36236QAsqCZ76rbTRVSSX2BHyJwJMG2tCRv7kRJ//NIgxj3H4w== +-----END CERTIFICATE----- + +issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test PCA (1024 bit) +-----BEGIN CERTIFICATE----- +MIICJzCCAZACAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYD +VQQDExNUZXN0IFBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTczN1oXDTAxMDYw +OTEzNTczN1owXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy +NCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdoWk/3+WcMlfjIrkg +40ketmnQaEogQe1LLcuOJV6rKfUSAsPgwgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp +22Jp85PmemiDzyUIStwk72qhp1imbANZvlmlCFKiQrjUyuDfu4TABmn+kkt3vR1Y +BEOGt+IFye1UBVSATVdRJ2UVhwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABNA1u/S +Cg/LJZWb7GliiKJsvuhxlE4E5JxQF2zMub/CSNbF97//tYSyj96sxeFQxZXbcjm9 +xt6mr/xNLA4szNQMJ4P+L7b5e/jC5DSqlwS+CUYJgaFs/SP+qJoCSu1bR3IM9XWO +cRBpDmcBbYLkSyB92WURvsZ1LtjEcn+cdQVI +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7 +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc= +-----END RSA PRIVATE KEY----- +subject=/C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority +issuer= /C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority +notBefore=941104185834Z +notAfter =991103185834Z +-----BEGIN X509 CERTIFICATE----- + +MIICIzCCAZACBQJBAAAWMA0GCSqGSIb3DQEBAgUAMFwxCzAJBgNVBAYTAlVTMSAw +HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVy +Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDQxODU4MzRaFw05 +OTExMDMxODU4MzRaMFwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBT +ZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVyY2lhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCk+4Fie84QJ93o +975sbsZwmdu41QUDaSiCnHJ/lj+O7Kwpkj+KFPhCdr69XQO5kNTQvAayUTNfxMK/ +touPmbZiImDd298ggrTKoi8tUO2UMt7gVY3UaOLgTNLNBRYulWZcYVI4HlGogqHE +7yXpCuaLK44xZtn42f29O2nZ6wIDAQABMA0GCSqGSIb3DQEBAgUAA34AdrW2EP4j +9/dZYkuwX5zBaLxJu7NJbyFHXSudVMQAKD+YufKKg5tgf+tQx6sFEC097TgCwaVI +0v5loMC86qYjFmZsGySp8+x5NRhPJsjjr1BKx6cxa9B8GJ1Qv6km+iYrRpwUqbtb +MJhCKLVLU7tDCZJAuqiqWqTGtotXTcU= +-----END X509 CERTIFICATE----- +subject=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority +issuer= /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority +notBefore=941109235417Z +notAfter =991231235417Z +-----BEGIN X509 CERTIFICATE----- + +MIICKTCCAZYCBQJBAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw +HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl +IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDkyMzU0MTda +Fw05OTEyMzEyMzU0MTdaMF8xCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0 +YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJlIFNlcnZlciBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCSznrB +roM+WqqJg1esJQF2DK2ujiw3zus1eGRUA+WEQFHJv48I4oqCCNIWhjdV6bEhAq12 +aIGaBaJLyUslZiJWbIgHj/eBWW2EB2VwE3F2Ppt3TONQiVaYSLkdpykaEy5KEVmc +HhXVSVQsczppgrGXOZxtcGdI5d0t1sgeewIDAQABMA0GCSqGSIb3DQEBAgUAA34A +iNHReSHO4ovo+MF9NFM/YYPZtgs4F7boviGNjwC4i1N+RGceIr2XJ+CchcxK9oU7 +suK+ktPlDemvXA4MRpX/oRxePug2WHpzpgr4IhFrwwk4fia7c+8AvQKk8xQNMD9h +cHsg/jKjn7P0Z1LctO6EjJY2IN6BCINxIYoPnqk= +-----END X509 CERTIFICATE----- +subject=/C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc +	/OU=Certification Services Division/CN=Thawte Server CA +	/Email=server-certs@thawte.com +issuer= /C=ZA/SP=Western Cape/L=Cape Town/O=Thawte Consulting cc +	/OU=Certification Services Division/CN=Thawte Server CA +	/Email=server-certs@thawte.com +-----BEGIN CERTIFICATE----- +MIIC+TCCAmICAQAwDQYJKoZIhvcNAQEEBQAwgcQxCzAJBgNVBAYTAlpBMRUwEwYD +VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkq +hkiG9w0BCQEWF3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMB4XDTk2MDcyNzE4MDc1 +N1oXDTk4MDcyNzE4MDc1N1owgcQxCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0 +ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENv +bnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 +aXNpb24xGTAXBgNVBAMTEFRoYXd0ZSBTZXJ2ZXIgQ0ExJjAkBgkqhkiG9w0BCQEW +F3NlcnZlci1jZXJ0c0B0aGF3dGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDTpFBuyP9Wa+bPXbbqDGh1R6KqwtqEJfyo9EdR2oW1IHSUhh4PdcnpCGH1 +Bm0wbhUZAulSwGLbTZme4moMRDjN/r7jZAlwxf6xaym2L0nIO9QnBCUQly/nkG3A +KEKZ10xD3sP1IW1Un13DWOHA5NlbsLjctHvfNjrCtWYiEtaHDQIDAQABMA0GCSqG +SIb3DQEBBAUAA4GBAIsvn7ifX3RUIrvYXtpI4DOfARkTogwm6o7OwVdl93yFhDcX +7h5t0XZ11MUAMziKdde3rmTvzUYIUCYoY5b032IwGMTvdiclK+STN6NP2m5nvFAM +qJT5gC5O+j/jBuZRQ4i0AMYQr5F4lT8oBJnhgafw6PL8aDY2vMHGSPl9+7uf +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDDTCCAnYCAQAwDQYJKoZIhvcNAQEEBQAwgc4xCzAJBgNVBAYTAlpBMRUwEwYD +VQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBD +QTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTAeFw05 +NjA3MjcxODA3MTRaFw05ODA3MjcxODA3MTRaMIHOMQswCQYDVQQGEwJaQTEVMBMG +A1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNVBAoT +FFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzIERpdmlzaW9uMSEwHwYDVQQDExhUaGF3dGUgUHJlbWl1bSBTZXJ2ZXIg +Q0ExKDAmBgkqhkiG9w0BCQEWGXByZW1pdW0tc2VydmVyQHRoYXd0ZS5jb20wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANI2NmqL18JbntqBQWKPOO5JBFXW0O8c +G5UWR+8YSDU6UvQragaPOy/qVuOvho2eF/eetGV1Ak3vywmiIVHYm9Bn0LoNkgYU +c9STy5cqAJxcTgy8+hVS/PJEbtoRSm4Iny8t4/mqOoZztkZTWMiJBb2DEbhzP6oH +jfRCTedAnRw3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAutFIgTRZVYerIZfL9lvR +w9Eifvvo5KTZ3h+Bj+VzNnyw4Qc/IyXkPOu6SIiH9LQ3sCmWBdxpe+qr4l77rLj2 +GYuMtESFfn1XVALzkYgC7JcPuTOjMfIiMByt+uFf8AV8x0IW/Qkuv+hEQcyM9vxK +3VZdLbCVIhNoEsysrxCpxcI= +-----END CERTIFICATE----- +Tims test GCI CA + +-----BEGIN CERTIFICATE----- +MIIB8DCCAZoCAQAwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAkFVMRMwEQYD +VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5 +cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBD +cnlwdFNvZnQgRGV2IENBMB4XDTk3MDMyMjEzMzQwNFoXDTk4MDMyMjEzMzQwNFow +gYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhC +cmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2Rl +dmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQgRGV2IENBMFwwDQYJKoZIhvcN +AQEBBQADSwAwSAJBAOAOAqogG5QwAmLhzyO4CoRnx/wVy4NZP4dxJy83O1EnL0rw +OdsamJKvPOLHgSXo3gDu9uVyvCf/QJmZAmC5ml8CAwEAATANBgkqhkiG9w0BAQQF +AANBADRRS/GVdd7rAqRW6SdmgLJduOU2yq3avBu99kRqbp9A/dLu6r6jU+eP4oOA +TfdbFZtAAD2Hx9jUtY3tfdrJOb8=  +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICVjCCAgACAQAwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAkFVMRMwEQYD +VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5 +cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsTI1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9O +IEFVVEhPUklUSUVTMTQwMgYDVQQDEytaRVJPIFZBTFVFIENBIC0gREVNT05TVFJB +VElPTiBQVVJQT1NFUyBPTkxZMB4XDTk3MDQwMzEzMjI1NFoXDTk4MDQwMzEzMjI1 +NFowgbUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH +EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsT +I1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9OIEFVVEhPUklUSUVTMTQwMgYDVQQDEyta +RVJPIFZBTFVFIENBIC0gREVNT05TVFJBVElPTiBQVVJQT1NFUyBPTkxZMFwwDQYJ +KoZIhvcNAQEBBQADSwAwSAJBAOZ7T7yqP/tyspcko3yPY1y0Cm2EmwNvzW4QgVXR +Fjs3HmJ4xtSpXdo6mwcGezL3Abt/aQXaxv9PU8xt+Jr0OFUCAwEAATANBgkqhkiG +9w0BAQQFAANBAOQpYmGgyCqCy1OljgJhCqQOu627oVlHzK1L+t9vBaMfn40AVUR4 +WzQVWO31KTgi5vTK1U+3h46fgUWqQ0h+6rU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIAwgKADAgECAgEAMA0GCSqGSIb3DQEBBAUAMGIxETAPBgNVBAcTCEludGVybmV0 +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xh +c3MgMSBDQSAtIEluZGl2aWR1YWwgU3Vic2NyaWJlcjAeFw05NjA0MDgxMDIwMjda +Fw05NzA0MDgxMDIwMjdaMGIxETAPBgNVBAcTCEludGVybmV0MRcwFQYDVQQKEw5W +ZXJpU2lnbiwgSW5jLjE0MDIGA1UECxMrVmVyaVNpZ24gQ2xhc3MgMSBDQSAtIElu +ZGl2aWR1YWwgU3Vic2NyaWJlcjCAMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2 +FKbPTdAFDdjKI9BvqrQpkmOOLPhvltcunXZLEbE2jVfJw/0cxrr+Hgi6M8qV6r7j +W80GqLd5HUQq7XPysVKDaBBwZJHXPmv5912dFEObbpdFmIFH0S3L3bty10w/cari +QPJUObwW7s987LrbP2wqsxaxhhKdrpM01bjV0Pc+qQIDAQABAAAAADANBgkqhkiG +9w0BAQQFAAOBgQA+1nJryNt8VBRjRr07ArDAV/3jAH7GjDc9jsrxZS68ost9v06C +TvTNKGL+LISNmFLXl+JXhgGB0JZ9fvyYzNgHQ46HBUng1H6voalfJgS2KdEo50wW +8EFZYMDkT1k4uynwJqkVN2QJK/2q4/A/VCov5h6SlM8Affg2W+1TLqvqkwAA +-----END CERTIFICATE----- + + subject=/L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber + issuer= /L=Internet/O=VeriSign, Inc./OU=VeriSign Class 2 CA - Individual Subscriber + +-----BEGIN CERTIFICATE----- +MIIEkzCCA/ygAwIBAgIRANDTUpSRL3nTFeMrMayFSPAwDQYJKoZIhvcNAQECBQAw +YjERMA8GA1UEBxMISW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQw +MgYDVQQLEytWZXJpU2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3Jp +YmVyMB4XDTk2MDYwNDAwMDAwMFoXDTk4MDYwNDIzNTk1OVowYjERMA8GA1UEBxMI +SW50ZXJuZXQxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTQwMgYDVQQLEytWZXJp +U2lnbiBDbGFzcyAyIENBIC0gSW5kaXZpZHVhbCBTdWJzY3JpYmVyMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQC6A+2czKGRcYMfm8gdnk+0de99TDDzsqo0v5nb +RsbUmMcdRQ7nsMbRWe0SAb/9QoLTZ/cJ0iOBqdrkz7UpqqKarVoTSdlSMVM92tWp +3bJncZHQD1t4xd6lQVdI1/T6R+5J0T1ukOdsI9Jmf+F28S6g3R3L1SFwiHKeZKZv +z+793wIDAQABo4ICRzCCAkMwggIpBgNVHQMBAf8EggIdMIICGTCCAhUwggIRBgtg +hkgBhvhFAQcBATCCAgAWggGrVGhpcyBjZXJ0aWZpY2F0ZSBpbmNvcnBvcmF0ZXMg +YnkgcmVmZXJlbmNlLCBhbmQgaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0IHRv +LCB0aGUgVmVyaVNpZ24gQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQg +KENQUyksIGF2YWlsYWJsZSBhdDogaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL0NQ +Uy0xLjA7IGJ5IEUtbWFpbCBhdCBDUFMtcmVxdWVzdHNAdmVyaXNpZ24uY29tOyBv +ciBieSBtYWlsIGF0IFZlcmlTaWduLCBJbmMuLCAyNTkzIENvYXN0IEF2ZS4sIE1v +dW50YWluIFZpZXcsIENBIDk0MDQzIFVTQSBUZWwuICsxICg0MTUpIDk2MS04ODMw +IENvcHlyaWdodCAoYykgMTk5NiBWZXJpU2lnbiwgSW5jLiAgQWxsIFJpZ2h0cyBS +ZXNlcnZlZC4gQ0VSVEFJTiBXQVJSQU5USUVTIERJU0NMQUlNRUQgYW5kIExJQUJJ +TElUWSBMSU1JVEVELqAOBgxghkgBhvhFAQcBAQGhDgYMYIZIAYb4RQEHAQECMC8w +LRYraHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTLTEuMDAU +BglghkgBhvhCAQEBAf8EBAMCAgQwDQYJKoZIhvcNAQECBQADgYEApRJRkNBqLLgs +53IR/d18ODdLOWMTZ+QOOxBrq460iBEdUwgF8vmPRX1ku7UiDeNzaLlurE6eFqHq +2zPyK5j60zfTLVJMWKcQWwTJLjHtXrW8pxhNtFc6Fdvy5ZkHnC/9NIl7/t4U6WqB +p4y+p7SdMIkEwIZfds0VbnQyX5MRUJY= +-----END CERTIFICATE----- + + subject=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority + issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority +-----BEGIN CERTIFICATE----- +MIICMTCCAZoCBQKhAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa +Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln +biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyVxZ +nvIbigEUtBDfBEDb41evakVAj4QMC9Ez2dkRz+4CWB8l9yqoRAWq7AMfeH+ek7ma +AKojfdashaJjRcdyJ8z0TMZ1cdI5709C8HXfCpDGjiBvmA/4rCNfcCk2pMmG57Ga +IMtTpYXnPb59mv4kRTPcdhXtD6JxZExlLoFoRacCAwEAATANBgkqhkiG9w0BAQIF +AAOBgQB1Zmw+0c2B27X4LzZRtvdCvM1Cr9wO+hVs+GeTVzrrtpLotgHKjLeOQ7RJ +Zfk+7r11Ri7J/CVdqMcvi5uPaM+0nJcYwE3vH9mvgrPmZLiEXIqaB1JDYft0nls6 +NvxMsvwaPxUupVs8G5DsiCnkWRb5zget7Ond2tIxik/W2O8XjQ== +-----END CERTIFICATE----- + subject=/C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority + issuer= /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority +-----BEGIN CERTIFICATE----- +MIICMTCCAZoCBQKmAAABMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBa +Fw05OTEyMzEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln +biwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LJ1 +9njQrlpQ9OlQqZ+M1++RlHDo0iSQdomF1t+s5gEXMoDwnZNHvJplnR+Xrr/phnVj +IIm9gFidBAydqMEk6QvlMXi9/C0MN2qeeIDpRnX57aP7E3vIwUzSo+/1PLBij0pd +O92VZ48TucE81qcmm+zDO3rZTbxtm+gVAePwR6kCAwEAATANBgkqhkiG9w0BAQIF +AAOBgQBT3dPwnCR+QKri/AAa19oM/DJhuBUNlvP6Vxt/M3yv6ZiaYch6s7f/sdyZ +g9ysEvxwyR84Qu1E9oAuW2szaayc01znX1oYx7EteQSWQZGZQbE8DbqEOcY7l/Am +yY7uvcxClf8exwI/VAx49byqYHwCaejcrOICdmHEPgPq0ook0Q== +-----END CERTIFICATE----- diff --git a/main/openssl/apps/sess_id.c b/main/openssl/apps/sess_id.c new file mode 100644 index 00000000..b99179f2 --- /dev/null +++ b/main/openssl/apps/sess_id.c @@ -0,0 +1,320 @@ +/* apps/sess_id.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#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\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 CRL output\n", +" -context arg    - set the session ID context\n", +NULL +}; + +static SSL_SESSION *load_sess_id(char *file, int format); + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	SSL_SESSION *x=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) +			text= ++num; +		else if (strcmp(*argv,"-cert") == 0) +			cert= ++num; +		else if (strcmp(*argv,"-noout") == 0) +			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; +			} +		argc--; +		argv++; +		} + +	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; } + +	if(context) +	    { +	    x->sid_ctx_length=strlen(context); +	    if(x->sid_ctx_length > SSL_MAX_SID_CTX_LENGTH) +		{ +		BIO_printf(bio_err,"Context too long\n"); +		goto end; +		} +	    memcpy(x->sid_ctx,context,x->sid_ctx_length); +	    } + +#ifdef undef +	/* just testing for memory leaks :-) */ +	{ +	SSL_SESSION *s; +	char buf[1024*10],*p; +	int i; + +	s=SSL_SESSION_new(); + +	p= &buf; +	i=i2d_SSL_SESSION(x,&p); +	p= &buf; +	d2i_SSL_SESSION(&s,&p,(long)i); +	p= &buf; +	d2i_SSL_SESSION(&s,&p,(long)i); +	p= &buf; +	d2i_SSL_SESSION(&s,&p,(long)i); +	SSL_SESSION_free(s); +	} +#endif + +	if (!noout || text) +		{ +		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 (text) +		{ +		SSL_SESSION_print(out,x); + +		if (cert) +			{ +			if (x->peer == NULL) +				BIO_puts(out,"No certificate present\n"); +			else +				X509_print(out,x->peer); +			} +		} + +	if (!noout && !cert) +		{ +		if 	(outformat == FORMAT_ASN1) +			i=i2d_SSL_SESSION_bio(out,x); +		else if (outformat == FORMAT_PEM) +			i=PEM_write_bio_SSL_SESSION(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 SSL_SESSION\n"); +			goto end; +			} +		} +	else if (!noout && (x->peer != NULL)) /* just print the certificate */ +		{ +		if 	(outformat == FORMAT_ASN1) +			i=(int)i2d_X509_bio(out,x->peer); +		else if (outformat == FORMAT_PEM) +			i=PEM_write_bio_X509(out,x->peer); +		else	{ +			BIO_printf(bio_err,"bad output format specified for outfile\n"); +			goto end; +			} +		if (!i) { +			BIO_printf(bio_err,"unable to write X509\n"); +			goto end; +			} +		} +	ret=0; +end: +	if (out != NULL) BIO_free_all(out); +	if (x != NULL) SSL_SESSION_free(x); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +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); +		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) +		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); +		goto end; +		} +	 +end: +	if (in != NULL) BIO_free(in); +	return(x); +	} + diff --git a/main/openssl/apps/smime.c b/main/openssl/apps/smime.c new file mode 100644 index 00000000..c583f8a0 --- /dev/null +++ b/main/openssl/apps/smime.c @@ -0,0 +1,857 @@ +/* smime.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* S/MIME utility function */ + +#include <stdio.h> +#include <string.h> +#include "apps.h" +#include <openssl/crypto.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#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); + +#define SMIME_OP	0x10 +#define SMIME_IP	0x20 +#define SMIME_SIGNERS	0x40 +#define SMIME_ENCRYPT	(1 | SMIME_OP) +#define SMIME_DECRYPT	(2 | SMIME_IP) +#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS) +#define SMIME_VERIFY	(4 | SMIME_IP) +#define SMIME_PK7OUT	(5 | SMIME_IP | SMIME_OP) +#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) + +int MAIN(int, char **); + +int 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; +	EVP_PKEY *key = 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; +	const EVP_MD *sign_md = NULL; +	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; +        int keyform = FORMAT_PEM; +#ifndef OPENSSL_NO_ENGINE +	char *engine=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; + +	while (!badarg && *args && *args[0] == '-') +		{ +		if (!strcmp (*args, "-encrypt")) +			operation = SMIME_ENCRYPT; +		else if (!strcmp (*args, "-decrypt")) +			operation = SMIME_DECRYPT; +		else if (!strcmp (*args, "-sign")) +			operation = SMIME_SIGN; +		else if (!strcmp (*args, "-resign")) +			operation = SMIME_RESIGN; +		else if (!strcmp (*args, "-verify")) +			operation = SMIME_VERIFY; +		else if (!strcmp (*args, "-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"))  +				flags |= PKCS7_TEXT; +		else if (!strcmp (*args, "-nointern"))  +				flags |= PKCS7_NOINTERN; +		else if (!strcmp (*args, "-noverify"))  +				flags |= PKCS7_NOVERIFY; +		else if (!strcmp (*args, "-nochain"))  +				flags |= PKCS7_NOCHAIN; +		else if (!strcmp (*args, "-nocerts"))  +				flags |= PKCS7_NOCERTS; +		else if (!strcmp (*args, "-noattr"))  +				flags |= PKCS7_NOATTR; +		else if (!strcmp (*args, "-nodetach"))  +				flags &= ~PKCS7_DETACHED; +		else if (!strcmp (*args, "-nosmimecap")) +				flags |= PKCS7_NOSMIMECAP; +		else if (!strcmp (*args, "-binary")) +				flags |= PKCS7_BINARY; +		else if (!strcmp (*args, "-nosigs")) +				flags |= PKCS7_NOSIGS; +		else if (!strcmp (*args, "-stream")) +				indef = 1; +		else if (!strcmp (*args, "-indef")) +				indef = 1; +		else if (!strcmp (*args, "-noindef")) +				indef = 0; +		else if (!strcmp (*args, "-nooldmime")) +				flags |= PKCS7_NOOLDMIMETYPE; +		else if (!strcmp (*args, "-crlfeol")) +				flags |= PKCS7_CRLFEOL; +		else if (!strcmp(*args,"-rand")) +			{ +			if (!args[1]) +				goto argerr; +			args++; +			inrand = *args; +			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; +			/* If previous -signer argument add signer to list */ + +			if (signerfile) +				{ +				if (!sksigners) +					sksigners = sk_OPENSSL_STRING_new_null(); +				sk_OPENSSL_STRING_push(sksigners, signerfile); +				if (!keyfile) +					keyfile = signerfile; +				if (!skkeys) +					skkeys = sk_OPENSSL_STRING_new_null(); +				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; +			/* If previous -inkey arument add signer to list */ +			if (keyfile) +				{ +				if (!signerfile) +					{ +					BIO_puts(bio_err, "Illegal -inkey without -signer\n"); +					goto argerr; +					} +				if (!sksigners) +					sksigners = sk_OPENSSL_STRING_new_null(); +				sk_OPENSSL_STRING_push(sksigners, signerfile); +				signerfile = NULL; +				if (!skkeys) +					skkeys = sk_OPENSSL_STRING_new_null(); +				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++; +		} + +	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) +		{ +		BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); +		goto argerr; +		} + +	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; +			} +		if (signerfile) +			{ +			if (!sksigners) +				sksigners = sk_OPENSSL_STRING_new_null(); +			sk_OPENSSL_STRING_push(sksigners, signerfile); +			if (!skkeys) +				skkeys = sk_OPENSSL_STRING_new_null(); +			if (!keyfile) +				keyfile = signerfile; +			sk_OPENSSL_STRING_push(skkeys, keyfile); +			} +		if (!sksigners) +			{ +			BIO_printf(bio_err, "No signer certificate specified\n"); +			badarg = 1; +			} +		signerfile = NULL; +		keyfile = NULL; +		need_rand = 1; +		} +	else if (operation == SMIME_DECRYPT) +		{ +		if (!recipfile && !keyfile) +			{ +			BIO_printf(bio_err, "No recipient certificate or key specified\n"); +			badarg = 1; +			} +		} +	else if (operation == SMIME_ENCRYPT) +		{ +		if (!*args) +			{ +			BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); +			badarg = 1; +			} +		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, "-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; +		} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	if (!app_passwd(bio_err, passargin, 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)); +		if (inrand != NULL) +			BIO_printf(bio_err,"%ld semi-random bytes loaded\n", +				app_RAND_load_files(inrand)); +		} + +	ret = 2; + +	if (!(operation & SMIME_SIGNERS)) +		flags &= ~PKCS7_DETACHED; + +	if (operation & SMIME_OP) +		{ +		if (outformat == FORMAT_ASN1) +			outmode = "wb"; +		} +	else +		{ +		if (flags & PKCS7_BINARY) +			outmode = "wb"; +		} + +	if (operation & SMIME_IP) +		{ +		if (informat == FORMAT_ASN1) +			inmode = "rb"; +		} +	else +		{ +		if (flags & PKCS7_BINARY) +			inmode = "rb"; +		} + +	if (operation == SMIME_ENCRYPT) +		{ +		if (!cipher) +			{ +#ifndef OPENSSL_NO_RC2			 +			cipher = EVP_rc2_40_cbc(); +#else +			BIO_printf(bio_err, "No cipher selected\n"); +			goto end; +#endif +			} +		encerts = sk_X509_new_null(); +		while (*args) +			{ +			if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, +				NULL, e, "recipient certificate file"))) +				{ +#if 0				/* An appropriate message is already printed */ +				BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args); +#endif +				goto end; +				} +			sk_X509_push(encerts, cert); +			cert = NULL; +			args++; +			} +		} + +	if (certfile) +		{ +		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, +			e, "certificate file"))) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (recipfile && (operation == SMIME_DECRYPT)) +		{ +		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, +			e, "recipient certificate file"))) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} +		} + +	if (operation == SMIME_DECRYPT) +		{ +		if (!keyfile) +			keyfile = recipfile; +		} +	else if (operation == SMIME_SIGN) +		{ +		if (!keyfile) +			keyfile = signerfile; +		} +	else keyfile = NULL; + +	if (keyfile) +		{ +		key = load_key(bio_err, 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); + +	if (operation & SMIME_IP) +		{ +		if (informat == FORMAT_SMIME)  +			p7 = SMIME_read_PKCS7(in, &indata); +		else if (informat == FORMAT_PEM)  +			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); +		else if (informat == FORMAT_ASN1)  +			p7 = d2i_PKCS7_bio(in, NULL); +		else +			{ +			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); +			goto end; +			} + +		if (!p7) +			{ +			BIO_printf(bio_err, "Error reading S/MIME message\n"); +			goto end; +			} +		if (contfile) +			{ +			BIO_free(indata); +			if (!(indata = BIO_new_file(contfile, "rb"))) +				{ +				BIO_printf(bio_err, "Can't read content file %s\n", contfile); +				goto end; +				} +			} +		} + +	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 +		} + +	if (operation == SMIME_VERIFY) +		{ +		if (!(store = setup_verify(bio_err, CAfile, CApath))) +			goto end; +		X509_STORE_set_verify_cb(store, smime_cb); +		if (vpm) +			X509_STORE_set1_param(store, vpm); +		} + + +	ret = 3; + +	if (operation == SMIME_ENCRYPT) +		{ +		if (indef) +			flags |= PKCS7_STREAM; +		p7 = PKCS7_encrypt(encerts, in, cipher, flags); +		} +	else if (operation & SMIME_SIGNERS) +		{ +		int i; +		/* If detached data content we only enable streaming if +		 * S/MIME output format. +		 */ +		if (operation == SMIME_SIGN) +			{ +			if (flags & PKCS7_DETACHED) +				{ +				if (outformat == FORMAT_SMIME) +					flags |= PKCS7_STREAM; +				} +			else if (indef) +				flags |= PKCS7_STREAM; +			flags |= PKCS7_PARTIAL; +			p7 = PKCS7_sign(NULL, NULL, other, in, flags); +			if (!p7) +				goto end; +			} +		else +			flags |= PKCS7_REUSE_DIGEST; +		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, +					e, "signer certificate"); +			if (!signer) +				goto end; +			key = load_key(bio_err, keyfile, keyform, 0, passin, e, +			       "signing key file"); +			if (!key) +				goto end; +			if (!PKCS7_sign_add_signer(p7, signer, key, +						sign_md, flags)) +				goto end; +			X509_free(signer); +			signer = NULL; +			EVP_PKEY_free(key); +			key = NULL; +			} +		/* If not streaming or resigning finalize structure */ +		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) +			{ +			if (!PKCS7_final(p7, in, flags)) +				goto end; +			} +		} + +	if (!p7) +		{ +		BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); +		goto end; +		} + +	ret = 4; +	if (operation == SMIME_DECRYPT) +		{ +		if (!PKCS7_decrypt(p7, key, recip, out, flags)) +			{ +			BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); +			goto end; +			} +		} +	else if (operation == SMIME_VERIFY) +		{ +		STACK_OF(X509) *signers; +		if (PKCS7_verify(p7, other, store, indata, out, flags)) +			BIO_printf(bio_err, "Verification successful\n"); +		else +			{ +			BIO_printf(bio_err, "Verification failure\n"); +			goto end; +			} +		signers = PKCS7_get0_signers(p7, other, flags); +		if (!save_certs(signerfile, signers)) +			{ +			BIO_printf(bio_err, "Error writing signers to %s\n", +								signerfile); +			ret = 5; +			goto end; +			} +		sk_X509_free(signers); +		} +	else if (operation == SMIME_PK7OUT) +		PEM_write_bio_PKCS7(out, p7); +	else +		{ +		if (to) +			BIO_printf(out, "To: %s\n", to); +		if (from) +			BIO_printf(out, "From: %s\n", from); +		if (subject) +			BIO_printf(out, "Subject: %s\n", subject); +		if (outformat == FORMAT_SMIME)  +			{ +			if (operation == SMIME_RESIGN) +				SMIME_write_PKCS7(out, p7, indata, flags); +			else +				SMIME_write_PKCS7(out, p7, in, flags); +			} +		else if (outformat == FORMAT_PEM)  +			PEM_write_bio_PKCS7_stream(out, p7, in, flags); +		else if (outformat == FORMAT_ASN1)  +			i2d_PKCS7_bio_stream(out,p7, in, flags); +		else +			{ +			BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); +			goto end; +			} +		} +	ret = 0; +end: +	if (need_rand) +		app_RAND_write_file(NULL, bio_err); +	if (ret) ERR_print_errors(bio_err); +	sk_X509_pop_free(encerts, X509_free); +	sk_X509_pop_free(other, X509_free); +	if (vpm) +		X509_VERIFY_PARAM_free(vpm); +	if (sksigners) +		sk_OPENSSL_STRING_free(sksigners); +	if (skkeys) +		sk_OPENSSL_STRING_free(skkeys); +	X509_STORE_free(store); +	X509_free(cert); +	X509_free(recip); +	X509_free(signer); +	EVP_PKEY_free(key); +	PKCS7_free(p7); +	BIO_free(in); +	BIO_free(indata); +	BIO_free_all(out); +	if (passin) OPENSSL_free(passin); +	return (ret); +} + +static int save_certs(char *signerfile, STACK_OF(X509) *signers) +	{ +	int i; +	BIO *tmp; +	if (!signerfile) +		return 1; +	tmp = BIO_new_file(signerfile, "w"); +	if (!tmp) return 0; +	for(i = 0; i < sk_X509_num(signers); i++) +		PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); +	BIO_free(tmp); +	return 1; +	} +	 + +/* Minimal callback just to output policy info (if any) */ + +static int smime_cb(int ok, X509_STORE_CTX *ctx) +	{ +	int error; + +	error = X509_STORE_CTX_get_error(ctx); + +	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) +		&& ((error != X509_V_OK) || (ok != 2))) +		return ok; + +	policies_print(NULL, ctx); + +	return ok; + +	} diff --git a/main/openssl/apps/speed.c b/main/openssl/apps/speed.c new file mode 100644 index 00000000..b3c54424 --- /dev/null +++ b/main/openssl/apps/speed.c @@ -0,0 +1,2787 @@ +/* apps/speed.c -*- mode:C; c-file-style: "eay" -*- */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by  + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The ECDH and ECDSA speed test software is originally written by  + * Sumit Gupta of Sun Microsystems Laboratories. + * + */ + +/* most of this code has been pilfered from my libdes speed.c program */ + +#ifndef OPENSSL_NO_SPEED + +#undef SECONDS +#define SECONDS		3	 +#define RSA_SECONDS	10 +#define DSA_SECONDS	10 +#define ECDSA_SECONDS   10 +#define ECDH_SECONDS    10 + +/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */ + +#undef PROG +#define PROG speed_main + +#include <stdio.h> +#include <stdlib.h> + +#include <string.h> +#include <math.h> +#include "apps.h" +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#if !defined(OPENSSL_SYS_MSDOS) +#include OPENSSL_UNISTD +#endif + +#ifndef OPENSSL_SYS_NETWARE +#include <signal.h> +#endif + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include <openssl/bn.h> +#ifndef OPENSSL_NO_DES +#include <openssl/des.h> +#endif +#ifndef OPENSSL_NO_AES +#include <openssl/aes.h> +#endif +#ifndef OPENSSL_NO_CAMELLIA +#include <openssl/camellia.h> +#endif +#ifndef OPENSSL_NO_MD2 +#include <openssl/md2.h> +#endif +#ifndef OPENSSL_NO_MDC2 +#include <openssl/mdc2.h> +#endif +#ifndef OPENSSL_NO_MD4 +#include <openssl/md4.h> +#endif +#ifndef OPENSSL_NO_MD5 +#include <openssl/md5.h> +#endif +#ifndef OPENSSL_NO_HMAC +#include <openssl/hmac.h> +#endif +#include <openssl/evp.h> +#ifndef OPENSSL_NO_SHA +#include <openssl/sha.h> +#endif +#ifndef OPENSSL_NO_RIPEMD +#include <openssl/ripemd.h> +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +#include <openssl/whrlpool.h> +#endif +#ifndef OPENSSL_NO_RC4 +#include <openssl/rc4.h> +#endif +#ifndef OPENSSL_NO_RC5 +#include <openssl/rc5.h> +#endif +#ifndef OPENSSL_NO_RC2 +#include <openssl/rc2.h> +#endif +#ifndef OPENSSL_NO_IDEA +#include <openssl/idea.h> +#endif +#ifndef OPENSSL_NO_SEED +#include <openssl/seed.h> +#endif +#ifndef OPENSSL_NO_BF +#include <openssl/blowfish.h> +#endif +#ifndef OPENSSL_NO_CAST +#include <openssl/cast.h> +#endif +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#include "./testrsa.h" +#endif +#include <openssl/x509.h> +#ifndef OPENSSL_NO_DSA +#include <openssl/dsa.h> +#include "./testdsa.h" +#endif +#ifndef OPENSSL_NO_ECDSA +#include <openssl/ecdsa.h> +#endif +#ifndef OPENSSL_NO_ECDH +#include <openssl/ecdh.h> +#endif + +#ifndef HAVE_FORK +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE) +#  define HAVE_FORK 0 +# else +#  define HAVE_FORK 1 +# endif +#endif + +#if HAVE_FORK +#undef NO_FORK +#else +#define NO_FORK +#endif + +#undef BUFSIZE +#define BUFSIZE	((long)1024*8+1) +int run=0; + +static int mr=0; +static int usertime=1; + +static double Time_F(int s); +static void print_message(const char *s,long num,int length); +static void pkey_print_message(const char *str, const char *str2, +	long num, int bits, int sec); +static void print_result(int alg,int run_no,int count,double time_used); +#ifndef NO_FORK +static int do_multi(int multi); +#endif + +#define ALGOR_NUM	29 +#define SIZE_NUM	5 +#define RSA_NUM		4 +#define DSA_NUM		3 + +#define EC_NUM       16 +#define MAX_ECDH_SIZE 256 + +static const char *names[ALGOR_NUM]={ +  "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4", +  "des cbc","des ede3","idea cbc","seed cbc", +  "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc", +  "aes-128 cbc","aes-192 cbc","aes-256 cbc", +  "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc", +  "evp","sha256","sha512","whirlpool", +  "aes-128 ige","aes-192 ige","aes-256 ige"}; +static double results[ALGOR_NUM][SIZE_NUM]; +static int lengths[SIZE_NUM]={16,64,256,1024,8*1024}; +#ifndef OPENSSL_NO_RSA +static double rsa_results[RSA_NUM][2]; +#endif +#ifndef OPENSSL_NO_DSA +static double dsa_results[DSA_NUM][2]; +#endif +#ifndef OPENSSL_NO_ECDSA +static double ecdsa_results[EC_NUM][2]; +#endif +#ifndef OPENSSL_NO_ECDH +static double ecdh_results[EC_NUM][1]; +#endif + +#if defined(OPENSSL_NO_DSA) && !(defined(OPENSSL_NO_ECDSA) && defined(OPENSSL_NO_ECDH)) +static const char rnd_seed[] = "string to make the random number generator think it has entropy"; +static int rnd_fake = 0; +#endif + +#ifdef SIGALRM +#if defined(__STDC__) || defined(sgi) || defined(_AIX) +#define SIGRETTYPE void +#else +#define SIGRETTYPE int +#endif  + +static SIGRETTYPE sig_done(int sig); +static SIGRETTYPE sig_done(int sig) +	{ +	signal(SIGALRM,sig_done); +	run=0; +#ifdef LINT +	sig=sig; +#endif +	} +#endif + +#define START	0 +#define STOP	1 + +#if defined(_WIN32) + +#define SIGALRM +static unsigned int lapse,schlock; +static void alarm(unsigned int secs) { lapse = secs*1000; } + +static DWORD WINAPI sleepy(VOID *arg) +	{ +	schlock = 1; +	Sleep(lapse); +	run = 0; +	return 0; +	} + +static double Time_F(int s) +	{ +	if (s == START) +		{ +		HANDLE	thr; +		schlock = 0; +		thr = CreateThread(NULL,4096,sleepy,NULL,0,NULL); +		if (thr==NULL) +			{ +			DWORD ret=GetLastError(); +			BIO_printf(bio_err,"unable to CreateThread (%d)",ret); +			ExitProcess(ret); +			} +		CloseHandle(thr);		/* detach the thread	*/ +		while (!schlock) Sleep(0);	/* scheduler spinlock	*/ +		} + +	return app_tminterval(s,usertime); +	} +#else + +static double Time_F(int s) +	{ +	return app_tminterval(s,usertime); +	} +#endif + + +#ifndef OPENSSL_NO_ECDH +static const int KDF1_SHA1_len = 20; +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) +	{ +#ifndef OPENSSL_NO_SHA +	if (*outlen < SHA_DIGEST_LENGTH) +		return NULL; +	else +		*outlen = SHA_DIGEST_LENGTH; +	return SHA1(in, inlen, out); +#else +	return NULL; +#endif	/* OPENSSL_NO_SHA */ +	} +#endif	/* OPENSSL_NO_ECDH */ + + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	unsigned char *buf=NULL,*buf2=NULL; +	int mret=1; +	long count=0,save_count=0; +	int i,j,k; +#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 +#ifndef OPENSSL_NO_MDC2 +	unsigned char mdc2[MDC2_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_MD4 +	unsigned char md4[MD4_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_MD5 +	unsigned char md5[MD5_DIGEST_LENGTH]; +	unsigned char hmac[MD5_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_SHA +	unsigned char sha[SHA_DIGEST_LENGTH]; +#ifndef OPENSSL_NO_SHA256 +	unsigned char sha256[SHA256_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_SHA512 +	unsigned char sha512[SHA512_DIGEST_LENGTH]; +#endif +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +	unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_RIPEMD +	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH]; +#endif +#ifndef OPENSSL_NO_RC4 +	RC4_KEY rc4_ks; +#endif +#ifndef OPENSSL_NO_RC5 +	RC5_32_KEY rc5_ks; +#endif +#ifndef OPENSSL_NO_RC2 +	RC2_KEY rc2_ks; +#endif +#ifndef OPENSSL_NO_IDEA +	IDEA_KEY_SCHEDULE idea_ks; +#endif +#ifndef OPENSSL_NO_SEED +	SEED_KEY_SCHEDULE seed_ks; +#endif +#ifndef OPENSSL_NO_BF +	BF_KEY bf_ks; +#endif +#ifndef OPENSSL_NO_CAST +	CAST_KEY cast_ks; +#endif +	static const unsigned char key16[16]= +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; +#ifndef OPENSSL_NO_AES +	static const unsigned char key24[24]= +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12, +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; +	static const unsigned char key32[32]= +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12, +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34, +		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56}; +#endif +#ifndef OPENSSL_NO_CAMELLIA +	static const unsigned char ckey24[24]= +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12, +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; +	static const unsigned char ckey32[32]= +		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, +		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12, +		 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34, +		 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56}; +#endif +#ifndef OPENSSL_NO_AES +#define MAX_BLOCK_SIZE 128 +#else +#define MAX_BLOCK_SIZE 64 +#endif +	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}; +	DES_key_schedule sch; +	DES_key_schedule sch2; +	DES_key_schedule sch3; +#endif +#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 +	double d=0.0; +	long c[ALGOR_NUM][SIZE_NUM]; +#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_4096	3 + +#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 +	RSA *rsa_key[RSA_NUM]; +	long rsa_c[RSA_NUM][2]; +	static unsigned int rsa_bits[RSA_NUM]={512,1024,2048,4096}; +	static unsigned char *rsa_data[RSA_NUM]= +		{test512,test1024,test2048,test4096}; +	static int rsa_data_length[RSA_NUM]={ +		sizeof(test512),sizeof(test1024), +		sizeof(test2048),sizeof(test4096)}; +#endif +#ifndef OPENSSL_NO_DSA +	DSA *dsa_key[DSA_NUM]; +	long dsa_c[DSA_NUM][2]; +	static unsigned int dsa_bits[DSA_NUM]={512,1024,2048}; +#endif +#ifndef OPENSSL_NO_EC +	/* We only test over the following curves as they are representative,  +	 * To add tests over more curves, simply add the curve NID +	 * and curve name to the following arrays and increase the  +	 * EC_NUM value accordingly.  +	 */ +	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, +	/* Binary Curves */ +	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", +	/* Binary Curves */ +	"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 +        }; + +#endif + +#ifndef OPENSSL_NO_ECDSA +	unsigned char ecdsasig[256]; +	unsigned int ecdsasiglen; +	EC_KEY *ecdsa[EC_NUM]; +	long ecdsa_c[EC_NUM][2]; +#endif + +#ifndef OPENSSL_NO_ECDH +	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]; +#endif + +	int rsa_doit[RSA_NUM]; +	int dsa_doit[DSA_NUM]; +#ifndef OPENSSL_NO_ECDSA +	int ecdsa_doit[EC_NUM]; +#endif +#ifndef OPENSSL_NO_ECDH +        int ecdh_doit[EC_NUM]; +#endif +	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 + +#ifndef TIMES +	usertime=-1; +#endif + +	apps_startup(); +	memset(results, 0, sizeof(results)); +#ifndef OPENSSL_NO_DSA +	memset(dsa_key,0,sizeof(dsa_key)); +#endif +#ifndef OPENSSL_NO_ECDSA +	for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL; +#endif +#ifndef OPENSSL_NO_ECDH +	for (i=0; i<EC_NUM; i++) +		{ +		ecdh_a[i] = NULL; +		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=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		goto end; +		} +	if ((buf2=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL) +		{ +		BIO_printf(bio_err,"out of memory\n"); +		goto end; +		} + +	memset(c,0,sizeof(c)); +	memset(DES_iv,0,sizeof(DES_iv)); +	memset(iv,0,sizeof(iv)); + +	for (i=0; i<ALGOR_NUM; i++) +		doit[i]=0; +	for (i=0; i<RSA_NUM; i++) +		rsa_doit[i]=0; +	for (i=0; i<DSA_NUM; i++) +		dsa_doit[i]=0; +#ifndef OPENSSL_NO_ECDSA +	for (i=0; i<EC_NUM; i++) +		ecdsa_doit[i]=0; +#endif +#ifndef OPENSSL_NO_ECDH +	for (i=0; i<EC_NUM; i++) +		ecdh_doit[i]=0; +#endif + +	 +	j=0; +	argc--; +	argv++; +	while (argc) +		{ +		if	((argc > 0) && (strcmp(*argv,"-elapsed") == 0)) +			{ +			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); +				goto end; +				} +			doit[D_EVP]=1; +			} +		else if (argc > 0 && !strcmp(*argv,"-decrypt")) +			{ +			decrypt=1; +			j--;	/* Otherwise, -elapsed gets confused with +				   an algorithm. */ +			} +#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--; +			} +#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. */ +			} +#endif +		else if (argc > 0 && !strcmp(*argv,"-mr")) +			{ +			mr=1; +			j--;	/* Otherwise, -mr gets confused with +				   an algorithm. */ +			} +		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 +#ifndef OPENSSL_NO_SHA +			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 +#ifndef OPENSSL_NO_SHA256 +			if (strcmp(*argv,"sha256") == 0) doit[D_SHA256]=1; +		else +#endif +#ifndef OPENSSL_NO_SHA512 +			if (strcmp(*argv,"sha512") == 0) doit[D_SHA512]=1; +		else +#endif +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +			if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1; +		else +#endif +#ifndef OPENSSL_NO_RIPEMD +			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 +#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 +#endif +#ifndef OPENSSL_NO_RSA +#if 0 /* was: #ifdef RSAref */ +			if (strcmp(*argv,"rsaref") == 0)  +			{ +			RSA_set_default_openssl_method(RSA_PKCS1_RSAref()); +			j--; +			} +		else +#endif +#ifndef RSA_NULL +			if (strcmp(*argv,"openssl") == 0)  +			{ +			RSA_set_default_method(RSA_PKCS1_SSLeay()); +			j--; +			} +		else +#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,"rsa4096") == 0) rsa_doit[R_RSA_4096]=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 +#endif +#ifndef OPENSSL_NO_DES +			if (strcmp(*argv,"des") == 0) +			{ +			doit[D_CBC_DES]=1; +			doit[D_EDE3_DES]=1; +			} +		else +#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 +#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_4096]=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 +#endif +#ifndef OPENSSL_NO_ECDSA +		     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) +			{ +			for (i=0; i < EC_NUM; i++) +				ecdsa_doit[i]=1; +			} +		else +#endif +#ifndef OPENSSL_NO_ECDH +		     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) +			{ +			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      "); +#ifndef OPENSSL_NO_HMAC +			BIO_printf(bio_err,"hmac     "); +#endif +#endif +#ifndef OPENSSL_NO_SHA1 +			BIO_printf(bio_err,"sha1     "); +#endif +#ifndef OPENSSL_NO_SHA256 +			BIO_printf(bio_err,"sha256   "); +#endif +#ifndef OPENSSL_NO_SHA512 +			BIO_printf(bio_err,"sha512   "); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +			BIO_printf(bio_err,"whirlpool"); +#endif +#ifndef OPENSSL_NO_RIPEMD160 +			BIO_printf(bio_err,"rmd160"); +#endif +#if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \ +    !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \ +    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \ +    !defined(OPENSSL_NO_WHIRLPOOL) +			BIO_printf(bio_err,"\n"); +#endif + +#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  rsa4096\n"); +#endif + +#ifndef OPENSSL_NO_DSA +			BIO_printf(bio_err,"dsa512   dsa1024  dsa2048\n"); +#endif +#ifndef OPENSSL_NO_ECDSA +			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"); +#endif +#ifndef OPENSSL_NO_ECDH +			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"); +#ifndef NO_FORK +			BIO_printf(bio_err,"-multi n        run n benchmarks in parallel.\n"); +#endif +			goto end; +			} +		argc--; +		argv++; +		j++; +		} + +#ifndef NO_FORK +	if(multi && do_multi(multi)) +		goto show_res; +#endif + +	if (j == 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++) +			dsa_doit[i]=1; +#ifndef OPENSSL_NO_ECDSA +		for (i=0; i<EC_NUM; i++) +			ecdsa_doit[i]=1; +#endif +#ifndef OPENSSL_NO_ECDH +		for (i=0; i<EC_NUM; i++) +			ecdh_doit[i]=1; +#endif +		} +	for (i=0; i<ALGOR_NUM; i++) +		if (doit[i]) pr_header++; + +	if (usertime == 0 && !mr) +		BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n"); + +#ifndef OPENSSL_NO_RSA +	for (i=0; i<RSA_NUM; i++) +		{ +		const unsigned char *p; + +		p=rsa_data[i]; +		rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]); +		if (rsa_key[i] == NULL) +			{ +			BIO_printf(bio_err,"internal error loading RSA key number %d\n",i); +			goto end; +			} +#if 0 +		else +			{ +			BIO_printf(bio_err,mr ? "+RK:%d:" +				   : "Loaded RSA key, %d bit modulus and e= 0x", +				   BN_num_bits(rsa_key[i]->n)); +			BN_print(bio_err,rsa_key[i]->e); +			BIO_printf(bio_err,"\n"); +			} +#endif +		} +#endif + +#ifndef OPENSSL_NO_DSA +	dsa_key[0]=get_dsa512(); +	dsa_key[1]=get_dsa1024(); +	dsa_key[2]=get_dsa2048(); +#endif + +#ifndef OPENSSL_NO_DES +	DES_set_key_unchecked(&key,&sch); +	DES_set_key_unchecked(&key2,&sch2); +	DES_set_key_unchecked(&key3,&sch3); +#endif +#ifndef OPENSSL_NO_AES +	AES_set_encrypt_key(key16,128,&aes_ks1); +	AES_set_encrypt_key(key24,192,&aes_ks2); +	AES_set_encrypt_key(key32,256,&aes_ks3); +#endif +#ifndef OPENSSL_NO_CAMELLIA +	Camellia_set_key(key16,128,&camellia_ks1); +	Camellia_set_key(ckey24,192,&camellia_ks2); +	Camellia_set_key(ckey32,256,&camellia_ks3); +#endif +#ifndef OPENSSL_NO_IDEA +	idea_set_encrypt_key(key16,&idea_ks); +#endif +#ifndef OPENSSL_NO_SEED +	SEED_set_key(key16,&seed_ks); +#endif +#ifndef OPENSSL_NO_RC4 +	RC4_set_key(&rc4_ks,16,key16); +#endif +#ifndef OPENSSL_NO_RC2 +	RC2_set_key(&rc2_ks,16,key16,128); +#endif +#ifndef OPENSSL_NO_RC5 +	RC5_32_set_key(&rc5_ks,16,key16,12); +#endif +#ifndef OPENSSL_NO_BF +	BF_set_key(&bf_ks,16,key16); +#endif +#ifndef OPENSSL_NO_CAST +	CAST_set_key(&cast_ks,16,key16); +#endif +#ifndef OPENSSL_NO_RSA +	memset(rsa_c,0,sizeof(rsa_c)); +#endif +#ifndef SIGALRM +#ifndef OPENSSL_NO_DES +	BIO_printf(bio_err,"First we calculate the approximate speed ...\n"); +	count=10; +	do	{ +		long it; +		count*=2; +		Time_F(START); +		for (it=count; it; it--) +			DES_ecb_encrypt((DES_cblock *)buf, +				(DES_cblock *)buf, +				&sch,DES_ENCRYPT); +		d=Time_F(STOP); +		} while (d <3); +	save_count=count; +	c[D_MD2][0]=count/10; +	c[D_MDC2][0]=count/10; +	c[D_MD4][0]=count; +	c[D_MD5][0]=count; +	c[D_HMAC][0]=count; +	c[D_SHA1][0]=count; +	c[D_RMD160][0]=count; +	c[D_RC4][0]=count*5; +	c[D_CBC_DES][0]=count; +	c[D_EDE3_DES][0]=count/3; +	c[D_CBC_IDEA][0]=count; +	c[D_CBC_SEED][0]=count; +	c[D_CBC_RC2][0]=count; +	c[D_CBC_RC5][0]=count; +	c[D_CBC_BF][0]=count; +	c[D_CBC_CAST][0]=count; +	c[D_CBC_128_AES][0]=count; +	c[D_CBC_192_AES][0]=count; +	c[D_CBC_256_AES][0]=count; +	c[D_CBC_128_CML][0]=count; +	c[D_CBC_192_CML][0]=count; +	c[D_CBC_256_CML][0]=count; +	c[D_SHA256][0]=count; +	c[D_SHA512][0]=count; +	c[D_WHIRLPOOL][0]=count; +	c[D_IGE_128_AES][0]=count; +	c[D_IGE_192_AES][0]=count; +	c[D_IGE_256_AES][0]=count; + +	for (i=1; i<SIZE_NUM; i++) +		{ +		c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i]; +		c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i]; +		c[D_MD4][i]=c[D_MD4][0]*4*lengths[0]/lengths[i]; +		c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i]; +		c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i]; +		c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i]; +		c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i]; +		c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i]; +		c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i]; +		c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i]; +		} +	for (i=1; i<SIZE_NUM; i++) +		{ +		long l0,l1; + +		l0=(long)lengths[i-1]; +		l1=(long)lengths[i]; +		c[D_RC4][i]=c[D_RC4][i-1]*l0/l1; +		c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1; +		c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1; +		c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1; +		c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1; +		c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1; +		c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1; +		c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1; +		c[D_CBC_CAST][i]=c[D_CBC_CAST][i-1]*l0/l1; +		c[D_CBC_128_AES][i]=c[D_CBC_128_AES][i-1]*l0/l1; +		c[D_CBC_192_AES][i]=c[D_CBC_192_AES][i-1]*l0/l1; +		c[D_CBC_256_AES][i]=c[D_CBC_256_AES][i-1]*l0/l1; + 		c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1; +		c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1; +		c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1; +		c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1; +		c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1; +		c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1; +		} +#ifndef OPENSSL_NO_RSA +	rsa_c[R_RSA_512][0]=count/2000; +	rsa_c[R_RSA_512][1]=count/400; +	for (i=1; i<RSA_NUM; i++) +		{ +		rsa_c[i][0]=rsa_c[i-1][0]/8; +		rsa_c[i][1]=rsa_c[i-1][1]/4; +		if ((rsa_doit[i] <= 1) && (rsa_c[i][0] == 0)) +			rsa_doit[i]=0; +		else +			{ +			if (rsa_c[i][0] == 0) +				{ +				rsa_c[i][0]=1; +				rsa_c[i][1]=20; +				} +			}				 +		} +#endif + +#ifndef OPENSSL_NO_DSA +	dsa_c[R_DSA_512][0]=count/1000; +	dsa_c[R_DSA_512][1]=count/1000/2; +	for (i=1; i<DSA_NUM; i++) +		{ +		dsa_c[i][0]=dsa_c[i-1][0]/4; +		dsa_c[i][1]=dsa_c[i-1][1]/4; +		if ((dsa_doit[i] <= 1) && (dsa_c[i][0] == 0)) +			dsa_doit[i]=0; +		else +			{ +			if (dsa_c[i] == 0) +				{ +				dsa_c[i][0]=1; +				dsa_c[i][1]=1; +				} +			}				 +		} +#endif + +#ifndef OPENSSL_NO_ECDSA +	ecdsa_c[R_EC_P160][0]=count/1000; +	ecdsa_c[R_EC_P160][1]=count/1000/2; +	for (i=R_EC_P192; i<=R_EC_P521; i++) +		{ +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2; +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2; +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0)) +			ecdsa_doit[i]=0; +		else +			{ +			if (ecdsa_c[i] == 0) +				{ +				ecdsa_c[i][0]=1; +				ecdsa_c[i][1]=1; +				} +			} +		} +	ecdsa_c[R_EC_K163][0]=count/1000; +	ecdsa_c[R_EC_K163][1]=count/1000/2; +	for (i=R_EC_K233; i<=R_EC_K571; i++) +		{ +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2; +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2; +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0)) +			ecdsa_doit[i]=0; +		else +			{ +			if (ecdsa_c[i] == 0) +				{ +				ecdsa_c[i][0]=1; +				ecdsa_c[i][1]=1; +				} +			} +		} +	ecdsa_c[R_EC_B163][0]=count/1000; +	ecdsa_c[R_EC_B163][1]=count/1000/2; +	for (i=R_EC_B233; i<=R_EC_B571; i++) +		{ +		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2; +		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2; +		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0)) +			ecdsa_doit[i]=0; +		else +			{ +			if (ecdsa_c[i] == 0) +				{ +				ecdsa_c[i][0]=1; +				ecdsa_c[i][1]=1; +				} +			} +		} +#endif + +#ifndef OPENSSL_NO_ECDH +	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++) +		{ +		ecdh_c[i][0]=ecdh_c[i-1][0]/2; +		ecdh_c[i][1]=ecdh_c[i-1][1]/2; +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0)) +			ecdh_doit[i]=0; +		else +			{ +			if (ecdh_c[i] == 0) +				{ +				ecdh_c[i][0]=1; +				ecdh_c[i][1]=1; +				} +			} +		} +	ecdh_c[R_EC_K163][0]=count/1000; +	ecdh_c[R_EC_K163][1]=count/1000; +	for (i=R_EC_K233; i<=R_EC_K571; i++) +		{ +		ecdh_c[i][0]=ecdh_c[i-1][0]/2; +		ecdh_c[i][1]=ecdh_c[i-1][1]/2; +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0)) +			ecdh_doit[i]=0; +		else +			{ +			if (ecdh_c[i] == 0) +				{ +				ecdh_c[i][0]=1; +				ecdh_c[i][1]=1; +				} +			} +		} +	ecdh_c[R_EC_B163][0]=count/1000; +	ecdh_c[R_EC_B163][1]=count/1000; +	for (i=R_EC_B233; i<=R_EC_B571; i++) +		{ +		ecdh_c[i][0]=ecdh_c[i-1][0]/2; +		ecdh_c[i][1]=ecdh_c[i-1][1]/2; +		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0)) +			ecdh_doit[i]=0; +		else +			{ +			if (ecdh_c[i] == 0) +				{ +				ecdh_c[i][0]=1; +				ecdh_c[i][1]=1; +				} +			} +		} +#endif + +#define COND(d)	(count < (d)) +#define COUNT(d) (d) +#else +/* not worth fixing */ +# error "You cannot disable DES on systems without SIGALRM." +#endif /* OPENSSL_NO_DES */ +#else +#define COND(c)	(run) +#define COUNT(d) (count) +#ifndef _WIN32 +	signal(SIGALRM,sig_done); +#endif +#endif /* SIGALRM */ + +#ifndef OPENSSL_NO_MD2 +	if (doit[D_MD2]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_MD2],c[D_MD2][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_MD2][j]); count++) +				EVP_Digest(buf,(unsigned long)lengths[j],&(md2[0]),NULL,EVP_md2(),NULL); +			d=Time_F(STOP); +			print_result(D_MD2,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_MDC2 +	if (doit[D_MDC2]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_MDC2][j]); count++) +				EVP_Digest(buf,(unsigned long)lengths[j],&(mdc2[0]),NULL,EVP_mdc2(),NULL); +			d=Time_F(STOP); +			print_result(D_MDC2,j,count,d); +			} +		} +#endif + +#ifndef OPENSSL_NO_MD4 +	if (doit[D_MD4]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_MD4],c[D_MD4][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_MD4][j]); count++) +				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md4[0]),NULL,EVP_md4(),NULL); +			d=Time_F(STOP); +			print_result(D_MD4,j,count,d); +			} +		} +#endif + +#ifndef OPENSSL_NO_MD5 +	if (doit[D_MD5]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_MD5],c[D_MD5][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_MD5][j]); count++) +				EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL); +			d=Time_F(STOP); +			print_result(D_MD5,j,count,d); +			} +		} +#endif + +#if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_HMAC) +	if (doit[D_HMAC]) +		{ +		HMAC_CTX hctx; + +		HMAC_CTX_init(&hctx); +		HMAC_Init_ex(&hctx,(unsigned char *)"This is a key...", +			16,EVP_md5(), NULL); + +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_HMAC][j]); count++) +				{ +				HMAC_Init_ex(&hctx,NULL,0,NULL,NULL); +				HMAC_Update(&hctx,buf,lengths[j]); +				HMAC_Final(&hctx,&(hmac[0]),NULL); +				} +			d=Time_F(STOP); +			print_result(D_HMAC,j,count,d); +			} +		HMAC_CTX_cleanup(&hctx); +		} +#endif +#ifndef OPENSSL_NO_SHA +	if (doit[D_SHA1]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_SHA1][j]); count++) +				EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL); +			d=Time_F(STOP); +			print_result(D_SHA1,j,count,d); +			} +		} + +#ifndef OPENSSL_NO_SHA256 +	if (doit[D_SHA256]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_SHA256],c[D_SHA256][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_SHA256][j]); count++) +				SHA256(buf,lengths[j],sha256); +			d=Time_F(STOP); +			print_result(D_SHA256,j,count,d); +			} +		} +#endif + +#ifndef OPENSSL_NO_SHA512 +	if (doit[D_SHA512]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_SHA512],c[D_SHA512][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_SHA512][j]); count++) +				SHA512(buf,lengths[j],sha512); +			d=Time_F(STOP); +			print_result(D_SHA512,j,count,d); +			} +		} +#endif +#endif + +#ifndef OPENSSL_NO_WHIRLPOOL +	if (doit[D_WHIRLPOOL]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++) +				WHIRLPOOL(buf,lengths[j],whirlpool); +			d=Time_F(STOP); +			print_result(D_WHIRLPOOL,j,count,d); +			} +		} +#endif + +#ifndef OPENSSL_NO_RIPEMD +	if (doit[D_RMD160]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_RMD160][j]); count++) +				EVP_Digest(buf,(unsigned long)lengths[j],&(rmd160[0]),NULL,EVP_ripemd160(),NULL); +			d=Time_F(STOP); +			print_result(D_RMD160,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_RC4 +	if (doit[D_RC4]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_RC4],c[D_RC4][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_RC4][j]); count++) +				RC4(&rc4_ks,(unsigned int)lengths[j], +					buf,buf); +			d=Time_F(STOP); +			print_result(D_RC4,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_DES +	if (doit[D_CBC_DES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_DES],c[D_CBC_DES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_DES][j]); count++) +				DES_ncbc_encrypt(buf,buf,lengths[j],&sch, +						 &DES_iv,DES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_DES,j,count,d); +			} +		} + +	if (doit[D_EDE3_DES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_EDE3_DES],c[D_EDE3_DES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_EDE3_DES][j]); count++) +				DES_ede3_cbc_encrypt(buf,buf,lengths[j], +						     &sch,&sch2,&sch3, +						     &DES_iv,DES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_EDE3_DES,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_AES +	if (doit[D_CBC_128_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_128_AES],c[D_CBC_128_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_128_AES][j]); count++) +				AES_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&aes_ks1, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_128_AES,j,count,d); +			} +		} +	if (doit[D_CBC_192_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_192_AES],c[D_CBC_192_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_192_AES][j]); count++) +				AES_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&aes_ks2, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_192_AES,j,count,d); +			} +		} +	if (doit[D_CBC_256_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_256_AES],c[D_CBC_256_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_256_AES][j]); count++) +				AES_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&aes_ks3, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_256_AES,j,count,d); +			} +		} + +#if 0 /* ANDROID */ +	if (doit[D_IGE_128_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++) +				AES_ige_encrypt(buf,buf2, +					(unsigned long)lengths[j],&aes_ks1, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_IGE_128_AES,j,count,d); +			} +		} +	if (doit[D_IGE_192_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++) +				AES_ige_encrypt(buf,buf2, +					(unsigned long)lengths[j],&aes_ks2, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_IGE_192_AES,j,count,d); +			} +		} +	if (doit[D_IGE_256_AES]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++) +				AES_ige_encrypt(buf,buf2, +					(unsigned long)lengths[j],&aes_ks3, +					iv,AES_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_IGE_256_AES,j,count,d); +			} +		} + + +#endif +#endif +#ifndef OPENSSL_NO_CAMELLIA +	if (doit[D_CBC_128_CML]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_128_CML],c[D_CBC_128_CML][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_128_CML][j]); count++) +				Camellia_cbc_encrypt(buf,buf, +				        (unsigned long)lengths[j],&camellia_ks1, +				        iv,CAMELLIA_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_128_CML,j,count,d); +			} +		} +	if (doit[D_CBC_192_CML]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_192_CML],c[D_CBC_192_CML][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_192_CML][j]); count++) +				Camellia_cbc_encrypt(buf,buf, +				        (unsigned long)lengths[j],&camellia_ks2, +				        iv,CAMELLIA_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_192_CML,j,count,d); +			} +		} +	if (doit[D_CBC_256_CML]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_256_CML],c[D_CBC_256_CML][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_256_CML][j]); count++) +				Camellia_cbc_encrypt(buf,buf, +				        (unsigned long)lengths[j],&camellia_ks3, +				        iv,CAMELLIA_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_256_CML,j,count,d); +			} +		} + +#endif +#ifndef OPENSSL_NO_IDEA +	if (doit[D_CBC_IDEA]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_IDEA],c[D_CBC_IDEA][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_IDEA][j]); count++) +				idea_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&idea_ks, +					iv,IDEA_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_IDEA,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_SEED +	if (doit[D_CBC_SEED]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++) +				SEED_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&seed_ks,iv,1); +			d=Time_F(STOP); +			print_result(D_CBC_SEED,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_RC2 +	if (doit[D_CBC_RC2]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_RC2],c[D_CBC_RC2][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_RC2][j]); count++) +				RC2_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&rc2_ks, +					iv,RC2_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_RC2,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_RC5 +	if (doit[D_CBC_RC5]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_RC5],c[D_CBC_RC5][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_RC5][j]); count++) +				RC5_32_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&rc5_ks, +					iv,RC5_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_RC5,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_BF +	if (doit[D_CBC_BF]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_BF],c[D_CBC_BF][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_BF][j]); count++) +				BF_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&bf_ks, +					iv,BF_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_BF,j,count,d); +			} +		} +#endif +#ifndef OPENSSL_NO_CAST +	if (doit[D_CBC_CAST]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			print_message(names[D_CBC_CAST],c[D_CBC_CAST][j],lengths[j]); +			Time_F(START); +			for (count=0,run=1; COND(c[D_CBC_CAST][j]); count++) +				CAST_cbc_encrypt(buf,buf, +					(unsigned long)lengths[j],&cast_ks, +					iv,CAST_ENCRYPT); +			d=Time_F(STOP); +			print_result(D_CBC_CAST,j,count,d); +			} +		} +#endif + +	if (doit[D_EVP]) +		{ +		for (j=0; j<SIZE_NUM; j++) +			{ +			if (evp_cipher) +				{ +				EVP_CIPHER_CTX ctx; +				int outl; + +				names[D_EVP]=OBJ_nid2ln(evp_cipher->nid); +				/* -O3 -fschedule-insns messes up an +				 * optimization here!  names[D_EVP] +				 * somehow becomes NULL */ +				print_message(names[D_EVP],save_count, +					lengths[j]); + +				EVP_CIPHER_CTX_init(&ctx); +				if(decrypt) +					EVP_DecryptInit_ex(&ctx,evp_cipher,NULL,key16,iv); +				else +					EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv); +				EVP_CIPHER_CTX_set_padding(&ctx, 0); + +				Time_F(START); +				if(decrypt) +					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++) +						EVP_DecryptUpdate(&ctx,buf,&outl,buf,lengths[j]); +				else +					for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++) +						EVP_EncryptUpdate(&ctx,buf,&outl,buf,lengths[j]); +				if(decrypt) +					EVP_DecryptFinal_ex(&ctx,buf,&outl); +				else +					EVP_EncryptFinal_ex(&ctx,buf,&outl); +				d=Time_F(STOP); +				EVP_CIPHER_CTX_cleanup(&ctx); +				} +			if (evp_md) +				{ +				names[D_EVP]=OBJ_nid2ln(evp_md->type); +				print_message(names[D_EVP],save_count, +					lengths[j]); + +				Time_F(START); +				for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++) +					EVP_Digest(buf,lengths[j],&(md[0]),NULL,evp_md,NULL); + +				d=Time_F(STOP); +				} +			print_result(D_EVP,j,count,d); +			} +		} + +	RAND_pseudo_bytes(buf,36); +#ifndef OPENSSL_NO_RSA +	for (j=0; j<RSA_NUM; j++) +		{ +		int ret; +		if (!rsa_doit[j]) continue; +		ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num, rsa_key[j]); +		if (ret == 0) +			{ +			BIO_printf(bio_err,"RSA sign failure.  No RSA sign will be done.\n"); +			ERR_print_errors(bio_err); +			rsa_count=1; +			} +		else +			{ +			pkey_print_message("private","rsa", +				rsa_c[j][0],rsa_bits[j], +				RSA_SECONDS); +/*			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) +					{ +					BIO_printf(bio_err, +						"RSA sign failure\n"); +					ERR_print_errors(bio_err); +					count=1; +					break; +					} +				} +			d=Time_F(STOP); +			BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n" +				   : "%ld %d bit private RSA's in %.2fs\n", +				   count,rsa_bits[j],d); +			rsa_results[j][0]=d/(double)count; +			rsa_count=count; +			} + +#if 1 +		ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num, rsa_key[j]); +		if (ret <= 0) +			{ +			BIO_printf(bio_err,"RSA verify failure.  No RSA verify will be done.\n"); +			ERR_print_errors(bio_err); +			rsa_doit[j] = 0; +			} +		else +			{ +			pkey_print_message("public","rsa", +				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) +					{ +					BIO_printf(bio_err, +						"RSA verify failure\n"); +					ERR_print_errors(bio_err); +					count=1; +					break; +					} +				} +			d=Time_F(STOP); +			BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n" +				   : "%ld %d bit public RSA's in %.2fs\n", +				   count,rsa_bits[j],d); +			rsa_results[j][1]=d/(double)count; +			} +#endif + +		if (rsa_count <= 1) +			{ +			/* if longer than 10s, don't do any more */ +			for (j++; j<RSA_NUM; j++) +				rsa_doit[j]=0; +			} +		} +#endif + +	RAND_pseudo_bytes(buf,20); +#ifndef OPENSSL_NO_DSA +	if (RAND_status() != 1) +		{ +		RAND_seed(rnd_seed, sizeof rnd_seed); +		rnd_fake = 1; +		} +	for (j=0; j<DSA_NUM; j++) +		{ +		unsigned int kk; +		int ret; + +		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) +			{ +			BIO_printf(bio_err,"DSA sign failure.  No DSA sign will be done.\n"); +			ERR_print_errors(bio_err); +			rsa_count=1; +			} +		else +			{ +			pkey_print_message("sign","dsa", +				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) +					{ +					BIO_printf(bio_err, +						"DSA sign failure\n"); +					ERR_print_errors(bio_err); +					count=1; +					break; +					} +				} +			d=Time_F(STOP); +			BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n" +				   : "%ld %d bit DSA signs in %.2fs\n", +				   count,dsa_bits[j],d); +			dsa_results[j][0]=d/(double)count; +			rsa_count=count; +			} + +		ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2, +			kk,dsa_key[j]); +		if (ret <= 0) +			{ +			BIO_printf(bio_err,"DSA verify failure.  No DSA verify will be done.\n"); +			ERR_print_errors(bio_err); +			dsa_doit[j] = 0; +			} +		else +			{ +			pkey_print_message("verify","dsa", +				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) +					{ +					BIO_printf(bio_err, +						"DSA verify failure\n"); +					ERR_print_errors(bio_err); +					count=1; +					break; +					} +				} +			d=Time_F(STOP); +			BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n" +				   : "%ld %d bit DSA verify in %.2fs\n", +				   count,dsa_bits[j],d); +			dsa_results[j][1]=d/(double)count; +			} + +		if (rsa_count <= 1) +			{ +			/* if longer than 10s, don't do any more */ +			for (j++; j<DSA_NUM; j++) +				dsa_doit[j]=0; +			} +		} +	if (rnd_fake) RAND_cleanup(); +#endif + +#ifndef OPENSSL_NO_ECDSA +	if (RAND_status() != 1)  +		{ +		RAND_seed(rnd_seed, sizeof rnd_seed); +		rnd_fake = 1; +		} +	for (j=0; j<EC_NUM; j++)  +		{ +		int ret; + +		if (!ecdsa_doit[j]) continue; /* Ignore Curve */  +		ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]); +		if (ecdsa[j] == NULL)  +			{ +			BIO_printf(bio_err,"ECDSA failure.\n"); +			ERR_print_errors(bio_err); +			rsa_count=1; +			}  +		else  +			{ +#if 1 +			EC_KEY_precompute_mult(ecdsa[j], NULL); +#endif +			/* Perform ECDSA signature test */ +			EC_KEY_generate_key(ecdsa[j]); +			ret = ECDSA_sign(0, buf, 20, ecdsasig,  +				&ecdsasiglen, ecdsa[j]); +			if (ret == 0)  +				{ +				BIO_printf(bio_err,"ECDSA sign failure.  No ECDSA sign will be done.\n"); +				ERR_print_errors(bio_err); +				rsa_count=1; +				}  +			else  +				{ +				pkey_print_message("sign","ecdsa", +					ecdsa_c[j][0],  +					test_curves_bits[j], +					ECDSA_SECONDS); + +				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)  +						{ +						BIO_printf(bio_err, "ECDSA sign failure\n"); +						ERR_print_errors(bio_err); +						count=1; +						break; +						} +					} +				d=Time_F(STOP); + +				BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" : +					"%ld %d bit ECDSA signs in %.2fs \n",  +					count, test_curves_bits[j], d); +				ecdsa_results[j][0]=d/(double)count; +				rsa_count=count; +				} + +			/* Perform ECDSA verification test */ +			ret=ECDSA_verify(0, buf, 20, ecdsasig,  +				ecdsasiglen, ecdsa[j]); +			if (ret != 1)  +				{ +				BIO_printf(bio_err,"ECDSA verify failure.  No ECDSA verify will be done.\n"); +				ERR_print_errors(bio_err); +				ecdsa_doit[j] = 0; +				}  +			else  +				{ +				pkey_print_message("verify","ecdsa", +				ecdsa_c[j][1], +				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)  +						{ +						BIO_printf(bio_err, "ECDSA verify failure\n"); +						ERR_print_errors(bio_err); +						count=1; +						break; +						} +					} +				d=Time_F(STOP); +				BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n" +						: "%ld %d bit ECDSA verify in %.2fs\n", +				count, test_curves_bits[j], d); +				ecdsa_results[j][1]=d/(double)count; +				} + +			if (rsa_count <= 1)  +				{ +				/* if longer than 10s, don't do any more */ +				for (j++; j<EC_NUM; j++) +				ecdsa_doit[j]=0; +				} +			} +		} +	if (rnd_fake) RAND_cleanup(); +#endif + +#ifndef OPENSSL_NO_ECDH +	if (RAND_status() != 1) +		{ +		RAND_seed(rnd_seed, sizeof rnd_seed); +		rnd_fake = 1; +		} +	for (j=0; j<EC_NUM; j++) +		{ +		if (!ecdh_doit[j]) continue; +		ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]); +		ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]); +		if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL)) +			{ +			BIO_printf(bio_err,"ECDH failure.\n"); +			ERR_print_errors(bio_err); +			rsa_count=1; +			} +		else +			{ +			/* generate two ECDH key pairs */ +			if (!EC_KEY_generate_key(ecdh_a[j]) || +				!EC_KEY_generate_key(ecdh_b[j])) +				{ +				BIO_printf(bio_err,"ECDH key generation failure.\n"); +				ERR_print_errors(bio_err); +				rsa_count=1;		 +				} +			else +				{ +				/* If field size is not more than 24 octets, then use SHA-1 hash of result; +				 * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt). +				 */ +				int field_size, outlen; +				void *(*kdf)(const void *in, size_t inlen, void *out, size_t *xoutlen); +				field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j])); +				if (field_size <= 24 * 8) +					{ +					outlen = KDF1_SHA1_len; +					kdf = KDF1_SHA1; +					} +				else +					{ +					outlen = (field_size+7)/8; +					kdf = NULL; +					} +				secret_size_a = ECDH_compute_key(secret_a, outlen, +					EC_KEY_get0_public_key(ecdh_b[j]), +					ecdh_a[j], kdf); +				secret_size_b = ECDH_compute_key(secret_b, outlen, +					EC_KEY_get0_public_key(ecdh_a[j]), +					ecdh_b[j], kdf); +				if (secret_size_a != secret_size_b)  +					ecdh_checks = 0; +				else +					ecdh_checks = 1; + +				for (secret_idx = 0;  +				    (secret_idx < secret_size_a) +					&& (ecdh_checks == 1); +				    secret_idx++) +					{ +					if (secret_a[secret_idx] != secret_b[secret_idx]) +					ecdh_checks = 0; +					} + +				if (ecdh_checks == 0) +					{ +					BIO_printf(bio_err,"ECDH computations don't match.\n"); +					ERR_print_errors(bio_err); +					rsa_count=1;		 +					} + +				pkey_print_message("","ecdh", +				ecdh_c[j][0],  +				test_curves_bits[j], +				ECDH_SECONDS); +				Time_F(START); +				for (count=0,run=1; COND(ecdh_c[j][0]); count++) +					{ +					ECDH_compute_key(secret_a, outlen, +					EC_KEY_get0_public_key(ecdh_b[j]), +					ecdh_a[j], kdf); +					} +				d=Time_F(STOP); +				BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n", +				count, test_curves_bits[j], d); +				ecdh_results[j][0]=d/(double)count; +				rsa_count=count; +				} +			} + + +		if (rsa_count <= 1) +			{ +			/* if longer than 10s, don't do any more */ +			for (j++; j<EC_NUM; j++) +			ecdh_doit[j]=0; +			} +		} +	if (rnd_fake) RAND_cleanup(); +#endif +#ifndef NO_FORK +show_res: +#endif +	if(!mr) +		{ +		fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_VERSION)); +        fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_BUILT_ON)); +		printf("options:"); +		printf("%s ",BN_options()); +#ifndef OPENSSL_NO_MD2 +		printf("%s ",MD2_options()); +#endif +#ifndef OPENSSL_NO_RC4 +		printf("%s ",RC4_options()); +#endif +#ifndef OPENSSL_NO_DES +		printf("%s ",DES_options()); +#endif +#ifndef OPENSSL_NO_AES +		printf("%s ",AES_options()); +#endif +#ifndef OPENSSL_NO_IDEA +		printf("%s ",idea_options()); +#endif +#ifndef OPENSSL_NO_BF +		printf("%s ",BF_options()); +#endif +		fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS)); +		} + +	if (pr_header) +		{ +		if(mr) +			fprintf(stdout,"+H"); +		else +			{ +			fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n");  +			fprintf(stdout,"type        "); +			} +		for (j=0;  j<SIZE_NUM; j++) +			fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]); +		fprintf(stdout,"\n"); +		} + +	for (k=0; k<ALGOR_NUM; k++) +		{ +		if (!doit[k]) continue; +		if(mr) +			fprintf(stdout,"+F:%d:%s",k,names[k]); +		else +			fprintf(stdout,"%-13s",names[k]); +		for (j=0; j<SIZE_NUM; j++) +			{ +			if (results[k][j] > 10000 && !mr) +				fprintf(stdout," %11.2fk",results[k][j]/1e3); +			else +				fprintf(stdout,mr ? ":%.2f" : " %11.2f ",results[k][j]); +			} +		fprintf(stdout,"\n"); +		} +#ifndef OPENSSL_NO_RSA +	j=1; +	for (k=0; k<RSA_NUM; k++) +		{ +		if (!rsa_doit[k]) continue; +		if (j && !mr) +			{ +			printf("%18ssign    verify    sign/s verify/s\n"," "); +			j=0; +			} +		if(mr) +			fprintf(stdout,"+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]); +		} +#endif +#ifndef OPENSSL_NO_DSA +	j=1; +	for (k=0; k<DSA_NUM; k++) +		{ +		if (!dsa_doit[k]) continue; +		if (j && !mr) +			{ +			printf("%18ssign    verify    sign/s verify/s\n"," "); +			j=0; +			} +		if(mr) +			fprintf(stdout,"+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]); +		} +#endif +#ifndef OPENSSL_NO_ECDSA +	j=1; +	for (k=0; k<EC_NUM; k++) +		{ +		if (!ecdsa_doit[k]) continue; +		if (j && !mr) +			{ +			printf("%30ssign    verify    sign/s verify/s\n"," "); +			j=0; +			} + +		if (mr) +			fprintf(stdout,"+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]); +		} +#endif + + +#ifndef OPENSSL_NO_ECDH +	j=1; +	for (k=0; k<EC_NUM; k++) +		{ +		if (!ecdh_doit[k]) continue; +		if (j && !mr) +			{ +			printf("%30sop      op/s\n"," "); +			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]); + +		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]); +		} +#endif + +	mret=0; + +end: +	ERR_print_errors(bio_err); +	if (buf != NULL) OPENSSL_free(buf); +	if (buf2 != NULL) OPENSSL_free(buf2); +#ifndef OPENSSL_NO_RSA +	for (i=0; i<RSA_NUM; i++) +		if (rsa_key[i] != NULL) +			RSA_free(rsa_key[i]); +#endif +#ifndef OPENSSL_NO_DSA +	for (i=0; i<DSA_NUM; i++) +		if (dsa_key[i] != NULL) +			DSA_free(dsa_key[i]); +#endif + +#ifndef OPENSSL_NO_ECDSA +	for (i=0; i<EC_NUM; i++) +		if (ecdsa[i] != NULL) +			EC_KEY_free(ecdsa[i]); +#endif +#ifndef OPENSSL_NO_ECDH +	for (i=0; i<EC_NUM; i++) +	{ +		if (ecdh_a[i] != NULL) +			EC_KEY_free(ecdh_a[i]); +		if (ecdh_b[i] != NULL) +			EC_KEY_free(ecdh_b[i]); +	} +#endif + +	apps_shutdown(); +	OPENSSL_EXIT(mret); +	} + +static void print_message(const char *s, long num, int length) +	{ +#ifdef SIGALRM +	BIO_printf(bio_err,mr ? "+DT:%s:%d:%d\n" +		   : "Doing %s for %ds on %d size blocks: ",s,SECONDS,length); +	(void)BIO_flush(bio_err); +	alarm(SECONDS); +#else +	BIO_printf(bio_err,mr ? "+DN:%s:%ld:%d\n" +		   : "Doing %s %ld times on %d size blocks: ",s,num,length); +	(void)BIO_flush(bio_err); +#endif +#ifdef LINT +	num=num; +#endif +	} + +static void pkey_print_message(const char *str, const char *str2, long num, +	int bits, int tm) +	{ +#ifdef SIGALRM +	BIO_printf(bio_err,mr ? "+DTP:%d:%s:%s:%d\n" +			   : "Doing %d bit %s %s's for %ds: ",bits,str,str2,tm); +	(void)BIO_flush(bio_err); +	alarm(RSA_SECONDS); +#else +	BIO_printf(bio_err,mr ? "+DNP:%ld:%d:%s:%s\n" +			   : "Doing %ld %d bit %s %s's: ",num,bits,str,str2); +	(void)BIO_flush(bio_err); +#endif +#ifdef LINT +	num=num; +#endif +	} + +static void print_result(int alg,int run_no,int count,double time_used) +	{ +	BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n" +		   : "%d %s's in %.2fs\n",count,names[alg],time_used); +	results[alg][run_no]=((double)count)/time_used*lengths[run_no]; +	} + +#ifndef NO_FORK +static char *sstrsep(char **string, const char *delim) +    { +    char isdelim[256]; +    char *token = *string; + +    if (**string == 0) +        return NULL; + +    memset(isdelim, 0, sizeof isdelim); +    isdelim[0] = 1; + +    while (*delim) +        { +        isdelim[(unsigned char)(*delim)] = 1; +        delim++; +        } + +    while (!isdelim[(unsigned char)(**string)]) +        { +        (*string)++; +        } + +    if (**string) +        { +        **string = 0; +        (*string)++; +        } + +    return token; +    } + +static int do_multi(int multi) +	{ +	int n; +	int fd[2]; +	int *fds; +	static char sep[]=":"; + +	fds=malloc(multi*sizeof *fds); +	for(n=0 ; n < multi ; ++n) +		{ +		pipe(fd); +		fflush(stdout); +		fflush(stderr); +		if(fork()) +			{ +			close(fd[1]); +			fds[n]=fd[0]; +			} +		else +			{ +			close(fd[0]); +			close(1); +			dup(fd[1]); +			close(fd[1]); +			mr=1; +			usertime=0; +			free(fds); +			return 0; +			} +		printf("Forked child %d\n",n); +		} + +	/* for now, assume the pipe is long enough to take all the output */ +	for(n=0 ; n < multi ; ++n) +		{ +		FILE *f; +		char buf[1024]; +		char *p; + +		f=fdopen(fds[n],"r"); +		while(fgets(buf,sizeof buf,f)) +			{ +			p=strchr(buf,'\n'); +			if(p) +				*p='\0'; +			if(buf[0] != '+') +				{ +				fprintf(stderr,"Don't understand line '%s' from child %d\n", +						buf,n); +				continue; +				} +			printf("Got: %s from %d\n",buf,n); +			if(!strncmp(buf,"+F:",3)) +				{ +				int alg; +				int j; + +				p=buf+3; +				alg=atoi(sstrsep(&p,sep)); +				sstrsep(&p,sep); +				for(j=0 ; j < SIZE_NUM ; ++j) +					results[alg][j]+=atof(sstrsep(&p,sep)); +				} +			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); +				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); +				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; +				} +#ifndef OPENSSL_NO_DSA +			else if(!strncmp(buf,"+F3:",4)) +				{ +				int k; +				double d; +				 +				p=buf+4; +				k=atoi(sstrsep(&p,sep)); +				sstrsep(&p,sep); + +				d=atof(sstrsep(&p,sep)); +				if(n) +					dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d); +				else +					dsa_results[k][0]=d; + +				d=atof(sstrsep(&p,sep)); +				if(n) +					dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d); +				else +					dsa_results[k][1]=d; +				} +#endif +#ifndef OPENSSL_NO_ECDSA +			else if(!strncmp(buf,"+F4:",4)) +				{ +				int k; +				double d; +				 +				p=buf+4; +				k=atoi(sstrsep(&p,sep)); +				sstrsep(&p,sep); + +				d=atof(sstrsep(&p,sep)); +				if(n) +					ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d); +				else +					ecdsa_results[k][0]=d; + +				d=atof(sstrsep(&p,sep)); +				if(n) +					ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d); +				else +					ecdsa_results[k][1]=d; +				} +#endif  + +#ifndef OPENSSL_NO_ECDH +			else if(!strncmp(buf,"+F5:",4)) +				{ +				int k; +				double d; +				 +				p=buf+4; +				k=atoi(sstrsep(&p,sep)); +				sstrsep(&p,sep); + +				d=atof(sstrsep(&p,sep)); +				if(n) +					ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d); +				else +					ecdh_results[k][0]=d; + +				} +#endif + +			else if(!strncmp(buf,"+H:",3)) +				{ +				} +			else +				fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n); +			} + +		fclose(f); +		} +	free(fds); +	return 1; +	} +#endif +#endif diff --git a/main/openssl/apps/spkac.c b/main/openssl/apps/spkac.c new file mode 100644 index 00000000..0e01ea99 --- /dev/null +++ b/main/openssl/apps/spkac.c @@ -0,0 +1,308 @@ +/* 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). + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/conf.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/lhash.h> +#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 **); + +int 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; +	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) +			noout=1; +		else if (strcmp(*argv,"-pubkey") == 0) +			pubkey=1; +		else if (strcmp(*argv,"-verify") == 0) +			verify=1; +		else badops = 1; +		argc--; +		argv++; +		} + +	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; +		} + +	ERR_load_crypto_strings(); +	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { +		BIO_printf(bio_err, "Error getting password\n"); +		goto end; +	} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	if(keyfile) { +		pkey = load_key(bio_err, +				strcmp(keyfile, "-") ? keyfile : NULL, +				FORMAT_PEM, 1, passin, e, "private key"); +		if(!pkey) { +			goto end; +		} +		spki = NETSCAPE_SPKI_new(); +		if(challenge) ASN1_STRING_set(spki->spkac->challenge, +						 challenge, (int)strlen(challenge)); +		NETSCAPE_SPKI_set_pubkey(spki, pkey); +		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); +			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); +		goto end; +	} + +	conf = NCONF_new(NULL); +	i = NCONF_load_bio(conf, in, NULL); + +	if(!i) { +		BIO_printf(bio_err, "Error parsing config file\n"); +		ERR_print_errors(bio_err); +		goto end; +	} + +	spkstr = NCONF_get_string(conf, spksect, spkac); +		 +	if(!spkstr) { +		BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac); +		ERR_print_errors(bio_err); +		goto end; +	} + +	spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); +	 +	if(!spki) { +		BIO_printf(bio_err, "Error loading SPKAC\n"); +		ERR_print_errors(bio_err); +		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); +		goto end; +	} + +	if(!noout) NETSCAPE_SPKI_print(out, spki); +	pkey = NETSCAPE_SPKI_get_pubkey(spki); +	if(verify) { +		i = NETSCAPE_SPKI_verify(spki, pkey); +		if (i > 0) BIO_printf(bio_err, "Signature OK\n"); +		else { +			BIO_printf(bio_err, "Signature Failure\n"); +			ERR_print_errors(bio_err); +			goto end; +		} +	} +	if(pubkey) PEM_write_bio_PUBKEY(out, pkey); + +	ret = 0; + +end: +	NCONF_free(conf); +	NETSCAPE_SPKI_free(spki); +	BIO_free(in); +	BIO_free_all(out); +	EVP_PKEY_free(pkey); +	if(passin) OPENSSL_free(passin); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} diff --git a/main/openssl/apps/testCA.pem b/main/openssl/apps/testCA.pem new file mode 100644 index 00000000..dcb710aa --- /dev/null +++ b/main/openssl/apps/testCA.pem @@ -0,0 +1,8 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBBzCBsgIBADBNMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEX +MBUGA1UEChMOTWluY29tIFB0eSBMdGQxEDAOBgNVBAMTB1RFU1QgQ0EwXDANBgkq +hkiG9w0BAQEFAANLADBIAkEAzW9brgA8efT2ODB+NrsflJZj3KKqKsm4OrXTRqfL +VETj1ws/zCXl42XJAxdWQMCP0liKfc9Ut4xi1qCVI7N07wIDAQABoAAwDQYJKoZI +hvcNAQEEBQADQQBjZZ42Det9Uw0AFwJy4ufUEy5Cv74pxBp5SZnljgHY+Az0Hs2S +uNkIegr2ITX5azKi9nOkg9ZmsmGG13FIjiC/ +-----END CERTIFICATE REQUEST----- diff --git a/main/openssl/apps/testdsa.h b/main/openssl/apps/testdsa.h new file mode 100644 index 00000000..9e84e31c --- /dev/null +++ b/main/openssl/apps/testdsa.h @@ -0,0 +1,217 @@ +/* NOCW */ +/* used by apps/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, +	}; +static unsigned char dsa512_pub[] = { +	0x00,0x95,0xa7,0x0d,0xec,0x93,0x68,0xba,0x5f,0xf7,0x5f,0x07, +	0xf2,0x3b,0xad,0x6b,0x01,0xdc,0xbe,0xec,0xde,0x04,0x7a,0x3a, +	0x27,0xb3,0xec,0x49,0xfd,0x08,0x43,0x3d,0x7e,0xa8,0x2c,0x5e, +	0x7b,0xbb,0xfc,0xf4,0x6e,0xeb,0x6c,0xb0,0x6e,0xf8,0x02,0x12, +	0x8c,0x38,0x5d,0x83,0x56,0x7d,0xee,0x53,0x05,0x3e,0x24,0x84, +	0xbe,0xba,0x0a,0x6b,0xc8, +	}; +static unsigned char dsa512_p[]={ +	0x9D,0x1B,0x69,0x8E,0x26,0xDB,0xF2,0x2B,0x11,0x70,0x19,0x86, +	0xF6,0x19,0xC8,0xF8,0x19,0xF2,0x18,0x53,0x94,0x46,0x06,0xD0, +	0x62,0x50,0x33,0x4B,0x02,0x3C,0x52,0x30,0x03,0x8B,0x3B,0xF9, +	0x5F,0xD1,0x24,0x06,0x4F,0x7B,0x4C,0xBA,0xAA,0x40,0x9B,0xFD, +	0x96,0xE4,0x37,0x33,0xBB,0x2D,0x5A,0xD7,0x5A,0x11,0x40,0x66, +	0xA2,0x76,0x7D,0x31, +	}; +static unsigned char dsa512_q[]={ +	0xFB,0x53,0xEF,0x50,0xB4,0x40,0x92,0x31,0x56,0x86,0x53,0x7A, +	0xE8,0x8B,0x22,0x9A,0x49,0xFB,0x71,0x8F, +	}; +static unsigned char dsa512_g[]={ +	0x83,0x3E,0x88,0xE5,0xC5,0x89,0x73,0xCE,0x3B,0x6C,0x01,0x49, +	0xBF,0xB3,0xC7,0x9F,0x0A,0xEA,0x44,0x91,0xE5,0x30,0xAA,0xD9, +	0xBE,0x5B,0x5F,0xB7,0x10,0xD7,0x89,0xB7,0x8E,0x74,0xFB,0xCF, +	0x29,0x1E,0xEB,0xA8,0x2C,0x54,0x51,0xB8,0x10,0xDE,0xA0,0xCE, +	0x2F,0xCC,0x24,0x6B,0x90,0x77,0xDE,0xA2,0x68,0xA6,0x52,0x12, +	0xA2,0x03,0x9D,0x20, +	}; + +DSA *get_dsa512() +	{ +	DSA *dsa; + +	if ((dsa=DSA_new()) == NULL) return(NULL); +	dsa->priv_key=BN_bin2bn(dsa512_priv,sizeof(dsa512_priv),NULL); +	dsa->pub_key=BN_bin2bn(dsa512_pub,sizeof(dsa512_pub),NULL); +	dsa->p=BN_bin2bn(dsa512_p,sizeof(dsa512_p),NULL); +	dsa->q=BN_bin2bn(dsa512_q,sizeof(dsa512_q),NULL); +	dsa->g=BN_bin2bn(dsa512_g,sizeof(dsa512_g),NULL); +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) || +				(dsa->q == NULL) || (dsa->g == NULL)) +		return(NULL); +	return(dsa); +	} + +static unsigned char dsa1024_priv[]={ +	0x7d,0x21,0xda,0xbb,0x62,0x15,0x47,0x36,0x07,0x67,0x12,0xe8, +	0x8c,0xaa,0x1c,0xcd,0x38,0x12,0x61,0x18, +	}; +static unsigned char dsa1024_pub[]={ +	0x3c,0x4e,0x9c,0x2a,0x7f,0x16,0xc1,0x25,0xeb,0xac,0x78,0x63, +	0x90,0x14,0x8c,0x8b,0xf4,0x68,0x43,0x3c,0x2d,0xee,0x65,0x50, +	0x7d,0x9c,0x8f,0x8c,0x8a,0x51,0xd6,0x11,0x2b,0x99,0xaf,0x1e, +	0x90,0x97,0xb5,0xd3,0xa6,0x20,0x25,0xd6,0xfe,0x43,0x02,0xd5, +	0x91,0x7d,0xa7,0x8c,0xdb,0xc9,0x85,0xa3,0x36,0x48,0xf7,0x68, +	0xaa,0x60,0xb1,0xf7,0x05,0x68,0x3a,0xa3,0x3f,0xd3,0x19,0x82, +	0xd8,0x82,0x7a,0x77,0xfb,0xef,0xf4,0x15,0x0a,0xeb,0x06,0x04, +	0x7f,0x53,0x07,0x0c,0xbc,0xcb,0x2d,0x83,0xdb,0x3e,0xd1,0x28, +	0xa5,0xa1,0x31,0xe0,0x67,0xfa,0x50,0xde,0x9b,0x07,0x83,0x7e, +	0x2c,0x0b,0xc3,0x13,0x50,0x61,0xe5,0xad,0xbd,0x36,0xb8,0x97, +	0x4e,0x40,0x7d,0xe8,0x83,0x0d,0xbc,0x4b +	}; +static unsigned char dsa1024_p[]={ +	0xA7,0x3F,0x6E,0x85,0xBF,0x41,0x6A,0x29,0x7D,0xF0,0x9F,0x47, +	0x19,0x30,0x90,0x9A,0x09,0x1D,0xDA,0x6A,0x33,0x1E,0xC5,0x3D, +	0x86,0x96,0xB3,0x15,0xE0,0x53,0x2E,0x8F,0xE0,0x59,0x82,0x73, +	0x90,0x3E,0x75,0x31,0x99,0x47,0x7A,0x52,0xFB,0x85,0xE4,0xD9, +	0xA6,0x7B,0x38,0x9B,0x68,0x8A,0x84,0x9B,0x87,0xC6,0x1E,0xB5, +	0x7E,0x86,0x4B,0x53,0x5B,0x59,0xCF,0x71,0x65,0x19,0x88,0x6E, +	0xCE,0x66,0xAE,0x6B,0x88,0x36,0xFB,0xEC,0x28,0xDC,0xC2,0xD7, +	0xA5,0xBB,0xE5,0x2C,0x39,0x26,0x4B,0xDA,0x9A,0x70,0x18,0x95, +	0x37,0x95,0x10,0x56,0x23,0xF6,0x15,0xED,0xBA,0x04,0x5E,0xDE, +	0x39,0x4F,0xFD,0xB7,0x43,0x1F,0xB5,0xA4,0x65,0x6F,0xCD,0x80, +	0x11,0xE4,0x70,0x95,0x5B,0x50,0xCD,0x49, +	}; +static unsigned char dsa1024_q[]={ +	0xF7,0x07,0x31,0xED,0xFA,0x6C,0x06,0x03,0xD5,0x85,0x8A,0x1C, +	0xAC,0x9C,0x65,0xE7,0x50,0x66,0x65,0x6F, +	}; +static unsigned char dsa1024_g[]={ +	0x4D,0xDF,0x4C,0x03,0xA6,0x91,0x8A,0xF5,0x19,0x6F,0x50,0x46, +	0x25,0x99,0xE5,0x68,0x6F,0x30,0xE3,0x69,0xE1,0xE5,0xB3,0x5D, +	0x98,0xBB,0x28,0x86,0x48,0xFC,0xDE,0x99,0x04,0x3F,0x5F,0x88, +	0x0C,0x9C,0x73,0x24,0x0D,0x20,0x5D,0xB9,0x2A,0x9A,0x3F,0x18, +	0x96,0x27,0xE4,0x62,0x87,0xC1,0x7B,0x74,0x62,0x53,0xFC,0x61, +	0x27,0xA8,0x7A,0x91,0x09,0x9D,0xB6,0xF1,0x4D,0x9C,0x54,0x0F, +	0x58,0x06,0xEE,0x49,0x74,0x07,0xCE,0x55,0x7E,0x23,0xCE,0x16, +	0xF6,0xCA,0xDC,0x5A,0x61,0x01,0x7E,0xC9,0x71,0xB5,0x4D,0xF6, +	0xDC,0x34,0x29,0x87,0x68,0xF6,0x5E,0x20,0x93,0xB3,0xDB,0xF5, +	0xE4,0x09,0x6C,0x41,0x17,0x95,0x92,0xEB,0x01,0xB5,0x73,0xA5, +	0x6A,0x7E,0xD8,0x32,0xED,0x0E,0x02,0xB8, +	}; + +DSA *get_dsa1024() +	{ +	DSA *dsa; + +	if ((dsa=DSA_new()) == NULL) return(NULL); +	dsa->priv_key=BN_bin2bn(dsa1024_priv,sizeof(dsa1024_priv),NULL); +	dsa->pub_key=BN_bin2bn(dsa1024_pub,sizeof(dsa1024_pub),NULL); +	dsa->p=BN_bin2bn(dsa1024_p,sizeof(dsa1024_p),NULL); +	dsa->q=BN_bin2bn(dsa1024_q,sizeof(dsa1024_q),NULL); +	dsa->g=BN_bin2bn(dsa1024_g,sizeof(dsa1024_g),NULL); +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) || +				(dsa->q == NULL) || (dsa->g == NULL)) +		return(NULL); +	return(dsa); +	} + +static unsigned char dsa2048_priv[]={ +	0x32,0x67,0x92,0xf6,0xc4,0xe2,0xe2,0xe8,0xa0,0x8b,0x6b,0x45, +	0x0c,0x8a,0x76,0xb0,0xee,0xcf,0x91,0xa7, +	}; +static unsigned char dsa2048_pub[]={ +	0x17,0x8f,0xa8,0x11,0x84,0x92,0xec,0x83,0x47,0xc7,0x6a,0xb0, +	0x92,0xaf,0x5a,0x20,0x37,0xa3,0x64,0x79,0xd2,0xd0,0x3d,0xcd, +	0xe0,0x61,0x88,0x88,0x21,0xcc,0x74,0x5d,0xce,0x4c,0x51,0x47, +	0xf0,0xc5,0x5c,0x4c,0x82,0x7a,0xaf,0x72,0xad,0xb9,0xe0,0x53, +	0xf2,0x78,0xb7,0xf0,0xb5,0x48,0x7f,0x8a,0x3a,0x18,0xd1,0x9f, +	0x8b,0x7d,0xa5,0x47,0xb7,0x95,0xab,0x98,0xf8,0x7b,0x74,0x50, +	0x56,0x8e,0x57,0xf0,0xee,0xf5,0xb7,0xba,0xab,0x85,0x86,0xf9, +	0x2b,0xef,0x41,0x56,0xa0,0xa4,0x9f,0xb7,0x38,0x00,0x46,0x0a, +	0xa6,0xf1,0xfc,0x1f,0xd8,0x4e,0x85,0x44,0x92,0x43,0x21,0x5d, +	0x6e,0xcc,0xc2,0xcb,0x26,0x31,0x0d,0x21,0xc4,0xbd,0x8d,0x24, +	0xbc,0xd9,0x18,0x19,0xd7,0xdc,0xf1,0xe7,0x93,0x50,0x48,0x03, +	0x2c,0xae,0x2e,0xe7,0x49,0x88,0x5f,0x93,0x57,0x27,0x99,0x36, +	0xb4,0x20,0xab,0xfc,0xa7,0x2b,0xf2,0xd9,0x98,0xd7,0xd4,0x34, +	0x9d,0x96,0x50,0x58,0x9a,0xea,0x54,0xf3,0xee,0xf5,0x63,0x14, +	0xee,0x85,0x83,0x74,0x76,0xe1,0x52,0x95,0xc3,0xf7,0xeb,0x04, +	0x04,0x7b,0xa7,0x28,0x1b,0xcc,0xea,0x4a,0x4e,0x84,0xda,0xd8, +	0x9c,0x79,0xd8,0x9b,0x66,0x89,0x2f,0xcf,0xac,0xd7,0x79,0xf9, +	0xa9,0xd8,0x45,0x13,0x78,0xb9,0x00,0x14,0xc9,0x7e,0x22,0x51, +	0x86,0x67,0xb0,0x9f,0x26,0x11,0x23,0xc8,0x38,0xd7,0x70,0x1d, +	0x15,0x8e,0x4d,0x4f,0x95,0x97,0x40,0xa1,0xc2,0x7e,0x01,0x18, +	0x72,0xf4,0x10,0xe6,0x8d,0x52,0x16,0x7f,0xf2,0xc9,0xf8,0x33, +	0x8b,0x33,0xb7,0xce, +	}; +static unsigned char dsa2048_p[]={ +	0xA0,0x25,0xFA,0xAD,0xF4,0x8E,0xB9,0xE5,0x99,0xF3,0x5D,0x6F, +	0x4F,0x83,0x34,0xE2,0x7E,0xCF,0x6F,0xBF,0x30,0xAF,0x6F,0x81, +	0xEB,0xF8,0xC4,0x13,0xD9,0xA0,0x5D,0x8B,0x5C,0x8E,0xDC,0xC2, +	0x1D,0x0B,0x41,0x32,0xB0,0x1F,0xFE,0xEF,0x0C,0xC2,0xA2,0x7E, +	0x68,0x5C,0x28,0x21,0xE9,0xF5,0xB1,0x58,0x12,0x63,0x4C,0x19, +	0x4E,0xFF,0x02,0x4B,0x92,0xED,0xD2,0x07,0x11,0x4D,0x8C,0x58, +	0x16,0x5C,0x55,0x8E,0xAD,0xA3,0x67,0x7D,0xB9,0x86,0x6E,0x0B, +	0xE6,0x54,0x6F,0x40,0xAE,0x0E,0x67,0x4C,0xF9,0x12,0x5B,0x3C, +	0x08,0x7A,0xF7,0xFC,0x67,0x86,0x69,0xE7,0x0A,0x94,0x40,0xBF, +	0x8B,0x76,0xFE,0x26,0xD1,0xF2,0xA1,0x1A,0x84,0xA1,0x43,0x56, +	0x28,0xBC,0x9A,0x5F,0xD7,0x3B,0x69,0x89,0x8A,0x36,0x2C,0x51, +	0xDF,0x12,0x77,0x2F,0x57,0x7B,0xA0,0xAA,0xDD,0x7F,0xA1,0x62, +	0x3B,0x40,0x7B,0x68,0x1A,0x8F,0x0D,0x38,0xBB,0x21,0x5D,0x18, +	0xFC,0x0F,0x46,0xF7,0xA3,0xB0,0x1D,0x23,0xC3,0xD2,0xC7,0x72, +	0x51,0x18,0xDF,0x46,0x95,0x79,0xD9,0xBD,0xB5,0x19,0x02,0x2C, +	0x87,0xDC,0xE7,0x57,0x82,0x7E,0xF1,0x8B,0x06,0x3D,0x00,0xA5, +	0x7B,0x6B,0x26,0x27,0x91,0x0F,0x6A,0x77,0xE4,0xD5,0x04,0xE4, +	0x12,0x2C,0x42,0xFF,0xD2,0x88,0xBB,0xD3,0x92,0xA0,0xF9,0xC8, +	0x51,0x64,0x14,0x5C,0xD8,0xF9,0x6C,0x47,0x82,0xB4,0x1C,0x7F, +	0x09,0xB8,0xF0,0x25,0x83,0x1D,0x3F,0x3F,0x05,0xB3,0x21,0x0A, +	0x5D,0xA7,0xD8,0x54,0xC3,0x65,0x7D,0xC3,0xB0,0x1D,0xBF,0xAE, +	0xF8,0x68,0xCF,0x9B, +	}; +static unsigned char dsa2048_q[]={ +	0x97,0xE7,0x33,0x4D,0xD3,0x94,0x3E,0x0B,0xDB,0x62,0x74,0xC6, +	0xA1,0x08,0xDD,0x19,0xA3,0x75,0x17,0x1B, +	}; +static unsigned char dsa2048_g[]={ +	0x2C,0x78,0x16,0x59,0x34,0x63,0xF4,0xF3,0x92,0xFC,0xB5,0xA5, +	0x4F,0x13,0xDE,0x2F,0x1C,0xA4,0x3C,0xAE,0xAD,0x38,0x3F,0x7E, +	0x90,0xBF,0x96,0xA6,0xAE,0x25,0x90,0x72,0xF5,0x8E,0x80,0x0C, +	0x39,0x1C,0xD9,0xEC,0xBA,0x90,0x5B,0x3A,0xE8,0x58,0x6C,0x9E, +	0x30,0x42,0x37,0x02,0x31,0x82,0xBC,0x6A,0xDF,0x6A,0x09,0x29, +	0xE3,0xC0,0x46,0xD1,0xCB,0x85,0xEC,0x0C,0x30,0x5E,0xEA,0xC8, +	0x39,0x8E,0x22,0x9F,0x22,0x10,0xD2,0x34,0x61,0x68,0x37,0x3D, +	0x2E,0x4A,0x5B,0x9A,0xF5,0xC1,0x48,0xC6,0xF6,0xDC,0x63,0x1A, +	0xD3,0x96,0x64,0xBA,0x34,0xC9,0xD1,0xA0,0xD1,0xAE,0x6C,0x2F, +	0x48,0x17,0x93,0x14,0x43,0xED,0xF0,0x21,0x30,0x19,0xC3,0x1B, +	0x5F,0xDE,0xA3,0xF0,0x70,0x78,0x18,0xE1,0xA8,0xE4,0xEE,0x2E, +	0x00,0xA5,0xE4,0xB3,0x17,0xC8,0x0C,0x7D,0x6E,0x42,0xDC,0xB7, +	0x46,0x00,0x36,0x4D,0xD4,0x46,0xAA,0x3D,0x3C,0x46,0x89,0x40, +	0xBF,0x1D,0x84,0x77,0x0A,0x75,0xF3,0x87,0x1D,0x08,0x4C,0xA6, +	0xD1,0xA9,0x1C,0x1E,0x12,0x1E,0xE1,0xC7,0x30,0x28,0x76,0xA5, +	0x7F,0x6C,0x85,0x96,0x2B,0x6F,0xDB,0x80,0x66,0x26,0xAE,0xF5, +	0x93,0xC7,0x8E,0xAE,0x9A,0xED,0xE4,0xCA,0x04,0xEA,0x3B,0x72, +	0xEF,0xDC,0x87,0xED,0x0D,0xA5,0x4C,0x4A,0xDD,0x71,0x22,0x64, +	0x59,0x69,0x4E,0x8E,0xBF,0x43,0xDC,0xAB,0x8E,0x66,0xBB,0x01, +	0xB6,0xF4,0xE7,0xFD,0xD2,0xAD,0x9F,0x36,0xC1,0xA0,0x29,0x99, +	0xD1,0x96,0x70,0x59,0x06,0x78,0x35,0xBD,0x65,0x55,0x52,0x9E, +	0xF8,0xB2,0xE5,0x38, +	}; +  +DSA *get_dsa2048() +	{ +	DSA *dsa; +  +	if ((dsa=DSA_new()) == NULL) return(NULL); +	dsa->priv_key=BN_bin2bn(dsa2048_priv,sizeof(dsa2048_priv),NULL); +	dsa->pub_key=BN_bin2bn(dsa2048_pub,sizeof(dsa2048_pub),NULL); +	dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL); +	dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL); +	dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL); +	if ((dsa->priv_key == NULL) || (dsa->pub_key == NULL) || (dsa->p == NULL) || +				(dsa->q == NULL) || (dsa->g == NULL)) +		return(NULL); +	return(dsa); +	} + +static const char rnd_seed[] = "string to make the random number generator think it has entropy"; +static int rnd_fake = 0; diff --git a/main/openssl/apps/testrsa.h b/main/openssl/apps/testrsa.h new file mode 100644 index 00000000..3007d792 --- /dev/null +++ b/main/openssl/apps/testrsa.h @@ -0,0 +1,518 @@ +/* apps/testrsa.h */ +/* used by apps/speed.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.] + */ + +static unsigned char test512[]={ +	0x30,0x82,0x01,0x3a,0x02,0x01,0x00,0x02,0x41,0x00, +	0xd6,0x33,0xb9,0xc8,0xfb,0x4f,0x3c,0x7d,0xc0,0x01, +	0x86,0xd0,0xe7,0xa0,0x55,0xf2,0x95,0x93,0xcc,0x4f, +	0xb7,0x5b,0x67,0x5b,0x94,0x68,0xc9,0x34,0x15,0xde, +	0xa5,0x2e,0x1c,0x33,0xc2,0x6e,0xfc,0x34,0x5e,0x71, +	0x13,0xb7,0xd6,0xee,0xd8,0xa5,0x65,0x05,0x72,0x87, +	0xa8,0xb0,0x77,0xfe,0x57,0xf5,0xfc,0x5f,0x55,0x83, +	0x87,0xdd,0x57,0x49,0x02,0x03,0x01,0x00,0x01,0x02, +	0x41,0x00,0xa7,0xf7,0x91,0xc5,0x0f,0x84,0x57,0xdc, +	0x07,0xf7,0x6a,0x7f,0x60,0x52,0xb3,0x72,0xf1,0x66, +	0x1f,0x7d,0x97,0x3b,0x9e,0xb6,0x0a,0x8f,0x8c,0xcf, +	0x42,0x23,0x00,0x04,0xd4,0x28,0x0e,0x1c,0x90,0xc4, +	0x11,0x25,0x25,0xa5,0x93,0xa5,0x2f,0x70,0x02,0xdf, +	0x81,0x9c,0x49,0x03,0xa0,0xf8,0x6d,0x54,0x2e,0x26, +	0xde,0xaa,0x85,0x59,0xa8,0x31,0x02,0x21,0x00,0xeb, +	0x47,0xd7,0x3b,0xf6,0xc3,0xdd,0x5a,0x46,0xc5,0xb9, +	0x2b,0x9a,0xa0,0x09,0x8f,0xa6,0xfb,0xf3,0x78,0x7a, +	0x33,0x70,0x9d,0x0f,0x42,0x6b,0x13,0x68,0x24,0xd3, +	0x15,0x02,0x21,0x00,0xe9,0x10,0xb0,0xb3,0x0d,0xe2, +	0x82,0x68,0x77,0x8a,0x6e,0x7c,0xda,0xbc,0x3e,0x53, +	0x83,0xfb,0xd6,0x22,0xe7,0xb5,0xae,0x6e,0x80,0xda, +	0x00,0x55,0x97,0xc1,0xd0,0x65,0x02,0x20,0x4c,0xf8, +	0x73,0xb1,0x6a,0x49,0x29,0x61,0x1f,0x46,0x10,0x0d, +	0xf3,0xc7,0xe7,0x58,0xd7,0x88,0x15,0x5e,0x94,0x9b, +	0xbf,0x7b,0xa2,0x42,0x58,0x45,0x41,0x0c,0xcb,0x01, +	0x02,0x20,0x12,0x11,0xba,0x31,0x57,0x9d,0x3d,0x11, +	0x0e,0x5b,0x8c,0x2f,0x5f,0xe2,0x02,0x4f,0x05,0x47, +	0x8c,0x15,0x8e,0xb3,0x56,0x3f,0xb8,0xfb,0xad,0xd4, +	0xf4,0xfc,0x10,0xc5,0x02,0x20,0x18,0xa1,0x29,0x99, +	0x5b,0xd9,0xc8,0xd4,0xfc,0x49,0x7a,0x2a,0x21,0x2c, +	0x49,0xe4,0x4f,0xeb,0xef,0x51,0xf1,0xab,0x6d,0xfb, +	0x4b,0x14,0xe9,0x4b,0x52,0xb5,0x82,0x2c, +	}; + +static unsigned char test1024[]={ +	0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81, +	0x00,0xdc,0x98,0x43,0xe8,0x3d,0x43,0x5b,0xe4,0x05, +	0xcd,0xd0,0xa9,0x3e,0xcb,0x83,0x75,0xf6,0xb5,0xa5, +	0x9f,0x6b,0xe9,0x34,0x41,0x29,0x18,0xfa,0x6a,0x55, +	0x4d,0x70,0xfc,0xec,0xae,0x87,0x38,0x0a,0x20,0xa9, +	0xc0,0x45,0x77,0x6e,0x57,0x60,0x57,0xf4,0xed,0x96, +	0x22,0xcb,0x8f,0xe1,0x33,0x3a,0x17,0x1f,0xed,0x37, +	0xa5,0x6f,0xeb,0xa6,0xbc,0x12,0x80,0x1d,0x53,0xbd, +	0x70,0xeb,0x21,0x76,0x3e,0xc9,0x2f,0x1a,0x45,0x24, +	0x82,0xff,0xcd,0x59,0x32,0x06,0x2e,0x12,0x3b,0x23, +	0x78,0xed,0x12,0x3d,0xe0,0x8d,0xf9,0x67,0x4f,0x37, +	0x4e,0x47,0x02,0x4c,0x2d,0xc0,0x4f,0x1f,0xb3,0x94, +	0xe1,0x41,0x2e,0x2d,0x90,0x10,0xfc,0x82,0x91,0x8b, +	0x0f,0x22,0xd4,0xf2,0xfc,0x2c,0xab,0x53,0x55,0x02, +	0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x2b,0xcc,0x3f, +	0x8f,0x58,0xba,0x8b,0x00,0x16,0xf6,0xea,0x3a,0xf0, +	0x30,0xd0,0x05,0x17,0xda,0xb0,0xeb,0x9a,0x2d,0x4f, +	0x26,0xb0,0xd6,0x38,0xc1,0xeb,0xf5,0xd8,0x3d,0x1f, +	0x70,0xf7,0x7f,0xf4,0xe2,0xcf,0x51,0x51,0x79,0x88, +	0xfa,0xe8,0x32,0x0e,0x7b,0x2d,0x97,0xf2,0xfa,0xba, +	0x27,0xc5,0x9c,0xd9,0xc5,0xeb,0x8a,0x79,0x52,0x3c, +	0x64,0x34,0x7d,0xc2,0xcf,0x28,0xc7,0x4e,0xd5,0x43, +	0x0b,0xd1,0xa6,0xca,0x6d,0x03,0x2d,0x72,0x23,0xbc, +	0x6d,0x05,0xfa,0x16,0x09,0x2f,0x2e,0x5c,0xb6,0xee, +	0x74,0xdd,0xd2,0x48,0x8e,0x36,0x0c,0x06,0x3d,0x4d, +	0xe5,0x10,0x82,0xeb,0x6a,0xf3,0x4b,0x9f,0xd6,0xed, +	0x11,0xb1,0x6e,0xec,0xf4,0xfe,0x8e,0x75,0x94,0x20, +	0x2f,0xcb,0xac,0x46,0xf1,0x02,0x41,0x00,0xf9,0x8c, +	0xa3,0x85,0xb1,0xdd,0x29,0xaf,0x65,0xc1,0x33,0xf3, +	0x95,0xc5,0x52,0x68,0x0b,0xd4,0xf1,0xe5,0x0e,0x02, +	0x9f,0x4f,0xfa,0x77,0xdc,0x46,0x9e,0xc7,0xa6,0xe4, +	0x16,0x29,0xda,0xb0,0x07,0xcf,0x5b,0xa9,0x12,0x8a, +	0xdd,0x63,0x0a,0xde,0x2e,0x8c,0x66,0x8b,0x8c,0xdc, +	0x19,0xa3,0x7e,0xf4,0x3b,0xd0,0x1a,0x8c,0xa4,0xc2, +	0xe1,0xd3,0x02,0x41,0x00,0xe2,0x4c,0x05,0xf2,0x04, +	0x86,0x4e,0x61,0x43,0xdb,0xb0,0xb9,0x96,0x86,0x52, +	0x2c,0xca,0x8d,0x7b,0xab,0x0b,0x13,0x0d,0x7e,0x38, +	0x5b,0xe2,0x2e,0x7b,0x0e,0xe7,0x19,0x99,0x38,0xe7, +	0xf2,0x21,0xbd,0x85,0x85,0xe3,0xfd,0x28,0x77,0x20, +	0x31,0x71,0x2c,0xd0,0xff,0xfb,0x2e,0xaf,0x85,0xb4, +	0x86,0xca,0xf3,0xbb,0xca,0xaa,0x0f,0x95,0x37,0x02, +	0x40,0x0e,0x41,0x9a,0x95,0xe8,0xb3,0x59,0xce,0x4b, +	0x61,0xde,0x35,0xec,0x38,0x79,0x9c,0xb8,0x10,0x52, +	0x41,0x63,0xab,0x82,0xae,0x6f,0x00,0xa9,0xf4,0xde, +	0xdd,0x49,0x0b,0x7e,0xb8,0xa5,0x65,0xa9,0x0c,0x8f, +	0x8f,0xf9,0x1f,0x35,0xc6,0x92,0xb8,0x5e,0xb0,0x66, +	0xab,0x52,0x40,0xc0,0xb6,0x36,0x6a,0x7d,0x80,0x46, +	0x04,0x02,0xe5,0x9f,0x41,0x02,0x41,0x00,0xc0,0xad, +	0xcc,0x4e,0x21,0xee,0x1d,0x24,0x91,0xfb,0xa7,0x80, +	0x8d,0x9a,0xb6,0xb3,0x2e,0x8f,0xc2,0xe1,0x82,0xdf, +	0x69,0x18,0xb4,0x71,0xff,0xa6,0x65,0xde,0xed,0x84, +	0x8d,0x42,0xb7,0xb3,0x21,0x69,0x56,0x1c,0x07,0x60, +	0x51,0x29,0x04,0xff,0x34,0x06,0xdd,0xb9,0x67,0x2c, +	0x7c,0x04,0x93,0x0e,0x46,0x15,0xbb,0x2a,0xb7,0x1b, +	0xe7,0x87,0x02,0x40,0x78,0xda,0x5d,0x07,0x51,0x0c, +	0x16,0x7a,0x9f,0x29,0x20,0x84,0x0d,0x42,0xfa,0xd7, +	0x00,0xd8,0x77,0x7e,0xb0,0xb0,0x6b,0xd6,0x5b,0x53, +	0xb8,0x9b,0x7a,0xcd,0xc7,0x2b,0xb8,0x6a,0x63,0xa9, +	0xfb,0x6f,0xa4,0x72,0xbf,0x4c,0x5d,0x00,0x14,0xba, +	0xfa,0x59,0x88,0xed,0xe4,0xe0,0x8c,0xa2,0xec,0x14, +	0x7e,0x2d,0xe2,0xf0,0x46,0x49,0x95,0x45, +	}; + +static unsigned char test2048[]={ +	0x30,0x82,0x04,0xa3,0x02,0x01,0x00,0x02,0x82,0x01, +	0x01,0x00,0xc0,0xc0,0xce,0x3e,0x3c,0x53,0x67,0x3f, +	0x4f,0xc5,0x2f,0xa4,0xc2,0x5a,0x2f,0x58,0xfd,0x27, +	0x52,0x6a,0xe8,0xcf,0x4a,0x73,0x47,0x8d,0x25,0x0f, +	0x5f,0x03,0x26,0x78,0xef,0xf0,0x22,0x12,0xd3,0xde, +	0x47,0xb2,0x1c,0x0b,0x38,0x63,0x1a,0x6c,0x85,0x7a, +	0x80,0xc6,0x8f,0xa0,0x41,0xaf,0x62,0xc4,0x67,0x32, +	0x88,0xf8,0xa6,0x9c,0xf5,0x23,0x1d,0xe4,0xac,0x3f, +	0x29,0xf9,0xec,0xe1,0x8b,0x26,0x03,0x2c,0xb2,0xab, +	0xf3,0x7d,0xb5,0xca,0x49,0xc0,0x8f,0x1c,0xdf,0x33, +	0x3a,0x60,0xda,0x3c,0xb0,0x16,0xf8,0xa9,0x12,0x8f, +	0x64,0xac,0x23,0x0c,0x69,0x64,0x97,0x5d,0x99,0xd4, +	0x09,0x83,0x9b,0x61,0xd3,0xac,0xf0,0xde,0xdd,0x5e, +	0x9f,0x44,0x94,0xdb,0x3a,0x4d,0x97,0xe8,0x52,0x29, +	0xf7,0xdb,0x94,0x07,0x45,0x90,0x78,0x1e,0x31,0x0b, +	0x80,0xf7,0x57,0xad,0x1c,0x79,0xc5,0xcb,0x32,0xb0, +	0xce,0xcd,0x74,0xb3,0xe2,0x94,0xc5,0x78,0x2f,0x34, +	0x1a,0x45,0xf7,0x8c,0x52,0xa5,0xbc,0x8d,0xec,0xd1, +	0x2f,0x31,0x3b,0xf0,0x49,0x59,0x5e,0x88,0x9d,0x15, +	0x92,0x35,0x32,0xc1,0xe7,0x61,0xec,0x50,0x48,0x7c, +	0xba,0x05,0xf9,0xf8,0xf8,0xa7,0x8c,0x83,0xe8,0x66, +	0x5b,0xeb,0xfe,0xd8,0x4f,0xdd,0x6d,0x36,0xc0,0xb2, +	0x90,0x0f,0xb8,0x52,0xf9,0x04,0x9b,0x40,0x2c,0x27, +	0xd6,0x36,0x8e,0xc2,0x1b,0x44,0xf3,0x92,0xd5,0x15, +	0x9e,0x9a,0xbc,0xf3,0x7d,0x03,0xd7,0x02,0x14,0x20, +	0xe9,0x10,0x92,0xfd,0xf9,0xfc,0x8f,0xe5,0x18,0xe1, +	0x95,0xcc,0x9e,0x60,0xa6,0xfa,0x38,0x4d,0x02,0x03, +	0x01,0x00,0x01,0x02,0x82,0x01,0x00,0x00,0xc3,0xc3, +	0x0d,0xb4,0x27,0x90,0x8d,0x4b,0xbf,0xb8,0x84,0xaa, +	0xd0,0xb8,0xc7,0x5d,0x99,0xbe,0x55,0xf6,0x3e,0x7c, +	0x49,0x20,0xcb,0x8a,0x8e,0x19,0x0e,0x66,0x24,0xac, +	0xaf,0x03,0x33,0x97,0xeb,0x95,0xd5,0x3b,0x0f,0x40, +	0x56,0x04,0x50,0xd1,0xe6,0xbe,0x84,0x0b,0x25,0xd3, +	0x9c,0xe2,0x83,0x6c,0xf5,0x62,0x5d,0xba,0x2b,0x7d, +	0x3d,0x7a,0x6c,0xe1,0xd2,0x0e,0x54,0x93,0x80,0x01, +	0x91,0x51,0x09,0xe8,0x5b,0x8e,0x47,0xbd,0x64,0xe4, +	0x0e,0x03,0x83,0x55,0xcf,0x5a,0x37,0xf0,0x25,0xb5, +	0x7d,0x21,0xd7,0x69,0xdf,0x6f,0xc2,0xcf,0x10,0xc9, +	0x8a,0x40,0x9f,0x7a,0x70,0xc0,0xe8,0xe8,0xc0,0xe6, +	0x9a,0x15,0x0a,0x8d,0x4e,0x46,0xcb,0x7a,0xdb,0xb3, +	0xcb,0x83,0x02,0xc4,0xf0,0xab,0xeb,0x02,0x01,0x0e, +	0x23,0xfc,0x1d,0xc4,0xbd,0xd4,0xaa,0x5d,0x31,0x46, +	0x99,0xce,0x9e,0xf8,0x04,0x75,0x10,0x67,0xc4,0x53, +	0x47,0x44,0xfa,0xc2,0x25,0x73,0x7e,0xd0,0x8e,0x59, +	0xd1,0xb2,0x5a,0xf4,0xc7,0x18,0x92,0x2f,0x39,0xab, +	0xcd,0xa3,0xb5,0xc2,0xb9,0xc7,0xb9,0x1b,0x9f,0x48, +	0xfa,0x13,0xc6,0x98,0x4d,0xca,0x84,0x9c,0x06,0xca, +	0xe7,0x89,0x01,0x04,0xc4,0x6c,0xfd,0x29,0x59,0x35, +	0xe7,0xf3,0xdd,0xce,0x64,0x59,0xbf,0x21,0x13,0xa9, +	0x9f,0x0e,0xc5,0xff,0xbd,0x33,0x00,0xec,0xac,0x6b, +	0x11,0xef,0x51,0x5e,0xad,0x07,0x15,0xde,0xb8,0x5f, +	0xc6,0xb9,0xa3,0x22,0x65,0x46,0x83,0x14,0xdf,0xd0, +	0xf1,0x44,0x8a,0xe1,0x9c,0x23,0x33,0xb4,0x97,0x33, +	0xe6,0x6b,0x81,0x02,0x81,0x81,0x00,0xec,0x12,0xa7, +	0x59,0x74,0x6a,0xde,0x3e,0xad,0xd8,0x36,0x80,0x50, +	0xa2,0xd5,0x21,0x81,0x07,0xf1,0xd0,0x91,0xf2,0x6c, +	0x12,0x2f,0x9d,0x1a,0x26,0xf8,0x30,0x65,0xdf,0xe8, +	0xc0,0x9b,0x6a,0x30,0x98,0x82,0x87,0xec,0xa2,0x56, +	0x87,0x62,0x6f,0xe7,0x9f,0xf6,0x56,0xe6,0x71,0x8f, +	0x49,0x86,0x93,0x5a,0x4d,0x34,0x58,0xfe,0xd9,0x04, +	0x13,0xaf,0x79,0xb7,0xad,0x11,0xd1,0x30,0x9a,0x14, +	0x06,0xa0,0xfa,0xb7,0x55,0xdc,0x6c,0x5a,0x4c,0x2c, +	0x59,0x56,0xf6,0xe8,0x9d,0xaf,0x0a,0x78,0x99,0x06, +	0x06,0x9e,0xe7,0x9c,0x51,0x55,0x43,0xfc,0x3b,0x6c, +	0x0b,0xbf,0x2d,0x41,0xa7,0xaf,0xb7,0xe0,0xe8,0x28, +	0x18,0xb4,0x13,0xd1,0xe6,0x97,0xd0,0x9f,0x6a,0x80, +	0xca,0xdd,0x1a,0x7e,0x15,0x02,0x81,0x81,0x00,0xd1, +	0x06,0x0c,0x1f,0xe3,0xd0,0xab,0xd6,0xca,0x7c,0xbc, +	0x7d,0x13,0x35,0xce,0x27,0xcd,0xd8,0x49,0x51,0x63, +	0x64,0x0f,0xca,0x06,0x12,0xfc,0x07,0x3e,0xaf,0x61, +	0x6d,0xe2,0x53,0x39,0x27,0xae,0xc3,0x11,0x9e,0x94, +	0x01,0x4f,0xe3,0xf3,0x67,0xf9,0x77,0xf9,0xe7,0x95, +	0x3a,0x6f,0xe2,0x20,0x73,0x3e,0xa4,0x7a,0x28,0xd4, +	0x61,0x97,0xf6,0x17,0xa0,0x23,0x10,0x2b,0xce,0x84, +	0x57,0x7e,0x25,0x1f,0xf4,0xa8,0x54,0xd2,0x65,0x94, +	0xcc,0x95,0x0a,0xab,0x30,0xc1,0x59,0x1f,0x61,0x8e, +	0xb9,0x6b,0xd7,0x4e,0xb9,0x83,0x43,0x79,0x85,0x11, +	0xbc,0x0f,0xae,0x25,0x20,0x05,0xbc,0xd2,0x48,0xa1, +	0x68,0x09,0x84,0xf6,0x12,0x9a,0x66,0xb9,0x2b,0xbb, +	0x76,0x03,0x17,0x46,0x4e,0x97,0x59,0x02,0x81,0x80, +	0x09,0x4c,0xfa,0xd6,0xe5,0x65,0x48,0x78,0x43,0xb5, +	0x1f,0x00,0x93,0x2c,0xb7,0x24,0xe8,0xc6,0x7d,0x5a, +	0x70,0x45,0x92,0xc8,0x6c,0xa3,0xcd,0xe1,0xf7,0x29, +	0x40,0xfa,0x3f,0x5b,0x47,0x44,0x39,0xc1,0xe8,0x72, +	0x9e,0x7a,0x0e,0xda,0xaa,0xa0,0x2a,0x09,0xfd,0x54, +	0x93,0x23,0xaa,0x37,0x85,0x5b,0xcc,0xd4,0xf9,0xd8, +	0xff,0xc1,0x61,0x0d,0xbd,0x7e,0x18,0x24,0x73,0x6d, +	0x40,0x72,0xf1,0x93,0x09,0x48,0x97,0x6c,0x84,0x90, +	0xa8,0x46,0x14,0x01,0x39,0x11,0xe5,0x3c,0x41,0x27, +	0x32,0x75,0x24,0xed,0xa1,0xd9,0x12,0x29,0x8a,0x28, +	0x71,0x89,0x8d,0xca,0x30,0xb0,0x01,0xc4,0x2f,0x82, +	0x19,0x14,0x4c,0x70,0x1c,0xb8,0x23,0x2e,0xe8,0x90, +	0x49,0x97,0x92,0x97,0x6b,0x7a,0x9d,0xb9,0x02,0x81, +	0x80,0x0f,0x0e,0xa1,0x76,0xf6,0xa1,0x44,0x8f,0xaf, +	0x7c,0x76,0xd3,0x87,0xbb,0xbb,0x83,0x10,0x88,0x01, +	0x18,0x14,0xd1,0xd3,0x75,0x59,0x24,0xaa,0xf5,0x16, +	0xa5,0xe9,0x9d,0xd1,0xcc,0xee,0xf4,0x15,0xd9,0xc5, +	0x7e,0x27,0xe9,0x44,0x49,0x06,0x72,0xb9,0xfc,0xd3, +	0x8a,0xc4,0x2c,0x36,0x7d,0x12,0x9b,0x5a,0xaa,0xdc, +	0x85,0xee,0x6e,0xad,0x54,0xb3,0xf4,0xfc,0x31,0xa1, +	0x06,0x3a,0x70,0x57,0x0c,0xf3,0x95,0x5b,0x3e,0xe8, +	0xfd,0x1a,0x4f,0xf6,0x78,0x93,0x46,0x6a,0xd7,0x31, +	0xb4,0x84,0x64,0x85,0x09,0x38,0x89,0x92,0x94,0x1c, +	0xbf,0xe2,0x3c,0x2a,0xe0,0xff,0x99,0xa3,0xf0,0x2b, +	0x31,0xc2,0x36,0xcd,0x60,0xbf,0x9d,0x2d,0x74,0x32, +	0xe8,0x9c,0x93,0x6e,0xbb,0x91,0x7b,0xfd,0xd9,0x02, +	0x81,0x81,0x00,0xa2,0x71,0x25,0x38,0xeb,0x2a,0xe9, +	0x37,0xcd,0xfe,0x44,0xce,0x90,0x3f,0x52,0x87,0x84, +	0x52,0x1b,0xae,0x8d,0x22,0x94,0xce,0x38,0xe6,0x04, +	0x88,0x76,0x85,0x9a,0xd3,0x14,0x09,0xe5,0x69,0x9a, +	0xff,0x58,0x92,0x02,0x6a,0x7d,0x7c,0x1e,0x2c,0xfd, +	0xa8,0xca,0x32,0x14,0x4f,0x0d,0x84,0x0d,0x37,0x43, +	0xbf,0xe4,0x5d,0x12,0xc8,0x24,0x91,0x27,0x8d,0x46, +	0xd9,0x54,0x53,0xe7,0x62,0x71,0xa8,0x2b,0x71,0x41, +	0x8d,0x75,0xf8,0x3a,0xa0,0x61,0x29,0x46,0xa6,0xe5, +	0x82,0xfa,0x3a,0xd9,0x08,0xfa,0xfc,0x63,0xfd,0x6b, +	0x30,0xbc,0xf4,0x4e,0x9e,0x8c,0x25,0x0c,0xb6,0x55, +	0xe7,0x3c,0xd4,0x4e,0x0b,0xfd,0x8b,0xc3,0x0e,0x1d, +	0x9c,0x44,0x57,0x8f,0x1f,0x86,0xf7,0xd5,0x1b,0xe4, +	0x95, +	}; + +static unsigned char test4096[]={ +	0x30,0x82,0x09,0x29,0x02,0x01,0x00,0x02,0x82,0x02, +	0x01,0x00,0xc0,0x71,0xac,0x1a,0x13,0x88,0x82,0x43, +	0x3b,0x51,0x57,0x71,0x8d,0xb6,0x2b,0x82,0x65,0x21, +	0x53,0x5f,0x28,0x29,0x4f,0x8d,0x7c,0x8a,0xb9,0x44, +	0xb3,0x28,0x41,0x4f,0xd3,0xfa,0x6a,0xf8,0xb9,0x28, +	0x50,0x39,0x67,0x53,0x2c,0x3c,0xd7,0xcb,0x96,0x41, +	0x40,0x32,0xbb,0xeb,0x70,0xae,0x1f,0xb0,0x65,0xf7, +	0x3a,0xd9,0x22,0xfd,0x10,0xae,0xbd,0x02,0xe2,0xdd, +	0xf3,0xc2,0x79,0x3c,0xc6,0xfc,0x75,0xbb,0xaf,0x4e, +	0x3a,0x36,0xc2,0x4f,0xea,0x25,0xdf,0x13,0x16,0x4b, +	0x20,0xfe,0x4b,0x69,0x16,0xc4,0x7f,0x1a,0x43,0xa6, +	0x17,0x1b,0xb9,0x0a,0xf3,0x09,0x86,0x28,0x89,0xcf, +	0x2c,0xd0,0xd4,0x81,0xaf,0xc6,0x6d,0xe6,0x21,0x8d, +	0xee,0xef,0xea,0xdc,0xb7,0xc6,0x3b,0x63,0x9f,0x0e, +	0xad,0x89,0x78,0x23,0x18,0xbf,0x70,0x7e,0x84,0xe0, +	0x37,0xec,0xdb,0x8e,0x9c,0x3e,0x6a,0x19,0xcc,0x99, +	0x72,0xe6,0xb5,0x7d,0x6d,0xfa,0xe5,0xd3,0xe4,0x90, +	0xb5,0xb2,0xb2,0x12,0x70,0x4e,0xca,0xf8,0x10,0xf8, +	0xa3,0x14,0xc2,0x48,0x19,0xeb,0x60,0x99,0xbb,0x2a, +	0x1f,0xb1,0x7a,0xb1,0x3d,0x24,0xfb,0xa0,0x29,0xda, +	0xbd,0x1b,0xd7,0xa4,0xbf,0xef,0x60,0x2d,0x22,0xca, +	0x65,0x98,0xf1,0xc4,0xe1,0xc9,0x02,0x6b,0x16,0x28, +	0x2f,0xa1,0xaa,0x79,0x00,0xda,0xdc,0x7c,0x43,0xf7, +	0x42,0x3c,0xa0,0xef,0x68,0xf7,0xdf,0xb9,0x69,0xfb, +	0x8e,0x01,0xed,0x01,0x42,0xb5,0x4e,0x57,0xa6,0x26, +	0xb8,0xd0,0x7b,0x56,0x6d,0x03,0xc6,0x40,0x8c,0x8c, +	0x2a,0x55,0xd7,0x9c,0x35,0x00,0x94,0x93,0xec,0x03, +	0xeb,0x22,0xef,0x77,0xbb,0x79,0x13,0x3f,0x15,0xa1, +	0x8f,0xca,0xdf,0xfd,0xd3,0xb8,0xe1,0xd4,0xcc,0x09, +	0x3f,0x3c,0x2c,0xdb,0xd1,0x49,0x7f,0x38,0x07,0x83, +	0x6d,0xeb,0x08,0x66,0xe9,0x06,0x44,0x12,0xac,0x95, +	0x22,0x90,0x23,0x67,0xd4,0x08,0xcc,0xf4,0xb7,0xdc, +	0xcc,0x87,0xd4,0xac,0x69,0x35,0x4c,0xb5,0x39,0x36, +	0xcd,0xa4,0xd2,0x95,0xca,0x0d,0xc5,0xda,0xc2,0xc5, +	0x22,0x32,0x28,0x08,0xe3,0xd2,0x8b,0x38,0x30,0xdc, +	0x8c,0x75,0x4f,0x6a,0xec,0x7a,0xac,0x16,0x3e,0xa8, +	0xd4,0x6a,0x45,0xe1,0xa8,0x4f,0x2e,0x80,0x34,0xaa, +	0x54,0x1b,0x02,0x95,0x7d,0x8a,0x6d,0xcc,0x79,0xca, +	0xf2,0xa4,0x2e,0x8d,0xfb,0xfe,0x15,0x51,0x10,0x0e, +	0x4d,0x88,0xb1,0xc7,0xf4,0x79,0xdb,0xf0,0xb4,0x56, +	0x44,0x37,0xca,0x5a,0xc1,0x8c,0x48,0xac,0xae,0x48, +	0x80,0x83,0x01,0x3f,0xde,0xd9,0xd3,0x2c,0x51,0x46, +	0xb1,0x41,0xb6,0xc6,0x91,0x72,0xf9,0x83,0x55,0x1b, +	0x8c,0xba,0xf3,0x73,0xe5,0x2c,0x74,0x50,0x3a,0xbe, +	0xc5,0x2f,0xa7,0xb2,0x6d,0x8c,0x9e,0x13,0x77,0xa3, +	0x13,0xcd,0x6d,0x8c,0x45,0xe1,0xfc,0x0b,0xb7,0x69, +	0xe9,0x27,0xbc,0x65,0xc3,0xfa,0x9b,0xd0,0xef,0xfe, +	0xe8,0x1f,0xb3,0x5e,0x34,0xf4,0x8c,0xea,0xfc,0xd3, +	0x81,0xbf,0x3d,0x30,0xb2,0xb4,0x01,0xe8,0x43,0x0f, +	0xba,0x02,0x23,0x42,0x76,0x82,0x31,0x73,0x91,0xed, +	0x07,0x46,0x61,0x0d,0x39,0x83,0x40,0xce,0x7a,0xd4, +	0xdb,0x80,0x2c,0x1f,0x0d,0xd1,0x34,0xd4,0x92,0xe3, +	0xd4,0xf1,0xc2,0x01,0x02,0x03,0x01,0x00,0x01,0x02, +	0x82,0x02,0x01,0x00,0x97,0x6c,0xda,0x6e,0xea,0x4f, +	0xcf,0xaf,0xf7,0x4c,0xd9,0xf1,0x90,0x00,0x77,0xdb, +	0xf2,0x97,0x76,0x72,0xb9,0xb7,0x47,0xd1,0x9c,0xdd, +	0xcb,0x4a,0x33,0x6e,0xc9,0x75,0x76,0xe6,0xe4,0xa5, +	0x31,0x8c,0x77,0x13,0xb4,0x29,0xcd,0xf5,0x52,0x17, +	0xef,0xf3,0x08,0x00,0xe3,0xbd,0x2e,0xbc,0xd4,0x52, +	0x88,0xe9,0x30,0x75,0x0b,0x02,0xf5,0xcd,0x89,0x0c, +	0x6c,0x57,0x19,0x27,0x3d,0x1e,0x85,0xb4,0xc1,0x2f, +	0x1d,0x92,0x00,0x5c,0x76,0x29,0x4b,0xa4,0xe1,0x12, +	0xb3,0xc8,0x09,0xfe,0x0e,0x78,0x72,0x61,0xcb,0x61, +	0x6f,0x39,0x91,0x95,0x4e,0xd5,0x3e,0xc7,0x8f,0xb8, +	0xf6,0x36,0xfe,0x9c,0x93,0x9a,0x38,0x25,0x7a,0xf4, +	0x4a,0x12,0xd4,0xa0,0x13,0xbd,0xf9,0x1d,0x12,0x3e, +	0x21,0x39,0xfb,0x72,0xe0,0x05,0x3d,0xc3,0xe5,0x50, +	0xa8,0x5d,0x85,0xa3,0xea,0x5f,0x1c,0xb2,0x3f,0xea, +	0x6d,0x03,0x91,0x55,0xd8,0x19,0x0a,0x21,0x12,0x16, +	0xd9,0x12,0xc4,0xe6,0x07,0x18,0x5b,0x26,0xa4,0xae, +	0xed,0x2b,0xb7,0xa6,0xed,0xf8,0xad,0xec,0x77,0xe6, +	0x7f,0x4f,0x76,0x00,0xc0,0xfa,0x15,0x92,0xb4,0x2c, +	0x22,0xc2,0xeb,0x6a,0xad,0x14,0x05,0xb2,0xe5,0x8a, +	0x9e,0x85,0x83,0xcc,0x04,0xf1,0x56,0x78,0x44,0x5e, +	0xde,0xe0,0x60,0x1a,0x65,0x79,0x31,0x23,0x05,0xbb, +	0x01,0xff,0xdd,0x2e,0xb7,0xb3,0xaa,0x74,0xe0,0xa5, +	0x94,0xaf,0x4b,0xde,0x58,0x0f,0x55,0xde,0x33,0xf6, +	0xe3,0xd6,0x34,0x36,0x57,0xd6,0x79,0x91,0x2e,0xbe, +	0x3b,0xd9,0x4e,0xb6,0x9d,0x21,0x5c,0xd3,0x48,0x14, +	0x7f,0x4a,0xc4,0x60,0xa9,0x29,0xf8,0x53,0x7f,0x88, +	0x11,0x2d,0xb5,0xc5,0x2d,0x6f,0xee,0x85,0x0b,0xf7, +	0x8d,0x9a,0xbe,0xb0,0x42,0xf2,0x2e,0x71,0xaf,0x19, +	0x31,0x6d,0xec,0xcd,0x6f,0x2b,0x23,0xdf,0xb4,0x40, +	0xaf,0x2c,0x0a,0xc3,0x1b,0x7d,0x7d,0x03,0x1d,0x4b, +	0xf3,0xb5,0xe0,0x85,0xd8,0xdf,0x91,0x6b,0x0a,0x69, +	0xf7,0xf2,0x69,0x66,0x5b,0xf1,0xcf,0x46,0x7d,0xe9, +	0x70,0xfa,0x6d,0x7e,0x75,0x4e,0xa9,0x77,0xe6,0x8c, +	0x02,0xf7,0x14,0x4d,0xa5,0x41,0x8f,0x3f,0xc1,0x62, +	0x1e,0x71,0x5e,0x38,0xb4,0xd6,0xe6,0xe1,0x4b,0xc2, +	0x2c,0x30,0x83,0x81,0x6f,0x49,0x2e,0x96,0xe6,0xc9, +	0x9a,0xf7,0x5d,0x09,0xa0,0x55,0x02,0xa5,0x3a,0x25, +	0x23,0xd0,0x92,0xc3,0xa3,0xe3,0x0e,0x12,0x2f,0x4d, +	0xef,0xf3,0x55,0x5a,0xbe,0xe6,0x19,0x86,0x31,0xab, +	0x75,0x9a,0xd3,0xf0,0x2c,0xc5,0x41,0x92,0xd9,0x1f, +	0x5f,0x11,0x8c,0x75,0x1c,0x63,0xd0,0x02,0x80,0x2c, +	0x68,0xcb,0x93,0xfb,0x51,0x73,0x49,0xb4,0x60,0xda, +	0xe2,0x26,0xaf,0xa9,0x46,0x12,0xb8,0xec,0x50,0xdd, +	0x12,0x06,0x5f,0xce,0x59,0xe6,0xf6,0x1c,0xe0,0x54, +	0x10,0xad,0xf6,0xcd,0x98,0xcc,0x0f,0xfb,0xcb,0x41, +	0x14,0x9d,0xed,0xe4,0xb4,0x74,0x5f,0x09,0x60,0xc7, +	0x12,0xf6,0x7b,0x3c,0x8f,0xa7,0x20,0xbc,0xe4,0xb1, +	0xef,0xeb,0xa4,0x93,0xc5,0x06,0xca,0x9a,0x27,0x9d, +	0x87,0xf3,0xde,0xca,0xe5,0xe7,0xf6,0x1c,0x01,0x65, +	0x5b,0xfb,0x19,0x79,0x6e,0x08,0x26,0xc5,0xc8,0x28, +	0x0e,0xb6,0x3b,0x07,0x08,0xc1,0x02,0x82,0x01,0x01, +	0x00,0xe8,0x1c,0x73,0xa6,0xb8,0xe0,0x0e,0x6d,0x8d, +	0x1b,0xb9,0x53,0xed,0x58,0x94,0xe6,0x1d,0x60,0x14, +	0x5c,0x76,0x43,0xc4,0x58,0x19,0xc4,0x24,0xe8,0xbc, +	0x1b,0x3b,0x0b,0x13,0x24,0x45,0x54,0x0e,0xcc,0x37, +	0xf0,0xe0,0x63,0x7d,0xc3,0xf7,0xfb,0x81,0x74,0x81, +	0xc4,0x0f,0x1a,0x21,0x48,0xaf,0xce,0xc1,0xc4,0x94, +	0x18,0x06,0x44,0x8d,0xd3,0xd2,0x22,0x2d,0x2d,0x3e, +	0x5a,0x31,0xdc,0x95,0x8e,0xf4,0x41,0xfc,0x58,0xc9, +	0x40,0x92,0x17,0x5f,0xe3,0xda,0xac,0x9e,0x3f,0x1c, +	0x2a,0x6b,0x58,0x5f,0x48,0x78,0x20,0xb1,0xaf,0x24, +	0x9b,0x3c,0x20,0x8b,0x93,0x25,0x9e,0xe6,0x6b,0xbc, +	0x13,0x42,0x14,0x6c,0x36,0x31,0xff,0x7a,0xd1,0xc1, +	0x1a,0x26,0x14,0x7f,0xa9,0x76,0xa7,0x0c,0xf8,0xcc, +	0xed,0x07,0x6a,0xd2,0xdf,0x62,0xee,0x0a,0x7c,0x84, +	0xcb,0x49,0x90,0xb2,0x03,0x0d,0xa2,0x82,0x06,0x77, +	0xf1,0xcd,0x67,0xf2,0x47,0x21,0x02,0x3f,0x43,0x21, +	0xf0,0x46,0x30,0x62,0x51,0x72,0xb1,0xe7,0x48,0xc6, +	0x67,0x12,0xcd,0x9e,0xd6,0x15,0xe5,0x21,0xed,0xfa, +	0x8f,0x30,0xa6,0x41,0xfe,0xb6,0xfa,0x8f,0x34,0x14, +	0x19,0xe8,0x11,0xf7,0xa5,0x77,0x3e,0xb7,0xf9,0x39, +	0x07,0x8c,0x67,0x2a,0xab,0x7b,0x08,0xf8,0xb0,0x06, +	0xa8,0xea,0x2f,0x8f,0xfa,0xcc,0xcc,0x40,0xce,0xf3, +	0x70,0x4f,0x3f,0x7f,0xe2,0x0c,0xea,0x76,0x4a,0x35, +	0x4e,0x47,0xad,0x2b,0xa7,0x97,0x5d,0x74,0x43,0x97, +	0x90,0xd2,0xfb,0xd9,0xf9,0x96,0x01,0x33,0x05,0xed, +	0x7b,0x03,0x05,0xad,0xf8,0x49,0x03,0x02,0x82,0x01, +	0x01,0x00,0xd4,0x40,0x17,0x66,0x10,0x92,0x95,0xc8, +	0xec,0x62,0xa9,0x7a,0xcb,0x93,0x8e,0xe6,0x53,0xd4, +	0x80,0x48,0x27,0x4b,0x41,0xce,0x61,0xdf,0xbf,0x94, +	0xa4,0x3d,0x71,0x03,0x0b,0xed,0x25,0x71,0x98,0xa4, +	0xd6,0xd5,0x4a,0x57,0xf5,0x6c,0x1b,0xda,0x21,0x7d, +	0x35,0x45,0xb3,0xf3,0x6a,0xd9,0xd3,0x43,0xe8,0x5c, +	0x54,0x1c,0x83,0x1b,0xb4,0x5f,0xf2,0x97,0x24,0x2e, +	0xdc,0x40,0xde,0x92,0x23,0x59,0x8e,0xbc,0xd2,0xa1, +	0xf2,0xe0,0x4c,0xdd,0x0b,0xd1,0xe7,0xae,0x65,0xbc, +	0xb5,0xf5,0x5b,0x98,0xe9,0xd7,0xc2,0xb7,0x0e,0x55, +	0x71,0x0e,0x3c,0x0a,0x24,0x6b,0xa6,0xe6,0x14,0x61, +	0x11,0xfd,0x33,0x42,0x99,0x2b,0x84,0x77,0x74,0x92, +	0x91,0xf5,0x79,0x79,0xcf,0xad,0x8e,0x04,0xef,0x80, +	0x1e,0x57,0xf4,0x14,0xf5,0x35,0x09,0x74,0xb2,0x13, +	0x71,0x58,0x6b,0xea,0x32,0x5d,0xf3,0xd3,0x76,0x48, +	0x39,0x10,0x23,0x84,0x9d,0xbe,0x92,0x77,0x4a,0xed, +	0x70,0x3e,0x1a,0xa2,0x6c,0xb3,0x81,0x00,0xc3,0xc9, +	0xe4,0x52,0xc8,0x24,0x88,0x0c,0x41,0xad,0x87,0x5a, +	0xea,0xa3,0x7a,0x85,0x1c,0x5e,0x31,0x7f,0xc3,0x35, +	0xc6,0xfa,0x10,0xc8,0x75,0x10,0xc4,0x96,0x99,0xe7, +	0xfe,0x01,0xb4,0x74,0xdb,0xb4,0x11,0xc3,0xc8,0x8c, +	0xf6,0xf7,0x3b,0x66,0x50,0xfc,0xdb,0xeb,0xca,0x47, +	0x85,0x89,0xe1,0x65,0xd9,0x62,0x34,0x3c,0x70,0xd8, +	0x2e,0xb4,0x2f,0x65,0x3c,0x4a,0xa6,0x2a,0xe7,0xc7, +	0xd8,0x41,0x8f,0x8a,0x43,0xbf,0x42,0xf2,0x4d,0xbc, +	0xfc,0x9e,0x27,0x95,0xfb,0x75,0xff,0xab,0x02,0x82, +	0x01,0x00,0x41,0x2f,0x44,0x57,0x6d,0x12,0x17,0x5b, +	0x32,0xc6,0xb7,0x6c,0x57,0x7a,0x8a,0x0e,0x79,0xef, +	0x72,0xa8,0x68,0xda,0x2d,0x38,0xe4,0xbb,0x8d,0xf6, +	0x02,0x65,0xcf,0x56,0x13,0xe1,0x1a,0xcb,0x39,0x80, +	0xa6,0xb1,0x32,0x03,0x1e,0xdd,0xbb,0x35,0xd9,0xac, +	0x43,0x89,0x31,0x08,0x90,0x92,0x5e,0x35,0x3d,0x7b, +	0x9c,0x6f,0x86,0xcb,0x17,0xdd,0x85,0xe4,0xed,0x35, +	0x08,0x8e,0xc1,0xf4,0x05,0xd8,0x68,0xc6,0x63,0x3c, +	0xf7,0xff,0xf7,0x47,0x33,0x39,0xc5,0x3e,0xb7,0x0e, +	0x58,0x35,0x9d,0x81,0xea,0xf8,0x6a,0x2c,0x1c,0x5a, +	0x68,0x78,0x64,0x11,0x6b,0xc1,0x3e,0x4e,0x7a,0xbd, +	0x84,0xcb,0x0f,0xc2,0xb6,0x85,0x1d,0xd3,0x76,0xc5, +	0x93,0x6a,0x69,0x89,0x56,0x34,0xdc,0x4a,0x9b,0xbc, +	0xff,0xa8,0x0d,0x6e,0x35,0x9c,0x60,0xa7,0x23,0x30, +	0xc7,0x06,0x64,0x39,0x8b,0x94,0x89,0xee,0xba,0x7f, +	0x60,0x8d,0xfa,0xb6,0x97,0x76,0xdc,0x51,0x4a,0x3c, +	0xeb,0x3a,0x14,0x2c,0x20,0x60,0x69,0x4a,0x86,0xfe, +	0x8c,0x21,0x84,0x49,0x54,0xb3,0x20,0xe1,0x01,0x7f, +	0x58,0xdf,0x7f,0xb5,0x21,0x51,0x8c,0x47,0x9f,0x91, +	0xeb,0x97,0x3e,0xf2,0x54,0xcf,0x16,0x46,0xf9,0xd9, +	0xb6,0xe7,0x64,0xc9,0xd0,0x54,0xea,0x2f,0xa1,0xcf, +	0xa5,0x7f,0x28,0x8d,0x84,0xec,0xd5,0x39,0x03,0x76, +	0x5b,0x2d,0x8e,0x43,0xf2,0x01,0x24,0xc9,0x6f,0xc0, +	0xf5,0x69,0x6f,0x7d,0xb5,0x85,0xd2,0x5f,0x7f,0x78, +	0x40,0x07,0x7f,0x09,0x15,0xb5,0x1f,0x28,0x65,0x10, +	0xe4,0x19,0xa8,0xc6,0x9e,0x8d,0xdc,0xcb,0x02,0x82, +	0x01,0x00,0x13,0x01,0xee,0x56,0x80,0x93,0x70,0x00, +	0x7f,0x52,0xd2,0x94,0xa1,0x98,0x84,0x4a,0x92,0x25, +	0x4c,0x9b,0xa9,0x91,0x2e,0xc2,0x79,0xb7,0x5c,0xe3, +	0xc5,0xd5,0x8e,0xc2,0x54,0x16,0x17,0xad,0x55,0x9b, +	0x25,0x76,0x12,0x63,0x50,0x22,0x2f,0x58,0x58,0x79, +	0x6b,0x04,0xe3,0xf9,0x9f,0x8f,0x04,0x41,0x67,0x94, +	0xa5,0x1f,0xac,0x8a,0x15,0x9c,0x26,0x10,0x6c,0xf8, +	0x19,0x57,0x61,0xd7,0x3a,0x7d,0x31,0xb0,0x2d,0x38, +	0xbd,0x94,0x62,0xad,0xc4,0xfa,0x36,0x42,0x42,0xf0, +	0x24,0x67,0x65,0x9d,0x8b,0x0b,0x7c,0x6f,0x82,0x44, +	0x1a,0x8c,0xc8,0xc9,0xab,0xbb,0x4c,0x45,0xfc,0x7b, +	0x38,0xee,0x30,0xe1,0xfc,0xef,0x8d,0xbc,0x58,0xdf, +	0x2b,0x5d,0x0d,0x54,0xe0,0x49,0x4d,0x97,0x99,0x8f, +	0x22,0xa8,0x83,0xbe,0x40,0xbb,0x50,0x2e,0x78,0x28, +	0x0f,0x95,0x78,0x8c,0x8f,0x98,0x24,0x56,0xc2,0x97, +	0xf3,0x2c,0x43,0xd2,0x03,0x82,0x66,0x81,0x72,0x5f, +	0x53,0x16,0xec,0xb1,0xb1,0x04,0x5e,0x40,0x20,0x48, +	0x7b,0x3f,0x02,0x97,0x6a,0xeb,0x96,0x12,0x21,0x35, +	0xfe,0x1f,0x47,0xc0,0x95,0xea,0xc5,0x8a,0x08,0x84, +	0x4f,0x5e,0x63,0x94,0x60,0x0f,0x71,0x5b,0x7f,0x4a, +	0xec,0x4f,0x60,0xc6,0xba,0x4a,0x24,0xf1,0x20,0x8b, +	0xa7,0x2e,0x3a,0xce,0x8d,0xe0,0x27,0x1d,0xb5,0x8e, +	0xb4,0x21,0xc5,0xe2,0xa6,0x16,0x0a,0x51,0x83,0x55, +	0x88,0xd1,0x30,0x11,0x63,0xd5,0xd7,0x8d,0xae,0x16, +	0x12,0x82,0xc4,0x85,0x00,0x4e,0x27,0x83,0xa5,0x7c, +	0x90,0x2e,0xe5,0xa2,0xa3,0xd3,0x4c,0x63,0x02,0x82, +	0x01,0x01,0x00,0x86,0x08,0x98,0x98,0xa5,0x00,0x05, +	0x39,0x77,0xd9,0x66,0xb3,0xcf,0xca,0xa0,0x71,0xb3, +	0x50,0xce,0x3d,0xb1,0x93,0x95,0x35,0xc4,0xd4,0x2e, +	0x90,0xdf,0x0f,0xfc,0x60,0xc1,0x94,0x68,0x61,0x43, +	0xca,0x9a,0x23,0x4a,0x1e,0x45,0x72,0x99,0xb5,0x1e, +	0x61,0x8d,0x77,0x0f,0xa0,0xbb,0xd7,0x77,0xb4,0x2a, +	0x15,0x11,0x88,0x2d,0xb3,0x56,0x61,0x5e,0x6a,0xed, +	0xa4,0x46,0x4a,0x3f,0x50,0x11,0xd6,0xba,0xb6,0xd7, +	0x95,0x65,0x53,0xc3,0xa1,0x8f,0xe0,0xa3,0xf5,0x1c, +	0xfd,0xaf,0x6e,0x43,0xd7,0x17,0xa7,0xd3,0x81,0x1b, +	0xa4,0xdf,0xe0,0x97,0x8a,0x46,0x03,0xd3,0x46,0x0e, +	0x83,0x48,0x4e,0xd2,0x02,0xcb,0xc0,0xad,0x79,0x95, +	0x8c,0x96,0xba,0x40,0x34,0x11,0x71,0x5e,0xe9,0x11, +	0xf9,0xc5,0x4a,0x5e,0x91,0x9d,0xf5,0x92,0x4f,0xeb, +	0xc6,0x70,0x02,0x2d,0x3d,0x04,0xaa,0xe9,0x3a,0x8e, +	0xd5,0xa8,0xad,0xf7,0xce,0x0d,0x16,0xb2,0xec,0x0a, +	0x9c,0xf5,0x94,0x39,0xb9,0x8a,0xfc,0x1e,0xf9,0xcc, +	0xf2,0x5f,0x21,0x31,0x74,0x72,0x6b,0x64,0xae,0x35, +	0x61,0x8d,0x0d,0xcb,0xe7,0xda,0x39,0xca,0xf3,0x21, +	0x66,0x0b,0x95,0xd7,0x0a,0x7c,0xca,0xa1,0xa9,0x5a, +	0xe8,0xac,0xe0,0x71,0x54,0xaf,0x28,0xcf,0xd5,0x70, +	0x89,0xe0,0xf3,0x9e,0x43,0x6c,0x8d,0x7b,0x99,0x01, +	0x68,0x4d,0xa1,0x45,0x46,0x0c,0x43,0xbc,0xcc,0x2c, +	0xdd,0xc5,0x46,0xc8,0x4e,0x0e,0xbe,0xed,0xb9,0x26, +	0xab,0x2e,0xdb,0xeb,0x8f,0xff,0xdb,0xb0,0xc6,0x55, +	0xaf,0xf8,0x2a,0x91,0x9d,0x50,0x44,0x21,0x17, +	}; diff --git a/main/openssl/apps/timeouts.h b/main/openssl/apps/timeouts.h new file mode 100644 index 00000000..89b5dc76 --- /dev/null +++ b/main/openssl/apps/timeouts.h @@ -0,0 +1,67 @@ +/* apps/timeouts.h */ +/*  + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.   + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef INCLUDED_TIMEOUTS_H +#define INCLUDED_TIMEOUTS_H + +/* numbers in us */ +#define DGRAM_RCV_TIMEOUT         250000 +#define DGRAM_SND_TIMEOUT         250000 + +#endif /* ! INCLUDED_TIMEOUTS_H */ diff --git a/main/openssl/apps/verify.c b/main/openssl/apps/verify.c new file mode 100644 index 00000000..9163997e --- /dev/null +++ b/main/openssl/apps/verify.c @@ -0,0 +1,350 @@ +/* apps/verify.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + *  + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to.  The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + *  + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + *  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *    "This product includes cryptographic software written by + *     Eric Young (eay@cryptsoft.com)" + *    The word 'cryptographic' can be left out if the rouines from the library + *    being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from  + *    the apps directory (application code) you must include an acknowledgement: + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + *  + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *  + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed.  i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/pem.h> + +#undef PROG +#define PROG	verify_main + +static int MS_CALLBACK 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); +static int v_verbose=0, vflags = 0; + +int MAIN(int, char **); + +int 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_VERIFY_PARAM *vpm = NULL; +#ifndef OPENSSL_NO_ENGINE +	char *engine=NULL; +#endif + +	cert_ctx=X509_STORE_new(); +	if (cert_ctx == 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; + +	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); +				} +#ifndef OPENSSL_NO_ENGINE +			else if (strcmp(*argv,"-engine") == 0) +				{ +				if (--argc < 1) goto end; +				engine= *(++argv); +				} +#endif +			else if (strcmp(*argv,"-help") == 0) +				goto end; +			else if (strcmp(*argv,"-verbose") == 0) +				v_verbose=1; +			else if (argv[0][0] == '-') +				goto end; +			else +				break; +			argc--; +			argv++; +			} +		else +			break; +		} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	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); + +	ERR_clear_error(); + +	if(untfile) +		{ +		untrusted = load_certs(bio_err, untfile, FORMAT_PEM, +					NULL, e, "untrusted certificates"); +		if(!untrusted) +			goto end; +		} + +	if(trustfile) +		{ +		trusted = load_certs(bio_err, 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"); +		if(!crls) +			goto end; +		} + +	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e); +	else +		for (i=0; i<argc; i++) +			check(cert_ctx,argv[i], untrusted, trusted, crls, e); +	ret=0; +end: +	if (ret == 1) { +		BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); +#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)); +		} +	} +	if (vpm) X509_VERIFY_PARAM_free(vpm); +	if (cert_ctx != NULL) X509_STORE_free(cert_ctx); +	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); +	} + +static int check(X509_STORE *ctx, char *file, +		STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, +		STACK_OF(X509_CRL) *crls, ENGINE *e) +	{ +	X509 *x=NULL; +	int i=0,ret=0; +	X509_STORE_CTX *csc; + +	x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file"); +	if (x == NULL) +		goto end; +	fprintf(stdout,"%s: ",(file == NULL)?"stdin":file); + +	csc = X509_STORE_CTX_new(); +	if (csc == NULL) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} +	X509_STORE_set_flags(ctx, vflags); +	if(!X509_STORE_CTX_init(csc,ctx,x,uchain)) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} +	if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain); +	if (crls) +		X509_STORE_CTX_set0_crls(csc, crls); +	i=X509_verify_cert(csc); +	X509_STORE_CTX_free(csc); + +	ret=0; +end: +	if (i > 0) +		{ +		fprintf(stdout,"OK\n"); +		ret=1; +		} +	else +		ERR_print_errors(bio_err); +	if (x != NULL) X509_free(x); + +	return(ret); +	} + +static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) +	{ +	int cert_error = X509_STORE_CTX_get_error(ctx); +	X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); + +	if (!ok) +		{ +		if (current_cert) +			{ +			X509_NAME_print_ex_fp(stdout, +				X509_get_subject_name(current_cert), +				0, XN_FLAG_ONELINE); +			printf("\n"); +			} +		printf("%serror %d at %d depth lookup:%s\n", +			X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "", +			cert_error, +			X509_STORE_CTX_get_error_depth(ctx), +			X509_verify_cert_error_string(cert_error)); +		switch(cert_error) +			{ +			case X509_V_ERR_NO_EXPLICIT_POLICY: +				policies_print(NULL, ctx); +			case X509_V_ERR_CERT_HAS_EXPIRED: + +			/* since we are just checking the certificates, it is +			 * ok if they are self signed. But we should still warn +			 * the user. +			 */ + +			case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: +			/* Continue after extension errors too */ +			case X509_V_ERR_INVALID_CA: +			case X509_V_ERR_INVALID_NON_CA: +			case X509_V_ERR_PATH_LENGTH_EXCEEDED: +			case X509_V_ERR_INVALID_PURPOSE: +			case X509_V_ERR_CRL_HAS_EXPIRED: +			case X509_V_ERR_CRL_NOT_YET_VALID: +			case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: +			ok = 1; + +			} + +		return ok; + +		} +	if (cert_error == X509_V_OK && ok == 2) +		policies_print(NULL, ctx); +	if (!v_verbose) +		ERR_clear_error(); +	return(ok); +	} diff --git a/main/openssl/apps/version.c b/main/openssl/apps/version.c new file mode 100644 index 00000000..e9555cbd --- /dev/null +++ b/main/openssl/apps/version.c @@ -0,0 +1,217 @@ +/* apps/version.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.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "apps.h" +#include <openssl/evp.h> +#include <openssl/crypto.h> +#include <openssl/bn.h> +#ifndef OPENSSL_NO_MD2 +# include <openssl/md2.h> +#endif +#ifndef OPENSSL_NO_RC4 +# include <openssl/rc4.h> +#endif +#ifndef OPENSSL_NO_DES +# include <openssl/des.h> +#endif +#ifndef OPENSSL_NO_IDEA +# include <openssl/idea.h> +#endif +#ifndef OPENSSL_NO_BF +# include <openssl/blowfish.h> +#endif + +#undef PROG +#define PROG	version_main + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	int i,ret=0; +	int cflags=0,version=0,date=0,options=0,platform=0,dir=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 (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; +			goto end; +			} +		} + +	if (version) +		{ +		if (SSLeay() == SSLEAY_VERSION_NUMBER) +			{ +			printf("%s\n",SSLeay_version(SSLEAY_VERSION)); +			} +		else +			{ +			printf("%s (Library: %s)\n", +				OPENSSL_VERSION_TEXT, +				SSLeay_version(SSLEAY_VERSION)); +			} +		} +	if (date)    printf("%s\n",SSLeay_version(SSLEAY_BUILT_ON)); +	if (platform) printf("%s\n",SSLeay_version(SSLEAY_PLATFORM)); +	if (options)  +		{ +		printf("options:  "); +		printf("%s ",BN_options()); +#ifndef OPENSSL_NO_MD2 +		printf("%s ",MD2_options()); +#endif +#ifndef OPENSSL_NO_RC4 +		printf("%s ",RC4_options()); +#endif +#ifndef OPENSSL_NO_DES +		printf("%s ",DES_options()); +#endif +#ifndef OPENSSL_NO_IDEA +		printf("%s ",idea_options()); +#endif +#ifndef OPENSSL_NO_BF +		printf("%s ",BF_options()); +#endif +		printf("\n"); +		} +	if (cflags)  printf("%s\n",SSLeay_version(SSLEAY_CFLAGS)); +	if (dir)  printf("%s\n",SSLeay_version(SSLEAY_DIR)); +end: +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} diff --git a/main/openssl/apps/winrand.c b/main/openssl/apps/winrand.c new file mode 100644 index 00000000..59bede3d --- /dev/null +++ b/main/openssl/apps/winrand.c @@ -0,0 +1,148 @@ +/* apps/winrand.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.  + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Usage: winrand [filename] + * + * Collects entropy from mouse movements and other events and writes + * random data to filename or .rnd + */ + +#include <windows.h> +#include <openssl/opensslv.h> +#include <openssl/rand.h> + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +const char *filename; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, +        PSTR cmdline, int iCmdShow) +	{ +	static char appname[] = "OpenSSL"; +	HWND hwnd; +	MSG msg; +	WNDCLASSEX wndclass; +        char buffer[200]; + +        if (cmdline[0] == '\0') +                filename = RAND_file_name(buffer, sizeof buffer); +        else +                filename = cmdline; + +        RAND_load_file(filename, -1); + +	wndclass.cbSize = sizeof(wndclass); +	wndclass.style = CS_HREDRAW | CS_VREDRAW; +	wndclass.lpfnWndProc = WndProc; +	wndclass.cbClsExtra = 0; +	wndclass.cbWndExtra = 0; +	wndclass.hInstance = hInstance; +	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); +	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); +	wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); +	wndclass.lpszMenuName = NULL; +        wndclass.lpszClassName = appname; +	wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); +	RegisterClassEx(&wndclass); + +        hwnd = CreateWindow(appname, OPENSSL_VERSION_TEXT, +		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, +		CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); + +	ShowWindow(hwnd, iCmdShow); +	UpdateWindow(hwnd); + + +	while (GetMessage(&msg, NULL, 0, 0)) +		{ +		TranslateMessage(&msg); +		DispatchMessage(&msg); +		} + +	return msg.wParam; +	} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) +	{ +        HDC hdc; +	PAINTSTRUCT ps; +        RECT rect; +        static int seeded = 0; + +	switch (iMsg) +		{ +	case WM_PAINT: +		hdc = BeginPaint(hwnd, &ps); +		GetClientRect(hwnd, &rect); +                DrawText(hdc, "Seeding the PRNG. Please move the mouse!", -1, +			&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); +		EndPaint(hwnd, &ps); +		return 0; +		 +        case WM_DESTROY: +                PostQuitMessage(0); +                return 0; +                } + +        if (RAND_event(iMsg, wParam, lParam) == 1 && seeded == 0) +                { +                seeded = 1; +                if (RAND_write_file(filename) <= 0) +                        MessageBox(hwnd, "Couldn't write random file!", +				"OpenSSL", MB_OK | MB_ICONERROR); +                PostQuitMessage(0); +                } + +	return DefWindowProc(hwnd, iMsg, wParam, lParam); +	} diff --git a/main/openssl/apps/x509.c b/main/openssl/apps/x509.c new file mode 100644 index 00000000..ed1e8c69 --- /dev/null +++ b/main/openssl/apps/x509.c @@ -0,0 +1,1292 @@ +/* apps/x509.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 <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef OPENSSL_NO_STDIO +#define APPS_WIN16 +#endif +#include "apps.h" +#include <openssl/bio.h> +#include <openssl/asn1.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/objects.h> +#include <openssl/pem.h> +#ifndef OPENSSL_NO_RSA +#include <openssl/rsa.h> +#endif +#ifndef OPENSSL_NO_DSA +#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", +NULL +}; + +static int MS_CALLBACK 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); +static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest, +			 X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial, +			 int create,int days, int clrext, CONF *conf, char *section, +						ASN1_INTEGER *sno); +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); +static int reqfile=0; + +int MAIN(int, char **); + +int MAIN(int argc, char **argv) +	{ +	ENGINE *e = NULL; +	int ret=1; +	X509_REQ *req=NULL; +	X509 *x=NULL,*xca=NULL; +	ASN1_OBJECT *objtmp; +	EVP_PKEY *Upkey=NULL,*CApkey=NULL; +	ASN1_INTEGER *sno = NULL; +	int i,num,badops=0; +	BIO *out=NULL; +	BIO *STDout=NULL; +	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; +	int informat,outformat,keyformat,CAformat,CAkeyformat; +	char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL; +	char *CAkeyfile=NULL,*CAserial=NULL; +	char *alias=NULL; +	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; +#ifndef OPENSSL_NO_ENGINE +	char *engine=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); +	} +#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,"-days") == 0) +			{ +			if (--argc < 1) goto bad; +			days=atoi(*(++argv)); +			if (days == 0) +				{ +				BIO_printf(STDout,"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); +			sign_flag= ++num; +			need_rand = 1; +			} +		else if (strcmp(*argv,"-CA") == 0) +			{ +			if (--argc < 1) goto bad; +			CAfile= *(++argv); +			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,"-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; +				} +			if (!trust) trust = sk_ASN1_OBJECT_new_null(); +			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))) +				{ +				BIO_printf(bio_err, +					"Invalid reject object value %s\n", *argv); +				goto bad; +				} +			if (!reject) reject = sk_ASN1_OBJECT_new_null(); +			sk_ASN1_OBJECT_push(reject, objtmp); +			trustout = 1; +			} +		else if (strcmp(*argv,"-setalias") == 0) +			{ +			if (--argc < 1) goto bad; +			alias= *(++argv); +			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) +			C= ++num; +		else if (strcmp(*argv,"-email") == 0) +			email= ++num; +		else if (strcmp(*argv,"-ocsp_uri") == 0) +			ocsp_uri= ++num; +		else if (strcmp(*argv,"-serial") == 0) +			serial= ++num; +		else if (strcmp(*argv,"-next_serial") == 0) +			next_serial= ++num; +		else if (strcmp(*argv,"-modulus") == 0) +			modulus= ++num; +		else if (strcmp(*argv,"-pubkey") == 0) +			pubkey= ++num; +		else if (strcmp(*argv,"-x509toreq") == 0) +			x509req= ++num; +		else if (strcmp(*argv,"-text") == 0) +			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) +			subject= ++num; +		else if (strcmp(*argv,"-issuer") == 0) +			issuer= ++num; +		else if (strcmp(*argv,"-fingerprint") == 0) +			fingerprint= ++num; +		else if (strcmp(*argv,"-dates") == 0) +			{ +			startdate= ++num; +			enddate= ++num; +			} +		else if (strcmp(*argv,"-purpose") == 0) +			pprint= ++num; +		else if (strcmp(*argv,"-startdate") == 0) +			startdate= ++num; +		else if (strcmp(*argv,"-enddate") == 0) +			enddate= ++num; +		else if (strcmp(*argv,"-checkend") == 0) +			{ +			if (--argc < 1) goto bad; +			checkoffset=atoi(*(++argv)); +			checkend=1; +			} +		else if (strcmp(*argv,"-noout") == 0) +			noout= ++num; +		else if (strcmp(*argv,"-trustout") == 0) +			trustout= 1; +		else if (strcmp(*argv,"-clrtrust") == 0) +			clrtrust= ++num; +		else if (strcmp(*argv,"-clrreject") == 0) +			clrreject= ++num; +		else if (strcmp(*argv,"-alias") == 0) +			aliasout= ++num; +		else if (strcmp(*argv,"-CAcreateserial") == 0) +			CA_createserial= ++num; +		else if (strcmp(*argv,"-clrext") == 0) +			clrext = 1; +#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */ +		else if (strcmp(*argv,"-crlext") == 0) +			{ +			BIO_printf(bio_err,"use -clrext instead of -crlext\n"); +			clrext = 1; +			} +#endif +		else if (strcmp(*argv,"-ocspid") == 0) +			ocspid= ++num; +		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; +			} +		argc--; +		argv++; +		} + +	if (badops) +		{ +bad: +		for (pp=x509_usage; (*pp != NULL); pp++) +			BIO_printf(bio_err,"%s",*pp); +		goto end; +		} + +#ifndef OPENSSL_NO_ENGINE +        e = setup_engine(bio_err, engine, 0); +#endif + +	if (need_rand) +		app_RAND_load_file(NULL, bio_err, 0); + +	ERR_load_crypto_strings(); + +	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) +		{ +		BIO_printf(bio_err, "Error getting password\n"); +		goto end; +		} + +	if (!X509_STORE_set_default_paths(ctx)) +		{ +		ERR_print_errors(bio_err); +		goto end; +		} + +	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) +		{ CAkeyfile=CAfile; } +	else if ((CA_flag) && (CAkeyfile == NULL)) +		{ +		BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n"); +		goto end; +		} + +	if (extfile) +		{ +		long errorline = -1; +		X509V3_CTX ctx2; +		extconf = NCONF_new(NULL); +		if (!NCONF_load(extconf, extfile,&errorline)) +			{ +			if (errorline <= 0) +				BIO_printf(bio_err, +					"error loading the config file '%s'\n", +								extfile); +                	else +                        	BIO_printf(bio_err, +				       "error on line %ld of config file '%s'\n" +							,errorline,extfile); +			goto end; +			} +		if (!extsect) +			{ +			extsect = NCONF_get_string(extconf, "default", "extensions"); +			if (!extsect) +				{ +				ERR_clear_error(); +				extsect = "default"; +				} +			} +		X509V3_set_ctx_test(&ctx2); +		X509V3_set_nconf(&ctx2, extconf); +		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) +			{ +			BIO_printf(bio_err, +				"Error Loading extension section %s\n", +								 extsect); +			ERR_print_errors(bio_err); +			goto end; +			} +		} + + +	if (reqfile) +		{ +		EVP_PKEY *pkey; +		BIO *in; + +		if (!sign_flag && !CA_flag) +			{ +			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); +			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); + +		if (req == NULL) +			{ +			ERR_print_errors(bio_err); +			goto end; +			} + +		if (	(req->req_info == NULL) || +			(req->req_info->pubkey == NULL) || +			(req->req_info->pubkey->public_key == NULL) || +			(req->req_info->pubkey->public_key->data == NULL)) +			{ +			BIO_printf(bio_err,"The certificate request appears to corrupted\n"); +			BIO_printf(bio_err,"It does not contain a public key\n"); +			goto end; +			} +		if ((pkey=X509_REQ_get_pubkey(req)) == NULL) +	                { +	                BIO_printf(bio_err,"error unpacking public key\n"); +	                goto end; +	                } +		i=X509_REQ_verify(req,pkey); +		EVP_PKEY_free(pkey); +		if (i < 0) +			{ +			BIO_printf(bio_err,"Signature verification error\n"); +			ERR_print_errors(bio_err); +			goto end; +			} +	        if (i == 0) +			{ +			BIO_printf(bio_err,"Signature did not match the certificate request\n"); +			goto end; +			} +		else +			BIO_printf(bio_err,"Signature ok\n"); + +		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); + +		if ((x=X509_new()) == NULL) goto end; + +		if (sno == NULL) +			{ +			sno = ASN1_INTEGER_new(); +			if (!sno || !rand_serial(NULL, sno)) +				goto end; +			if (!X509_set_serialNumber(x, sno))  +				goto end; +			ASN1_INTEGER_free(sno); +			sno = NULL; +			} +		else if (!X509_set_serialNumber(x, sno))  +			goto end; + +		if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; +		if (!X509_set_subject_name(x,req->req_info->subject)) goto end; + +		X509_gmtime_adj(X509_get_notBefore(x),0); +	        X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL); + +		pkey = X509_REQ_get_pubkey(req); +		X509_set_pubkey(x,pkey); +		EVP_PKEY_free(pkey); +		} +	else +		x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); + +	if (x == NULL) goto end; +	if (CA_flag) +		{ +		xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); +		if (xca == NULL) goto end; +		} + +	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) X509_alias_set1(x, (unsigned char *)alias, -1); + +	if (clrtrust) X509_trust_clear(x); +	if (clrreject) X509_reject_clear(x); + +	if (trust) +		{ +		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) +			{ +			objtmp = sk_ASN1_OBJECT_value(trust, i); +			X509_add1_trust_object(x, objtmp); +			} +		} + +	if (reject) +		{ +		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) +			{ +			objtmp = sk_ASN1_OBJECT_value(reject, i); +			X509_add1_reject_object(x, objtmp); +			} +		} + +	if (num) +		{ +		for (i=1; i<=num; i++) +			{ +			if (issuer == i) +				{ +				print_name(STDout, "issuer= ", +					X509_get_issuer_name(x), nmflag); +				} +			else if (subject == i)  +				{ +				print_name(STDout, "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"); +				} +			else if (next_serial == i) +				{ +				BIGNUM *bnser; +				ASN1_INTEGER *ser; +				ser = X509_get_serialNumber(x); +				bnser = ASN1_INTEGER_to_BN(ser, NULL); +				if (!bnser) +					goto end; +				if (!BN_add_word(bnser, 1)) +					goto end; +				ser = BN_to_ASN1_INTEGER(bnser, NULL); +				if (!ser) +					goto end; +				BN_free(bnser); +				i2a_ASN1_INTEGER(out, ser); +				ASN1_INTEGER_free(ser); +				BIO_puts(out, "\n"); +				} +			else if ((email == i) || (ocsp_uri == i)) +				{ +				int j; +				STACK_OF(OPENSSL_STRING) *emlst; +				if (email == i) +					emlst = X509_get1_email(x); +				else +					emlst = X509_get1_ocsp(x); +				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) +					BIO_printf(STDout, "%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); +				else BIO_puts(STDout,"<No Alias>\n"); +				} +			else if (subject_hash == i) +				{ +				BIO_printf(STDout,"%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)); +				} +#endif +			else if (issuer_hash == i) +				{ +				BIO_printf(STDout,"%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)); +				} +#endif +			else if (pprint == i) +				{ +				X509_PURPOSE *ptmp; +				int j; +				BIO_printf(STDout, "Certificate purposes:\n"); +				for (j = 0; j < X509_PURPOSE_get_count(); j++) +					{ +					ptmp = X509_PURPOSE_get0(j); +					purpose_print(STDout, x, ptmp); +					} +				} +			else +				if (modulus == i) +				{ +				EVP_PKEY *pkey; + +				pkey=X509_get_pubkey(x); +				if (pkey == NULL) +					{ +					BIO_printf(bio_err,"Modulus=unavailable\n"); +					ERR_print_errors(bio_err); +					goto end; +					} +				BIO_printf(STDout,"Modulus="); +#ifndef OPENSSL_NO_RSA +				if (pkey->type == EVP_PKEY_RSA) +					BN_print(STDout,pkey->pkey.rsa->n); +				else +#endif +#ifndef OPENSSL_NO_DSA +				if (pkey->type == EVP_PKEY_DSA) +					BN_print(STDout,pkey->pkey.dsa->pub_key); +				else +#endif +					BIO_printf(STDout,"Wrong Algorithm type"); +				BIO_printf(STDout,"\n"); +				EVP_PKEY_free(pkey); +				} +			else +				if (pubkey == i) +				{ +				EVP_PKEY *pkey; + +				pkey=X509_get_pubkey(x); +				if (pkey == NULL) +					{ +					BIO_printf(bio_err,"Error getting public key\n"); +					ERR_print_errors(bio_err); +					goto end; +					} +				PEM_write_bio_PUBKEY(STDout, pkey); +				EVP_PKEY_free(pkey); +				} +			else +				if (C == i) +				{ +				unsigned char *d; +				char *m; +				int y,z; + +				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); + +				z=i2d_X509(x,NULL); +				m=OPENSSL_malloc(z); + +				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); +				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); +				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"); + +				OPENSSL_free(m); +				} +			else if (text == i) +				{ +				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"); +				} +			else if (enddate == i) +				{ +				BIO_puts(STDout,"notAfter="); +				ASN1_TIME_print(STDout,X509_get_notAfter(x)); +				BIO_puts(STDout,"\n"); +				} +			else if (fingerprint == i) +				{ +				int j; +				unsigned int n; +				unsigned char md[EVP_MAX_MD_SIZE]; +				const EVP_MD *fdig = digest; + +				if (!fdig) +					fdig = EVP_sha1(); + +				if (!X509_digest(x,fdig,md,&n)) +					{ +					BIO_printf(bio_err,"out of memory\n"); +					goto end; +					} +				BIO_printf(STDout,"%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) +						?'\n':':'); +					} +				} + +			/* should be in the library */ +			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, +						passin, e, "Private key"); +					if (Upkey == NULL) goto end; +					} + +				assert(need_rand); +				if (!sign(x,Upkey,days,clrext,digest, +						 extconf, extsect)) goto end; +				} +			else if (CA_flag == i) +				{ +				BIO_printf(bio_err,"Getting CA Private Key\n"); +				if (CAkeyfile != NULL) +					{ +					CApkey=load_key(bio_err, +						CAkeyfile, CAkeyformat, +						0, passin, e, +						"CA Private Key"); +					if (CApkey == NULL) goto end; +					} +				 +				assert(need_rand); +				if (!x509_certify(ctx,CAfile,digest,x,xca, +					CApkey, CAserial,CA_createserial,days, clrext, +					extconf, extsect, sno)) +					goto end; +				} +			else if (x509req == i) +				{ +				EVP_PKEY *pk; + +				BIO_printf(bio_err,"Getting request Private Key\n"); +				if (keyfile == NULL) +					{ +					BIO_printf(bio_err,"no request key file specified\n"); +					goto end; +					} +				else +					{ +					pk=load_key(bio_err, +						keyfile, FORMAT_PEM, 0, +						passin, e, "request key"); +					if (pk == NULL) goto end; +					} + +				BIO_printf(bio_err,"Generating certificate request\n"); + +				rq=X509_to_X509_REQ(x,pk,digest); +				EVP_PKEY_free(pk); +				if (rq == NULL) +					{ +					ERR_print_errors(bio_err); +					goto end; +					} +				if (!noout) +					{ +					X509_REQ_print(out,rq); +					PEM_write_bio_X509_REQ(out,rq); +					} +				noout=1; +				} +			else if (ocspid == i) +				{ +				X509_ocspid_print(out, x); +				} +			} +		} + +	if (checkend) +		{ +		time_t tcheck=time(NULL) + checkoffset; + +		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) +			{ +			BIO_printf(out,"Certificate will expire\n"); +			ret=1; +			} +		else +			{ +			BIO_printf(out,"Certificate will not expire\n"); +			ret=0; +			} +		goto end; +		} + +	if (noout) +		{ +		ret=0; +		goto end; +		} + +	if 	(outformat == FORMAT_ASN1) +		i=i2d_X509_bio(out,x); +	else if (outformat == FORMAT_PEM) +		{ +		if (trustout) i=PEM_write_bio_X509_AUX(out,x); +		else i=PEM_write_bio_X509(out,x); +		} +	else if (outformat == FORMAT_NETSCAPE) +		{ +		NETSCAPE_X509 nx; +		ASN1_OCTET_STRING hdr; + +		hdr.data=(unsigned char *)NETSCAPE_CERT_HDR; +		hdr.length=strlen(NETSCAPE_CERT_HDR); +		nx.header= &hdr; +		nx.cert=x; + +		i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx); +		} +	else	{ +		BIO_printf(bio_err,"bad output format specified for outfile\n"); +		goto end; +		} +	if (!i) +		{ +		BIO_printf(bio_err,"unable to write certificate\n"); +		ERR_print_errors(bio_err); +		goto end; +		} +	ret=0; +end: +	if (need_rand) +		app_RAND_write_file(NULL, bio_err); +	OBJ_cleanup(); +	NCONF_free(extconf); +	BIO_free_all(out); +	BIO_free_all(STDout); +	X509_STORE_free(ctx); +	X509_REQ_free(req); +	X509_free(x); +	X509_free(xca); +	EVP_PKEY_free(Upkey); +	EVP_PKEY_free(CApkey); +	X509_REQ_free(rq); +	ASN1_INTEGER_free(sno); +	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); +	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); +	if (passin) OPENSSL_free(passin); +	apps_shutdown(); +	OPENSSL_EXIT(ret); +	} + +static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create) +	{ +	char *buf = NULL, *p; +	ASN1_INTEGER *bs = NULL; +	BIGNUM *serial = NULL; +	size_t len; + +	len = ((serialfile == NULL) +		?(strlen(CAfile)+strlen(POSTFIX)+1) +		:(strlen(serialfile)))+1; +	buf=OPENSSL_malloc(len); +	if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; } +	if (serialfile == NULL) +		{ +		BUF_strlcpy(buf,CAfile,len); +		for (p=buf; *p; p++) +			if (*p == '.') +				{ +				*p='\0'; +				break; +				} +		BUF_strlcat(buf,POSTFIX,len); +		} +	else +		BUF_strlcpy(buf,serialfile,len); + +	serial = load_serial(buf, create, NULL); +	if (serial == NULL) goto end; + +	if (!BN_add_word(serial,1)) +		{ BIO_printf(bio_err,"add_word failure\n"); goto end; } + +	if (!save_serial(buf, NULL, serial, &bs)) goto end; + + end: +	if (buf) OPENSSL_free(buf); +	BN_free(serial); +	return bs; +	} + +static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, +	     X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create, +	     int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno) +	{ +	int ret=0; +	ASN1_INTEGER *bs=NULL; +	X509_STORE_CTX xsc; +	EVP_PKEY *upkey; + +	upkey = X509_get_pubkey(xca); +	EVP_PKEY_copy_parameters(upkey,pkey); +	EVP_PKEY_free(upkey); + +	if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL)) +		{ +		BIO_printf(bio_err,"Error initialising X509 store\n"); +		goto end; +		} +	if (sno) bs = sno; +	else if (!(bs = x509_load_serial(CAfile, serialfile, create))) +		goto end; + +/*	if (!X509_STORE_add_cert(ctx,x)) goto end;*/ + +	/* NOTE: this certificate can/should be self signed, unless it was +	 * a certificate request in which case it is not. */ +	X509_STORE_CTX_set_cert(&xsc,x); +	X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); +	if (!reqfile && X509_verify_cert(&xsc) <= 0) +		goto end; + +	if (!X509_check_private_key(xca,pkey)) +		{ +		BIO_printf(bio_err,"CA certificate and CA private key do not match\n"); +		goto end; +		} + +	if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end; +	if (!X509_set_serialNumber(x,bs)) goto end; + +	if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL) +		goto end; + +	/* hardwired expired */ +	if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL) +		goto end; + +	if (clrext) +		{ +		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0); +		} + +	if (conf) +		{ +		X509V3_CTX ctx2; +		X509_set_version(x,2); /* version 3 certificate */ +                X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); +                X509V3_set_nconf(&ctx2, conf); +                if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end; +		} + +	if (!X509_sign(x,pkey,digest)) goto end; +	ret=1; +end: +	X509_STORE_CTX_cleanup(&xsc); +	if (!ret) +		ERR_print_errors(bio_err); +	if (!sno) ASN1_INTEGER_free(bs); +	return ret; +	} + +static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx) +	{ +	int err; +	X509 *err_cert; + +	/* it is ok to use a self signed certificate +	 * This case will catch both the initial ok == 0 and the +	 * final ok == 1 calls to this function */ +	err=X509_STORE_CTX_get_error(ctx); +	if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) +		return 1; + +	/* BAD we should have gotten an error.  Normally if everything +	 * worked X509_STORE_CTX_get_error(ctx) will still be set to +	 * DEPTH_ZERO_SELF_.... */ +	if (ok) +		{ +		BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n"); +		return 0; +		} +	else +		{ +		err_cert=X509_STORE_CTX_get_current_cert(ctx); +		print_name(bio_err, NULL, X509_get_subject_name(err_cert),0); +		BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n", +			err,X509_STORE_CTX_get_error_depth(ctx), +			X509_verify_cert_error_string(err)); +		return 1; +		} +	} + +/* self sign */ +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; + +	if (!X509_set_pubkey(x,pkey)) goto err; +	if (clrext) +		{ +		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0); +		} +	if (conf) +		{ +		X509V3_CTX ctx; +		X509_set_version(x,2); /* version 3 certificate */ +                X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); +                X509V3_set_nconf(&ctx, conf); +                if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err; +		} +	if (!X509_sign(x,pkey,digest)) goto err; +	return 1; +err: +	ERR_print_errors(bio_err); +	return 0; +	} + +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) +{ +	int id, i, idret; +	char *pname; +	id = X509_PURPOSE_get_id(pt); +	pname = X509_PURPOSE_get0_name(pt); +	for (i = 0; i < 2; i++) +		{ +		idret = X509_check_purpose(cert, id, i); +		BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");  +		if (idret == 1) BIO_printf(bio, "Yes\n"); +		else if (idret == 0) BIO_printf(bio, "No\n"); +		else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret); +		} +	return 1; +}  | 
