summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCGantert345 <57003061+CGantert345@users.noreply.github.com>2022-01-28 17:06:47 +0100
committerCGantert345 <57003061+CGantert345@users.noreply.github.com>2022-01-28 17:06:47 +0100
commit7410ac59ba8e1994254a872104ea660b992cba9a (patch)
tree049814e34b34a6a8688a79db1d97055b51ae4cc3
parenttest for the new dynamic header version 2 (diff)
downloadUIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar.gz
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar.bz2
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar.lz
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar.xz
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.tar.zst
UIC-barcode-7410ac59ba8e1994254a872104ea660b992cba9a.zip
-rw-r--r--misc/uicBarcodeHeader_v2.0.0.asn25
-rw-r--r--src/main/java/org/uic/barcode/Decoder.java44
-rw-r--r--src/main/java/org/uic/barcode/Encoder.java59
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java1
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoCoordinateSystemType.java1
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/GeoUnitType.java1
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLatitudeType.java1
-rw-r--r--src/main/java/org/uic/barcode/dynamicContent/fdc1/HemisphereLongitudeType.java1
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java107
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java75
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java60
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java183
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java11
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java19
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java19
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java25
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java41
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java2
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeFieldOrderTest.java2
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeIntegerExtensionTest.java2
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeSequenceOfStringTest.java2
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java2
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java4
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java4
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameV2FcbVersion3Test.java4
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameV2SignatureInsertTest.java289
-rw-r--r--src/test/java/org/uic/barcode/test/DynamicFrameV2ValidityDateTest.java10
-rw-r--r--src/test/java/org/uic/barcode/test/utils/DynamicTestContent.java2
30 files changed, 729 insertions, 271 deletions
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;
}
+
+
}