JCE: add RSA support in KeyPairGenerator, Rsa supporting methods, native cleanup

pull/49/head
Chris Conlon 2023-06-05 10:43:09 -06:00
parent b964b59f02
commit 9401c82d31
8 changed files with 1082 additions and 177 deletions

View File

@ -65,6 +65,7 @@ The JCE provider currently supports the following algorithms:
ECDH
KeyPairGenerator Class
RSA
EC
DH

View File

@ -57,6 +57,30 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey___3B_3
JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_MakeRsaKey
(JNIEnv *, jobject, jint, jlong, jobject);
/*
* Class: com_wolfssl_wolfcrypt_Rsa
* Method: wc_RsaKeyToDer
* Signature: ()[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaKeyToDer
(JNIEnv *, jobject);
/*
* Class: com_wolfssl_wolfcrypt_Rsa
* Method: wc_RsaKeyToPublicDer
* Signature: ()[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaKeyToPublicDer
(JNIEnv *, jobject);
/*
* Class: com_wolfssl_wolfcrypt_Rsa
* Method: wc_RsaPrivateKeyToPkcs8
* Signature: ()[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyToPkcs8
(JNIEnv *, jobject);
/*
* Class: com_wolfssl_wolfcrypt_Rsa
* Method: wc_InitRsaKey
@ -145,6 +169,14 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Sign
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Verify
(JNIEnv *, jobject, jbyteArray);
/*
* Class: com_wolfssl_wolfcrypt_Rsa
* Method: getDefaultRsaExponent
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Rsa_getDefaultRsaExponent
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif

View File

@ -25,8 +25,10 @@
#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>
@ -43,20 +45,36 @@ JNIEXPORT jlong JNICALL
Java_com_wolfssl_wolfcrypt_Rsa_mallocNativeStruct(
JNIEnv* env, jobject this)
{
jlong ret = 0;
void* ret = NULL;
#ifndef NO_RSA
ret = (jlong) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (!ret)
ret = (void*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ret == NULL) {
throwOutOfMemoryException(env, "Failed to allocate Rsa object");
}
else {
XMEMSET(ret, 0, sizeof(RsaKey));
}
LogStr("new Rsa() = %p\n", (void*)ret);
#else
throwNotCompiledInException(env);
#endif
return ret;
return (jlong)ret;
}
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 void JNICALL
@ -87,10 +105,11 @@ Java_com_wolfssl_wolfcrypt_Rsa_MakeRsaKey(
ret = wc_MakeRsaKey(key, size, (long)e, rng);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("MakeRsaKey(%d, %lu) = %d\n", size, e, ret);
LogStr("wc_MakeRsaKey(%d, %lu) = %d\n", size, e, ret);
#else
throwNotCompiledInException(env);
#endif
@ -123,8 +142,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecodeRaw__Ljava_nio_ByteBuffer_2
ret = wc_RsaPublicKeyDecodeRaw(n, (long)nSize, e, (long)eSize, key);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz) = %d\n", ret);
LogStr("n[%u]: [%p]\n", (word32)nSize, n);
@ -163,8 +183,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecodeRaw___3BJ_3BJ(
ret = wc_RsaPublicKeyDecodeRaw(n, (long)nSize, e, (long)eSize, key);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz) = %d\n", ret);
LogStr("n[%u]: [%p]\n", (word32)nSize, n);
@ -201,9 +222,12 @@ Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey__Ljava_nio_ByteBuffer_2Ljava_
nSize = n ? getDirectBufferLimit(env, n_object) : 0;
eSize = e ? getDirectBufferLimit(env, e_object) : 0;
ret = (!key || !n || !e)
? BAD_FUNC_ARG
: wc_RsaFlattenPublicKey(key, e, &eSize, n, &nSize);
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);
@ -220,7 +244,7 @@ Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey__Ljava_nio_ByteBuffer_2Ljava_
}
}
LogStr("RsaFlattenPublicKey(key, e, eSz, n, nSz) = %d\n", ret);
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);
@ -263,9 +287,12 @@ Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey___3B_3J_3B_3J(
return;
}
ret = (!key || !n || !e)
? BAD_FUNC_ARG
: wc_RsaFlattenPublicKey(key, e, (word32*) &eSz, n, (word32*) &nSz);
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);
@ -299,6 +326,270 @@ Java_com_wolfssl_wolfcrypt_Rsa_RsaFlattenPublicKey___3B_3J_3B_3J(
#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) {
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) {
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)
@ -311,14 +602,18 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1InitRsaKey(
return;
}
ret = (!key)
? BAD_FUNC_ARG
: wc_InitRsaKey(key, NULL);
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_InitRsaKey(key, NULL);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("RsaInitKey(key) = %d\n", ret);
LogStr("wc_InitRsaKey(key) = %d\n", ret);
#else
throwNotCompiledInException(env);
#endif
@ -336,12 +631,16 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1FreeRsaKey(
return;
}
ret = (!key)
? BAD_FUNC_ARG
: wc_FreeRsaKey(key);
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_FreeRsaKey(key);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_FreeRsaKey(key) = %d\n", ret);
#else
@ -372,16 +671,21 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSetRNG(
return JNI_FALSE;
}
ret = (key == NULL)
? BAD_FUNC_ARG
: wc_RsaSetRNG(key, rng);
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_RsaSetRNG(key, rng);
}
LogStr("wc_RsaSetRNG(key, rng) = %d\n", ret);
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
else
}
else {
return JNI_TRUE;
}
#endif
#else
@ -410,18 +714,23 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecode(
k = getByteArray(env, key_object);
kSz = getByteArrayLength(env, key_object);
ret = (!key || !k)
? BAD_FUNC_ARG
: wc_RsaPrivateKeyDecode(k, &index, key, kSz);
if (key == NULL || k == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_RsaPrivateKeyDecode(k, &index, key, kSz);
}
if (ret != 0)
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);
releaseByteArray(env, key_object, k, JNI_ABORT);
#else
throwNotCompiledInException(env);
#endif
@ -446,18 +755,24 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecodePKC
k = getByteArray(env, key_object);
kSz = getByteArrayLength(env, key_object);
if (!key || !k) {
if (key == NULL || k == NULL) {
ret = BAD_FUNC_ARG;
} else {
length = wc_GetPkcs8TraditionalOffset(k, &offset, kSz);
ret = (length < 0)
? length
: wc_RsaPrivateKeyDecode(k, &offset, key, kSz);
}
if (ret != 0)
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);
@ -485,12 +800,16 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicKeyDecode
k = getByteArray(env, key_object);
kSz = getByteArrayLength(env, key_object);
ret = (!key || !k)
? BAD_FUNC_ARG
: wc_RsaPublicKeyDecode(k, &index, key, kSz);
if (key == NULL || k == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_RsaPublicKeyDecode(k, &index, key, kSz);
}
if (ret != 0)
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_RsaPublicKeyDecode(k, kSize, key) = %d\n", ret);
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
@ -512,15 +831,18 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaEncryptSize
return 0;
}
ret = (!key)
? BAD_FUNC_ARG
: wc_RsaEncryptSize(key);
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = wc_RsaEncryptSize(key);
}
if (ret < 0)
if (ret < 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_RsaEncryptSize(key=%p) = %d\n", key, ret);
#else
throwNotCompiledInException(env);
#endif
@ -556,30 +878,41 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicEncrypt(
plaintext = getByteArray(env, plaintext_object);
size = getByteArrayLength(env, plaintext_object);
outputSz = wc_RsaEncryptSize(key);
output = XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
throwOutOfMemoryException(env, "Failed to allocate ciphertext buffer");
releaseByteArray(env, plaintext_object, plaintext, JNI_ABORT);
return result;
if (key == NULL || rng == NULL || plaintext == NULL) {
ret = BAD_FUNC_ARG;
}
ret = (!key || !rng || !plaintext)
? BAD_FUNC_ARG
: wc_RsaPublicEncrypt(plaintext, size, output, outputSz, key, rng);
if (ret == 0) {
outputSz = wc_RsaEncryptSize(key);
if (outputSz < 0) {
ret = outputSz;
}
}
if (ret >= 0) {
outputSz = ret;
if (ret == 0) {
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
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);
(const jbyte*) output);
} else {
throwWolfCryptException(env, "Failed to allocate ciphertext");
throwWolfCryptException(env, "Failed to create ciphertext array");
}
} else {
throwWolfCryptExceptionFromError(env, ret);
@ -589,8 +922,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPublicEncrypt(
LogStr("output[%u]: [%p]\n", outputSz, output);
LogHex((byte*) output, 0, outputSz);
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output != NULL) {
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
releaseByteArray(env, plaintext_object, plaintext, JNI_ABORT);
#else
throwNotCompiledInException(env);
@ -620,30 +954,41 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateDecrypt(
ciphertext = getByteArray(env, ciphertext_object);
size = getByteArrayLength(env, ciphertext_object);
outputSz = wc_RsaEncryptSize(key);
output = XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
throwOutOfMemoryException(env, "Failed to allocate plaintext buffer");
releaseByteArray(env, ciphertext_object, ciphertext, JNI_ABORT);
return result;
if (key == NULL || ciphertext == NULL) {
ret = BAD_FUNC_ARG;
}
ret = (!key || !ciphertext)
? BAD_FUNC_ARG
: wc_RsaPrivateDecrypt(ciphertext, size, output, outputSz, key);
if (ret == 0) {
outputSz = wc_RsaEncryptSize(key);
if (outputSz < 0) {
ret = outputSz;
}
}
if (ret >= 0) {
outputSz = ret;
if (ret == 0) {
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
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);
(const jbyte*) output);
} else {
throwWolfCryptException(env, "Failed to allocate plaintext");
throwWolfCryptException(env, "Failed to create plaintext array");
}
} else {
throwWolfCryptExceptionFromError(env, ret);
@ -653,8 +998,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateDecrypt(
LogStr("output[%u]: [%p]\n", outputSz, output);
LogHex((byte*) output, 0, outputSz);
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output != NULL) {
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
releaseByteArray(env, ciphertext_object, ciphertext, JNI_ABORT);
#else
throwNotCompiledInException(env);
@ -691,30 +1037,42 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Sign(
data = getByteArray(env, data_object);
size = getByteArrayLength(env, data_object);
outputSz = wc_RsaEncryptSize(key);
output = XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
throwOutOfMemoryException(env, "Failed to allocate signature buffer");
releaseByteArray(env, data_object, data, JNI_ABORT);
return result;
if (key == NULL || rng == NULL || data == NULL) {
ret = BAD_FUNC_ARG;
}
ret = (!key || !rng || !data)
? BAD_FUNC_ARG
: wc_RsaSSL_Sign(data, size, output, outputSz, key, rng);
if (ret == 0) {
outputSz = wc_RsaEncryptSize(key);
if (outputSz < 0) {
ret = outputSz;
}
}
if (ret >= 0) {
outputSz = ret;
if (ret == 0) {
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
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);
(const jbyte*) output);
} else {
throwWolfCryptException(env, "Failed to allocate signature");
throwWolfCryptException(env,
"Failed to create new signature array");
}
} else {
throwWolfCryptExceptionFromError(env, ret);
@ -724,8 +1082,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Sign(
LogStr("output[%u]: [%p]\n", outputSz, output);
LogHex((byte*) output, 0, outputSz);
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output != NULL) {
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
releaseByteArray(env, data_object, data, JNI_ABORT);
#else
throwNotCompiledInException(env);
@ -739,7 +1098,6 @@ 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;
@ -755,30 +1113,41 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Verify(
signature = getByteArray(env, signature_object);
size = getByteArrayLength(env, signature_object);
outputSz = wc_RsaEncryptSize(key);
output = XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
throwOutOfMemoryException(env, "Failed to allocate verify buffer");
releaseByteArray(env, signature_object, signature, JNI_ABORT);
return result;
if (key == NULL || signature == NULL) {
ret = BAD_FUNC_ARG;
}
ret = (!key || !signature)
? BAD_FUNC_ARG
: wc_RsaSSL_Verify(signature, size, output, outputSz, key);
if (ret == 0) {
outputSz = wc_RsaEncryptSize(key);
if (outputSz < 0) {
ret = outputSz;
}
}
if (ret >= 0) {
outputSz = ret;
if (ret == 0) {
output = (byte*)XMALLOC(outputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
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);
(const jbyte*) output);
} else {
throwWolfCryptException(env, "Failed to allocate verify");
throwWolfCryptException(env, "Failed to create new verify array");
}
} else {
throwWolfCryptExceptionFromError(env, ret);
@ -788,8 +1157,9 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Verify(
LogStr("output[%u]: [%p]\n", outputSz, output);
LogHex((byte*) output, 0, outputSz);
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (output != NULL) {
XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
releaseByteArray(env, signature_object, signature, JNI_ABORT);
#else
throwNotCompiledInException(env);
@ -797,3 +1167,4 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaSSL_1Verify(
return result;
}

View File

@ -38,7 +38,10 @@ import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
@ -48,6 +51,7 @@ import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPrivateKeySpec;
import javax.crypto.spec.DHPublicKeySpec;
import com.wolfssl.wolfcrypt.Rsa;
import com.wolfssl.wolfcrypt.Ecc;
import com.wolfssl.wolfcrypt.Dh;
import com.wolfssl.wolfcrypt.Rng;
@ -60,6 +64,7 @@ import com.wolfssl.provider.jce.WolfCryptDebug;
public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
enum KeyType {
WC_RSA,
WC_ECC,
WC_DH
}
@ -68,6 +73,7 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
private String curve = null;
private int keysize = 0;
private long publicExponent = 0;
private byte[] dhP = null;
private byte[] dhG = null;
@ -100,6 +106,11 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
this.keysize = keysize;
if (type == KeyType.WC_RSA) {
/* Set default RSA exponent for wolfSSL */
this.publicExponent = Rsa.getDefaultRsaExponent();
}
if (debug.DEBUG)
log("init with keysize: " + keysize);
}
@ -115,6 +126,31 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
switch (type) {
case WC_RSA:
if (!(params instanceof RSAKeyGenParameterSpec)) {
throw new InvalidAlgorithmParameterException(
"params must be of type RSAKeyGenParameterSpec");
}
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
this.keysize = rsaSpec.getKeysize();
try {
this.publicExponent =
rsaSpec.getPublicExponent().longValueExact();
} catch (ArithmeticException e) {
throw new InvalidAlgorithmParameterException(
"RSA public exponent value larger than long");
}
if (debug.DEBUG) {
log("init with RSA spec, keysize = " + keysize +
", public exponent = " + publicExponent);
}
break;
case WC_ECC:
int curvesize;
@ -183,6 +219,58 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
switch (this.type) {
case WC_RSA:
if (keysize == 0) {
throw new RuntimeException(
"keysize is 0, please set before generating key");
}
RSAPrivateKey rsaPriv = null;
RSAPublicKey rsaPub = null;
Rsa rsa = new Rsa();
try {
rsa.makeKey(this.keysize, this.publicExponent, rng);
/* private key */
privDer = rsa.privateKeyEncodePKCS8();
if (privDer == null) {
throw new RuntimeException(
"Unable to get RSA private key DER");
}
privSpec = new PKCS8EncodedKeySpec(privDer);
/* public key */
pubDer = rsa.exportPublicDer();
if (pubDer == null) {
throw new RuntimeException(
"Unable to get RSA public key DER");
}
pubSpec = new X509EncodedKeySpec(pubDer);
zeroArray(privDer);
zeroArray(pubDer);
rsa.releaseNativeStruct();
KeyFactory kf = KeyFactory.getInstance("RSA");
rsaPriv = (RSAPrivateKey)kf.generatePrivate(privSpec);
rsaPub = (RSAPublicKey)kf.generatePublic(pubSpec);
pair = new KeyPair(rsaPub, rsaPriv);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (debug.DEBUG) {
log("generated RSA KeyPair");
}
break;
case WC_ECC:
if (keysize == 0) {
@ -203,10 +291,18 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
/* private key */
privDer = ecc.privateKeyEncodePKCS8();
if (privDer == null) {
throw new RuntimeException(
"Unable to get ECC private key DER");
}
privSpec = new PKCS8EncodedKeySpec(privDer);
/* public key */
pubDer = ecc.publicKeyEncode();
if (pubDer == null) {
throw new RuntimeException(
"Unable to get ECC public key DER");
}
pubSpec = new X509EncodedKeySpec(pubDer);
zeroArray(privDer);
@ -226,7 +322,7 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
}
if (debug.DEBUG)
log("generated KeyPair");
log("generated ECC KeyPair");
break;
@ -274,13 +370,13 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
}
if (debug.DEBUG)
log("generated KeyPair");
log("generated DH KeyPair");
break;
default:
throw new RuntimeException(
"Unsupported algorithm for key generation");
"Unsupported algorithm for key generation: " + this.type);
}
return pair;
@ -288,6 +384,8 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
private String typeToString(KeyType type) {
switch (type) {
case WC_RSA:
return "RSA";
case WC_ECC:
return "ECC";
case WC_DH:
@ -324,6 +422,19 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
}
}
/**
* wolfCrypt RSA key pair generator class
*/
public static final class wcKeyPairGenRSA
extends WolfCryptKeyPairGenerator {
/**
* Create new wcKeyPairGenRSA object
*/
public wcKeyPairGenRSA() {
super(KeyType.WC_RSA);
}
}
/**
* wolfCrypt ECC key pair generator class
*/

View File

@ -136,6 +136,8 @@ public final class WolfCryptProvider extends Provider {
"com.wolfssl.provider.jce.WolfCryptKeyAgreement$wcECDH");
/* KeyPairGenerator */
put("KeyPairGenerator.RSA",
"com.wolfssl.provider.jce.WolfCryptKeyPairGenerator$wcKeyPairGenRSA");
put("KeyPairGenerator.EC",
"com.wolfssl.provider.jce.WolfCryptKeyPairGenerator$wcKeyPairGenECC");
put("KeyPairGenerator.DH",

View File

@ -52,24 +52,43 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
*/
private native void wc_RsaPublicKeyDecodeRaw(ByteBuffer n, long nSize,
ByteBuffer e, long eSize);
ByteBuffer e, long eSize) throws WolfCryptException;
private native void wc_RsaPublicKeyDecodeRaw(byte[] n, long nSize, byte[] e,
long eSize);
private native void RsaFlattenPublicKey(ByteBuffer n, ByteBuffer e);
long eSize) throws WolfCryptException;
private native void RsaFlattenPublicKey(ByteBuffer n, ByteBuffer e)
throws WolfCryptException;
private native void RsaFlattenPublicKey(byte[] n, long[] nSize, byte[] e,
long[] eSize);
private native void MakeRsaKey(int size, long e, Rng rng);
private native void wc_InitRsaKey();
private native void wc_FreeRsaKey();
private native boolean wc_RsaSetRNG(Rng rng);
private native void wc_RsaPrivateKeyDecode(byte[] key);
private native void wc_RsaPrivateKeyDecodePKCS8(byte[] key);
private native void wc_RsaPublicKeyDecode(byte[] key);
private native int wc_RsaEncryptSize();
private native byte[] wc_RsaPublicEncrypt(byte[] data, Rng rng);
private native byte[] wc_RsaPrivateDecrypt(byte[] data);
private native byte[] wc_RsaSSL_Sign(byte[] data, Rng rng);
private native byte[] wc_RsaSSL_Verify(byte[] data);
long[] eSize) throws WolfCryptException;
private native void MakeRsaKey(int size, long e, Rng rng)
throws WolfCryptException;
private native byte[] wc_RsaKeyToDer()
throws WolfCryptException;
private native byte[] wc_RsaKeyToPublicDer()
throws WolfCryptException;
private native byte[] wc_RsaPrivateKeyToPkcs8()
throws WolfCryptException;
private native void wc_InitRsaKey()
throws WolfCryptException;
private native void wc_FreeRsaKey()
throws WolfCryptException;
private native boolean wc_RsaSetRNG(Rng rng)
throws WolfCryptException;
private native void wc_RsaPrivateKeyDecode(byte[] key)
throws WolfCryptException;
private native void wc_RsaPrivateKeyDecodePKCS8(byte[] key)
throws WolfCryptException;
private native void wc_RsaPublicKeyDecode(byte[] key)
throws WolfCryptException;
private native int wc_RsaEncryptSize()
throws WolfCryptException;
private native byte[] wc_RsaPublicEncrypt(byte[] data, Rng rng)
throws WolfCryptException;
private native byte[] wc_RsaPrivateDecrypt(byte[] data)
throws WolfCryptException;
private native byte[] wc_RsaSSL_Sign(byte[] data, Rng rng)
throws WolfCryptException;
private native byte[] wc_RsaSSL_Verify(byte[] data)
throws WolfCryptException;
/**
* Create new Rsa object
@ -85,7 +104,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public Rsa(byte[] key) {
public Rsa(byte[] key) throws WolfCryptException {
decodePrivateKey(key);
}
@ -97,10 +116,18 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public Rsa(byte[] n, byte[] e) {
public Rsa(byte[] n, byte[] e) throws WolfCryptException {
decodeRawPublicKey(n, e);
}
/**
* Return the value of native wolfCrypt default RSA public exponent size.
* Native default is stored in the WC_RSA_EXPONENT define.
*
* @return value of native WC_RSA_EXPONENT, default RSA expoonent size
*/
public static native long getDefaultRsaExponent();
/**
* Set Rng for Rsa object
*
@ -108,7 +135,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public void setRng(Rng rng) {
public void setRng(Rng rng) throws WolfCryptException {
init();
if (wc_RsaSetRNG(rng))
@ -124,8 +151,10 @@ public class Rsa extends NativeStruct {
/**
* Initialize Rsa object
*
* @throws WolfCryptException if native operation fails
*/
protected void init() {
protected void init() throws WolfCryptException {
if (state == WolfCryptState.UNINITIALIZED) {
wc_InitRsaKey();
state = WolfCryptState.INITIALIZED;
@ -135,9 +164,12 @@ public class Rsa extends NativeStruct {
/**
* Initialize native RsaKey struct, check if object already has key
*
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has key
*/
protected void willSetKey() throws IllegalStateException {
protected void willSetKey()
throws WolfCryptException, IllegalStateException {
init();
if (state != WolfCryptState.INITIALIZED)
@ -155,17 +187,19 @@ public class Rsa extends NativeStruct {
protected void willUseKey(boolean priv) throws IllegalStateException {
if (priv && !hasPrivateKey)
throw new IllegalStateException(
"No available private key to perform the opperation.");
"No available private key to perform the operation.");
if (state != WolfCryptState.READY)
throw new IllegalStateException(
"No available key to perform the opperation.");
"No available key to perform the operation.");
}
/**
* Free Rsa object
*
* @throws WolfCryptException if native operation fails
*/
protected void free() {
protected void free() throws WolfCryptException {
if (state != WolfCryptState.UNINITIALIZED) {
wc_FreeRsaKey();
state = WolfCryptState.UNINITIALIZED;
@ -182,7 +216,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void makeKey(int size, long e, Rng rng) {
public void makeKey(int size, long e, Rng rng)
throws WolfCryptException, IllegalStateException {
willSetKey();
MakeRsaKey(size, e, rng);
@ -199,7 +234,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodePublicKey(byte[] key) {
public void decodePublicKey(byte[] key)
throws WolfCryptException, IllegalStateException {
willSetKey();
wc_RsaPublicKeyDecode(key);
@ -214,7 +250,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodePrivateKey(byte[] key) {
public void decodePrivateKey(byte[] key)
throws WolfCryptException, IllegalStateException {
willSetKey();
wc_RsaPrivateKeyDecode(key);
@ -230,7 +267,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodePrivateKeyPKCS8(byte[] key) {
public void decodePrivateKeyPKCS8(byte[] key)
throws WolfCryptException, IllegalStateException {
willSetKey();
wc_RsaPrivateKeyDecodePKCS8(key);
@ -248,7 +286,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodeRawPublicKey(byte[] n, byte[] e) {
public void decodeRawPublicKey(byte[] n, byte[] e)
throws WolfCryptException, IllegalStateException {
decodeRawPublicKey(n, n.length, e, e.length);
}
@ -263,7 +302,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodeRawPublicKey(byte[] n, long nSize, byte[] e, long eSize) {
public void decodeRawPublicKey(byte[] n, long nSize, byte[] e, long eSize)
throws WolfCryptException, IllegalStateException {
willSetKey();
wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize);
@ -279,7 +319,8 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized
*/
public void decodeRawPublicKey(ByteBuffer n, ByteBuffer e) {
public void decodeRawPublicKey(ByteBuffer n, ByteBuffer e)
throws WolfCryptException, IllegalStateException {
decodeRawPublicKey(n, n.limit(), e, e.limit());
}
@ -295,7 +336,7 @@ public class Rsa extends NativeStruct {
* @throws IllegalStateException if object is already initialized
*/
public void decodeRawPublicKey(ByteBuffer n, long nSz, ByteBuffer e,
long eSz) {
long eSz) throws WolfCryptException, IllegalStateException {
willSetKey();
wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz);
@ -314,7 +355,8 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public void exportRawPublicKey(byte[] n, long[] nSz, byte[] e, long[] eSz) {
public void exportRawPublicKey(byte[] n, long[] nSz, byte[] e, long[] eSz)
throws WolfCryptException {
willUseKey(false);
RsaFlattenPublicKey(n, nSz, e, eSz);
@ -328,12 +370,52 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public void exportRawPublicKey(ByteBuffer n, ByteBuffer e) {
public void exportRawPublicKey(ByteBuffer n, ByteBuffer e)
throws WolfCryptException {
willUseKey(false);
RsaFlattenPublicKey(n, e);
}
/**
* Export RSA private key in DER format.
*
* @return DER encoded byte array with private RSA key
*
* @throws WolfCryptException if native operation fails
*/
public byte[] exportPrivateDer() throws WolfCryptException {
willUseKey(true);
return wc_RsaKeyToDer();
}
/**
* Export RSA public key in DER format.
*
* @return DER encoded byte array with public RSA key
*
* @throws WolfCryptException if native operation fails
*/
public byte[] exportPublicDer() throws WolfCryptException {
willUseKey(false);
return wc_RsaKeyToPublicDer();
}
/**
* Encode and return RSA private key in PKCS#8 format.
*
* @return encoded private key as byte array
*
* @throws WolfCryptException if native operation fails
*/
public byte[] privateKeyEncodePKCS8() throws WolfCryptException {
willUseKey(true);
return wc_RsaPrivateKeyToPkcs8();
}
/**
* Get RSA encrypt size
*
@ -341,7 +423,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public int getEncryptSize() {
public int getEncryptSize() throws WolfCryptException {
willUseKey(false);
return wc_RsaEncryptSize();
@ -357,7 +439,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public byte[] encrypt(byte[] plain, Rng rng) {
public byte[] encrypt(byte[] plain, Rng rng) throws WolfCryptException {
willUseKey(false);
return wc_RsaPublicEncrypt(plain, rng);
@ -372,7 +454,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public byte[] decrypt(byte[] ciphertext) {
public byte[] decrypt(byte[] ciphertext) throws WolfCryptException {
willUseKey(true);
return wc_RsaPrivateDecrypt(ciphertext);
@ -389,7 +471,7 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object does not have key
*/
public byte[] sign(byte[] data, Rng rng) {
public byte[] sign(byte[] data, Rng rng) throws WolfCryptException {
willUseKey(true);
return wc_RsaSSL_Sign(data, rng);
@ -404,7 +486,7 @@ public class Rsa extends NativeStruct {
*
* @throws WolfCryptException if native operation fails
*/
public byte[] verify(byte[] signature) {
public byte[] verify(byte[] signature) throws WolfCryptException {
willUseKey(false);
return wc_RsaSSL_Verify(signature);

View File

@ -48,10 +48,12 @@ import java.security.KeyFactory;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import com.wolfssl.wolfcrypt.Rsa;
import com.wolfssl.wolfcrypt.Ecc;
import com.wolfssl.wolfcrypt.test.Util;
import com.wolfssl.wolfcrypt.WolfCryptException;
@ -94,13 +96,14 @@ public class WolfCryptKeyPairGeneratorTest {
private static ArrayList<String> enabledCurves =
new ArrayList<String>();
private static int supportedKeySizes[] = {
112, 128, 160, 192, 224, 239, 256, 320, 384, 521
};
private static ArrayList<Integer> enabledKeySizes =
private static ArrayList<Integer> enabledEccKeySizes =
new ArrayList<Integer>();
/* Test generation of these RSA key sizes */
private static int testedRSAKeySizes[] = {
1024, 2048, 3072, 4096
};
/* DH test params */
private static byte[] prime = Util.h2b(
"B0A108069C0813BA59063CBC30D5F500C14F44A7D6EF4AC625271CE8D" +
@ -119,7 +122,7 @@ public class WolfCryptKeyPairGeneratorTest {
public static void testProviderInstallationAtRuntime() {
/* install wolfJCE provider at runtime */
Security.addProvider(new WolfCryptProvider());
Security.insertProviderAt(new WolfCryptProvider(), 1);
Provider p = Security.getProvider("wolfJCE");
assertNotNull(p);
@ -135,8 +138,8 @@ public class WolfCryptKeyPairGeneratorTest {
if (size > 0) {
enabledCurves.add(supportedCurves[i]);
if (!enabledKeySizes.contains(Integer.valueOf(size))) {
enabledKeySizes.add(Integer.valueOf(size));
if (!enabledEccKeySizes.contains(Integer.valueOf(size))) {
enabledEccKeySizes.add(Integer.valueOf(size));
}
}
}
@ -148,6 +151,8 @@ public class WolfCryptKeyPairGeneratorTest {
KeyPairGenerator kpg;
kpg = KeyPairGenerator.getInstance("EC", "wolfJCE");
kpg = KeyPairGenerator.getInstance("RSA", "wolfJCE");
kpg = KeyPairGenerator.getInstance("DH", "wolfJCE");
/* getting a garbage algorithm should throw an exception */
try {
@ -159,6 +164,135 @@ public class WolfCryptKeyPairGeneratorTest {
} catch (NoSuchAlgorithmException e) { }
}
@Test
public void testKeyPairGeneratorRsaInitializeWithParamSpec()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
/* try initializing KPG for all tested key sizes */
for (int i = 0; i < testedRSAKeySizes.length; i++) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
RSAKeyGenParameterSpec rsaSpec =
new RSAKeyGenParameterSpec(testedRSAKeySizes[i],
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
/* bad key size should fail */
try {
rsaSpec = new RSAKeyGenParameterSpec(10,
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
} catch (InvalidAlgorithmParameterException e) {}
}
}
@Test
public void testKeyPairGeneratorRsaInitializeWithKeySize()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
/* try initializing KPG for all tested key sizes */
for (int i = 0; i < testedRSAKeySizes.length; i++) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
kpg.initialize(testedRSAKeySizes[i]);
/* bad key size should fail */
try {
kpg.initialize(10);
} catch (WolfCryptException e) {}
}
}
@Test
public void testKeyPairGeneratorRsaKeyGenAllSizes()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
/* try generating keys for all tested sizes */
for (int i = 0; i < testedRSAKeySizes.length; i++) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
RSAKeyGenParameterSpec rsaSpec =
new RSAKeyGenParameterSpec(testedRSAKeySizes[i],
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
KeyPair kp = kpg.generateKeyPair();
}
}
@Test
public void testKeyPairGeneratorRsaMultipleInits()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
if (testedRSAKeySizes.length > 0) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
RSAKeyGenParameterSpec rsaSpec =
new RSAKeyGenParameterSpec(testedRSAKeySizes[0],
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
kpg.initialize(rsaSpec);
}
}
@Test
public void testKeyPairGeneratorRsaMultipleKeyGen()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
if (testedRSAKeySizes.length > 0) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
RSAKeyGenParameterSpec rsaSpec =
new RSAKeyGenParameterSpec(testedRSAKeySizes[0],
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
KeyPair kp1 = kpg.generateKeyPair();
KeyPair kp2 = kpg.generateKeyPair();
}
}
@Test
public void testKeyPairGeneratorRsaNewKeyFromExisting()
throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeySpecException {
if (testedRSAKeySizes.length > 0) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("RSA", "wolfJCE");
RSAKeyGenParameterSpec rsaSpec =
new RSAKeyGenParameterSpec(testedRSAKeySizes[0],
BigInteger.valueOf(Rsa.getDefaultRsaExponent()));
kpg.initialize(rsaSpec);
KeyPair kp = kpg.generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub = kf.generatePublic(new X509EncodedKeySpec(
kp.getPublic().getEncoded()));
PrivateKey priv = kf.generatePrivate(new PKCS8EncodedKeySpec(
kp.getPrivate().getEncoded()));
}
}
@Test
public void testKeyPairGeneratorEccInitializeWithParamSpec()
throws NoSuchProviderException, NoSuchAlgorithmException,
@ -178,7 +312,9 @@ public class WolfCryptKeyPairGeneratorTest {
try {
ecSpec = new ECGenParameterSpec("BADCURVE");
kpg.initialize(ecSpec);
} catch (InvalidAlgorithmParameterException e) {}
} catch (InvalidAlgorithmParameterException e) {
/* expected */
}
}
}
@ -188,17 +324,19 @@ public class WolfCryptKeyPairGeneratorTest {
InvalidAlgorithmParameterException {
/* try initializing KPG for all supported key sizes */
for (int i = 0; i < enabledKeySizes.size(); i++) {
for (int i = 0; i < enabledEccKeySizes.size(); i++) {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance("EC", "wolfJCE");
kpg.initialize(enabledKeySizes.get(i));
kpg.initialize(enabledEccKeySizes.get(i));
/* bad key size should fail */
try {
kpg.initialize(9999);
} catch (WolfCryptException e) {}
} catch (WolfCryptException e) {
/* expected */
}
}
}

View File

@ -31,6 +31,7 @@ import org.junit.Test;
import com.wolfssl.wolfcrypt.Rsa;
import com.wolfssl.wolfcrypt.Rng;
import com.wolfssl.wolfcrypt.Fips;
import com.wolfssl.wolfcrypt.NativeStruct;
import com.wolfssl.wolfcrypt.WolfCryptError;
import com.wolfssl.wolfcrypt.WolfCryptException;
@ -60,10 +61,177 @@ public class RsaTest {
}
@Test
public void makeKeyShouldNotRaiseExceptions() {
Rsa key = new Rsa();
public void testMakeKey() {
Rsa key = new Rsa();
key.makeKey(1024, 65537, rng);
key.releaseNativeStruct();
key = new Rsa();
key.makeKey(2048, 65537, rng);
key.releaseNativeStruct();
key = new Rsa();
key.makeKey(3072, 65537, rng);
key.releaseNativeStruct();
key = new Rsa();
key.makeKey(4096, 65537, rng);
key.releaseNativeStruct();
}
@Test
public void testDerExportImportSignVerify() {
/* generate new 2048-bit key */
Rsa key = new Rsa();
key.makeKey(2048, 65537, rng);
/* export key to DER */
byte[] rsaDer = key.exportPrivateDer();
assertNotNull(rsaDer);
assertTrue(rsaDer.length > 0);
key.releaseNativeStruct();
/* try to re-import DER into new Rsa object */
key = new Rsa();
key.decodePrivateKey(rsaDer);
/* sign data */
byte[] data = "Hello wolfSSL".getBytes();
byte[] signed = key.sign(data, rng);
/* verify data matches original */
byte[] verify = key.verify(signed);
assertNotNull(verify);
assertArrayEquals(data, verify);
key.releaseNativeStruct();
}
@Test
public void rsaPrivateToPkcs8() {
Rsa key = new Rsa();
byte[] pkcs8;
int size;
byte[] prvKey = Util.h2b(
"308204a40201000282010100c303d12bfe39a432453b53c8842b2a7c"
+ "749abdaa2a520747d6a636b207328ed0ba697bc6c3449ed48148"
+ "fd2d68a28b67bba175c8362c4ad21bf78bbacf0df9efecf1811e"
+ "7b9b03479abf65cc7f652469a6e814895be434f7c5b01493f567"
+ "7b3a7a78e101565691a613428dd23c409c4cefd186df37511b0c"
+ "a13bf5f1a34a35e4e1ce96df1b7ebf4e97d010e8a8083081af20"
+ "0b4314c57467b432826f8d86c28840993683ba1e40722217d752"
+ "652473b0ceef19cdaeff786c7bc01203d44e720d506d3ba33ba3"
+ "995e9dc8d90c85b3d98ad95426db6dfaacbbff254cc4d179f471"
+ "d386401813b063b5724e30c49784862d562fd715f77fc0aef5fc"
+ "5be5fba1bad302030100010282010100a2e6d85f107164089e2e"
+ "6dd16d1e85d20ab18c47ce2c516aa0129e53de914c1d6dea597b"
+ "f277aad9c6d98aabd8e116e46326ffb56c1359b8e3a5c872172e"
+ "0c9f6fe5593f766f49b111c25a2e16290ddeb78edc40d5a2eee0"
+ "1ea1f4be97db86639614cd9809602d30769c3ccde688ee479279"
+ "0b5a00e25e5f117c7df908b72006892a5dfd00ab22e1f0b3bc24"
+ "a95e260e1f002dfe219a535b6dd32bab9482684336d8f62fc622"
+ "fcb5415d0d3360eaa47d7ee84b559156d35c578f1f94172faade"
+ "e99ea8f4cf8a4c8ea0e45673b2cf4f86c5693cf324208b5c960c"
+ "fa6b123b9a67c1dfc696b2a5d5920d9b094268241045d450e417"
+ "3948d0358b946d11de8fca5902818100ea24a7f96933e971dc52"
+ "7d8821282f49deba7216e9cc477a880d94578458163a81b03fa2"
+ "cfa66c1eb00629008fe77776acdbcac7d95e9b3f269052aefc38"
+ "900014bbb40f5894e72f6a7e1c4f4121d431591f4e8a1a8da757"
+ "6c22d8e5f47e32a610cb64a5550387a627058cc3d7b627b24dba"
+ "30da478f54d33d8b848d949858a502818100d5381bc38fc5930c"
+ "470b6f3592c5b08d46c892188ff5800af7efa1fe80b9b52abaca"
+ "18b05da507d0938dd89c041cd4628ea6268101ffce8a2a633435"
+ "40aa6d80de89236a574d9e6ead934e56900b6d9d738b0cae273d"
+ "de4ef0aac56c78676c94529c37676c2defbbafdfa6903cc447cf"
+ "8d969e98a9b49fc5a650dcb3f0fb74170281805e830962bdba7c"
+ "a2bf4274f57c1cd269c9040d857e3e3d2412c3187bf329f35f0e"
+ "766c5975e44184699d32f3cd22abb035ba4ab23ce5d958b6624f"
+ "5ddee59e0aca53b22cf79eb36b0a5b7965ec6e914e9220f6fcfc"
+ "16edd3760ce2ec7fb269136b780e5a4664b45eb725a05a753a4b"
+ "efc73c3ef7fd26b820c4990a9a73bec31902818100ba449314ac"
+ "34193b5f9160acf7b4d681053651533de865dcaf2edc613ec97d"
+ "b87f87f03b9b03822937ce724e11d5b1c10c07a099914a8d7fec"
+ "79cff139b5e985ec62f7da7dbc644d223c0ef2d651f587d899c0"
+ "11205d0f29fd5be2aed91cd921566dfc84d05fed10151c1821e7"
+ "c43d4bd7d09e6a95cf22c9037b9ee36001fc2f02818011d04bcf"
+ "1b67b99f1075478665ae31c2c630ac590650d90fb57006f7f0d3"
+ "c8627ca8da6ef6213fd37f5fea8aab3fd92a5ef351d2c23037e3"
+ "2da3750d1e4d2134d557705c89bf72ec4a6e68d5cd1874334e8c"
+ "3a458fe69640eb63f919863a51dd894bb0f3f99f5d289538be35"
+ "abca5ce7935334a1455d1339654246a19fcdf5bf");
byte[] expectedPkcs8 = Util.h2b(
"308204be020100300d06092a864886f70d0101010500048204a8"
+ "308204a40201000282010100c303d12bfe39a432453b53c8842b"
+ "2a7c749abdaa2a520747d6a636b207328ed0ba697bc6c3449ed4"
+ "8148fd2d68a28b67bba175c8362c4ad21bf78bbacf0df9efecf1"
+ "811e7b9b03479abf65cc7f652469a6e814895be434f7c5b01493"
+ "f5677b3a7a78e101565691a613428dd23c409c4cefd186df3751"
+ "1b0ca13bf5f1a34a35e4e1ce96df1b7ebf4e97d010e8a8083081"
+ "af200b4314c57467b432826f8d86c28840993683ba1e40722217"
+ "d752652473b0ceef19cdaeff786c7bc01203d44e720d506d3ba3"
+ "3ba3995e9dc8d90c85b3d98ad95426db6dfaacbbff254cc4d179"
+ "f471d386401813b063b5724e30c49784862d562fd715f77fc0ae"
+ "f5fc5be5fba1bad302030100010282010100a2e6d85f10716408"
+ "9e2e6dd16d1e85d20ab18c47ce2c516aa0129e53de914c1d6dea"
+ "597bf277aad9c6d98aabd8e116e46326ffb56c1359b8e3a5c872"
+ "172e0c9f6fe5593f766f49b111c25a2e16290ddeb78edc40d5a2"
+ "eee01ea1f4be97db86639614cd9809602d30769c3ccde688ee47"
+ "92790b5a00e25e5f117c7df908b72006892a5dfd00ab22e1f0b3"
+ "bc24a95e260e1f002dfe219a535b6dd32bab9482684336d8f62f"
+ "c622fcb5415d0d3360eaa47d7ee84b559156d35c578f1f94172f"
+ "aadee99ea8f4cf8a4c8ea0e45673b2cf4f86c5693cf324208b5c"
+ "960cfa6b123b9a67c1dfc696b2a5d5920d9b094268241045d450"
+ "e4173948d0358b946d11de8fca5902818100ea24a7f96933e971"
+ "dc527d8821282f49deba7216e9cc477a880d94578458163a81b0"
+ "3fa2cfa66c1eb00629008fe77776acdbcac7d95e9b3f269052ae"
+ "fc38900014bbb40f5894e72f6a7e1c4f4121d431591f4e8a1a8d"
+ "a7576c22d8e5f47e32a610cb64a5550387a627058cc3d7b627b2"
+ "4dba30da478f54d33d8b848d949858a502818100d5381bc38fc5"
+ "930c470b6f3592c5b08d46c892188ff5800af7efa1fe80b9b52a"
+ "baca18b05da507d0938dd89c041cd4628ea6268101ffce8a2a63"
+ "343540aa6d80de89236a574d9e6ead934e56900b6d9d738b0cae"
+ "273dde4ef0aac56c78676c94529c37676c2defbbafdfa6903cc4"
+ "47cf8d969e98a9b49fc5a650dcb3f0fb74170281805e830962bd"
+ "ba7ca2bf4274f57c1cd269c9040d857e3e3d2412c3187bf329f3"
+ "5f0e766c5975e44184699d32f3cd22abb035ba4ab23ce5d958b6"
+ "624f5ddee59e0aca53b22cf79eb36b0a5b7965ec6e914e9220f6"
+ "fcfc16edd3760ce2ec7fb269136b780e5a4664b45eb725a05a75"
+ "3a4befc73c3ef7fd26b820c4990a9a73bec31902818100ba4493"
+ "14ac34193b5f9160acf7b4d681053651533de865dcaf2edc613e"
+ "c97db87f87f03b9b03822937ce724e11d5b1c10c07a099914a8d"
+ "7fec79cff139b5e985ec62f7da7dbc644d223c0ef2d651f587d8"
+ "99c011205d0f29fd5be2aed91cd921566dfc84d05fed10151c18"
+ "21e7c43d4bd7d09e6a95cf22c9037b9ee36001fc2f02818011d0"
+ "4bcf1b67b99f1075478665ae31c2c630ac590650d90fb57006f7"
+ "f0d3c8627ca8da6ef6213fd37f5fea8aab3fd92a5ef351d2c230"
+ "37e32da3750d1e4d2134d557705c89bf72ec4a6e68d5cd187433"
+ "4e8c3a458fe69640eb63f919863a51dd894bb0f3f99f5d289538"
+ "be35abca5ce7935334a1455d1339654246a19fcdf5bf");
/* Test that exception is thrown without private key available */
try {
pkcs8 = key.privateKeyEncodePKCS8();
fail("Rsa.privateKeyEncodePKCS8() should throw exception");
} catch (IllegalStateException e) {
/* expected */
}
/* Test that encoded PKCS#8 private key matches expected */
key.decodePrivateKey(prvKey);
pkcs8 = key.privateKeyEncodePKCS8();
assertArrayEquals(pkcs8, expectedPkcs8);
key.releaseNativeStruct();
/* Test that generated key encodes without error */
key = new Rsa();
key.makeKey(1024, 65537, rng);
pkcs8 = key.privateKeyEncodePKCS8();
assertTrue(pkcs8 != null);
assertTrue(pkcs8.length != 0);
key.releaseNativeStruct();
}
@Test