CharonVpnService provides a function to get trusted certificates via JNI
This commit is contained in:
@@ -142,6 +142,53 @@ failed:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(charonservice_t, get_trusted_certificates, linked_list_t*,
|
||||
private_charonservice_t *this)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jobjectArray jcerts;
|
||||
linked_list_t *list;
|
||||
jsize i;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
method_id = (*env)->GetMethodID(env,
|
||||
android_charonvpnservice_class,
|
||||
"getTrustedCertificates", "(Ljava/lang/String;)[[B");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
jcerts = (*env)->CallObjectMethod(env, this->vpn_service, method_id, NULL);
|
||||
if (!jcerts)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
list = linked_list_create();
|
||||
for (i = 0; i < (*env)->GetArrayLength(env, jcerts); ++i)
|
||||
{
|
||||
chunk_t *ca_cert;
|
||||
jbyteArray jcert;
|
||||
|
||||
ca_cert = malloc_thing(chunk_t);
|
||||
list->insert_last(list, ca_cert);
|
||||
|
||||
jcert = (*env)->GetObjectArrayElement(env, jcerts, i);
|
||||
*ca_cert = chunk_alloc((*env)->GetArrayLength(env, jcert));
|
||||
(*env)->GetByteArrayRegion(env, jcert, 0, ca_cert->len, ca_cert->ptr);
|
||||
(*env)->DeleteLocalRef(env, jcert);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jcerts);
|
||||
androidjni_detach_thread();
|
||||
return list;
|
||||
|
||||
failed:
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the charonservice object
|
||||
*/
|
||||
@@ -159,6 +206,7 @@ static void charonservice_init(JNIEnv *env, jobject service)
|
||||
.public = {
|
||||
.update_status = _update_status,
|
||||
.bypass_socket = _bypass_socket,
|
||||
.get_trusted_certificates = _get_trusted_certificates,
|
||||
},
|
||||
.vpn_service = (*env)->NewGlobalRef(env, service),
|
||||
);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define CHARONSERVICE_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
typedef enum android_vpn_state_t android_vpn_state_t;
|
||||
typedef struct charonservice_t charonservice_t;
|
||||
@@ -71,6 +72,14 @@ struct charonservice_t {
|
||||
*/
|
||||
bool (*bypass_socket)(charonservice_t *this, int fd, int family);
|
||||
|
||||
/**
|
||||
* Get a list of trusted certificates via JNI
|
||||
*
|
||||
* @return list of DER encoded certificates (as chunk_t*),
|
||||
* NULL on failure
|
||||
*/
|
||||
linked_list_t *(*get_trusted_certificates)(charonservice_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
|
||||
package org.strongswan.android.logic;
|
||||
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.data.VpnProfileDataSource;
|
||||
import org.strongswan.android.logic.VpnStateService.ErrorState;
|
||||
@@ -328,6 +332,63 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called via JNI to generate a list of DER encoded CA certificates
|
||||
* as byte array.
|
||||
*
|
||||
* @param hash optional alias (only hash part), if given matching certificates are returned
|
||||
* @return a list of DER encoded CA certificates
|
||||
*/
|
||||
private synchronized byte[][] getTrustedCertificates(String hash)
|
||||
{
|
||||
ArrayList<byte[]> certs = new ArrayList<byte[]>();
|
||||
TrustedCertificateManager certman = TrustedCertificateManager.getInstance();
|
||||
try
|
||||
{
|
||||
if (hash != null)
|
||||
{
|
||||
String alias = "user:" + hash + ".0";
|
||||
X509Certificate cert = certman.getCACertificateFromAlias(alias);
|
||||
if (cert == null)
|
||||
{
|
||||
alias = "system:" + hash + ".0";
|
||||
cert = certman.getCACertificateFromAlias(alias);
|
||||
}
|
||||
if (cert == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
certs.add(cert.getEncoded());
|
||||
}
|
||||
else
|
||||
{
|
||||
String alias = this.mCurrentProfile.getCertificateAlias();
|
||||
if (alias != null)
|
||||
{
|
||||
X509Certificate cert = certman.getCACertificateFromAlias(alias);
|
||||
if (cert == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
certs.add(cert.getEncoded());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (X509Certificate cert : certman.getAllCACertificates().values())
|
||||
{
|
||||
certs.add(cert.getEncoded());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CertificateEncodingException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return certs.toArray(new byte[certs.size()][]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization of charon, provided by libandroidbridge.so
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user