ipsec-tools: Support IPSec RSA sessions again.

This change supports command-line usage and android service at
the same time. It also removes the access to native keystore.

Change-Id: Ia3d931b0ba8f83624d668de97c9dfc10280bef3b
diff --git a/Android.mk b/Android.mk
index 078770f..f95284b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -55,8 +55,7 @@
 	$(LOCAL_PATH)/src/libipsec \
 	$(LOCAL_PATH)/src/racoon \
 	$(LOCAL_PATH)/src/racoon/missing \
-	external/openssl/include \
-	frameworks/base/cmds/keystore
+	external/openssl/include
 
 LOCAL_STATIC_LIBRARIES := libipsec
 
diff --git a/main.c b/main.c
index c10e32b..acb399e 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,20 +31,22 @@
 
 #include "config.h"
 #include "gcmalloc.h"
+#include "vmbuf.h"
+#include "localconf.h"
 #include "session.h"
 #include "schedule.h"
 #include "plog.h"
 
 #ifdef ANDROID_CHANGES
 
-static void android_get_arguments(int *argc, char ***argv)
+static int get_control_and_arguments(int *argc, char ***argv)
 {
     static char *args[32];
     int control;
     int i;
 
     if ((i = android_get_control_socket("racoon")) == -1) {
-        return;
+        return -1;
     }
     do_plog(LLV_DEBUG, "Waiting for control socket");
     if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
@@ -84,7 +86,7 @@
 
     *argc = i;
     *argv = args;
-    close(control);
+    return control;
 }
 
 #endif
@@ -110,7 +112,15 @@
 
 int main(int argc, char **argv)
 {
+#ifdef ANDROID_CHANGES
+    int control = get_control_and_arguments(&argc, &argv);
+    if (control != -1) {
+        lcconf->chroot = "%p";
+    }
+#endif
+
     do_plog(LLV_INFO, "ipsec-tools 0.8.0 (http://ipsec-tools.sf.net)\n");
+    setup(argc, argv);
 
     signal(SIGHUP, terminate);
     signal(SIGINT, terminate);
@@ -118,12 +128,6 @@
     signal(SIGPIPE, SIG_IGN);
     atexit(terminated);
 
-#ifdef ANDROID_CHANGES
-/*    setuid(AID_VPN); */
-    android_get_arguments(&argc, &argv);
-#endif
-    setup(argc, argv);
-
     while (1) {
         struct timeval *tv = schedular();
         int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;
diff --git a/setup.c b/setup.c
index eb575ce..7a30078 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -123,6 +123,7 @@
     localconf.port_isakmp = PORT_ISAKMP;
     localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
     localconf.default_af = AF_INET;
+    localconf.pathinfo[LC_PATHTYPE_CERT] = "./";
     localconf.pad_random = LC_DEFAULT_PAD_RANDOM;
     localconf.pad_randomlen = LC_DEFAULT_PAD_RANDOM;
     localconf.pad_strict = LC_DEFAULT_PAD_STRICT;
@@ -335,14 +336,28 @@
         spdadd(myaddrs[0].addr, target, IPPROTO_UDP, NULL, NULL);
         remoteconf->myprivfile = argv[5];
         remoteconf->mycertfile = argv[6];
-        remoteconf->cacertfile = argv[7];
+        remoteconf->mycert = eay_get_x509cert(argv[6]);
+        if (!remoteconf->mycert) {
+            do_plog(LLV_ERROR, "Cannot load user certificate\n");
+            exit(1);
+        }
+        if (!*argv[7]) {
+            remoteconf->verify_cert = FALSE;
+        } else {
+            remoteconf->cacertfile = argv[7];
+            remoteconf->cacert = eay_get_x509cert(argv[7]);
+            if (!remoteconf->cacert) {
+                do_plog(LLV_ERROR, "Cannot load CA certificate\n");
+                exit(1);
+            }
+        }
         remoteconf->idvtype = IDTYPE_ASN1DN;
         auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;
     } else {
         printf("Usage: %s <interface> <server> [...],\n"
                "    where [...] can be:\n"
                "    udppsk <port> <pre-shared-key>\n"
-               "    udprsa <port> <my-private-key> <my-cert> <ca-cert>\n",
+               "    udprsa <port> <user-private-key> <user-cert> <ca-cert>\n",
                argv[0]);
         exit(0);
     }
@@ -400,7 +415,11 @@
 
 void getpathname(char *path, int length, int type, const char *name)
 {
-    strncpy(path, name, length);
+    if (localconf.chroot) {
+        snprintf(path, length, localconf.chroot, name);
+    } else {
+        strncpy(path, name, length);
+    }
 }
 
 /* sainfo.h */
diff --git a/src/racoon/crypto_openssl.c b/src/racoon/crypto_openssl.c
index f8a4db9..789b7b1 100644
--- a/src/racoon/crypto_openssl.c
+++ b/src/racoon/crypto_openssl.c
@@ -69,7 +69,6 @@
 #else
 #define EVP_bf_cbc()    NULL
 #define EVP_cast5_cbc() NULL
-#include "keystore_get.h"
 #endif
 #include <openssl/err.h>
 #ifdef HAVE_OPENSSL_RC5_H
@@ -461,18 +460,18 @@
 }
 
 #ifdef ANDROID_CHANGES
-static BIO *BIO_from_keystore(char *key)
-{
-	BIO *bio = NULL;
-	char value[KEYSTORE_MESSAGE_SIZE];
-	int length = keystore_get(key, strlen(key), value);
-	if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) {
-		BIO_write(bio, value, length);
-	}
-	return bio;
-}
-#endif
 
+#include "localconf.h"
+static BIO *BIO_from_android(char *path)
+{
+	void *data;
+	if (sscanf(path, lcconf->chroot, &data) == 1) {
+		return BIO_new_mem_buf(data, -1);
+	}
+	return NULL;
+}
+
+#endif
 
 /*
  * this functions is derived from apps/verify.c in OpenSSL0.9.5
@@ -499,26 +498,9 @@
 	else 
 		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
 
-#ifndef ANDROID_CHANGES
-	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
-	if (lookup == NULL)
-		goto end;
-
-	X509_LOOKUP_load_file(lookup, CAfile, 
-	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
-
-	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
-	if (lookup == NULL)
-		goto end;
-	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
-	if(!error) {
-		error = -1;
-		goto end;
-	}
-	error = -1;	/* initialized */
-#else
-	if (CAfile) {
-		BIO *bio = BIO_from_keystore(CAfile);
+#ifdef ANDROID_CHANGES
+	if (lcconf->chroot) {
+		BIO *bio = BIO_from_android(CApath);
 		STACK_OF(X509_INFO) *stack;
 		X509_INFO *info;
 		int i;
@@ -541,6 +523,25 @@
 			}
 		}
 		sk_X509_INFO_pop_free(stack, X509_INFO_free);
+	} else {
+#endif
+	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+	if (lookup == NULL)
+		goto end;
+
+	X509_LOOKUP_load_file(lookup, CAfile, 
+	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
+
+	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
+	if (lookup == NULL)
+		goto end;
+	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
+	if(!error) {
+		error = -1;
+		goto end;
+	}
+	error = -1;	/* initialized */
+#ifdef ANDROID_CHANGES
 	}
 #endif
 
@@ -955,19 +956,23 @@
 	int error;
 
 #ifdef ANDROID_CHANGES
-	BIO *bio = BIO_from_keystore(path);
-	x509 = NULL;
-	if (bio) {
+	if (lcconf->chroot) {
+		BIO *bio = BIO_from_android(path);
+		if (!bio) {
+			return NULL;
+		}
 		x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
 		BIO_free(bio);
-	}
-#else
+	} else {
+#endif
 	/* Read private key */
 	fp = fopen(path, "r");
 	if (fp == NULL)
 		return NULL;
 	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
 	fclose (fp);
+#ifdef ANDROID_CHANGES
+	}
 #endif
 
 	if (x509 == NULL)
@@ -1057,12 +1062,15 @@
 	int error = -1;
 
 #ifdef ANDROID_CHANGES
-	BIO *bio = BIO_from_keystore(path);
-	if (bio) {
+	if (lcconf->chroot) {
+		BIO *bio = BIO_from_android(path);
+		if (!bio) {
+			return NULL;
+		}
 		evp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
 		BIO_free(bio);
-	}
-#else
+	} else {
+#endif
 	/* Read private key */
 	fp = fopen(path, "r");
 	if (fp == NULL)
@@ -1071,6 +1079,8 @@
 	evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
 
 	fclose (fp);
+#ifdef ANDROID_CHANGES
+	}
 #endif
 
 	if (evp == NULL)