diff options
Diffstat (limited to 'src/cz')
4 files changed, 114 insertions, 54 deletions
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat index 3530fe9..9b0d6f7 100755 --- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat +++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile.bat @@ -5,6 +5,7 @@ setlocal EnableDelayedExpansion :: - JAVA_HOME
:: - CC
:: - USE_EXT_MSCNG
+:: - DEBUG
:: See if we are cleaning.
if "%1" == "clean" (
@@ -13,11 +14,13 @@ if "%1" == "clean" ( exit
)
+set TAB=
+
:: Determine arch.
-reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && (set ARCH=32& set ARCH_S=x86& set ARCH_VS=x86) || (set ARCH=64& set ARCH_S=x64& set ARCH_VS=amd64)
+reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL 2>&1 && (set ARCH=32& set ARCH_S=x86& set ARCH_VS=x86) || (set ARCH=64& set ARCH_S=x64& set ARCH_VS=amd64)
-echo ** ARCH %ARCH_S%
+echo ** ARCH%TAB%%TAB%%ARCH_S%
:: Find a working visual studio environment.
@@ -27,7 +30,7 @@ set vsw_path="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" set vs_path=
for /f "usebackq delims=" %%i in (`%vsw_path% -nologo -prerelease -latest -property installationPath`) do (
if exist "%%i\Common7\Tools\vsdevcmd.bat" (
- echo ** VsDevCmd at %%i\Common7\Tools\vsdevcmd.bat
+ echo ** VsDevCmd%TAB%%TAB%%%i\Common7\Tools\vsdevcmd.bat
call "%%i\Common7\Tools\vsdevcmd.bat" -no_logo -arch=%ARCH_VS%
if ERRORLEVEL 1 (
echo nope.
@@ -45,7 +48,7 @@ if %found% EQU 0 ( exit /b 2
)
-echo ** VS_PATH %vs_path%
+echo ** VS_PATH%TAB%%TAB%%vs_path%
:: Try to find vcruntime.
@@ -55,7 +58,7 @@ if exist %vc_base% ( for /f "delims=" %%i in ('dir /b /on "!vc_base!"') do (
set vc_version=%%i
)
- echo ** VC_VERSION !vc_version!
+ echo ** VC_VERSION%TAB%!vc_version!
set vc_include=%vc_base%!vc_version!\include
set vc_lib=%vc_base%!vc_version!\lib\%ARCH_S%
)
@@ -77,8 +80,8 @@ popd set mscng_lib_arch=%mscng_lib%\X%ARCH%
-echo ** CNG_INCLUDE !mscng_include!
-echo ** CNG_LIB !mscng_lib!
+echo ** CNG_INCLUDE%TAB%%mscng_include%
+echo ** CNG_LIB%TAB%%TAB%%mscng_lib_arch%
:: Get the paths to Java JNI.
@@ -92,7 +95,7 @@ if not defined JAVA_HOME ( popd
)
-echo ** JAVA_HOME !JAVA_HOME!
+echo ** JAVA_HOME%TAB%%JAVA_HOME%
set JNI_INCLUDEDIR=%JAVA_HOME%\include
set JNI_PLATFORMINCLUDEDIR=%JNI_INCLUDEDIR%\win32
@@ -104,7 +107,7 @@ if not defined CC ( set CC=cl.exe
)
-echo ** CC !CC!
+echo ** CC%TAB%%TAB%%CC%
:: Try to find uCRT.
@@ -114,7 +117,7 @@ if exist %ucrt_base% ( for /f "delims=" %%i in ('dir /b /on "!ucrt_base!\Include"') do (
set ucrt_version=%%i
)
- echo ** uCRT !ucrt_version!
+ echo ** uCRT%TAB%%TAB%!ucrt_version!
set ucrt_include=%ucrt_base%Include\!ucrt_version!\ucrt
set ucrt_lib=%ucrt_base%Lib\!ucrt_version!
set ucrt_lib_arch=!ucrt_lib!\ucrt\%ARCH_S%
@@ -128,8 +131,8 @@ if defined USE_EXT_MSCNG ( set INCLUDE_CLI=!INCLUDE_CLI! /I"%mscng_include%"
)
-echo ** INCLUDE %INCLUDE%
-echo ** INCLUDE_CLI %INCLUDE_CLI%
+echo ** INCLUDE%TAB%%TAB%%INCLUDE%
+echo ** INCLUDE_CLI%TAB%%INCLUDE_CLI%
:: Setup LIB paths.
@@ -139,9 +142,22 @@ if defined USE_EXT_MSCNG ( set LIBPATH=!LIBPATH! /LIBPATH:"%mscng_lib_arch%"
)
-echo ** LIB %LIB%
-echo ** LIBPATH %LIBPATH%
+echo ** LIB%TAB%%TAB%%LIB%
+echo ** LIBPATH%TAB%%TAB%%LIBPATH%
+
+
+:: Setup DEBUB options.
+set OTHER_CLI=
+if defined DEBUG (
+ set OTHER_CLI=/Od /Z7
+) else (
+ set OTHER_CLI=/O2
+)
+
+echo ** OTHER_CLI%TAB%%OTHER_CLI%
echo.
+echo ^>^> %CC% /W2 /EHsc %OTHER_CLI% %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH% /nologo
+echo.
-%CC% /EHsc %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH%
\ No newline at end of file +%CC% /W2 /EHsc %OTHER_CLI% %INCLUDE_CLI% mscng.c c_utils.c bcrypt.lib jvm.lib /Femscng_provider.dll /LD /link %LIBPATH% /nologo
\ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java index c11c803..4ed3469 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java @@ -11,6 +11,7 @@ import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECParameterSpec; +import java.security.spec.ECGenParameterSpec; /** * @author Jan Jancar johny@neuromancer.sk @@ -18,7 +19,7 @@ import java.security.spec.ECParameterSpec; public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { ECPrivateKey privateKey; ECPublicKey publicKey; - ECParameterSpec params; + AlgorithmParameterSpec params; @Override protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException { @@ -31,15 +32,6 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { } @Override - protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { - if (!(params instanceof ECParameterSpec)) { - throw new InvalidAlgorithmParameterException(); - } - engineInit(key, random); - this.params = (ECParameterSpec) params; - } - - @Override protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { if (privateKey == null) { throw new IllegalStateException("Not initialized"); @@ -71,27 +63,36 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { @Override protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException { - // TODO: This is dangerous/not correct ! Need to actually implement KDF1 and KDF2 here probably. + // TODO: This is dangerous/not correct ! Need to actually implement KDF1 and KDF2 here probably. Or just pass it off to the libs through some different interface. return new SecretKeySpec(engineGenerateSecret(), algorithm); } private abstract static class SimpleKeyAgreementSpi extends NativeKeyAgreementSpi { @Override + protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (!(params instanceof ECParameterSpec)) { + throw new InvalidAlgorithmParameterException(); + } + engineInit(key, random); + this.params = params; + } + + @Override protected byte[] engineGenerateSecret() throws IllegalStateException { byte[] pubkey; if (publicKey instanceof NativeECPublicKey) { pubkey = ((NativeECPublicKey) publicKey).getData(); } else { - pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), params.getCurve()); + pubkey = ECUtil.toX962Uncompressed(publicKey.getW(), ((ECParameterSpec) params).getCurve()); } byte[] privkey; if (privateKey instanceof NativeECPrivateKey) { privkey = ((NativeECPrivateKey) privateKey).getData(); } else { - privkey = ECUtil.toByteArray(privateKey.getS(), params.getCurve().getField().getFieldSize()); + privkey = ECUtil.toByteArray(privateKey.getS(), ((ECParameterSpec) params).getCurve().getField().getFieldSize()); } - return generateSecret(pubkey, privkey, params); + return generateSecret(pubkey, privkey, (ECParameterSpec) params); } abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params); @@ -100,11 +101,20 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { private abstract static class ExtendedKeyAgreementSpi extends NativeKeyAgreementSpi { @Override + protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { + if (!(params instanceof ECParameterSpec || params instanceof ECGenParameterSpec)) { + throw new InvalidAlgorithmParameterException(); + } + engineInit(key, random); + this.params = params; + } + + @Override protected byte[] engineGenerateSecret() throws IllegalStateException { return generateSecret(publicKey, privateKey, params); } - abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params); + abstract byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params); } @@ -203,7 +213,7 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { } @Override - native byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, ECParameterSpec params); + native byte[] generateSecret(ECPublicKey pubkey, ECPrivateKey privkey, AlgorithmParameterSpec params); } public static class MscngECDHwithSHA1KDF 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 a284901..16736d7 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c @@ -28,9 +28,10 @@ typedef struct { //Provider things
static jclass provider_class;
-#define KEYFLAG_IMPLICIT 0
-#define KEYFLAG_EXPLICIT 1
-#define KEYFLAG_NIST 2
+#define KEYFLAG_IMPLICIT 0 //Mscng native key, over named curve
+#define KEYFLAG_EXPLICIT 1 //Mscng native key, over explicit ecc parameters
+#define KEYFLAG_NIST 2 //Mscng native key, over NIST parameters, custom ECDH/ECDSA_P* algo
+#define KEYFLAG_OTHER 3 //Other key, explicit ecc parameters
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");
@@ -797,11 +798,12 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty }
switch (keyflag) {
- case 0:
- case 1:
+ case KEYFLAG_IMPLICIT:
+ case KEYFLAG_EXPLICIT:
+ case KEYFLAG_OTHER:
algo = algos[0];
break;
- case 2: {
+ case KEYFLAG_NIST: {
jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
jobject elliptic_curve = (*env)->CallObjectMethod(env, params, get_curve);
@@ -834,7 +836,7 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty }
switch (keyflag) {
- case 0: {
+ case KEYFLAG_IMPLICIT: {
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))) {
@@ -845,7 +847,8 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty (*env)->ReleaseByteArrayElements(env, meta, meta_data, JNI_ABORT);
break;
}
- case 1: {
+ case KEYFLAG_EXPLICIT:
+ case KEYFLAG_OTHER: {
PBYTE curve;
ULONG curve_len = create_curve(env, params, &curve);
if (NT_FAILURE(status = BCryptSetProperty(*handle, BCRYPT_ECC_PARAMETERS, curve, curve_len, 0))) {
@@ -861,15 +864,23 @@ static NTSTATUS init_use_algo(JNIEnv *env, BCRYPT_ALG_HANDLE *handle, LPCWSTR ty }
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);
+ if ((*env)->IsInstanceOf(env, key, pubkey_class) || (*env)->IsInstanceOf(env, key, privkey_class)) {
+ jclass key_class = (*env)->GetObjectClass(env, key);
+ jmethodID get_flag = (*env)->GetMethodID(env, key_class, "getFlag", "()I");
+ return (*env)->CallIntMethod(env, key, get_flag);
+ } else {
+ return KEYFLAG_OTHER;
+ }
}
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);
+ if ((*env)->IsInstanceOf(env, key, pubkey_class) || (*env)->IsInstanceOf(env, key, privkey_class)) {
+ 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);
+ } else {
+ return NULL;
+ }
}
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret(JNIEnv *env, jobject self, jobject pubkey, jobject privkey, jobject params) {
@@ -897,6 +908,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey BCRYPT_ALG_HANDLE kaHandle = NULL;
jint pub_flag = get_keyflag(env, pubkey);
+ if (pub_flag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native public key.");
+ return NULL;
+ }
jbyteArray meta = get_meta(env, pubkey);
if (NT_FAILURE(status = init_use_algo(env, &kaHandle, BCRYPT_ECDH_ALGORITHM, pub_flag, meta, params))) {
@@ -906,27 +921,38 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey 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);
+ jmethodID get_data_priv = (*env)->GetMethodID(env, pubkey_class, "getData", "()[B");
+ jbyteArray pubkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, pubkey, get_data_priv);
+
+ jint pub_length = (*env)->GetArrayLength(env, pubkey_barray);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey_barray, 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);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
return NULL;
}
- (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+ (*env)->ReleaseByteArrayElements(env, pubkey_barray, 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 (priv_flag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native private key.");
+ return NULL;
+ }
+
+ jmethodID get_data_pub = (*env)->GetMethodID(env, privkey_class, "getData", "()[B");
+ jbyteArray privkey_barray = (jbyteArray)(*env)->CallObjectMethod(env, privkey, get_data_pub);
+
+ jint priv_length = (*env)->GetArrayLength(env, privkey_barray);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey_barray, 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);
+ (*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);
BCRYPT_SECRET_HANDLE ka = NULL;
@@ -1002,6 +1028,10 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig BCRYPT_ALG_HANDLE sigHandle = NULL;
jint keyflag = get_keyflag(env, privkey);
+ if (keyflag == KEYFLAG_OTHER) {
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native private key.");
+ return NULL;
+ }
jbyteArray meta = get_meta(env, privkey);
if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
@@ -1099,6 +1129,10 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna BCRYPT_ALG_HANDLE sigHandle = NULL;
jint keyflag = get_keyflag(env, pubkey);
+ if (keyflag == KEYFLAG_OTHER) { // TODO: This is not necessary
+ throw_new(env, "java/security/InvalidAlgorithmParameterException", "Cannot import non-native public key.");
+ return JNI_FALSE;
+ }
jbyteArray meta = get_meta(env, pubkey);
if (NT_FAILURE(status = init_use_algo(env, &sigHandle, BCRYPT_ECDSA_ALGORITHM, keyflag, meta, params))) {
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h index b5cde43..dcdaa1b 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h @@ -819,7 +819,7 @@ extern "C" { /*
* Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Mscng
* Method: generateSecret
- * Signature: (Ljava/security/interfaces/ECPublicKey;Ljava/security/interfaces/ECPrivateKey;Ljava/security/spec/ECParameterSpec;)[B
+ * Signature: (Ljava/security/interfaces/ECPublicKey;Ljava/security/interfaces/ECPrivateKey;Ljava/security/spec/AlgorithmParameterSpec;)[B
*/
JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Mscng_generateSecret
(JNIEnv *, jobject, jobject, jobject, jobject);
|
