Restoring openssl s_server, pkey, pkeyparam, pkeyutl

This is only for the /system/bin/openssl test app which does not ship
by default. Instructions for running s_server for testing are added in
README.android.

Change-Id: I9c6032871f853c780e4c9ffef9b2dd8ad009f32b
diff --git a/README.android b/README.android
index be1e365..1dd32bf 100644
--- a/README.android
+++ b/README.android
@@ -65,6 +65,12 @@
      harmony_tests.jar is built from Subversion http://harmony.apache.org/
      Within Google it can be found at ~dalvik-prebuild/bin/harmony_tests.jar
 
+     # You can also run openssl s_server as a test server on the device:
+     adb push ./android.testssl/CAss.cnf /sdcard/CAss.cnf
+     adb shell openssl req -config /sdcard/CAss.cnf -x509 -nodes -days 365 -subj '/C=US/ST=California/L=Mountain View/CN=localhost' -newkey rsa:1024 -keyout /sdcard/server.pem -out /sdcard/server.pem
+     adb shell openssl s_server -cert /sdcard/server.pem -www -verify 1
+     adb shell am start https://localhost:4433 # confirm result in browser
+
 8) Do a full build before checking in:
 
      m -j16
diff --git a/apps/Android.mk b/apps/Android.mk
index e9f215c..06e07a2 100644
--- a/apps/Android.mk
+++ b/apps/Android.mk
@@ -32,6 +32,9 @@
 	pkcs12.c \
 	pkcs7.c \
 	pkcs8.c \
+	pkey.c \
+	pkeyparam.c \
+	pkeyutl.c \
 	prime.c \
 	rand.c \
 	req.c \
@@ -39,6 +42,7 @@
 	rsautl.c \
 	s_cb.c \
 	s_client.c \
+	s_server.c \
 	s_socket.c \
 	s_time.c \
 	sess_id.c \
diff --git a/apps/pkey.c b/apps/pkey.c
new file mode 100644
index 0000000..17e6702
--- /dev/null
+++ b/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/apps/pkeyparam.c b/apps/pkeyparam.c
new file mode 100644
index 0000000..7f18010
--- /dev/null
+++ b/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/apps/pkeyutl.c b/apps/pkeyutl.c
new file mode 100644
index 0000000..22a6c4b
--- /dev/null
+++ b/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/apps/progs.h b/apps/progs.h
index 40bfcb5..728bb6d 100644
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -43,9 +43,7 @@
 extern int smime_main(int argc,char *argv[]);
 extern int rand_main(int argc,char *argv[]);
 extern int engine_main(int argc,char *argv[]);
-#ifndef OPENSSL_NO_OCSP
 extern int ocsp_main(int argc,char *argv[]);
-#endif
 extern int prime_main(int argc,char *argv[]);
 extern int ts_main(int argc,char *argv[]);
 
@@ -109,9 +107,7 @@
 #endif
 	{FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
 #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
-#if 0 /* ANDROID */
-        {FUNC_TYPE_GENERAL,"s_server",s_server_main},
-#endif
+	{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},
@@ -137,11 +133,9 @@
 	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
 #endif
 	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
-#if 0 /* ANDROID */
 	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
 	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
 	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
-#endif
 	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
 	{FUNC_TYPE_GENERAL,"smime",smime_main},
 	{FUNC_TYPE_GENERAL,"rand",rand_main},
diff --git a/apps/s_client.c b/apps/s_client.c
index f2b8b43..6ed90f7 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -216,9 +216,6 @@
 /* Default PSK identity and key */
 static char *psk_identity="Client_identity";
 /*char *psk_key=NULL;  by default PSK is not used */
-#if 1 /* ANDROID */
-char *psk_key=NULL;
-#endif
 
 static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
 	unsigned int max_identity_len, unsigned char *psk,
diff --git a/openssl.config b/openssl.config
index 7d8064f..0471619 100644
--- a/openssl.config
+++ b/openssl.config
@@ -60,9 +60,6 @@
 README.ASN1 \
 README.ENGINE \
 apps/Makefile \
-apps/pkey.c \
-apps/pkeyparam.c \
-apps/pkeyutl.c \
 apps/ts.c \
 apps/tsget \
 config \
diff --git a/patches/apps_Android.mk b/patches/apps_Android.mk
index e9f215c..06e07a2 100644
--- a/patches/apps_Android.mk
+++ b/patches/apps_Android.mk
@@ -32,6 +32,9 @@
 	pkcs12.c \
 	pkcs7.c \
 	pkcs8.c \
+	pkey.c \
+	pkeyparam.c \
+	pkeyutl.c \
 	prime.c \
 	rand.c \
 	req.c \
@@ -39,6 +42,7 @@
 	rsautl.c \
 	s_cb.c \
 	s_client.c \
+	s_server.c \
 	s_socket.c \
 	s_time.c \
 	sess_id.c \
diff --git a/patches/progs.patch b/patches/progs.patch
index a00af00..16fd9b0 100644
--- a/patches/progs.patch
+++ b/patches/progs.patch
@@ -13,39 +13,6 @@
  			config = NULL;
 --- openssl-1.0.0.orig/apps/progs.h	2009-06-30 08:08:38.000000000 -0700
 +++ openssl-1.0.0/apps/progs.h	2010-05-18 14:05:38.000000000 -0700
-@@ -43,7 +43,9 @@ extern int spkac_main(int argc,char *arg
- extern int smime_main(int argc,char *argv[]);
- extern int rand_main(int argc,char *argv[]);
- extern int engine_main(int argc,char *argv[]);
-+#ifndef OPENSSL_NO_OCSP
- extern int ocsp_main(int argc,char *argv[]);
-+#endif
- extern int prime_main(int argc,char *argv[]);
- extern int ts_main(int argc,char *argv[]);
- 
-@@ -107,7 +109,9 @@ FUNCTION functions[] = {
- #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},
-+#if 0 /* ANDROID */
-+        {FUNC_TYPE_GENERAL,"s_server",s_server_main},
-+#endif
- #endif
- #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
- 	{FUNC_TYPE_GENERAL,"s_client",s_client_main},
-@@ -133,9 +137,11 @@ FUNCTION functions[] = {
- 	{FUNC_TYPE_GENERAL,"pkcs12",pkcs12_main},
- #endif
- 	{FUNC_TYPE_GENERAL,"pkcs8",pkcs8_main},
-+#if 0 /* ANDROID */
- 	{FUNC_TYPE_GENERAL,"pkey",pkey_main},
- 	{FUNC_TYPE_GENERAL,"pkeyparam",pkeyparam_main},
- 	{FUNC_TYPE_GENERAL,"pkeyutl",pkeyutl_main},
-+#endif
- 	{FUNC_TYPE_GENERAL,"spkac",spkac_main},
- 	{FUNC_TYPE_GENERAL,"smime",smime_main},
- 	{FUNC_TYPE_GENERAL,"rand",rand_main},
 @@ -146,7 +152,9 @@ FUNCTION functions[] = {
  	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
  #endif
@@ -85,15 +52,3 @@
  # undef  TERMIOS
  # define TERMIO
  # undef  SGTTY
---- openssl-1.0.0.orig/apps/s_client.c	2009-12-16 12:28:28.000000000 -0800
-+++ openssl-1.0.0/apps/s_client.c	2010-04-14 14:25:09.000000000 -0700
-@@ -216,6 +216,9 @@ static int c_ign_eof=0;
- /* Default PSK identity and key */
- static char *psk_identity="Client_identity";
- /*char *psk_key=NULL;  by default PSK is not used */
-+#if 1 /* ANDROID */
-+char *psk_key=NULL;
-+#endif
- 
- static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
- 	unsigned int max_identity_len, unsigned char *psk,