aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-09-26 18:35:59 +0200
committerTobias Brunner <tobias@strongswan.org>2017-11-08 16:48:10 +0100
commit72b7c0ffd820895e73973108426c47123499c78f (patch)
treebd7146b3ed5ec03e576fef354be3b5ca53c87e2d /src
parent414f2555617a70c95490df0ca8d9796b933bd5b4 (diff)
downloadstrongswan-72b7c0ffd820895e73973108426c47123499c78f.tar.bz2
strongswan-72b7c0ffd820895e73973108426c47123499c78f.tar.xz
android: Add support for creating RSASSA-PSS signatures via JNI
Diffstat (limited to 'src')
-rw-r--r--src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_private_key.c144
1 files changed, 142 insertions, 2 deletions
diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_private_key.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_private_key.c
index 4e49c2e4d..21043f6f4 100644
--- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_private_key.c
+++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_private_key.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2012-2014 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2012-2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,6 +18,7 @@
#include "../android_jni.h"
#include <utils/debug.h>
#include <asn1/asn1.h>
+#include <credentials/keys/signature_params.h>
typedef struct private_private_key_t private_private_key_t;
@@ -52,6 +53,113 @@ struct private_private_key_t {
refcount_t ref;
};
+/**
+ * Get the Java name for the given hash algorithm
+ */
+static jstring hash_name(JNIEnv *env, hash_algorithm_t alg)
+{
+ const char *hash = NULL;
+
+ switch (alg)
+ {
+ case HASH_SHA1:
+ hash = "SHA-1";
+ break;
+ case HASH_SHA224:
+ hash = "SHA-224";
+ break;
+ case HASH_SHA256:
+ hash = "SHA-256";
+ break;
+ case HASH_SHA384:
+ hash = "SHA-384";
+ break;
+ case HASH_SHA512:
+ hash = "SHA-512";
+ break;
+ default:
+ return NULL;
+ }
+ return (*env)->NewStringUTF(env, hash);
+}
+
+/**
+ * Set PSSParameterSpec on Signature object
+ */
+static bool set_pss_params(private_private_key_t *this, JNIEnv *env,
+ jobject jsignature, rsa_pss_params_t *pss)
+{
+ jmethodID method_id;
+ jclass cls;
+ jstring jhash, jmgf1;
+ jobject obj;
+ int slen;
+
+ /* create MGF1ParameterSpec instance */
+ cls = (*env)->FindClass(env, "java/security/spec/MGF1ParameterSpec");
+ if (!cls)
+ {
+ return FALSE;
+ }
+ method_id = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
+ if (!method_id)
+ {
+ return FALSE;
+ }
+ jhash = hash_name(env, pss->mgf1_hash);
+ if (!jhash)
+ {
+ return FALSE;
+ }
+ obj = (*env)->NewObject(env, cls, method_id, jhash);
+ if (!obj)
+ {
+ return FALSE;
+ }
+ /* create PSSParameterSpec instance */
+ cls = (*env)->FindClass(env, "java/security/spec/PSSParameterSpec");
+ if (!cls)
+ {
+ return FALSE;
+ }
+ method_id = (*env)->GetMethodID(env, cls, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;"
+ "Ljava/security/spec/AlgorithmParameterSpec;II)V");
+ if (!method_id)
+ {
+ return FALSE;
+ }
+ jhash = hash_name(env, pss->hash);
+ jmgf1 = (*env)->NewStringUTF(env, "MGF1");
+ if (!jhash || !jmgf1)
+ {
+ return FALSE;
+ }
+ slen = hasher_hash_size(pss->hash);
+ if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ slen = pss->salt_len;
+ }
+ obj = (*env)->NewObject(env, cls, method_id, jhash, jmgf1, obj, slen, 1);
+ if (!obj)
+ {
+ return FALSE;
+ }
+ /* update Signature instance */
+ method_id = (*env)->GetMethodID(env, this->signature_class, "setParameter",
+ "(Ljava/security/spec/AlgorithmParameterSpec;)V");
+ if (!method_id)
+ {
+ return FALSE;
+ }
+ (*env)->CallVoidMethod(env, jsignature, method_id, obj);
+ if (androidjni_exception_occurred(env))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(private_key_t, sign, bool,
private_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
@@ -59,6 +167,7 @@ METHOD(private_key_t, sign, bool,
JNIEnv *env;
jmethodID method_id;
const char *method = NULL;
+ rsa_pss_params_t *pss = NULL;
jstring jmethod;
jobject jsignature;
jbyteArray jdata, jsigarray;
@@ -89,6 +198,33 @@ METHOD(private_key_t, sign, bool,
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
method = "SHA512withRSA";
break;
+ case SIGN_RSA_EMSA_PSS:
+ if (!params)
+ {
+ return FALSE;
+ }
+ pss = params;
+ switch (pss->hash)
+ {
+ case HASH_SHA1:
+ method = "SHA1withRSA/PSS";
+ break;
+ case HASH_SHA224:
+ method = "SHA224withRSA/PSS";
+ break;
+ case HASH_SHA256:
+ method = "SHA256withRSA/PSS";
+ break;
+ case HASH_SHA384:
+ method = "SHA384withRSA/PSS";
+ break;
+ case HASH_SHA512:
+ method = "SHA512withRSA/PSS";
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -145,6 +281,10 @@ METHOD(private_key_t, sign, bool,
{
goto failed;
}
+ if (pss && !set_pss_params(this, env, jsignature, pss))
+ {
+ goto failed;
+ }
method_id = (*env)->GetMethodID(env, this->signature_class, "initSign",
"(Ljava/security/PrivateKey;)V");
if (!method_id)