aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2014-07-08 13:56:54 +0200
committerTobias Brunner <tobias@strongswan.org>2014-07-22 10:41:51 +0200
commit7073bfe4e9a618eea5b27a18e22362b501bc4b30 (patch)
tree662dfa601ffa8c667de62d88fb28bcdde28b5db0
parent3dc92ff9cfaac6293e7643d24945f612103f7694 (diff)
downloadstrongswan-7073bfe4e9a618eea5b27a18e22362b501bc4b30.tar.bz2
strongswan-7073bfe4e9a618eea5b27a18e22362b501bc4b30.tar.xz
android: Add support for ECDSA private keys
With 4.4.4 these work fine now.
-rw-r--r--src/frontends/android/jni/libandroidbridge/backend/android_private_key.c123
1 files changed, 99 insertions, 24 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c b/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c
index 1aeabac2f..1985f0e98 100644
--- a/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c
+++ b/src/frontends/android/jni/libandroidbridge/backend/android_private_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -17,6 +17,7 @@
#include "../android_jni.h"
#include <utils/debug.h>
+#include <asn1/asn1.h>
typedef struct private_private_key_t private_private_key_t;
@@ -57,35 +58,62 @@ METHOD(private_key_t, sign, bool,
{
JNIEnv *env;
jmethodID method_id;
- const char *method;
+ const char *method = NULL;
jstring jmethod;
jobject jsignature;
jbyteArray jdata, jsigarray;
- switch (scheme)
+ switch (this->pubkey->get_type(this->pubkey))
{
- case SIGN_RSA_EMSA_PKCS1_MD5:
- method = "MD5withRSA";
+ case KEY_RSA:
+ switch (scheme)
+ {
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ method = "MD5withRSA";
+ break;
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ method = "SHA1withRSA";
+ break;
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ method = "SHA224withRSA";
+ break;
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ method = "SHA256withRSA";
+ break;
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ method = "SHA384withRSA";
+ break;
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ method = "SHA512withRSA";
+ break;
+ default:
+ break;
+ }
break;
- case SIGN_RSA_EMSA_PKCS1_SHA1:
- method = "SHA1withRSA";
- break;
- case SIGN_RSA_EMSA_PKCS1_SHA224:
- method = "SHA224withRSA";
- break;
- case SIGN_RSA_EMSA_PKCS1_SHA256:
- method = "SHA256withRSA";
- break;
- case SIGN_RSA_EMSA_PKCS1_SHA384:
- method = "SHA384withRSA";
- break;
- case SIGN_RSA_EMSA_PKCS1_SHA512:
- method = "SHA512withRSA";
+ case KEY_ECDSA:
+ switch (scheme)
+ {
+ case SIGN_ECDSA_256:
+ method = "SHA256withECDSA";
+ break;
+ case SIGN_ECDSA_384:
+ method = "SHA384withECDSA";
+ break;
+ case SIGN_ECDSA_521:
+ method = "SHA512withECDSA";
+ break;
+ default:
+ break;
+ }
break;
default:
- DBG1(DBG_LIB, "signature scheme %N not supported via JNI",
- signature_scheme_names, scheme);
- return FALSE;
+ break;
+ }
+ if (!method)
+ {
+ DBG1(DBG_LIB, "signature scheme %N not supported via JNI",
+ signature_scheme_names, scheme);
+ return FALSE;
}
androidjni_attach_thread(&env);
@@ -142,7 +170,54 @@ METHOD(private_key_t, sign, bool,
{
goto failed;
}
- *signature = chunk_from_byte_array(env, jsigarray);
+ if (this->pubkey->get_type(this->pubkey) == KEY_ECDSA)
+ {
+ chunk_t encoded, parse, r, s;
+ size_t len = 0;
+
+ switch (scheme)
+ {
+ case SIGN_ECDSA_256:
+ len = 32;
+ break;
+ case SIGN_ECDSA_384:
+ len = 48;
+ break;
+ case SIGN_ECDSA_521:
+ len = 66;
+ break;
+ default:
+ break;
+ }
+
+ /* we get an ASN.1 encoded sequence of integers r and s */
+ parse = encoded = chunk_from_byte_array(env, jsigarray);
+ if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE ||
+ asn1_unwrap(&parse, &r) != ASN1_INTEGER ||
+ asn1_unwrap(&parse, &s) != ASN1_INTEGER)
+ {
+ chunk_free(&encoded);
+ goto failed;
+ }
+ r = chunk_skip_zero(r);
+ s = chunk_skip_zero(s);
+ if (r.len > len || s.len > len)
+ {
+ chunk_free(&encoded);
+ goto failed;
+ }
+
+ /* concatenate r and s (forced to the defined length) */
+ *signature = chunk_alloc(2*len);
+ memset(signature->ptr, 0, signature->len);
+ memcpy(signature->ptr + (len - r.len), r.ptr, r.len);
+ memcpy(signature->ptr + len + (len - s.len), s.ptr, s.len);
+ chunk_free(&encoded);
+ }
+ else
+ {
+ *signature = chunk_from_byte_array(env, jsigarray);
+ }
androidjni_detach_thread();
return TRUE;
@@ -157,7 +232,7 @@ failed:
METHOD(private_key_t, get_type, key_type_t,
private_private_key_t *this)
{
- return KEY_RSA;
+ return this->pubkey->get_type(this->pubkey);
}
METHOD(private_key_t, decrypt, bool,