From: Tobias Brunner Date: Sun, 23 Sep 2012 07:00:34 +0000 (+0200) Subject: android: Added a method to get the user's private key via JNI X-Git-Tag: 5.0.1~48 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=406d680e45303a4652f0829207b56348357362f2;p=thirdparty%2Fstrongswan.git android: Added a method to get the user's private key via JNI --- diff --git a/src/frontends/android/jni/libandroidbridge/charonservice.c b/src/frontends/android/jni/libandroidbridge/charonservice.c index 59ec62fc76..ef4d42edfb 100644 --- a/src/frontends/android/jni/libandroidbridge/charonservice.c +++ b/src/frontends/android/jni/libandroidbridge/charonservice.c @@ -25,6 +25,7 @@ #include "android_jni.h" #include "backend/android_attr.h" #include "backend/android_creds.h" +#include "backend/android_private_key.h" #include "backend/android_service.h" #include "kernel/android_ipsec.h" #include "kernel/android_net.h" @@ -275,7 +276,7 @@ METHOD(charonservice_t, get_user_certificate, linked_list_t*, { goto failed; } - jencodings = (*env)->CallObjectMethod(env, this->vpn_service, method_id, NULL); + jencodings = (*env)->CallObjectMethod(env, this->vpn_service, method_id); if (!jencodings) { goto failed; @@ -290,6 +291,39 @@ failed: return NULL; } +METHOD(charonservice_t, get_user_key, private_key_t*, + private_charonservice_t *this, public_key_t *pubkey) +{ + JNIEnv *env; + jmethodID method_id; + private_key_t *key; + jobject jkey; + + androidjni_attach_thread(&env); + + method_id = (*env)->GetMethodID(env, + android_charonvpnservice_class, + "getUserKey", "()Ljava/security/PrivateKey;"); + if (!method_id) + { + goto failed; + } + jkey = (*env)->CallObjectMethod(env, this->vpn_service, method_id); + if (!jkey) + { + goto failed; + } + key = android_private_key_create(jkey, pubkey); + androidjni_detach_thread(); + return key; + +failed: + DESTROY_IF(pubkey); + androidjni_exception_occurred(env); + androidjni_detach_thread(); + return NULL; +} + METHOD(charonservice_t, get_vpnservice_builder, vpnservice_builder_t*, private_charonservice_t *this) { @@ -364,6 +398,7 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder) .bypass_socket = _bypass_socket, .get_trusted_certificates = _get_trusted_certificates, .get_user_certificate = _get_user_certificate, + .get_user_key = _get_user_key, .get_vpnservice_builder = _get_vpnservice_builder, }, .attr = android_attr_create(), diff --git a/src/frontends/android/jni/libandroidbridge/charonservice.h b/src/frontends/android/jni/libandroidbridge/charonservice.h index 507010badf..367c76cd08 100644 --- a/src/frontends/android/jni/libandroidbridge/charonservice.h +++ b/src/frontends/android/jni/libandroidbridge/charonservice.h @@ -96,6 +96,14 @@ struct charonservice_t { */ linked_list_t *(*get_user_certificate)(charonservice_t *this); + /** + * Get the configured private key via JNI + * + * @param pubkey the public key as extracted from the certificate + * @return PrivateKey object, NULL on failure + */ + private_key_t *(*get_user_key)(charonservice_t *this, public_key_t *pubkey); + /** * Get the current vpnservice_builder_t object * diff --git a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java index 3a91c2f236..966fdb9246 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java @@ -461,6 +461,23 @@ public class CharonVpnService extends VpnService implements Runnable return encodings.toArray(new byte[encodings.size()][]); } + /** + * Function called via JNI to get the private key the user selected. + * + * Since this method is called from a thread of charon's thread pool we are safe + * to call methods on KeyChain directly. + * + * @return the private key + * @throws InterruptedException + * @throws KeyChainException + * @throws CertificateEncodingException + */ + private PrivateKey getUserKey() throws KeyChainException, InterruptedException + { + return KeyChain.getPrivateKey(getApplicationContext(), mCurrentUserCertificateAlias); + + } + /** * Initialization of charon, provided by libandroidbridge.so *