Skip to content

Commit e22f3d3

Browse files
committed
Remove ed-25519-java
* Remove ed-25519-java because of the security issue * Split the public keys representation to avoid the use of the SecurityProvide and heavy exception
1 parent 8923fb1 commit e22f3d3

27 files changed

+313
-260
lines changed

Diff for: pom.xml

+5-10
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@
3535
<vavr.version>0.10.3</vavr.version>
3636
<re2j.version>1.6</re2j.version>
3737
<gson.version>2.8.9</gson.version>
38-
<bcprov.version>1.79</bcprov.version>
38+
<bcprov.version>1.80</bcprov.version>
3939

4040
<!-- test dependencies -->
4141
<junit.version>5.8.2</junit.version>
4242
<awssdk-kms.version>2.30.2</awssdk-kms.version>
43-
<testcontainers-junit-jupiter.version>1.20.4</testcontainers-junit-jupiter.version>
44-
<testcontainers-localstack.version>1.20.4</testcontainers-localstack.version>
43+
<testcontainers-junit-jupiter.version>1.20.6</testcontainers-junit-jupiter.version>
44+
<testcontainers-localstack.version>1.20.6</testcontainers-localstack.version>
4545
</properties>
4646

4747
<licenses>
@@ -221,7 +221,7 @@
221221
<artifactId>maven-failsafe-plugin</artifactId>
222222
<version>2.22.2</version>
223223
</plugin>
224-
<plugin>
224+
<plugin>
225225
<artifactId>maven-surefire-plugin</artifactId>
226226
<version>3.2.5</version>
227227
<dependencies>
@@ -237,7 +237,7 @@
237237
<disable>true</disable>
238238
</consoleOutputReporter>
239239
<statelessTestsetInfoReporter
240-
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
240+
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
241241
<printStacktraceOnError>true</printStacktraceOnError>
242242
<printStacktraceOnFailure>true</printStacktraceOnFailure>
243243
<printStdoutOnError>true</printStdoutOnError>
@@ -281,11 +281,6 @@
281281
<artifactId>protobuf-java</artifactId>
282282
<version>${protobuf.version}</version>
283283
</dependency>
284-
<dependency>
285-
<groupId>net.i2p.crypto</groupId>
286-
<artifactId>eddsa</artifactId>
287-
<version>${net.i2p.crypto.eddsa.version}</version>
288-
</dependency>
289284
<dependency>
290285
<groupId>io.vavr</groupId>
291286
<artifactId>vavr</artifactId>
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,52 @@
11
package org.biscuitsec.biscuit.crypto;
22

3-
import biscuit.format.schema.Schema;
4-
import java.security.InvalidKeyException;
5-
import java.security.MessageDigest;
6-
import java.security.NoSuchAlgorithmException;
73
import java.security.SecureRandom;
8-
import java.security.Signature;
9-
import java.security.SignatureException;
10-
import net.i2p.crypto.eddsa.EdDSAEngine;
11-
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
12-
import net.i2p.crypto.eddsa.EdDSAPublicKey;
13-
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
14-
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
15-
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
16-
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
174
import org.biscuitsec.biscuit.token.builder.Utils;
5+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
6+
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
7+
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
8+
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
9+
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
10+
import org.bouncycastle.crypto.signers.Ed25519Signer;
1811

1912
final class Ed25519KeyPair extends KeyPair {
20-
private static final int BUFFER_SIZE = 32;
21-
2213
public static final int SIGNATURE_LENGTH = 64;
2314

24-
private final EdDSAPrivateKey privateKey;
25-
private final EdDSAPublicKey publicKey;
26-
27-
private static final EdDSANamedCurveSpec ED_25519 =
28-
EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
15+
private final Ed25519PrivateKeyParameters privateKey;
16+
private final Ed25519PublicKeyParameters publicKey;
2917

3018
Ed25519KeyPair(byte[] bytes) {
31-
EdDSAPrivateKeySpec privKeySpec = new EdDSAPrivateKeySpec(bytes, ED_25519);
32-
EdDSAPrivateKey privKey = new EdDSAPrivateKey(privKeySpec);
33-
34-
EdDSAPublicKeySpec pubKeySpec = new EdDSAPublicKeySpec(privKey.getA(), ED_25519);
35-
EdDSAPublicKey pubKey = new EdDSAPublicKey(pubKeySpec);
19+
Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(bytes);
20+
Ed25519PublicKeyParameters publicKey = privateKey.generatePublicKey();
3621

37-
this.privateKey = privKey;
38-
this.publicKey = pubKey;
22+
this.privateKey = privateKey;
23+
this.publicKey = publicKey;
3924
}
4025

4126
Ed25519KeyPair(SecureRandom rng) {
42-
byte[] b = new byte[BUFFER_SIZE];
43-
rng.nextBytes(b);
4427

45-
EdDSAPrivateKeySpec privKeySpec = new EdDSAPrivateKeySpec(b, ED_25519);
46-
EdDSAPrivateKey privKey = new EdDSAPrivateKey(privKeySpec);
28+
Ed25519KeyPairGenerator kpg = new Ed25519KeyPairGenerator();
29+
kpg.init(new Ed25519KeyGenerationParameters(rng));
4730

48-
EdDSAPublicKeySpec pubKeySpec = new EdDSAPublicKeySpec(privKey.getA(), ED_25519);
49-
EdDSAPublicKey pubKey = new EdDSAPublicKey(pubKeySpec);
50-
51-
this.privateKey = privKey;
52-
this.publicKey = pubKey;
53-
}
54-
55-
Ed25519KeyPair(String hex) {
56-
this(Utils.hexStringToByteArray(hex));
57-
}
58-
59-
public static java.security.PublicKey decode(byte[] data) {
60-
return new EdDSAPublicKey(new EdDSAPublicKeySpec(data, ED_25519));
61-
}
31+
AsymmetricCipherKeyPair kp = kpg.generateKeyPair();
32+
Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) kp.getPrivate();
33+
Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) kp.getPublic();
6234

63-
public static Signature getSignature() throws NoSuchAlgorithmException {
64-
return new EdDSAEngine(MessageDigest.getInstance(ED_25519.getHashAlgorithm()));
35+
this.privateKey = privateKey;
36+
this.publicKey = publicKey;
6537
}
6638

6739
@Override
68-
public byte[] sign(byte[] data)
69-
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
70-
Signature sgr = KeyPair.generateSignature(Schema.PublicKey.Algorithm.Ed25519);
71-
sgr.initSign(privateKey);
72-
sgr.update(data);
73-
return sgr.sign();
40+
public byte[] sign(byte[] data) {
41+
var sgr = new Ed25519Signer();
42+
sgr.init(true, this.privateKey);
43+
sgr.update(data, 0, data.length);
44+
return sgr.generateSignature();
7445
}
7546

7647
@Override
7748
public byte[] toBytes() {
78-
return privateKey.getSeed();
49+
return privateKey.getEncoded();
7950
}
8051

8152
@Override
@@ -85,6 +56,6 @@ public String toHex() {
8556

8657
@Override
8758
public PublicKey getPublicKey() {
88-
return new PublicKey(Schema.PublicKey.Algorithm.Ed25519, this.publicKey);
59+
return new Ed25519PublicKey(this.publicKey);
8960
}
9061
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.biscuitsec.biscuit.crypto;
2+
3+
import biscuit.format.schema.Schema.PublicKey.Algorithm;
4+
import java.util.Arrays;
5+
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
6+
import org.bouncycastle.crypto.signers.Ed25519Signer;
7+
8+
class Ed25519PublicKey extends PublicKey {
9+
private final Ed25519PublicKeyParameters publicKey;
10+
11+
Ed25519PublicKey(final Ed25519PublicKeyParameters publicKey) {
12+
super();
13+
this.publicKey = publicKey;
14+
}
15+
16+
static Ed25519PublicKey loadEd25519(byte[] data) {
17+
return new Ed25519PublicKey(new Ed25519PublicKeyParameters(data));
18+
}
19+
20+
@Override
21+
public byte[] toBytes() {
22+
return this.publicKey.getEncoded();
23+
}
24+
25+
@Override
26+
public boolean equals(Object o) {
27+
if (this == o) {
28+
return true;
29+
}
30+
if (o == null || getClass() != o.getClass()) {
31+
return false;
32+
}
33+
34+
Ed25519PublicKey publicKey = (Ed25519PublicKey) o;
35+
36+
return Arrays.equals(this.toBytes(), publicKey.toBytes());
37+
}
38+
39+
@Override
40+
public int hashCode() {
41+
return this.publicKey.hashCode();
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "ed25519/" + toHex().toLowerCase();
47+
}
48+
49+
public Algorithm getAlgorithm() {
50+
return Algorithm.Ed25519;
51+
}
52+
53+
@Override
54+
public boolean verify(byte[] data, byte[] signature) {
55+
var sgr = new Ed25519Signer();
56+
sgr.init(false, this.publicKey);
57+
sgr.update(data, 0, data.length);
58+
return sgr.verifySignature(signature);
59+
}
60+
}

Diff for: src/main/java/org/biscuitsec/biscuit/crypto/KeyPair.java

+2-24
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package org.biscuitsec.biscuit.crypto;
22

33
import biscuit.format.schema.Schema.PublicKey.Algorithm;
4-
import java.security.InvalidKeyException;
5-
import java.security.NoSuchAlgorithmException;
64
import java.security.SecureRandom;
7-
import java.security.Signature;
8-
import java.security.SignatureException;
9-
import net.i2p.crypto.eddsa.Utils;
5+
import org.biscuitsec.biscuit.token.builder.Utils;
106

117
/** Private and public key. */
128
public abstract class KeyPair implements Signer {
@@ -16,7 +12,7 @@ public static KeyPair generate(Algorithm algorithm) {
1612
}
1713

1814
public static KeyPair generate(Algorithm algorithm, String hex) {
19-
return generate(algorithm, Utils.hexToBytes(hex));
15+
return generate(algorithm, Utils.hexStringToByteArray(hex));
2016
}
2117

2218
public static KeyPair generate(Algorithm algorithm, byte[] bytes) {
@@ -39,24 +35,6 @@ public static KeyPair generate(Algorithm algorithm, SecureRandom rng) {
3935
}
4036
}
4137

42-
public static Signature generateSignature(Algorithm algorithm) throws NoSuchAlgorithmException {
43-
if (algorithm == Algorithm.Ed25519) {
44-
return Ed25519KeyPair.getSignature();
45-
} else if (algorithm == Algorithm.SECP256R1) {
46-
return SECP256R1KeyPair.getSignature();
47-
} else {
48-
throw new NoSuchAlgorithmException("Unsupported algorithm");
49-
}
50-
}
51-
52-
public static boolean verify(PublicKey publicKey, byte[] data, byte[] signature)
53-
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
54-
Signature sgr = KeyPair.generateSignature(publicKey.getAlgorithm());
55-
sgr.initVerify(publicKey.getKey());
56-
sgr.update(data);
57-
return sgr.verify(signature);
58-
}
59-
6038
public abstract byte[] toBytes();
6139

6240
public abstract String toHex();

0 commit comments

Comments
 (0)