From 7410ac59ba8e1994254a872104ea660b992cba9a Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Fri, 28 Jan 2022 17:06:47 +0100 Subject: new dynamic header version --- misc/uicBarcodeHeader_v2.0.0.asn | 25 +- src/main/java/org/uic/barcode/Decoder.java | 44 +++- src/main/java/org/uic/barcode/Encoder.java | 59 ++++- .../dynamicContent/api/IUicDynamicContent.java | 1 - .../fdc1/GeoCoordinateSystemType.java | 1 - .../barcode/dynamicContent/fdc1/GeoUnitType.java | 1 - .../fdc1/HemisphereLatitudeType.java | 1 - .../fdc1/HemisphereLongitudeType.java | 1 - .../dynamicFrame/api/DynamicFrameCoder.java | 107 ++++++++ .../barcode/dynamicFrame/api/IDynamicFrame.java | 75 +++--- .../uic/barcode/dynamicFrame/api/ILevel1Data.java | 60 ++++- .../dynamicFrame/api/SimpleDynamicFrame.java | 183 ++++--------- .../barcode/dynamicFrame/api/SimpleLevel1Data.java | 11 + .../barcode/dynamicFrame/api/SimpleLevel2Data.java | 19 -- .../dynamicFrame/v1/DynamicFrameCoderV1.java | 19 +- .../org/uic/barcode/dynamicFrame/v2/DataType.java | 2 - .../uic/barcode/dynamicFrame/v2/DynamicFrame.java | 2 - .../dynamicFrame/v2/DynamicFrameCoderV2.java | 25 +- .../barcode/dynamicFrame/v2/Level1DataType.java | 41 +-- .../barcode/dynamicFrame/v2/Level2DataType.java | 2 - .../asn1/test/UperEncodeFieldOrderTest.java | 2 - .../asn1/test/UperEncodeIntegerExtensionTest.java | 2 - .../asn1/test/UperEncodeSequenceOfStringTest.java | 2 - .../test/DynamicFrameDynamicContentTest.java | 2 +- .../barcode/test/DynamicFrameFcbVersion1Test.java | 4 +- .../barcode/test/DynamicFrameFcbVersion3Test.java | 4 +- .../test/DynamicFrameV2FcbVersion3Test.java | 4 +- .../test/DynamicFrameV2SignatureInsertTest.java | 289 +++++++++++++++++++++ .../test/DynamicFrameV2ValidityDateTest.java | 10 +- .../uic/barcode/test/utils/DynamicTestContent.java | 2 + 30 files changed, 729 insertions(+), 271 deletions(-) create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameV2SignatureInsertTest.java diff --git a/misc/uicBarcodeHeader_v2.0.0.asn b/misc/uicBarcodeHeader_v2.0.0.asn index 79d104d..e7363b0 100644 --- a/misc/uicBarcodeHeader_v2.0.0.asn +++ b/misc/uicBarcodeHeader_v2.0.0.asn @@ -52,10 +52,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN level2SignedData Level2DataType, -- signature is calculated on the PER unaligned encoding of level2 signature data - level2Signature OCTET STRING OPTIONAL, - ... - - + level2Signature OCTET STRING OPTIONAL } Level2DataType ::= SEQUENCE { @@ -65,8 +62,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN -- signature is calculated on the PER unaligned encoding of level1 signature data level1Signature OCTET STRING OPTIONAL, - level2Data DataType OPTIONAL, - ... + level2Data DataType OPTIONAL } @@ -98,17 +94,21 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN level2SigningAlg OBJECT IDENTIFIER OPTIONAL, level2PublicKey OCTET STRING OPTIONAL, - -- end of the validity of the bar code, after this date and time the bar code needs to be regenerated + -- end of the validity of the bar code, after this date and time the bar code needs to be regenerated + -- by the provider of the ticket -- if end of validity is provided year day and time must be provided. -- year, day, time are in UTC - -- the provider of the bar code must ensure that the end of validity of the bar code is - -- before the end of validity of the key pair used on level 2 + -- the provider of the bar code should ensure that the endOfValidity given here does not exceed + -- the validity of the key pair used on level 2. endOfValidityYear INTEGER (2016..2269) OPTIONAL, -- number of the day in the year (1.1. = 1) endOfValidityDay INTEGER (1..366) OPTIONAL, -- The number of the minutes of the day - endOfValidityTime INTEGER (0..1439) OPTIONAL, - ... + endOfValidityTime INTEGER (0..1439) OPTIONAL, + + -- validity duration in seconds of the bar code shown with reference to the time stamp dynamicContentTimeStamp + -- in the dynamic data included in the level2Data + validityDuration INTEGER (1..3600) OPTIONAL } DataType ::= SEQUENCE { @@ -118,8 +118,7 @@ ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN -- or proprietary: -- _RICS company code + addon dataFormat IA5String, - data OCTET STRING, - ... + data OCTET STRING } diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java index 5cb0546..3d97e0a 100644 --- a/src/main/java/org/uic/barcode/Decoder.java +++ b/src/main/java/org/uic/barcode/Decoder.java @@ -10,11 +10,11 @@ import java.util.zip.DataFormatException; import org.uic.barcode.dynamicContent.api.IUicDynamicContent; import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.dynamicFrame.api.DynamicFrameCoder; import org.uic.barcode.dynamicFrame.api.IData; import org.uic.barcode.dynamicFrame.api.IDynamicFrame; import org.uic.barcode.dynamicFrame.api.ILevel1Data; import org.uic.barcode.dynamicFrame.api.ILevel2Data; -import org.uic.barcode.dynamicFrame.api.SimpleDynamicFrame; import org.uic.barcode.staticFrame.StaticFrame; import org.uic.barcode.staticFrame.UFLEXDataRecord; import org.uic.barcode.staticFrame.UTLAYDataRecord; @@ -80,7 +80,7 @@ public class Decoder { * @throws EncodingFormatException the encoding format exception */ public int validateLevel1(PublicKey key, String signingAlg) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException { - if (!isStaticHeader(data)) { + if (dynamicFrame != null) { return dynamicFrame.validateLevel1(key, data) ; } else { if (staticFrame.verifyByAlgorithmOid(key,signingAlg)) { @@ -158,9 +158,7 @@ public class Decoder { if (!isStaticHeader(data)) { - dynamicFrame = new SimpleDynamicFrame(); - - dynamicFrame.decode(data); + dynamicFrame = DynamicFrameCoder.decode(data); ILevel2Data level2 = dynamicFrame.getLevel2Data(); @@ -229,13 +227,13 @@ public class Decoder { public TicketLayout getLayout() { return layout; } - + /** * Gets the dynamic header. * * @return the dynamic header */ - public IDynamicFrame getDynamicHeader() { + public IDynamicFrame getDynamicFrame() { return dynamicFrame; } @@ -284,7 +282,39 @@ public class Decoder { return null; } + public byte[] getEncodedLevel1Data() throws IOException, EncodingFormatException { + if (!isStaticHeader(data)) { + return dynamicFrame.getLevel1DataBin(); + } else if (staticFrame != null) { + return staticFrame.getDataForSignature(); + } else { + throw new EncodingFormatException("Unknown Header"); + } + } + public byte[] getLevel1Signature() throws IOException, EncodingFormatException { + + if (!isStaticHeader(data)) { + return dynamicFrame.getLevel2Data().getLevel1Signature(); + } else if (staticFrame != null) { + return staticFrame.getDataForSignature(); + } else { + throw new EncodingFormatException("Unknown Header"); + } + } + public String getLevel1KeyId() throws EncodingFormatException { + + if (dynamicFrame != null + && dynamicFrame.getLevel2Data() != null + && dynamicFrame.getLevel2Data().getLevel1Data() != null) { + return dynamicFrame.getLevel2Data().getLevel1Data().getKeyId().toString(); + } else if (staticFrame != null) { + return staticFrame.getSignatureKey(); + } else { + throw new EncodingFormatException("Unknown Header"); + } + + } } diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java index 5f10806..51e86a2 100644 --- a/src/main/java/org/uic/barcode/Encoder.java +++ b/src/main/java/org/uic/barcode/Encoder.java @@ -8,12 +8,16 @@ import java.security.PublicKey; import org.uic.barcode.dynamicContent.api.IUicDynamicContent; import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.dynamicFrame.api.DynamicFrameCoder; import org.uic.barcode.dynamicFrame.api.IData; import org.uic.barcode.dynamicFrame.api.IDynamicFrame; +import org.uic.barcode.dynamicFrame.api.ILevel1Data; import org.uic.barcode.dynamicFrame.api.SimpleData; import org.uic.barcode.dynamicFrame.api.SimpleDynamicFrame; import org.uic.barcode.dynamicFrame.api.SimpleLevel1Data; import org.uic.barcode.dynamicFrame.api.SimpleLevel2Data; +import org.uic.barcode.dynamicFrame.v1.DynamicFrameCoderV1; +import org.uic.barcode.dynamicFrame.v2.DynamicFrameCoderV2; import org.uic.barcode.staticFrame.StaticFrame; import org.uic.barcode.staticFrame.UFLEXDataRecord; import org.uic.barcode.staticFrame.UHEADDataRecord; @@ -116,6 +120,48 @@ public class Encoder { } } + /** + * Instantiates a new encoder for a level 2 encoding. + * + * @param level1Data the level 1 data (binary as signed) + * @param signatureLevel1 the signature of the level 1 data + * @param version the version of the bar code + * @throws IOException Signals that an I/O exception has occurred. + * @throws EncodingFormatException the encoding format exception + */ + public Encoder(byte[] level1DataBin, byte[] signatureLevel1, int version) throws IOException, EncodingFormatException { + + + dynamicFrame = new SimpleDynamicFrame(); + dynamicFrame.setLevel2Data(new SimpleLevel2Data()); + + if (version == 1) { + + dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1); + + ILevel1Data l1 = DynamicFrameCoderV1.decodeLevel1(level1DataBin); + + dynamicFrame.getLevel2Data().setLevel1Data(l1); + + dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1); + + } else if (version == 2) { + + dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2); + + ILevel1Data l1 = DynamicFrameCoderV2.decodeLevel1(level1DataBin); + + dynamicFrame.getLevel2Data().setLevel1Data(l1); + + dynamicFrame.getLevel2Data().setLevel1Signature(signatureLevel1); + + } else { + throw new EncodingFormatException("Version of the dynamic header not supported"); + } + + + } + /** @@ -265,7 +311,6 @@ public class Encoder { dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(signingAlg); dynamicFrame.getLevel2Data().getLevel1Data().setKeyId(Long.parseLong(keyId)); dynamicFrame.signLevel1(key,prov); - //dynamicFrame.getLevel2Data().signLevel1(key, prov); } else if (staticFrame != null) { staticFrame.setSignatureKey(keyId); staticFrame.setSecurityProvider(securityProvider); @@ -321,7 +366,7 @@ public class Encoder { */ public byte[] encode() throws IOException, Exception { if (dynamicFrame != null) { - return dynamicFrame.encode(); + return DynamicFrameCoder.encode(dynamicFrame); } else if (staticFrame != null) { return staticFrame.encode(); } @@ -329,7 +374,15 @@ public class Encoder { } - + public byte[] getEncodedLevel1Data() throws IOException, EncodingFormatException { + if (dynamicFrame != null) { + return DynamicFrameCoder.encodeLevel1(dynamicFrame); + } else if (staticFrame != null) { + return staticFrame.getDataForSignature(); + } else { + throw new EncodingFormatException("Unknown Header"); + } + } diff --git a/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java b/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java index 718d013..3b0afde 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java +++ b/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java @@ -6,7 +6,6 @@ import java.util.List; import org.uic.barcode.ticket.api.spec.IExtension; import org.uic.barcode.ticket.api.spec.IGeoCoordinate; -// TODO: Auto-generated Javadoc /** * The Interface IUicDynamicContent. */ diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java index b25ad1a..700c542 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java @@ -20,7 +20,6 @@ package org.uic.barcode.dynamicContent.fdc1; -// TODO: Auto-generated Javadoc /** * The Enum GeoCoordinateSystemType. */ diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java index 4eaa8c9..591e28a 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java @@ -19,7 +19,6 @@ */ package org.uic.barcode.dynamicContent.fdc1; -// TODO: Auto-generated Javadoc /** * The Enum GeoUnitType. */ diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java index 5157b0e..b39e599 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java @@ -19,7 +19,6 @@ */ package org.uic.barcode.dynamicContent.fdc1; -// TODO: Auto-generated Javadoc /** * The Enum HemisphereLatitudeType. */ diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java index c0e33e6..e1e39f0 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java @@ -19,7 +19,6 @@ */ package org.uic.barcode.dynamicContent.fdc1; -// TODO: Auto-generated Javadoc /** * The Enum HemisphereLongitudeType. */ diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java b/src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java new file mode 100644 index 0000000..53efb3e --- /dev/null +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java @@ -0,0 +1,107 @@ +package org.uic.barcode.dynamicFrame.api; + +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.dynamicFrame.v1.DynamicFrameCoderV1; +import org.uic.barcode.dynamicFrame.v2.DynamicFrameCoderV2; +import org.uic.barcode.ticket.EncodingFormatException; + +public class DynamicFrameCoder { + + /** + * Encode. + * + * Encode the header as ASN.1 PER UNALIGNED byte array + * + * @return the byte[] + * @throws EncodingFormatException + */ + public static byte[] encode(IDynamicFrame frame) throws EncodingFormatException { + + if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(frame.getFormat())) { + + return DynamicFrameCoderV1.encode(frame); + + } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(frame.getFormat())) { + + return DynamicFrameCoderV2.encode(frame); + + } + + throw new EncodingFormatException("Frame version not supported for encoding"); + } + + + /** + * Decode. + * + * Decode the header from an ASN.1 PER UNALIGNED encoded byte array + * + * @param bytes the bytes + * @return the dynamic header + * @throws EncodingFormatException + */ + public static IDynamicFrame decode(byte[] bytes) throws EncodingFormatException { + + IDynamicFrame frame = new SimpleDynamicFrame(); + + try { + DynamicFrameCoderV1.decode(frame,bytes); + + if (frame.getFormat() != null && frame.getFormat().equals(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1)) { + return frame; + } + } catch(Exception e1) { + frame = null; + // failed, try next + } + + frame = new SimpleDynamicFrame(); + try { + DynamicFrameCoderV2.decode(frame,bytes); + + if (frame.getFormat() != null && frame.getFormat().equals(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2)) { + return frame; + } + } catch(Exception e1) { + throw new EncodingFormatException("Dynamic Header Version not supported"); + // failed + } + + throw new EncodingFormatException("Dynamic Header Version not supported"); + + } + + + public static byte[] encodeLevel1(IDynamicFrame frame) throws EncodingFormatException { + + if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(frame.getFormat())) { + + return DynamicFrameCoderV1.encodeLevel1(frame); + + } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(frame.getFormat())) { + + return DynamicFrameCoderV2.encodeLevel1(frame); + + } + + throw new EncodingFormatException("Frame version not supported for encoding"); + + } + + + public static byte[] encodeLevel2Data(IDynamicFrame frame) throws EncodingFormatException { + + if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(frame.getFormat())) { + + return DynamicFrameCoderV1.encodeLevel2Data(frame.getLevel2Data()); + + } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(frame.getFormat())) { + + return DynamicFrameCoderV2.encodeLevel2Data(frame.getLevel2Data()); + + } + + throw new EncodingFormatException("Dynamic Header Version not supported: " + frame.getFormat()); + } + +} diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java index d901a6e..c917b6a 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java @@ -8,9 +8,9 @@ import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; import org.uic.barcode.ticket.EncodingFormatException; + /** - * The DynamicHeader for bar codes - * + * The DynamicHeader for bar codes . */ public interface IDynamicFrame{ @@ -41,7 +41,7 @@ public interface IDynamicFrame{ /** * Sets the level 2 signed data. * - * @param level2SignedData the new level 2 signed data + * @param level2Data the new level 2 data */ public void setLevel2Data(ILevel2Data level2Data); @@ -61,29 +61,6 @@ public interface IDynamicFrame{ */ public void setLevel2Signature(byte[] level2Signature); - - /** - * Encode. - * - * Encode the header as ASN.1 PER UNALIGNED byte array - * - * @return the byte[] - * @throws EncodingFormatException - */ - public byte[] encode() throws EncodingFormatException; - - /** - * Decode. - * - * Decode the header from an ASN.1 PER UNALIGNED encoded byte array - * - * @param bytes the bytes - * @return the dynamic header - * @throws EncodingFormatException - */ - public void decode(byte[] bytes) throws EncodingFormatException; - - /** * Verify the level 2 signature @@ -92,7 +69,7 @@ public interface IDynamicFrame{ * * @param data the data content * @return the return error code - * @throws EncodingFormatException + * @throws EncodingFormatException the encoding format exception */ public int validateLevel2(byte[] data) throws EncodingFormatException; @@ -102,9 +79,9 @@ public interface IDynamicFrame{ * Note: an appropriate security provider (e.g. BC) must be registered before * * @param prov the registered security provider - * @param data the data content + * @param data the data content * @return the return error code - * @throws EncodingFormatException + * @throws EncodingFormatException the encoding format exception */ public int validateLevel2(Provider prov, byte[] data) throws EncodingFormatException; @@ -116,7 +93,7 @@ public interface IDynamicFrame{ * @param key the key * @param data the data content * @return the return error code - * @throws EncodingFormatException + * @throws EncodingFormatException the encoding format exception */ public int validateLevel1(PublicKey key, byte[] data) throws EncodingFormatException; @@ -126,10 +103,10 @@ public interface IDynamicFrame{ * Note: an appropriate security provider (e.g. BC) must be registered before * * @param key the key - * @param prov the registered security provider - * @param the data content + * @param prov the registered security provider + * @param data the data * @return the return error code - * @throws EncodingFormatException + * @throws EncodingFormatException the encoding format exception */ public int validateLevel1(PublicKey key, Provider prov, byte[] data) throws EncodingFormatException; @@ -183,9 +160,8 @@ public interface IDynamicFrame{ * Note: an appropriate security provider (e.g. BC) must be registered before * * @param key the key - * @return * @return the byte[] - * @throws Exception + * @throws Exception the exception */ public void signLevel1(PrivateKey key) throws Exception; @@ -195,13 +171,36 @@ public interface IDynamicFrame{ * Note: an appropriate security provider (e.g. BC) must be registered before * * @param key the key - * @param security provider - security provider that must be sued to create the signature - * @return + * @param prov the prov * @return the byte[] - * @throws Exception + * @throws Exception the exception */ public void signLevel1(PrivateKey key, Provider prov) throws Exception; + + + /** + * Gets the signature of the level 1 data. + * + * @return the level 1 signature + */ + public byte[] getLevel1Signature(); + + + /** + * Gets the level 1 data in binary as they are signed by the level 1 signature. + * + * @return the level 1 data binary + * @throws EncodingFormatException the encoding format exception + */ + public byte[] getLevel1DataBin() throws EncodingFormatException; + /** + * Gets the level 2 data in binary as they are signed by the level 1 signature. + * + * @return the level 2 data binary + * @throws EncodingFormatException the encoding format exception + */ + public byte[] getLevel2DataBin() throws EncodingFormatException; } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java index 206d613..e23fc88 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java @@ -11,15 +11,15 @@ public interface ILevel1Data { /** - * Sets the security provider + * Sets the security provider . * - * @param securityProviderNum the new security provider + * @param securityProvider the new security provider */ public void setSecurityProvider(String securityProvider); /** - * Gets the security provider + * Gets the security provider. * * @return the security provider */ @@ -68,7 +68,7 @@ public interface ILevel1Data { public void addData(IData data); /** - * Gets the level 2 key alg. + * Gets the level 2 key algorithm OID. * * @return the level 2 key alg */ @@ -76,7 +76,7 @@ public interface ILevel1Data { /** - * Sets the level 2 key alg. + * Sets the level 2 key algorithm OID. * * @param level2KeyAlg the new level 2 key alg */ @@ -92,7 +92,7 @@ public interface ILevel1Data { /** - * Sets the level 1 signing alg. + * Sets the level 1 signing algorithm OID. * * @param level1SigningAlg the new level 1 signing alg */ @@ -100,7 +100,7 @@ public interface ILevel1Data { /** - * Gets the level 2 signing alg. + * Gets the level 2 signing algorithm OID. * * @return the level 2 signing alg */ @@ -108,7 +108,7 @@ public interface ILevel1Data { /** - * Sets the level 2 signing alg. + * Sets the level 2 signing algorithm OID. * * @param level2SigningAlg the new level 2 signing alg */ @@ -133,14 +133,14 @@ public interface ILevel1Data { /** - * Gets the level 1 key alg. + * Gets the level 1 key algorithm OID. * * @return the level 1 key alg */ public String getLevel1KeyAlg(); /** - * Sets the level 1 key alg. + * Sets the level 1 key algorithm OID. * * @param level1KeyAlg the new level 1 key alg */ @@ -149,6 +149,13 @@ public interface ILevel1Data { /** * Sets the end of validity date. The validity date has to be provided in UTC. + * + * -- end of the validity of the bar code, after this date and time the bar code needs to be regenerated + * -- by the provider of the ticket + * -- if end of validity is provided year day and time must be provided. + * -- year, day, time are in UTC + * -- the provider of the bar code should ensure that the endOfValidity given here does not exceed + * -- the validity of the key pair used on level 2. * * @param date the new end of validity date */ @@ -156,9 +163,40 @@ public interface ILevel1Data { /** - * Gets the end of validity date. + * Gets the end of validity date and time. + * + * -- end of the validity of the bar code, after this date and time the bar code needs to be regenerated + * -- by the provider of the ticket + * -- if end of validity is provided year day and time must be provided. + * -- year, day, time are in UTC + * -- the provider of the bar code should ensure that the endOfValidity given here does not exceed + * -- the validity of the key pair used on level 2. * * @return the end of validity date */ public Date getEndOfBarcodeValidity(); + + + /** + * Gets the validity duration of the bar code in seconds. + * + * -- validity duration in seconds of the bar code shown with reference to the time stamp dynamicContentTimeStamp + * -- in the dynamic data included in the level2Data + * + * @return the validity duration + */ + public Long getValidityDuration(); + + + /** + * Sets the validity validity duration of the bar code in seconds. + * + * -- validity duration in seconds of the bar code shown with reference to the time stamp dynamicContentTimeStamp + * -- in the dynamic data included in the level2Data + * + * @param validityDuration the new validity duration + */ + public void setValidityDuration(Long validityDuration); + + } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java index 65b81d6..8d53f9a 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java @@ -12,7 +12,7 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Date; -import org.uic.barcode.asn1.uper.AsnUtils; +import org.uic.barcode.asn1.uper.UperEncoder; import org.uic.barcode.dynamicContent.api.DynamicContentCoder; import org.uic.barcode.dynamicContent.api.IUicDynamicContent; import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; @@ -40,7 +40,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { } /** The format. */ - public String format = Constants.DYNAMIC_BARCODE_FORMAT_DEFAULT; + public String format = null; /** The level 2 signed data. */ /*level 2 data*/ @@ -115,136 +115,15 @@ public class SimpleDynamicFrame implements IDynamicFrame { * @throws EncodingFormatException */ public byte[] encode() throws EncodingFormatException { - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { - - return DynamicFrameCoderV1.encode(this); - - } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { - - return DynamicFrameCoderV2.encode(this); - - } - - return null; - } - - private byte[] encode(ILevel1Data level1Data) throws EncodingFormatException { - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { - - return DynamicFrameCoderV1.encode(level1Data); - - } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { - - return DynamicFrameCoderV2.encode(level1Data); - - } - throw new EncodingFormatException("Dynamic Header Version not supported: " + format); - } - - private byte[] getEncoded(String path, byte[] data) throws EncodingFormatException { - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { - - return DynamicFrameCoderV1.getEncoded(path, data); - - } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { - - return DynamicFrameCoderV2.getEncoded(path, data); - - } - throw new EncodingFormatException("Dynamic Header Version not supported: " + format); - } - - - private byte[] encode(ILevel2Data level2Data) throws EncodingFormatException { - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { - - return DynamicFrameCoderV1.encode(level2Data); - - } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { - - return DynamicFrameCoderV2.encode(level2Data); - - } - - throw new EncodingFormatException("Dynamic Header Version not supported: " + format); - } - - /** - * Decode. - * - * Decode the header from an ASN.1 PER UNALIGNED encoded byte array - * - * @param bytes the bytes - * @return the dynamic header - * @throws EncodingFormatException - */ - public void decode(byte[] bytes) throws EncodingFormatException { - - String format = getFormat(bytes); - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { - - DynamicFrameCoderV1.decode(this,bytes); - return; + return DynamicFrameCoder.encode(this); - } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { - - DynamicFrameCoderV2.decode(this,bytes); - return; - } - - throw new EncodingFormatException("Dynamic Header Version not supported"); + } - - /** - * Checks if is static header. - * - * @param data the data - * @return true, if is static header - */ - private static String getFormat(byte[] data) { - - if (data == null || data.length < 4) return null; - - byte[] startBits = new byte[4]; - startBits[0] = data[0]; - startBits[1] = data[1]; - startBits[2] = data[2]; - startBits[3] = data[3]; - - String start = AsnUtils.toBooleanString(startBits); - - /* - * bitshift: - * - * version 1: - * optional Level2Data 1 bit - * length of format: 8 bit - * - * version 2: - * extensionIndicator 1 bit - * optional Level2Data 1 bit - * length of format: 8 bit - */ - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1_BIN.equals(start.substring(9, 23))) { - return Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1; - } - - if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2_BIN.equals(start.substring(10, 24))) { - return Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2; - } - return null; - } /** * Verify the level 2 signature @@ -334,13 +213,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { } try { - //TODO - //byte[] signedData = encode(level2Data); - //String s1 = AsnUtils.toBooleanString(signedData); - - byte[] signedData2 = getEncoded("Level2Data", data); - //String s2 = AsnUtils.toBooleanString(signedData); - + byte[] signedData2 = getLevel2DataBin(); sig.update(signedData2); } catch (SignatureException e) { return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED; @@ -416,7 +289,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { try { - byte[] encodedData = getEncoded("Level1Data", data); + byte[] encodedData = getLevel1DataBin(); sig.update(encodedData); @@ -489,7 +362,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { sig = Signature.getInstance(algo); } sig.initSign(key); - byte[] signedData = encode(level2Data); + byte[] signedData = DynamicFrameCoder.encodeLevel2Data(this); sig.update(signedData); level2Signature = sig.sign(); @@ -584,9 +457,49 @@ public class SimpleDynamicFrame implements IDynamicFrame { } sig.initSign(key); - byte[] data = encode(level1Data); + byte[] data = DynamicFrameCoder.encodeLevel1(this); sig.update(data); level2Data.setLevel1Signature(sig.sign()); } + + @Override + public byte[] getLevel1Signature() { + return getLevel2Data().getLevel1Signature(); + } + + @Override + public byte[] getLevel1DataBin() throws EncodingFormatException { + + if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { + + return DynamicFrameCoderV1.encode(getLevel2Data().getLevel1Data()); + + } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { + + return DynamicFrameCoderV2.encode(getLevel2Data().getLevel1Data()); + + } + + throw new EncodingFormatException("Dynamic Header Version not supported"); + + } + + + public byte[] getLevel2DataBin() throws EncodingFormatException { + + if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) { + + return DynamicFrameCoderV1.encodeLevel2Data(getLevel2Data()); + + } else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) { + + return DynamicFrameCoderV2.encodeLevel2Data(getLevel2Data()); + + } + + throw new EncodingFormatException("Dynamic Header Version not supported"); + + } + } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java index e9b1d4e..f42ff98 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java @@ -63,6 +63,7 @@ public class SimpleLevel1Data implements ILevel1Data { public Date endOfBarcodeValidity = null; + public Long validityDuration = null; @@ -250,4 +251,14 @@ public class SimpleLevel1Data implements ILevel1Data { dataList.add(data); } + + public Long getValidityDuration() { + return validityDuration; + } + + public void setValidityDuration(Long validityDuration) { + this.validityDuration = validityDuration; + } + + } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java index 395db4d..17e71db 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java @@ -2,15 +2,10 @@ package org.uic.barcode.dynamicFrame.api; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; -import org.uic.barcode.asn1.datatypes.Sequence; -import org.uic.barcode.asn1.uper.UperEncoder; /** * The Class DataType. */ -@Sequence -@HasExtensionMarker public class SimpleLevel2Data implements ILevel2Data { @FieldOrder(order = 0) @@ -56,20 +51,6 @@ public class SimpleLevel2Data implements ILevel2Data { public void setLevel2Data(IData level2Data) { this.level2Data = level2Data; } - - - /** - * Encode. - * - * Encode the header as ASN.1 PER UNALIGNED byte array - * - * @return the byte[] - */ - public byte[] encode() { - return UperEncoder.encode(this); - } - - } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java index 39fcf32..71de58e 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java @@ -3,6 +3,7 @@ package org.uic.barcode.dynamicFrame.v1; import org.uic.barcode.asn1.datatypesimpl.OctetString; import org.uic.barcode.asn1.uper.UperEncoder; import org.uic.barcode.dynamicFrame.v1.DynamicFrame; +import org.uic.barcode.dynamicFrame.v1.Level1DataType; import org.uic.barcode.ticket.EncodingFormatException; import org.uic.barcode.dynamicFrame.api.IData; import org.uic.barcode.dynamicFrame.api.IDynamicFrame; @@ -30,6 +31,14 @@ public class DynamicFrameCoderV1 { } } + + public static ILevel1Data decodeLevel1(byte[] bytes) { + + Level1DataType asnData = UperEncoder.decode(bytes,Level1DataType.class); + + return populateApi(asnData); + + } private static void populateApi(ILevel2Data level2, Level2DataType asnLevel2) { @@ -113,7 +122,7 @@ public class DynamicFrameCoderV1 { } - public static byte[] encode(ILevel2Data level2Data) throws EncodingFormatException { + public static byte[] encodeLevel2Data(ILevel2Data level2Data) throws EncodingFormatException { Level2DataType asn = populateAsn(level2Data); @@ -198,6 +207,14 @@ public class DynamicFrameCoderV1 { } + public static byte[] encodeLevel1(IDynamicFrame frame) throws EncodingFormatException { + + Level1DataType asnLevel1Data = populateAsn(frame.getLevel2Data().getLevel1Data()); + + return UperEncoder.encode(asnLevel1Data); + + } + diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java index f94b622..d4f3c15 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java @@ -1,7 +1,6 @@ package org.uic.barcode.dynamicFrame.v2; import org.uic.barcode.asn1.datatypes.CharacterRestriction; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.datatypesimpl.OctetString; @@ -11,7 +10,6 @@ import org.uic.barcode.asn1.uper.UperEncoder; * The Class DataType. */ @Sequence -@HasExtensionMarker public class DataType { diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java index 2986f75..4831c6a 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java @@ -14,7 +14,6 @@ import java.security.spec.X509EncodedKeySpec; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.CharacterRestriction; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.datatypesimpl.OctetString; @@ -33,7 +32,6 @@ import org.uic.barcode.utils.AlgorithmNameResolver; * Implementation of the Draft under discussion, not final. */ @Sequence -@HasExtensionMarker public class DynamicFrame extends Object{ /** diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java index de475a9..5d980dd 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java @@ -34,11 +34,20 @@ public class DynamicFrameCoderV2 { } } + + public static ILevel1Data decodeLevel1(byte[] bytes) { + + Level1DataType asnData = UperEncoder.decode(bytes,Level1DataType.class); + + return populateApi(asnData); + + } + private static void populateApi(ILevel2Data level2, Level2DataType asnLevel2) { if (asnLevel2 == null) return; - + level2.setLevel1Signature(asnLevel2.getLevel1SignatureBytes()); if (asnLevel2.getLevel1Data() != null) { @@ -89,6 +98,8 @@ public class DynamicFrameCoderV2 { level1.setEndOfBarcodeValidity(asnLevel1.getEndOfValidityDate()); } + level1.setValidityDuration(asnLevel1.getValidityDuration()); + return level1; } @@ -109,7 +120,7 @@ public class DynamicFrameCoderV2 { return UperEncoder.encode(asn); } - public static byte[] encode(ILevel2Data level2SignedData) throws EncodingFormatException { + public static byte[] encodeLevel2Data(ILevel2Data level2SignedData) throws EncodingFormatException { Level2DataType asn = populateAsn(level2SignedData); @@ -194,6 +205,8 @@ public class DynamicFrameCoderV2 { asnLevel1.setEndOfValidityDate(level1.getEndOfBarcodeValidity()); + asnLevel1.setValidityDuration(level1.getValidityDuration()); + return asnLevel1; } @@ -208,6 +221,14 @@ public class DynamicFrameCoderV2 { return null; } + + public static byte[] encodeLevel1(IDynamicFrame frame) throws EncodingFormatException { + + Level1DataType asnLevel1Data = populateAsn(frame.getLevel2Data().getLevel1Data()); + + return UperEncoder.encode(asnLevel1Data); + + } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java index 63db364..b42e9dc 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java @@ -7,7 +7,6 @@ import java.util.TimeZone; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.CharacterRestriction; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; import org.uic.barcode.asn1.datatypes.IntRange; import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; @@ -16,12 +15,10 @@ import org.uic.barcode.asn1.uper.UperEncoder; import org.uic.barcode.ticket.EncodingFormatException; import org.uic.barcode.ticket.api.utils.UicEncoderUtils; -// TODO: Auto-generated Javadoc /** * The Class SignedDataType. */ @Sequence -@HasExtensionMarker public class Level1DataType { /** @@ -100,18 +97,22 @@ public class Level1DataType { /** The End of validity year. */ @FieldOrder(order = 9) @IntRange(minValue=2016,maxValue=2269) - @Asn1Optional public Long EndOfValidityYear; + @Asn1Optional public Long endOfValidityYear; /** The End of validity day. */ @FieldOrder(order = 10) @IntRange(minValue=1,maxValue=366) - @Asn1Optional public Long EndOfValidityDay; + @Asn1Optional public Long endOfValidityDay; /** The End of validity time. */ @FieldOrder(order = 11) @IntRange(minValue=0,maxValue=1439) - @Asn1Optional public Long EndOfValidityTime; + @Asn1Optional public Long endOfValidityTime; + /** The validity duration in seconds. */ + @FieldOrder(order = 12) + @IntRange(minValue=1,maxValue=3600) + @Asn1Optional public Long validityDuration; @@ -322,11 +323,11 @@ public class Level1DataType { Calendar cal = Calendar.getInstance(); cal.setTime(date); - this.EndOfValidityYear = new Long( cal.get(Calendar.YEAR)); - this.EndOfValidityDay = new Long (cal.get(Calendar.DAY_OF_YEAR)); + this.endOfValidityYear = new Long( cal.get(Calendar.YEAR)); + this.endOfValidityDay = new Long (cal.get(Calendar.DAY_OF_YEAR)); int time = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE); if (time >= 0) { - this.EndOfValidityTime = new Long (time ); + this.endOfValidityTime = new Long (time ); } TimeZone.setDefault(local); @@ -339,7 +340,7 @@ public class Level1DataType { */ public Date getEndOfValidityDate() { - if (this.EndOfValidityYear == null || this.EndOfValidityDay == null) return null; + if (this.endOfValidityYear == null || this.endOfValidityDay == null) return null; TimeZone local = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); @@ -347,13 +348,13 @@ public class Level1DataType { Calendar cal = Calendar.getInstance(); cal.clear(); cal.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.set(Calendar.YEAR, this.EndOfValidityYear.intValue()); - cal.set(Calendar.DAY_OF_YEAR, this.EndOfValidityDay.intValue()); + cal.set(Calendar.YEAR, this.endOfValidityYear.intValue()); + cal.set(Calendar.DAY_OF_YEAR, this.endOfValidityDay.intValue()); - if (this.EndOfValidityTime != null) { + if (this.endOfValidityTime != null) { - int hours = this.EndOfValidityTime.intValue() / 60; - int minutes = this.EndOfValidityTime.intValue() % 60; + int hours = this.endOfValidityTime.intValue() / 60; + int minutes = this.endOfValidityTime.intValue() % 60; cal.set(Calendar.HOUR_OF_DAY, hours); cal.set(Calendar.MINUTE,minutes); @@ -365,6 +366,16 @@ public class Level1DataType { return d; } + + + + public Long getValidityDuration() { + return validityDuration; + } + + public void setValidityDuration(Long validityDuration) { + this.validityDuration = validityDuration; + } /** * Gets the data for signature. diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java index 6534c4d..cd0800e 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java @@ -6,7 +6,6 @@ import java.security.Signature; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.datatypesimpl.OctetString; import org.uic.barcode.asn1.uper.UperEncoder; @@ -16,7 +15,6 @@ import org.uic.barcode.utils.AlgorithmNameResolver; * The Class DataType. */ @Sequence -@HasExtensionMarker public class Level2DataType { @FieldOrder(order = 0) diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeFieldOrderTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeFieldOrderTest.java index 5a23f24..d86b4cd 100644 --- a/src/test/java/org/uic/barcode/asn1/test/UperEncodeFieldOrderTest.java +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeFieldOrderTest.java @@ -2,8 +2,6 @@ package org.uic.barcode.asn1.test; import static org.junit.Assert.assertEquals; -import java.util.logging.Level; - import org.junit.Test; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.CharacterRestriction; diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeIntegerExtensionTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeIntegerExtensionTest.java index d0acd20..acec756 100644 --- a/src/test/java/org/uic/barcode/asn1/test/UperEncodeIntegerExtensionTest.java +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeIntegerExtensionTest.java @@ -2,8 +2,6 @@ package org.uic.barcode.asn1.test; import static org.junit.Assert.assertEquals; -import java.util.logging.Level; - import org.junit.Test; import org.uic.barcode.asn1.datatypes.Asn1BigInteger; import org.uic.barcode.asn1.datatypes.FieldOrder; diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeSequenceOfStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeSequenceOfStringTest.java index f8eccc6..f3bff6d 100644 --- a/src/test/java/org/uic/barcode/asn1/test/UperEncodeSequenceOfStringTest.java +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeSequenceOfStringTest.java @@ -5,9 +5,7 @@ import static org.junit.Assert.assertEquals; import java.util.logging.Level; import org.junit.Test; -import org.uic.barcode.asn1.datatypes.CharacterRestriction; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.datatypesimpl.SequenceOfStringIA5; import org.uic.barcode.asn1.uper.UperEncoder; diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java index 4cfca12..d26ab77 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java @@ -218,7 +218,7 @@ public class DynamicFrameDynamicContentTest { assert(level2check == Constants.LEVEL2_VALIDATION_OK); - IUicDynamicContent dynamicData = dec.getDynamicHeader().getDynamicContent(); + IUicDynamicContent dynamicData = dec.getDynamicFrame().getDynamicContent(); assert(dynamicData.getChallengeString().equals("CHALLENGE")); diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java index 861fc85..ea95a88 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java @@ -143,9 +143,9 @@ public class DynamicFrameFcbVersion1Test { assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - assert(dec.getDynamicHeader().getFormat().equals("U1")); + assert(dec.getDynamicFrame().getFormat().equals("U1")); - for (IData data : dec.getDynamicHeader().getLevel2Data().getLevel1Data().getData()) { + for (IData data : dec.getDynamicFrame().getLevel2Data().getLevel1Data().getData()) { assert(data.getFormat().equals("FCB1") ); } diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java index fa055dc..4095d93 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java @@ -143,9 +143,9 @@ public class DynamicFrameFcbVersion3Test { assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - assert(dec.getDynamicHeader().getFormat().equals("U1")); + assert(dec.getDynamicFrame().getFormat().equals("U1")); - for (IData data : dec.getDynamicHeader().getLevel2Data().getLevel1Data().getData()) { + for (IData data : dec.getDynamicFrame().getLevel2Data().getLevel1Data().getData()) { assert(data.getFormat().equals("FCB3") ); } diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameV2FcbVersion3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameV2FcbVersion3Test.java index 8014b78..17bccd6 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameV2FcbVersion3Test.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameV2FcbVersion3Test.java @@ -143,9 +143,9 @@ public class DynamicFrameV2FcbVersion3Test { assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - assert(dec.getDynamicHeader().getFormat().equals("U2")); + assert(dec.getDynamicFrame().getFormat().equals("U2")); - for (IData data : dec.getDynamicHeader().getLevel2Data().getLevel1Data().getData()) { + for (IData data : dec.getDynamicFrame().getLevel2Data().getLevel1Data().getData()) { assert(data.getFormat().equals("FCB3") ); } diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameV2SignatureInsertTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameV2SignatureInsertTest.java new file mode 100644 index 0000000..8f97574 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameV2SignatureInsertTest.java @@ -0,0 +1,289 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.TimeZone; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.DynamicTestContent; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameV2SignatureInsertTest { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPairLevel1 = null; + public KeyPair keyPairLevel2 = null; + + public byte[] passIdHash = "PassId".getBytes(); + public byte[] phoneIdHash = "myPhone".getBytes(); + + public IUicRailTicket testFCBticket = null; + + ZonedDateTime originalTimeStamp = ZonedDateTime.now(ZoneId.of("UTC")); + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPairLevel1 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + keyPairLevel2 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + } catch (Exception e) { + assert(false); + } + + + assert(keyPairLevel1 != null); + assert(keyPairLevel2 != null); + + } + + + @Test public void testDynamicHeaderBarcodeDecoding() { + + //--------------------------------------------------------------------------- + //create barcode data + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 2, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + assert(enc != null); + + //complete level 1 data + enc.setLevel1Algs(signatureAlgorithmOID, keyPairAlgorithmOID); + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID,keyPairLevel2.getPublic()); + enc.getDynamicFrame().getLevel2Data().getLevel1Data().setEndOfBarcodeValidity(getUtcDate("2021.03.04-12:30")); + enc.getDynamicFrame().getLevel2Data().getLevel1Data().setValidityDuration(100L); + + + //sign level 1 data + try { + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + // encode + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + assert(encoded != null); + + + + //---------------------------------------------------------------------------------------------- + //decode and check level 1 + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + String keyId = null; + try { + keyId = dec.getLevel1KeyId(); + } catch (EncodingFormatException e3) { + assert(false); + } + assert(keyId != null); + + + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + + + + + //-------------------------------------------------------------------------------------------------- + // get encoded level 1 data + // add level 2 data and signature + + + byte[] signatureLevel1Data = enc.getDynamicFrame().getLevel2Data().getLevel1Signature(); + byte[] encodedLevel1Data = null; + try { + encodedLevel1Data = enc.getEncodedLevel1Data(); + } catch (IOException e2) { + assert(false); + } catch (EncodingFormatException e2) { + assert(false); + } + + + + //dynamic barcode creation + + //------------------------------------------------------------------------------- + //add the signed level 1 data for encoding of level 2 + try { + enc = new Encoder(encodedLevel1Data,signatureLevel1Data , 2); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + + //set dynamic content + try { + enc.setDynamicData(DynamicTestContent.createDynamicTestContent()); + } catch (EncodingFormatException e1) { + assert(false); + } + //----------- + // sign level 2 + try { + enc.signLevel2(keyPairLevel2.getPrivate()); + } catch (Exception e) { + assert(false); + } + + //------------------------ + //encode complete bar code + encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + assert(encoded != null); + + //---------------------------------------------------------------------------------------------------- + //decode full bar code + + dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + //--------------------------------------------------------------------------------------------------- + //check level 1 signature + + signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + //-------------------------------------------------------------------------------------------------------- + //check level 2 signature + + signatureCheck = 0; + try { + signatureCheck = dec.validateLevel2(); + } catch (Exception e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL2_VALIDATION_OK); + + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + + } + + public Date getUtcDate(String s) { + + TimeZone local = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + Date date = null; + try { + date = new SimpleDateFormat( "yyyy.MM.dd-HH:mm" ).parse(s); + } catch (ParseException e1) { + assert(false); + } + TimeZone.setDefault(local); + + return date; + + } + + public String formatUTC(Date date) { + + TimeZone local = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + String dateS = new SimpleDateFormat( "yyyy.MM.dd-HH:mm" ).format(date); + TimeZone.setDefault(local); + return dateS; + + } + + +} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameV2ValidityDateTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameV2ValidityDateTest.java index 03536c4..9bbd736 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameV2ValidityDateTest.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameV2ValidityDateTest.java @@ -87,6 +87,7 @@ public class DynamicFrameV2ValidityDateTest { TimeZone.setDefault(local); enc.getDynamicFrame().getLevel2Data().getLevel1Data().setEndOfBarcodeValidity(endDate); + enc.getDynamicFrame().getLevel2Data().getLevel1Data().setValidityDuration(100L); try { enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); @@ -132,6 +133,7 @@ public class DynamicFrameV2ValidityDateTest { TimeZone.setDefault(local); enc.getDynamicFrame().getLevel2Data().getLevel1Data().setEndOfBarcodeValidity(endDate); + enc.getDynamicFrame().getLevel2Data().getLevel1Data().setValidityDuration(100L); try { enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); @@ -171,13 +173,13 @@ public class DynamicFrameV2ValidityDateTest { assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - assert(dec.getDynamicHeader().getFormat().equals("U2")); + assert(dec.getDynamicFrame().getFormat().equals("U2")); - for (IData data : dec.getDynamicHeader().getLevel2Data().getLevel1Data().getData()) { + for (IData data : dec.getDynamicFrame().getLevel2Data().getLevel1Data().getData()) { assert(data.getFormat().equals("FCB3") ); } - Date endDate2 = dec.getDynamicHeader().getLevel2Data().getLevel1Data().getEndOfBarcodeValidity(); + Date endDate2 = dec.getDynamicFrame().getLevel2Data().getLevel1Data().getEndOfBarcodeValidity(); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); @@ -186,6 +188,8 @@ public class DynamicFrameV2ValidityDateTest { assert("2021.03.04-12:30".equals(date2)); + assert(100L == dec.getDynamicFrame().getLevel2Data().getLevel1Data().getValidityDuration()); + } public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ diff --git a/src/test/java/org/uic/barcode/test/utils/DynamicTestContent.java b/src/test/java/org/uic/barcode/test/utils/DynamicTestContent.java index a39b270..9380372 100644 --- a/src/test/java/org/uic/barcode/test/utils/DynamicTestContent.java +++ b/src/test/java/org/uic/barcode/test/utils/DynamicTestContent.java @@ -35,4 +35,6 @@ public class DynamicTestContent { return dc; } + + } -- cgit v1.2.3