Skip to content

Commit

Permalink
Fix libgcrypt issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
J08nY committed Jun 19, 2024
1 parent c38ef1e commit 57c4f0e
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import cz.crcs.ectester.common.test.SimpleTest;
import cz.crcs.ectester.common.test.TestCallback;

import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;

/**
* @author Jan Jancar [email protected]
*/
Expand Down Expand Up @@ -38,6 +41,15 @@ public static KeyGeneratorTest function(KeyGeneratorTestable ka, TestCallback<Ke

@Override
public String getDescription() {
return "KeyPairGenerator " + testable.getKpg().getAlgorithm();
String params = "";
if (testable.getKeysize() != 0) {
params = String.format("(default %d-bit curve)", testable.getKeysize());
} else if (testable.getSpec() instanceof ECGenParameterSpec) {
String name = ((ECGenParameterSpec)testable.getSpec()).getName();
params = String.format("(%s)", name);
} else if (testable.getSpec() instanceof ECParameterSpec) {
params = "(custom curve)";
}
return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " on " + params;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;

/**
Expand All @@ -12,7 +14,7 @@ public class KeyGeneratorTestable extends StandaloneTestable<KeyGeneratorTestabl
private KeyPair kp;
private final KeyPairGenerator kpg;
private int keysize = 0;
private ECParameterSpec spec = null;
private AlgorithmParameterSpec spec = null;

public KeyGeneratorTestable(KeyPairGenerator kpg) {
this.kpg = kpg;
Expand All @@ -28,6 +30,19 @@ public KeyGeneratorTestable(KeyPairGenerator kpg, ECParameterSpec spec) {
this.spec = spec;
}

public KeyGeneratorTestable(KeyPairGenerator kpg, ECGenParameterSpec spec) {
this.kpg = kpg;
this.spec = spec;
}

public int getKeysize() {
return keysize;
}

public AlgorithmParameterSpec getSpec() {
return spec;
}

public KeyPairGenerator getKpg() {
return kpg;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.KeyPairGenerator;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;

Expand Down Expand Up @@ -82,17 +83,29 @@ protected void runTests() throws Exception {
KeyPair kp = kgt.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
} else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve);
} else {
// If KeyPair generation fails, try generating it on named curve instead.
ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
runTest(generateOnNamedCurve);
kp = kgtOnNamedCurve.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
} else {
Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail));
continue;
// If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
} else {
Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail));
continue;
}
}
}
ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.KeyPairGenerator;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;

Expand Down Expand Up @@ -81,17 +82,29 @@ protected void runTests() throws Exception {
KeyPair kp = kgt.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
} else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve);
} else {
// If KeyPair generation fails, try generating it on named curve instead.
ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
runTest(generateOnNamedCurve);
kp = kgtOnNamedCurve.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
} else {
Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail));
continue;
// If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
} else {
Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail));
continue;
}
}
}
ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.KeyPairGenerator;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.util.*;

Expand Down Expand Up @@ -81,17 +82,29 @@ protected void runTests() throws Exception {
KeyPair kp = kgt.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
} else { //If KeyPair generation fails, try generating it on a default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generateOnDefaultCurve);
} else {
// If KeyPair generation fails, try generating it on named curve instead.
ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
runTest(generateOnNamedCurve);
kp = kgtOnNamedCurve.getKeyPair();
if (kp != null) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
} else {
Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail));
continue;
// If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
runTest(generateOnDefaultCurve);
kp = kgtOnDefaultCurve.getKeyPair();
if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
} else {
Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail));
continue;
}
}
}
ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,6 @@ static gcry_mpi_t biginteger_to_mpi(JNIEnv *env, jobject bigint) {
return bytearray_to_mpi(env, byte_array);
}

static jint mpi_to_jint(gcry_mpi_t mpi) {
jint result = 0;
unsigned long nbits = gcry_mpi_get_nbits(mpi);
int max_bits = sizeof(jint) * 8;
for (size_t i = 0; i < nbits && i < max_bits; ++i) {
if (gcry_mpi_test_bit(mpi, nbits - i - 1)) {
result = ((result << 1) | 1);
} else {
result = (result << 1);
}
}
return result;
}

static jobject buff_to_ecpoint(JNIEnv *env, gcry_buffer_t buff) {
jint coord_size = (buff.len - 1) / 2;
jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
Expand All @@ -236,9 +222,10 @@ static jobject buff_to_ecpoint(JNIEnv *env, gcry_buffer_t buff) {

static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
jobject result = NULL;
gcry_mpi_t p, a, b, n, h;
gcry_mpi_t p, a, b, n;
unsigned int h;
gcry_buffer_t g = {0};
gcry_error_t err = gcry_sexp_extract_param(key, "ecc", "pab&g+nh", &p, &a, &b, &g, &n, &h, NULL);
gcry_error_t err = gcry_sexp_extract_param(key, "ecc", "pab&g+n%uh", &p, &a, &b, &g, &n, &h, NULL);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error exporting domain parameters. Error: %ui", gcry_err_code(err));
goto end;
Expand All @@ -261,7 +248,7 @@ static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
jobject gen = buff_to_ecpoint(env, g);

jobject order = mpi_to_biginteger(env, n);
jint cofactor = mpi_to_jint(h);
jint cofactor = (jint) h;

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");
result = (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, gen, order, cofactor);
Expand All @@ -272,7 +259,6 @@ static jobject create_ec_param_spec(JNIEnv *env, gcry_sexp_t key) {
gcry_mpi_release(b);
gcry_free(g.data);
gcry_mpi_release(n);
gcry_mpi_release(h);
return result;
}

Expand Down Expand Up @@ -479,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey
} SIG_CATCH_HANDLE(env);

if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDH. Error: %ui", gcry_err_code(err));
throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDH. Error: %u", gcry_err_code(err));
goto end;
}

Expand Down Expand Up @@ -594,15 +580,15 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
} SIG_CATCH_HANDLE(env);

if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDSA. Error: %ui", gcry_err_code(err));
throw_new_var(env, "java/security/GeneralSecurityException", "Error performing ECDSA. Error: %u", gcry_err_code(err));
goto release_init;
}

gcry_buffer_t r_buf = {0};
gcry_buffer_t s_buf = {0};
err = gcry_sexp_extract_param(res_sexp, "ecdsa", "&rs", &r_buf, &s_buf, NULL);
if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
throw_new_var(env, "java/security/GeneralSecurityException", "Error extracting ECDSA output. Error: %ui", gcry_err_code(err));
throw_new_var(env, "java/security/GeneralSecurityException", "Error extracting ECDSA output. Error: %u", gcry_err_code(err));
goto release_res;
}
result = asn1_der_encode(env, r_buf.data, r_buf.len, s_buf.data, s_buf.len);
Expand Down Expand Up @@ -654,7 +640,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna

if (gcry_err_code(err) != GPG_ERR_NO_ERROR) {
if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) {
throw_new(env, "java/security/GeneralSecurityException", "Error verif sig.");
throw_new_var(env, "java/security/GeneralSecurityException", "Error verif sig. Error: %u", gcry_err_code(err));
goto release_init;
}
} else {
Expand Down

0 comments on commit 57c4f0e

Please sign in to comment.