1196 lines
30 KiB
C
1196 lines
30 KiB
C
/* jni_rsa.c
|
|
*
|
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef WOLFSSL_USER_SETTINGS
|
|
#include <wolfssl/wolfcrypt/settings.h>
|
|
#elif !defined(__ANDROID__)
|
|
#include <wolfssl/options.h>
|
|
#endif
|
|
#include <wolfssl/wolfcrypt/rsa.h>
|
|
#include <wolfssl/wolfcrypt/asn.h>
|
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
|
#include <wolfssl/wolfcrypt/misc.h>
|
|
|
|
#include <com_wolfssl_wolfcrypt_Rsa.h>
|
|
#include <wolfcrypt_jni_NativeStruct.h>
|
|
#include <wolfcrypt_jni_error.h>
|
|
|
|
/* #define WOLFCRYPT_JNI_DEBUG_ON */
|
|
#include <wolfcrypt_jni_debug.h>
|
|
|
|
#if !defined(WC_NO_RNG) && defined(NO_OLD_RNGNAME)
|
|
#define RNG WC_RNG
|
|
#endif
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_mallocNativeStruct(
|
|
JNIEnv* env, jobject this)
|
|
{
|
|
#ifndef NO_RSA
|
|
RsaKey* rsa = NULL;
|
|
|
|
rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (rsa == NULL) {
|
|
throwOutOfMemoryException(env, "Failed to allocate Rsa object");
|
|
}
|
|
else {
|
|
XMEMSET(rsa, 0, sizeof(RsaKey));
|
|
}
|
|
|
|
LogStr("new Rsa() = %p\n", rsa);
|
|
|
|
return (jlong)(uintptr_t)rsa;
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
|
|
return (jlong)0;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Rsa_getDefaultRsaExponent
|
|
(JNIEnv *env, jclass jcl)
|
|
{
|
|
(void)env;
|
|
(void)jcl;
|
|
|
|
#ifndef NO_RSA
|
|
return WC_RSA_EXPONENT;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Rsa_rsaMinSize
|
|
(JNIEnv *env, jclass jcl)
|
|
{
|
|
(void)env;
|
|
(void)jcl;
|
|
|
|
return (jint)RSA_MIN_SIZE;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_MakeRsaKey(
|
|
JNIEnv *env, jobject this, jint size, jlong e, jobject rng_object)
|
|
{
|
|
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
RNG* rng = NULL;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
rng = (RNG*) getNativeStruct(env, rng_object);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
if (key == NULL || rng == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_MakeRsaKey(key, size, (long)e, rng);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_MakeRsaKey(%d, %lu) = %d\n", size, e, ret);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecodeRaw__Ljava_nio_ByteBuffer_2JLjava_nio_ByteBuffer_2J(
|
|
JNIEnv* env, jobject this, jobject n_object, jlong nSize, jobject e_object,
|
|
jlong eSize)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* n = NULL;
|
|
byte* e = NULL;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
n = getDirectBufferAddress(env, n_object);
|
|
e = getDirectBufferAddress(env, e_object);
|
|
|
|
if (key == NULL || n == NULL || e == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaPublicKeyDecodeRaw(n, (long)nSize, e, (long)eSize, key);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz) = %d\n", ret);
|
|
LogStr("n[%u]: [%p]\n", (word32)nSize, n);
|
|
LogHex((byte*) n, 0, nSize);
|
|
LogStr("e[%u]: [%p]\n", (word32)eSize, e);
|
|
LogHex((byte*) e, 0, eSize);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecodeRaw___3BJ_3BJ(
|
|
JNIEnv* env, jobject this, jbyteArray n_object, jlong nSize,
|
|
jbyteArray e_object, jlong eSize)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* n = NULL;
|
|
byte* e = NULL;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
n = getByteArray(env, n_object);
|
|
e = getByteArray(env, e_object);
|
|
|
|
if (key == NULL || n == NULL || e == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaPublicKeyDecodeRaw(n, (long)nSize, e, (long)eSize, key);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz) = %d\n", ret);
|
|
LogStr("n[%u]: [%p]\n", (word32)nSize, n);
|
|
LogHex((byte*) n, 0, nSize);
|
|
LogStr("e[%u]: [%p]\n", (word32)eSize, e);
|
|
LogHex((byte*) e, 0, eSize);
|
|
|
|
releaseByteArray(env, n_object, n, JNI_ABORT);
|
|
releaseByteArray(env, e_object, e, JNI_ABORT);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey__Ljava_nio_ByteBuffer_2Ljava_nio_ByteBuffer_2(
|
|
JNIEnv* env, jobject this, jobject n_object, jobject e_object)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* n = NULL;
|
|
byte* e = NULL;
|
|
word32 nSize = 0, eSize = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
n = getDirectBufferAddress(env, n_object);
|
|
e = getDirectBufferAddress(env, e_object);
|
|
nSize = n ? getDirectBufferLimit(env, n_object) : 0;
|
|
eSize = e ? getDirectBufferLimit(env, e_object) : 0;
|
|
|
|
if (key == NULL || n == NULL || e == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaFlattenPublicKey(key, e, &eSize, n, &nSize);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
} else {
|
|
|
|
setDirectBufferLimit(env, n_object, nSize);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
return;
|
|
}
|
|
|
|
setDirectBufferLimit(env, e_object, eSize);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
LogStr("wc_RsaFlattenPublicKey(key, e, eSz, n, nSz) = %d\n", ret);
|
|
LogStr("n[%u]: [%p]\n", (word32)nSize, n);
|
|
LogHex((byte*) n, 0, nSize);
|
|
LogStr("e[%u]: [%p]\n", (word32)eSize, e);
|
|
LogHex((byte*) e, 0, eSize);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey___3B_3J_3B_3J(
|
|
JNIEnv* env, jobject this, jbyteArray n_object, jlongArray nSize,
|
|
jbyteArray e_object, jlongArray eSize)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* n = NULL;
|
|
byte* e = NULL;
|
|
jlong nSz;
|
|
jlong eSz;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
n = getByteArray(env, n_object);
|
|
e = getByteArray(env, e_object);
|
|
|
|
(*env)->GetLongArrayRegion(env, nSize, 0, 1, &nSz);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
return;
|
|
}
|
|
|
|
(*env)->GetLongArrayRegion(env, eSize, 0, 1, &eSz);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
releaseByteArray(env, n_object, n, ret);
|
|
return;
|
|
}
|
|
|
|
if (key == NULL || n == NULL || e == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaFlattenPublicKey(key, e, (word32*) &eSz, n, (word32*) &nSz);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
} else {
|
|
|
|
(*env)->SetLongArrayRegion(env, nSize, 0, 1, &nSz);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
releaseByteArray(env, n_object, n, ret);
|
|
releaseByteArray(env, e_object, e, ret);
|
|
return;
|
|
}
|
|
|
|
(*env)->SetLongArrayRegion(env, eSize, 0, 1, &eSz);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
releaseByteArray(env, n_object, n, ret);
|
|
releaseByteArray(env, e_object, e, ret);
|
|
return;
|
|
}
|
|
}
|
|
|
|
LogStr("RsaFlattenPublicKey(key, e, eSz, n, nSz) = %d\n", ret);
|
|
LogStr("n[%u]: [%p]\n", (word32)nSz, n);
|
|
LogHex((byte*) n, 0, nSz);
|
|
LogStr("e[%u]: [%p]\n", (word32)eSz, e);
|
|
LogHex((byte*) e, 0, eSz);
|
|
|
|
releaseByteArray(env, n_object, n, ret);
|
|
releaseByteArray(env, e_object, e, ret);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaKeyToDer
|
|
(JNIEnv* env, jobject this)
|
|
{
|
|
jbyteArray result = NULL;
|
|
#if !defined(NO_RSA) && (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* output = NULL;
|
|
word32 outputSz = 0;
|
|
word32 outputBufSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0 && key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
/* Get length of DER encoded RSA private key */
|
|
if (ret == 0) {
|
|
ret = wc_RsaKeyToDer(key, NULL, 0);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
outputBufSz = outputSz;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
/* Allocate temp buffer to hold DER encoded key */
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaKeyToDer(key, output, outputSz);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env, "Failed NewByteArray() for DER key");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaKeyToDer() = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XMEMSET(output, 0, outputBufSz);
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaKeyToPublicDer
|
|
(JNIEnv* env, jobject this)
|
|
{
|
|
jbyteArray result = NULL;
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* output = NULL;
|
|
word32 outputSz = 0;
|
|
word32 outputBufSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0 && key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
/* Get length of DER encoded RSA private key */
|
|
if (ret == 0) {
|
|
ret = wc_RsaKeyToPublicDer(key, NULL, 0);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
outputBufSz = outputSz;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
/* Allocate temp buffer to hold DER encoded key */
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaKeyToPublicDer(key, output, outputSz);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env,
|
|
"Failed NewByteArray() for DER public key");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaKeyToPublicDer() = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XMEMSET(output, 0, outputBufSz);
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyToPkcs8
|
|
(JNIEnv* env, jobject this)
|
|
{
|
|
jbyteArray result = NULL;
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* derKey = NULL;
|
|
byte* pkcs8 = NULL;
|
|
word32 derKeySz = 0;
|
|
word32 pkcs8Sz = 0;
|
|
|
|
/* Keep track of malloc sizes for memset cleanup */
|
|
word32 derKeyBufSz = 0;
|
|
word32 pkcs8BufSz = 0;
|
|
|
|
int algoID = RSAk;
|
|
word32 oidSz = 0;
|
|
const byte* curveOID = NULL;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0 && key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
/* Get length of DER encoded RSA private key */
|
|
if (ret == 0) {
|
|
ret = wc_RsaKeyToDer(key, NULL, 0);
|
|
if (ret > 0) {
|
|
derKeySz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
/* Get PKCS#8 output size, into pkcs8Sz */
|
|
if (ret == 0) {
|
|
ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, derKey, derKeySz, algoID,
|
|
curveOID, oidSz);
|
|
if (ret == LENGTH_ONLY_E) {
|
|
pkcs8 = (byte*)XMALLOC(pkcs8Sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (pkcs8 == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
else {
|
|
XMEMSET(pkcs8, 0, pkcs8Sz);
|
|
pkcs8BufSz = pkcs8Sz;
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
/* Allocate temp buffer to hold DER encoded key */
|
|
derKey = (byte*)XMALLOC(derKeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (derKey == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
else {
|
|
XMEMSET(derKey, 0, derKeySz);
|
|
derKeyBufSz = derKeySz;
|
|
}
|
|
}
|
|
|
|
/* Get DER encoded RSA private key */
|
|
if (ret == 0) {
|
|
ret = wc_RsaKeyToDer(key, derKey, derKeySz);
|
|
if (ret > 0) {
|
|
derKeySz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
/* Create PKCS#8 from DER key */
|
|
if (ret == 0) {
|
|
ret = wc_CreatePKCS8Key(pkcs8, &pkcs8Sz, derKey, derKeySz,
|
|
algoID, curveOID, oidSz);
|
|
if (ret > 0) {
|
|
pkcs8Sz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
/* Create new Java byte[] and return */
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, pkcs8Sz);
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, pkcs8Sz,
|
|
(const jbyte*) pkcs8);
|
|
}
|
|
}
|
|
|
|
if (derKey != NULL) {
|
|
XMEMSET(derKey, 0, derKeyBufSz);
|
|
XFREE(derKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
if (pkcs8 != NULL) {
|
|
XMEMSET(pkcs8, 0, pkcs8BufSz);
|
|
XFREE(pkcs8, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif /* !NO_RSA */
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1InitRsaKey(
|
|
JNIEnv* env, jobject this)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
if (key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_InitRsaKey(key, NULL);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_InitRsaKey(key) = %d\n", ret);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1FreeRsaKey(
|
|
JNIEnv* env, jobject this)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
if (key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_FreeRsaKey(key);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_FreeRsaKey(key) = %d\n", ret);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSetRNG(
|
|
JNIEnv* env, jobject this, jobject rng_object)
|
|
{
|
|
#ifndef NO_RSA
|
|
|
|
#ifdef WC_RSA_BLINDING
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
RNG* rng = NULL;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return JNI_FALSE;
|
|
}
|
|
|
|
rng = (RNG*) getNativeStruct(env, rng_object);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return JNI_FALSE;
|
|
}
|
|
|
|
if (key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaSetRNG(key, rng);
|
|
}
|
|
|
|
LogStr("wc_RsaSetRNG(key, rng) = %d\n", ret);
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
else {
|
|
return JNI_TRUE;
|
|
}
|
|
#endif
|
|
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return JNI_FALSE;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecode(
|
|
JNIEnv* env, jobject this, jbyteArray key_object)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* k = NULL;
|
|
word32 kSz = 0, index = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
k = getByteArray(env, key_object);
|
|
kSz = getByteArrayLength(env, key_object);
|
|
|
|
if (key == NULL || k == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaPrivateKeyDecode(k, &index, key, kSz);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
releaseByteArray(env, key_object, k, JNI_ABORT);
|
|
|
|
LogStr("wc_RsaPrivateKeyDecode(k, kSize, key) = %d\n", ret);
|
|
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
|
|
LogHex((byte*) k, 0, kSz);
|
|
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecodePKCS8
|
|
(JNIEnv* env, jobject this, jbyteArray key_object)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
int length = 0;
|
|
RsaKey* key = NULL;
|
|
byte* k = NULL;
|
|
word32 kSz = 0, offset = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
k = getByteArray(env, key_object);
|
|
kSz = getByteArrayLength(env, key_object);
|
|
|
|
if (key == NULL || k == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0) {
|
|
length = wc_GetPkcs8TraditionalOffset(k, &offset, kSz);
|
|
if (length < 0) {
|
|
ret = length;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
ret = wc_RsaPrivateKeyDecode(k, &offset, key, kSz);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPrivateKeyDecodePKCS8(k, kSize, key) = %d\n", ret);
|
|
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
|
|
LogHex((byte*) k, 0, kSz);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecode
|
|
(JNIEnv* env, jobject this, jbyteArray key_object)
|
|
{
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* k = NULL;
|
|
word32 kSz = 0, index = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return;
|
|
}
|
|
|
|
k = getByteArray(env, key_object);
|
|
kSz = getByteArrayLength(env, key_object);
|
|
|
|
if (key == NULL || k == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaPublicKeyDecode(k, &index, key, kSz);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPublicKeyDecode(k, kSize, key) = %d\n", ret);
|
|
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
|
|
LogHex((byte*) k, 0, kSz);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaEncryptSize
|
|
(JNIEnv* env, jobject this)
|
|
{
|
|
jint ret = 0;
|
|
|
|
#ifndef NO_RSA
|
|
RsaKey* key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return 0;
|
|
}
|
|
|
|
if (key == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
else {
|
|
ret = wc_RsaEncryptSize(key);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaEncryptSize(key=%p) = %d\n", key, ret);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicEncrypt(
|
|
JNIEnv* env, jobject this, jbyteArray plaintext_object, jobject rng_object)
|
|
{
|
|
jbyteArray result = NULL;
|
|
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
RNG* rng = NULL;
|
|
byte* plaintext = NULL;
|
|
byte* output = NULL;
|
|
word32 size = 0, outputSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
rng = (RNG*) getNativeStruct(env, rng_object);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
plaintext = getByteArray(env, plaintext_object);
|
|
size = getByteArrayLength(env, plaintext_object);
|
|
|
|
if (key == NULL || rng == NULL || plaintext == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0) {
|
|
outputSz = wc_RsaEncryptSize(key);
|
|
if (outputSz < 0) {
|
|
ret = outputSz;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaPublicEncrypt(plaintext, size, output, outputSz, key, rng);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env, "Failed to create ciphertext array");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPublicEncrypt(in, inSz, out, outSz, key=, rng) = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
releaseByteArray(env, plaintext_object, plaintext, JNI_ABORT);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateDecrypt(
|
|
JNIEnv* env, jobject this, jbyteArray ciphertext_object)
|
|
{
|
|
jbyteArray result = NULL;
|
|
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* ciphertext = NULL;
|
|
byte* output = NULL;
|
|
word32 size = 0, outputSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
ciphertext = getByteArray(env, ciphertext_object);
|
|
size = getByteArrayLength(env, ciphertext_object);
|
|
|
|
if (key == NULL || ciphertext == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0) {
|
|
outputSz = wc_RsaEncryptSize(key);
|
|
if (outputSz < 0) {
|
|
ret = outputSz;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaPrivateDecrypt(ciphertext, size, output, outputSz, key);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env, "Failed to create plaintext array");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaPrivateDecrypt(in, inSz, out, outSz, key) = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
releaseByteArray(env, ciphertext_object, ciphertext, JNI_ABORT);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Sign(
|
|
JNIEnv* env, jobject this, jbyteArray data_object, jobject rng_object)
|
|
{
|
|
jbyteArray result = NULL;
|
|
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
RNG* rng = NULL;
|
|
byte* data = NULL;
|
|
byte* output = NULL;
|
|
word32 size = 0, outputSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
rng = (RNG*) getNativeStruct(env, rng_object);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
data = getByteArray(env, data_object);
|
|
size = getByteArrayLength(env, data_object);
|
|
|
|
if (key == NULL || rng == NULL || data == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0) {
|
|
outputSz = wc_RsaEncryptSize(key);
|
|
if (outputSz < 0) {
|
|
ret = outputSz;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaSSL_Sign(data, size, output, outputSz, key, rng);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env,
|
|
"Failed to create new signature array");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaSSL_Sign(in, inSz, out, outSz, key, rng) = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
releaseByteArray(env, data_object, data, JNI_ABORT);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Verify(
|
|
JNIEnv* env, jobject this, jbyteArray signature_object)
|
|
{
|
|
jbyteArray result = NULL;
|
|
#ifndef NO_RSA
|
|
int ret = 0;
|
|
RsaKey* key = NULL;
|
|
byte* signature = NULL;
|
|
byte* output = NULL;
|
|
word32 size = 0, outputSz = 0;
|
|
|
|
key = (RsaKey*) getNativeStruct(env, this);
|
|
if ((*env)->ExceptionOccurred(env)) {
|
|
/* getNativeStruct may throw exception, prevent throwing another */
|
|
return NULL;
|
|
}
|
|
|
|
signature = getByteArray(env, signature_object);
|
|
size = getByteArrayLength(env, signature_object);
|
|
|
|
if (key == NULL || signature == NULL) {
|
|
ret = BAD_FUNC_ARG;
|
|
}
|
|
|
|
if (ret == 0) {
|
|
outputSz = wc_RsaEncryptSize(key);
|
|
if (outputSz < 0) {
|
|
ret = outputSz;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
if (output == NULL) {
|
|
ret = MEMORY_E;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
XMEMSET(output, 0, outputSz);
|
|
|
|
ret = wc_RsaSSL_Verify(signature, size, output, outputSz, key);
|
|
if (ret > 0) {
|
|
outputSz = ret;
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
if (ret == 0) {
|
|
result = (*env)->NewByteArray(env, outputSz);
|
|
|
|
if (result) {
|
|
(*env)->SetByteArrayRegion(env, result, 0, outputSz,
|
|
(const jbyte*) output);
|
|
} else {
|
|
throwWolfCryptException(env, "Failed to create new verify array");
|
|
}
|
|
} else {
|
|
throwWolfCryptExceptionFromError(env, ret);
|
|
}
|
|
|
|
LogStr("wc_RsaSSL_Verify(in, inSz, out, outSz, key) = %d\n", ret);
|
|
LogStr("output[%u]: [%p]\n", outputSz, output);
|
|
LogHex((byte*) output, 0, outputSz);
|
|
|
|
if (output != NULL) {
|
|
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
releaseByteArray(env, signature_object, signature, JNI_ABORT);
|
|
#else
|
|
throwNotCompiledInException(env);
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|