aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2012-03-15 09:42:07 -0700
committerKenny Root <kroot@google.com>2012-03-26 14:52:55 -0700
commitc1b51d45a7363d6fa58b59bf6f12182993a7c1d0 (patch)
treeafb89cab2b7f5f2f0f0a3adce51c8791dfb9726b
parentc91307af2622f6625525f3c1f9c954376df950ad (diff)
downloadipsec-tools-c1b51d45a7363d6fa58b59bf6f12182993a7c1d0.tar.gz
Add support for OpenSSL ENGINE for keystore
keystore now has an OpenSSL ENGINE frontend that can be used to ask for private keys or public keys to be loaded and also signing operations to take place. Use that instead of the crazy byte-array marshalling of the private key material that is used for the "privsep" stuff. Change-Id: I6171ca1fb0e77e338c19f04d8c34ad7744984b63
-rw-r--r--Android.mk4
-rw-r--r--main.c16
-rw-r--r--src/racoon/oakley.c45
3 files changed, 63 insertions, 2 deletions
diff --git a/Android.mk b/Android.mk
index 3a1c65f..c7ac4d7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -62,7 +62,7 @@ LOCAL_STATIC_LIBRARIES := libipsec
LOCAL_SHARED_LIBRARIES := libcutils libcrypto
-LOCAL_CFLAGS := -DANDROID_CHANGES -DHAVE_CONFIG_H
+LOCAL_CFLAGS := -DANDROID_CHANGES -DHAVE_CONFIG_H -DHAVE_OPENSSL_ENGINE_H
LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers
@@ -78,7 +78,7 @@ LOCAL_SRC_FILES := \
src/libipsec/pfkey.c \
src/libipsec/ipsec_strerror.c
-LOCAL_CFLAGS := -DHAVE_CONFIG_H
+LOCAL_CFLAGS := -DHAVE_CONFIG_H -DHAVE_OPENSSL_ENGINE_H
LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers
diff --git a/main.c b/main.c
index 2976ecc..d2e815e 100644
--- a/main.c
+++ b/main.c
@@ -27,6 +27,8 @@
#ifdef ANDROID_CHANGES
+#include <openssl/engine.h>
+
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -156,9 +158,17 @@ int main(int argc, char **argv)
{
#ifdef ANDROID_CHANGES
int control = android_get_control_and_arguments(&argc, &argv);
+ ENGINE *e;
if (control != -1) {
pname = "%p";
monitor_fd(control, NULL);
+
+ ENGINE_load_dynamic();
+ e = ENGINE_by_id("keystore");
+ if (!e || !ENGINE_init(e)) {
+ do_plog(LLV_ERROR, "ipsec-tools: cannot load keystore engine");
+ exit(1);
+ }
}
#endif
@@ -194,6 +204,12 @@ int main(int argc, char **argv)
}
}
}
+#ifdef ANDROID_CHANGES
+ if (e) {
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ }
+#endif
return 0;
}
diff --git a/src/racoon/oakley.c b/src/racoon/oakley.c
index 183ac2f..c446bbb 100644
--- a/src/racoon/oakley.c
+++ b/src/racoon/oakley.c
@@ -40,6 +40,9 @@
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
+#ifdef ANDROID_CHANGES
+#include <openssl/engine.h>
+#endif
#include <stdlib.h>
#include <stdio.h>
@@ -1799,6 +1802,44 @@ end:
}
#endif
+#ifdef ANDROID_CHANGES
+static vchar_t* keystore_sign(vchar_t* src, const char* path) {
+ vchar_t* sig = NULL;
+
+ ENGINE* e = ENGINE_by_id("keystore");
+ if (!e) {
+ return NULL;
+ }
+
+ if (!ENGINE_init(e)) {
+ ENGINE_free(e);
+ return NULL;
+ }
+
+ const char *key_id;
+ if (sscanf(path, pname, &key_id) != 1) {
+ do_plog(LLV_ERROR, "couldn't read private key info\n");
+ return NULL;
+ }
+
+ EVP_PKEY* evp = ENGINE_load_private_key(e, key_id, NULL, NULL);
+ if (!evp) {
+ do_plog(LLV_ERROR, "couldn't retrieve private key");
+ ERR_clear_error();
+ return NULL;
+ }
+
+ sig = eay_rsa_sign(src, evp->pkey.rsa);
+
+ EVP_PKEY_free(evp);
+
+ ENGINE_finish(e);
+ ENGINE_free(e);
+
+ return sig;
+}
+#endif
+
/* get signature */
int
oakley_getsign(iph1)
@@ -1820,6 +1861,9 @@ oakley_getsign(iph1)
getpathname(path, sizeof(path),
LC_PATHTYPE_CERT,
iph1->rmconf->myprivfile);
+#ifdef ANDROID_CHANGES
+ iph1->sig = keystore_sign(iph1->hash, path);
+#else
privkey = privsep_eay_get_pkcs1privkey(path);
if (privkey == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
@@ -1830,6 +1874,7 @@ oakley_getsign(iph1)
plogdump(LLV_DEBUG2, privkey->v, privkey->l);
iph1->sig = eay_get_x509sign(iph1->hash, privkey);
+#endif
break;
#ifndef ANDROID_PATCHED
case ISAKMP_CERT_PLAINRSA: