diff --git a/pom.xml b/pom.xml index 5dec3d76..745a0722 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,6 @@ 3.25.5 0.6.1 1.7.1 - 0.3.0 0.10.3 1.6 2.8.9 diff --git a/src/main/java/org/eclipse/biscuit/crypto/Ed25519KeyPair.java b/src/main/java/org/eclipse/biscuit/crypto/Ed25519KeyPair.java index 781694f4..0cc0bf7e 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/Ed25519KeyPair.java +++ b/src/main/java/org/eclipse/biscuit/crypto/Ed25519KeyPair.java @@ -12,6 +12,8 @@ import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.signers.Ed25519Signer; +import org.bouncycastle.math.ec.rfc8032.Ed25519; +import org.eclipse.biscuit.error.Error; import org.eclipse.biscuit.token.builder.Utils; final class Ed25519KeyPair extends KeyPair { @@ -20,7 +22,11 @@ final class Ed25519KeyPair extends KeyPair { private final Ed25519PrivateKeyParameters privateKey; private final Ed25519PublicKeyParameters publicKey; - Ed25519KeyPair(byte[] bytes) { + Ed25519KeyPair(byte[] bytes) throws Error.FormatError.InvalidKeySize { + if (bytes.length != Ed25519.SECRET_KEY_SIZE) { + throw new Error.FormatError.InvalidKeySize(bytes.length); + } + Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(bytes); Ed25519PublicKeyParameters publicKey = privateKey.generatePublicKey(); diff --git a/src/main/java/org/eclipse/biscuit/crypto/Ed25519PublicKey.java b/src/main/java/org/eclipse/biscuit/crypto/Ed25519PublicKey.java index 39e77176..5408b8b0 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/Ed25519PublicKey.java +++ b/src/main/java/org/eclipse/biscuit/crypto/Ed25519PublicKey.java @@ -9,6 +9,7 @@ import java.util.Arrays; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.signers.Ed25519Signer; +import org.eclipse.biscuit.error.Error; class Ed25519PublicKey extends PublicKey { private final Ed25519PublicKeyParameters publicKey; @@ -18,8 +19,14 @@ class Ed25519PublicKey extends PublicKey { this.publicKey = publicKey; } - static Ed25519PublicKey loadEd25519(byte[] data) { - return new Ed25519PublicKey(new Ed25519PublicKeyParameters(data)); + static Ed25519PublicKey loadEd25519(byte[] data) throws Error.FormatError.InvalidKey { + Ed25519PublicKeyParameters params; + try { + params = new Ed25519PublicKeyParameters(data); + } catch (IllegalArgumentException e) { + throw new Error.FormatError.InvalidKey(e.getMessage()); + } + return new Ed25519PublicKey(params); } @Override diff --git a/src/main/java/org/eclipse/biscuit/crypto/KeyPair.java b/src/main/java/org/eclipse/biscuit/crypto/KeyPair.java index f60b2512..cfb23c80 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/KeyPair.java +++ b/src/main/java/org/eclipse/biscuit/crypto/KeyPair.java @@ -7,24 +7,61 @@ import biscuit.format.schema.Schema.PublicKey.Algorithm; import java.security.SecureRandom; +import org.eclipse.biscuit.error.Error; import org.eclipse.biscuit.token.builder.Utils; /** Private and public key. */ public abstract class KeyPair implements Signer { + public interface Factory { + KeyPair generate(byte[] bytes) throws Error.FormatError.InvalidKeySize; + + KeyPair generate(SecureRandom rng); + } + + public static final Factory DEFAULT_ED25519_FACTORY = + new Factory() { + @Override + public KeyPair generate(byte[] bytes) throws Error.FormatError.InvalidKeySize { + return new Ed25519KeyPair(bytes); + } + + @Override + public KeyPair generate(SecureRandom rng) { + return new Ed25519KeyPair(rng); + } + }; + + public static final Factory DEFAULT_SECP256R1_FACTORY = + new Factory() { + @Override + public KeyPair generate(byte[] bytes) throws Error.FormatError.InvalidKeySize { + return new SECP256R1KeyPair(bytes); + } + + @Override + public KeyPair generate(SecureRandom rng) { + return new SECP256R1KeyPair(rng); + } + }; + + private static volatile Factory ed25519Factory = DEFAULT_ED25519_FACTORY; + private static volatile Factory secp256r1Factory = DEFAULT_SECP256R1_FACTORY; public static KeyPair generate(Algorithm algorithm) { return generate(algorithm, new SecureRandom()); } - public static KeyPair generate(Algorithm algorithm, String hex) { + public static KeyPair generate(Algorithm algorithm, String hex) + throws Error.FormatError.InvalidKeySize { return generate(algorithm, Utils.hexStringToByteArray(hex)); } - public static KeyPair generate(Algorithm algorithm, byte[] bytes) { + public static KeyPair generate(Algorithm algorithm, byte[] bytes) + throws Error.FormatError.InvalidKeySize { if (algorithm == Algorithm.Ed25519) { - return new Ed25519KeyPair(bytes); + return ed25519Factory.generate(bytes); } else if (algorithm == Algorithm.SECP256R1) { - return new SECP256R1KeyPair(bytes); + return secp256r1Factory.generate(bytes); } else { throw new IllegalArgumentException("Unsupported algorithm"); } @@ -32,14 +69,22 @@ public static KeyPair generate(Algorithm algorithm, byte[] bytes) { public static KeyPair generate(Algorithm algorithm, SecureRandom rng) { if (algorithm == Algorithm.Ed25519) { - return new Ed25519KeyPair(rng); + return ed25519Factory != null ? ed25519Factory.generate(rng) : new Ed25519KeyPair(rng); } else if (algorithm == Algorithm.SECP256R1) { - return new SECP256R1KeyPair(rng); + return secp256r1Factory != null ? secp256r1Factory.generate(rng) : new SECP256R1KeyPair(rng); } else { throw new IllegalArgumentException("Unsupported algorithm"); } } + public static void setEd25519Factory(Factory factory) { + ed25519Factory = factory; + } + + public static void setSECP256R1Factory(Factory factory) { + secp256r1Factory = factory; + } + public abstract byte[] toBytes(); public abstract String toHex(); diff --git a/src/main/java/org/eclipse/biscuit/crypto/PublicKey.java b/src/main/java/org/eclipse/biscuit/crypto/PublicKey.java index e55e25e5..b10aac41 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/PublicKey.java +++ b/src/main/java/org/eclipse/biscuit/crypto/PublicKey.java @@ -17,21 +17,32 @@ import org.eclipse.biscuit.token.builder.Utils; public abstract class PublicKey { + public interface Factory { + PublicKey load(byte[] bytes) throws Error.FormatError.InvalidKey; + } + + public static final Factory DEFAULT_ED25519_FACTORY = + bytes -> Ed25519PublicKey.loadEd25519(bytes); + public static final Factory DEFAULT_SECP256R1_FACTORY = + bytes -> SECP256R1PublicKey.loadSECP256R1(bytes); + + private static volatile Factory ed25519Factory = DEFAULT_ED25519_FACTORY; + private static volatile Factory secp256r1Factory = DEFAULT_SECP256R1_FACTORY; private static final Set SUPPORTED_ALGORITHMS = Set.of(Algorithm.Ed25519, Algorithm.SECP256R1); - public static PublicKey load(Algorithm algorithm, byte[] data) { + public static PublicKey load(Algorithm algorithm, byte[] data) throws Error.FormatError { if (algorithm == Algorithm.Ed25519) { - return Ed25519PublicKey.loadEd25519(data); + return ed25519Factory.load(data); } else if (algorithm == Algorithm.SECP256R1) { - return SECP256R1PublicKey.loadSECP256R1(data); + return secp256r1Factory.load(data); } else { throw new IllegalArgumentException("Unsupported algorithm"); } } - public static PublicKey load(Algorithm algorithm, String hex) { + public static PublicKey load(Algorithm algorithm, String hex) throws Error.FormatError { return load(algorithm, Utils.hexStringToByteArray(hex)); } @@ -48,8 +59,7 @@ public Schema.PublicKey serialize() { return publicKey.build(); } - public static PublicKey deserialize(Schema.PublicKey pk) - throws Error.FormatError.DeserializationError { + public static PublicKey deserialize(Schema.PublicKey pk) throws Error.FormatError { if (!pk.hasAlgorithm() || !pk.hasKey() || !SUPPORTED_ALGORITHMS.contains(pk.getAlgorithm())) { throw new Error.FormatError.DeserializationError("Invalid public key"); } @@ -74,6 +84,14 @@ public static Optional validateSignatureLength(Algorithm algorithm, int l return error; } + public static void setEd25519Factory(Factory factory) { + ed25519Factory = factory; + } + + public static void setSECP256R1Factory(Factory factory) { + secp256r1Factory = factory; + } + public abstract Algorithm getAlgorithm(); public abstract boolean verify(byte[] data, byte[] signature) diff --git a/src/main/java/org/eclipse/biscuit/crypto/SECP256R1KeyPair.java b/src/main/java/org/eclipse/biscuit/crypto/SECP256R1KeyPair.java index 8c032c32..f8821320 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/SECP256R1KeyPair.java +++ b/src/main/java/org/eclipse/biscuit/crypto/SECP256R1KeyPair.java @@ -5,12 +5,11 @@ package org.eclipse.biscuit.crypto; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; +import java.io.IOException; import java.security.SecureRandom; -import java.security.Security; -import java.security.Signature; -import java.security.SignatureException; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.ECNamedCurveTable; @@ -19,6 +18,7 @@ import org.bouncycastle.jce.spec.ECPrivateKeySpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.util.BigIntegers; +import org.eclipse.biscuit.error.Error; import org.eclipse.biscuit.token.builder.Utils; @SuppressWarnings("checkstyle:AbbreviationAsWordInName") @@ -31,15 +31,14 @@ final class SECP256R1KeyPair extends KeyPair { private final BCECPrivateKey privateKey; private final BCECPublicKey publicKey; - static { - Security.addProvider(new BouncyCastleProvider()); - } - static final String ALGORITHM = "ECDSA"; static final String CURVE = "secp256r1"; static final ECNamedCurveParameterSpec SECP256R1 = ECNamedCurveTable.getParameterSpec(CURVE); - SECP256R1KeyPair(byte[] bytes) { + SECP256R1KeyPair(byte[] bytes) throws Error.FormatError.InvalidKeySize { + if (bytes.length != BUFFER_SIZE) { + throw new Error.FormatError.InvalidKeySize(bytes.length); + } var privateKeySpec = new ECPrivateKeySpec(BigIntegers.fromUnsignedByteArray(bytes), SECP256R1); var privateKey = new BCECPrivateKey(ALGORITHM, privateKeySpec, BouncyCastleProvider.CONFIGURATION); @@ -68,18 +67,22 @@ final class SECP256R1KeyPair extends KeyPair { this.publicKey = publicKey; } - static Signature getSignature() throws NoSuchAlgorithmException { - return Signature.getInstance( - "SHA256withECDSA", Security.getProvider(BouncyCastleProvider.PROVIDER_NAME)); - } - @Override - public byte[] sign(byte[] data) - throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { - Signature sgr = getSignature(); - sgr.initSign(privateKey); - sgr.update(data); - return sgr.sign(); + public byte[] sign(byte[] data) { + var digest = new SHA256Digest(); + digest.update(data, 0, data.length); + var hash = new byte[digest.getDigestSize()]; + digest.doFinal(hash, 0); + + var signer = new ECDSASigner(); + signer.init(true, privateKey.engineGetKeyParameters()); + var sig = signer.generateSignature(hash); + + try { + return StandardDSAEncoding.INSTANCE.encode(signer.getOrder(), sig[0], sig[1]); + } catch (IOException e) { + throw new IllegalStateException(e.toString()); + } } @Override diff --git a/src/main/java/org/eclipse/biscuit/crypto/SECP256R1PublicKey.java b/src/main/java/org/eclipse/biscuit/crypto/SECP256R1PublicKey.java index 370a3c93..5199eab7 100644 --- a/src/main/java/org/eclipse/biscuit/crypto/SECP256R1PublicKey.java +++ b/src/main/java/org/eclipse/biscuit/crypto/SECP256R1PublicKey.java @@ -6,21 +6,37 @@ package org.eclipse.biscuit.crypto; import static org.eclipse.biscuit.crypto.SECP256R1KeyPair.CURVE; -import static org.eclipse.biscuit.crypto.SECP256R1KeyPair.getSignature; import biscuit.format.schema.Schema.PublicKey.Algorithm; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SignatureException; +import java.io.IOException; +import java.math.BigInteger; import java.util.Arrays; +import org.bouncycastle.asn1.sec.SECNamedCurves; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.crypto.signers.HMacDSAKCalculator; +import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECPublicKeySpec; +import org.bouncycastle.math.ec.ECPoint; +import org.eclipse.biscuit.error.Error; @SuppressWarnings("checkstyle:AbbreviationAsWordInName") class SECP256R1PublicKey extends PublicKey { + private static final X9ECParameters x9ECParameters = SECNamedCurves.getByName("secp256r1"); + private static final ECDomainParameters domainParameters = + new ECDomainParameters( + x9ECParameters.getCurve(), + x9ECParameters.getG(), + x9ECParameters.getN(), + x9ECParameters.getH()); + private final BCECPublicKey publicKey; SECP256R1PublicKey(BCECPublicKey publicKey) { @@ -28,9 +44,15 @@ class SECP256R1PublicKey extends PublicKey { this.publicKey = publicKey; } - static SECP256R1PublicKey loadSECP256R1(byte[] data) { + static SECP256R1PublicKey loadSECP256R1(byte[] data) throws Error.FormatError.InvalidKey { var params = ECNamedCurveTable.getParameterSpec(CURVE); - var spec = new ECPublicKeySpec(params.getCurve().decodePoint(data), params); + ECPoint ecPoint; + try { + ecPoint = params.getCurve().decodePoint(data); + } catch (IllegalArgumentException e) { + throw new Error.FormatError.InvalidKey(e.getMessage()); + } + var spec = new ECPublicKeySpec(ecPoint, params); return new SECP256R1PublicKey( new BCECPublicKey(SECP256R1KeyPair.ALGORITHM, spec, BouncyCastleProvider.CONFIGURATION)); } @@ -69,11 +91,22 @@ public Algorithm getAlgorithm() { } @Override - public boolean verify(byte[] data, byte[] signature) - throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { - var sgr = getSignature(); - sgr.initVerify(this.publicKey); - sgr.update(data); - return sgr.verify(signature); + public boolean verify(byte[] data, byte[] signature) { + var digest = new SHA256Digest(); + digest.update(data, 0, data.length); + var hash = new byte[digest.getDigestSize()]; + digest.doFinal(hash, 0); + + var signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())); + signer.init(false, new ECPublicKeyParameters(publicKey.getQ(), domainParameters)); + + BigInteger[] sig; + try { + sig = StandardDSAEncoding.INSTANCE.decode(signer.getOrder(), signature); + } catch (IOException e) { + throw new IllegalStateException(e.toString()); + } + + return signer.verifySignature(hash, sig[0], sig[1]); } } diff --git a/src/main/java/org/eclipse/biscuit/error/Error.java b/src/main/java/org/eclipse/biscuit/error/Error.java index 8830b9b8..76bad6e0 100644 --- a/src/main/java/org/eclipse/biscuit/error/Error.java +++ b/src/main/java/org/eclipse/biscuit/error/Error.java @@ -401,6 +401,82 @@ public JsonElement toJson() { return FormatError.jsonWrapper(jo); } } + + public static final class InvalidKeySize extends FormatError { + private final int size; + + public InvalidKeySize(int size) { + this.size = size; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + InvalidKeySize iss = (InvalidKeySize) o; + + return size == iss.size; + } + + @Override + public int hashCode() { + return Objects.hash(size); + } + + @Override + public String toString() { + return "InvalidKeySize{" + "size=" + size + '}'; + } + + @Override + public JsonElement toJson() { + JsonObject jo = new JsonObject(); + jo.add("InvalidKeySize", new JsonPrimitive(size)); + return FormatError.jsonWrapper(jo); + } + } + + public static final class InvalidKey extends FormatError { + private final String err; + + public InvalidKey(String e) { + this.err = e; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InvalidKey other = (InvalidKey) o; + return err.equals(other.err); + } + + @Override + public int hashCode() { + return Objects.hash(err); + } + + @Override + public String toString() { + return "Err(Format(InvalidKey(\"" + this.err + "\"))"; + } + + @Override + public JsonElement toJson() { + JsonObject jo = new JsonObject(); + jo.addProperty("InvalidKey", this.err); + return FormatError.jsonWrapper(jo); + } + } } public static final class InvalidAuthorityIndex extends Error { diff --git a/src/main/java/org/eclipse/biscuit/token/ThirdPartyBlockContents.java b/src/main/java/org/eclipse/biscuit/token/ThirdPartyBlockContents.java index af34dec6..cc76e3c4 100644 --- a/src/main/java/org/eclipse/biscuit/token/ThirdPartyBlockContents.java +++ b/src/main/java/org/eclipse/biscuit/token/ThirdPartyBlockContents.java @@ -39,7 +39,7 @@ public Schema.ThirdPartyBlockContents serialize() throws Error.FormatError.Seria } public static ThirdPartyBlockContents deserialize(Schema.ThirdPartyBlockContents b) - throws Error.FormatError.DeserializationError { + throws Error.FormatError { byte[] payload = b.getPayload().toByteArray(); byte[] signature = b.getExternalSignature().getSignature().toByteArray(); PublicKey publicKey = PublicKey.deserialize(b.getExternalSignature().getPublicKey()); @@ -48,7 +48,7 @@ public static ThirdPartyBlockContents deserialize(Schema.ThirdPartyBlockContents } public static ThirdPartyBlockContents fromBytes(byte[] slice) - throws InvalidProtocolBufferException, Error.FormatError.DeserializationError { + throws InvalidProtocolBufferException, Error.FormatError { return ThirdPartyBlockContents.deserialize(Schema.ThirdPartyBlockContents.parseFrom(slice)); } diff --git a/src/main/java/org/eclipse/biscuit/token/builder/parser/Parser.java b/src/main/java/org/eclipse/biscuit/token/builder/parser/Parser.java index 43febdde..9a2eaa83 100644 --- a/src/main/java/org/eclipse/biscuit/token/builder/parser/Parser.java +++ b/src/main/java/org/eclipse/biscuit/token/builder/parser/Parser.java @@ -41,8 +41,8 @@ private Parser() {} *

If one succeeds it returns Right(Block) else it returns a Map[lineNumber, List[Error]] * * @param s datalog string to parse - * @return Either>, Tuple5, List, - * List, List, List>> + * @return Either>, Tuple5, List, List, + * List, List>> */ public static Either< Map>, @@ -157,16 +157,13 @@ private Parser() {} } /** - * Takes a datalog string with \n as datalog line separator. It - * tries to parse each + * Takes a datalog string with \n as datalog line separator. It tries to parse each * line using fact, rule, check and scope sequentially. * - *

- * If one succeeds it returns Right(Block) else it returns a Map[lineNumber, - * List[Error]] + *

If one succeeds it returns Right(Block) else it returns a Map[lineNumber, List[Error]] * * @param index block index - * @param s datalog string to parse + * @param s datalog string to parse * @return Either>, Block> */ public static Either>, Block> datalog(long index, String s) { @@ -510,19 +507,25 @@ public static Either> scope(String s) { } public static Either> publicKey(String s) { + Schema.PublicKey.Algorithm algorithm; if (s.startsWith("ed25519/")) { s = s.substring("ed25519/".length()); - Tuple2 t = hex(s); - return Either.right( - new Tuple2(t._1, PublicKey.load(Schema.PublicKey.Algorithm.Ed25519, t._2))); + algorithm = Schema.PublicKey.Algorithm.Ed25519; } else if (s.startsWith("secp256r1/")) { s = s.substring("secp256r1/".length()); - Tuple2 t = hex(s); - return Either.right( - new Tuple2(t._1, PublicKey.load(Schema.PublicKey.Algorithm.SECP256R1, t._2))); + algorithm = Schema.PublicKey.Algorithm.SECP256R1; } else { return Either.left(new Error(s, "unrecognized public key prefix")); } + + var t = hex(s); + PublicKey publicKey; + try { + publicKey = PublicKey.load(algorithm, t._2); + } catch (org.eclipse.biscuit.error.Error.FormatError e) { + return Either.left(new Error(s, e.getMessage())); + } + return Either.right(new Tuple2<>(t._1, publicKey)); } public static Either> factPredicate(String s) { diff --git a/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java b/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java index 25dcc19e..aa40985a 100644 --- a/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java +++ b/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java @@ -115,10 +115,9 @@ static SerializedBiscuit fromBytesInner(Schema.Biscuit data, PublicKey root) * * @param slice * @return SerializedBiscuit - * @throws Error.FormatError.DeserializationError + * @throws Error.FormatError */ - public static SerializedBiscuit deserializeUnsafe(byte[] slice) - throws Error.FormatError.DeserializationError { + public static SerializedBiscuit deserializeUnsafe(byte[] slice) throws Error.FormatError { try { Schema.Biscuit data = Schema.Biscuit.parseFrom(slice); return SerializedBiscuit.deserialize(data); @@ -132,10 +131,9 @@ public static SerializedBiscuit deserializeUnsafe(byte[] slice) * * @param data * @return SerializedBiscuit - * @throws Error.FormatError.DeserializationError + * @throws Error.FormatError */ - private static SerializedBiscuit deserialize(Schema.Biscuit data) - throws Error.FormatError.DeserializationError { + private static SerializedBiscuit deserialize(Schema.Biscuit data) throws Error.FormatError { if (data.getAuthority().hasExternalSignature()) { throw new Error.FormatError.DeserializationError( "the authority block must not contain an external signature"); diff --git a/src/test/java/org/eclipse/biscuit/builder/parser/ParserTest.java b/src/test/java/org/eclipse/biscuit/builder/parser/ParserTest.java index cbb4f99c..5bd4ef09 100644 --- a/src/test/java/org/eclipse/biscuit/builder/parser/ParserTest.java +++ b/src/test/java/org/eclipse/biscuit/builder/parser/ParserTest.java @@ -251,7 +251,7 @@ void ruleWithFreeExpressionVariables() { } @Test - void testRuleWithScope() { + void testRuleWithScope() throws org.eclipse.biscuit.error.Error.FormatError { Either> res = Parser.rule( "valid_date(\"file1\") <- resource(\"file1\") trusting" diff --git a/src/test/java/org/eclipse/biscuit/crypto/SignatureTest.java b/src/test/java/org/eclipse/biscuit/crypto/SignatureTest.java index dd094f2c..f10ea097 100644 --- a/src/test/java/org/eclipse/biscuit/crypto/SignatureTest.java +++ b/src/test/java/org/eclipse/biscuit/crypto/SignatureTest.java @@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import biscuit.format.schema.Schema; import java.security.InvalidKeyException; @@ -24,7 +25,7 @@ */ public class SignatureTest { @Test - public void testSerialize() { + public void testSerialize() throws Error.FormatError { prTestSerialize(Schema.PublicKey.Algorithm.Ed25519, 32); prTestSerialize( // compressed - 0x02 or 0x03 prefix byte, 32 bytes for X coordinate @@ -32,7 +33,7 @@ public void testSerialize() { } @Test - public void testHex() { + public void testHex() throws Error.FormatError { prGenSigKeys(Schema.PublicKey.Algorithm.SECP256R1); prGenSigKeys(Schema.PublicKey.Algorithm.Ed25519); } @@ -57,8 +58,36 @@ public void testSerializeBiscuit() throws Error { assertDoesNotThrow(() -> unverified.verify(root.getPublicKey())); } + @Test + void testInvalidSepc256r1Key() { + assertThrows( + Error.FormatError.InvalidKeySize.class, + () -> KeyPair.generate(Schema.PublicKey.Algorithm.SECP256R1, "badkey".getBytes())); + } + + @Test + void testInvalidEd25519Key() { + assertThrows( + Error.FormatError.InvalidKeySize.class, + () -> KeyPair.generate(Schema.PublicKey.Algorithm.Ed25519, "badkey".getBytes())); + } + + @Test + void testInvalidSepc256r1PublicKey() { + assertThrows( + Error.FormatError.InvalidKey.class, + () -> PublicKey.load(Schema.PublicKey.Algorithm.SECP256R1, "badkey".getBytes())); + } + + @Test + void testInvalidEd25519PublicKey() { + assertThrows( + Error.FormatError.InvalidKey.class, + () -> PublicKey.load(Schema.PublicKey.Algorithm.Ed25519, "badkey".getBytes())); + } + private static void prTestSerialize( - Schema.PublicKey.Algorithm algorithm, int expectedPublicKeyLength) { + Schema.PublicKey.Algorithm algorithm, int expectedPublicKeyLength) throws Error.FormatError { byte[] seed = {1, 2, 3, 4}; SecureRandom rng = new SecureRandom(seed); @@ -110,7 +139,7 @@ private static void prTestThreeMessages(Schema.PublicKey.Algorithm algorithm) assertEquals(Right(null), token3.verify(root.getPublicKey())); } - private static void prGenSigKeys(Schema.PublicKey.Algorithm algorithm) { + private static void prGenSigKeys(Schema.PublicKey.Algorithm algorithm) throws Error.FormatError { var keypair = KeyPair.generate(algorithm); var pubKey = keypair.getPublicKey(); var privHexString = keypair.toHex(); diff --git a/src/test/java/org/eclipse/biscuit/token/SamplesTest.java b/src/test/java/org/eclipse/biscuit/token/SamplesTest.java index b788b253..ff1a5b29 100644 --- a/src/test/java/org/eclipse/biscuit/token/SamplesTest.java +++ b/src/test/java/org/eclipse/biscuit/token/SamplesTest.java @@ -48,7 +48,7 @@ class SamplesTest { final RunLimits runLimits = new RunLimits(500, 100, Duration.ofMillis(500)); @TestFactory - Stream jsonTest() { + Stream jsonTest() throws Error.FormatError { InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("samples/samples.json"); Gson gson = new Gson();