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 "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(),
@@ -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
*
@@ -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
*