Skip to content

Commit c639e59

Browse files
committed
Improve testing around nondeterministic ECDSA
1 parent 967fa3b commit c639e59

3 files changed

Lines changed: 74 additions & 10 deletions

File tree

src/main/java/org/eclipse/biscuit/crypto/KeyPair.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,25 @@ public KeyPair generate(SecureRandom rng) {
3535
new Factory() {
3636
@Override
3737
public KeyPair generate(byte[] bytes) throws Error.FormatError.InvalidKeySize {
38-
return new SECP256R1KeyPair(bytes);
38+
return new SECP256R1KeyPair(bytes, true);
3939
}
4040

4141
@Override
4242
public KeyPair generate(SecureRandom rng) {
43-
return new SECP256R1KeyPair(rng);
43+
return new SECP256R1KeyPair(rng, true);
44+
}
45+
};
46+
47+
public static final Factory DEFAULT_NONDETERMINISTIC_SECP256R1_FACTORY =
48+
new Factory() {
49+
@Override
50+
public KeyPair generate(byte[] bytes) throws Error.FormatError.InvalidKeySize {
51+
return new SECP256R1KeyPair(bytes, false);
52+
}
53+
54+
@Override
55+
public KeyPair generate(SecureRandom rng) {
56+
return new SECP256R1KeyPair(rng, false);
4457
}
4558
};
4659

@@ -69,9 +82,9 @@ public static KeyPair generate(Algorithm algorithm, byte[] bytes)
6982

7083
public static KeyPair generate(Algorithm algorithm, SecureRandom rng) {
7184
if (algorithm == Algorithm.Ed25519) {
72-
return ed25519Factory != null ? ed25519Factory.generate(rng) : new Ed25519KeyPair(rng);
85+
return ed25519Factory.generate(rng);
7386
} else if (algorithm == Algorithm.SECP256R1) {
74-
return secp256r1Factory != null ? secp256r1Factory.generate(rng) : new SECP256R1KeyPair(rng);
87+
return secp256r1Factory.generate(rng);
7588
} else {
7689
throw new IllegalArgumentException("Unsupported algorithm");
7790
}

src/main/java/org/eclipse/biscuit/crypto/SECP256R1KeyPair.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@ final class SECP256R1KeyPair extends KeyPair {
3131

3232
private final BCECPrivateKey privateKey;
3333
private final BCECPublicKey publicKey;
34+
private final boolean deterministicNonce;
3435

3536
static final String ALGORITHM = "ECDSA";
3637
static final String CURVE = "secp256r1";
3738
static final ECNamedCurveParameterSpec SECP256R1 = ECNamedCurveTable.getParameterSpec(CURVE);
3839

39-
SECP256R1KeyPair(byte[] bytes) throws Error.FormatError.InvalidKeySize {
40+
SECP256R1KeyPair(byte[] bytes, boolean deterministicNonce)
41+
throws Error.FormatError.InvalidKeySize {
42+
this.deterministicNonce = deterministicNonce;
43+
4044
if (bytes.length != BUFFER_SIZE) {
4145
throw new Error.FormatError.InvalidKeySize(bytes.length);
4246
}
@@ -52,7 +56,9 @@ final class SECP256R1KeyPair extends KeyPair {
5256
this.publicKey = publicKey;
5357
}
5458

55-
SECP256R1KeyPair(SecureRandom rng) {
59+
SECP256R1KeyPair(SecureRandom rng, boolean deterministicNonce) {
60+
this.deterministicNonce = deterministicNonce;
61+
5662
byte[] bytes = new byte[BUFFER_SIZE];
5763
rng.nextBytes(bytes);
5864

@@ -78,10 +84,6 @@ final class SECP256R1KeyPair extends KeyPair {
7884
/// a weak RNG.
7985
@Override
8086
public byte[] sign(byte[] data) {
81-
return sign(data, true);
82-
}
83-
84-
public byte[] sign(byte[] data, boolean deterministicNonce) {
8587
var digest = new SHA256Digest();
8688
digest.update(data, 0, data.length);
8789
var hash = new byte[digest.getDigestSize()];
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2019 Geoffroy Couprie <contact@geoffroycouprie.com> and Contributors to the Eclipse Foundation.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.eclipse.biscuit.token;
7+
8+
import static org.eclipse.biscuit.token.builder.Utils.fact;
9+
import static org.eclipse.biscuit.token.builder.Utils.str;
10+
11+
import biscuit.format.schema.Schema;
12+
import java.security.InvalidKeyException;
13+
import java.security.NoSuchAlgorithmException;
14+
import java.security.SecureRandom;
15+
import java.security.SignatureException;
16+
import java.util.List;
17+
import org.eclipse.biscuit.crypto.KeyPair;
18+
import org.eclipse.biscuit.error.Error;
19+
import org.eclipse.biscuit.token.builder.Block;
20+
import org.junit.jupiter.api.AfterAll;
21+
import org.junit.jupiter.api.BeforeAll;
22+
import org.junit.jupiter.api.Test;
23+
import org.junit.jupiter.api.parallel.Isolated;
24+
25+
/** Top-level test to ensure ECDSA with nondeterministic nonce also works. */
26+
@Isolated
27+
public class NondeterministicEcdsaTest {
28+
@BeforeAll
29+
static void beforeAll() {
30+
KeyPair.setSECP256R1Factory(KeyPair.DEFAULT_NONDETERMINISTIC_SECP256R1_FACTORY);
31+
}
32+
33+
@AfterAll
34+
static void afterAll() {
35+
KeyPair.setSECP256R1Factory(KeyPair.DEFAULT_SECP256R1_FACTORY);
36+
}
37+
38+
@Test
39+
public void simpleSigningTest()
40+
throws Error, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
41+
var root = KeyPair.generate(Schema.PublicKey.Algorithm.SECP256R1);
42+
var b =
43+
Biscuit.make(
44+
new SecureRandom(),
45+
root,
46+
new Block().addFact(fact("foo", List.of(str("bar")))).build());
47+
Biscuit.fromBytes(b.serialize(), root.getPublicKey());
48+
}
49+
}

0 commit comments

Comments
 (0)