android: Add support for creating RSASSA-PSS signatures via JNI
This commit is contained in:
+142
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2014 Tobias Brunner
|
* Copyright (C) 2012-2017 Tobias Brunner
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "../android_jni.h"
|
#include "../android_jni.h"
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <asn1/asn1.h>
|
#include <asn1/asn1.h>
|
||||||
|
#include <credentials/keys/signature_params.h>
|
||||||
|
|
||||||
typedef struct private_private_key_t private_private_key_t;
|
typedef struct private_private_key_t private_private_key_t;
|
||||||
|
|
||||||
@@ -52,6 +53,113 @@ struct private_private_key_t {
|
|||||||
refcount_t ref;
|
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,
|
METHOD(private_key_t, sign, bool,
|
||||||
private_private_key_t *this, signature_scheme_t scheme, void *params,
|
private_private_key_t *this, signature_scheme_t scheme, void *params,
|
||||||
chunk_t data, chunk_t *signature)
|
chunk_t data, chunk_t *signature)
|
||||||
@@ -59,6 +167,7 @@ METHOD(private_key_t, sign, bool,
|
|||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
jmethodID method_id;
|
jmethodID method_id;
|
||||||
const char *method = NULL;
|
const char *method = NULL;
|
||||||
|
rsa_pss_params_t *pss = NULL;
|
||||||
jstring jmethod;
|
jstring jmethod;
|
||||||
jobject jsignature;
|
jobject jsignature;
|
||||||
jbyteArray jdata, jsigarray;
|
jbyteArray jdata, jsigarray;
|
||||||
@@ -89,6 +198,33 @@ METHOD(private_key_t, sign, bool,
|
|||||||
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
|
||||||
method = "SHA512withRSA";
|
method = "SHA512withRSA";
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -145,6 +281,10 @@ METHOD(private_key_t, sign, bool,
|
|||||||
{
|
{
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
if (pss && !set_pss_params(this, env, jsignature, pss))
|
||||||
|
{
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
method_id = (*env)->GetMethodID(env, this->signature_class, "initSign",
|
method_id = (*env)->GetMethodID(env, this->signature_class, "initSign",
|
||||||
"(Ljava/security/PrivateKey;)V");
|
"(Ljava/security/PrivateKey;)V");
|
||||||
if (!method_id)
|
if (!method_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user