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
*/
.public = {
.update_status = _update_status,
.bypass_socket = _bypass_socket,
+ .get_trusted_certificates = _get_trusted_certificates,
},
.vpn_service = (*env)->NewGlobalRef(env, service),
);
#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;
*/
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);
+
};
/**
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;
}
/**
+ * 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
*/
public native void initializeCharon();