openssl/lk: Adding openssl 1.0.0a to LK

This is the same openssl 1.0.0a in the external
folder of Android tree with Android.mk files.

Change-Id: Ie21f916d5925042c260f0640cfaec231f46cf74a
diff --git a/lib/openssl/apps/Android.mk b/lib/openssl/apps/Android.mk
new file mode 100644
index 0000000..06e07a2
--- /dev/null
+++ b/lib/openssl/apps/Android.mk
@@ -0,0 +1,79 @@
+# Copyright 2006 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+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
+
+#   cms.c ec.c s_server.c
+
+LOCAL_SHARED_LIBRARIES := \
+	libssl \
+	libcrypto 
+
+LOCAL_C_INCLUDES := \
+	external/openssl \
+	external/openssl/include
+
+LOCAL_CFLAGS := -DMONOLITH
+
+include $(LOCAL_PATH)/../android-config.mk
+
+# These flags omit whole features from the commandline "openssl".
+# However, portions of these features are actually turned on.
+LOCAL_CFLAGS += -DOPENSSL_NO_DTLS1
+
+
+LOCAL_MODULE:= openssl
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/lib/openssl/apps/CA.com b/lib/openssl/apps/CA.com
new file mode 100644
index 0000000..69b7bb3
--- /dev/null
+++ b/lib/openssl/apps/CA.com
@@ -0,0 +1,220 @@
+$! 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 'openssl cmd' instead of 'cmd'.
+$! 18-Apr-96 tjh    Original hacking
+$!
+$! Tim Hudson
+$! tjh@cryptsoft.com
+$!
+$!
+$! default ssleay.cnf file has setup as per the following
+$! demoCA ... where everything is stored
+$
+$ IF F$TYPE(SSLEAY_CONFIG) .EQS. "" THEN SSLEAY_CONFIG := SSLLIB:SSLEAY.CNF
+$
+$ DAYS   = "-days 365"
+$ REQ    = openssl + " req " + SSLEAY_CONFIG
+$ CA     = openssl + " ca " + SSLEAY_CONFIG
+$ VERIFY = openssl + " verify"
+$ X509   = openssl + " x509"
+$ PKCS12 = openssl + " pkcs12"
+$ echo   = "write sys$Output"
+$!
+$ s = F$PARSE(F$ENVIRONMENT("DEFAULT"),"[]") - "].;"
+$ CATOP  := 's'.demoCA
+$ CAKEY  := ]cakey.pem
+$ CACERT := ]cacert.pem
+$
+$ __INPUT := SYS$COMMAND
+$ RET = 1
+$!
+$ i = 1
+$opt_loop:
+$ if i .gt. 8 then goto opt_loop_end
+$
+$ prog_opt = F$EDIT(P'i',"lowercase")
+$
+$ IF (prog_opt .EQS. "?" .OR. prog_opt .EQS. "-h" .OR. prog_opt .EQS. "-help") 
+$ THEN
+$   echo "usage: CA -newcert|-newreq|-newca|-sign|-verify" 
+$   exit
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-input")
+$ THEN
+$   ! Get input from somewhere other than SYS$COMMAND
+$   i = i + 1
+$   __INPUT = P'i'
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newcert")
+$ THEN
+$   ! Create a certificate.
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   REQ -new -x509 -keyout newreq.pem -out newreq.pem 'DAYS'
+$   RET=$STATUS
+$   echo "Certificate (and private key) is in newreq.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newreq")
+$ THEN
+$   ! Create a certificate request
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   REQ -new -keyout newreq.pem -out newreq.pem 'DAYS'
+$   RET=$STATUS
+$   echo "Request (and private key) is in newreq.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-newca")
+$ THEN
+$   ! If explicitly asked for or it doesn't exist then setup the directory
+$   ! structure that Eric likes to manage things.
+$   IF F$SEARCH(CATOP+"]serial.") .EQS. ""
+$   THEN
+$     CREATE /DIR /PROTECTION=OWNER:RWED 'CATOP']
+$     CREATE /DIR /PROTECTION=OWNER:RWED 'CATOP'.certs]
+$     CREATE /DIR /PROTECTION=OWNER:RWED 'CATOP'.crl]
+$     CREATE /DIR /PROTECTION=OWNER:RWED 'CATOP'.newcerts]
+$     CREATE /DIR /PROTECTION=OWNER:RWED 'CATOP'.private]
+$
+$     OPEN   /WRITE ser_file 'CATOP']serial. 
+$     WRITE ser_file "01"
+$     CLOSE ser_file
+$     APPEND/NEW NL: 'CATOP']index.txt
+$
+$     ! The following is to make sure access() doesn't get confused.  It
+$     ! really needs one file in the directory to give correct answers...
+$     COPY NLA0: 'CATOP'.certs].;
+$     COPY NLA0: 'CATOP'.crl].;
+$     COPY NLA0: 'CATOP'.newcerts].;
+$     COPY NLA0: 'CATOP'.private].;
+$   ENDIF
+$!
+$   IF F$SEARCH(CATOP+".private"+CAKEY) .EQS. ""
+$   THEN
+$     READ '__INPUT' FILE -
+	   /PROMPT="CA certificate filename (or enter to create)"
+$     IF (FILE .NES. "") .AND. (F$SEARCH(FILE) .NES. "")
+$     THEN
+$       COPY 'FILE' 'CATOP'.private'CAKEY'
+$	RET=$STATUS
+$     ELSE
+$       echo "Making CA certificate ..."
+$       DEFINE/USER SYS$INPUT '__INPUT'
+$       REQ -new -x509 -keyout 'CATOP'.private'CAKEY' -
+		       -out 'CATOP''CACERT' 'DAYS'
+$	RET=$STATUS
+$     ENDIF
+$   ENDIF
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-pkcs12")
+$ THEN
+$   i = i + 1
+$   cname = P'i'
+$   IF cname .EQS. "" THEN cname = "My certificate"
+$   PKCS12 -in newcert.pem -inkey newreq.pem -certfile 'CATOP''CACERT -
+	   -out newcert.p12 -export -name "''cname'"
+$   RET=$STATUS
+$   exit RET
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-xsign")
+$ THEN
+$!
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -infiles newreq.pem
+$   RET=$STATUS
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF ((prog_opt .EQS. "-sign") .OR. (prog_opt .EQS. "-signreq"))
+$ THEN
+$!   
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -out newcert.pem -infiles newreq.pem
+$   RET=$STATUS
+$   type newcert.pem
+$   echo "Signed certificate is in newcert.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-signcert")
+$  THEN
+$!   
+$   echo "Cert passphrase will be requested twice - bug?"
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   X509 -x509toreq -in newreq.pem -signkey newreq.pem -out tmp.pem
+$   DEFINE/USER SYS$INPUT '__INPUT'
+$   CA -policy policy_anything -out newcert.pem -infiles tmp.pem
+y
+y
+$   type newcert.pem
+$   echo "Signed certificate is in newcert.pem"
+$   GOTO opt_loop_continue
+$ ENDIF
+$!
+$ IF (prog_opt .EQS. "-verify")
+$ THEN
+$!   
+$   i = i + 1
+$   IF (p'i' .EQS. "")
+$   THEN
+$     DEFINE/USER SYS$INPUT '__INPUT'
+$     VERIFY "-CAfile" 'CATOP''CACERT' newcert.pem
+$   ELSE
+$     j = i
+$    verify_opt_loop:
+$     IF j .GT. 8 THEN GOTO verify_opt_loop_end
+$     IF p'j' .NES. ""
+$     THEN 
+$       DEFINE/USER SYS$INPUT '__INPUT'
+$       __tmp = p'j'
+$       VERIFY "-CAfile" 'CATOP''CACERT' '__tmp'
+$       tmp=$STATUS
+$       IF tmp .NE. 0 THEN RET=tmp
+$     ENDIF
+$     j = j + 1
+$     GOTO verify_opt_loop
+$    verify_opt_loop_end:
+$   ENDIF
+$   
+$   GOTO opt_loop_end
+$ ENDIF
+$!
+$ IF (prog_opt .NES. "")
+$ THEN
+$!   
+$   echo "Unknown argument ''prog_opt'"
+$   
+$   EXIT 3
+$ ENDIF
+$
+$opt_loop_continue:
+$ i = i + 1
+$ GOTO opt_loop
+$
+$opt_loop_end:
+$ EXIT 'RET'
diff --git a/lib/openssl/apps/CA.pl b/lib/openssl/apps/CA.pl
new file mode 100644
index 0000000..a3965ec
--- /dev/null
+++ b/lib/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/lib/openssl/apps/CA.pl.in b/lib/openssl/apps/CA.pl.in
new file mode 100644
index 0000000..c783a6e
--- /dev/null
+++ b/lib/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/lib/openssl/apps/CA.sh b/lib/openssl/apps/CA.sh
new file mode 100644
index 0000000..7ad6b8c
--- /dev/null
+++ b/lib/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/lib/openssl/apps/app_rand.c b/lib/openssl/apps/app_rand.c
new file mode 100644
index 0000000..b7b6128
--- /dev/null
+++ b/lib/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/lib/openssl/apps/apps.c b/lib/openssl/apps/apps.c
new file mode 100644
index 0000000..acc50df
--- /dev/null
+++ b/lib/openssl/apps/apps.c
@@ -0,0 +1,3013 @@
+/* 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 == '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,len,i;
+	char *p;
+
+	*argc=0;
+	*argv=NULL;
+
+	len=strlen(buf);
+	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
+		setvbuf(stdin, NULL, _IONBF, 0);
+#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
+		setvbuf(stdin, NULL, _IONBF, 0);
+#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
+		setvbuf(stdin, NULL, _IONBF, 0);
+#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
diff --git a/lib/openssl/apps/apps.h b/lib/openssl/apps/apps.h
new file mode 100644
index 0000000..596a39a
--- /dev/null
+++ b/lib/openssl/apps/apps.h
@@ -0,0 +1,360 @@
+/* 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
diff --git a/lib/openssl/apps/asn1pars.c b/lib/openssl/apps/asn1pars.c
new file mode 100644
index 0000000..b5d65e7
--- /dev/null
+++ b/lib/openssl/apps/asn1pars.c
@@ -0,0 +1,444 @@
+/* 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);
+
+	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/lib/openssl/apps/ca-cert.srl b/lib/openssl/apps/ca-cert.srl
new file mode 100644
index 0000000..2c7456e
--- /dev/null
+++ b/lib/openssl/apps/ca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/lib/openssl/apps/ca-key.pem b/lib/openssl/apps/ca-key.pem
new file mode 100644
index 0000000..3a520b2
--- /dev/null
+++ b/lib/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/lib/openssl/apps/ca-req.pem b/lib/openssl/apps/ca-req.pem
new file mode 100644
index 0000000..77bf7ec
--- /dev/null
+++ b/lib/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/lib/openssl/apps/ca.c b/lib/openssl/apps/ca.c
new file mode 100644
index 0000000..6b8b0ef
--- /dev/null
+++ b/lib/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/lib/openssl/apps/cert.pem b/lib/openssl/apps/cert.pem
new file mode 100644
index 0000000..de4a77a
--- /dev/null
+++ b/lib/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/lib/openssl/apps/ciphers.c b/lib/openssl/apps/ciphers.c
new file mode 100644
index 0000000..3d4c60d
--- /dev/null
+++ b/lib/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/lib/openssl/apps/client.pem b/lib/openssl/apps/client.pem
new file mode 100644
index 0000000..307910e
--- /dev/null
+++ b/lib/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/lib/openssl/apps/cms.c b/lib/openssl/apps/cms.c
new file mode 100644
index 0000000..d29a884
--- /dev/null
+++ b/lib/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, &ltmp);
+			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, &ltmp);
+			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/lib/openssl/apps/crl.c b/lib/openssl/apps/crl.c
new file mode 100644
index 0000000..c395b2a
--- /dev/null
+++ b/lib/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/lib/openssl/apps/crl2p7.c b/lib/openssl/apps/crl2p7.c
new file mode 100644
index 0000000..bbc8377
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dgst.c b/lib/openssl/apps/dgst.c
new file mode 100644
index 0000000..9bf38ce
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dh.c b/lib/openssl/apps/dh.c
new file mode 100644
index 0000000..e9609d6
--- /dev/null
+++ b/lib/openssl/apps/dh.c
@@ -0,0 +1,358 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/dh1024.pem b/lib/openssl/apps/dh1024.pem
new file mode 100644
index 0000000..6eaeca9
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dh2048.pem b/lib/openssl/apps/dh2048.pem
new file mode 100644
index 0000000..dcd0b8d
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dh4096.pem b/lib/openssl/apps/dh4096.pem
new file mode 100644
index 0000000..1b35ad8
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dh512.pem b/lib/openssl/apps/dh512.pem
new file mode 100644
index 0000000..200d16c
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dhparam.c b/lib/openssl/apps/dhparam.c
new file mode 100644
index 0000000..5fab29e
--- /dev/null
+++ b/lib/openssl/apps/dhparam.c
@@ -0,0 +1,563 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/dsa-ca.pem b/lib/openssl/apps/dsa-ca.pem
new file mode 100644
index 0000000..cccc142
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dsa-pca.pem b/lib/openssl/apps/dsa-pca.pem
new file mode 100644
index 0000000..d23774e
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dsa.c b/lib/openssl/apps/dsa.c
new file mode 100644
index 0000000..5222487
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dsa1024.pem b/lib/openssl/apps/dsa1024.pem
new file mode 100644
index 0000000..082dec3
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dsa512.pem b/lib/openssl/apps/dsa512.pem
new file mode 100644
index 0000000..5f86d1a
--- /dev/null
+++ b/lib/openssl/apps/dsa512.pem
@@ -0,0 +1,6 @@
+-----BEGIN DSA PARAMETERS-----
+MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97
+TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA
+gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO
+L8wka5B33qJoplISogOdIA==
+-----END DSA PARAMETERS-----
diff --git a/lib/openssl/apps/dsap.pem b/lib/openssl/apps/dsap.pem
new file mode 100644
index 0000000..d4dfdb3
--- /dev/null
+++ b/lib/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/lib/openssl/apps/dsaparam.c b/lib/openssl/apps/dsaparam.c
new file mode 100644
index 0000000..4305a73
--- /dev/null
+++ b/lib/openssl/apps/dsaparam.c
@@ -0,0 +1,484 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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,bits_q,bits_g;
+
+		len=BN_num_bytes(dsa->p);
+		bits_p=BN_num_bits(dsa->p);
+		bits_q=BN_num_bits(dsa->q);
+		bits_g=BN_num_bits(dsa->g);
+		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/lib/openssl/apps/ec.c b/lib/openssl/apps/ec.c
new file mode 100644
index 0000000..31194b4
--- /dev/null
+++ b/lib/openssl/apps/ec.c
@@ -0,0 +1,409 @@
+/* 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)
+{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE 	*e = NULL;
+#endif
+	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
+        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 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/lib/openssl/apps/ecparam.c b/lib/openssl/apps/ecparam.c
new file mode 100644
index 0000000..e9aa0a1
--- /dev/null
+++ b/lib/openssl/apps/ecparam.c
@@ -0,0 +1,734 @@
+/* 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;
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE	*e = NULL;
+#endif
+	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
+	e = 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/lib/openssl/apps/enc.c b/lib/openssl/apps/enc.c
new file mode 100644
index 0000000..3c2c91e
--- /dev/null
+++ b/lib/openssl/apps/enc.c
@@ -0,0 +1,723 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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)
+	        {
+		if (bufsize != NULL)
+			setvbuf(stdin, (char *)NULL, _IONBF, 0);
+		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);
+		if (bufsize != NULL)
+			setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#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/lib/openssl/apps/engine.c b/lib/openssl/apps/engine.c
new file mode 100644
index 0000000..9a02943
--- /dev/null
+++ b/lib/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/lib/openssl/apps/errstr.c b/lib/openssl/apps/errstr.c
new file mode 100644
index 0000000..fe3b980
--- /dev/null
+++ b/lib/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/lib/openssl/apps/gendh.c b/lib/openssl/apps/gendh.c
new file mode 100644
index 0000000..caa7327
--- /dev/null
+++ b/lib/openssl/apps/gendh.c
@@ -0,0 +1,244 @@
+/* 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;
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/gendsa.c b/lib/openssl/apps/gendsa.c
new file mode 100644
index 0000000..22c3962
--- /dev/null
+++ b/lib/openssl/apps/gendsa.c
@@ -0,0 +1,288 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/genpkey.c b/lib/openssl/apps/genpkey.c
new file mode 100644
index 0000000..6dfda08
--- /dev/null
+++ b/lib/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/lib/openssl/apps/genrsa.c b/lib/openssl/apps/genrsa.c
new file mode 100644
index 0000000..37e9310
--- /dev/null
+++ b/lib/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/lib/openssl/apps/install.com b/lib/openssl/apps/install.com
new file mode 100644
index 0000000..c5821b4
--- /dev/null
+++ b/lib/openssl/apps/install.com
@@ -0,0 +1,65 @@
+$! INSTALL.COM -- Installs the files in a given directory tree
+$!
+$! Author: Richard Levitte <richard@levitte.org>
+$! Time of creation: 22-MAY-1998 10:13
+$!
+$! P1	root of the directory tree
+$!
+$
+$	IF P1 .EQS. ""
+$	THEN
+$	    WRITE SYS$OUTPUT "First argument missing."
+$	    WRITE SYS$OUTPUT -
+		  "Should be the directory where you want things installed."
+$	    EXIT
+$	ENDIF
+$
+$	IF (F$GETSYI("CPU").LT.128)
+$	THEN
+$	    ARCH := VAX
+$	ELSE
+$	    ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$	    IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$	ENDIF
+$
+$	ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0"
+$	ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY")
+$	ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") -
+		   - "[000000." - "][" - "[" - "]"
+$	ROOT = ROOT_DEV + "[" + ROOT_DIR
+$
+$	DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC
+$	DEFINE/NOLOG WRK_SSLEXE WRK_SSLROOT:['ARCH'_EXE]
+$
+$	IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN -
+	   CREATE/DIR/LOG WRK_SSLROOT:[000000]
+$	IF F$PARSE("WRK_SSLEXE:") .EQS. "" THEN -
+	   CREATE/DIR/LOG WRK_SSLEXE:
+$
+$	EXE := openssl
+$
+$	EXE_DIR := [-.'ARCH'.EXE.APPS]
+$
+$	I = 0
+$ LOOP_EXE: 
+$	E = F$EDIT(F$ELEMENT(I, ",", EXE),"TRIM")
+$	I = I + 1
+$	IF E .EQS. "," THEN GOTO LOOP_EXE_END
+$	SET NOON
+$	IF F$SEARCH(EXE_DIR+E+".EXE") .NES. ""
+$	THEN
+$	  COPY 'EXE_DIR''E'.EXE WRK_SSLEXE:'E'.EXE/log
+$	  SET FILE/PROT=W:RE WRK_SSLEXE:'E'.EXE
+$	ENDIF
+$	SET ON
+$	GOTO LOOP_EXE
+$ LOOP_EXE_END:
+$
+$	SET NOON
+$	COPY CA.COM WRK_SSLEXE:CA.COM/LOG
+$	SET FILE/PROT=W:RE WRK_SSLEXE:CA.COM
+$	COPY OPENSSL-VMS.CNF WRK_SSLROOT:[000000]OPENSSL.CNF/LOG
+$	SET FILE/PROT=W:R WRK_SSLROOT:[000000]OPENSSL.CNF
+$	SET ON
+$
+$	EXIT
diff --git a/lib/openssl/apps/makeapps.com b/lib/openssl/apps/makeapps.com
new file mode 100644
index 0000000..58f2865
--- /dev/null
+++ b/lib/openssl/apps/makeapps.com
@@ -0,0 +1,997 @@
+$!
+$!  MAKEAPPS.COM
+$!  Written By:  Robert Byer
+$!               Vice-President
+$!               A-Com Computing, Inc.
+$!               byer@mail.all-net.net
+$!
+$!  Changes by Richard Levitte <richard@levitte.org>
+$!             Zoltan Arpadffy <zoli@polarhome.com>   
+$!
+$!  This command files compiles and creates all the various different
+$!  "application" programs for the different types of encryption for OpenSSL.
+$!  The EXE's are placed in the directory [.xxx.EXE.APPS] where "xxx" denotes
+$!  ALPHA, IA64 or VAX, depending on your machine architecture.
+$!
+$!  It was written so it would try to determine what "C" compiler to
+$!  use or you can specify which "C" compiler to use.
+$!
+$!  Specify DEBUG or NODEBUG as P1 to compile with or without debugger
+$!  information.
+$!
+$!  Specify which compiler at P2 to try to compile under.
+$!
+$!	   VAXC	 For VAX C.
+$!	   DECC	 For DEC C.
+$!	   GNUC	 For GNU C.
+$!
+$!  If you don't specify a compiler, it will try to determine which
+$!  "C" compiler to use.
+$!
+$!  P3, if defined, sets a TCP/IP library to use, through one of the following
+$!  keywords:
+$!
+$!	UCX		for UCX
+$!	SOCKETSHR	for SOCKETSHR+NETLIB
+$!	TCPIP		for TCPIP (post UCX)
+$!
+$!  P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
+$!
+$!  P5, if defined, sets a choice of programs to compile.
+$!
+$!
+$! Define A TCP/IP Library That We Will Need To Link To.
+$! (That Is, If We Need To Link To One.)
+$!
+$ TCPIP_LIB = ""
+$!
+$! Check What Architecture We Are Using.
+$!
+$ IF (F$GETSYI("CPU").LT.128)
+$ THEN
+$!
+$!  The Architecture Is VAX.
+$!
+$   ARCH = "VAX"
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  The Architecture Is Alpha, IA64 or whatever comes in the future.
+$!
+$   ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
+$   IF (ARCH .EQS. "") THEN ARCH = "UNK"
+$!
+$! End The Architecture Check.
+$!
+$ ENDIF
+$!
+$! Define what programs should be compiled
+$!
+$ PROGRAMS := OPENSSL
+$!
+$! Define The CRYPTO Library.
+$!
+$ CRYPTO_LIB := SYS$DISK:[-.'ARCH'.EXE.CRYPTO]LIBCRYPTO.OLB
+$!
+$! Define The SSL Library.
+$!
+$ SSL_LIB := SYS$DISK:[-.'ARCH'.EXE.SSL]LIBSSL.OLB
+$!
+$! Define The OBJ Directory.
+$!
+$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.APPS]
+$!
+$! Define The EXE Directory.
+$!
+$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.APPS]
+$!
+$! Check To Make Sure We Have Valid Command Line Parameters.
+$!
+$ GOSUB CHECK_OPTIONS
+$!
+$! Initialise logical names and such
+$!
+$ GOSUB INITIALISE
+$!
+$! Tell The User What Kind of Machine We Run On.
+$!
+$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
+$!
+$! Check To See If The OBJ Directory Exists.
+$!
+$ IF (F$PARSE(OBJ_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIRECTORY 'OBJ_DIR'
+$!
+$! End The OBJ Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If The EXE Directory Exists.
+$!
+$ IF (F$PARSE(EXE_DIR).EQS."")
+$ THEN
+$!
+$!  It Dosen't Exist, So Create It.
+$!
+$   CREATE/DIRECTORY 'EXE_DIR'
+$!
+$! End The EXE Directory Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have The Proper Libraries.
+$!
+$ GOSUB LIB_CHECK
+$!
+$! Check To See If We Have A Linker Option File.
+$!
+$ GOSUB CHECK_OPT_FILE
+$!
+$! Define The Application Files.
+$! NOTE: Some might think this list ugly.  However, it's made this way to
+$! reflect the E_OBJ variable in Makefile as closely as possible, thereby
+$! making it fairly easy to verify that the lists are the same.
+$!
+$ LIB_OPENSSL = "VERIFY,ASN1PARS,REQ,DGST,DH,DHPARAM,ENC,PASSWD,GENDH,ERRSTR,"+-
+	     	"CA,PKCS7,CRL2P7,CRL,"+-
+	      	"RSA,RSAUTL,DSA,DSAPARAM,EC,ECPARAM,"+-
+	      	"X509,GENRSA,GENDSA,GENPKEY,S_SERVER,S_CLIENT,SPEED,"+-
+	      	"S_TIME,APPS,S_CB,S_SOCKET,APP_RAND,VERSION,SESS_ID,"+-
+	      	"CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
+	      	"SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS"
+$ TCPIP_PROGRAMS = ",,"
+$ IF COMPILER .EQS. "VAXC" THEN -
+     TCPIP_PROGRAMS = ",OPENSSL,"
+$!
+$! Setup exceptional compilations
+$!
+$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
+$!
+$ PHASE := LIB
+$!
+$ RESTART: 
+$!
+$!  Define An App Counter And Set It To "0".
+$!
+$ APP_COUNTER = 0
+$!
+$!  Top Of The App Loop.
+$!
+$ NEXT_APP:
+$!
+$!  Make The Application File Name
+$!
+$ CURRENT_APP = F$EDIT(F$ELEMENT(APP_COUNTER,",",PROGRAMS),"TRIM")
+$!
+$!  Create The Executable File Name.
+$!
+$   EXE_FILE = EXE_DIR + CURRENT_APP + ".EXE"
+$!
+$!  Check To See If We Are At The End Of The File List.
+$!
+$ IF (CURRENT_APP.EQS.",")
+$ THEN
+$   IF (PHASE.EQS."LIB")
+$   THEN
+$     PHASE := APP
+$     GOTO RESTART
+$   ELSE
+$     GOTO APP_DONE
+$   ENDIF
+$ ENDIF
+$!
+$!  Increment The Counter.
+$!
+$ APP_COUNTER = APP_COUNTER + 1
+$!
+$!  Decide if we're building the object files or not.
+$!
+$ IF (PHASE.EQS."LIB")
+$ THEN
+$!
+$!  Define A Library File Counter And Set It To "-1".
+$!  -1 Means The Application File Name Is To Be Used.
+$!
+$   LIB_COUNTER = -1
+$!
+$!  Create a .OPT file for the object files
+$!
+$   OPEN/WRITE OBJECTS 'EXE_DIR''CURRENT_APP'.OPT
+$!
+$!  Top Of The File Loop.
+$!
+$  NEXT_LIB:
+$!
+$!  O.K, Extract The File Name From The File List.
+$!
+$   IF LIB_COUNTER .GE. 0
+$   THEN
+$     FILE_NAME = F$EDIT(F$ELEMENT(LIB_COUNTER,",",LIB_'CURRENT_APP'),"TRIM")
+$   ELSE
+$     FILE_NAME = CURRENT_APP
+$   ENDIF
+$!
+$!  Check To See If We Are At The End Of The File List.
+$!
+$   IF (FILE_NAME.EQS.",")
+$   THEN
+$     CLOSE OBJECTS
+$     GOTO NEXT_APP
+$   ENDIF
+$!
+$!  Increment The Counter.
+$!
+$   LIB_COUNTER = LIB_COUNTER + 1
+$!
+$!  Create The Source File Name.
+$!
+$   SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
+$!
+$!  Create The Object File Name.
+$!
+$   OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$   ON WARNING THEN GOTO NEXT_LIB
+$!
+$!  Check To See If The File We Want To Compile Actually Exists.
+$!
+$   IF (F$SEARCH(SOURCE_FILE).EQS."")
+$   THEN
+$!
+$!    Tell The User That The File Dosen't Exist.
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Exit The Build.
+$!
+$     GOTO EXIT
+$!
+$!  End The File Exist Check.
+$!
+$   ENDIF
+$!
+$!  Tell The User What We Are Building.
+$!
+$   IF (PHASE.EQS."LIB")
+$   THEN
+$     WRITE SYS$OUTPUT "Compiling The ",FILE_NAME,".C File."
+$   ELSE
+$     WRITE SYS$OUTPUT "Building The ",FILE_NAME," Application Program."
+$   ENDIF
+$!
+$!  Compile The File.
+$!
+$   ON ERROR THEN GOTO NEXT_LIB
+$   IF COMPILEWITH_CC2 - FILE_NAME .NES. COMPILEWITH_CC2
+$   THEN
+$     CC2/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$   ELSE
+$     CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$   ENDIF
+$   WRITE OBJECTS OBJECT_FILE
+$!
+$   GOTO NEXT_LIB
+$ ENDIF
+$!
+$!  Check if this program works well without a TCPIP library
+$!
+$ IF TCPIP_LIB .EQS. "" .AND. TCPIP_PROGRAMS - CURRENT_APP .NES. TCPIP_PROGRAMS
+$ THEN
+$   WRITE SYS$OUTPUT CURRENT_APP," needs a TCP/IP library.  Can't link.  Skipping..."
+$   GOTO NEXT_APP
+$ ENDIF
+$!
+$! Link The Program.
+$! Check To See If We Are To Link With A Specific TCP/IP Library.
+$!
+$ ON WARNING THEN GOTO NEXT_APP
+$!
+$ IF (TCPIP_LIB.NES."")
+$ THEN
+$!
+$! Don't Link With The RSAREF Routines And TCP/IP Library.
+$!
+$   LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
+	'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
+        'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+        'TCPIP_LIB','OPT_FILE'/OPTION
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$! Don't Link With The RSAREF Routines And Link With A TCP/IP Library.
+$!
+$   LINK/'DEBUGGER'/'TRACEBACK' /EXE='EXE_FILE' -
+	'EXE_DIR''CURRENT_APP'.OPT/OPTION, -
+        'SSL_LIB'/LIBRARY,'CRYPTO_LIB'/LIBRARY, -
+        'OPT_FILE'/OPTION
+$!
+$! End The TCP/IP Library Check.
+$!
+$ ENDIF
+$!
+$! Go Back And Do It Again.
+$!
+$ GOTO NEXT_APP
+$!
+$! All Done With This File.
+$!
+$ APP_DONE:
+$ EXIT:
+$!
+$! All Done, Time To Clean Up And Exit.
+$!
+$ GOSUB CLEANUP
+$ EXIT
+$!
+$! Check For The Link Option FIle.
+$!
+$ CHECK_OPT_FILE:
+$!
+$! Check To See If We Need To Make A VAX C Option File.
+$!
+$ IF (COMPILER.EQS."VAXC")
+$ THEN
+$!
+$!  Check To See If We Already Have A VAX C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A VAX C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable VAX C Runtime Library.
+!
+SYS$SHARE:VAXCRTL.EXE/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The VAXC Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A GNU C Option File.
+$!
+$ IF (COMPILER.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If We Already Have A GNU C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    We Need A GNU C Linker Option File.
+$!
+$     CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable C Runtime Library.
+!
+GNU_CC:[000000]GCCLIB/LIBRARY
+SYS$SHARE:VAXCRTL/SHARE
+$EOD
+$!
+$!  End The Option File Check.
+$!
+$   ENDIF
+$!
+$! End The GNU C Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Need A DEC C Option File.
+$!
+$ IF (COMPILER.EQS."DECC")
+$ THEN
+$!
+$!  Check To See If We Already Have A DEC C Linker Option File.
+$!
+$   IF (F$SEARCH(OPT_FILE).EQS."")
+$   THEN
+$!
+$!    Figure Out If We Need An AXP Or A VAX Linker Option File.
+$!
+$     IF ARCH.EQS."VAX"
+$     THEN
+$!
+$!      We Need A DEC C Linker Option File For VAX.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File To Link Agianst 
+! The Sharable DEC C Runtime Library.
+!
+SYS$SHARE:DECC$SHR.EXE/SHARE
+$EOD
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Create The non-VAX Linker Option File.
+$!
+$       CREATE 'OPT_FILE'
+$DECK
+!
+! Default System Options File For non-VAX To Link Agianst 
+! The Sharable C Runtime Library.
+!
+SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
+SYS$SHARE:CMA$OPEN_RTL/SHARE
+$EOD
+$!
+$!    End The DEC C Option File Check.
+$!
+$     ENDIF
+$!
+$!  End The Option File Search.
+$!
+$   ENDIF
+$!
+$! End The DEC C Check.
+$!
+$ ENDIF
+$!
+$!  Tell The User What Linker Option File We Are Using.
+$!
+$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."	
+$!
+$! Time To RETURN.
+$!
+$ RETURN
+$!
+$! Check To See If We Have The Appropiate Libraries.
+$!
+$ LIB_CHECK:
+$!
+$! Look For The Library LIBCRYPTO.OLB.
+$!
+$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBCRYPTO.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
+$   WRITE SYS$OUTPUT "We Can't Link Without It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The Crypto Library Check.
+$!
+$ ENDIF
+$!
+$! Look For The Library LIBSSL.OLB.
+$!
+$ IF (F$SEARCH(SSL_LIB).EQS."")
+$ THEN
+$!
+$!  Tell The User We Can't Find The LIBSSL.OLB Library.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
+$   WRITE SYS$OUTPUT "Some Of The Test Programs Need To Link To It."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Since We Can't Link Without It, Exit.
+$!
+$   EXIT
+$!
+$! End The SSL Library Check.
+$!
+$ ENDIF
+$!
+$! Time To Return.
+$!
+$ RETURN
+$!
+$! Check The User's Options.
+$!
+$ CHECK_OPTIONS:
+$!
+$! Check To See If P1 Is Blank.
+$!
+$ IF (P1.EQS."NODEBUG")
+$ THEN
+$!
+$!   P1 Is NODEBUG, So Compile Without Debugger Information.
+$!
+$    DEBUGGER  = "NODEBUG"
+$    TRACEBACK = "NOTRACEBACK" 
+$    GCC_OPTIMIZE = "OPTIMIZE"
+$    CC_OPTIMIZE = "OPTIMIZE"
+$    WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
+$    WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
+$!
+$! Else...
+$!
+$ ELSE
+$!
+$!  Check To See If We Are To Compile With Debugger Information.
+$!
+$   IF (P1.EQS."DEBUG")
+$   THEN
+$!
+$!    Compile With Debugger Information.
+$!
+$     DEBUGGER  = "DEBUG"
+$     TRACEBACK = "TRACEBACK"
+$     GCC_OPTIMIZE = "NOOPTIMIZE"
+$     CC_OPTIMIZE = "NOOPTIMIZE"
+$     WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
+$     WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
+$   ELSE
+$!
+$!    Tell The User Entered An Invalid Option..
+$!
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "The Option ",P1," Is Invalid.  The Valid Options Are:"
+$     WRITE SYS$OUTPUT ""
+$     WRITE SYS$OUTPUT "    DEBUG    :  Compile With The Debugger Information."
+$     WRITE SYS$OUTPUT "    NODEBUG  :  Compile Without The Debugger Information."
+$     WRITE SYS$OUTPUT ""
+$!
+$!    Time To EXIT.
+$!
+$     EXIT
+$!
+$!  End The Valid Argument Check.
+$!
+$   ENDIF
+$!
+$! End The P1 Check.
+$!
+$ ENDIF
+$!
+$! Check To See If P2 Is Blank.
+$!
+$ IF (P2.EQS."")
+$ THEN
+$!
+$!  O.K., The User Didn't Specify A Compiler, Let's Try To
+$!  Find Out Which One To Use.
+$!
+$!  Check To See If We Have GNU C.
+$!
+$   IF (F$TRNLNM("GNU_CC").NES."")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     P2 = "GNUC"
+$!
+$!  Else...
+$!
+$   ELSE
+$!
+$!  Check To See If We Have VAXC Or DECC.
+$!
+$     IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
+$     THEN 
+$!
+$!      Looks Like DECC, Set To Use DECC.
+$!
+$       P2 = "DECC"
+$!
+$!    Else...
+$!
+$     ELSE
+$!
+$!      Looks Like VAXC, Set To Use VAXC.
+$!
+$       P2 = "VAXC"
+$!
+$!    End The VAXC Compiler Check.
+$!
+$     ENDIF
+$!
+$!  End The DECC & VAXC Compiler Check.
+$!
+$   ENDIF
+$!
+$!  End The Compiler Check.
+$!
+$ ENDIF
+$!
+$! Check To See If We Have A Option For P3.
+$!
+$ IF (P3.EQS."")
+$ THEN
+$!
+$!  Find out what socket library we have available
+$!
+$   IF F$PARSE("SOCKETSHR:") .NES. ""
+$   THEN
+$!
+$!    We have SOCKETSHR, and it is my opinion that it's the best to use.
+$!
+$     P3 = "SOCKETSHR"
+$!
+$!    Tell the user
+$!
+$     WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
+$!
+$!    Else, let's look for something else
+$!
+$   ELSE
+$!
+$!    Like UCX (the reason to do this before Multinet is that the UCX
+$!    emulation is easier to use...)
+$!
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
+	 .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
+	 .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
+$     THEN
+$!
+$!	Last resort: a UCX or UCX-compatible library
+$!
+$	P3 = "UCX"
+$!
+$!      Tell the user
+$!
+$       WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
+$!
+$!	That was all...
+$!
+$     ENDIF
+$   ENDIF
+$ ENDIF
+$!
+$! Set Up Initial CC Definitions, Possibly With User Ones
+$!
+$ CCDEFS = "MONOLITH"
+$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
+$ CCEXTRAFLAGS = ""
+$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
+$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
+$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
+	CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS
+$!
+$!  Check To See If The User Entered A Valid Paramter.
+$!
+$ IF (P2.EQS."VAXC").OR.(P2.EQS."DECC").OR.(P2.EQS."GNUC")
+$ THEN
+$!
+$!  Check To See If The User Wanted DECC.
+$!
+$   IF (P2.EQS."DECC")
+$   THEN
+$!
+$!    Looks Like DECC, Set To Use DECC.
+$!
+$     COMPILER = "DECC"
+$!
+$!    Tell The User We Are Using DECC.
+$!
+$     WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
+$!
+$!    Use DECC...
+$!
+$     CC = "CC"
+$     IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
+	 THEN CC = "CC/DECC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
+           "/NOLIST/PREFIX=ALL" + -
+	   "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
+$!
+$!  End DECC Check.
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use VAXC.
+$!
+$   IF (P2.EQS."VAXC")
+$   THEN
+$!
+$!    Looks Like VAXC, Set To Use VAXC.
+$!
+$     COMPILER = "VAXC"
+$!
+$!    Tell The User We Are Using VAX C.
+$     WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
+$!
+$!    Compile Using VAXC.
+$!
+$     CC = "CC"
+$     IF ARCH.NES."VAX"
+$     THEN
+$	WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
+$	EXIT
+$     ENDIF
+$     IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
+$     CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$     CCDEFS = CCDEFS + ",""VAXC"""
+$!
+$!    Define <sys> As SYS$COMMON:[SYSLIB]
+$!
+$     DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
+$!
+$!  End VAXC Check
+$!
+$   ENDIF
+$!
+$!  Check To See If We Are To Use GNU C.
+$!
+$   IF (P2.EQS."GNUC")
+$   THEN
+$!
+$!    Looks Like GNUC, Set To Use GNUC.
+$!
+$     COMPILER = "GNUC"
+$!
+$!    Tell The User We Are Using GNUC.
+$!
+$     WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
+$!
+$!    Use GNU C...
+$!
+$     IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
+$     CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+	   "/INCLUDE=(SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + CCEXTRAFLAGS
+$!
+$!    Define The Linker Options File Name.
+$!
+$     OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
+$!
+$!  End The GNU C Check.
+$!
+$   ENDIF
+$!
+$!  Set up default defines
+$!
+$   CCDEFS = """FLAT_INC=1""," + CCDEFS
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P2," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    VAXC  :  To Compile With VAX C."
+$   WRITE SYS$OUTPUT "    DECC  :  To Compile With DEC C."
+$   WRITE SYS$OUTPUT "    GNUC  :  To Compile With GNU C."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$ ENDIF
+$!
+$! Time to check the contents, and to make sure we get the correct library.
+$!
+$ IF P3.EQS."SOCKETSHR" .OR. P3.EQS."MULTINET" .OR. P3.EQS."UCX" -
+     .OR. P3.EQS."TCPIP" .OR. P3.EQS."NONE"
+$ THEN
+$!
+$!  Check to see if SOCKETSHR was chosen
+$!
+$   IF P3.EQS."SOCKETSHR"
+$   THEN
+$!
+$!    Set the library to use SOCKETSHR
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT"
+$!
+$!    Done with SOCKETSHR
+$!
+$   ENDIF
+$!
+$!  Check to see if MULTINET was chosen
+$!
+$   IF P3.EQS."MULTINET"
+$   THEN
+$!
+$!    Set the library to use UCX emulation.
+$!
+$     P3 = "UCX"
+$!
+$!    Done with MULTINET
+$!
+$   ENDIF
+$!
+$!  Check to see if UCX was chosen
+$!
+$   IF P3.EQS."UCX"
+$   THEN
+$!
+$!    Set the library to use UCX.
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT"
+$     IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
+$     THEN
+$       TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT"
+$     ELSE
+$       IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
+	  TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT"
+$     ENDIF
+$!
+$!    Done with UCX
+$!
+$   ENDIF
+$!
+$!  Check to see if TCPIP (post UCX) was chosen
+$!
+$   IF P3.EQS."TCPIP"
+$   THEN
+$!
+$!    Set the library to use TCPIP.
+$!
+$     TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT"
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Check to see if NONE was chosen
+$!
+$   IF P3.EQS."NONE"
+$   THEN
+$!
+$!    Do not use TCPIP.
+$!
+$     TCPIP_LIB = ""
+$!
+$!    Done with TCPIP
+$!
+$   ENDIF
+$!
+$!  Add TCP/IP type to CC definitions.
+$!
+$   CCDEFS = CCDEFS + ",TCPIP_TYPE_''P3'"
+$!
+$!  Print info
+$!
+$   WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB
+$!
+$!  Else The User Entered An Invalid Argument.
+$!
+$ ELSE
+$!
+$!  Tell The User We Don't Know What They Want.
+$!
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "The Option ",P3," Is Invalid.  The Valid Options Are:"
+$   WRITE SYS$OUTPUT ""
+$   WRITE SYS$OUTPUT "    SOCKETSHR  :  To link with SOCKETSHR TCP/IP library."
+$   WRITE SYS$OUTPUT "    UCX        :  To link with UCX TCP/IP library."
+$   WRITE SYS$OUTPUT "    TCPIP      :  To link with TCPIP (post UCX) TCP/IP library."
+$   WRITE SYS$OUTPUT ""
+$!
+$!  Time To EXIT.
+$!
+$   EXIT
+$!
+$!  Done with TCP/IP libraries
+$!
+$ ENDIF
+$!
+$! Finish up the definition of CC.
+$!
+$ IF COMPILER .EQS. "DECC"
+$ THEN
+$   IF CCDISABLEWARNINGS .NES. ""
+$   THEN
+$     CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
+$   ENDIF
+$ ELSE
+$   CCDISABLEWARNINGS = ""
+$ ENDIF
+$ CC2 = CC + "/DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
+$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
+$!
+$! Show user the result
+$!
+$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
+$!
+$! Special Threads For OpenVMS v7.1 Or Later
+$!
+$! Written By:  Richard Levitte
+$!              richard@levitte.org
+$!
+$!
+$! Check To See If We Have A Option For P4.
+$!
+$ IF (P4.EQS."")
+$ THEN
+$!
+$!  Get The Version Of VMS We Are Using.
+$!
+$   ISSEVEN :=
+$   TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
+$   TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
+$!
+$!  Check To See If The VMS Version Is v7.1 Or Later.
+$!
+$   IF (TMP.GE.71)
+$   THEN
+$!
+$!    We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
+$!
+$     ISSEVEN := ,PTHREAD_USE_D4
+$!
+$!  End The VMS Version Check.
+$!
+$   ENDIF
+$!
+$! End The P4 Check.
+$!
+$ ENDIF
+$!
+$! Check if the user wanted to compile just a subset of all the programs.
+$!
+$ IF P5 .NES. ""
+$ THEN
+$   PROGRAMS = P5
+$ ENDIF
+$!
+$!  Time To RETURN...
+$!
+$ RETURN
+$!
+$ INITIALISE:
+$!
+$! Save old value of the logical name OPENSSL
+$!
+$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
+$!
+$! Save directory information
+$!
+$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
+$ __HERE = F$EDIT(__HERE,"UPCASE")
+$ __TOP = __HERE - "APPS]"
+$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
+$!
+$! Set up the logical name OPENSSL to point at the include directory
+$!
+$ DEFINE OPENSSL/NOLOG '__INCLUDE'
+$!
+$! Done
+$!
+$ RETURN
+$!
+$ CLEANUP:
+$!
+$! Restore the logical name OPENSSL if it had a value
+$!
+$ IF __SAVE_OPENSSL .EQS. ""
+$ THEN
+$   DEASSIGN OPENSSL
+$ ELSE
+$   DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
+$ ENDIF
+$!
+$! Done
+$!
+$ RETURN
diff --git a/lib/openssl/apps/md4.c b/lib/openssl/apps/md4.c
new file mode 120000
index 0000000..7f457b2
--- /dev/null
+++ b/lib/openssl/apps/md4.c
@@ -0,0 +1 @@
+../crypto/md4/md4.c
\ No newline at end of file
diff --git a/lib/openssl/apps/nseq.c b/lib/openssl/apps/nseq.c
new file mode 100644
index 0000000..e3c4dba
--- /dev/null
+++ b/lib/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/lib/openssl/apps/ocsp.c b/lib/openssl/apps/ocsp.c
new file mode 100644
index 0000000..01847df
--- /dev/null
+++ b/lib/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/lib/openssl/apps/oid.cnf b/lib/openssl/apps/oid.cnf
new file mode 100644
index 0000000..faf425a
--- /dev/null
+++ b/lib/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/lib/openssl/apps/openssl-vms.cnf b/lib/openssl/apps/openssl-vms.cnf
new file mode 100644
index 0000000..20ed61b
--- /dev/null
+++ b/lib/openssl/apps/openssl-vms.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		= sys\$disk:[.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		= sys\$disk:[.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/lib/openssl/apps/openssl.c b/lib/openssl/apps/openssl.c
new file mode 100644
index 0000000..be37ee6
--- /dev/null
+++ b/lib/openssl/apps/openssl.c
@@ -0,0 +1,654 @@
+/* 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);
+		}
+	}
+
+
+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;
+ 
+	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;
+		}
+	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/lib/openssl/apps/openssl.cnf b/lib/openssl/apps/openssl.cnf
new file mode 100644
index 0000000..9d2cd5b
--- /dev/null
+++ b/lib/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/lib/openssl/apps/passwd.c b/lib/openssl/apps/passwd.c
new file mode 100644
index 0000000..9ca25dd
--- /dev/null
+++ b/lib/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/lib/openssl/apps/pca-cert.srl b/lib/openssl/apps/pca-cert.srl
new file mode 100644
index 0000000..2c7456e
--- /dev/null
+++ b/lib/openssl/apps/pca-cert.srl
@@ -0,0 +1 @@
+07
diff --git a/lib/openssl/apps/pca-key.pem b/lib/openssl/apps/pca-key.pem
new file mode 100644
index 0000000..20029ab
--- /dev/null
+++ b/lib/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/lib/openssl/apps/pca-req.pem b/lib/openssl/apps/pca-req.pem
new file mode 100644
index 0000000..33f1553
--- /dev/null
+++ b/lib/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/lib/openssl/apps/pkcs12.c b/lib/openssl/apps/pkcs12.c
new file mode 100644
index 0000000..514a02e
--- /dev/null
+++ b/lib/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) 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/lib/openssl/apps/pkcs7.c b/lib/openssl/apps/pkcs7.c
new file mode 100644
index 0000000..86d31b9
--- /dev/null
+++ b/lib/openssl/apps/pkcs7.c
@@ -0,0 +1,323 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/pkcs8.c b/lib/openssl/apps/pkcs8.c
new file mode 100644
index 0000000..7edeb17
--- /dev/null
+++ b/lib/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/lib/openssl/apps/pkey.c b/lib/openssl/apps/pkey.c
new file mode 100644
index 0000000..17e6702
--- /dev/null
+++ b/lib/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/lib/openssl/apps/pkeyparam.c b/lib/openssl/apps/pkeyparam.c
new file mode 100644
index 0000000..7f18010
--- /dev/null
+++ b/lib/openssl/apps/pkeyparam.c
@@ -0,0 +1,201 @@
+/* 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
+	ENGINE *e = NULL;
+	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
+        e = 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/lib/openssl/apps/pkeyutl.c b/lib/openssl/apps/pkeyutl.c
new file mode 100644
index 0000000..22a6c4b
--- /dev/null
+++ b/lib/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;
+                        infile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-out"))
+			{
+			if (--argc < 1) badarg = 1;
+			outfile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-sigfile"))
+			{
+			if (--argc < 1) badarg = 1;
+			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;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-peerform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			peerform=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			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/lib/openssl/apps/prime.c b/lib/openssl/apps/prime.c
new file mode 100644
index 0000000..f1aaef8
--- /dev/null
+++ b/lib/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/lib/openssl/apps/privkey.pem b/lib/openssl/apps/privkey.pem
new file mode 100644
index 0000000..0af4647
--- /dev/null
+++ b/lib/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/lib/openssl/apps/progs.h b/lib/openssl/apps/progs.h
new file mode 100644
index 0000000..728bb6d
--- /dev/null
+++ b/lib/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/lib/openssl/apps/progs.pl b/lib/openssl/apps/progs.pl
new file mode 100644
index 0000000..de6fdea
--- /dev/null
+++ b/lib/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/lib/openssl/apps/rand.c b/lib/openssl/apps/rand.c
new file mode 100644
index 0000000..44a1d46
--- /dev/null
+++ b/lib/openssl/apps/rand.c
@@ -0,0 +1,248 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+        e = 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/lib/openssl/apps/req.c b/lib/openssl/apps/req.c
new file mode 100644
index 0000000..820cd18
--- /dev/null
+++ b/lib/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/lib/openssl/apps/req.pem b/lib/openssl/apps/req.pem
new file mode 100644
index 0000000..5537df6
--- /dev/null
+++ b/lib/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/lib/openssl/apps/rsa.c b/lib/openssl/apps/rsa.c
new file mode 100644
index 0000000..a17708f
--- /dev/null
+++ b/lib/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/lib/openssl/apps/rsa8192.pem b/lib/openssl/apps/rsa8192.pem
new file mode 100644
index 0000000..946a6e5
--- /dev/null
+++ b/lib/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/lib/openssl/apps/rsautl.c b/lib/openssl/apps/rsautl.c
new file mode 100644
index 0000000..b01f004
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s1024key.pem b/lib/openssl/apps/s1024key.pem
new file mode 100644
index 0000000..19e0403
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s1024req.pem b/lib/openssl/apps/s1024req.pem
new file mode 100644
index 0000000..bb75e7e
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s512-key.pem b/lib/openssl/apps/s512-key.pem
new file mode 100644
index 0000000..0e3ff2d
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s512-req.pem b/lib/openssl/apps/s512-req.pem
new file mode 100644
index 0000000..ea314be
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s_apps.h b/lib/openssl/apps/s_apps.h
new file mode 100644
index 0000000..820e5c5
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s_cb.c b/lib/openssl/apps/s_cb.c
new file mode 100644
index 0000000..c4f5512
--- /dev/null
+++ b/lib/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/lib/openssl/apps/s_client.c b/lib/openssl/apps/s_client.c
new file mode 100644
index 0000000..6ed90f7
--- /dev/null
+++ b/lib/openssl/apps/s_client.c
@@ -0,0 +1,1794 @@
+/* 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");
+	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;
+	}
+#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};
+#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; }
+#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();
+
+#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 (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
+	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/lib/openssl/apps/s_server.c b/lib/openssl/apps/s_server.c
new file mode 100644
index 0000000..1a06d19
--- /dev/null
+++ b/lib/openssl/apps/s_server.c
@@ -0,0 +1,2691 @@
+/* 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");
+#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;
+	}
+#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};
+#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);
+			}
+			
+#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);
+		}
+#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;
+					}
+				}
+#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 ((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 (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,blank,dot;
+	SSL *con;
+	const SSL_CIPHER *c;
+	BIO *io,*ssl_bio,*sbio;
+	long total_bytes;
+
+	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);
+		}
+
+	blank=0;
+	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 */
+			total_bytes=0;
+			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/lib/openssl/apps/s_socket.c b/lib/openssl/apps/s_socket.c
new file mode 100644
index 0000000..6b8713d
--- /dev/null
+++ b/lib/openssl/apps/s_socket.c
@@ -0,0 +1,621 @@
+/* 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,i;
+
+	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;
+	i=0;
+	*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,i;
+	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))
+		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);
+			}
+		i=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/lib/openssl/apps/s_time.c b/lib/openssl/apps/s_time.c
new file mode 100644
index 0000000..b823c33
--- /dev/null
+++ b/lib/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/lib/openssl/apps/server.pem b/lib/openssl/apps/server.pem
new file mode 100644
index 0000000..56248e5
--- /dev/null
+++ b/lib/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/lib/openssl/apps/server.srl b/lib/openssl/apps/server.srl
new file mode 100644
index 0000000..8a0f05e
--- /dev/null
+++ b/lib/openssl/apps/server.srl
@@ -0,0 +1 @@
+01
diff --git a/lib/openssl/apps/server2.pem b/lib/openssl/apps/server2.pem
new file mode 100644
index 0000000..8bb6641
--- /dev/null
+++ b/lib/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/lib/openssl/apps/sess_id.c b/lib/openssl/apps/sess_id.c
new file mode 100644
index 0000000..b99179f
--- /dev/null
+++ b/lib/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/lib/openssl/apps/smime.c b/lib/openssl/apps/smime.c
new file mode 100644
index 0000000..c583f8a
--- /dev/null
+++ b/lib/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/lib/openssl/apps/speed.c b/lib/openssl/apps/speed.c
new file mode 100644
index 0000000..b903864
--- /dev/null
+++ b/lib/openssl/apps/speed.c
@@ -0,0 +1,2791 @@
+/* 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)
+	{
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+#endif
+	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
+	DES_cblock *buf_as_des_cblock = NULL;
+	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;
+		}
+#ifndef OPENSSL_NO_DES
+	buf_as_des_cblock = (DES_cblock *)buf;
+#endif
+	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;
+				}
+                        e = 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(buf_as_des_cblock,buf_as_des_cblock,
+				&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;
+				}
+			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;
+				}
+#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/lib/openssl/apps/spkac.c b/lib/openssl/apps/spkac.c
new file mode 100644
index 0000000..0e01ea9
--- /dev/null
+++ b/lib/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/lib/openssl/apps/testCA.pem b/lib/openssl/apps/testCA.pem
new file mode 100644
index 0000000..dcb710a
--- /dev/null
+++ b/lib/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/lib/openssl/apps/testdsa.h b/lib/openssl/apps/testdsa.h
new file mode 100644
index 0000000..9e84e31
--- /dev/null
+++ b/lib/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/lib/openssl/apps/testrsa.h b/lib/openssl/apps/testrsa.h
new file mode 100644
index 0000000..3007d79
--- /dev/null
+++ b/lib/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/lib/openssl/apps/timeouts.h b/lib/openssl/apps/timeouts.h
new file mode 100644
index 0000000..89b5dc7
--- /dev/null
+++ b/lib/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/lib/openssl/apps/verify.c b/lib/openssl/apps/verify.c
new file mode 100644
index 0000000..9163997
--- /dev/null
+++ b/lib/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/lib/openssl/apps/version.c b/lib/openssl/apps/version.c
new file mode 100644
index 0000000..e9555cb
--- /dev/null
+++ b/lib/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/lib/openssl/apps/winrand.c b/lib/openssl/apps/winrand.c
new file mode 100644
index 0000000..59bede3
--- /dev/null
+++ b/lib/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/lib/openssl/apps/x509.c b/lib/openssl/apps/x509.c
new file mode 100644
index 0000000..e7e46d7
--- /dev/null
+++ b/lib/openssl/apps/x509.c
@@ -0,0 +1,1294 @@
+/* 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;
+		X509_CINF *ci;
+		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;
+		ci=x->cert_info;
+
+		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;
+}