summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/c_utils.c10
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/c_utils.h5
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/mscng.c1010
3 files changed, 548 insertions, 477 deletions
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index f920fc4..6954c36 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -1,4 +1,5 @@
#include "c_utils.h"
+#define _ISOC99_SOURCE
#include <string.h>
jclass ec_parameter_spec_class;
@@ -64,3 +65,12 @@ void throw_new(JNIEnv *env, const char *class, const char *message) {
jclass clazz = (*env)->FindClass(env, class);
(*env)->ThrowNew(env, clazz, message);
}
+
+void throw_new_var(JNIEnv *env, const char *class, const char *format, ...) {
+ char buffer[2048];
+ va_list args;
+ va_start(args, format);
+ int res = vsnprintf(buffer, 2048, format, args);
+ va_end(args);
+ throw_new(env, class, buffer);
+} \ No newline at end of file
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
index 3ef8f86..2e5fa1a 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h
@@ -28,6 +28,11 @@ void init_classes(JNIEnv *env, const char* lib_name);
void throw_new(JNIEnv *env, const char *class, const char *message);
/**
+ * Throw a new exception of class, with formatted message.
+ */
+void throw_new_var(JNIEnv *env, const char *class, const char *format, ...);
+
+/**
* Some useful defines to init the provider.
*/
#define INIT_PROVIDER(env, provider_class) jmethodID provider_put = (*env)->GetMethodID(env, provider_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 04b0fcf..12cc13d 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -24,97 +24,97 @@ typedef struct {
ULONG cbSeed; //Byte length of the seed used to generate the curve.
} BCRYPT_ECC_PARAMETER_HEADER;
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self){
- jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
- provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_createProvider(JNIEnv *env, jobject self) {
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Mscng");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
- jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V");
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V");
- jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
- double version = 1.0;
+ jstring name = (*env)->NewStringUTF(env, "Microsoft CNG");
+ double version = 1.0;
- return (*env)->NewObject(env, provider_class, init, name, version, name);
+ return (*env)->NewObject(env, provider_class, init, name, version, name);
}
JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Mscng_setup(JNIEnv *env, jobject self) {
- INIT_PROVIDER(env, provider_class);
+ INIT_PROVIDER(env, provider_class);
- ADD_KPG(env, self, "ECDH", "MscngECDH");
- ADD_KPG(env, self, "ECDSA", "MscngECDSA");
+ ADD_KPG(env, self, "ECDH", "MscngECDH");
+ ADD_KPG(env, self, "ECDSA", "MscngECDSA");
- ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
- ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
- ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
- ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
+ ADD_KA(env, self, "ECDHwithSHA1KDF", "MscngECDHwithSHA1KDF");
+ ADD_KA(env, self, "ECDHwithSHA256KDF", "MscngECDHwithSHA256KDF");
+ ADD_KA(env, self, "ECDHwithSHA384KDF", "MscngECDHwithSHA384KDF");
+ ADD_KA(env, self, "ECDHwithSHA512KDF", "MscngECDHwithSHA512KDF");
- ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
- ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
- ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
- ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
+ ADD_SIG(env, self, "SHA1withECDSA", "MscngECDSAwithSHA1");
+ ADD_SIG(env, self, "SHA256withECDSA", "MscngECDSAwithSHA256");
+ ADD_SIG(env, self, "SHA384withECDSA", "MscngECDSAwithSHA384");
+ ADD_SIG(env, self, "SHA512withECDSA", "MscngECDSAwithSHA112");
- init_classes(env, "Mscng");
+ init_classes(env, "Mscng");
}
typedef struct {
- LPCSTR name;
- ULONG bits;
+ LPCSTR name;
+ ULONG bits;
} named_curve_t;
static named_curve_t named_curves[] = {
- {"curve25519", 256},
- {"brainpoolP160r1", 160},
- {"brainpoolP160t1", 160},
- {"brainpoolP192r1", 192},
- {"brainpoolP192t1", 192},
- {"brainpoolP224r1", 224},
- {"brainpoolP224t1", 224},
- {"brainpoolP256r1", 256},
- {"brainpoolP256t1", 256},
- {"brainpoolP320r1", 320},
- {"brainpoolP320t1", 320},
- {"brainpoolP384r1", 384},
- {"brainpoolP384t1", 384},
- {"brainpoolP512r1", 512},
- {"brainpoolP512t1", 512},
- {"ec192wapi", 192},
- {"nistP192", 192},
- {"nistP224", 224},
- {"nistP256", 256},
- {"nistP384", 384},
- {"nistP521", 521},
- {"numsP256t1", 256},
- {"numsP384t1", 384},
- {"numsP512t1", 512},
- {"secP160k1", 160},
- {"secP160r1", 160},
- {"secP160r2", 160},
- {"secP192k1", 192},
- {"secP192r1", 192},
- {"secP224k1", 224},
- {"secP224r1", 224},
- {"secP256k1", 256},
- {"secP256r1", 256},
- {"secP384r1", 384},
- {"secP521r1", 521},
- {"wtls12", 224},
- {"wtls7", 160},
- {"wtls9", 160},
- {"x962P192v1", 192},
- {"x962P192v2", 192},
- {"x962P192v3", 192},
- {"x962P239v1", 239},
- {"x962P239v2", 239},
- {"x962P239v3", 239},
- {"x962P256v1", 256}
+ {"curve25519", 256},
+ {"brainpoolP160r1", 160},
+ {"brainpoolP160t1", 160},
+ {"brainpoolP192r1", 192},
+ {"brainpoolP192t1", 192},
+ {"brainpoolP224r1", 224},
+ {"brainpoolP224t1", 224},
+ {"brainpoolP256r1", 256},
+ {"brainpoolP256t1", 256},
+ {"brainpoolP320r1", 320},
+ {"brainpoolP320t1", 320},
+ {"brainpoolP384r1", 384},
+ {"brainpoolP384t1", 384},
+ {"brainpoolP512r1", 512},
+ {"brainpoolP512t1", 512},
+ {"ec192wapi", 192},
+ {"nistP192", 192},
+ {"nistP224", 224},
+ {"nistP256", 256},
+ {"nistP384", 384},
+ {"nistP521", 521},
+ {"numsP256t1", 256},
+ {"numsP384t1", 384},
+ {"numsP512t1", 512},
+ {"secP160k1", 160},
+ {"secP160r1", 160},
+ {"secP160r2", 160},
+ {"secP192k1", 192},
+ {"secP192r1", 192},
+ {"secP224k1", 224},
+ {"secP224r1", 224},
+ {"secP256k1", 256},
+ {"secP256r1", 256},
+ {"secP384r1", 384},
+ {"secP521r1", 521},
+ {"wtls12", 224},
+ {"wtls7", 160},
+ {"wtls9", 160},
+ {"x962P192v1", 192},
+ {"x962P192v2", 192},
+ {"x962P192v3", 192},
+ {"x962P239v1", 239},
+ {"x962P239v2", 239},
+ {"x962P239v3", 239},
+ {"x962P256v1", 256}
};
static const named_curve_t* lookup_curve(const char *name) {
- for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
- if (strcmp(name, named_curves[i].name) == 0) {
- return &named_curves[i];
- }
- }
- return NULL;
+ for (size_t i = 0; i < sizeof(named_curves) / sizeof(named_curve_t); ++i) {
+ if (strcmp(name, named_curves[i].name) == 0) {
+ return &named_curves[i];
+ }
+ }
+ return NULL;
}
static const named_curve_t* lookup_curve_bits(jint bitsize) {
@@ -161,24 +161,25 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
BCRYPT_ALG_HANDLE handle;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, BCRYPT_ECDH_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ return result;
}
ULONG bufSize;
if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, NULL, 0, &bufSize, 0))) {
- //err
wprintf(L"**** Error 0x%x returned by BCryptGetProperty(length only)\n", status);
- return 0;
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return result;
}
BCRYPT_ECC_CURVE_NAMES *curves = (BCRYPT_ECC_CURVE_NAMES *)calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, (PBYTE) curves, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptGetProperty(handle, BCRYPT_ECC_CURVE_NAME_LIST, (PBYTE)curves, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptGetProperty(whole)\n", status);
- return 0;
+ BCryptCloseAlgorithmProvider(handle, 0);
+ free(curves);
+ return result;
}
+
for (size_t i = 0; i < curves->dwEccCurveNames; ++i) {
NPSTR curve_name;
ULONG len = utf_16to8(&curve_name, curves->pEccCurveNames[i]);
@@ -190,7 +191,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv
free(curves);
BCryptCloseAlgorithmProvider(handle, 0);
- return result;
+ return result;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_keysizeSupported(JNIEnv *env, jobject self, jint keysize) {
@@ -206,55 +207,55 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPa
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_paramsSupported(JNIEnv *env, jobject self, jobject params) {
if (params == NULL) {
- return JNI_FALSE;
- }
+ return JNI_FALSE;
+ }
- if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
- jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
- jstring name = (*env)->CallObjectMethod(env, params, get_name);
- const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL);
- const named_curve_t *curve = lookup_curve(utf_name);
- (*env)->ReleaseStringUTFChars(env, name, utf_name);
- return curve == NULL ? JNI_FALSE : JNI_TRUE;
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
- jobject curve = (*env)->CallObjectMethod(env, params, get_curve);
+ if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
+ jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
+ jstring name = (*env)->CallObjectMethod(env, params, get_name);
+ const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL);
+ const named_curve_t *curve = lookup_curve(utf_name);
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return curve == NULL ? JNI_FALSE : JNI_TRUE;
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject curve = (*env)->CallObjectMethod(env, params, get_curve);
- jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
- jobject field = (*env)->CallObjectMethod(env, curve, get_field);
+ jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
+ jobject field = (*env)->CallObjectMethod(env, curve, get_field);
- if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- } else {
- return JNI_FALSE;
- }
+ if ((*env)->IsInstanceOf(env, field, fp_field_class)) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+ } else {
+ return JNI_FALSE;
+ }
}
static jobject bytes_to_biginteger(JNIEnv *env, PBYTE bytes, int len) {
- jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
- jbyteArray byte_array = (*env)->NewByteArray(env, len);
- jbyte *data = (*env)->GetByteArrayElements(env, byte_array, NULL);
- memcpy(data, bytes, len);
- (*env)->ReleaseByteArrayElements(env, byte_array, data, 0);
- jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, byte_array);
- return result;
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
+ jbyteArray byte_array = (*env)->NewByteArray(env, len);
+ jbyte *data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ memcpy(data, bytes, len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, byte_array);
+ return result;
}
static void biginteger_to_bytes(JNIEnv *env, jobject bigint, PBYTE bytes, ULONG len) {
- jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B");
+ jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B");
- jbyteArray byte_array = (jbyteArray) (*env)->CallObjectMethod(env, bigint, to_byte_array);
- jsize byte_length = (*env)->GetArrayLength(env, byte_array);
- jbyte *byte_data = (*env)->GetByteArrayElements(env, byte_array, NULL);
- memcpy(bytes, &byte_data[byte_length - len], len);
- (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+ jbyteArray byte_array = (jbyteArray)(*env)->CallObjectMethod(env, bigint, to_byte_array);
+ jsize byte_length = (*env)->GetArrayLength(env, byte_array);
+ jbyte *byte_data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ memcpy(bytes, &byte_data[byte_length - len], len);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
}
static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, PULONG paramLength) {
- //
+ //
// BCRYPT_ECCFULLKEY_BLOB header
// P[cbFieldLength] Prime specifying the base field.
// A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
@@ -266,151 +267,148 @@ static jobject create_ec_param_spec(JNIEnv *env, PBYTE eccParams, PULONG paramLe
// S[cbSeed] Seed of the curve.
BCRYPT_ECCFULLKEY_BLOB *header = (BCRYPT_ECCFULLKEY_BLOB*)eccParams;
- PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECCFULLKEY_BLOB)];
+ PBYTE paramsStart = &eccParams[sizeof(BCRYPT_ECCFULLKEY_BLOB)];
- //cbFieldLength
- PBYTE P = paramsStart;
- PBYTE A = P + header->cbFieldLength;
- PBYTE B = A + header->cbFieldLength;
- PBYTE GX = B + header->cbFieldLength;
- PBYTE GY = GX + header->cbFieldLength;
+ //cbFieldLength
+ PBYTE P = paramsStart;
+ PBYTE A = P + header->cbFieldLength;
+ PBYTE B = A + header->cbFieldLength;
+ PBYTE GX = B + header->cbFieldLength;
+ PBYTE GY = GX + header->cbFieldLength;
- //cbSubgroupOrder
- PBYTE N = GY + header->cbFieldLength;
+ //cbSubgroupOrder
+ PBYTE N = GY + header->cbFieldLength;
- //cbCofactor
- PBYTE H = N + header->cbSubgroupOrder;
+ //cbCofactor
+ PBYTE H = N + header->cbSubgroupOrder;
- //cbSeed
- PBYTE S = H + header->cbCofactor;
+ //cbSeed
+ PBYTE S = H + header->cbCofactor;
*paramLength = sizeof(BCRYPT_ECCFULLKEY_BLOB) + 5 * header->cbFieldLength + header->cbSubgroupOrder + header->cbCofactor + header->cbSeed;
- jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
+ jobject p_int = bytes_to_biginteger(env, P, header->cbFieldLength);
- jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
- jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
+ jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p_int);
- jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
- jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
+ jobject a_int = bytes_to_biginteger(env, A, header->cbFieldLength);
+ jobject b_int = bytes_to_biginteger(env, B, header->cbFieldLength);
- jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
- jobject elliptic_curve = (*env)->NewObject(env, elliptic_curve_class, elliptic_curve_init, field, a_int, b_int);
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject elliptic_curve = (*env)->NewObject(env, elliptic_curve_class, elliptic_curve_init, field, a_int, b_int);
- jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
- jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
+ jobject gx_int = bytes_to_biginteger(env, GX, header->cbFieldLength);
+ jobject gy_int = bytes_to_biginteger(env, GY, header->cbFieldLength);
- jmethodID point_init = (*env)->GetMethodID(env, point_class, "<init>", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
- jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "<init>", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx_int, gy_int);
- jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
+ jobject n_int = bytes_to_biginteger(env, N, header->cbSubgroupOrder);
- jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
- jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
- jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
+ jobject h_int = bytes_to_biginteger(env, H, header->cbCofactor);
+ jmethodID bigint_to_int = (*env)->GetMethodID(env, biginteger_class, "intValue", "()I");
+ jint cof = (*env)->CallIntMethod(env, h_int, bigint_to_int);
- jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
- return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n_int, cof);
}
static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) {
- jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
- jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
- jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
- jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field);
+ jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
+ jobject field = (*env)->CallObjectMethod(env, elliptic_curve, get_field);
- jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
- jint bits = (*env)->CallIntMethod(env, field, get_bits);
- jint bytes = (bits + 7) / 8;
+ jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
+ jint bits = (*env)->CallIntMethod(env, field, get_bits);
+ jint bytes = (bits + 7) / 8;
- jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
- jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, elliptic_curve, get_a);
- jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
- jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, elliptic_curve, get_b);
- jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
- jobject p = (*env)->CallObjectMethod(env, field, get_p);
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
- jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;");
- jobject g = (*env)->CallObjectMethod(env, params, get_g);
+ jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;");
+ jobject g = (*env)->CallObjectMethod(env, params, get_g);
- jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;");
- jobject gx = (*env)->CallObjectMethod(env, g, get_x);
+ jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;");
+ jobject gx = (*env)->CallObjectMethod(env, g, get_x);
- jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
- jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
- jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
- jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
- jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
- jint h = (*env)->CallIntMethod(env, params, get_h);
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
- jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
- jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
- jint order_bytes = (order_bits + 7) / 8;
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint order_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint order_bytes = (order_bits + 7) / 8;
- // header_size + 5*bytes + order_bytes + cof_size + 0
- ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5*bytes + order_bytes + 1 + 0;
- *curve = calloc(bufSize, 1);
- BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
- header->dwVersion = 1;
- header->dwCurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
- header->dwCurveGenerationAlgId = 0;
- header->cbFieldLength = bytes;
- header->cbSubgroupOrder = order_bytes;
+ // header_size + 5*bytes + order_bytes + cof_size + 0
+ ULONG bufSize = sizeof(BCRYPT_ECC_PARAMETER_HEADER) + 5 * bytes + order_bytes + 1 + 0;
+ *curve = calloc(bufSize, 1);
+ BCRYPT_ECC_PARAMETER_HEADER *header = (BCRYPT_ECC_PARAMETER_HEADER*)*curve;
+ header->dwVersion = 1;
+ header->dwCurveType = 1; //1 -> Prime short Weierstrass, 2 -> Prime Twisted Edwards, 3 -> Montgomery
+ header->dwCurveGenerationAlgId = 0;
+ header->cbFieldLength = bytes;
+ header->cbSubgroupOrder = order_bytes;
header->cbCofactor = 1;
- header->cbSeed = 0;
+ header->cbSeed = 0;
- PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
+ PBYTE paramsStart = &(*curve)[sizeof(BCRYPT_ECC_PARAMETER_HEADER)];
- biginteger_to_bytes(env, p, paramsStart, bytes);
- biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
- biginteger_to_bytes(env, b, paramsStart + 2*bytes, bytes);
- biginteger_to_bytes(env, gx, paramsStart + 3*bytes, bytes);
- biginteger_to_bytes(env, gy, paramsStart + 4*bytes, bytes);
- biginteger_to_bytes(env, n, paramsStart + 5*bytes, order_bytes);
- PBYTE cof_ptr = (PBYTE) (paramsStart + 5*bytes + order_bytes);
+ biginteger_to_bytes(env, p, paramsStart, bytes);
+ biginteger_to_bytes(env, a, paramsStart + bytes, bytes);
+ biginteger_to_bytes(env, b, paramsStart + 2 * bytes, bytes);
+ biginteger_to_bytes(env, gx, paramsStart + 3 * bytes, bytes);
+ biginteger_to_bytes(env, gy, paramsStart + 4 * bytes, bytes);
+ biginteger_to_bytes(env, n, paramsStart + 5 * bytes, order_bytes);
+ PBYTE cof_ptr = (PBYTE)(paramsStart + 5 * bytes + order_bytes);
*cof_ptr = (BYTE)h;
- return bufSize;
+ return bufSize;
}
static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
NTSTATUS status;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
- }
+ return 0;
+ }
ULONG result = 0;
- if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
- jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
- jstring name = (*env)->CallObjectMethod(env, params, get_name);
+ if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
+ jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
+ jstring name = (*env)->CallObjectMethod(env, params, get_name);
jint utf_length = (*env)->GetStringUTFLength(env, name);
PUCHAR chars = calloc(utf_length + 1, 1);
(*env)->GetStringUTFRegion(env, name, 0, utf_length, chars);
- const named_curve_t *curve = lookup_curve(chars);
+ const named_curve_t *curve = lookup_curve(chars);
NWPSTR curve_utf16;
ULONG ret = utf_8to16(&curve_utf16, chars);
- if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR) curve_utf16, ret * sizeof(WCHAR), 0))) {
- //err
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR)curve_utf16, ret * sizeof(WCHAR), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
- return 0;
- }
+ return 0;
+ }
free(chars);
free(curve_utf16);
result = curve->bits;
- } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
- PBYTE curve;
- ULONG curveLen = create_curve(env, params, &curve);
- if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
- //err
+ } else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ PBYTE curve;
+ ULONG curveLen = create_curve(env, params, &curve);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curveLen, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
- return 0;
- }
- free(curve);
+ return 0;
+ }
+ free(curve);
jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
@@ -421,27 +419,24 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job
jmethodID get_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
jint bits = (*env)->CallIntMethod(env, field, get_bits);
result = bits;
- }
- return result;
+ }
+ return result;
}
static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
NTSTATUS status;
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
- //err
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
return NULL;
- }
- if (bufSize == 0) {
- //err
- printf("err0\n");
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
return NULL;
- }
+ }
PBYTE fullBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, fullBuf, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
return NULL;
}
@@ -449,7 +444,7 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
ULONG paramLength;
jobject ec_priv_param_spec = create_ec_param_spec(env, fullBuf, &paramLength);
- // fullBuf looks like:
+ // fullBuf looks like:
// BCRYPT_ECCFULLKEY_BLOB header
// P[cbFieldLength] Prime specifying the base field.
// A[cbFieldLength] Coefficient A of the equation y^2 = x^3 + A*x + B mod p
@@ -463,56 +458,53 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
// Qy[cbFieldLength] Y-coordinate of the public point.
// d[cbSubgroupOrder] Private key.
BCRYPT_ECCFULLKEY_BLOB *privHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
- PBYTE priv_x = &fullBuf[paramLength];
- PBYTE priv_y = priv_x + privHeader->cbFieldLength;
- PBYTE priv = priv_y + privHeader->cbFieldLength;
+ PBYTE priv_x = &fullBuf[paramLength];
+ PBYTE priv_y = priv_x + privHeader->cbFieldLength;
+ PBYTE priv = priv_y + privHeader->cbFieldLength;
+
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, privHeader, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, privHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
-
- jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, priv_x, privHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+ jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, priv_x, privHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, priv_y, privHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, priv_y, privHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
- jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbSubgroupOrder);
- jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
- memcpy(key_priv, priv, privHeader->cbSubgroupOrder);
- (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, privHeader->cbSubgroupOrder);
+ jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ memcpy(key_priv, priv, privHeader->cbSubgroupOrder);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0);
free(fullBuf);
-
- jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "<init>", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
+
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "<init>", "([B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
}
static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
NTSTATUS status;
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
- //err
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, length only)\n", status);
return NULL;
- }
+ }
if (bufSize == 0) {
- //err
printf("err0\n");
return NULL;
}
PBYTE fullBuf = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, fullBuf, bufSize, &bufSize, 0))) {
- //err
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, fullBuf, bufSize, &bufSize, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey(full, whole)\n", status);
return NULL;
- }
+ }
ULONG paramLength;
jobject ec_pub_param_spec = create_ec_param_spec(env, fullBuf, &paramLength);
@@ -530,28 +522,28 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
// Qx[cbFieldLength] X-coordinate of the public point.
// Qy[cbFieldLength] Y-coordinate of the public point.
BCRYPT_ECCFULLKEY_BLOB *pubHeader = (BCRYPT_ECCFULLKEY_BLOB*)fullBuf;
- PBYTE pub_x = &fullBuf[paramLength];
- PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
+ PBYTE pub_x = &fullBuf[paramLength];
+ PBYTE pub_y = pub_x + pubHeader->cbFieldLength;
- jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
- jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
- memcpy(header_data, pubHeader, paramLength);
- (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ jbyteArray header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, pubHeader, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
- jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
- jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
- memcpy(x_data, pub_x, pubHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
+ jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
+ jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
+ memcpy(x_data, pub_x, pubHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, x_bytes, x_data, 0);
- jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
- jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
- memcpy(y_data, pub_y, pubHeader->cbFieldLength);
- (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
+ jbyteArray y_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
+ jbyte *y_data = (*env)->GetByteArrayElements(env, y_bytes, NULL);
+ memcpy(y_data, pub_y, pubHeader->cbFieldLength);
+ (*env)->ReleaseByteArrayElements(env, y_bytes, y_data, 0);
free(fullBuf);
- jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "<init>", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
- return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "<init>", "([B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, header_bytes, x_bytes, y_bytes, ec_pub_param_spec);
}
JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__ILjava_security_SecureRandom_2(JNIEnv *env, jobject self, jint keysize, jobject random) {
@@ -575,8 +567,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
algo = BCRYPT_ECDH_P521_ALGORITHM;
break;
default:
- //err
- break;
+ //unreachable
+ return NULL;
}
} else if (strcmp(type_data, "ECDSA") == 0) {
switch (keysize) {
@@ -590,28 +582,32 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
algo = BCRYPT_ECDSA_P521_ALGORITHM;
break;
default:
- //err
- break;
+ //unreachable
+ return NULL;
}
} else {
- //err
+ //unreachable
+ return NULL;
}
(*env)->ReleaseStringUTFChars(env, type, type_data);
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider", status);
return NULL;
}
BCRYPT_KEY_HANDLE key = NULL;
if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, keysize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
}
if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
}
jobject privkey = key_to_privkey(env, key);
@@ -624,276 +620,336 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai
return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
-JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random){
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Mscng_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(JNIEnv *env, jobject self, jobject params, jobject random) {
NTSTATUS status;
- BCRYPT_ALG_HANDLE handle = NULL;
- BCRYPT_KEY_HANDLE key = NULL;
-
- jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR algo;
- if (strcmp(type_data, "ECDH") == 0) {
- algo = BCRYPT_ECDH_ALGORITHM;
- } else if (strcmp(type_data, "ECDSA") == 0) {
- algo = BCRYPT_ECDSA_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
+ BCRYPT_ALG_HANDLE handle = NULL;
+ BCRYPT_KEY_HANDLE key = NULL;
+
+ jclass mscng_kpg_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_kpg_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR algo;
+ if (strcmp(type_data, "ECDH") == 0) {
+ algo = BCRYPT_ECDH_ALGORITHM;
+ } else if (strcmp(type_data, "ECDSA") == 0) {
+ algo = BCRYPT_ECDSA_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
ULONG bits = init_algo(env, &handle, algo, params);
- if (bits == 0) {
- //err
- }
+ if (bits == 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ return NULL;
+ }
- if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, bits, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGenerateKeyPair\n", status);
- }
+ if (NT_FAILURE(status = BCryptGenerateKeyPair(handle, &key, bits, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGenerateKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
+ }
- if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
- }
+ if (NT_FAILURE(status = BCryptFinalizeKeyPair(key, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptFinalizeKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return NULL;
+ }
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key);
+ jobject pubkey = key_to_pubkey(env, key);
- jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
- BCryptDestroyKey(key);
- BCryptCloseAlgorithmProvider(handle, 0);
- return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+ BCryptDestroyKey(key);
+ BCryptCloseAlgorithmProvider(handle, 0);
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jbyteArray pubkey, jbyteArray privkey, jobject params) {
NTSTATUS status;
printf("generateSecret!\n");
- jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR kdf_algo;
- if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
- kdf_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
- kdf_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
- kdf_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
- kdf_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
+ jclass mscng_ka_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_ka_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR kdf_algo;
+ if (strcmp(type_data, "ECDHwithSHA1KDF") == 0) {
+ kdf_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA256KDF") == 0) {
+ kdf_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA384KDF") == 0) {
+ kdf_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "ECDHwithSHA512KDF") == 0) {
+ kdf_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
- BCRYPT_ALG_HANDLE kaHandle = NULL;
+ BCRYPT_ALG_HANDLE kaHandle = NULL;
- if (!init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params)) {
- //err
- }
+ ULONG bits = init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params);
+ if (bits == 0) {
+ throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ return NULL;
+ }
- BCRYPT_KEY_HANDLE pkey = NULL;
- BCRYPT_KEY_HANDLE skey = NULL;
+ BCRYPT_KEY_HANDLE pkey = NULL;
+ BCRYPT_KEY_HANDLE skey = NULL;
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(pub)\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(kaHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair(priv)\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ BCryptDestroyKey(pkey);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
- BCRYPT_SECRET_HANDLE ka = NULL;
+ BCRYPT_SECRET_HANDLE ka = NULL;
- if (NT_FAILURE(status = BCryptSecretAgreement(skey, pkey, &ka, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSecretAgreement\n", status);
- }
+ if (NT_FAILURE(status = BCryptSecretAgreement(skey, pkey, &ka, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSecretAgreement\n", status);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ return NULL;
+ }
- BCryptBufferDesc paramList = {0};
- BCryptBuffer kdfParams[1] = {0};
- kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
- kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
- kdfParams[0].pvBuffer = (PVOID)kdf_algo;
- paramList.cBuffers = 1;
- paramList.pBuffers = kdfParams;
- paramList.ulVersion = BCRYPTBUFFER_VERSION;
+ BCryptBufferDesc paramList = { 0 };
+ BCryptBuffer kdfParams[1] = { 0 };
+ kdfParams[0].BufferType = KDF_HASH_ALGORITHM;
+ kdfParams[0].cbBuffer = (DWORD)((wcslen(kdf_algo) + 1) * sizeof(WCHAR));
+ kdfParams[0].pvBuffer = (PVOID)kdf_algo;
+ paramList.cBuffers = 1;
+ paramList.pBuffers = kdfParams;
+ paramList.ulVersion = BCRYPTBUFFER_VERSION;
- //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
- ULONG bufSize = 0;
- if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, &paramList, NULL, 0, &bufSize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(length only)\n", status);
- }
+ //TODO: Is this the actual KDF-1 or KDF-2 algo or something completely different? *This does not use the counter!!!*
+ ULONG bufSize = 0;
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, &paramList, NULL, 0, &bufSize, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptDeriveKey(length only)\n", status);
+ return NULL;
+ }
PBYTE derived = calloc(bufSize, 1);
- if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, &paramList, derived, bufSize, &bufSize, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptDeriveKey(whole)\n", status);
- }
+ if (NT_FAILURE(status = BCryptDeriveKey(ka, BCRYPT_KDF_HASH, &paramList, derived, bufSize, &bufSize, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptDeriveKey(whole)\n", status);
+ return NULL;
+ }
- jbyteArray result = (*env)->NewByteArray(env, bufSize);
- jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
- memcpy(result_data, derived, bufSize);
- (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
+ jbyteArray result = (*env)->NewByteArray(env, bufSize);
+ jbyte *result_data = (*env)->GetByteArrayElements(env, result, NULL);
+ memcpy(result_data, derived, bufSize);
+ (*env)->ReleaseByteArrayElements(env, result, result_data, 0);
free(derived);
- BCryptDestroyKey(pkey);
- BCryptDestroyKey(skey);
- BCryptDestroySecret(ka);
- BCryptCloseAlgorithmProvider(kaHandle, 0);
- return result;
+ BCryptDestroyKey(pkey);
+ BCryptDestroyKey(skey);
+ BCryptDestroySecret(ka);
+ BCryptCloseAlgorithmProvider(kaHandle, 0);
+ return result;
}
static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) {
- jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
- jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
- jstring type = (jstring) (*env)->GetObjectField(env, self, type_id);
- const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
- LPCWSTR hash_algo;
- if (strcmp(type_data, "SHA1withECDSA") == 0) {
- hash_algo = BCRYPT_SHA1_ALGORITHM;
- } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
- hash_algo = BCRYPT_SHA256_ALGORITHM;
- } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
- hash_algo = BCRYPT_SHA384_ALGORITHM;
- } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
- hash_algo = BCRYPT_SHA512_ALGORITHM;
- } else {
- //err
- }
- (*env)->ReleaseStringUTFChars(env, type, type_data);
- return hash_algo;
+ jclass mscng_sig_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi$Mscng");
+ jfieldID type_id = (*env)->GetFieldID(env, mscng_sig_class, "type", "Ljava/lang/String;");
+ jstring type = (jstring)(*env)->GetObjectField(env, self, type_id);
+ const char* type_data = (*env)->GetStringUTFChars(env, type, NULL);
+ LPCWSTR hash_algo;
+ if (strcmp(type_data, "SHA1withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA1_ALGORITHM;
+ } else if (strcmp(type_data, "SHA256withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA256_ALGORITHM;
+ } else if (strcmp(type_data, "SHA384withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA384_ALGORITHM;
+ } else if (strcmp(type_data, "SHA512withECDSA") == 0) {
+ hash_algo = BCRYPT_SHA512_ALGORITHM;
+ } else {
+ //unreachable
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars(env, type, type_data);
+ return hash_algo;
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jbyteArray privkey, jobject params) {
NTSTATUS status;
- LPCWSTR hash_algo = get_sighash_algo(env, self);
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
- BCRYPT_ALG_HANDLE sigHandle = NULL;
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return NULL;
}
- BCRYPT_ALG_HANDLE hashHandle = NULL;
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ return NULL;
+ }
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
- }
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ return NULL;
+ }
PBYTE hash = calloc(hash_len, 1);
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptHash\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
- BCRYPT_KEY_HANDLE skey = NULL;
+ BCRYPT_KEY_HANDLE skey = NULL;
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ jint priv_length = (*env)->GetArrayLength(env, privkey);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, &skey, priv_data, priv_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
- DWORD sig_len = 0;
- if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSignHash(len only)\n", status);
- }
+ DWORD sig_len = 0;
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSignHash(len only)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ return NULL;
+ }
- jbyteArray sig = (*env)->NewByteArray(env, sig_len);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptSignHash(do)\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
+ jbyteArray sig = (*env)->NewByteArray(env, sig_len);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, sig_data, sig_len, &sig_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSignHash(do)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+ return NULL;
+ }
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, 0);
free(hash);
- BCryptDestroyKey(skey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptDestroyKey(skey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
- return sig;
+ return sig;
}
JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jbyteArray pubkey, jobject params) {
NTSTATUS status;
- LPCWSTR hash_algo = get_sighash_algo(env, self);
+ LPCWSTR hash_algo = get_sighash_algo(env, self);
- BCRYPT_ALG_HANDLE sigHandle = NULL;
+ BCRYPT_ALG_HANDLE sigHandle = NULL;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- //err
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- return 0;
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return JNI_FALSE;
}
- BCRYPT_ALG_HANDLE hashHandle = NULL;
+ BCRYPT_ALG_HANDLE hashHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
- }
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&hashHandle, hash_algo, NULL, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ return JNI_FALSE;
+ }
- DWORD dummy = 0;
- DWORD hash_len = 0;
- if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
- }
+ DWORD dummy = 0;
+ DWORD hash_len = 0;
+ if (NT_FAILURE(status = BCryptGetProperty(hashHandle, BCRYPT_HASH_LENGTH, (PBYTE)&hash_len, sizeof(DWORD), &dummy, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptGetProperty(hash len)\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ return JNI_FALSE;
+ }
PBYTE hash = calloc(hash_len, 1);
- jint data_len = (*env)->GetArrayLength(env, data);
- jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
- if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
- wprintf(L"**** Error 0x%x returned by BCryptHash\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ jint data_len = (*env)->GetArrayLength(env, data);
+ jbyte *data_bytes = (*env)->GetByteArrayElements(env, data, NULL);
+ if (NT_FAILURE(status = BCryptHash(hashHandle, NULL, 0, data_bytes, data_len, hash, hash_len))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptHash\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
+ return JNI_FALSE;
+ }
+ (*env)->ReleaseByteArrayElements(env, data, data_bytes, JNI_ABORT);
- BCRYPT_KEY_HANDLE pkey = NULL;
+ BCRYPT_KEY_HANDLE pkey = NULL;
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
- if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
- wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status);
- }
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ jint pub_length = (*env)->GetArrayLength(env, pubkey);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ if (NT_FAILURE(status = BCryptImportKeyPair(sigHandle, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, &pkey, pub_data, pub_length, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptImportKeyPair\n", status);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ free(hash);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ return JNI_FALSE;
+ }
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
- jint sig_len = (*env)->GetArrayLength(env, sig);
- jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
- NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
- (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
+ jint sig_len = (*env)->GetArrayLength(env, sig);
+ jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
+ NTSTATUS result = BCryptVerifySignature(pkey, NULL, hash, hash_len, sig_data, sig_len, 0);
+ (*env)->ReleaseByteArrayElements(env, sig, sig_data, JNI_ABORT);
free(hash);
- BCryptDestroyKey(pkey);
- BCryptCloseAlgorithmProvider(hashHandle, 0);
- BCryptCloseAlgorithmProvider(sigHandle, 0);
+ BCryptDestroyKey(pkey);
+ BCryptCloseAlgorithmProvider(hashHandle, 0);
+ BCryptCloseAlgorithmProvider(sigHandle, 0);
- if (result == STATUS_SUCCESS) {
- return JNI_TRUE;
- } else if (result == STATUS_INVALID_SIGNATURE) {
- return JNI_FALSE;
- } else {
- wprintf(L"**** Error 0x%x returned by BCryptVerifySignature\n", status);
- return JNI_FALSE;
- }
+ if (result == STATUS_SUCCESS) {
+ return JNI_TRUE;
+ } else if (result == STATUS_INVALID_SIGNATURE) {
+ return JNI_FALSE;
+ } else {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptVerifySignature\n", status);
+ return JNI_FALSE;
+ }
} \ No newline at end of file