diff options
Diffstat (limited to 'src')
6 files changed, 345 insertions, 70 deletions
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index 2897d20..2f132fa 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -275,7 +275,6 @@ public class ECTesterStandalone { .findFirst() .orElse(null))); - if (kaIdent == null || kpIdent == null) { throw new NoSuchAlgorithmException(algo); } else { diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java index 76786fe..4cd4a9d 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java @@ -86,23 +86,38 @@ public abstract class NativeECPrivateKey implements ECPrivateKey { } public static class Mscng extends Raw { + // 0 -> implicit (meta = curveName UTF16, header = full); + // 1 -> explicit (meta = null, header = full); + // 2 -> nist (meta = null, header = full) + private int flag; + private byte[] meta = null; private byte[] header; private byte[] x; private byte[] y; - public Mscng(byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) { + public Mscng(int flag, byte[] meta, byte[] header, byte[] x, byte[] y, byte[] keyData, ECParameterSpec params) { super(keyData, params); + this.flag = flag; + this.meta = Arrays.clone(meta); this.header = Arrays.clone(header); this.x = Arrays.clone(x); this.y = Arrays.clone(y); } + public int getFlag() { + return flag; + } + + public byte[] getMeta() { + return Arrays.clone(meta); + } + public byte[] getHeader() { return Arrays.clone(header); } public byte[] getBlob() { - return ByteUtil.concatenate(header, x, y, keyData); + return ByteUtil.concatenate(header, x, y, keyData); } @Override diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java index e55ed33..ccf21c0 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java @@ -88,23 +88,38 @@ public abstract class NativeECPublicKey implements ECPublicKey { } public static class Mscng extends ANSIX962 { + // 0 -> implicit (meta = curveName UTF16, header = full); + // 1 -> explicit (meta = null, header = full); + // 2 -> nist (meta = null, header = full) + private int flag; + private byte[] meta = null; private byte[] header; private byte[] x; private byte[] y; - public Mscng(byte[] header, byte[] x, byte[] y, ECParameterSpec params) { + public Mscng(int flag, byte[] meta, byte[] header, byte[] x, byte[] y, ECParameterSpec params) { super(ByteUtil.concatenate(new byte[]{0x04}, x, y), params); + this.flag = flag; + this.meta = Arrays.clone(meta); this.header = Arrays.clone(header); this.x = Arrays.clone(x); this.y = Arrays.clone(y); } + public int getFlag() { + return flag; + } + + public byte[] getMeta() { + return Arrays.clone(meta); + } + public byte[] getHeader() { return Arrays.clone(header); } public byte[] getBlob() { - return ByteUtil.concatenate(header, x, y); + return ByteUtil.concatenate(header, x, y); } @Override diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java index 81c7948..b60f2c6 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java @@ -92,6 +92,23 @@ public abstract class NativeSignatureSpi extends SignatureSpi { abstract boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params); } + private abstract static class ExtendedSignatureSpi extends NativeSignatureSpi { + + @Override + protected byte[] engineSign() throws SignatureException { + return sign(buffer.toByteArray(), signKey, params); + } + + @Override + protected boolean engineVerify(byte[] sigBytes) throws SignatureException { + return verify(sigBytes, buffer.toByteArray(), verifyKey, params); + } + + abstract byte[] sign(byte[] data, ECPrivateKey privkey, ECParameterSpec params); + + abstract boolean verify(byte[] signature, byte[] data, ECPublicKey pubkey, ECParameterSpec params); + } + public static class TomCryptRaw extends SimpleSignatureSpi { @Override @@ -311,7 +328,7 @@ public abstract class NativeSignatureSpi extends SignatureSpi { } } - public abstract static class Mscng extends SimpleSignatureSpi { + public abstract static class Mscng extends ExtendedSignatureSpi { private String type; public Mscng(String type) { @@ -319,10 +336,10 @@ public abstract class NativeSignatureSpi extends SignatureSpi { } @Override - native byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params); + native byte[] sign(byte[] data, ECPrivateKey privkey, ECParameterSpec params); @Override - native boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params); + native boolean verify(byte[] signature, byte[] data, ECPublicKey pubkey, ECParameterSpec params); } public static class MscngECDSAwithSHA1 extends Mscng { diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c index 12cc13d..8cd96fc 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c @@ -6,8 +6,9 @@ #include <stdio.h>
-static jclass provider_class;
+
+// BCRYPT and NT things.
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#define NT_FAILURE(status) !NT_SUCCESS(status)
@@ -24,6 +25,13 @@ typedef struct { ULONG cbSeed; //Byte length of the seed used to generate the curve.
} BCRYPT_ECC_PARAMETER_HEADER;
+//Provider things
+static jclass provider_class;
+
+#define KEYFLAG_IMPLICIT 0
+#define KEYFLAG_EXPLICIT 1
+#define KEYFLAG_NIST 2
+
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);
@@ -138,8 +146,8 @@ static ULONG utf_8to16(NWPSTR *out_buf, LPCSTR in_str) { return MultiByteToWideChar(CP_UTF8, 0, in_str, -1, *out_buf, result);
}
-// Convert Java String to UTF-16 LPCWSTR null-terminated.
-// Returns: Length of LPCWSTR in bytes!
+// Convert Java String to UTF-16 NWPSTR null-terminated.
+// Returns: Length of NWPSTR in bytes!
static ULONG utf_strto16(NWPSTR *out_buf, JNIEnv *env, jobject str) {
jsize len = (*env)->GetStringLength(env, str);
*out_buf = calloc(len * sizeof(jchar) + 1, 1);
@@ -378,7 +386,7 @@ static ULONG create_curve(JNIEnv *env, jobject params, PBYTE *curve) { return bufSize;
}
-static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, jobject params) {
+static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, jint *keyflag, NWPSTR *curve_name, LPCWSTR algo, jobject params) {
NTSTATUS status;
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
@@ -392,15 +400,14 @@ static ULONG init_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR algo, job PUCHAR chars = calloc(utf_length + 1, 1);
(*env)->GetStringUTFRegion(env, name, 0, utf_length, 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))) {
+ ULONG ret = utf_8to16(curve_name, chars);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, (PUCHAR)*curve_name, ret * sizeof(WCHAR), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
return 0;
}
free(chars);
- free(curve_utf16);
result = curve->bits;
+ *keyflag = KEYFLAG_IMPLICIT;
} else if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
PBYTE curve;
ULONG curveLen = create_curve(env, params, &curve);
@@ -419,11 +426,13 @@ 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;
+ *keyflag = KEYFLAG_EXPLICIT;
+ *curve_name = NULL;
}
return result;
}
-static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jint flag, LPCWSTR curve) {
NTSTATUS status;
ULONG bufSize = 0;
if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
@@ -438,6 +447,7 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) { PBYTE fullBuf = calloc(bufSize, 1);
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);
+ free(fullBuf);
return NULL;
}
@@ -462,10 +472,59 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) { 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 meta_bytes = NULL;
+ jbyteArray header_bytes = NULL;
+ switch (flag) {
+ case 0: {
+ // meta = curve
+ jint meta_len = (wcslen(curve) + 1) * sizeof(WCHAR);
+ meta_bytes = (*env)->NewByteArray(env, meta_len);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta_bytes, NULL);
+ memcpy(meta_data, curve, meta_len);
+ (*env)->ReleaseByteArrayElements(env, meta_bytes, meta_data, 0);
+ }
+ case 1:
+ case 2: {
+ // meta = null
+ // header = full
+ header_bytes = (*env)->NewByteArray(env, paramLength);
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, fullBuf, paramLength);
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ break;
+ }
+ default:
+ // header = small
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, NULL, 0, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, length only)\n", status);
+ free(fullBuf);
+ return NULL;
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
+ free(fullBuf);
+ return NULL;
+ }
+ PBYTE smallBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPRIVATE_BLOB, smallBuf, bufSize, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, whole)\n", status);
+ free(fullBuf);
+ free(smallBuf);
+ return NULL;
+ }
+ // smallBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ // d[cbSubgroupOrder] Private key.
+ header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, smallBuf, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ free(smallBuf);
+ break;
+ }
jbyteArray x_bytes = (*env)->NewByteArray(env, privHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
@@ -484,11 +543,11 @@ static jobject key_to_privkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) { 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>", "(I[B[B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, privkey_class, ec_priv_init, flag, meta_bytes, header_bytes, x_bytes, y_bytes, priv_bytes, ec_priv_param_spec);
}
-static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) {
+static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key, jint flag, LPCWSTR curve) {
NTSTATUS status;
ULONG bufSize = 0;
if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCFULLPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
@@ -525,10 +584,55 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) { 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 meta_bytes = NULL;
+ jbyteArray header_bytes = NULL;
+ switch (flag) {
+ case 0: {
+ // meta = curve
+ jint meta_len = (wcslen(curve) + 1) * sizeof(WCHAR);
+ meta_bytes = (*env)->NewByteArray(env, meta_len);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta_bytes, NULL);
+ memcpy(meta_data, curve, meta_len);
+ (*env)->ReleaseByteArrayElements(env, meta_bytes, meta_data, 0);
+ }
+ case 1:
+ case 2: {
+ 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);
+ break;
+ }
+ default:
+ // header = small
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, NULL, 0, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, length only)\n", status);
+ free(fullBuf);
+ return NULL;
+ }
+ if (bufSize == 0) {
+ printf("buf 0\n");
+ free(fullBuf);
+ return NULL;
+ }
+ PBYTE smallBuf = calloc(bufSize, 1);
+ if (NT_FAILURE(status = BCryptExportKey(key, NULL, BCRYPT_ECCPUBLIC_BLOB, smallBuf, bufSize, &bufSize, 0))) {
+ wprintf(L"**** Error 0x%x returned by BCryptExportKey(small, whole)\n", status);
+ free(fullBuf);
+ free(smallBuf);
+ return NULL;
+ }
+ // smallBuf looks like:
+ // BCRYPT_ECCKEY_BLOB header
+ // Qx[cbFieldLength] X-coordinate of the public point.
+ // Qy[cbFieldLength] Y-coordinate of the public point.
+ header_bytes = (*env)->NewByteArray(env, sizeof(BCRYPT_ECCKEY_BLOB));
+ jbyte *header_data = (*env)->GetByteArrayElements(env, header_bytes, NULL);
+ memcpy(header_data, smallBuf, sizeof(BCRYPT_ECCKEY_BLOB));
+ (*env)->ReleaseByteArrayElements(env, header_bytes, header_data, 0);
+ free(smallBuf);
+ break;
+ }
jbyteArray x_bytes = (*env)->NewByteArray(env, pubHeader->cbFieldLength);
jbyte *x_data = (*env)->GetByteArrayElements(env, x_bytes, NULL);
@@ -542,8 +646,8 @@ static jobject key_to_pubkey(JNIEnv *env, BCRYPT_KEY_HANDLE key) { 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>", "(I[B[B[B[BLjava/security/spec/ECParameterSpec;)V");
+ return (*env)->NewObject(env, pubkey_class, ec_pub_init, flag, meta_bytes, 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) {
@@ -610,8 +714,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return NULL;
}
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key, KEYFLAG_NIST, NULL);
+ jobject pubkey = key_to_pubkey(env, key, KEYFLAG_NIST, NULL);
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
@@ -640,7 +744,9 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai }
(*env)->ReleaseStringUTFChars(env, type, type_data);
- ULONG bits = init_algo(env, &handle, algo, params);
+ jint keyflag;
+ NWPSTR curveName;
+ ULONG bits = init_algo(env, &handle, &keyflag, &curveName, algo, params);
if (bits == 0) {
throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
return NULL;
@@ -658,8 +764,12 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return NULL;
}
- jobject privkey = key_to_privkey(env, key);
- jobject pubkey = key_to_pubkey(env, key);
+ jobject privkey = key_to_privkey(env, key, keyflag, curveName);
+ jobject pubkey = key_to_pubkey(env, key, keyflag, curveName);
+
+ if (curveName) {
+ free(curveName);
+ }
jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
@@ -668,9 +778,109 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
}
+static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR type, jint keyflag, jbyteArray meta, jobject params) {
+ LPCWSTR ecdh_algos[] = {
+ BCRYPT_ECDH_ALGORITHM,
+ BCRYPT_ECDH_P256_ALGORITHM,
+ BCRYPT_ECDH_P384_ALGORITHM,
+ BCRYPT_ECDH_P521_ALGORITHM
+ };
+ LPCWSTR ecdsa_algos[] = {
+ BCRYPT_ECDSA_ALGORITHM,
+ BCRYPT_ECDSA_P256_ALGORITHM,
+ BCRYPT_ECDSA_P384_ALGORITHM,
+ BCRYPT_ECDSA_P521_ALGORITHM
+ };
+
+ LPCWSTR *algos;
+ LPCWSTR algo;
+ if (lstrcmpW(type, BCRYPT_ECDH_ALGORITHM) == 0) {
+ algos = ecdh_algos;
+ } else if (lstrcmpW(type, BCRYPT_ECDSA_ALGORITHM) == 0) {
+ algos = ecdsa_algos;
+ } else {
+ //unreachable
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (keyflag) {
+ case 0:
+ case 1:
+ algo = algos[0];
+ break;
+ case 2: {
+ 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_bits = (*env)->GetMethodID(env, fp_field_class, "getFieldSize", "()I");
+ jint bits = (*env)->CallIntMethod(env, field, get_bits);
+ switch (bits) {
+ case 256:
+ algo = algos[1];
+ break;
+ case 384:
+ algo = algos[2];
+ break;
+ case 521:
+ algo = algos[3];
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ }
+ NTSTATUS status;
+
+ if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(handle, algo, MS_PRIMITIVE_PROVIDER, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ return status;
+ }
+
+ switch (keyflag) {
+ case 0: {
+ jint meta_len = (*env)->GetArrayLength(env, meta);
+ jbyte *meta_data = (*env)->GetByteArrayElements(env, meta, NULL);
+ //if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_CURVE_NAME, meta_data, meta_len, 0))) {
+ // throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSetProperty(curve name)\n", status);
+ // (*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
+ // return status;
+ //}
+ (*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
+ break;
+ }
+ case 1: {
+ PBYTE curve;
+ ULONG curve_len = create_curve(env, params, &curve);
+ if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curve_len, 0))) {
+ throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptSetProperty(parameters)\n", status);
+ free(curve);
+ return status;
+ }
+ free(curve);
+ break;
+ }
+ }
+ return STATUS_SUCCESS;
+}
+
+static jint get_keyflag(JNIEnv *env, jobject key) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_flag = (*env)->GetMethodID(env, key_class, "getFlag", "()I");
+ return (*env)->CallIntMethod(env, key, get_flag);
+}
+
+static jbyteArray get_meta(JNIEnv *env, jobject key) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_meta = (*env)->GetMethodID(env, key_class, "getMeta", "()[B");
+ return (jbyteArray)(*env)->CallObjectMethod(env, key, get_meta);
+}
+
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;");
@@ -693,9 +903,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey BCRYPT_ALG_HANDLE kaHandle = NULL;
- ULONG bits = init_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, params);
- if (bits == 0) {
- throw_new(env, "java/security/GeneralSecurityException", "Couldn't initialize algo.");
+ jint pub_flag = get_keyflag(env, pubkey);
+ jbyteArray meta = get_meta(env, pubkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, pub_flag, meta, params))) {
return NULL;
}
@@ -712,6 +923,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey }
(*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ jint priv_flag = get_keyflag(env, privkey);
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))) {
@@ -791,12 +1003,19 @@ static LPCWSTR get_sighash_algo(JNIEnv *env, jobject self) { 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) {
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign(JNIEnv *env, jobject self, jbyteArray data, jobject privkey, jobject params) {
NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
+ jint keyflag = get_keyflag(env, privkey);
+ jbyteArray meta = get_meta(env, privkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
+ return NULL;
+ }
+
if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
return NULL;
@@ -835,17 +1054,21 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig BCRYPT_KEY_HANDLE skey = NULL;
- jint priv_length = (*env)->GetArrayLength(env, privkey);
- jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ jmethodID get_data = (*env)->GetMethodID(env, privkey_class, "getData", "()[B");
+ jbyteArray privkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, privkey, get_data);
+
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey_barray);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey_barray, 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);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
return NULL;
}
- (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, privkey_barray, priv_data, JNI_ABORT);
DWORD sig_len = 0;
if (NT_FAILURE(status = BCryptSignHash(skey, NULL, hash, hash_len, NULL, 0, &sig_len, 0))) {
@@ -877,14 +1100,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig 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) {
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify(JNIEnv *env, jobject self, jbyteArray sig, jbyteArray data, jobject pubkey, jobject params) {
NTSTATUS status;
LPCWSTR hash_algo = get_sighash_algo(env, self);
BCRYPT_ALG_HANDLE sigHandle = NULL;
- if (NT_FAILURE(status = BCryptOpenAlgorithmProvider(&sigHandle, BCRYPT_ECDSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0))) {
- throw_new_var(env, "java/security/GeneralSecurityException", "Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
+ jint keyflag = get_keyflag(env, pubkey);
+ jbyteArray meta = get_meta(env, pubkey);
+
+ if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
return JNI_FALSE;
}
@@ -921,17 +1146,21 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna BCRYPT_KEY_HANDLE pkey = NULL;
- jint pub_length = (*env)->GetArrayLength(env, pubkey);
- jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ jmethodID get_data = (*env)->GetMethodID(env, pubkey_class, "getData", "()[B");
+ jbyteArray pubkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, pubkey, get_data);
+
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey_barray);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey_barray, 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);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
return JNI_FALSE;
}
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
jint sig_len = (*env)->GetArrayLength(env, sig);
jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h index a2dedae..e8dff88 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h @@ -35,7 +35,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_TomcryptLib_getC extern "C" { #endif #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 1421746759512286392i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_MAX_ARRAY_SIZE 2147483639L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_KEYS @@ -45,9 +45,9 @@ extern "C" { #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_ENTRIES 2L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID 4112578634029874840i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt_serialVersionUID -4298000515446427739i64 /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_TomCrypt * Method: setup @@ -206,7 +206,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_BotanLib_getCurv extern "C" { #endif #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 1421746759512286392i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_MAX_ARRAY_SIZE 2147483639L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_KEYS @@ -216,9 +216,9 @@ extern "C" { #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_ENTRIES 2L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID 4112578634029874840i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan_serialVersionUID -4298000515446427739i64 /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Botan * Method: setup @@ -377,7 +377,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_CryptoppLib_getC extern "C" { #endif #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 1421746759512286392i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_MAX_ARRAY_SIZE 2147483639L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_KEYS @@ -387,9 +387,9 @@ extern "C" { #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_ENTRIES 2L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID 4112578634029874840i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp_serialVersionUID -4298000515446427739i64 /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Cryptopp * Method: setup @@ -548,7 +548,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_OpensslLib_getCu extern "C" { #endif #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 1421746759512286392i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_MAX_ARRAY_SIZE 2147483639L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_KEYS @@ -558,9 +558,9 @@ extern "C" { #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_ENTRIES 2L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID 4112578634029874840i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl_serialVersionUID -4298000515446427739i64 /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Openssl * Method: setup @@ -719,7 +719,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_MscngLib_getCurv extern "C" { #endif #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 1421746759512286392i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_MAX_ARRAY_SIZE 2147483639L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_KEYS @@ -729,9 +729,9 @@ extern "C" { #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES #define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_ENTRIES 2L #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID 4112578634029874840i64 #undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739LL +#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng_serialVersionUID -4298000515446427739i64 /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Mscng * Method: setup @@ -838,18 +838,18 @@ extern "C" { /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng * Method: sign - * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + * Signature: ([BLjava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B */ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_sign - (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + (JNIEnv *, jobject, jbyteArray, jobject, jobject); /* * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Mscng * Method: verify - * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z + * Signature: ([B[BLjava/security/interfaces/ECPublicKey;Ljava/security/spec/ECParameterSpec;)Z */ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Mscng_verify - (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject); + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jobject); #ifdef __cplusplus } |
