From a0ad6dab7da01aaad12d2b68d2bf91670d961c53 Mon Sep 17 00:00:00 2001 From: sp717 Date: Tue, 13 Aug 2024 13:55:50 -0700 Subject: [PATCH] Update error handling, cpp includes, kpg initialize, and unit tests --- csrc/ed_gen.cpp | 3 ++ csrc/sign.cpp | 3 +- .../corretto/crypto/provider/EdGen.java | 7 ++- .../crypto/provider/test/EdDSATest.java | 49 ++++++++++++------- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/csrc/ed_gen.cpp b/csrc/ed_gen.cpp index f50ac382..ef7f10ec 100644 --- a/csrc/ed_gen.cpp +++ b/csrc/ed_gen.cpp @@ -1,6 +1,9 @@ // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +#include #include "auto_free.h" +#include "env.h" +#include "generated-headers.h" using namespace AmazonCorrettoCryptoProvider; diff --git a/csrc/sign.cpp b/csrc/sign.cpp index 8be32193..bb456151 100644 --- a/csrc/sign.cpp +++ b/csrc/sign.cpp @@ -541,7 +541,8 @@ JNIEXPORT jboolean JNICALL Java_com_amazon_corretto_crypto_provider_EvpSignature // Mismatched signatures are not an error case, so return false // instead of throwing per JCA convention. if (ECDSA_R_MISMATCHED_SIGNATURE == (errorCode & ECDSA_R_MISMATCHED_SIGNATURE) - || RSA_R_MISMATCHED_SIGNATURE == (errorCode & RSA_R_MISMATCHED_SIGNATURE)) { + || RSA_R_MISMATCHED_SIGNATURE == (errorCode & RSA_R_MISMATCHED_SIGNATURE) + || EVP_R_INVALID_SIGNATURE == (errorCode & EVP_R_INVALID_SIGNATURE)) { return false; } diff --git a/src/com/amazon/corretto/crypto/provider/EdGen.java b/src/com/amazon/corretto/crypto/provider/EdGen.java index d092b0ac..ba84c99e 100644 --- a/src/com/amazon/corretto/crypto/provider/EdGen.java +++ b/src/com/amazon/corretto/crypto/provider/EdGen.java @@ -5,6 +5,7 @@ import java.security.KeyPair; import java.security.KeyPairGeneratorSpi; import java.security.SecureRandom; +import java.security.InvalidParameterException; class EdGen extends KeyPairGeneratorSpi { /** Generates a new Ed25519 key and returns a pointer to it. */ @@ -18,8 +19,10 @@ class EdGen extends KeyPairGeneratorSpi { } public void initialize(int keysize, SecureRandom random) { - // Has some behavior in Java, but throws error as placeholder for now. - throw new UnsupportedOperationException(); + if (keysize != 255) { + throw new InvalidParameterException("Params must be Ed25519."); + } + return; } @Override diff --git a/tst/com/amazon/corretto/crypto/provider/test/EdDSATest.java b/tst/com/amazon/corretto/crypto/provider/test/EdDSATest.java index 02bd0a8a..2eeaf330 100644 --- a/tst/com/amazon/corretto/crypto/provider/test/EdDSATest.java +++ b/tst/com/amazon/corretto/crypto/provider/test/EdDSATest.java @@ -134,18 +134,20 @@ public void jceInteropValidation() throws GeneralSecurityException { final byte[] message = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; nativeSig.initSign(keyPair.getPrivate()); nativeSig.update(message, 0, message.length); - byte[] signature = nativeSig.sign(); + final byte[] signatureACCP = nativeSig.sign(); jceSig.initVerify(publicKey); jceSig.update(message); - assertTrue(jceSig.verify(signature), "Native->JCE: Ed25519"); + assertTrue(jceSig.verify(signatureACCP), "Native->JCE: Ed25519"); // Sign with SunEC and verify with ACCP jceSig.initSign(privateKey); jceSig.update(message, 0, message.length); - signature = jceSig.sign(); + final byte[] signatureJCE = jceSig.sign(); nativeSig.initVerify(keyPair.getPublic()); nativeSig.update(message); - assertTrue(nativeSig.verify(signature), "JCE->Native: Ed25519"); + assertTrue(nativeSig.verify(signatureJCE), "JCE->Native: Ed25519"); + + assertTrue(Arrays.equals(signatureJCE, signatureACCP)); } @Test @@ -169,17 +171,20 @@ public void bcInteropValidation() throws GeneralSecurityException { // Sign with ACCP, Verify with BouncyCastle nativeSig.initSign(keyPair.getPrivate()); nativeSig.update(message, 0, message.length); - byte[] signature = nativeSig.sign(); + final byte[] signatureACCP = nativeSig.sign(); bcSig.initVerify(publicKey); bcSig.update(message); - assertTrue(bcSig.verify(signature), "Native->BC: Ed25519"); + assertTrue(bcSig.verify(signatureACCP), "Native->BC: Ed25519"); + // Sign with BouncyCastle, Verify with ACCP bcSig.initSign(privateKey); bcSig.update(message, 0, message.length); - signature = bcSig.sign(); + final byte[] signatureBC = bcSig.sign(); nativeSig.initVerify(keyPair.getPublic()); nativeSig.update(message); - assertTrue(nativeSig.verify(signature), "BC->Native: Ed25519"); + assertTrue(nativeSig.verify(signatureBC), "BC->Native: Ed25519"); + + assertTrue(Arrays.equals(signatureBC, signatureACCP)); } @Test @@ -224,15 +229,25 @@ public void mismatchSignature() throws GeneralSecurityException { final byte[] message2 = new byte[] {5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; final KeyPair kp = nativeGen.generateKeyPair(); - final Signature eddsa = Signature.getInstance("Ed25519", NATIVE_PROVIDER); - eddsa.initSign(kp.getPrivate()); - eddsa.update(message1, 0, message1.length); - final byte[] signature = eddsa.sign(); + final X509EncodedKeySpec publicKeyX509 = new X509EncodedKeySpec(kp.getPublic().getEncoded()); + final KeyFactory kf = KeyFactory.getInstance("Ed25519", BOUNCYCASTLE_PROVIDER); + final PublicKey pbkJCE = kf.generatePublic(publicKeyX509); + + final Signature nativeSig = Signature.getInstance("Ed25519", NATIVE_PROVIDER); + final Signature jceSig = Signature.getInstance("Ed25519", "SunEC"); + + nativeSig.initSign(kp.getPrivate()); + nativeSig.update(message1, 0, message1.length); + final byte[] signature = nativeSig.sign(); + + nativeSig.initVerify(kp.getPublic()); + nativeSig.update(message2, 0, message2.length); + assertTrue(!nativeSig.verify(signature)); - eddsa.initVerify(kp.getPublic()); - eddsa.update(message2, 0, message2.length); - TestUtil.assertThrows(SignatureException.class, () -> eddsa.verify(signature)); + jceSig.initVerify(pbkJCE); + jceSig.update(message2, 0, message2.length); + assertTrue(!jceSig.verify(signature)); } @Test @@ -244,9 +259,9 @@ public void testInvalidKey() throws GeneralSecurityException { final KeyFactory kf = KeyFactory.getInstance("Ed25519", NATIVE_PROVIDER); TestUtil.assertThrows( - InvalidKeySpecException.class, () -> kf.generatePrivate(invalidPrivateKeySpec)); + InvalidKeySpecException.class, () -> kf.generatePrivate(invalidPrivateKeySpec)); TestUtil.assertThrows( - InvalidKeySpecException.class, () -> kf.generatePublic(invalidPublicKeySpec)); + InvalidKeySpecException.class, () -> kf.generatePublic(invalidPublicKeySpec)); } @Test