android: Added a method to get the user's private key via JNI

This commit is contained in:
Tobias Brunner
2012-09-24 17:12:18 +02:00
parent c35d468fb1
commit 406d680e45
3 changed files with 61 additions and 1 deletions
@@ -25,6 +25,7 @@
#include "android_jni.h" #include "android_jni.h"
#include "backend/android_attr.h" #include "backend/android_attr.h"
#include "backend/android_creds.h" #include "backend/android_creds.h"
#include "backend/android_private_key.h"
#include "backend/android_service.h" #include "backend/android_service.h"
#include "kernel/android_ipsec.h" #include "kernel/android_ipsec.h"
#include "kernel/android_net.h" #include "kernel/android_net.h"
@@ -275,7 +276,7 @@ METHOD(charonservice_t, get_user_certificate, linked_list_t*,
{ {
goto failed; goto failed;
} }
jencodings = (*env)->CallObjectMethod(env, this->vpn_service, method_id, NULL); jencodings = (*env)->CallObjectMethod(env, this->vpn_service, method_id);
if (!jencodings) if (!jencodings)
{ {
goto failed; goto failed;
@@ -290,6 +291,39 @@ failed:
return NULL; 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*, METHOD(charonservice_t, get_vpnservice_builder, vpnservice_builder_t*,
private_charonservice_t *this) private_charonservice_t *this)
{ {
@@ -364,6 +398,7 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
.bypass_socket = _bypass_socket, .bypass_socket = _bypass_socket,
.get_trusted_certificates = _get_trusted_certificates, .get_trusted_certificates = _get_trusted_certificates,
.get_user_certificate = _get_user_certificate, .get_user_certificate = _get_user_certificate,
.get_user_key = _get_user_key,
.get_vpnservice_builder = _get_vpnservice_builder, .get_vpnservice_builder = _get_vpnservice_builder,
}, },
.attr = android_attr_create(), .attr = android_attr_create(),
@@ -96,6 +96,14 @@ struct charonservice_t {
*/ */
linked_list_t *(*get_user_certificate)(charonservice_t *this); 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 * Get the current vpnservice_builder_t object
* *
@@ -461,6 +461,23 @@ public class CharonVpnService extends VpnService implements Runnable
return encodings.toArray(new byte[encodings.size()][]); 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 * Initialization of charon, provided by libandroidbridge.so
* *