summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/uic/barcode/dynamicFrame
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/uic/barcode/dynamicFrame')
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/Constants.java5
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java337
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java107
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/IData.java39
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java225
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java202
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/ILevel2Data.java25
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java52
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java499
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java264
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java56
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/package.html9
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java (renamed from src/main/java/org/uic/barcode/dynamicFrame/DataType.java)5
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java229
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java221
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java (renamed from src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java)2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/Level2DataType.java74
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java (renamed from src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java)2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java96
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java230
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java235
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java392
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java (renamed from src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java)2
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/v2/SequenceOfDataType.java25
24 files changed, 2983 insertions, 350 deletions
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
index 8f47986..3623817 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
@@ -36,4 +36,9 @@ public class Constants {
public static int LEVEL1_VALIDATION_KEY_ALG_NOT_IMPLEMENTED = 5;
public static int LEVEL1_VALIDATION_ENCODING_ERROR = 6;
+ public static String DYNAMIC_BARCODE_FORMAT_VERSION_1 = "U1";
+ public static String DYNAMIC_BARCODE_FORMAT_VERSION_2 = "U2";
+
+ public static String DYNAMIC_BARCODE_FORMAT_VERSION_1_BIN = "10101010110001";
+ public static String DYNAMIC_BARCODE_FORMAT_VERSION_2_BIN = "10101010110010";
}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
deleted file mode 100644
index c74215d..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
+++ /dev/null
@@ -1,337 +0,0 @@
-package org.uic.barcode.dynamicFrame;
-
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.spec.InvalidKeySpecException;
-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.RestrictedString;
-import org.uic.barcode.asn1.datatypes.Sequence;
-import org.uic.barcode.asn1.datatypesimpl.OctetString;
-import org.uic.barcode.asn1.uper.UperEncoder;
-import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
-import org.uic.barcode.utils.AlgorithmNameResolver;
-
-
-/**
- * The DynamicHeader for bar codes
- *
- * Implementation of the Draft under discussion, not final.
- */
-@Sequence
-public class DynamicFrame extends Object{
-
- public DynamicFrame() {}
-
- /** The format. */
- @FieldOrder(order = 0)
- @RestrictedString(CharacterRestriction.IA5String)
- public String format;
-
- /*level 2 data*/
- @FieldOrder(order = 1)
- Level2DataType level2SignedData;
-
-
- /** The signature of level 2 data*/
- @FieldOrder(order = 2)
- @Asn1Optional public OctetString level2Signature;
-
- /**
- * Gets the format.
- *
- * @return the format
- */
- public String getFormat() {
- return format;
- }
-
- /**
- * Sets the format.
- *
- * @param format the new format
- */
- public void setFormat(String format) {
- this.format = format;
- }
-
- public Level2DataType getLevel2SignedData() {
- return level2SignedData;
- }
-
- public void setLevel2SignedData(Level2DataType level2SignedData) {
- this.level2SignedData = level2SignedData;
- }
-
- public OctetString getLevel2Signature() {
- return level2Signature;
- }
-
- public void setLevel2Signature(OctetString level2Signature) {
- this.level2Signature = level2Signature;
- }
-
- /**
- * Encode.
- *
- * Encode the header as ASN.1 PER UNALIGNED byte array
- *
- * @return the byte[]
- */
- public byte[] encode() {
- return UperEncoder.encode(this);
- }
-
- /**
- * Decode.
- *
- * Decode the header from an ASN.1 PER UNALIGNED encoded byte array
- *
- * @param bytes the bytes
- * @return the dynamic header
- */
- public static DynamicFrame decode(byte[] bytes) {
- return UperEncoder.decode(bytes, DynamicFrame.class);
- }
-
- /**
- * Verify the level 2 signature
- *
- * Note: an appropriate security provider (e.g. BC) must be registered before
- *
- */
- public int validateLevel2() {
-
- return validateLevel2(null);
-
- }
-
- /**
- * Verify the level 2 signature
- *
- * Note: an appropriate security provider (e.g. BC) must be registered before
- *
- */
- public int validateLevel2(Provider prov) {
-
-
- String level2KeyAlg = this.getLevel2SignedData().getLevel1Data().level2KeyAlg;
-
-
- if (level2KeyAlg == null || level2KeyAlg.length() == 0) {
- return Constants.LEVEL2_VALIDATION_NO_KEY;
- }
-
- if (this.level2Signature.toByteArray() == null || this.level2Signature.toByteArray().length == 0) {
- return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
- }
-
- String keyAlgName = null;
- try {
- keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg);
- } catch (Exception e1) {
- return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
- }
- if (keyAlgName == null || keyAlgName.length() == 0) {
- return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
- }
-
- PublicKey key = null;
- try {
- byte[] keyBytes = this.getLevel2SignedData().getLevel1Data().level2publicKey.toByteArray();
- X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
- key = KeyFactory.getInstance(keyAlgName).generatePublic(keySpec);
- } catch (InvalidKeySpecException e1) {
- return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
- } catch (NoSuchAlgorithmException e1) {
- return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
- }
-
- //find the algorithm name for the signature OID
- String level2SigAlg = this.getLevel2SignedData().getLevel1Data().level2SigningAlg;
-
- String sigAlgName = null;
- try {
- sigAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,level2SigAlg);
- } catch (Exception e1) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- if (sigAlgName == null) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
-
- Signature sig;
- try {
- if (prov == null) {
- sig = Signature.getInstance(sigAlgName);
- } else {
- sig = Signature.getInstance(sigAlgName, prov);
- }
- } catch (NoSuchAlgorithmException e) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- try {
- sig.initVerify(key);
- } catch (InvalidKeyException e) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
-
- try {
- byte[] data = UperEncoder.encode(level2SignedData);
- sig.update(data);
- } catch (SignatureException e) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- } catch (IllegalArgumentException e) {
- return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
- } catch (UnsupportedOperationException e) {
- return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
- }
-
- byte[] signature = level2Signature.toByteArray();
- try {
- if (sig.verify(signature)){
- return Constants.LEVEL2_VALIDATION_OK;
- } else {
- return Constants.LEVEL2_VALIDATION_FRAUD;
- }
- } catch (SignatureException e) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- }
-
- /**
- * Verify the level 1 signature
- *
- * Note: an appropriate security provider (e.g. BC) must be registered before
- *
- */
- public int validateLevel1(PublicKey key, Provider prov) {
-
- if (this.level2SignedData == null) {
- return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
- }
-
-
- if (this.level2SignedData.level1Signature == null || this.level2SignedData.level1Signature.toByteArray().length == 0) {
- return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
- }
-
- byte[] signature = this.getLevel2SignedData().level1Signature.toByteArray();
-
- //find the algorithm name for the signature OID
- String algo = null;
- try {
- algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel2SignedData().getLevel1Data().level1SigningAlg);
- } catch (Exception e1) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- if (algo == null) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
-
- Signature sig;
- try {
- if (prov != null) {
- sig = Signature.getInstance(algo, prov);
- } else {
- sig = Signature.getInstance(algo);
-
- }
- } catch (NoSuchAlgorithmException e) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- try {
- sig.initVerify(key);
- } catch (InvalidKeyException e) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
-
- try {
- sig.update(this.level2SignedData.level1Data.encode());
- } catch (SignatureException e) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- } catch (IllegalArgumentException e) {
- return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
- } catch (UnsupportedOperationException e) {
- return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
- }
-
-
- try {
- if (sig.verify(signature)){
- return Constants.LEVEL2_VALIDATION_OK;
- } else {
- return Constants.LEVEL2_VALIDATION_FRAUD;
- }
- } catch (SignatureException e) {
- return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
- }
- }
-
- /**
- * Verify the level 1 signature
- *
- * Note: an appropriate security provider (e.g. BC) must be registered before
- *
- */
- public int validateLevel1(PublicKey key) {
-
- return validateLevel1(key, null);
-
- }
-
- public void signLevel2(PrivateKey key) throws Exception {
-
- //find the algorithm name for the signature OID
- String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
- Signature sig = Signature.getInstance(algo);
- sig.initSign(key);
- byte[] data = level2SignedData.encode();
- sig.update(data);
- byte[] signature = sig.sign();
- this.level2Signature = new OctetString(signature);
-
- }
-
- public void signLevel2(PrivateKey key, Provider prov) throws Exception {
-
- //find the algorithm name for the signature OID
- String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
- Signature sig = Signature.getInstance(algo,prov);
- sig.initSign(key);
- byte[] data = level2SignedData.encode();
- sig.update(data);
- this.level2Signature = new OctetString(sig.sign());
-
- }
-
-
- public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
- this.getLevel2SignedData().setLevel2Data( dynamicData.getDataType());
- }
-
- public UicDynamicContentDataFDC1 getDynamicDataFDC1() {
-
- if (this.getLevel2SignedData() == null ||
- this.getLevel2SignedData().getLevel2Data() == null){
- return null;
- }
-
- if ( UicDynamicContentDataFDC1.getFormat().equals(this.getLevel2SignedData().getLevel2Data().getFormat())) {
- return UperEncoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData(), UicDynamicContentDataFDC1.class);
- }
- return null;
-
- }
-
-
-}
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/IData.java b/src/main/java/org/uic/barcode/dynamicFrame/api/IData.java
new file mode 100644
index 0000000..51f9c7b
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IData.java
@@ -0,0 +1,39 @@
+package org.uic.barcode.dynamicFrame.api;
+
+/**
+ * The Class DataType.
+ */
+public interface IData {
+
+
+
+
+ /**
+ * Gets the data format.
+ *
+ * @return the data format
+ */
+ public String getFormat();
+
+ /**
+ * Sets the data format.
+ *
+ * @param dataFormat the new data format
+ */
+ public void setFormat(String format);
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public byte[] getData();
+
+ /**
+ * Sets the data.
+ *
+ * @param data the new data
+ */
+ public void setData(byte[] data);
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
new file mode 100644
index 0000000..4b2d1f4
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
@@ -0,0 +1,225 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import org.uic.barcode.dynamicContent.api.IUicDynamicContent;
+import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
+import org.uic.barcode.ticket.EncodingFormatException;
+
+
+
+/**
+ * The DynamicHeader for bar codes .
+ */
+public interface IDynamicFrame{
+
+
+
+ /**
+ * Gets the format.
+ *
+ * @return the format
+ */
+ public String getFormat();
+
+
+ /**
+ * Sets the format.
+ *
+ * @param format the new format
+ */
+ public void setFormat(String format);
+
+ /**
+ * Gets the level 2 signed data.
+ *
+ * @return the level 2 signed data
+ */
+ public ILevel2Data getLevel2Data();
+
+ /**
+ * Sets the level 2 signed data.
+ *
+ * @param level2Data the new level 2 data
+ */
+ public void setLevel2Data(ILevel2Data level2Data);
+
+
+ /**
+ * Gets the level 2 signature.
+ *
+ * @return the level 2 signature
+ */
+ public byte[] getLevel2Signature();
+
+
+ /**
+ * Sets the level 2 signature.
+ *
+ * @param level2Signature the new level 2 signature
+ */
+ public void setLevel2Signature(byte[] level2Signature);
+
+
+ /**
+ * Verify the level 2 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel2() throws EncodingFormatException;
+
+ /**
+ * Verify the level 2 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param prov the registered security provider
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel2(Provider prov) throws EncodingFormatException;
+
+ /**
+ * Verify the level 1 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the key
+ * @param data the data content
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel1(PublicKey key) throws EncodingFormatException;
+
+ /**
+ * Verify the level 1 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the key
+ * @param signatureAlgorithmOid the signature algorithmOid to be used in case it is not contained in the barcode
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel1(PublicKey key,String signatureAlgorithmOid) throws EncodingFormatException;
+
+
+ /**
+ * Verify the level 1 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the key
+ * @param prov the registered security provider
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException;
+
+ /**
+ * Verify the level 1 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the key
+ * @param prov the registered security provider
+ * @return the return error code
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public int validateLevel1(PublicKey key, Provider prov, String signatureAlgorithmOid) throws EncodingFormatException;
+
+ /**
+ * Sign level 2 data without a specific security provider.
+ *
+ * @param key the key
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key) throws Exception;
+
+
+ /**
+ * Sign level 2 data.
+ *
+ * @param key the key
+ * @param prov the security Provider
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key, Provider prov) throws Exception;
+
+
+ /**
+ * Adds the dynamic content and encodes it. (API level)
+ *
+ * @param content the dynamic content
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException;
+
+
+ /**
+ * Adds the level 2 dynamic data. (ASN level)
+ *
+ * @param dynamicData the dynamic data
+ */
+ public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData);
+
+ /**
+ * Gets the dynamic content.
+ *
+ * @return the dynamic content
+ */
+ public IUicDynamicContent getDynamicContent();
+
+
+ /**
+ * Sign the contained data block.
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the private key
+ * @return the signature
+ * @throws Exception the exception
+ */
+ public void signLevel1(PrivateKey key) throws Exception;
+
+ /**
+ * Sign the contained data block.
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the private key
+ * @param prov the security provider providing the signature implementation
+ * @return the byte[]
+ * @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
new file mode 100644
index 0000000..e23fc88
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java
@@ -0,0 +1,202 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * The Class SignedDataType.
+ */
+public interface ILevel1Data {
+
+
+
+ /**
+ * Sets the security provider .
+ *
+ * @param securityProvider the new security provider
+ */
+ public void setSecurityProvider(String securityProvider);
+
+
+ /**
+ * Gets the security provider.
+ *
+ * @return the security provider
+ */
+ public String getSecurityProvider();
+
+
+
+
+
+
+ /**
+ * Gets the key id.
+ *
+ * @return the key id
+ */
+ public Long getKeyId();
+
+
+ /**
+ * Sets the key id.
+ *
+ * @param keyId the new key id
+ */
+ public void setKeyId(Long keyId);
+
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public Collection<IData> getData();
+
+
+ /**
+ * Sets the data.
+ *
+ * @param data the new data
+ */
+ public void setData(Collection<IData> data);
+
+ /**
+ * Adds data.
+ *
+ * @param data the new data
+ */
+ public void addData(IData data);
+
+ /**
+ * Gets the level 2 key algorithm OID.
+ *
+ * @return the level 2 key alg
+ */
+ public String getLevel2KeyAlg();
+
+
+ /**
+ * Sets the level 2 key algorithm OID.
+ *
+ * @param level2KeyAlg the new level 2 key alg
+ */
+ public void setLevel2KeyAlg(String level2KeyAlg);
+
+
+ /**
+ * Gets the level 1 signing alg.
+ *
+ * @return the level 1 signing alg
+ */
+ public String getLevel1SigningAlg();
+
+
+ /**
+ * Sets the level 1 signing algorithm OID.
+ *
+ * @param level1SigningAlg the new level 1 signing alg
+ */
+ public void setLevel1SigningAlg(String level1SigningAlg);
+
+
+ /**
+ * Gets the level 2 signing algorithm OID.
+ *
+ * @return the level 2 signing alg
+ */
+ public String getLevel2SigningAlg();
+
+
+ /**
+ * Sets the level 2 signing algorithm OID.
+ *
+ * @param level2SigningAlg the new level 2 signing alg
+ */
+ public void setLevel2SigningAlg(String level2SigningAlg);
+
+
+ /**
+ * Gets the level 2 public key.
+ *
+ * @return the level 2 public key
+ */
+ public byte[] getLevel2publicKey();
+
+
+ /**
+ * Sets the level 2 public key.
+ *
+ * @param level2publicKey the new level 2 public key
+ */
+ public void setLevel2publicKey(byte[] level2publicKey);
+
+
+
+ /**
+ * Gets the level 1 key algorithm OID.
+ *
+ * @return the level 1 key alg
+ */
+ public String getLevel1KeyAlg();
+
+ /**
+ * Sets the level 1 key algorithm OID.
+ *
+ * @param level1KeyAlg the new level 1 key alg
+ */
+ public void setLevel1KeyAlg(String level1KeyAlg);
+
+
+ /**
+ * 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
+ */
+ public void setEndOfBarcodeValidity(Date 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/ILevel2Data.java b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel2Data.java
new file mode 100644
index 0000000..cc28422
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel2Data.java
@@ -0,0 +1,25 @@
+package org.uic.barcode.dynamicFrame.api;
+
+/**
+ * The Level 2 data.
+ */
+
+public interface ILevel2Data {
+
+
+
+ public ILevel1Data getLevel1Data();
+
+ public void setLevel1Data(ILevel1Data level1Data);
+
+ public byte[] getLevel1Signature();
+
+ public byte[] getLevel1SignatureBytes();
+
+ public void setLevel1Signature(byte[] level1Signature);
+
+ public IData getLevel2Data();
+
+ public void setLevel2Data(IData level2Data);
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
new file mode 100644
index 0000000..d6e1410
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
@@ -0,0 +1,52 @@
+package org.uic.barcode.dynamicFrame.api;
+
+/**
+ * The Class DataType.
+ */
+public class SimpleData implements IData{
+
+
+ /** The data format.
+ *
+ * -- FCB1 FCB version 1
+ * -- FCB2 FCB version 2
+ * -- RICS company code + ...
+ **/
+ public String format;
+
+ /** The data. */
+ public byte[] data;
+
+ /**
+ * Gets the data format.
+ *
+ * @return the data format
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the data format.
+ *
+ * @param dataFormat the new data format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public byte[] getData() {
+ return data;
+ }
+
+ @Override
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
new file mode 100644
index 0000000..a05a936
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
@@ -0,0 +1,499 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
+
+import org.uic.barcode.dynamicContent.api.DynamicContentCoder;
+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.v1.DynamicFrameCoderV1;
+import org.uic.barcode.dynamicFrame.v2.DynamicFrameCoderV2;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.utils.AlgorithmNameResolver;
+
+
+
+/**
+ * The DynamicHeader for bar codes
+ *
+ */
+public class SimpleDynamicFrame implements IDynamicFrame {
+
+ /**
+ * Instantiates a new dynamic frame.
+ */
+ public SimpleDynamicFrame() {}
+
+ public SimpleDynamicFrame(String format) {
+ this.format = format;
+ }
+
+ /** The format. */
+ public String format = null;
+
+ /** The level 2 signed data. */
+ /*level 2 data*/
+ public ILevel2Data level2Data;
+
+
+ /** The signature of level 2 data. */
+ public byte[] level2Signature;
+
+ public Date endOfValidity = null;
+
+ /**
+ * Gets the format.
+ *
+ * @return the format
+ */
+ @Override
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the format.
+ *
+ * @param format the new format
+ */
+ @Override
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the level 2 signed data.
+ *
+ * @return the level 2 signed data
+ */
+ @Override
+ public ILevel2Data getLevel2Data() {
+ return level2Data;
+ }
+
+ /**
+ * Sets the level 2 signed data.
+ *
+ * @param level2SignedData the new level 2 signed data
+ */
+ @Override
+ public void setLevel2Data(ILevel2Data level2SignedData) {
+ this.level2Data = level2SignedData;
+ }
+
+ /**
+ * Gets the level 2 signature.
+ *
+ * @return the level 2 signature
+ */
+ @Override
+ public byte[] getLevel2Signature() {
+ return level2Signature;
+ }
+
+ /**
+ * Sets the level 2 signature.
+ *
+ * @param level2Signature the new level 2 signature
+ */
+ @Override
+ public void setLevel2Signature(byte[] level2Signature) {
+ this.level2Signature = level2Signature;
+ }
+
+
+
+ /**
+ * Verify the level 2 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @return the int
+ * @throws EncodingFormatException
+ */
+ @Override
+ public int validateLevel2() throws EncodingFormatException {
+ return validateLevel2(null);
+
+ }
+
+ /**
+ * Verify the level 2 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param prov the registered security provider
+ * @return the return error code
+ * @throws EncodingFormatException
+ */
+ @Override
+ public int validateLevel2(Provider prov) throws EncodingFormatException {
+
+ if (getLevel2Data() == null
+ || getLevel2Data().getLevel1Data() == null
+ || getLevel2Data().getLevel1Data().getLevel2KeyAlg() == null
+ || getLevel2Data().getLevel1Data().getLevel2KeyAlg().length() == 0) {
+ return Constants.LEVEL2_VALIDATION_NO_KEY;
+ }
+
+ String level2KeyAlg = getLevel2Data().getLevel1Data().getLevel2KeyAlg();
+
+
+ if (level2KeyAlg == null || level2KeyAlg.length() == 0) {
+ return Constants.LEVEL2_VALIDATION_NO_KEY;
+ }
+
+ if (level2Signature == null || level2Signature.length == 0) {
+ return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
+ }
+
+ String keyAlgName = null;
+ try {
+ keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg,prov);
+ } catch (Exception e1) {
+ return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
+ }
+ if (keyAlgName == null || keyAlgName.length() == 0) {
+ return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
+ }
+
+ PublicKey key = null;
+ try {
+ byte[] keyBytes = this.getLevel2Data().getLevel1Data().getLevel2publicKey();
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ key = KeyFactory.getInstance(keyAlgName).generatePublic(keySpec);
+ } catch (InvalidKeySpecException e1) {
+ return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
+ } catch (NoSuchAlgorithmException e1) {
+ return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
+ }
+
+ //find the algorithm name for the signature OID
+ String level2SigAlg = this.getLevel2Data().getLevel1Data().getLevel2SigningAlg();
+
+ String sigAlgName = null;
+ try {
+ sigAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,level2SigAlg,prov);
+ } catch (Exception e1) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ if (sigAlgName == null) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+
+ Signature sig;
+ try {
+ if (prov == null) {
+ sig = Signature.getInstance(sigAlgName);
+ } else {
+ sig = Signature.getInstance(sigAlgName, prov);
+ }
+ } catch (NoSuchAlgorithmException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ try {
+ sig.initVerify(key);
+ } catch (InvalidKeyException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+
+ try {
+ byte[] signedData2 = getLevel2DataBin();
+ sig.update(signedData2);
+ } catch (SignatureException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ } catch (IllegalArgumentException e) {
+ return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
+ } catch (UnsupportedOperationException e) {
+ return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
+ }
+
+ byte[] signature = level2Signature;
+ try {
+ if (sig.verify(signature)){
+ return Constants.LEVEL2_VALIDATION_OK;
+ } else {
+ return Constants.LEVEL2_VALIDATION_FRAUD;
+ }
+ } catch (SignatureException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ }
+
+ @Override
+ public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException {
+ return validateLevel1(key, prov, null);
+
+ }
+
+ @Override
+ public int validateLevel1(PublicKey key) throws EncodingFormatException {
+ return validateLevel1(key, null, null);
+ }
+
+ @Override
+ public int validateLevel1(PublicKey key, String signatureAlgorithmOid) throws EncodingFormatException {
+ return validateLevel1(key, null, signatureAlgorithmOid);
+ }
+
+ @Override
+ public int validateLevel1(PublicKey key, Provider prov, String signatureAlgorithmOid) throws EncodingFormatException {
+
+ if (getLevel2Data() == null
+ || getLevel2Data().getLevel1Signature() == null
+ || getLevel2Data().getLevel1Signature() == null
+ || getLevel2Data().getLevel1Signature().length == 0) {
+ return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
+ }
+
+ byte[] signature = this.getLevel2Data().getLevel1Signature();
+
+
+ //find the algorithm name for the signature OID
+ String signingAlgorithmOid = null;
+ if (getLevel2Data() != null
+ && getLevel2Data().getLevel1Data() != null
+ && getLevel2Data().getLevel1Data().getLevel1SigningAlg() != null
+ && getLevel2Data().getLevel1Data().getLevel1SigningAlg().length() > 0) {
+ signingAlgorithmOid = getLevel2Data().getLevel1Data().getLevel1SigningAlg();
+ } else {
+ signingAlgorithmOid = signatureAlgorithmOid;
+ }
+
+ if (signingAlgorithmOid == null || signingAlgorithmOid.length() == 0) {
+ return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
+ }
+ //find the algorithm name for the signature OID
+ String algo = null;
+ try {
+ algo = AlgorithmNameResolver.getSignatureAlgorithmName(signingAlgorithmOid, prov);
+ } catch (Exception e1) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ if (algo == null) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+
+ Signature sig;
+ try {
+ if (prov != null) {
+ sig = Signature.getInstance(algo, prov);
+ } else {
+ sig = Signature.getInstance(algo);
+
+ }
+ } catch (NoSuchAlgorithmException e) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ try {
+ sig.initVerify(key);
+ } catch (InvalidKeyException e) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+
+ try {
+
+ byte[] encodedData = getLevel1DataBin();
+
+ sig.update(encodedData);
+
+ } catch (SignatureException e) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ } catch (IllegalArgumentException e) {
+ return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
+ } catch (UnsupportedOperationException e) {
+ return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
+ }
+
+ try {
+ if (sig.verify(signature)){
+ return Constants.LEVEL1_VALIDATION_OK;
+ } else {
+ return Constants.LEVEL1_VALIDATION_FRAUD;
+ }
+ } catch (SignatureException e) {
+ return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ }
+
+ @Override
+ public void signLevel2(PrivateKey key) throws Exception {
+ signLevel2(key, null);
+ }
+
+ /**
+ * Sign level 2 data.
+ *
+ * @param key the key
+ * @param prov the registered security provider
+ * @throws Exception the exception
+ */
+ @Override
+ public void signLevel2(PrivateKey key, Provider prov) throws Exception {
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2Data().getLevel1Data().getLevel2SigningAlg(), prov);
+ Signature sig = null;
+ if (prov != null) {
+ sig = Signature.getInstance(algo,prov);
+ } else {
+ sig = Signature.getInstance(algo);
+ }
+ sig.initSign(key);
+ byte[] signedData = DynamicFrameCoder.encodeLevel2Data(this);
+ sig.update(signedData);
+ level2Signature = sig.sign();
+
+ }
+
+
+ /**
+ * Adds the dynamic content and encodes it. (API level)
+ *
+ * @param content the dynamic content
+ * @throws EncodingFormatException the encoding format exception
+ */
+ @Override
+ public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
+
+ level2Data.setLevel2Data(new SimpleData());
+
+ level2Data.getLevel2Data().setFormat(DynamicContentCoder.dynamicContentDataFDC1);
+
+ level2Data.getLevel2Data().setData(DynamicContentCoder.encode(content, DynamicContentCoder.dynamicContentDataFDC1));
+
+ }
+
+ /**
+ * Adds the level 2 dynamic data. (ASN level)
+ *
+ * @param dynamicData the dynamic data
+ */
+ @Override
+ public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
+ this.getLevel2Data().setLevel2Data(dynamicData.getApiDataType());
+ }
+
+ /**
+ * Gets the dynamic content.
+ *
+ * @return the dynamic content
+ */
+ @Override
+ public IUicDynamicContent getDynamicContent() {
+
+ if (this.getLevel2Data() == null ||
+ this.getLevel2Data().getLevel2Data() == null){
+ return null;
+ }
+
+ return DynamicContentCoder.decode(level2Data.getLevel2Data().getData());
+
+ }
+
+
+ /**
+ * Sign the contained data block.
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ * @param key the key
+ * @return
+ * @return the byte[]
+ * @throws Exception
+ */
+ @Override
+ public void signLevel1(PrivateKey key) throws Exception {
+
+ signLevel1(key, null);
+
+ }
+
+ /**
+ * Sign the contained data block.
+ *
+ * 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
+ * @return the byte[]
+ * @throws Exception
+ */
+ @Override
+ public void signLevel1(PrivateKey key, Provider prov) throws Exception {
+
+ if (level2Data == null) return;
+
+ ILevel1Data level1Data = level2Data.getLevel1Data();
+
+ if (level1Data == null) return;
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level1Data.getLevel1SigningAlg());
+ Signature sig = null;
+ if (prov != null) {
+ sig = Signature.getInstance(algo, prov);
+ } else {
+ sig = Signature.getInstance(algo);
+ }
+ sig.initSign(key);
+
+ 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");
+
+ }
+
+ @Override
+ 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
new file mode 100644
index 0000000..f42ff98
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java
@@ -0,0 +1,264 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * The Class SignedDataType.
+ */
+
+public class SimpleLevel1Data implements ILevel1Data {
+
+ /** The security provider */
+ public String securityProvider;
+
+
+ /** The key id. */
+ public Long keyId;
+
+
+ /** The data. */
+ public Collection<IData> dataList;
+
+ /**
+ * The key generator algorithms
+ * Object Identifier of the Algorithm
+ * Number notation:
+ *
+ * e.g.:
+ * -- DSA SHA224 2.16.840.1.101.3.4.3.1
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
+ * -- ECC 256 1.2.840.10045.3.1.7
+ *
+ *
+ */
+ public String level1KeyAlg;
+
+ /** The level 2 key alg. */
+ public String level2KeyAlg;
+
+ /**
+ * The signing algorithm
+ * Object Identifier of the Algorithms
+ * Number notation:
+ *
+ * e.g.:
+ * -- DSA SHA224 2.16.840.1.101.3.4.3.1
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
+ * -- ECC 256 1.2.840.10045.3.1.7
+ *
+ *
+ */
+ public String level1SigningAlg;
+
+ /** The level 2 signing alg. */
+ public String level2SigningAlg;
+
+
+ /** The level 2 public key. */
+ public byte[] level2publicKey;
+
+
+ public Date endOfBarcodeValidity = null;
+
+
+ public Long validityDuration = null;
+
+
+
+ /**
+ * Gets the security provider .
+ *
+ * @return the security provider
+ */
+ public String getSecurityProvider() {
+ return securityProvider;
+ }
+
+ /**
+ * Sets the security provider.
+ *
+ * in case the security provider code is encoded in IA5 this will return null
+ *
+ * @param securityProviderNum the new security provider
+ */
+ public void setSecurityProvider(String securityProvider) {
+ this.securityProvider = securityProvider;
+ }
+
+
+
+
+
+ /**
+ * Gets the key id.
+ *
+ * @return the key id
+ */
+ public Long getKeyId() {
+ return keyId;
+ }
+
+ /**
+ * Sets the key id.
+ *
+ * @param keyId the new key id
+ */
+ public void setKeyId(Long keyId) {
+ this.keyId = keyId;
+ }
+
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public Collection<IData> getData() {
+ return dataList;
+ }
+
+ /**
+ * Sets the data.
+ *
+ * @param data the new data
+ */
+ public void setData(Collection<IData> data) {
+ this.dataList = data;
+ }
+
+ /**
+ * Gets the level 2 key alg.
+ *
+ * @return the level 2 key alg
+ */
+ public String getLevel2KeyAlg() {
+ return level2KeyAlg;
+ }
+
+ /**
+ * Sets the level 2 key alg.
+ *
+ * @param level2KeyAlg the new level 2 key alg
+ */
+ public void setLevel2KeyAlg(String level2KeyAlg) {
+ this.level2KeyAlg = level2KeyAlg;
+ }
+
+ /**
+ * Gets the level 1 signing alg.
+ *
+ * @return the level 1 signing alg
+ */
+ public String getLevel1SigningAlg() {
+ return level1SigningAlg;
+ }
+
+ /**
+ * Sets the level 1 signing alg.
+ *
+ * @param level1SigningAlg the new level 1 signing alg
+ */
+ public void setLevel1SigningAlg(String level1SigningAlg) {
+ this.level1SigningAlg = level1SigningAlg;
+ }
+
+ /**
+ * Gets the level 2 signing alg.
+ *
+ * @return the level 2 signing alg
+ */
+ public String getLevel2SigningAlg() {
+ return level2SigningAlg;
+ }
+
+ /**
+ * Sets the level 2 signing alg.
+ *
+ * @param level2SigningAlg the new level 2 signing alg
+ */
+ public void setLevel2SigningAlg(String level2SigningAlg) {
+ this.level2SigningAlg = level2SigningAlg;
+ }
+
+ /**
+ * Gets the level 2 public key.
+ *
+ * @return the level 2 public key
+ */
+ public byte[] getLevel2publicKey() {
+ return level2publicKey;
+ }
+
+ /**
+ * Sets the level 2 public key.
+ *
+ * @param level2publicKey the new level 2 public key
+ */
+ public void setLevel2publicKey(byte[] level2publicKey) {
+ this.level2publicKey = level2publicKey;
+ }
+
+
+
+ /**
+ * Gets the level 1 key alg.
+ *
+ * @return the level 1 key alg
+ */
+ public String getLevel1KeyAlg() {
+ return level1KeyAlg;
+ }
+
+ /**
+ * Sets the level 1 key alg.
+ *
+ * @param level1KeyAlg the new level 1 key alg
+ */
+ public void setLevel1KeyAlg(String level1KeyAlg) {
+ this.level1KeyAlg = level1KeyAlg;
+ }
+
+ /**
+ * Sets the end of validity date. The validity date has to be provided in UTC.
+ *
+ * @param date the new end of validity date
+ */
+ public void setEndOfBarcodeValidity(Date date){
+
+ endOfBarcodeValidity = date;
+
+
+ }
+
+ /**
+ * Gets the end of validity date.
+ *
+ * @return the end of validity date
+ */
+ public Date getEndOfBarcodeValidity() {
+
+ return endOfBarcodeValidity;
+ }
+
+ @Override
+ public void addData(IData data) {
+
+ if (dataList == null) {
+ dataList = new ArrayList<IData>();
+ }
+
+ 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
new file mode 100644
index 0000000..17e71db
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java
@@ -0,0 +1,56 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+
+/**
+ * The Class DataType.
+ */
+public class SimpleLevel2Data implements ILevel2Data {
+
+ @FieldOrder(order = 0)
+ ILevel1Data level1Data;
+
+ /** The data. */
+ @FieldOrder(order = 1)
+ @Asn1Optional public byte[] level1Signature;
+
+ @FieldOrder(order = 2)
+ @Asn1Optional IData level2Data;
+
+
+ public ILevel1Data getLevel1Data() {
+ return level1Data;
+ }
+
+
+ public void setLevel1Data(ILevel1Data level1Data) {
+ this.level1Data = level1Data;
+ }
+
+
+ public byte[] getLevel1Signature() {
+ return level1Signature;
+ }
+
+ public byte[] getLevel1SignatureBytes() {
+ return level1Signature;
+ }
+
+
+ public void setLevel1Signature(byte[] level1Signature) {
+ this.level1Signature = level1Signature;
+ }
+
+
+ public IData getLevel2Data() {
+ return level2Data;
+ }
+
+
+ public void setLevel2Data(IData level2Data) {
+ this.level2Data = level2Data;
+ }
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/package.html b/src/main/java/org/uic/barcode/dynamicFrame/package.html
deleted file mode 100644
index dbe6c06..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/package.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head></head>
-<body>
-
-<h1>drafted new header for dynamic content </h1>
-<p>Provides a decoding and encoding of the header data frame. (Draft for UIC IRS 90918-9).</p>
-</body>
-</html> \ No newline at end of file
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
index 2ea63ca..e8cfc50 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
@@ -1,6 +1,7 @@
-package org.uic.barcode.dynamicFrame;
+package org.uic.barcode.dynamicFrame.v1;
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.OctetString;
@@ -19,10 +20,12 @@ public class DataType {
* -- FCB2 FCB version 2
* -- RICS company code + ...
**/
+ @FieldOrder(order = 0)
@RestrictedString(CharacterRestriction.IA5String)
public String format;
/** The data. */
+ @FieldOrder(order = 1)
public OctetString data;
/**
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
new file mode 100644
index 0000000..3bfcbf5
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
@@ -0,0 +1,229 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Signature;
+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.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+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;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.utils.AlgorithmNameResolver;
+
+
+/**
+ * The DynamicHeader for bar codes
+ *
+ * Implementation of the Draft under discussion, not final.
+ */
+@Sequence
+public class DynamicFrame extends Object{
+
+ /**
+ * Instantiates a new dynamic frame.
+ */
+ public DynamicFrame() {}
+
+ /** The format. */
+ @FieldOrder(order = 0)
+ @RestrictedString(CharacterRestriction.IA5String)
+ public String format;
+
+ /** The level 2 signed data. */
+ /*level 2 data*/
+ @FieldOrder(order = 1)
+ Level2DataType level2SignedData;
+
+
+ /** The signature of level 2 data. */
+ @FieldOrder(order = 2)
+ @Asn1Optional public OctetString level2Signature;
+
+ /**
+ * Gets the format.
+ *
+ * @return the format
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the format.
+ *
+ * @param format the new format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the level 2 signed data.
+ *
+ * @return the level 2 signed data
+ */
+ public Level2DataType getLevel2SignedData() {
+ return level2SignedData;
+ }
+
+ /**
+ * Sets the level 2 signed data.
+ *
+ * @param level2SignedData the new level 2 signed data
+ */
+ public void setLevel2SignedData(Level2DataType level2SignedData) {
+ this.level2SignedData = level2SignedData;
+ }
+
+ /**
+ * Gets the level 2 signature.
+ *
+ * @return the level 2 signature
+ */
+ public OctetString getLevel2Signature() {
+ return level2Signature;
+ }
+
+ /**
+ * Sets the level 2 signature.
+ *
+ * @param level2Signature the new level 2 signature
+ */
+ public void setLevel2Signature(OctetString level2Signature) {
+ this.level2Signature = level2Signature;
+ }
+
+ /**
+ * Encode.
+ *
+ * Encode the header as ASN.1 PER UNALIGNED byte array
+ *
+ * @return the byte[]
+ */
+ public byte[] encode() {
+ return UperEncoder.encode(this);
+ }
+
+ /**
+ * Decode.
+ *
+ * Decode the header from an ASN.1 PER UNALIGNED encoded byte array
+ *
+ * @param bytes the bytes
+ * @return the dynamic header
+ */
+ public static DynamicFrame decode(byte[] bytes) {
+ return UperEncoder.decode(bytes, DynamicFrame.class);
+ }
+
+ /**
+ * Sign level 2 data without a specific security provider.
+ *
+ * @param key the key
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key) throws Exception {
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
+ Signature sig = Signature.getInstance(algo);
+ sig.initSign(key);
+ byte[] data = level2SignedData.encode();
+ sig.update(data);
+ byte[] signature = sig.sign();
+ this.level2Signature = new OctetString(signature);
+
+ }
+
+ /**
+ * Sign level 2 data.
+ *
+ * @param key the key
+ * @param prov the security Provider
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key, Provider prov) throws Exception {
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
+ Signature sig = Signature.getInstance(algo,prov);
+ sig.initSign(key);
+ byte[] data = level2SignedData.encode();
+ sig.update(data);
+ this.level2Signature = new OctetString(sig.sign());
+
+ }
+
+
+ /**
+ * Adds the dynamic content and encodes it. (API level)
+ *
+ * @param content the dynamic content
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
+
+
+ level2SignedData.setLevel2Data(new DataType());
+
+ level2SignedData.getLevel2Data().setFormat(DynamicContentCoder.dynamicContentDataFDC1);
+
+ level2SignedData.getLevel2Data().setByteData(DynamicContentCoder.encode(content, DynamicContentCoder.dynamicContentDataFDC1));
+
+ }
+
+ /**
+ * Adds the level 2 dynamic data. (ASN level)
+ *
+ * @param dynamicData the dynamic data
+ */
+ public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
+ DataType dt = new DataType();
+ dt.setByteData(dynamicData.getDataType().getByteData());
+ dt.setFormat(dynamicData.getDataType().getFormat());
+ level2SignedData.setLevel2Data(dt);
+ }
+
+ /**
+ * Gets the dynamic content.
+ *
+ * @return the dynamic content
+ */
+ public IUicDynamicContent getDynamicContent() {
+
+ if (level2SignedData == null ||
+ level2SignedData.getLevel2Data() == null){
+ return null;
+ }
+
+ return DynamicContentCoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData());
+
+ }
+
+ /**
+ * Gets the dynamic data FDC 1.
+ *
+ * @return the dynamic data FDC 1
+ */
+ public UicDynamicContentDataFDC1 getDynamicDataFDC1() {
+
+ if (level2SignedData == null ||
+ level2SignedData.getLevel2Data() == null){
+ return null;
+ }
+
+ if ( UicDynamicContentDataFDC1.getFormat().equals(this.getLevel2SignedData().getLevel2Data().getFormat())) {
+ return UperEncoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData(), UicDynamicContentDataFDC1.class);
+ }
+ return null;
+
+ }
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
new file mode 100644
index 0000000..71de58e
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
@@ -0,0 +1,221 @@
+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;
+import org.uic.barcode.dynamicFrame.api.ILevel1Data;
+import org.uic.barcode.dynamicFrame.api.ILevel2Data;
+import org.uic.barcode.dynamicFrame.api.SimpleData;
+import org.uic.barcode.dynamicFrame.api.SimpleLevel1Data;
+import org.uic.barcode.dynamicFrame.api.SimpleLevel2Data;
+
+public class DynamicFrameCoderV1 {
+
+ public static void decode(IDynamicFrame frame, byte[] bytes) {
+
+ DynamicFrame asnFrame = UperEncoder.decode(bytes,DynamicFrame.class);
+
+ frame.setFormat(asnFrame.getFormat());
+
+ if (asnFrame.getLevel2Signature() != null) {
+ frame.setLevel2Signature(asnFrame.getLevel2Signature().toByteArray());
+ }
+
+ if (asnFrame.getLevel2SignedData() != null) {
+ frame.setLevel2Data(new SimpleLevel2Data());
+ populateApi(frame.getLevel2Data(), asnFrame.getLevel2SignedData());
+ }
+
+ }
+
+ 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) {
+ level2.setLevel1Data(new SimpleLevel1Data());
+ level2.setLevel1Data(populateApi(asnLevel2.getLevel1Data()));
+ }
+
+ if (asnLevel2.getLevel2Data() != null) {
+ level2.setLevel2Data(new SimpleData());
+ level2.setLevel2Data(populateApi(asnLevel2.getLevel2Data()));
+ }
+ }
+
+ private static IData populateApi(DataType asnData) {
+
+ IData data = new SimpleData();
+ data.setData(asnData.getByteData());
+ data.setFormat(asnData.getFormat());
+ return data;
+ }
+
+ private static ILevel1Data populateApi(Level1DataType asnLevel1) {
+
+ ILevel1Data level1 = new SimpleLevel1Data();
+
+ level1.setKeyId(asnLevel1.getKeyId());
+ level1.setSecurityProvider(asnLevel1.getSecurityProvider());
+ level1.setLevel1KeyAlg(asnLevel1.getLevel1KeyAlg());
+ level1.setLevel1SigningAlg(asnLevel1.getLevel1SigningAlg());
+ level1.setLevel2KeyAlg(asnLevel1.getLevel2KeyAlg());
+ level1.setLevel2SigningAlg(asnLevel1.getLevel2SigningAlg());
+ if (asnLevel1.getLevel2publicKey() != null) {
+ level1.setLevel2publicKey(asnLevel1.getLevel2publicKey().toByteArray());
+ }
+
+ if (asnLevel1.getData() != null && !asnLevel1.getData().isEmpty()) {
+
+ for (DataType asnData : asnLevel1.getData()) {
+ IData data = new SimpleData();
+ data.setData(asnData.getByteData());
+ data.setFormat(asnData.getFormat());
+ level1.addData(data);
+ }
+ }
+
+ return level1;
+ }
+
+ public static byte[] encode(IDynamicFrame dynamicFrame) throws EncodingFormatException {
+
+ DynamicFrame asnDynamicFrame = populateAsn(dynamicFrame);
+
+ return UperEncoder.encode(asnDynamicFrame);
+
+ }
+
+
+ public static byte[] encode(ILevel1Data level1Data) throws EncodingFormatException {
+
+ Level1DataType asn = populateAsn(level1Data);
+
+ return UperEncoder.encode(asn);
+ }
+
+
+ public static byte[] getEncoded(String path, byte[] data) {
+
+ if (path.endsWith("Level1Data")){
+ return UperEncoder.extract(data, "Level1DataType" ,DynamicFrame.class );
+ } else if (path.endsWith("Level2Data")){
+ return UperEncoder.extract(data, "Level2DataType" ,DynamicFrame.class );
+ }
+
+ return null;
+ }
+
+
+ public static byte[] encodeLevel2Data(ILevel2Data level2Data) throws EncodingFormatException {
+
+ Level2DataType asn = populateAsn(level2Data);
+
+ return UperEncoder.encode(asn);
+ }
+
+ private static DynamicFrame populateAsn(IDynamicFrame frame) throws EncodingFormatException {
+
+ DynamicFrame asnFrame = new DynamicFrame();
+
+ asnFrame.setFormat(frame.getFormat());
+
+ if (frame.getLevel2Signature() != null && frame.getLevel2Signature().length > 0) {
+ asnFrame.setLevel2Signature(new OctetString(frame.getLevel2Signature()));
+ }
+
+ Level2DataType asnLevel2 = populateAsn(frame.getLevel2Data());
+ if (asnLevel2 != null) {
+ asnFrame.setLevel2SignedData(asnLevel2);
+ }
+
+ return asnFrame;
+ }
+
+
+ private static Level2DataType populateAsn(ILevel2Data level2) throws EncodingFormatException {
+
+ Level2DataType asnLevel2 = new Level2DataType();
+
+ asnLevel2.setLevel1Signature(level2.getLevel1Signature());
+
+ Level1DataType asnLevel1 = populateAsn(level2.getLevel1Data());
+
+ asnLevel2.setLevel1Data(asnLevel1);
+
+ if (level2.getLevel2Data() != null) {
+ DataType asnData = new DataType();
+ asnData.setFormat(level2.getLevel2Data().getFormat());
+ asnData.setData(new OctetString(level2.getLevel2Data().getData()));
+ asnLevel2.setLevel2Data(asnData);
+ }
+
+ return asnLevel2;
+ }
+
+ private static Level1DataType populateAsn(ILevel1Data level1) throws EncodingFormatException {
+
+ Level1DataType asnLevel1 = new Level1DataType();
+
+ asnLevel1.setSecurityProvider(level1.getSecurityProvider());
+
+ asnLevel1.setKeyId(level1.getKeyId());
+
+ asnLevel1.setLevel1KeyAlg(level1.getLevel1KeyAlg());
+
+ asnLevel1.setLevel1SigningAlg(level1.getLevel1SigningAlg());
+
+ asnLevel1.setLevel2KeyAlg(level1.getLevel2KeyAlg());
+
+ if (level1.getLevel2publicKey() != null && level1.getLevel2publicKey().length > 0) {
+ asnLevel1.setLevel2publicKey(new OctetString(level1.getLevel2publicKey()));
+ }
+
+ asnLevel1.setLevel2SigningAlg(level1.getLevel2SigningAlg());
+
+ if (level1.getData() != null && !level1.getData().isEmpty()) {
+
+ asnLevel1.setData(new SequenceOfDataType());
+
+ for (IData data : level1.getData()) {
+
+ DataType asnData = new DataType();
+ asnData.setByteData(data.getData());
+ asnData.setFormat(data.getFormat());
+ asnLevel1.getData().add(asnData);
+
+ }
+
+ }
+
+ return asnLevel1;
+ }
+
+
+ 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/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java
index 958cafc..5104c50 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java
@@ -1,4 +1,4 @@
-package org.uic.barcode.dynamicFrame;
+package org.uic.barcode.dynamicFrame.v1;
import org.uic.barcode.asn1.datatypes.Asn1Optional;
import org.uic.barcode.asn1.datatypes.CharacterRestriction;
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/Level2DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level2DataType.java
new file mode 100644
index 0000000..7813cf2
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level2DataType.java
@@ -0,0 +1,74 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+/**
+ * The Class DataType.
+ */
+@Sequence
+public class Level2DataType {
+
+ @FieldOrder(order = 0)
+ Level1DataType level1Data;
+
+ /** The data. */
+ @FieldOrder(order = 1)
+ @Asn1Optional public OctetString level1Signature;
+
+ @FieldOrder(order = 2)
+ @Asn1Optional DataType level2Data;
+
+
+ public Level1DataType getLevel1Data() {
+ return level1Data;
+ }
+
+
+ public void setLevel1Data(Level1DataType level1Data) {
+ this.level1Data = level1Data;
+ }
+
+
+ public OctetString getLevel1Signature() {
+ return level1Signature;
+ }
+
+ public byte[] getLevel1SignatureBytes() {
+ return level1Signature.toByteArray();
+ }
+
+ public void setLevel1Signature(OctetString level1Signature) {
+ this.level1Signature = level1Signature;
+ }
+
+ public void setLevel1Signature(byte[] level1Signature) {
+ this.level1Signature = new OctetString(level1Signature);
+ }
+
+
+ public DataType getLevel2Data() {
+ return level2Data;
+ }
+
+
+ public void setLevel2Data(DataType 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/SequenceOfDataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java
index b5c130e..be0bf95 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java
@@ -1,4 +1,4 @@
-package org.uic.barcode.dynamicFrame;
+package org.uic.barcode.dynamicFrame.v1;
import java.util.Collection;
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
new file mode 100644
index 0000000..beceda9
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
@@ -0,0 +1,96 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+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.OctetString;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+/**
+ * The Class DataType.
+ */
+@Sequence
+public class DataType {
+
+
+ /** The data format.
+ *
+ * -- FCB1 FCB version 1
+ * -- FCB2 FCB version 2
+ * -- RICS company code + ...
+ **/
+ @RestrictedString(CharacterRestriction.IA5String)
+ @FieldOrder(order = 0)
+ public String format;
+
+ /** The data. */
+ @FieldOrder(order = 1)
+ public OctetString data;
+
+ /**
+ * Gets the data format.
+ *
+ * @return the data format
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the data format.
+ *
+ * @param dataFormat the new data format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public OctetString getData() {
+ return data;
+ }
+
+ /**
+ * Sets the data.
+ *
+ * @param data the new data
+ */
+ public void setData(OctetString data) {
+ this.data = data;
+ }
+
+ /**
+ * Gets the data as byte array.
+ *
+ * @return the data
+ */
+ public byte[] getByteData() {
+ return data.toByteArray();
+ }
+
+ /**
+ * Sets the data from a byte array.
+ *
+ * @param data the new data
+ */
+ public void setByteData(byte[] data) {
+ this.data = new OctetString(data);
+ }
+
+ /**
+ * 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/v2/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
new file mode 100644
index 0000000..55af066
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
@@ -0,0 +1,230 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Signature;
+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.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+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;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.utils.AlgorithmNameResolver;
+
+
+/**
+ * The DynamicHeader for bar codes
+ *
+ * Implementation of the Draft under discussion, not final.
+ */
+@Sequence
+public class DynamicFrame extends Object{
+
+ /**
+ * Instantiates a new dynamic frame.
+ */
+ public DynamicFrame() {}
+
+ /** The format. */
+ @FieldOrder(order = 0)
+ @RestrictedString(CharacterRestriction.IA5String)
+ public String format;
+
+ /** The level 2 signed data. */
+ /*level 2 data*/
+ @FieldOrder(order = 1)
+ Level2DataType level2SignedData;
+
+
+ /** The signature of level 2 data. */
+ @FieldOrder(order = 2)
+ @Asn1Optional public OctetString level2Signature;
+
+ /**
+ * Gets the format.
+ *
+ * @return the format
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the format.
+ *
+ * @param format the new format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the level 2 signed data.
+ *
+ * @return the level 2 signed data
+ */
+ public Level2DataType getLevel2SignedData() {
+ return level2SignedData;
+ }
+
+ /**
+ * Sets the level 2 signed data.
+ *
+ * @param level2SignedData the new level 2 signed data
+ */
+ public void setLevel2SignedData(Level2DataType level2SignedData) {
+ this.level2SignedData = level2SignedData;
+ }
+
+ /**
+ * Gets the level 2 signature.
+ *
+ * @return the level 2 signature
+ */
+ public OctetString getLevel2Signature() {
+ return level2Signature;
+ }
+
+ /**
+ * Sets the level 2 signature.
+ *
+ * @param level2Signature the new level 2 signature
+ */
+ public void setLevel2Signature(OctetString level2Signature) {
+ this.level2Signature = level2Signature;
+ }
+
+ /**
+ * Encode.
+ *
+ * Encode the header as ASN.1 PER UNALIGNED byte array
+ *
+ * @return the byte[]
+ */
+ public byte[] encode() {
+ return UperEncoder.encode(this);
+ }
+
+ /**
+ * Decode.
+ *
+ * Decode the header from an ASN.1 PER UNALIGNED encoded byte array
+ *
+ * @param bytes the bytes
+ * @return the dynamic header
+ */
+ public static DynamicFrame decode(byte[] bytes) {
+ return UperEncoder.decode(bytes, DynamicFrame.class);
+ }
+
+
+ /**
+ * Sign level 2 data without a specific security provider.
+ *
+ * @param key the key
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key) throws Exception {
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
+ Signature sig = Signature.getInstance(algo);
+ sig.initSign(key);
+ byte[] data = level2SignedData.encode();
+ sig.update(data);
+ byte[] signature = sig.sign();
+ this.level2Signature = new OctetString(signature);
+
+ }
+
+ /**
+ * Sign level 2 data.
+ *
+ * @param key the key
+ * @param prov the security Provider
+ * @throws Exception the exception
+ */
+ public void signLevel2(PrivateKey key, Provider prov) throws Exception {
+
+ //find the algorithm name for the signature OID
+ String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
+ Signature sig = Signature.getInstance(algo,prov);
+ sig.initSign(key);
+ byte[] data = level2SignedData.encode();
+ sig.update(data);
+ this.level2Signature = new OctetString(sig.sign());
+
+ }
+
+
+ /**
+ * Adds the dynamic content and encodes it. (API level)
+ *
+ * @param content the dynamic content
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
+
+
+ this.getLevel2SignedData().setLevel2Data(new DataType());
+
+ this.getLevel2SignedData().getLevel2Data().setFormat(DynamicContentCoder.dynamicContentDataFDC1);
+
+ this.getLevel2SignedData().getLevel2Data().setByteData(DynamicContentCoder.encode(content, DynamicContentCoder.dynamicContentDataFDC1));
+
+ }
+
+ /**
+ * Adds the level 2 dynamic data. (ASN level)
+ *
+ * @param dynamicData the dynamic data
+ */
+ public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
+ DataType dt = new DataType();
+ dt.setByteData(dynamicData.getDataType().getByteData());
+ dt.setFormat(dynamicData.getDataType().getFormat());
+ level2SignedData.setLevel2Data(dt);
+ }
+
+ /**
+ * Gets the dynamic content.
+ *
+ * @return the dynamic content
+ */
+ public IUicDynamicContent getDynamicContent() {
+
+ if (this.getLevel2SignedData() == null ||
+ this.getLevel2SignedData().getLevel2Data() == null){
+ return null;
+ }
+
+ return DynamicContentCoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData());
+
+ }
+
+ /**
+ * Gets the dynamic data FDC 1.
+ *
+ * @return the dynamic data FDC 1
+ */
+ public UicDynamicContentDataFDC1 getDynamicDataFDC1() {
+
+ if (this.getLevel2SignedData() == null ||
+ this.getLevel2SignedData().getLevel2Data() == null){
+ return null;
+ }
+
+ if ( UicDynamicContentDataFDC1.getFormat().equals(this.getLevel2SignedData().getLevel2Data().getFormat())) {
+ return UperEncoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData(), UicDynamicContentDataFDC1.class);
+ }
+ return null;
+
+ }
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
new file mode 100644
index 0000000..5d980dd
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
@@ -0,0 +1,235 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.dynamicFrame.v2.DynamicFrame;
+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.SimpleData;
+import org.uic.barcode.dynamicFrame.api.SimpleLevel1Data;
+import org.uic.barcode.dynamicFrame.api.SimpleLevel2Data;
+import org.uic.barcode.dynamicFrame.v2.Level2DataType;
+import org.uic.barcode.dynamicFrame.v2.DataType;
+import org.uic.barcode.dynamicFrame.v2.Level1DataType;
+import org.uic.barcode.dynamicFrame.v2.SequenceOfDataType;
+import org.uic.barcode.ticket.EncodingFormatException;
+
+public class DynamicFrameCoderV2 {
+
+ public static void decode(IDynamicFrame frame, byte[] bytes) {
+
+ DynamicFrame asnFrame = UperEncoder.decode(bytes,DynamicFrame.class);
+
+ frame.setFormat(asnFrame.getFormat());
+
+ if (asnFrame.getLevel2Signature() != null) {
+ frame.setLevel2Signature(asnFrame.getLevel2Signature().toByteArray());
+ }
+
+ if (asnFrame.getLevel2SignedData() != null) {
+ frame.setLevel2Data(new SimpleLevel2Data());
+ populateApi(frame.getLevel2Data(), asnFrame.getLevel2SignedData());
+ }
+
+ }
+
+ 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) {
+ level2.setLevel1Data(new SimpleLevel1Data());
+ level2.setLevel1Data(populateApi(asnLevel2.getLevel1Data()));
+ }
+
+ if (asnLevel2.getLevel2Data() != null) {
+ level2.setLevel2Data(new SimpleData());
+ level2.setLevel2Data(populateApi(asnLevel2.getLevel2Data()));
+ }
+
+ }
+
+ private static IData populateApi(DataType asnData) {
+
+ IData data = new SimpleData();
+ data.setData(asnData.getByteData());
+ data.setFormat(asnData.getFormat());
+ return data;
+ }
+
+ private static ILevel1Data populateApi(Level1DataType asnLevel1) {
+
+ ILevel1Data level1 = new SimpleLevel1Data();
+
+ level1.setKeyId(asnLevel1.getKeyId());
+ level1.setSecurityProvider(asnLevel1.getSecurityProvider());
+ level1.setLevel1KeyAlg(asnLevel1.getLevel1KeyAlg());
+ level1.setLevel1SigningAlg(asnLevel1.getLevel1SigningAlg());
+ level1.setLevel2KeyAlg(asnLevel1.getLevel2KeyAlg());
+ level1.setLevel2SigningAlg(asnLevel1.getLevel2SigningAlg());
+ if (asnLevel1.getLevel2publicKey() != null) {
+ level1.setLevel2publicKey(asnLevel1.getLevel2publicKey().toByteArray());
+ }
+
+ if (asnLevel1.getData() != null && !asnLevel1.getData().isEmpty()) {
+
+ for (DataType asnData : asnLevel1.getData()) {
+ IData data = new SimpleData();
+ data.setData(asnData.getByteData());
+ data.setFormat(asnData.getFormat());
+ level1.addData(data);
+ }
+ }
+
+ if (asnLevel1.getEndOfValidityDate() != null) {
+ level1.setEndOfBarcodeValidity(asnLevel1.getEndOfValidityDate());
+ }
+
+ level1.setValidityDuration(asnLevel1.getValidityDuration());
+
+ return level1;
+ }
+
+ public static byte[] encode(IDynamicFrame dynamicFrame) throws EncodingFormatException {
+
+ DynamicFrame asnDynamicFrame = populateAsn(dynamicFrame);
+
+ return UperEncoder.encode(asnDynamicFrame);
+
+ }
+
+
+
+ public static byte[] encode(ILevel1Data level1Data) throws EncodingFormatException {
+
+ Level1DataType asn = populateAsn(level1Data);
+
+ return UperEncoder.encode(asn);
+ }
+
+ public static byte[] encodeLevel2Data(ILevel2Data level2SignedData) throws EncodingFormatException {
+
+ Level2DataType asn = populateAsn(level2SignedData);
+
+ return UperEncoder.encode(asn);
+ }
+
+ private static DynamicFrame populateAsn(IDynamicFrame frame) throws EncodingFormatException {
+
+ DynamicFrame asnFrame = new DynamicFrame();
+
+ asnFrame.setFormat(frame.getFormat());
+
+ if (frame.getLevel2Signature() != null && frame.getLevel2Signature().length > 0) {
+ asnFrame.setLevel2Signature(new OctetString(frame.getLevel2Signature()));
+ }
+
+ Level2DataType asnLevel2 = populateAsn(frame.getLevel2Data());
+ if (asnLevel2 != null) {
+ asnFrame.setLevel2SignedData(asnLevel2);
+ }
+
+ return asnFrame;
+ }
+
+
+ private static Level2DataType populateAsn(ILevel2Data level2) throws EncodingFormatException {
+
+ Level2DataType asnLevel2 = new Level2DataType();
+
+ asnLevel2.setLevel1Signature(level2.getLevel1Signature());
+
+ Level1DataType asnLevel1 = populateAsn(level2.getLevel1Data());
+
+ asnLevel2.setLevel1Data(asnLevel1);
+
+ if (level2.getLevel2Data() != null) {
+ DataType data2 = new DataType();
+ data2.setFormat(level2.getLevel2Data().getFormat());
+ data2.setData(new OctetString(level2.getLevel2Data().getData()));
+ asnLevel2.setLevel2Data(data2);
+ }
+
+
+
+ return asnLevel2;
+ }
+
+ private static Level1DataType populateAsn(ILevel1Data level1) throws EncodingFormatException {
+
+ Level1DataType asnLevel1 = new Level1DataType();
+
+ asnLevel1.setSecurityProvider(level1.getSecurityProvider());
+
+ asnLevel1.setKeyId(level1.getKeyId());
+
+ asnLevel1.setLevel1KeyAlg(level1.getLevel1KeyAlg());
+
+ asnLevel1.setLevel1SigningAlg(level1.getLevel1SigningAlg());
+
+ asnLevel1.setLevel2KeyAlg(level1.getLevel2KeyAlg());
+
+ if (level1.getLevel2publicKey() != null && level1.getLevel2publicKey().length > 0) {
+ asnLevel1.setLevel2publicKey(new OctetString(level1.getLevel2publicKey()));
+ }
+
+ asnLevel1.setLevel2SigningAlg(level1.getLevel2SigningAlg());
+
+ if (level1.getData() != null && !level1.getData().isEmpty()) {
+
+ asnLevel1.setData(new SequenceOfDataType());
+
+ for (IData data : level1.getData()) {
+
+ DataType asnData = new DataType();
+ asnData.setByteData(data.getData());
+ asnData.setFormat(data.getFormat());
+ asnLevel1.getData().add(asnData);
+
+ }
+
+ }
+
+ asnLevel1.setEndOfValidityDate(level1.getEndOfBarcodeValidity());
+
+ asnLevel1.setValidityDuration(level1.getValidityDuration());
+
+
+ return asnLevel1;
+ }
+
+ public static byte[] getEncoded(String path, byte[] data) {
+
+ if (path.endsWith("Level1Data")){
+ return UperEncoder.extract(data, "Level1DataType" ,DynamicFrame.class );
+ } else if (path.endsWith("Level2Data")){
+ return UperEncoder.extract(data, "Level2DataType" ,DynamicFrame.class );
+ }
+
+ 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
new file mode 100644
index 0000000..b42e9dc
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java
@@ -0,0 +1,392 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+import java.util.Calendar;
+import java.util.Date;
+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.IntRange;
+import org.uic.barcode.asn1.datatypes.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.datatypesimpl.OctetString;
+import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.ticket.api.utils.UicEncoderUtils;
+
+/**
+ * The Class SignedDataType.
+ */
+@Sequence
+public class Level1DataType {
+
+ /**
+ * The security provider
+ * numeric codes 1 ...32000
+ *
+ * */
+ @FieldOrder(order = 0)
+ @IntRange(minValue=1,maxValue=32000)
+ @Asn1Optional public Long securityProviderNum;
+
+ /** The security provider alphanumeric codes. */
+ @FieldOrder(order = 1)
+ @RestrictedString(CharacterRestriction.IA5String)
+ @Asn1Optional public String securityProviderIA5;
+
+
+ /** The key id. */
+ @FieldOrder(order = 2)
+ @IntRange(minValue=0,maxValue=99999)
+ @Asn1Optional public Long keyId;
+
+
+ /** The data. */
+ @FieldOrder(order = 3)
+ public SequenceOfDataType data;
+
+ /**
+ * The key generator algorithms
+ * Object Identifier of the Algorithm
+ * Number notation:
+ *
+ * e.g.:
+ * -- DSA SHA224 2.16.840.1.101.3.4.3.1
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
+ * -- ECC 256 1.2.840.10045.3.1.7
+ *
+ *
+ */
+ @FieldOrder(order = 4)
+ @RestrictedString(CharacterRestriction.ObjectIdentifier)
+ @Asn1Optional public String level1KeyAlg;
+
+ /** The level 2 key alg. */
+ @FieldOrder(order = 5)
+ @RestrictedString(CharacterRestriction.ObjectIdentifier)
+ @Asn1Optional public String level2KeyAlg;
+
+ /**
+ * The signing algorithm
+ * Object Identifier of the Algorithms
+ * Number notation:
+ *
+ * e.g.:
+ * -- DSA SHA224 2.16.840.1.101.3.4.3.1
+ * -- DSA SHA256 2.16.840.1.101.3.4.3.2
+ * -- ECC 256 1.2.840.10045.3.1.7
+ *
+ *
+ */
+ @FieldOrder(order = 6)
+ @RestrictedString(CharacterRestriction.ObjectIdentifier)
+ @Asn1Optional public String level1SigningAlg;
+
+ /** The level 2 signing alg. */
+ @FieldOrder(order = 7)
+ @RestrictedString(CharacterRestriction.ObjectIdentifier)
+ @Asn1Optional public String level2SigningAlg;
+
+
+ /** The level 2 public key. */
+ @FieldOrder(order = 8)
+ @Asn1Optional public OctetString level2publicKey;
+
+
+ /** The End of validity year. */
+ @FieldOrder(order = 9)
+ @IntRange(minValue=2016,maxValue=2269)
+ @Asn1Optional public Long endOfValidityYear;
+
+ /** The End of validity day. */
+ @FieldOrder(order = 10)
+ @IntRange(minValue=1,maxValue=366)
+ @Asn1Optional public Long endOfValidityDay;
+
+ /** The End of validity time. */
+ @FieldOrder(order = 11)
+ @IntRange(minValue=0,maxValue=1439)
+ @Asn1Optional public Long endOfValidityTime;
+
+ /** The validity duration in seconds. */
+ @FieldOrder(order = 12)
+ @IntRange(minValue=1,maxValue=3600)
+ @Asn1Optional public Long validityDuration;
+
+
+
+
+ /**
+ * Gets the security provider num.
+ *
+ * @return the security provider num
+ */
+ public Long getSecurityProviderNum() {
+ return securityProviderNum;
+ }
+
+ /**
+ * Sets the security provider num.
+ *
+ * in case the security provider code is encoded in IA5 this will return null
+ *
+ * @param securityProviderNum the new security provider num
+ */
+ public void setSecurityProviderNum(Long securityProviderNum) {
+ this.securityProviderNum = securityProviderNum;
+ }
+
+ /**
+ * Gets the security provider IA5.
+ *
+ * in case the security provider code is encoded numerically this will return null
+ *
+ * @return the security provider IA5
+ */
+ public String getSecurityProviderIA5() {
+ return securityProviderIA5;
+ }
+
+ /**
+ * Sets the security provider
+ *
+ * The security provider code must use the IA5 Alphabet .
+ *
+ * @param securityProvider the new security provider
+ * @throws EncodingFormatException the encoding format exception
+ */
+ public void setSecurityProvider(String securityProvider) throws EncodingFormatException {
+ this.securityProviderNum = UicEncoderUtils.getNum(securityProvider);
+ this.securityProviderIA5 = UicEncoderUtils.getIA5NonNum(securityProvider);
+ }
+
+
+ /**
+ * Gets the security provider.
+ *
+ * @return the security provider
+ */
+ public String getSecurityProvider() {
+ return UicEncoderUtils.mapToString(this.securityProviderNum, this.securityProviderIA5);
+ }
+
+
+ /**
+ * Sets the security provider IA 5.
+ *
+ * @param securityProviderIA5 the new security provider IA 5
+ */
+ public void setSecurityProviderIA5(String securityProviderIA5) {
+ this.securityProviderIA5 = securityProviderIA5;
+ }
+
+ /**
+ * Gets the key id.
+ *
+ * @return the key id
+ */
+ public Long getKeyId() {
+ return keyId;
+ }
+
+ /**
+ * Sets the key id.
+ *
+ * @param keyId the new key id
+ */
+ public void setKeyId(Long keyId) {
+ this.keyId = keyId;
+ }
+
+ /**
+ * Gets the data.
+ *
+ * @return the data
+ */
+ public SequenceOfDataType getData() {
+ return data;
+ }
+
+ /**
+ * Sets the data.
+ *
+ * @param data the new data
+ */
+ public void setData(SequenceOfDataType data) {
+ this.data = data;
+ }
+
+ /**
+ * Gets the level 2 key alg.
+ *
+ * @return the level 2 key alg
+ */
+ public String getLevel2KeyAlg() {
+ return level2KeyAlg;
+ }
+
+ /**
+ * Sets the level 2 key alg.
+ *
+ * @param level2KeyAlg the new level 2 key alg
+ */
+ public void setLevel2KeyAlg(String level2KeyAlg) {
+ this.level2KeyAlg = level2KeyAlg;
+ }
+
+ /**
+ * Gets the level 1 signing alg.
+ *
+ * @return the level 1 signing alg
+ */
+ public String getLevel1SigningAlg() {
+ return level1SigningAlg;
+ }
+
+ /**
+ * Sets the level 1 signing alg.
+ *
+ * @param level1SigningAlg the new level 1 signing alg
+ */
+ public void setLevel1SigningAlg(String level1SigningAlg) {
+ this.level1SigningAlg = level1SigningAlg;
+ }
+
+ /**
+ * Gets the level 2 signing alg.
+ *
+ * @return the level 2 signing alg
+ */
+ public String getLevel2SigningAlg() {
+ return level2SigningAlg;
+ }
+
+ /**
+ * Sets the level 2 signing alg.
+ *
+ * @param level2SigningAlg the new level 2 signing alg
+ */
+ public void setLevel2SigningAlg(String level2SigningAlg) {
+ this.level2SigningAlg = level2SigningAlg;
+ }
+
+ /**
+ * Gets the level 2 public key.
+ *
+ * @return the level 2 public key
+ */
+ public OctetString getLevel2publicKey() {
+ return level2publicKey;
+ }
+
+ /**
+ * Sets the level 2 public key.
+ *
+ * @param level2publicKey the new level 2 public key
+ */
+ public void setLevel2publicKey(OctetString level2publicKey) {
+ this.level2publicKey = level2publicKey;
+ }
+
+
+
+ /**
+ * Gets the level 1 key alg.
+ *
+ * @return the level 1 key alg
+ */
+ public String getLevel1KeyAlg() {
+ return level1KeyAlg;
+ }
+
+ /**
+ * Sets the level 1 key alg.
+ *
+ * @param level1KeyAlg the new level 1 key alg
+ */
+ public void setLevel1KeyAlg(String level1KeyAlg) {
+ this.level1KeyAlg = level1KeyAlg;
+ }
+
+ /**
+ * Sets the end of validity date.
+ * @param date the new end of validity date
+ */
+ public void setEndOfValidityDate(Date date){
+
+ if (date == null) return;
+
+ TimeZone local = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
+ 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));
+ int time = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE);
+ if (time >= 0) {
+ this.endOfValidityTime = new Long (time );
+ }
+ TimeZone.setDefault(local);
+
+ }
+
+ /**
+ * Gets the end of validity date.
+ *
+ * @return the end of validity date
+ */
+ public Date getEndOfValidityDate() {
+
+ if (this.endOfValidityYear == null || this.endOfValidityDay == null) return null;
+
+ TimeZone local = TimeZone.getDefault();
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
+ 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());
+
+ if (this.endOfValidityTime != null) {
+
+ int hours = this.endOfValidityTime.intValue() / 60;
+ int minutes = this.endOfValidityTime.intValue() % 60;
+ cal.set(Calendar.HOUR_OF_DAY, hours);
+ cal.set(Calendar.MINUTE,minutes);
+
+ }
+
+ Date d = cal.getTime();
+
+ TimeZone.setDefault(local);
+
+ return d;
+ }
+
+
+
+ public Long getValidityDuration() {
+ return validityDuration;
+ }
+
+ public void setValidityDuration(Long validityDuration) {
+ this.validityDuration = validityDuration;
+ }
+
+ /**
+ * Gets the data for signature.
+ *
+ * The byte array containing the ASN.1 PER UNALIGNED encoded data of the DataBlock
+ *
+ *
+ * @return the data for signature
+ */
+ public byte[] encode() {
+ return UperEncoder.encode(this);
+
+ }
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java
index 8c3cd60..cd0800e 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java
@@ -1,4 +1,4 @@
-package org.uic.barcode.dynamicFrame;
+package org.uic.barcode.dynamicFrame.v2;
import java.security.PrivateKey;
import java.security.Provider;
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/SequenceOfDataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/SequenceOfDataType.java
new file mode 100644
index 0000000..fc76776
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/SequenceOfDataType.java
@@ -0,0 +1,25 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+
+import java.util.Collection;
+
+import org.uic.barcode.asn1.datatypes.Asn1SequenceOf;
+
+/**
+ * The Class SequenceOfDataType.
+ */
+public class SequenceOfDataType extends Asn1SequenceOf<DataType>{
+
+ /**
+ * Instantiates a new sequence of data type.
+ */
+ public SequenceOfDataType() { super(); }
+
+ /**
+ * Instantiates a new sequence of data type.
+ *
+ * @param coll the coll
+ */
+ public SequenceOfDataType(Collection<DataType> coll) { super(coll); }
+
+}