diff --git a/src/main/java/org/eclipse/biscuit/token/Biscuit.java b/src/main/java/org/eclipse/biscuit/token/Biscuit.java index ea4281ab..854ab5ea 100644 --- a/src/main/java/org/eclipse/biscuit/token/Biscuit.java +++ b/src/main/java/org/eclipse/biscuit/token/Biscuit.java @@ -128,10 +128,9 @@ private static Biscuit make( throw container.getLeft(); } else { SerializedBiscuit s = container.get(); - List revocationIds = s.revocationIdentifiers(); Option c = Option.some(s); - return new Biscuit(authority, blocks, authority.getSymbolTable(), s, revocationIds); + return new Biscuit(authority, blocks, authority.getSymbolTable(), s); } } @@ -139,9 +138,8 @@ private static Biscuit make( Block authority, List blocks, SymbolTable symbolTable, - SerializedBiscuit serializedBiscuit, - List revocationIds) { - super(authority, blocks, symbolTable, serializedBiscuit, revocationIds); + SerializedBiscuit serializedBiscuit) { + super(authority, blocks, symbolTable, serializedBiscuit); } /** @@ -268,9 +266,7 @@ static Biscuit fromSerializedBiscuit(SerializedBiscuit ser, SymbolTable symbolTa Block authority = t._1; ArrayList blocks = t._2; - List revocationIds = ser.revocationIdentifiers(); - - return new Biscuit(authority, blocks, symbolTable, ser, revocationIds); + return new Biscuit(authority, blocks, symbolTable, ser); } /** @@ -365,9 +361,8 @@ public Biscuit attenuate(final SecureRandom rng, final KeyPair keypair, Block bl blocks.add(block); SerializedBiscuit container = containerRes.get(); - List revocationIds = container.revocationIdentifiers(); - return new Biscuit(copiedBiscuit.authority, blocks, symbolTable, container, revocationIds); + return new Biscuit(copiedBiscuit.authority, blocks, symbolTable, container); } /** Generates a third party block request from a token */ diff --git a/src/main/java/org/eclipse/biscuit/token/UnverifiedBiscuit.java b/src/main/java/org/eclipse/biscuit/token/UnverifiedBiscuit.java index 63ab602d..e1ada075 100644 --- a/src/main/java/org/eclipse/biscuit/token/UnverifiedBiscuit.java +++ b/src/main/java/org/eclipse/biscuit/token/UnverifiedBiscuit.java @@ -17,6 +17,7 @@ import java.util.Base64; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.biscuit.crypto.BlockSignatureBuffer; import org.eclipse.biscuit.crypto.KeyDelegate; import org.eclipse.biscuit.crypto.KeyPair; @@ -36,19 +37,16 @@ public class UnverifiedBiscuit { protected final List blocks; protected final SymbolTable symbolTable; protected final SerializedBiscuit serializedBiscuit; - protected final List revocationIds; UnverifiedBiscuit( Block authority, List blocks, SymbolTable symbolTable, - SerializedBiscuit serializedBiscuit, - List revocationIds) { + SerializedBiscuit serializedBiscuit) { this.authority = authority; this.blocks = blocks; this.symbolTable = symbolTable; this.serializedBiscuit = serializedBiscuit; - this.revocationIds = revocationIds; } /** @@ -98,9 +96,7 @@ private static UnverifiedBiscuit fromSerializedBiscuit( Block authority = t._1; ArrayList blocks = t._2; - List revocationIds = ser.revocationIdentifiers(); - - return new UnverifiedBiscuit(authority, blocks, symbolTable, ser, revocationIds); + return new UnverifiedBiscuit(authority, blocks, symbolTable, ser); } /** @@ -139,7 +135,7 @@ public org.eclipse.biscuit.token.builder.Block createBlock() { * @return */ public UnverifiedBiscuit attenuate( - org.eclipse.biscuit.token.builder.Block block, Algorithm algorithm) throws Error { + org.eclipse.biscuit.token.builder.Block block, Algorithm algorithm) throws Error { SecureRandom rng = new SecureRandom(); KeyPair keypair = KeyPair.generate(algorithm, rng); SymbolTable builderSymbols = new SymbolTable(this.symbolTable); @@ -147,9 +143,7 @@ public UnverifiedBiscuit attenuate( } public UnverifiedBiscuit attenuate( - final SecureRandom rng, - final KeyPair keypair, - org.eclipse.biscuit.token.builder.Block block) + final SecureRandom rng, final KeyPair keypair, org.eclipse.biscuit.token.builder.Block block) throws Error { SymbolTable builderSymbols = new SymbolTable(this.symbolTable); return attenuate(rng, keypair, block.build(builderSymbols)); @@ -189,20 +183,25 @@ private UnverifiedBiscuit attenuate(final SecureRandom rng, final KeyPair keypai blocks.add(block); SerializedBiscuit container = containerRes.get(); - List revocationIds = container.revocationIdentifiers(); - - return new UnverifiedBiscuit( - copiedBiscuit.authority, blocks, symbols, container, revocationIds); + return new UnverifiedBiscuit(copiedBiscuit.authority, blocks, symbols, container); } // FIXME: attenuate 3rd Party public List revocationIdentifiers() { - return this.revocationIds.stream() + return this.serializedBiscuit.revocationIdentifiers().stream() .map(RevocationIdentifier::fromBytes) .collect(Collectors.toList()); } + public List> externalPublicKeys() { + return Stream.>concat( + Stream.of(Option.none()), + this.serializedBiscuit.getBlocks().stream() + .map(b -> b.getExternalSignature().map(ExternalSignature::getKey))) + .collect(Collectors.toList()); + } + public List> getChecks() { ArrayList> l = new ArrayList<>(); l.add(new ArrayList<>(this.authority.getChecks())); @@ -237,6 +236,26 @@ public Option getRootKeyId() { return this.serializedBiscuit.getRootKeyId(); } + public int blockCount() { + return 1 + blocks.size(); + } + + public Option blockExternalKey(int index) { + if (index == 0) { + return authority.getExternalKey(); + } else { + return blocks.get(index - 1).getExternalKey(); + } + } + + public List blockPublicKeys(int index) { + if (index == 0) { + return authority.getPublicKeys(); + } else { + return blocks.get(index - 1).getPublicKeys(); + } + } + /** Generates a third party block request from a token */ public ThirdPartyBlockRequest thirdPartyRequest() { PublicKey previousKey; @@ -304,9 +323,7 @@ public UnverifiedBiscuit appendThirdPartyBlock( } blocks.add(block); - List revocationIds = container.revocationIdentifiers(); - return new UnverifiedBiscuit( - copiedBiscuit.authority, blocks, symbols, container, revocationIds); + return new UnverifiedBiscuit(copiedBiscuit.authority, blocks, symbols, container); } /** Prints a token's content */ 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 9f39c4c7..500fa790 100644 --- a/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java +++ b/src/main/java/org/eclipse/biscuit/token/format/SerializedBiscuit.java @@ -172,13 +172,18 @@ private static SerializedBiscuit deserialize(Schema.Biscuit data) throw new Error.FormatError.DeserializationError("invalid proof"); } - final Proof proof = - data.getProof().hasFinalSignature() - ? new Proof.FinalSignature(data.getProof().getFinalSignature().toByteArray()) - : new Proof.NextSecret( - KeyPair.generate( - authority.getKey().getAlgorithm(), - data.getProof().getNextSecret().toByteArray())); + final Proof proof; + if (data.getProof().hasFinalSignature()) { + proof = new Proof.FinalSignature(data.getProof().getFinalSignature().toByteArray()); + } else { + final Schema.PublicKey.Algorithm proofAlgorithm = + blocks.isEmpty() + ? authority.getKey().getAlgorithm() + : blocks.get(blocks.size() - 1).getKey().getAlgorithm(); + proof = + new Proof.NextSecret( + KeyPair.generate(proofAlgorithm, data.getProof().getNextSecret().toByteArray())); + } Option rootKeyId = data.hasRootKeyId() ? Option.some(data.getRootKeyId()) : Option.none(); diff --git a/src/test/java/org/eclipse/biscuit/token/BiscuitTest.java b/src/test/java/org/eclipse/biscuit/token/BiscuitTest.java index a59c28d4..95138e6b 100644 --- a/src/test/java/org/eclipse/biscuit/token/BiscuitTest.java +++ b/src/test/java/org/eclipse/biscuit/token/BiscuitTest.java @@ -72,6 +72,7 @@ public void testBasic() System.out.println("deserializing the first token"); Biscuit deser = Biscuit.fromBytes(data, root.getPublicKey()); + assertEquals(1, deser.blockCount()); System.out.println(deser.print()); @@ -105,6 +106,7 @@ public void testBasic() System.out.println("deserializing the second token"); Biscuit deser2 = Biscuit.fromBytes(data2, root.getPublicKey()); + assertEquals(2, deser2.blockCount()); System.out.println(deser2.print()); @@ -135,6 +137,7 @@ public void testBasic() System.out.println("deserializing the third token"); Biscuit finalToken = Biscuit.fromBytes(data3, root.getPublicKey()); + assertEquals(3, finalToken.blockCount()); System.out.println(finalToken.print()); diff --git a/src/test/java/org/eclipse/biscuit/token/ThirdPartyTest.java b/src/test/java/org/eclipse/biscuit/token/ThirdPartyTest.java index b68610b7..a09b04bb 100644 --- a/src/test/java/org/eclipse/biscuit/token/ThirdPartyTest.java +++ b/src/test/java/org/eclipse/biscuit/token/ThirdPartyTest.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import biscuit.format.schema.Schema; +import io.vavr.control.Option; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -15,6 +16,7 @@ import java.security.SignatureException; import java.time.Duration; import java.util.Arrays; +import java.util.List; import org.eclipse.biscuit.crypto.KeyPair; import org.eclipse.biscuit.datalog.RunLimits; import org.eclipse.biscuit.error.Error; @@ -66,6 +68,10 @@ public void testRoundTrip() byte[] data = b2.serialize(); Biscuit deser = Biscuit.fromBytes(data, root.getPublicKey()); assertEquals(b2.print(), deser.print()); + assertEquals( + b2.externalPublicKeys(), List.of(Option.none(), Option.of(external.getPublicKey()))); + assertEquals(Option.none(), b2.blockExternalKey(0)); + assertEquals(Option.of(external.getPublicKey()), b2.blockExternalKey(1)); System.out.println("will check the token for resource=file1"); Authorizer authorizer = deser.authorizer();