From 25cebb6b8d641108e1b8bcbd8347994e20d7cdb0 Mon Sep 17 00:00:00 2001 From: Tore Frederiksen Date: Fri, 25 Mar 2022 13:32:37 +0100 Subject: [PATCH] Added wrapper to ensure compatibility with attestation.id main branch --- .../devcon/ticket/DevconTicketDecoder.java | 130 ++++++++++++++++++ .../devcon/ticket/LisconTicketDecoder.java | 2 +- .../java/org/devcon/ticket/TicketDecoder.java | 125 +++-------------- .../org/devcon/ticket/UseTicketBundle.java | 2 +- .../java/org/devcon/ticket/Validator.java | 4 +- .../java/org/devcon/ticket/TicketTest.java | 59 ++++++-- .../java/org/devcon/ticket/UseTicketTest.java | 5 +- .../attestation/eip712/EIP712ObjectTest.java | 10 +- 8 files changed, 204 insertions(+), 133 deletions(-) create mode 100644 src/main/java/org/devcon/ticket/DevconTicketDecoder.java diff --git a/src/main/java/org/devcon/ticket/DevconTicketDecoder.java b/src/main/java/org/devcon/ticket/DevconTicketDecoder.java new file mode 100644 index 00000000..184511e6 --- /dev/null +++ b/src/main/java/org/devcon/ticket/DevconTicketDecoder.java @@ -0,0 +1,130 @@ +package org.devcon.ticket; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bouncycastle.asn1.ASN1BitString; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1UTF8String; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; +import org.tokenscript.attestation.ObjectDecoder; +import org.tokenscript.attestation.core.ExceptionUtil; +import org.tokenscript.attestation.core.SignatureUtility; + +public class DevconTicketDecoder implements ObjectDecoder { + private static final Logger logger = LogManager.getLogger(DevconTicketDecoder.class); + private static final String DEFAULT = "default"; + + private Map idsToKeys; + + public DevconTicketDecoder(Map idsToKeys) { + this.idsToKeys = idsToKeys; + } + + public DevconTicketDecoder(AsymmetricKeyParameter publicKey) { + this(); + idsToKeys.put(DEFAULT, publicKey); + } + + public DevconTicketDecoder() { + idsToKeys = new HashMap<>(); + } + + @Override + public Ticket decode(byte[] encoding) throws IOException { + ASN1InputStream input = null; + try { + input = new ASN1InputStream(encoding); + ASN1Sequence asn1 = ASN1Sequence.getInstance(input.readObject()); + input.close(); + ASN1Sequence ticket = ASN1Sequence.getInstance(asn1.getObjectAt(0)); + String devconId = (ASN1UTF8String.getInstance(ticket.getObjectAt(0))).getString(); + ASN1Primitive ticketIdObj = ticket.getObjectAt(1).toASN1Primitive(); + String ticketId; + if (ticketIdObj instanceof ASN1Integer) { + ticketId = (ASN1Integer.getInstance(ticket.getObjectAt(1))).getValue().toString(); + } else { // ASN1UTF8String + ticketId = (ASN1UTF8String.getInstance(ticket.getObjectAt(1))).getString(); + } + int ticketClassInt = ASN1Integer.getInstance(ticket.getObjectAt(2)).getValue().intValueExact(); + byte[] commitment = (ASN1OctetString.getInstance(ticket.getObjectAt(3))).getOctets(); + /* refactored 2021-01-05 : we don't care about the ticket class set on our level + TicketClass ticketClass = null; + for (TicketClass current : TicketClass.values()) { + if (current.getValue() == ticketClassInt) { + ticketClass = current; + } + } + if (ticketClass == null) { + throw new IOException("Not valid ticket class"); + } + */ + byte[] signature = parsePKandSignature(asn1, devconId, 1); + return new Ticket(devconId, ticketId, ticketClassInt, commitment, signature, getPk(devconId)); + } finally { + input.close(); + } + } + + /** + * Returns the signature and ensures that the optional public key is properly restored + * @param input The encoded Ticket + * @return + */ + byte[] parsePKandSignature(ASN1Sequence input, String devconId, int asnBaseIdx) throws IOException, IllegalArgumentException{ + byte[] signature; + ASN1Encodable object = input.getObjectAt(asnBaseIdx); + if (object instanceof ASN1Sequence) { + // The optional PublicKeyInfo is included + parseEncodingOfPKInfo((ASN1Sequence) object, devconId); + signature = ASN1BitString.getInstance(input.getObjectAt(asnBaseIdx+1)).getBytes(); + } else if (object instanceof DERBitString) { + // Only the signature is included + signature = ASN1BitString.getInstance(input.getObjectAt(asnBaseIdx)).getBytes(); + } else { + throw ExceptionUtil.throwException(logger, + new IllegalArgumentException("Invalid ticket encoding")); + } + return signature; + } + + void parseEncodingOfPKInfo(ASN1Sequence publicKeyInfo, String devconId) throws IOException, IllegalArgumentException { + AlgorithmIdentifier algorithm = AlgorithmIdentifier.getInstance(publicKeyInfo.getObjectAt(0)); + byte[] publicKeyBytes = ASN1BitString.getInstance(publicKeyInfo.getObjectAt(1)).getEncoded(); + AsymmetricKeyParameter decodedPublicKey = SignatureUtility.restoreDefaultKey(algorithm, publicKeyBytes); + SubjectPublicKeyInfo decodedSpki = SubjectPublicKeyInfoFactory + .createSubjectPublicKeyInfo(decodedPublicKey); + // Ensure that the right type of public key is given + if (getPk(devconId) != null) { + SubjectPublicKeyInfo referenceSpki = SubjectPublicKeyInfoFactory + .createSubjectPublicKeyInfo(getPk(devconId)); + if (!Arrays.equals(referenceSpki.getEncoded(), decodedSpki.getEncoded())) { + throw ExceptionUtil.throwException(logger, new IllegalArgumentException( + "The public key is not of the same as supplied as argument")); + } + } + idsToKeys.put(devconId, decodedPublicKey); + } + + AsymmetricKeyParameter getPk(String devconId) { + AsymmetricKeyParameter pk; + if (idsToKeys.get(devconId) != null) { + pk = idsToKeys.get(devconId); + } else { + pk = idsToKeys.get(DEFAULT); + } + return pk; + } +} diff --git a/src/main/java/org/devcon/ticket/LisconTicketDecoder.java b/src/main/java/org/devcon/ticket/LisconTicketDecoder.java index 37cce667..52140bf7 100644 --- a/src/main/java/org/devcon/ticket/LisconTicketDecoder.java +++ b/src/main/java/org/devcon/ticket/LisconTicketDecoder.java @@ -14,7 +14,7 @@ * It is significantly less secure than the regular Ticket format and should only be used in legacy settings! */ @Deprecated -public class LisconTicketDecoder extends TicketDecoder { +public class LisconTicketDecoder extends DevconTicketDecoder { public LisconTicketDecoder(AsymmetricKeyParameter publicKey) { super(publicKey); } diff --git a/src/main/java/org/devcon/ticket/TicketDecoder.java b/src/main/java/org/devcon/ticket/TicketDecoder.java index 7b24bbb1..b9129c79 100644 --- a/src/main/java/org/devcon/ticket/TicketDecoder.java +++ b/src/main/java/org/devcon/ticket/TicketDecoder.java @@ -1,130 +1,43 @@ package org.devcon.ticket; import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bouncycastle.asn1.ASN1BitString; -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Integer; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.ASN1UTF8String; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.tokenscript.attestation.ObjectDecoder; import org.tokenscript.attestation.core.ExceptionUtil; -import org.tokenscript.attestation.core.SignatureUtility; -public class TicketDecoder implements ObjectDecoder { +/** + * Wrapper class that allows decoding of either Devcon or Liscon tickets. + * This class only exists for backward compatibility reasons + */ +@Deprecated +public class TicketDecoder implements ObjectDecoder { private static final Logger logger = LogManager.getLogger(TicketDecoder.class); - private static final String DEFAULT = "default"; - - private Map idsToKeys; + private final List> decoders = new ArrayList<>(2); public TicketDecoder(Map idsToKeys) { - this.idsToKeys = idsToKeys; + decoders.add(new DevconTicketDecoder(idsToKeys)); } public TicketDecoder(AsymmetricKeyParameter publicKey) { - this(); - idsToKeys.put(DEFAULT, publicKey); - } - - public TicketDecoder() { - idsToKeys = new HashMap<>(); + decoders.add(new DevconTicketDecoder(publicKey)); + decoders.add(new LisconTicketDecoder(publicKey)); } @Override public Ticket decode(byte[] encoding) throws IOException { - ASN1InputStream input = null; - try { - input = new ASN1InputStream(encoding); - ASN1Sequence asn1 = ASN1Sequence.getInstance(input.readObject()); - input.close(); - ASN1Sequence ticket = ASN1Sequence.getInstance(asn1.getObjectAt(0)); - String devconId = (ASN1UTF8String.getInstance(ticket.getObjectAt(0))).getString(); - ASN1Primitive ticketIdObj = ticket.getObjectAt(1).toASN1Primitive(); - String ticketId; - if (ticketIdObj instanceof ASN1Integer) { - ticketId = (ASN1Integer.getInstance(ticket.getObjectAt(1))).getValue().toString(); - } else { // ASN1UTF8String - ticketId = (ASN1UTF8String.getInstance(ticket.getObjectAt(1))).getString(); - } - int ticketClassInt = ASN1Integer.getInstance(ticket.getObjectAt(2)).getValue().intValueExact(); - byte[] commitment = (ASN1OctetString.getInstance(ticket.getObjectAt(3))).getOctets(); - /* refactored 2021-01-05 : we don't care about the ticket class set on our level - TicketClass ticketClass = null; - for (TicketClass current : TicketClass.values()) { - if (current.getValue() == ticketClassInt) { - ticketClass = current; - } + for (ObjectDecoder currentDecoder : decoders) { + try { + return currentDecoder.decode(encoding); + } catch (Exception e) { + continue; } - if (ticketClass == null) { - throw new IOException("Not valid ticket class"); - } - */ - byte[] signature = parsePKandSignature(asn1, devconId, 1); - return new Ticket(devconId, ticketId, ticketClassInt, commitment, signature, getPk(devconId)); - } finally { - input.close(); - } - } - - /** - * Returns the signature and ensures that the optional public key is properly restored - * @param input The encoded Ticket - * @return - */ - byte[] parsePKandSignature(ASN1Sequence input, String devconId, int asnBaseIdx) throws IOException, IllegalArgumentException{ - byte[] signature; - ASN1Encodable object = input.getObjectAt(asnBaseIdx); - if (object instanceof ASN1Sequence) { - // The optional PublicKeyInfo is included - parseEncodingOfPKInfo((ASN1Sequence) object, devconId); - signature = ASN1BitString.getInstance(input.getObjectAt(asnBaseIdx+1)).getBytes(); - } else if (object instanceof DERBitString) { - // Only the signature is included - signature = ASN1BitString.getInstance(input.getObjectAt(asnBaseIdx)).getBytes(); - } else { - throw ExceptionUtil.throwException(logger, - new IllegalArgumentException("Invalid ticket encoding")); - } - return signature; - } - - void parseEncodingOfPKInfo(ASN1Sequence publicKeyInfo, String devconId) throws IOException, IllegalArgumentException { - AlgorithmIdentifier algorithm = AlgorithmIdentifier.getInstance(publicKeyInfo.getObjectAt(0)); - byte[] publicKeyBytes = ASN1BitString.getInstance(publicKeyInfo.getObjectAt(1)).getEncoded(); - AsymmetricKeyParameter decodedPublicKey = SignatureUtility.restoreDefaultKey(algorithm, publicKeyBytes); - SubjectPublicKeyInfo decodedSpki = SubjectPublicKeyInfoFactory - .createSubjectPublicKeyInfo(decodedPublicKey); - // Ensure that the right type of public key is given - if (getPk(devconId) != null) { - SubjectPublicKeyInfo referenceSpki = SubjectPublicKeyInfoFactory - .createSubjectPublicKeyInfo(getPk(devconId)); - if (!Arrays.equals(referenceSpki.getEncoded(), decodedSpki.getEncoded())) { - throw ExceptionUtil.throwException(logger, new IllegalArgumentException( - "The public key is not of the same as supplied as argument")); - } - } - idsToKeys.put(devconId, decodedPublicKey); - } - - AsymmetricKeyParameter getPk(String devconId) { - AsymmetricKeyParameter pk; - if (idsToKeys.get(devconId) != null) { - pk = idsToKeys.get(devconId); - } else { - pk = idsToKeys.get(DEFAULT); } - return pk; + ExceptionUtil.throwException(logger, new RuntimeException("Could not decode ticket")); + return null; } } diff --git a/src/main/java/org/devcon/ticket/UseTicketBundle.java b/src/main/java/org/devcon/ticket/UseTicketBundle.java index 8240543d..1c60c35c 100644 --- a/src/main/java/org/devcon/ticket/UseTicketBundle.java +++ b/src/main/java/org/devcon/ticket/UseTicketBundle.java @@ -46,7 +46,7 @@ public UseTicketBundle(AttestedObject useTicket, UnpredictableNumberBundle un, b public UseTicketBundle(String jsonBundle, AsymmetricKeyParameter ticketIssuerPublicKey, AsymmetricKeyParameter attestorPublicKey) throws Exception { this.jsonMapper = new ObjectMapper(); JsonUseTicketBundle decodedBundle = jsonMapper.readValue(jsonBundle, JsonUseTicketBundle.class); - this.useTicket = new AttestedObject(decodedBundle.getUseTicketDer(), new TicketDecoder(ticketIssuerPublicKey), attestorPublicKey); + this.useTicket = new AttestedObject(decodedBundle.getUseTicketDer(), new DevconTicketDecoder(ticketIssuerPublicKey), attestorPublicKey); this.un = decodedBundle.getUn(); this.messageToSign = computeMessage(un); this.signature = decodedBundle.getSignature(); diff --git a/src/main/java/org/devcon/ticket/Validator.java b/src/main/java/org/devcon/ticket/Validator.java index 0dce9cca..7ca1c7ef 100644 --- a/src/main/java/org/devcon/ticket/Validator.java +++ b/src/main/java/org/devcon/ticket/Validator.java @@ -43,8 +43,8 @@ public static void main(String... args) { static void validateTicket(String ticketInUrl, String pokInUrl, String mail, Path keyFile) throws IOException { byte[] dataCER = DERUtility.restoreBytes(Files.readAllLines(keyFile)); AsymmetricKeyParameter issuerPubKey = DERUtility.restoreRFCRFC5915Key(dataCER); - TicketDecoder ticketDecoder = new TicketDecoder(issuerPubKey); - Ticket ticket = ticketDecoder.decode(URLUtility.decodeData(ticketInUrl)); + DevconTicketDecoder devconTicketDecoder = new DevconTicketDecoder(issuerPubKey); + Ticket ticket = devconTicketDecoder.decode(URLUtility.decodeData(ticketInUrl)); if (!ticket.checkValidity()) { throw new RuntimeException( "Something went wrong and the constructed ticket could not be validated"); diff --git a/src/test/java/org/devcon/ticket/TicketTest.java b/src/test/java/org/devcon/ticket/TicketTest.java index 5bda9af3..28a4d1d1 100644 --- a/src/test/java/org/devcon/ticket/TicketTest.java +++ b/src/test/java/org/devcon/ticket/TicketTest.java @@ -96,7 +96,7 @@ public void testTicketURLSunshine() throws IOException { List decoded = URLUtility.decodeList(ticket.getUrlEncoding()); - Ticket newTicket = (new TicketDecoder(senderKeys.getPublic())).decode(decoded.get(0)); + Ticket newTicket = (new DevconTicketDecoder(senderKeys.getPublic())).decode(decoded.get(0)); assertTrue(newTicket.verify()); assertTrue(newTicket.checkValidity()); assertArrayEquals(ticket.getDerEncoding(), newTicket.getDerEncoding()); @@ -114,7 +114,7 @@ public void testTicketURLConsistentEncoding() throws IOException { BigInteger senderSecret = new BigInteger("186416"); Ticket ticket = new Ticket("ticket@test.ts", "6", ticketID, ticketClass, senderKeys, senderSecret); String url = URLUtility.encodeData(ticket.getDerEncoding()); - Ticket newTicket = (new TicketDecoder(senderKeys.getPublic())).decode(URLUtility.decodeData(url)); + Ticket newTicket = (new DevconTicketDecoder(senderKeys.getPublic())).decode(URLUtility.decodeData(url)); String newUrl = URLUtility.encodeData(newTicket.getDerEncoding()); assertEquals(url, newUrl); /*** PRINT URL ***/ @@ -128,7 +128,7 @@ public void testFullDecoding() throws Exception { // write the ticket data Files.write(new File(PREFIX + "signed-devcon-ticket.der").toPath(), encoded); - Ticket newTicket = (new TicketDecoder(senderKeys.getPublic())).decode(encoded); + Ticket newTicket = (new DevconTicketDecoder(senderKeys.getPublic())).decode(encoded); assertTrue(ticket.verify()); assertTrue(newTicket.verify()); assertArrayEquals(encoded, newTicket.getDerEncoding()); @@ -166,7 +166,7 @@ public void stringTicketId() throws Exception { assertEquals(TICKET_CLASS, ticket.getTicketClass()); assertEquals(CONFERENCE_ID, ticket.getDevconId()); - TicketDecoder decoder = new TicketDecoder(senderKeys.getPublic()); + DevconTicketDecoder decoder = new DevconTicketDecoder(senderKeys.getPublic()); Ticket newTicket = decoder.decode(ticket.getDerEncoding()); assertTrue(newTicket.verify()); assertTrue(newTicket.checkValidity()); @@ -184,7 +184,7 @@ public void stringTicketId() throws Exception { public void testLegacyTicket() throws Exception { String legacyTicketUrl = "MIGXMFEMBDYuw5gCAwC-BgIBAARBBCtDxEZ1a0_c7qCE3k2UzDZQbziPc_mRgfdCGNi2wJx9GGM0Vg24wFNQX3s98rUVoJ8axKVcHlFAS0E2vFlSyZwDQgCc5Qp0GRCbBLQxw0C7K-pHmaDuuzaFwFO4tIVpjIAz0hNwZtshqRS_Z0R_rz2SbvQJeGcvy8ENnkFyyawubuiMHA=="; byte[] legacyTicketBytes = URLUtility.decodeData(legacyTicketUrl); - TicketDecoder decoder = new TicketDecoder(senderKeys.getPublic()); + DevconTicketDecoder decoder = new DevconTicketDecoder(senderKeys.getPublic()); Ticket legacyTicket = decoder.decode(legacyTicketBytes); assertTrue(legacyTicket.verify()); assertTrue(legacyTicket.checkValidity()); @@ -207,7 +207,7 @@ public void testFullDecodingWithPK() throws Exception { Ticket ticket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); byte[] encoded = ticket.getDerEncodingWithPK(); - Ticket newTicket = (new TicketDecoder(senderKeys.getPublic())).decode(encoded); + Ticket newTicket = (new DevconTicketDecoder(senderKeys.getPublic())).decode(encoded); assertTrue(ticket.verify()); assertTrue(newTicket.verify()); assertArrayEquals(encoded, newTicket.getDerEncodingWithPK()); @@ -226,7 +226,7 @@ public void testFullDecodingWithPK() throws Exception { assertArrayEquals(encoded, otherConstructor.getDerEncodingWithPK()); - Ticket noPKDecodingTicket = (new TicketDecoder()).decode(encoded); + Ticket noPKDecodingTicket = (new DevconTicketDecoder()).decode(encoded); assertTrue(noPKDecodingTicket.verify()); assertArrayEquals(encoded, noPKDecodingTicket.getDerEncodingWithPK()); } @@ -242,7 +242,7 @@ public void testMultiplePks() throws Exception { keys.put("secondConference", otherKeys.getPublic()); AsymmetricCipherKeyPair yetAnotherKey = SignatureUtility.constructECKeysWithSmallestY(rand); keys.put("some conference", yetAnotherKey.getPublic()); - TicketDecoder decoder = new TicketDecoder(keys); + DevconTicketDecoder decoder = new DevconTicketDecoder(keys); Ticket restoredFirstTicket = decoder.decode(firstEncodedTicket); Ticket restoredSecondTicket = decoder.decode(secondEncodedTicket); assertTrue(restoredFirstTicket.verify()); @@ -268,12 +268,41 @@ public void testLisconTicketDecoder() throws Exception { String lisconTicket = "MIGWMA0MATYCBWE3ap3-AgEABEEEKJZVxMEXbkSZZBWnNUTX_5ieu8GUqf0bx_a0tBPF6QYskABaMJBYhDOXsmQt3csk_TfMZ2wdmfRkK7ePCOI2kgNCAOOZKRpcE6tLBuPbfE_SmwPk2wNjbj5vpa6kkD7eqQXvBOCa0WNo8dEHKvipeUGZZEWWjJKxooB44dEYdQO70Vgc"; byte[] binaryLisconTicket = Base64.getUrlDecoder().decode(lisconTicket); // Normal ticket decoder is not compatible with Liscon ticket - assertThrows(Exception.class, () -> new TicketDecoder(senderKeys.getPublic()).decode(binaryLisconTicket)); + assertThrows(Exception.class, () -> new DevconTicketDecoder(senderKeys.getPublic()).decode(binaryLisconTicket)); Ticket ticket = new LisconTicketDecoder(senderKeys.getPublic()).decode(binaryLisconTicket); assertTrue(ticket.verify()); assertTrue(ticket.checkValidity()); } + @Test + public void universalDecoderDevconTicket() throws Exception { + Ticket devconTicket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); + Map keys = new HashMap<>(); + keys.put(CONFERENCE_ID, senderKeys.getPublic()); + TicketDecoder decoder = new TicketDecoder(keys); + Ticket decodedTicket = decoder.decode(devconTicket.getDerEncoding()); + assertArrayEquals(devconTicket.getDerEncoding(), decodedTicket.getDerEncoding()); + assertTrue(decodedTicket.checkValidity()); + assertTrue(decodedTicket.verify()); + } + + @Test + public void universalDecoderLisconTicket() throws Exception { + Ticket lisconTicket = new LisconTicket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); + TicketDecoder decoder = new TicketDecoder(senderKeys.getPublic()); + Ticket decodedTicket = decoder.decode(lisconTicket.getDerEncoding()); + assertArrayEquals(lisconTicket.getDerEncoding(), decodedTicket.getDerEncoding()); + assertTrue(decodedTicket.checkValidity()); + assertTrue(decodedTicket.verify()); + } + + @Test + public void universalDecoderInvalidTicket() throws Exception { + TicketDecoder decoder = new TicketDecoder(senderKeys.getPublic()); + Exception e = assertThrows(RuntimeException.class, ()-> decoder.decode(new byte[] {0x00})); + assertEquals(e.getMessage(), "Could not decode ticket"); + } + @Test public void saveDerEncodedLiscon() { LisconTicket ticket = new LisconTicket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); @@ -284,7 +313,7 @@ public void saveDerEncodedLiscon() { public void testMissingKey() { Ticket ticket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); byte[] encodedTicket = ticket.getDerEncoding(); - TicketDecoder decoder = new TicketDecoder(); + DevconTicketDecoder decoder = new DevconTicketDecoder(); assertThrows(RuntimeException.class, ()-> decoder.decode(encodedTicket)); } @@ -296,7 +325,7 @@ public void testWrongPks() { // Incorrect conference name keys.put("incorrect conference", senderKeys.getPublic()); keys.put("secondConference", otherKeys.getPublic()); - TicketDecoder decoder = new TicketDecoder(keys); + DevconTicketDecoder decoder = new DevconTicketDecoder(keys); assertThrows(RuntimeException.class, ()-> decoder.decode(encodedTicket)); } @@ -308,7 +337,7 @@ public void testWrongName() throws Exception { // Incorrect conference name keys.put("incorrect conference", senderKeys.getPublic()); keys.put("secondConference", otherKeys.getPublic()); - TicketDecoder decoder = new TicketDecoder(keys); + DevconTicketDecoder decoder = new DevconTicketDecoder(keys); Ticket restoredTicket = decoder.decode(encodedTicket); // TODO Currently supplied key is blankly accepted. Should throw exception. See https://github.com/TokenScript/attestation/issues/198 assertTrue(restoredTicket.verify()); @@ -323,7 +352,7 @@ public void testWrongUserSuppliedKey() throws Exception { field.set(ticket, otherKeys.getPublic()); byte[] encodingWithPK = ticket.getDerEncodingWithPK(); - TicketDecoder decoder = new TicketDecoder(senderKeys.getPublic()); + DevconTicketDecoder decoder = new DevconTicketDecoder(senderKeys.getPublic()); // The constructor verification will fail assertThrows(IllegalArgumentException.class, ()-> decoder.decode(encodingWithPK)); } @@ -352,7 +381,7 @@ public void testWrongKey() throws Exception { Ticket ticket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); byte[] encoding = ticket.getDerEncodingWithPK(); try { - Ticket otherTicket = (new TicketDecoder(otherKeys.getPublic())).decode(encoding); + Ticket otherTicket = (new DevconTicketDecoder(otherKeys.getPublic())).decode(encoding); fail(); } catch (IllegalArgumentException e) { // Expected @@ -364,7 +393,7 @@ public void testWrongKeyNoPKArgument() throws Exception { Ticket ticket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, senderKeys, SECRET); byte[] encoding = ticket.getDerEncoding(); try { - Ticket otherTicket = (new TicketDecoder(otherKeys.getPublic())).decode(encoding); + Ticket otherTicket = (new DevconTicketDecoder(otherKeys.getPublic())).decode(encoding); fail(); } catch (IllegalArgumentException e) { // Expected diff --git a/src/test/java/org/devcon/ticket/UseTicketTest.java b/src/test/java/org/devcon/ticket/UseTicketTest.java index 84af3f70..4c4e2153 100644 --- a/src/test/java/org/devcon/ticket/UseTicketTest.java +++ b/src/test/java/org/devcon/ticket/UseTicketTest.java @@ -23,7 +23,6 @@ import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.EC; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.tokenscript.attestation.Attestation; import org.tokenscript.attestation.AttestedObject; @@ -126,7 +125,7 @@ public void testWithUnpredictableNumberBundle() { @Test public void testDecoding() throws InvalidObjectException { - AttestedObject newAttestedTicket = new AttestedObject(attestedTicket.getDerEncoding(), new TicketDecoder( + AttestedObject newAttestedTicket = new AttestedObject(attestedTicket.getDerEncoding(), new DevconTicketDecoder( ticketIssuerKeys.getPublic()), attestorKeys.getPublic()); assertTrue(newAttestedTicket.getAttestableObject().verify()); assertTrue(newAttestedTicket.verify()); @@ -174,7 +173,7 @@ public void testRebuildComponents() { Ticket ticket = new Ticket(MAIL, CONFERENCE_ID, TICKET_ID, TICKET_CLASS, ticketIssuerKeys, TICKET_SECRET); AttestedObject useTicket = new AttestedObject<>(ticket, signed, ATTESTATION_SECRET, TICKET_SECRET, UN, crypto); - AttestedObject newUseTicket = new AttestedObject(useTicket.getDerEncoding(), new TicketDecoder( + AttestedObject newUseTicket = new AttestedObject(useTicket.getDerEncoding(), new DevconTicketDecoder( ticketIssuerKeys.getPublic()), attestorKeys.getPublic()); assertTrue(newUseTicket.getAttestableObject().verify()); diff --git a/src/test/java/org/tokenscript/attestation/eip712/EIP712ObjectTest.java b/src/test/java/org/tokenscript/attestation/eip712/EIP712ObjectTest.java index 8f02f8dd..728486f9 100644 --- a/src/test/java/org/tokenscript/attestation/eip712/EIP712ObjectTest.java +++ b/src/test/java/org/tokenscript/attestation/eip712/EIP712ObjectTest.java @@ -15,7 +15,7 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.devcon.ticket.Ticket; -import org.devcon.ticket.TicketDecoder; +import org.devcon.ticket.DevconTicketDecoder; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -69,7 +69,7 @@ public static void setupKeys() throws Exception { userKeys = SignatureUtility.constructECKeysWithSmallestY(rand); attestorKeys = SignatureUtility.constructECKeysWithSmallestY(rand); ticketKeys = SignatureUtility.constructECKeysWithSmallestY(rand); - ObjectDecoder ticketDecoder = new TicketDecoder(ticketKeys.getPublic()); + ObjectDecoder ticketDecoder = new DevconTicketDecoder(ticketKeys.getPublic()); ObjectDecoder> attestedObjectDecoder = new AttestedObjectDecoder(ticketDecoder, attestorKeys.getPublic()); encoder = new AuthenticatorEncoder(0, rand); @@ -114,7 +114,7 @@ public void testNewChainID() throws Exception { Eip712ObjectSigner localIssuer = new Eip712ObjectSigner(userKeys.getPrivate(), localAuthenticator); AttestedObject attestedTicket = makeAttestedTicket(); String token = localIssuer.buildSignedToken(attestedTicket, validatorDomain); - ObjectDecoder ticketDecoder = new TicketDecoder(ticketKeys.getPublic()); + ObjectDecoder ticketDecoder = new DevconTicketDecoder(ticketKeys.getPublic()); ObjectDecoder> attestedObjectDecoder = new AttestedObjectDecoder(ticketDecoder, attestorKeys.getPublic()); Eip712ObjectValidator localValidator = new Eip712ObjectValidator(attestedObjectDecoder, localAuthenticator, @@ -174,7 +174,7 @@ public void tooOld() throws Exception { long testTimestamp = 10000; Eip712ObjectSigner testIssuer = new TestEip712ObjectSigner(userKeys.getPrivate(), new TestAuthenticatorEncoder(), testTimestamp); String token = testIssuer.buildSignedToken(attestedTicket, validatorDomain); - ObjectDecoder decoder = new TicketDecoder(ticketKeys.getPublic()); + ObjectDecoder decoder = new DevconTicketDecoder(ticketKeys.getPublic()); Eip712ObjectValidator newValidator = new Eip712ObjectValidator(decoder, encoder, validatorDomain); assertFalse(newValidator.validateRequest(token)); } @@ -199,7 +199,7 @@ public void incorrectDomain() throws Exception { @Test public void invalidDomainVerifier() { - ObjectDecoder decoder = new TicketDecoder(ticketKeys.getPublic()); + ObjectDecoder decoder = new DevconTicketDecoder(ticketKeys.getPublic()); assertThrows( RuntimeException.class, () -> { new Eip712ObjectValidator(decoder, encoder, "www.noHttpPrefix.com"); });