Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better unit testing for Signatures #53

Merged
merged 2 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 166 additions & 46 deletions src/test/java/SignatureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.junit.Test;
import org.junit.BeforeClass;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

public class SignatureTest {
static {
Expand All @@ -54,41 +55,174 @@ public class SignatureTest {
+ "Etruscan mythology as Apulu.";

@Test
public void testRSA() throws Exception {
public void testRSABasic() throws Exception {
RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.generateKeyPair();
testSignature("RSA", gen.pubKey, gen.privKey);
}

public void testED25519() throws Exception {
EdDSAPublicKey publicKey = new EdDSAPublicKey("src/test/keys/ed25519-pub.pem");
EdDSAPrivateKey privateKey = new EdDSAPrivateKey("src/test/keys/ed25519-priv.pem");
testSignature("ED25519", publicKey, privateKey);
PublicKey publicKey = gen.pubKey;
PrivateKey privateKey = gen.privKey;

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256"); // TODO: why does this work only with SHA-256?
signer.initSign(privateKey);
byte[] bytes = message.getBytes();
signer.update(bytes, 0, bytes.length);
byte[] sigBytes = signer.sign();

Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);

assertTrue("SignatureTest for RSA failed.", verifier.verify(sigBytes));
}

public void testED448() throws Exception {
EdDSAPublicKey publicKey = new EdDSAPublicKey("src/test/keys/ed448-pub.pem");
EdDSAPrivateKey privateKey = new EdDSAPrivateKey("src/test/keys/ed448-priv.pem");
testSignature("ED448", publicKey, privateKey);
@Test
public void testRSAwithMultipleUpdates() throws Exception {
PublicKey publicKey = new RSAPublicKey("src/test/keys/rsa16384-pub.pem");
PrivateKey privateKey = new RSAPrivateKey("src/test/keys/rsa16384-priv.pem");

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();
signer.update(bytes, 0, bytes.length);
signer.update(bytes, 2, bytes.length-2);
signer.update(bytes, 3, bytes.length-3);
byte[] sigBytes = signer.sign();

Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);
verifier.update(bytes, 2, bytes.length-2);
verifier.update(bytes, 3, bytes.length-3);

assertTrue("SignatureTest with multiple updates for RSA failed.", verifier.verify(sigBytes));
}

private static void testSignature(String algo, PublicKey publicKey, PrivateKey privateKey) throws Exception {
Signature signer = Signature.getInstance(algo, "OpenSSLFIPSProvider");
if (algo.equals("RSA")) {
signer.setParameter("digest", "SHA-256"); // TODO: why does this work only with SHA-256?
@Test
public void testRSAsingleByteUpdates() throws Exception {
RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.generateKeyPair();

PublicKey publicKey = gen.pubKey;
PrivateKey privateKey = gen.privKey;

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();

for (var b : bytes) {
signer.update(b);
}
byte[] sigBytes = signer.sign();

Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);

assertTrue("RSA SignatureTest with byte updates failed.", verifier.verify(sigBytes));
}

@Test
public void testRSAmultipleByteBufferUpdates() throws Exception {
PublicKey publicKey = new RSAPublicKey("src/test/keys/rsa8192-pub.pem");
PrivateKey privateKey = new RSAPrivateKey("src/test/keys/rsa8192-priv.pem");

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();
signer.update(bytes, 0, bytes.length);
signer.update(ByteBuffer.wrap(message.getBytes()));
byte[] sigBytes = signer.sign();

Signature verifier = Signature.getInstance(algo, "OpenSSLFIPSProvider");
if (algo.equals("RSA")) {
verifier.setParameter("digest", "SHA-256");
Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);

assertTrue("RSA SignatureTest with ByteBuffer updates failed.", verifier.verify(sigBytes));
}

@Test
public void testRSAsignNonzeroOffset() throws Exception {
PublicKey publicKey = new RSAPublicKey("src/test/keys/rsa4096-pub.pem");
PrivateKey privateKey = new RSAPrivateKey("src/test/keys/rsa4096-priv.pem");

byte[] sigBytes = new byte[612];
Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();
signer.update(ByteBuffer.wrap(message.getBytes()));
signer.sign(sigBytes, 100, 512);

Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);

assertTrue("RSA SignatureTest with non-zero offset failed.", verifier.verify(sigBytes, 100, 512));
}

@Test
public void testRSAtamperedSignature() throws Exception {
RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.generateKeyPair();

PublicKey publicKey = gen.pubKey;
PrivateKey privateKey = gen.privKey;

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();

for (var b : bytes) {
signer.update(b);
}
byte[] sigBytes = signer.sign();

Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);
assertTrue("SignatureTest for " + algo + " failed.", verifier.verify(sigBytes));

// tamper signature
sigBytes[0] += 1;

assertFalse("RSA SignatureTest with tampered signature failed.", verifier.verify(sigBytes));
}

@Test
public void testRSAtamperedContent() throws Exception {
RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.generateKeyPair();

PublicKey publicKey = gen.pubKey;
PrivateKey privateKey = gen.privKey;

Signature signer = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
signer.setParameter("digest", "SHA-256");
signer.initSign(privateKey);
byte[] bytes = message.getBytes();

for (var b : bytes) {
signer.update(b);
}
byte[] sigBytes = signer.sign();

// tamper content
bytes[0] += 1;
Signature verifier = Signature.getInstance("RSA", "OpenSSLFIPSProvider");
verifier.setParameter("digest", "SHA-256");
verifier.initVerify(publicKey);
verifier.update(bytes, 0, bytes.length);

assertFalse("RSA SignatureTest with tampered content failed.", verifier.verify(sigBytes));
}

@BeforeClass
Expand All @@ -110,32 +244,6 @@ public String getAlgorithm() {
return "";
}
}

class EdDSAPublicKey extends TestKey implements OpenSSLPublicKey {
long nativeKey = 0L;
public long getNativeKeyHandle() {
return nativeKey;
}

EdDSAPublicKey(String filename) {
nativeKey = readPubKeyFromPem0(filename);
}

native long readPubKeyFromPem0(String filename);
}

class EdDSAPrivateKey extends TestKey implements OpenSSLPrivateKey {
long nativeKey = 0L;
public long getNativeKeyHandle() {
return nativeKey;
}

EdDSAPrivateKey(String filename) {
nativeKey = readPrivKeyFromPem0(filename);
}

native long readPrivKeyFromPem0(String filename);
}

class RSAPublicKey extends TestKey implements OpenSSLPublicKey {
long nativeKey = 0L;
Expand All @@ -144,9 +252,15 @@ public RSAPublicKey(long nativeKey) {
this.nativeKey = nativeKey;
}

public RSAPublicKey(String filename) {
this.nativeKey = readPubKeyFromPem0(filename);
}

public long getNativeKeyHandle() {
return nativeKey;
}

native long readPubKeyFromPem0(String filename);
}

class RSAPrivateKey extends TestKey implements OpenSSLPrivateKey {
Expand All @@ -156,9 +270,15 @@ public RSAPrivateKey(long nativeKey) {
this.nativeKey = nativeKey;
}

public RSAPrivateKey(String filename) {
this.nativeKey = readPrivKeyFromPem0(filename);
}

public long getNativeKeyHandle() {
return nativeKey;
}

native long readPrivKeyFromPem0(String filename);
}

class RSAKeyPairGenerator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
#include <stdlib.h>

/*
* Class: EdDSAPrivateKey
* Class: RSAPrivateKey
* Method: readPrivKeyFromPem0
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_EdDSAPrivateKey_readPrivKeyFromPem0
JNIEXPORT jlong JNICALL Java_RSAPrivateKey_readPrivKeyFromPem0
(JNIEnv *env, jobject this, jstring filename) {
OSSL_LIB_CTX *libctx = load_openssl_fips_provider("/usr/local/ssl/openssl.cnf");
char *c_filename = (char*)(*env)->GetStringUTFChars(env, filename, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
*/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class EdDSAPrivateKey */
/* Header for class RSAPrivateKey */

#ifndef _Included_EdDSAPrivateKey
#define _Included_EdDSAPrivateKey
#ifndef _Included_RSAPrivateKey
#define _Included_RSAPrivateKey
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: EdDSAPrivateKey
* Class: RSAPrivateKey
* Method: readPrivKeyFromPem0
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_EdDSAPrivateKey_readPrivKeyFromPem0
JNIEXPORT jlong JNICALL Java_RSAPrivateKey_readPrivKeyFromPem0
(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
#include <stdlib.h>

/*
* Class: EdDSAPublicKey
* Class: RSAPublicKey
* Method: readPubKeyFromPem0
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_EdDSAPublicKey_readPubKeyFromPem0
JNIEXPORT jlong JNICALL Java_RSAPublicKey_readPubKeyFromPem0
(JNIEnv *env, jobject this, jstring filename) {
OSSL_LIB_CTX *libctx = load_openssl_fips_provider("/usr/local/ssl/openssl.cnf");
char *c_filename = (char*)(*env)->GetStringUTFChars(env, filename, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
*/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class EdDSAPublicKey */
/* Header for class RSAPublicKey */

#ifndef _Included_EdDSAPublicKey
#define _Included_EdDSAPublicKey
#ifndef _Included_RSAPublicKey
#define _Included_RSAPublicKey
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: EdDSAPublicKey
* Class: RSAPublicKey
* Method: readPubKeyFromPem0
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_EdDSAPublicKey_readPubKeyFromPem0
JNIEXPORT jlong JNICALL Java_RSAPublicKey_readPubKeyFromPem0
(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
Expand Down
3 changes: 0 additions & 3 deletions src/test/keys/ed25519-priv.pem

This file was deleted.

3 changes: 0 additions & 3 deletions src/test/keys/ed25519-pub.pem

This file was deleted.

4 changes: 0 additions & 4 deletions src/test/keys/ed448-priv.pem

This file was deleted.

4 changes: 0 additions & 4 deletions src/test/keys/ed448-pub.pem

This file was deleted.

Loading
Loading