From 12b733b1062430ce4bad08c077148a7d235439f3 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Wed, 15 Dec 2021 16:36:47 +0100
Subject: - unit test for the dynamic content in DOSIPAS - api layoer for the
 dynamic content in DOSIPAS

---
 .../org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java  | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
index e8f3695..3ced173 100644
--- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
@@ -181,6 +181,8 @@ public class UicDynamicContentDataFDC1  {
 		this.timeStamp = timeStamp;
 	}
 
+	
+	
 	public SequenceOfExtension getExtensions() {
 		return dynamicContentResponseToChallenge;
 	}
-- 
cgit v1.2.3


From fbbc6349283bc8958cad51534da9cb82c46210c9 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Wed, 15 Dec 2021 16:37:37 +0100
Subject: api layer for dynamic content

---
 .../dynamicContent/api/DynamicContentCoder.java    | 211 +++++++++++++++++++++
 .../dynamicContent/api/IUicDynamicContent.java     | 130 +++++++++++++
 .../api/SimpleUicDynamicContent.java               | 150 +++++++++++++++
 3 files changed, 491 insertions(+)
 create mode 100644 src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicContent/api/SimpleUicDynamicContent.java

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java b/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
new file mode 100644
index 0000000..d8bf3b4
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
@@ -0,0 +1,211 @@
+package org.uic.barcode.dynamicContent.api;
+
+import java.util.Date;
+import java.util.List;
+
+import org.uic.barcode.dynamicContent.fdc1.GeoCoordinateType;
+import org.uic.barcode.dynamicContent.fdc1.SequenceOfExtension;
+import org.uic.barcode.dynamicContent.fdc1.TimeStamp;
+import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
+import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.asn1.uper.UperEncoder;
+import org.uic.barcode.dynamicContent.fdc1.ExtensionData;
+import org.uic.barcode.dynamicContent.fdc1.GeoCoordinateSystemType;
+import org.uic.barcode.dynamicContent.fdc1.GeoUnitType;
+import org.uic.barcode.dynamicContent.fdc1.HemisphereLatitudeType;
+import org.uic.barcode.dynamicContent.fdc1.HemisphereLongitudeType;
+import org.uic.barcode.ticket.api.impl.SimpleExtension;
+import org.uic.barcode.ticket.api.impl.SimpleGeoCoordinate;
+import org.uic.barcode.ticket.api.spec.IExtension;
+import org.uic.barcode.ticket.api.spec.IGeoCoordinate;
+import org.uic.barcode.ticket.api.spec.IGeoCoordinateSystemType;
+import org.uic.barcode.ticket.api.spec.IGeoUnitType;
+import org.uic.barcode.ticket.api.spec.IHemisphereLatitudeType;
+import org.uic.barcode.ticket.api.spec.IHemisphereLongitudeType;
+import org.uic.barcode.ticket.api.utils.UicEncoderUtils;
+
+public class DynamicContentCoder {
+	
+	public static byte[] encode(IUicDynamicContent content, String format) throws EncodingFormatException {
+		
+		if (format != null && !format.equals("FDC1")) {
+			throw new EncodingFormatException("Format of dynamic content not supported!");
+		}
+				
+		UicDynamicContentDataFDC1 asn = new UicDynamicContentDataFDC1();
+		
+		asn.setAppId(content.getAppId());
+		
+		if (content.getChallengeString() != null && content.getChallengeString().length() > 0) {
+			asn.setChallengeString(content.getChallengeString());
+		}
+
+		asn.setDynamicContentExtension(getAsnExtension(content.getExtension()));
+		
+		asn.setGeoCoordinate(getAsnGeoCoordinate(content.getGeoCoordinate()));
+		
+		asn.setTimeStamp(getAsnTimeStamp(content.getTimeStamp()));
+		
+		asn.setExtensions(getAsnContentExtensions(asn, content.getDynamicContentResponseList()));
+		
+		return UperEncoder.encode(asn);
+		
+	}
+	
+	
+
+	private static SequenceOfExtension getAsnContentExtensions(UicDynamicContentDataFDC1 asn, List<IExtension> dynamicContentResponseList) throws EncodingFormatException {
+		if (dynamicContentResponseList != null && !dynamicContentResponseList.isEmpty()){
+			
+			SequenceOfExtension asnList = asn.getExtensions();
+			if (asnList == null) asnList = new SequenceOfExtension();
+			for (IExtension extension : dynamicContentResponseList){
+				ExtensionData asnExtension = getAsnExtension(extension);
+				if (asnExtension!= null) {
+					asnList.add(asnExtension);
+				}
+			}
+			if (!asnList.isEmpty()){
+				return asnList;
+			}
+		}
+	
+		return null;
+	}
+
+	private static TimeStamp getAsnTimeStamp(Date date) {
+		
+		if (date == null) return null;
+		
+		TimeStamp asnTimeStamp = new TimeStamp();
+		asnTimeStamp.setDateTime(date);
+		
+		return asnTimeStamp;
+		
+	}
+
+	private static GeoCoordinateType getAsnGeoCoordinate(IGeoCoordinate point) {
+			
+			if (point == null) return null;
+			
+			GeoCoordinateType asnPoint = new GeoCoordinateType();
+			
+			asnPoint.setLatitude(point.getLatitude());  
+			asnPoint.setLongitude(point.getLongitude());
+			
+			if (point.getUnit() != IGeoUnitType.milliDegree && point.getUnit() != null){
+				asnPoint.setGeoUnit(GeoUnitType.valueOf(point.getUnit().name()));
+			}
+			
+			if (point.getAccuracy() != null) {
+				asnPoint.setAccuracy(GeoUnitType.valueOf(point.getAccuracy().name()));
+			}
+			
+			if (point.getHemisphereLatitude() != IHemisphereLatitudeType.east && point.getHemisphereLatitude() != null) {
+				asnPoint.setHemisphereLatitude(HemisphereLatitudeType.valueOf(point.getHemisphereLatitude().name()));
+			}
+			
+			if (point.getHemisphereLongitude() != IHemisphereLongitudeType.north && point.getHemisphereLongitude() != null) {
+				asnPoint.setHemisphereLongitude(HemisphereLongitudeType.valueOf(point.getHemisphereLongitude().name()));
+			}		
+			
+			if (point.getSystem() != IGeoCoordinateSystemType.wgs84 && point.getSystem() != null){
+				asnPoint.setCoordinateSystem(GeoCoordinateSystemType.valueOf(point.getSystem().name()));
+			}
+
+
+			return asnPoint;
+	}
+
+	private static ExtensionData getAsnExtension(IExtension extension) throws EncodingFormatException {
+		if (extension==null) return null;
+		
+		if (extension.getBinarydata() == null || extension.getBinarydata().length == 0) {
+			throw new EncodingFormatException("Extension does not include data");
+		}
+
+		if (extension.getId() == null || extension.getId().length() == 0) {
+			throw new EncodingFormatException("Extension does not include id");
+		}
+		
+		ExtensionData asnExtension = new ExtensionData();
+		
+		asnExtension.setExtensionData(extension.getBinarydata());
+		asnExtension.setExtensionId(UicEncoderUtils.getIA5(extension.getId()));
+
+		return asnExtension;
+	}
+
+	public static IUicDynamicContent decode(byte[] bytes) {	
+		
+		UicDynamicContentDataFDC1 asn = UperEncoder.decode(bytes, UicDynamicContentDataFDC1.class);
+		
+		IUicDynamicContent content = new SimpleUicDynamicContent();
+		
+		content.setAppId(asn.getAppId());
+		
+		content.setChallengeString(asn.getChallengeString());
+
+		content.setExtension(getExtension(asn.getDynamicContentExtension()));
+		
+		if (asn.getExtensions() != null && !asn.getExtensions().isEmpty()) {
+			for (ExtensionData e : asn.getExtensions())	{	
+				content.addDynamicContentResponse(getExtension(e));
+			}
+		}
+		
+		content.setGeoCoordinate(getGeoCoordinate(asn.getGeoCoordinate()));
+		
+		content.setTimeStamp(asn.getTimeStamp().getTimeAsDate());
+		
+
+		return content;
+
+	}
+
+	private static IGeoCoordinate getGeoCoordinate(GeoCoordinateType asnCoordinate) {
+		
+		IGeoCoordinate g = new SimpleGeoCoordinate();
+		
+		g.setLatitude(asnCoordinate.getLatitude());
+		g.setLongitude(asnCoordinate.getLongitude());
+		
+		if (asnCoordinate.getCoordinateSystem() != null) {
+			g.setSystem(IGeoCoordinateSystemType.valueOf(asnCoordinate.getCoordinateSystem().name()));
+		}
+		
+		if (asnCoordinate.getAccuracy() != null) {
+			g.setAccuracy(IGeoUnitType.valueOf(asnCoordinate.getAccuracy().name()));
+		}		
+		
+		if (asnCoordinate.getGeoUnit() != null) {
+			g.setUnit(IGeoUnitType.valueOf(asnCoordinate.getGeoUnit().name()));
+		}
+		
+		if (asnCoordinate.getHemisphereLatitude() != null) {
+			g.setHemisphereLatitude(IHemisphereLatitudeType.valueOf(asnCoordinate.getHemisphereLatitude().name()));
+		}
+
+		if (asnCoordinate.getHemisphereLongitude() != null) {
+			g.setHemisphereLongitude(IHemisphereLongitudeType.valueOf(asnCoordinate.getHemisphereLongitude().name()));
+		}	
+		
+		
+		return g;
+	}
+
+
+
+	private static IExtension getExtension(ExtensionData asnExtension) {
+		
+		if (asnExtension == null) return null;
+		
+		SimpleExtension e = new SimpleExtension();
+		e.setBinarydata(asnExtension.getExtensionData());
+		e.setId(asnExtension.getExtensionId());
+		
+		return e;
+	}
+	
+	
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java b/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java
new file mode 100644
index 0000000..718d013
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/api/IUicDynamicContent.java
@@ -0,0 +1,130 @@
+package org.uic.barcode.dynamicContent.api;
+
+import java.util.Date;
+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.
+ */
+public interface IUicDynamicContent {
+	
+	/**
+	 * Gets the app id.
+	 *
+	 * @return the app id
+	 */
+	public String getAppId();
+	
+	/**
+	 * Sets the app id.
+	 * @param string 
+	 *
+	 * @return the string
+	 */
+	public void setAppId(String string);
+	
+	/**
+	 * Gets the time stamp.
+	 *
+	 * @return the time stamp
+	 */
+	public Date getTimeStamp();
+		
+	/**
+	 * Sets the time stamp.
+	 *
+	 * @param date the new time stamp
+	 */
+	public void setTimeStamp(Date date);
+	
+	/**
+	 * Gets the geo coordinate.
+	 *
+	 * @return the geo coordinate
+	 */
+	public IGeoCoordinate getGeoCoordinate(); 
+	
+	/**
+	 * Sets the geo coordinate.
+	 *
+	 * @param geoCoordinate the new geo coordinate
+	 */
+	public void setGeoCoordinate(IGeoCoordinate geoCoordinate); 
+	
+	
+	/**
+	 * Gets the extension.
+	 *
+	 * @return the extension
+	 */
+	public IExtension getExtension();
+	
+	/**
+	 * Sets the extension.
+	 *
+	 * @param extension the new extension
+	 */
+	public void setExtension(IExtension extension);
+	
+	/**
+	 * Gets the challenge string.
+	 *
+	 * @return the challenge string
+	 */
+	public String getChallengeString();
+	
+	/**
+	 * Sets the challenge string.
+	 *
+	 * @param challenge the new challenge string
+	 */
+	public void setChallengeString(String challenge);
+	
+	/**
+	 * Gets the phone id hash.
+	 *
+	 * @return the phone id hash
+	 */
+	public byte[] getPhoneIdHash();
+	
+	/**
+	 * Sets the phone id hash.
+	 *
+	 * @param phoneIdHash the new phone id hash
+	 */
+	public void setPhoneIdHash(byte[] phoneIdHash);
+
+	/**
+	 * Gets the pass id hash.
+	 *
+	 * @return the pass id hash
+	 */
+	public byte[] getPassIdHash();
+
+	/**
+	 * Sets the pass id hash.
+	 *
+	 * @param passIdHash the new pass id hash
+	 */
+	public void setPassIdHash(byte[] passIdHash);
+	
+	/**
+	 * Gets the dynamic content response list.
+	 *
+	 * @return the dynamic content response list
+	 */
+	public List<IExtension> getDynamicContentResponseList();
+		
+	/**
+	 * Adds the dynamic content response.
+	 *
+	 * @param challenge the challenge
+	 */
+	public void addDynamicContentResponse(IExtension challenge);
+	
+	
+}
diff --git a/src/main/java/org/uic/barcode/dynamicContent/api/SimpleUicDynamicContent.java b/src/main/java/org/uic/barcode/dynamicContent/api/SimpleUicDynamicContent.java
new file mode 100644
index 0000000..ca5880d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicContent/api/SimpleUicDynamicContent.java
@@ -0,0 +1,150 @@
+package org.uic.barcode.dynamicContent.api;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.uic.barcode.ticket.api.impl.SimpleExtension;
+import org.uic.barcode.ticket.api.spec.IExtension;
+import org.uic.barcode.ticket.api.spec.IGeoCoordinate;
+
+public class SimpleUicDynamicContent implements IUicDynamicContent {
+	
+	
+	protected String appId;	
+
+	protected Date timeStamp;
+	
+	protected String challenge;	
+	
+	protected IGeoCoordinate geoCoordinate;
+	
+	protected IExtension dynamicContentExtension;
+	
+	protected List<IExtension> dynamicContentResponseList;
+	
+	
+	
+	public String getAppId() {
+		return appId;
+	}
+
+	public void setAppId(String appId) {
+		this.appId = appId;
+	}
+
+
+	public IGeoCoordinate getGeoCoordinate() {
+		return geoCoordinate;
+	}
+
+	public void setGeoCoordinate(IGeoCoordinate geoCoordinate) {
+		this.geoCoordinate = geoCoordinate;
+	}
+
+	public IExtension getDynamicContentExtension() {
+		return dynamicContentExtension;
+	}
+
+	public void setDynamicContentExtension(IExtension dynamicContentExtension) {
+		this.dynamicContentExtension = dynamicContentExtension;
+	}
+
+
+	@Override
+	public Date getTimeStamp() {
+		return timeStamp;
+	}
+
+	@Override
+	public void setTimeStamp(Date date) {
+		timeStamp = date;
+		
+	}
+
+	@Override
+	public IExtension getExtension() {
+		return dynamicContentExtension;
+	}
+
+	@Override
+	public void setExtension(IExtension extension) {
+		dynamicContentExtension = extension;
+	}
+
+	@Override
+	public String getChallengeString() {
+		return challenge;
+	}
+
+	@Override
+	public void setChallengeString(String challenge) {
+		this.challenge = challenge;		
+	}
+
+	@Override
+	public byte[] getPhoneIdHash() {
+		return getExtensionData("phone");
+	}
+
+	@Override
+	public void setPhoneIdHash(byte[] phoneIdHash) {
+		if (dynamicContentResponseList == null) {
+			dynamicContentResponseList = new ArrayList<IExtension>();
+		}
+		
+		IExtension e = new SimpleExtension();
+		e.setBinarydata(phoneIdHash);
+		e.setId("phone");
+		getDynamicContentResponseList().add(e);
+	}
+
+	@Override
+	public byte[] getPassIdHash() {
+		return getExtensionData("pass");
+	}
+
+	private byte[] getExtensionData(String name) {
+		if (dynamicContentResponseList == null) return null;
+		for (IExtension e : dynamicContentResponseList) {
+			if (e.getId().equals(name)){
+				return e.getBinarydata();
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public void setPassIdHash(byte[] passIdHash) {
+		if (dynamicContentResponseList == null) {
+			dynamicContentResponseList = new ArrayList<IExtension>();
+		}
+		
+		IExtension e = new SimpleExtension();
+		e.setBinarydata(passIdHash);
+		e.setId("pass");
+		getDynamicContentResponseList().add(e);
+	}
+
+	@Override
+	public List<IExtension> getDynamicContentResponseList() {
+		if (dynamicContentResponseList == null) {
+			dynamicContentResponseList = new ArrayList<IExtension>();
+		}
+		
+		return dynamicContentResponseList;
+	}
+
+	@Override
+	public void addDynamicContentResponse(IExtension challenge) {
+		
+		if (this.dynamicContentResponseList == null) {
+			this.dynamicContentResponseList = new ArrayList<IExtension>();
+		}
+		
+		this.dynamicContentResponseList.add(challenge);
+
+	}
+	
+	
+}
-- 
cgit v1.2.3


From bdb54c653eda54b003e50460928cfd8bbc80bc44 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Thu, 16 Dec 2021 16:13:13 +0100
Subject: extended api for dynamic content additional tests

---
 src/main/java/org/uic/barcode/Decoder.java         | 12 +++
 src/main/java/org/uic/barcode/Encoder.java         | 18 +++++
 .../dynamicContent/api/DynamicContentCoder.java    |  4 +-
 .../uic/barcode/dynamicContent/fdc1/TimeStamp.java |  7 +-
 .../org/uic/barcode/dynamicFrame/DynamicFrame.java | 94 +++++++++++++++++++++-
 5 files changed, 132 insertions(+), 3 deletions(-)

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java
index 9f102d3..4c8b044 100644
--- a/src/main/java/org/uic/barcode/Decoder.java
+++ b/src/main/java/org/uic/barcode/Decoder.java
@@ -8,6 +8,7 @@ import java.security.PublicKey;
 import java.security.SignatureException;
 import java.util.zip.DataFormatException;
 
+import org.uic.barcode.dynamicContent.api.IUicDynamicContent;
 import org.uic.barcode.dynamicFrame.Constants;
 import org.uic.barcode.dynamicFrame.DataType;
 import org.uic.barcode.dynamicFrame.DynamicFrame;
@@ -237,6 +238,17 @@ public class Decoder {
 		return dynamicFrame;
 	}
 
+	/**
+	 * Gets the dynamic content.
+	 *
+	 * @return the dynamic header
+	 */
+	public IUicDynamicContent getDynamicContent() {
+		if (dynamicFrame == null) return null;
+		
+		return dynamicFrame.getDynamicContent();
+	}
+	
 	/**
 	 * Sets the dynamic header.
 	 *
diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java
index f0f8d14..3b30e8a 100644
--- a/src/main/java/org/uic/barcode/Encoder.java
+++ b/src/main/java/org/uic/barcode/Encoder.java
@@ -6,6 +6,7 @@ import java.security.Provider;
 import java.security.PublicKey;
 
 import org.uic.barcode.asn1.datatypesimpl.OctetString;
+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.DataType;
@@ -178,6 +179,15 @@ public class Encoder {
 		}
 	}
 	
+	public void setDynamicData(IUicDynamicContent content) throws EncodingFormatException {
+		if (dynamicFrame != null) {
+			if (dynamicFrame.getLevel2SignedData() == null) {
+				dynamicFrame.setLevel2SignedData(new Level2DataType());
+			}		
+			dynamicFrame.addDynamicContent(content);
+		}		
+	}
+	
 	public void setLevel2Data(DataType level2data) {
 		if (dynamicFrame != null) {
 			if (dynamicFrame.getLevel2SignedData() == null) {
@@ -203,6 +213,14 @@ public class Encoder {
 		return null;
 	}
 	
+	
+	public IUicDynamicContent getDynamicContent() {
+		if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
+			return dynamicFrame.getDynamicContent();
+		}
+		return null;
+	}
+	
 	public UicDynamicContentDataFDC1 getDynamicContentDataUIC1() {
 		if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
 			return dynamicFrame.getDynamicDataFDC1();
diff --git a/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java b/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
index d8bf3b4..34406e0 100644
--- a/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
+++ b/src/main/java/org/uic/barcode/dynamicContent/api/DynamicContentCoder.java
@@ -26,9 +26,11 @@ import org.uic.barcode.ticket.api.utils.UicEncoderUtils;
 
 public class DynamicContentCoder {
 	
+	public static String dynamicContentDataFDC1 = "FDC1";
+	
 	public static byte[] encode(IUicDynamicContent content, String format) throws EncodingFormatException {
 		
-		if (format != null && !format.equals("FDC1")) {
+		if (format != null && !format.equals(dynamicContentDataFDC1)) {
 			throw new EncodingFormatException("Format of dynamic content not supported!");
 		}
 				
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
index ecbb226..a1b9581 100644
--- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
@@ -91,8 +91,11 @@ public class TimeStamp {
 		this.secondOfDay = time;
 	}
 	
+	
+	
+	
 	/**
-	 * Gets the time.
+	 * Gets the current date and time in UTC
 	 *
 	 * @return the date and time of content creation in UTC
 	 */
@@ -136,4 +139,6 @@ public class TimeStamp {
 		
 	}
 
+	
+	
 }
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
index c74215d..eb26729 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
@@ -18,10 +18,14 @@ 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;
 
 
+// TODO: Auto-generated Javadoc
 /**
  * The DynamicHeader for bar codes 
  * 
@@ -30,6 +34,9 @@ import org.uic.barcode.utils.AlgorithmNameResolver;
 @Sequence
 public class DynamicFrame extends Object{
 	
+	/**
+	 * Instantiates a new dynamic frame.
+	 */
 	public DynamicFrame() {}
 
 	/** The format. */
@@ -37,12 +44,13 @@ public class DynamicFrame extends Object{
 	@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*/
+	/**  The signature of level 2 data. */
 	@FieldOrder(order = 2)
 	@Asn1Optional public OctetString level2Signature;
 	
@@ -64,18 +72,38 @@ public class DynamicFrame extends Object{
 		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;
 	}
@@ -108,6 +136,7 @@ public class DynamicFrame extends Object{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
+	 * @return the int
 	 */	
 	public int validateLevel2() {
 
@@ -120,6 +149,8 @@ public class DynamicFrame extends Object{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
+	 * @param prov the prov
+	 * @return the int
 	 */	
 	public int validateLevel2(Provider prov) {
 		
@@ -213,6 +244,9 @@ public class DynamicFrame extends Object{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
+	 * @param key the key
+	 * @param prov the prov
+	 * @return the int
 	 */
 	public int validateLevel1(PublicKey key, Provider prov) {
 		
@@ -282,6 +316,8 @@ public class DynamicFrame extends Object{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
+	 * @param key the key
+	 * @return the int
 	 */
 	public int validateLevel1(PublicKey key) {
 		
@@ -289,6 +325,12 @@ public class DynamicFrame extends Object{
 
   	}
 	
+	/**
+	 * 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
@@ -302,6 +344,13 @@ public class DynamicFrame extends Object{
 		
 	}
 
+	/**
+	 * 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
@@ -315,10 +364,53 @@ public class DynamicFrame extends Object{
 	}
 
 	
+	/**
+	 * 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) {
 		this.getLevel2SignedData().setLevel2Data( dynamicData.getDataType());	
 	}
 	
+	/**
+	 * 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 || 
-- 
cgit v1.2.3


From 17f05b763d70f350bad482df9378c571c2ebddf6 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Fri, 21 Jan 2022 18:19:36 +0100
Subject: new dynamic header version 2.0.0

---
 src/main/java/org/uic/barcode/Decoder.java         |  44 +-
 src/main/java/org/uic/barcode/Encoder.java         | 102 ++--
 .../uic/barcode/dynamicContent/fdc1/TimeStamp.java |   7 +-
 .../fdc1/UicDynamicContentDataFDC1.java            |  12 +-
 .../org/uic/barcode/dynamicFrame/Constants.java    |   2 +
 .../org/uic/barcode/dynamicFrame/DataType.java     |  93 ----
 .../org/uic/barcode/dynamicFrame/DynamicFrame.java | 429 ----------------
 .../uic/barcode/dynamicFrame/Level1DataType.java   | 226 ---------
 .../uic/barcode/dynamicFrame/Level2DataType.java   | 121 -----
 .../barcode/dynamicFrame/SequenceOfDataType.java   |  25 -
 .../org/uic/barcode/dynamicFrame/api/IData.java    |  39 ++
 .../barcode/dynamicFrame/api/IDynamicFrame.java    | 202 ++++++++
 .../uic/barcode/dynamicFrame/api/ILevel1Data.java  | 164 ++++++
 .../uic/barcode/dynamicFrame/api/ILevel2Data.java  |  25 +
 .../uic/barcode/dynamicFrame/api/SimpleData.java   |  59 +++
 .../dynamicFrame/api/SimpleDynamicFrame.java       | 553 +++++++++++++++++++++
 .../barcode/dynamicFrame/api/SimpleLevel1Data.java | 254 ++++++++++
 .../barcode/dynamicFrame/api/SimpleLevel2Data.java |  75 +++
 .../java/org/uic/barcode/dynamicFrame/package.html |   9 -
 .../org/uic/barcode/dynamicFrame/v1/DataType.java  |  93 ++++
 .../uic/barcode/dynamicFrame/v1/DynamicFrame.java  | 432 ++++++++++++++++
 .../dynamicFrame/v1/DynamicFrameCoderV1.java       | 189 +++++++
 .../barcode/dynamicFrame/v1/Level1DataType.java    | 226 +++++++++
 .../barcode/dynamicFrame/v1/Level2DataType.java    |  74 +++
 .../dynamicFrame/v1/SequenceOfDataType.java        |  25 +
 .../org/uic/barcode/dynamicFrame/v2/DataType.java  |  95 ++++
 .../uic/barcode/dynamicFrame/v2/DynamicFrame.java  | 434 ++++++++++++++++
 .../dynamicFrame/v2/DynamicFrameCoderV2.java       | 203 ++++++++
 .../barcode/dynamicFrame/v2/Level1DataType.java    | 374 ++++++++++++++
 .../barcode/dynamicFrame/v2/Level2DataType.java    | 123 +++++
 .../dynamicFrame/v2/SequenceOfDataType.java        |  25 +
 31 files changed, 3753 insertions(+), 981 deletions(-)
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/DataType.java
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/IData.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/ILevel2Data.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java
 delete mode 100644 src/main/java/org/uic/barcode/dynamicFrame/package.html
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/Level2DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/v2/SequenceOfDataType.java

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java
index 4c8b044..b980f19 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.DataType;
-import org.uic.barcode.dynamicFrame.DynamicFrame;
-import org.uic.barcode.dynamicFrame.Level1DataType;
-import org.uic.barcode.dynamicFrame.Level2DataType;
-import org.uic.barcode.dynamicFrame.SequenceOfDataType;
+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;
@@ -34,7 +34,7 @@ public class Decoder {
 	
 	
 	/** The dynamic frame. */
-	private DynamicFrame dynamicFrame = null;
+	private IDynamicFrame dynamicFrame = null;
 	
 	/** The static frame. */
 	private StaticFrame staticFrame = null;
@@ -123,8 +123,9 @@ public class Decoder {
 	 * Validate level 2.
 	 *
 	 * @return the return code indicating errors
+	 * @throws EncodingFormatException 
 	 */
-	public int validateLevel2() {
+	public int validateLevel2() throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
 			return dynamicFrame.validateLevel2() ;
 		} else {
@@ -137,7 +138,7 @@ public class Decoder {
 	 * @param prov - provider of the java security implementation in case a dedicated provider must be used
 	 * @return the return code indicating errors
 	 */
-	public int validateLevel2(Provider prov) {
+	public int validateLevel2(Provider prov) throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
 			return dynamicFrame.validateLevel2(prov) ;
 		} else {
@@ -157,24 +158,25 @@ public class Decoder {
 	public void decode(byte[] data) throws IOException, EncodingFormatException, DataFormatException {
 		
 		if (!isStaticHeader(data)) {
+			
+			dynamicFrame = new SimpleDynamicFrame();
 						
-			dynamicFrame = DynamicFrame.decode(data);
+			dynamicFrame.decode(data);
 			
-			Level2DataType level2 = dynamicFrame.getLevel2SignedData();
+			ILevel2Data level2 = dynamicFrame.getLevel2Data();
 			
-			Level1DataType level1 = level2.getLevel1Data();
+			ILevel1Data level1 = level2.getLevel1Data();
 			
-			SequenceOfDataType dataList = level1.getData();
 			
-			for (DataType level1Content : dataList) {
+			for (IData level1Content : level1.getData()) {
 				
 				uicTicketCoder = new UicRailTicketCoder();
 				if (level1Content.getFormat().equals("FCB1")) {
-					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 1);
+					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getData(), 1);
 				} else if (level1Content.getFormat().equals("FCB2")) {
-					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 2);
+					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getData(), 2);
 				} else if (level1Content.getFormat().equals("FCB3")) {
-					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 3);
+					uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getData(), 3);
 				}
 			}
 			
@@ -234,7 +236,7 @@ public class Decoder {
 	 *
 	 * @return the dynamic header
 	 */
-	public DynamicFrame getDynamicHeader() {
+	public IDynamicFrame getDynamicHeader() {
 		return dynamicFrame;
 	}
 
@@ -254,7 +256,7 @@ public class Decoder {
 	 *
 	 * @param dynamicHeader the new dynamic header
 	 */
-	public void setDynamicHeader(DynamicFrame dynamicHeader) {
+	public void setDynamicHeader(IDynamicFrame dynamicHeader) {
 		this.dynamicFrame = dynamicHeader;
 	}
 
@@ -276,9 +278,9 @@ public class Decoder {
 		this.staticFrame = staticFrame;
 	}
 
-	public DataType getLevel2Data() {
-		if (!isStaticHeader(data) && dynamicFrame.getLevel2SignedData() != null) {
-			return dynamicFrame.getLevel2SignedData().getLevel2Data();
+	public IData getLevel2Data() {
+		if (!isStaticHeader(data) && dynamicFrame.getLevel2Data() != null) {
+			return dynamicFrame.getLevel2Data().getLevel2Data();
 		}
 		return null;
 	}
diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java
index 3b30e8a..5f10806 100644
--- a/src/main/java/org/uic/barcode/Encoder.java
+++ b/src/main/java/org/uic/barcode/Encoder.java
@@ -5,15 +5,15 @@ import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
 
-import org.uic.barcode.asn1.datatypesimpl.OctetString;
 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.DataType;
-import org.uic.barcode.dynamicFrame.DynamicFrame;
-import org.uic.barcode.dynamicFrame.Level1DataType;
-import org.uic.barcode.dynamicFrame.Level2DataType;
-import org.uic.barcode.dynamicFrame.SequenceOfDataType;
+import org.uic.barcode.dynamicFrame.api.IData;
+import org.uic.barcode.dynamicFrame.api.IDynamicFrame;
+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.staticFrame.StaticFrame;
 import org.uic.barcode.staticFrame.UFLEXDataRecord;
 import org.uic.barcode.staticFrame.UHEADDataRecord;
@@ -34,7 +34,7 @@ import org.uic.barcode.ticket.api.spec.IUicRailTicket;
 public class Encoder {
 	
 	/** The dynamic frame. */
-	private DynamicFrame dynamicFrame = null;
+	private IDynamicFrame dynamicFrame = null;
 
 	/** The static frame. */
 	private StaticFrame staticFrame = null;
@@ -87,18 +87,19 @@ public class Encoder {
 			
 		} else if (barcodeType == UIC_BARCODE_TYPE_DOSIPAS) {
 			
-			dynamicFrame = new DynamicFrame();
-			dynamicFrame.setLevel2SignedData(new Level2DataType());
-			dynamicFrame.getLevel2SignedData().setLevel1Data(new Level1DataType());
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setData(new SequenceOfDataType());
+			dynamicFrame = new SimpleDynamicFrame();
+			dynamicFrame.setLevel2Data(new SimpleLevel2Data());
+			dynamicFrame.getLevel2Data().setLevel1Data(new SimpleLevel1Data());
 			
 			if (ticket != null) {
 				
 				if (version == 1) {
-					dynamicFrame.setFormat("U1");
-				}
+					dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1);
+				} else if (version == 2) {
+					dynamicFrame.setFormat(Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2);
+				} 
 				
-				DataType ticketData = new DataType();
+				IData ticketData = new SimpleData();
 				
 				UicRailTicketCoder uicTicketCoder = new UicRailTicketCoder();
 				if (fcbVersion == 1 || fcbVersion == 13) {
@@ -108,8 +109,8 @@ public class Encoder {
 				} else if (fcbVersion == 3) {
 					ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_3);
 				}
-				ticketData.setData(new OctetString(uicTicketCoder.encode(ticket, fcbVersion)));
-				dynamicFrame.getLevel2SignedData().getLevel1Data().getData().add(ticketData);
+				ticketData.setData(uicTicketCoder.encode(ticket, fcbVersion));
+				dynamicFrame.getLevel2Data().getLevel1Data().addData(ticketData);
 				
 			}
 		}
@@ -151,8 +152,8 @@ public class Encoder {
 	 */
 	public void setLevel1Algs(String level1SigningAlg, String level1KeyAlg) {
 		if (dynamicFrame != null) {
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel1SigningAlg(level1SigningAlg);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel1KeyAlg(level1KeyAlg);	
+			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(level1SigningAlg);
+			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1KeyAlg(level1KeyAlg);	
 		}
 	}
 	
@@ -165,68 +166,62 @@ public class Encoder {
 	 */
 	public void setLevel2Algs(String level2SigningAlg, String level2KeyAlg, PublicKey publicKey) {
 		if (dynamicFrame != null) {
-			if (dynamicFrame.getLevel2SignedData() == null) {
-				dynamicFrame.setLevel2SignedData(new Level2DataType());
+			if (dynamicFrame.getLevel2Data() == null) {
+				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
 			}
-			if (dynamicFrame.getLevel2SignedData().getLevel1Data() == null) {
-				dynamicFrame.getLevel2SignedData().setLevel1Data(new Level1DataType());	
+			if (dynamicFrame.getLevel2Data().getLevel1Data() == null) {
+				dynamicFrame.getLevel2Data().setLevel1Data(new SimpleLevel1Data());	
 			}
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel2SigningAlg(level2SigningAlg);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel2KeyAlg(level2KeyAlg);
+			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2SigningAlg(level2SigningAlg);
+			dynamicFrame.getLevel2Data().getLevel1Data().setLevel2KeyAlg(level2KeyAlg);
 			if (publicKey != null) {
-				dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel2publicKey(new OctetString(publicKey.getEncoded()));
+				dynamicFrame.getLevel2Data().getLevel1Data().setLevel2publicKey(publicKey.getEncoded());
 			}
 		}
 	}
 	
 	public void setDynamicData(IUicDynamicContent content) throws EncodingFormatException {
 		if (dynamicFrame != null) {
-			if (dynamicFrame.getLevel2SignedData() == null) {
-				dynamicFrame.setLevel2SignedData(new Level2DataType());
+			if (dynamicFrame.getLevel2Data() == null) {
+				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
 			}		
 			dynamicFrame.addDynamicContent(content);
 		}		
 	}
 	
-	public void setLevel2Data(DataType level2data) {
+	public void setLevel2Data(IData level2data) {
 		if (dynamicFrame != null) {
-			if (dynamicFrame.getLevel2SignedData() == null) {
-				dynamicFrame.setLevel2SignedData(new Level2DataType());
+			if (dynamicFrame.getLevel2Data() == null) {
+				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
 			}		
-			dynamicFrame.getLevel2SignedData().setLevel2Data(level2data);
+			dynamicFrame.getLevel2Data().setLevel2Data(level2data);
 		}
 	}
 	
 	public void setDynamicContentDataUIC1(UicDynamicContentDataFDC1 dcd) {
 		if (dynamicFrame != null) {
-			if (dynamicFrame.getLevel2SignedData() == null) {
-				dynamicFrame.setLevel2SignedData(new Level2DataType());
+			if (dynamicFrame.getLevel2Data() == null) {
+				dynamicFrame.setLevel2Data(new SimpleLevel2Data());
 			}		
-			dynamicFrame.getLevel2SignedData().setLevel2Data(dcd.getDataType());
+			dynamicFrame.getLevel2Data().setLevel2Data(dcd.getApiDataType());
 		}
 	}
 		
-	public DataType getLevel2Data() {
-		if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
-			return dynamicFrame.getLevel2SignedData().getLevel2Data();
+	public IData getLevel2Data() {
+		if (dynamicFrame != null && dynamicFrame.getLevel2Data() != null) {
+			return dynamicFrame.getLevel2Data().getLevel2Data();
 		}
 		return null;
 	}
 	
 	
 	public IUicDynamicContent getDynamicContent() {
-		if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
+		if (dynamicFrame != null && dynamicFrame.getLevel2Data() != null) {
 			return dynamicFrame.getDynamicContent();
 		}
 		return null;
 	}
 	
-	public UicDynamicContentDataFDC1 getDynamicContentDataUIC1() {
-		if (dynamicFrame != null && dynamicFrame.getLevel2SignedData() != null) {
-			return dynamicFrame.getDynamicDataFDC1();
-		}
-		return null;
-	}
 
 	
 	/**
@@ -240,10 +235,10 @@ public class Encoder {
 	 */
 	public void signLevel1(String securityProvider,PrivateKey key,String signingAlg, String keyId) throws Exception {
 		if (dynamicFrame != null) {
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setSecurityProvider(securityProvider);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel1SigningAlg(signingAlg);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setKeyId(Long.parseLong(keyId));
-			dynamicFrame.getLevel2SignedData().signLevel1(key);
+			dynamicFrame.getLevel2Data().getLevel1Data().setSecurityProvider(securityProvider);
+			dynamicFrame.getLevel2Data().getLevel1Data().setLevel1SigningAlg(signingAlg);
+			dynamicFrame.getLevel2Data().getLevel1Data().setKeyId(Long.parseLong(keyId));
+			dynamicFrame.signLevel1(key);
 		} else if (staticFrame != null) {
 			staticFrame.setSignatureKey(keyId);
 			staticFrame.setSecurityProvider(securityProvider);
@@ -266,10 +261,11 @@ public class Encoder {
 	 */
 	public void signLevel1(String securityProvider,PrivateKey key,String signingAlg, String keyId, Provider prov) throws Exception {
 		if (dynamicFrame != null) {
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setSecurityProvider(securityProvider);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setLevel1SigningAlg(signingAlg);
-			dynamicFrame.getLevel2SignedData().getLevel1Data().setKeyId(Long.parseLong(keyId));
-			dynamicFrame.getLevel2SignedData().signLevel1(key, prov);
+			dynamicFrame.getLevel2Data().getLevel1Data().setSecurityProvider(securityProvider);
+			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);
@@ -299,7 +295,7 @@ public class Encoder {
 	 *
 	 * @return the dynamic frame
 	 */
-	public DynamicFrame getDynamicFrame() {
+	public IDynamicFrame getDynamicFrame() {
 		return dynamicFrame;
 	}
 	
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
index a1b9581..c2cd8fa 100644
--- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java
@@ -105,17 +105,18 @@ public class TimeStamp {
 		int dayOfYear = now.getDayOfYear();
 				
 		if (dayOfYear - day.intValue() > 250) {
-			now = now.plusDays(1);
+			now = now.plusYears(1);
 		}
 		if (day.intValue() - dayOfYear > 250) {
-			now = now.minusDays(1);
+			now = now.minusYears(1);
 		}
 
 		now = now.withDayOfYear(1);
 		now = now.withSecond(0);
 		now = now.withHour(0);
 		now = now.withMinute(0);
-		now = now.withDayOfYear(dayOfYear);
+		now = now.withNano(0);
+		now = now.withDayOfYear(day.intValue());
 		now = now.plusSeconds(secondOfDay);
 		
 		return Date.from(now.toInstant());
diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
index 3ced173..9957ede 100644
--- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
+++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java
@@ -11,7 +11,9 @@ 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.uper.UperEncoder;
-import org.uic.barcode.dynamicFrame.DataType;
+import org.uic.barcode.dynamicFrame.api.IData;
+import org.uic.barcode.dynamicFrame.api.SimpleData;
+import org.uic.barcode.dynamicFrame.v1.DataType;
 
 
 /**
@@ -94,6 +96,14 @@ public class UicDynamicContentDataFDC1  {
 		return "FDC1";
 	}
 	
+	public IData getApiDataType() {
+		IData data = new SimpleData();
+		data.setFormat(getFormat());
+		data.setData(UperEncoder.encode(this));
+		return data;
+	}
+	
+	
 	public DataType getDataType() {
 		DataType data = new DataType();
 		data.setFormat(getFormat());
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
index 8f47986..ba15f3f 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
@@ -36,4 +36,6 @@ 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";
 }
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/DataType.java
deleted file mode 100644
index 2ea63ca..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.uic.barcode.dynamicFrame;
-
-import org.uic.barcode.asn1.datatypes.CharacterRestriction;
-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)
-	public String format;
-	
-	/** The data. */
-	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/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
deleted file mode 100644
index eb26729..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
+++ /dev/null
@@ -1,429 +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.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;
-
-
-// TODO: Auto-generated Javadoc
-/**
- * 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);	
-	}
-	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @return the int
-	 */	
-	public int validateLevel2() {
-
-		return validateLevel2(null);
-	
-	}
-	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param prov the prov
-	 * @return the int
-	 */	
-	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 
-	 *
-	 * @param key the key
-	 * @param prov the prov
-	 * @return the int
-	 */
-	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 
-	 *
-	 * @param key the key
-	 * @return the int
-	 */
-	public int validateLevel1(PublicKey key) {
-		
-		return validateLevel1(key, null);
-
-  	}
-	
-	/**
-	 * 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) {
-		this.getLevel2SignedData().setLevel2Data( dynamicData.getDataType());	
-	}
-	
-	/**
-	 * 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/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
deleted file mode 100644
index 958cafc..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package org.uic.barcode.dynamicFrame;
-
-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;		
-		
-	@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;	
-	
-	@FieldOrder(order = 7)
-	@RestrictedString(CharacterRestriction.ObjectIdentifier)
-	@Asn1Optional public String level2SigningAlg;		
-	
-	
-	/** The level 2 public key*/
-	@FieldOrder(order = 8)
-	@Asn1Optional public OctetString level2publicKey;
-	
-
-	
-	/**
-	 * 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;
-	}
-	
-	public Long getKeyId() {
-		return keyId;
-	}
-
-	public void setKeyId(Long keyId) {
-		this.keyId = keyId;
-	}
-
-	public SequenceOfDataType getData() {
-		return data;
-	}
-
-	public void setData(SequenceOfDataType data) {
-		this.data = data;
-	}
-
-	public String getLevel2KeyAlg() {
-		return level2KeyAlg;
-	}
-
-	public void setLevel2KeyAlg(String level2KeyAlg) {
-		this.level2KeyAlg = level2KeyAlg;
-	}
-
-	public String getLevel1SigningAlg() {
-		return level1SigningAlg;
-	}
-
-	public void setLevel1SigningAlg(String level1SigningAlg) {
-		this.level1SigningAlg = level1SigningAlg;
-	}
-
-	public String getLevel2SigningAlg() {
-		return level2SigningAlg;
-	}
-
-	public void setLevel2SigningAlg(String level2SigningAlg) {
-		this.level2SigningAlg = level2SigningAlg;
-	}
-
-	public OctetString getLevel2publicKey() {
-		return level2publicKey;
-	}
-
-	public void setLevel2publicKey(OctetString level2publicKey) {
-		this.level2publicKey = level2publicKey;
-	}
-
-	
-	
-	public String getLevel1KeyAlg() {
-		return level1KeyAlg;
-	}
-
-	public void setLevel1KeyAlg(String level1KeyAlg) {
-		this.level1KeyAlg = level1KeyAlg;
-	}
-
-	/**
-	 * 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/Level2DataType.java
deleted file mode 100644
index 8c3cd60..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/Level2DataType.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.uic.barcode.dynamicFrame;
-
-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.FieldOrder;
-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.utils.AlgorithmNameResolver;
-
-/**
- * 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);
-	}
-	
-	/**
-	 * 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 
-	 */
-	public void signLevel1(PrivateKey key) throws Exception {
-		//find the algorithm name for the signature OID
-		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel1Data().level1SigningAlg);
-		Signature sig = Signature.getInstance(algo);
-		sig.initSign(key);
-		byte[] data = level1Data.encode();
-		sig.update(data);
-		this.level1Signature = new OctetString(sig.sign());
-	}
-
-	/**
-	 * 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 
-	 */
-	public void signLevel1(PrivateKey key, Provider prov) throws Exception {
-		//find the algorithm name for the signature OID
-		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel1Data().level1SigningAlg);
-		Signature sig = Signature.getInstance(algo, prov);
-		sig.initSign(key);
-		byte[] data = level1Data.encode();
-		sig.update(data);
-		this.level1Signature = new OctetString(sig.sign());
-	}
-	
-	
-}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java b/src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java
deleted file mode 100644
index b5c130e..0000000
--- a/src/main/java/org/uic/barcode/dynamicFrame/SequenceOfDataType.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.uic.barcode.dynamicFrame;
-
-
-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); }
-
-}
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..f357c4d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
@@ -0,0 +1,202 @@
+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 level2SignedData the new level 2 signed 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);
+	
+
+	/**
+	 * 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
+	 */
+	public void decode(byte[] bytes);
+	
+
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */	
+	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 prov
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */	
+	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 prov the prov
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */
+	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
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */
+	public int validateLevel1(PublicKey key) 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 key
+	 * @return 
+	 * @return the byte[]
+	 * @throws 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 key
+	 * @param security provider - security provider that must be sued to create the signature
+	 * @return 
+	 * @return the byte[]
+	 * @throws Exception 
+	 */
+	public void signLevel1(PrivateKey key, Provider prov) throws Exception;
+	
+	
+	
+}
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..206d613
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/ILevel1Data.java
@@ -0,0 +1,164 @@
+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 securityProviderNum 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 alg.
+	 *
+	 * @return the level 2 key alg
+	 */
+	public String getLevel2KeyAlg();
+	
+
+	/**
+	 * Sets the level 2 key alg.
+	 *
+	 * @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 alg.
+	 *
+	 * @param level1SigningAlg the new level 1 signing alg
+	 */
+	public void setLevel1SigningAlg(String level1SigningAlg);
+	
+
+	/**
+	 * Gets the level 2 signing alg.
+	 *
+	 * @return the level 2 signing alg
+	 */
+	public String getLevel2SigningAlg();
+	
+
+	/**
+	 * Sets the level 2 signing alg.
+	 *
+	 * @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 alg.
+	 *
+	 * @return the level 1 key alg
+	 */
+	public String getLevel1KeyAlg();
+	
+	/**
+	 * Sets the level 1 key alg.
+	 *
+	 * @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.
+	 *
+	 * @param date the new end of validity date
+	 */
+	public void setEndOfBarcodeValidity(Date date);
+	
+	
+	/**
+	 * Gets the end of validity date.
+	 *
+	 * @return the end of validity date
+	 */
+	public Date getEndOfBarcodeValidity();
+}
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..cb762de
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
@@ -0,0 +1,59 @@
+package org.uic.barcode.dynamicFrame.api;
+
+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;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+/**
+ * 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..4c5c879
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
@@ -0,0 +1,553 @@
+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 = Constants.DYNAMIC_BARCODE_FORMAT_DEFAULT;
+	
+	/** 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
+	 */
+	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 ILevel2Data getLevel2Data() {
+		return level2Data;
+	}
+
+	/**
+	 * Sets the level 2 signed data.
+	 *
+	 * @param level2SignedData the new level 2 signed data
+	 */
+	public void setLevel2Data(ILevel2Data level2SignedData) {
+		this.level2Data = level2SignedData;
+	}
+
+	/**
+	 * Gets the level 2 signature.
+	 *
+	 * @return the level 2 signature
+	 */
+	public byte[] getLevel2Signature() {
+		return level2Signature;
+	}
+
+	/**
+	 * Sets the level 2 signature.
+	 *
+	 * @param level2Signature the new level 2 signature
+	 */
+	public void setLevel2Signature(byte[] level2Signature) {
+		this.level2Signature = level2Signature;
+	}
+
+	/**
+	 * Encode.
+	 * 
+	 * Encode the header as ASN.1 PER UNALIGNED byte array
+	 *
+	 * @return the byte[]
+	 * @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_1.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_1.equals(format)) {
+			
+			return DynamicFrameCoderV2.encode(level1Data);
+			
+		}
+		
+		return null;
+	}
+	
+	private byte[] encode(ILevel2Data level2SignedData2) throws EncodingFormatException {
+		
+		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+			
+			return DynamicFrameCoderV1.encode(level2SignedData2);
+			
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+			
+			return DynamicFrameCoderV2.encode(level2SignedData2);
+			
+		}
+		
+		return null;
+	}
+	
+	/**
+	 * Decode.
+	 *
+	 * Decode the header from an ASN.1 PER UNALIGNED encoded byte array
+	 *
+	 * @param bytes the bytes
+	 * @return the dynamic header
+	 */
+	public void decode(byte[] bytes) {
+		
+		String format = getFormat(bytes);
+			
+		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+			
+			DynamicFrameCoderV1.decode(this,bytes);
+			
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
+		
+			DynamicFrameCoderV2.decode(this,bytes);
+			
+		}
+		
+		
+
+	}
+	
+
+
+	
+	/**
+	 * Checks if is static header.
+	 *
+	 * @param data the data
+	 * @return true, if is static header
+	 */
+	private static String getFormat(byte[] data) {
+		byte[] start = "U1".getBytes();
+		if (start[0] != data[0] || start[1]!= start[1]) {
+			return Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1;
+		}
+		start = "U2".getBytes();
+		if (start[0] != data[0] || start[1]!= start[1]) {
+			return Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2;
+		}
+		return null;
+	}
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */	
+	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 prov
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */	
+	public int validateLevel2(Provider prov) throws EncodingFormatException {
+		
+		
+		String level2KeyAlg = this.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);
+		} 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);
+		} 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 = encode(level2Data);
+			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;
+		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 
+	 *
+	 * @param key the key
+	 * @param prov the prov
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */
+	public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException {
+		
+		if (level2Data == null) {
+			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
+		}
+		
+	
+		if (level2Data == null || 
+			level2Data.getLevel1Signature().length == 0) {
+			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
+		}
+		
+		byte[] signature = this.getLevel2Data().getLevel1Signature();
+				
+		//find the algorithm name for the signature OID
+		String algo = null;
+		try {
+			algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel2Data().getLevel1Data().getLevel1SigningAlg());
+		} 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(encode(level2Data.getLevel1Data()));
+		} 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 
+	 *
+	 * @param key the key
+	 * @return the int
+	 * @throws EncodingFormatException 
+	 */
+	public int validateLevel1(PublicKey key) throws EncodingFormatException {
+		
+		return validateLevel1(key, null);
+
+  	}
+	
+	/**
+	 * 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(level2Data.getLevel1Data().getLevel2SigningAlg());
+		Signature sig = Signature.getInstance(algo);
+		sig.initSign(key);
+		byte[] data = encode(level2Data);
+		sig.update(data);
+		level2Signature = sig.sign();
+		
+	}
+
+	/**
+	 * 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.getLevel2Data().getLevel1Data().getLevel2SigningAlg());
+		Signature sig = Signature.getInstance(algo,prov);
+		sig.initSign(key);
+		byte[] data = encode(level2Data);
+		sig.update(data);
+		level2Signature = 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 {
+		
+		
+		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
+	 */
+	public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
+		this.getLevel2Data().setLevel2Data(dynamicData.getApiDataType());	
+	}
+	
+	/**
+	 * Gets the dynamic content.
+	 *
+	 * @return the dynamic content
+	 */
+	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 
+	 */
+	public void signLevel1(PrivateKey key) 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 = Signature.getInstance(algo);
+		sig.initSign(key);
+		byte[] data = encode(level1Data);
+		sig.update(data);
+		level2Data.setLevel1Signature(sig.sign());
+	}
+
+	/**
+	 * 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 = Signature.getInstance(algo, prov);
+		sig.initSign(key);
+				
+		byte[] data = encode(level1Data);
+		sig.update(data);
+		level2Data.setLevel1Signature(sig.sign());	
+	}
+
+
+
+	
+	
+}
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..241cf6d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java
@@ -0,0 +1,254 @@
+package org.uic.barcode.dynamicFrame.api;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+/**
+ * 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;
+	
+	
+	
+	
+	
+	/**
+	 * 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);
+		
+	}
+}
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..395db4d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel2Data.java
@@ -0,0 +1,75 @@
+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)
+	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;
+	}
+
+	
+	/**
+	 * 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/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/v1/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
new file mode 100644
index 0000000..6195b3c
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
@@ -0,0 +1,93 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+import org.uic.barcode.asn1.datatypes.CharacterRestriction;
+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)
+	public String format;
+	
+	/** The data. */
+	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/v1/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
new file mode 100644
index 0000000..3af9c8f
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
@@ -0,0 +1,432 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+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.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.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);	
+	}
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @return the int
+	 */	
+	public int validateLevel2() {
+
+		return validateLevel2(null);
+	
+	}
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @param prov the prov
+	 * @return the int
+	 */	
+	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 
+	 *
+	 * @param key the key
+	 * @param prov the prov
+	 * @return the int
+	 */
+	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 
+	 *
+	 * @param key the key
+	 * @return the int
+	 */
+	public int validateLevel1(PublicKey key) {
+		
+		return validateLevel1(key, null);
+
+  	}
+	
+	/**
+	 * 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..f7b3f3d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
@@ -0,0 +1,189 @@
+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.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());	
+		}
+					
+	}
+
+	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[] encode(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);
+				
+			}
+			
+		}
+		
+		return asnLevel1;
+	}
+	
+
+
+}
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java
new file mode 100644
index 0000000..5104c50
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/Level1DataType.java
@@ -0,0 +1,226 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+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;		
+		
+	@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;	
+	
+	@FieldOrder(order = 7)
+	@RestrictedString(CharacterRestriction.ObjectIdentifier)
+	@Asn1Optional public String level2SigningAlg;		
+	
+	
+	/** The level 2 public key*/
+	@FieldOrder(order = 8)
+	@Asn1Optional public OctetString level2publicKey;
+	
+
+	
+	/**
+	 * 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;
+	}
+	
+	public Long getKeyId() {
+		return keyId;
+	}
+
+	public void setKeyId(Long keyId) {
+		this.keyId = keyId;
+	}
+
+	public SequenceOfDataType getData() {
+		return data;
+	}
+
+	public void setData(SequenceOfDataType data) {
+		this.data = data;
+	}
+
+	public String getLevel2KeyAlg() {
+		return level2KeyAlg;
+	}
+
+	public void setLevel2KeyAlg(String level2KeyAlg) {
+		this.level2KeyAlg = level2KeyAlg;
+	}
+
+	public String getLevel1SigningAlg() {
+		return level1SigningAlg;
+	}
+
+	public void setLevel1SigningAlg(String level1SigningAlg) {
+		this.level1SigningAlg = level1SigningAlg;
+	}
+
+	public String getLevel2SigningAlg() {
+		return level2SigningAlg;
+	}
+
+	public void setLevel2SigningAlg(String level2SigningAlg) {
+		this.level2SigningAlg = level2SigningAlg;
+	}
+
+	public OctetString getLevel2publicKey() {
+		return level2publicKey;
+	}
+
+	public void setLevel2publicKey(OctetString level2publicKey) {
+		this.level2publicKey = level2publicKey;
+	}
+
+	
+	
+	public String getLevel1KeyAlg() {
+		return level1KeyAlg;
+	}
+
+	public void setLevel1KeyAlg(String level1KeyAlg) {
+		this.level1KeyAlg = level1KeyAlg;
+	}
+
+	/**
+	 * 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/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/v1/SequenceOfDataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java
new file mode 100644
index 0000000..be0bf95
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/SequenceOfDataType.java
@@ -0,0 +1,25 @@
+package org.uic.barcode.dynamicFrame.v1;
+
+
+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); }
+
+}
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..f94b622
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
@@ -0,0 +1,95 @@
+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;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+/**
+ * The Class DataType.
+ */
+@Sequence
+@HasExtensionMarker
+public class DataType {
+
+
+	/** The data format.
+	 * 
+	 *  -- FCB1  FCB version 1
+	 *  -- FCB2  FCB version 2
+	 *  -- RICS  company code + ...
+	 **/
+	@RestrictedString(CharacterRestriction.IA5String)
+	public String format;
+	
+	/** The data. */
+	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..2986f75
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
@@ -0,0 +1,434 @@
+package org.uic.barcode.dynamicFrame.v2;
+
+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.HasExtensionMarker;
+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.dynamicFrame.Constants;
+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
+@HasExtensionMarker
+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);	
+	}
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @return the int
+	 */	
+	public int validateLevel2() {
+
+		return validateLevel2(null);
+	
+	}
+	
+	/**
+	 * Verify the level 2 signature
+	 * 
+	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
+	 *
+	 * @param prov the prov
+	 * @return the int
+	 */	
+	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 
+	 *
+	 * @param key the key
+	 * @param prov the prov
+	 * @return the int
+	 */
+	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 
+	 *
+	 * @param key the key
+	 * @return the int
+	 */
+	public int validateLevel1(PublicKey key) {
+		
+		return validateLevel1(key, null);
+
+  	}
+	
+	/**
+	 * 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..8987f59
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
@@ -0,0 +1,203 @@
+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());	
+		}
+		
+	}
+
+	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());
+		}
+		
+		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[] encode(ILevel2Data level2SignedData) throws EncodingFormatException {
+		
+       Level2DataType asn = populateAsn(level2SignedData);
+		
+		return UperEncoder.encode(asn);
+	}
+
+	private static DynamicFrame populateAsn(IDynamicFrame frame) throws EncodingFormatException {
+		
+		DynamicFrame asnFrame = new DynamicFrame();
+		
+		frame.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());
+		
+		
+		return asnLevel1;
+	}
+	
+
+
+}
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..1dff709
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java
@@ -0,0 +1,374 @@
+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.HasExtensionMarker;
+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;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class SignedDataType.
+ */
+@Sequence
+@HasExtensionMarker
+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)
+	public Long EndOfValidityYear;
+
+	/** The End of validity day. */
+	@FieldOrder(order = 10)
+	@IntRange(minValue=1,maxValue=366)
+	public Long EndOfValidityDay;
+
+	/** The End of validity time. */
+	@FieldOrder(order = 11)
+	@IntRange(minValue=0,maxValue=1440)
+	@Asn1Optional public Long EndOfValidityTime;
+	
+	
+	
+	
+	
+	/**
+	 * 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. The validity date has to be provided in UTC.
+	 *
+	 * @param date the new end of validity date
+	 */
+	public void setEndOfValidityDate(Date date){
+		
+		if (date == null) {
+			date = Calendar.getInstance().getTime();
+		}
+		
+		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 );
+		}
+		
+	}
+	
+	/**
+	 * Gets the end of validity date.
+	 *
+	 * @return the end of validity date
+	 */
+	public Date getEndOfValidityDate() {
+		
+		if (this.EndOfValidityYear == null || this.EndOfValidityDay == null) return null;
+		
+		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();
+		return d;
+	}
+
+	/**
+	 * 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/v2/Level2DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java
new file mode 100644
index 0000000..6534c4d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level2DataType.java
@@ -0,0 +1,123 @@
+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.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;
+import org.uic.barcode.utils.AlgorithmNameResolver;
+
+/**
+ * The Class DataType.
+ */
+@Sequence
+@HasExtensionMarker
+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);
+	}
+	
+	/**
+	 * 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 
+	 */
+	public void signLevel1(PrivateKey key) throws Exception {
+		//find the algorithm name for the signature OID
+		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel1Data().level1SigningAlg);
+		Signature sig = Signature.getInstance(algo);
+		sig.initSign(key);
+		byte[] data = level1Data.encode();
+		sig.update(data);
+		this.level1Signature = new OctetString(sig.sign());
+	}
+
+	/**
+	 * 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 
+	 */
+	public void signLevel1(PrivateKey key, Provider prov) throws Exception {
+		//find the algorithm name for the signature OID
+		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel1Data().level1SigningAlg);
+		Signature sig = Signature.getInstance(algo, prov);
+		sig.initSign(key);
+		byte[] data = level1Data.encode();
+		sig.update(data);
+		this.level1Signature = new OctetString(sig.sign());
+	}
+	
+	
+}
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); }
+
+}
-- 
cgit v1.2.3


From 09f0f9449a10b713207126348105fafec4781bed Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Mon, 24 Jan 2022 16:51:04 +0100
Subject: signature validation changed to work with teh dynamic header version
 2.

---
 src/main/java/org/uic/barcode/Decoder.java         |   9 +-
 .../org/uic/barcode/asn1/uper/AsnExtractor.java    |  80 +++++++++++++++
 .../java/org/uic/barcode/asn1/uper/AsnUtils.java   |  59 +++++++++++
 .../java/org/uic/barcode/asn1/uper/BitBuffer.java  |   1 +
 .../org/uic/barcode/asn1/uper/BitStringCoder.java  |   2 +-
 .../org/uic/barcode/asn1/uper/BooleanCoder.java    |   2 +-
 .../org/uic/barcode/asn1/uper/ByteBitBuffer.java   |  30 ++++--
 .../java/org/uic/barcode/asn1/uper/ByteCoder.java  |   2 +-
 .../org/uic/barcode/asn1/uper/ChoiceCoder.java     |   6 +-
 .../java/org/uic/barcode/asn1/uper/Decoder.java    |   2 +-
 .../java/org/uic/barcode/asn1/uper/EnumCoder.java  |   2 +-
 .../java/org/uic/barcode/asn1/uper/IntCoder.java   |   2 +-
 .../java/org/uic/barcode/asn1/uper/SeqOfCoder.java |   4 +-
 .../org/uic/barcode/asn1/uper/SequenceCoder.java   |  29 +++++-
 .../org/uic/barcode/asn1/uper/StringCoder.java     |   2 +-
 .../org/uic/barcode/asn1/uper/UperEncoder.java     |  46 +++++++--
 .../barcode/dynamicFrame/api/IDynamicFrame.java    |  26 ++---
 .../dynamicFrame/api/SimpleDynamicFrame.java       | 109 ++++++++++++---------
 .../dynamicFrame/v1/DynamicFrameCoderV1.java       |  15 +++
 .../dynamicFrame/v2/DynamicFrameCoderV2.java       |  11 +++
 .../uic/barcode/utils/AlgorithmNameResolver.java   |  37 ++++++-
 21 files changed, 382 insertions(+), 94 deletions(-)
 create mode 100644 src/main/java/org/uic/barcode/asn1/uper/AsnExtractor.java
 create mode 100644 src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java
index b980f19..5cb0546 100644
--- a/src/main/java/org/uic/barcode/Decoder.java
+++ b/src/main/java/org/uic/barcode/Decoder.java
@@ -81,7 +81,7 @@ public class Decoder {
 	 */
 	public int validateLevel1(PublicKey key, String signingAlg) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel1(key) ;
+			return dynamicFrame.validateLevel1(key, data) ;
 		} else {
 			if (staticFrame.verifyByAlgorithmOid(key,signingAlg)) {
 				return Constants.LEVEL1_VALIDATION_OK;
@@ -91,7 +91,6 @@ public class Decoder {
 		}
 	}
 	
-	
 	/**
 	 * Validate level 1.
 	 *
@@ -109,7 +108,7 @@ public class Decoder {
 	 */
 	public int validateLevel1(PublicKey key, String signingAlg, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel1(key, provider) ;
+			return dynamicFrame.validateLevel1(key, provider, data) ;
 		} else {
 			if (staticFrame.verifyByAlgorithmOid(key,signingAlg, provider)) {
 				return Constants.LEVEL1_VALIDATION_OK;
@@ -127,7 +126,7 @@ public class Decoder {
 	 */
 	public int validateLevel2() throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel2() ;
+			return dynamicFrame.validateLevel2(null, data) ;
 		} else {
 			return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
 		}
@@ -140,7 +139,7 @@ public class Decoder {
 	 */
 	public int validateLevel2(Provider prov) throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel2(prov) ;
+			return dynamicFrame.validateLevel2(prov,data) ;
 		} else {
 			return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
 		}
diff --git a/src/main/java/org/uic/barcode/asn1/uper/AsnExtractor.java b/src/main/java/org/uic/barcode/asn1/uper/AsnExtractor.java
new file mode 100644
index 0000000..0d5d1da
--- /dev/null
+++ b/src/main/java/org/uic/barcode/asn1/uper/AsnExtractor.java
@@ -0,0 +1,80 @@
+package org.uic.barcode.asn1.uper;
+
+public class AsnExtractor {
+	
+	private String path = null;
+	
+	private boolean extractionStarted = false;
+	private boolean extractionCompleted = false;
+	
+	private BitBuffer bitBuffer = null;
+	private int startBit = 0;
+	private int endBit = 0;
+	
+	AsnExtractor(String path, BitBuffer bitBuffer) {
+		this.path = path;
+		this.bitBuffer = bitBuffer;
+	}
+
+	public byte[] getResult() {
+		
+		if (!extractionCompleted) {
+			return null;
+		}
+		
+		if (!(endBit > startBit)) {
+			return null;
+		}
+		
+		String bitString = bitBuffer.toBooleanString(startBit, endBit - startBit);
+		
+		while (bitString.length() % 8 != 0) {
+			bitString = bitString + "0";
+		}
+		
+		return AsnUtils.fromBooleanString(bitString);
+		
+	}
+	
+
+	
+	public boolean found(String className) {
+		
+		if (extractionStarted || extractionCompleted) return false;
+		
+		if (path != null && path.length() > 0 && className != null & className.length() > 0) {
+			if (className.endsWith(path)){
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	public void startExtraction(int position) {
+		
+		if (path == null || path.length() == 0 || bitBuffer == null) {
+			return;
+		}
+		
+		if (!extractionCompleted && !extractionStarted) {
+			extractionStarted = true;
+			startBit = position;
+		}
+	}
+	
+	public void endExtraction(int position) {
+		if (extractionStarted) {
+			extractionCompleted = true;
+			endBit = position;
+		}
+
+	}
+
+	public boolean isStarted() {
+		return extractionStarted;
+	}
+	
+	
+	
+}
diff --git a/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java b/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java
new file mode 100644
index 0000000..dbb95c9
--- /dev/null
+++ b/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java
@@ -0,0 +1,59 @@
+package org.uic.barcode.asn1.uper;
+
+public class AsnUtils {
+	
+
+    private static byte[] mask = new byte[] {
+    	     (byte) 0b1000_0000,
+    	            0b0100_0000,
+    	            0b0010_0000,
+    	            0b0001_0000,
+    	            0b0000_1000,
+    	            0b0000_0100,
+    	            0b0000_0010,
+    	            0b0000_0001,
+    	    };
+    
+    
+	public static byte[] fromBooleanString(final String s) {
+		
+		char[] ascii = s.toCharArray();
+        if (ascii == null || ascii.length == 0) {
+            return null;
+        }
+        // get length/8 times bytes with 3 bit shifts to the right of the length
+        final byte[] l_raw = new byte[ascii.length >> 3];
+        /*
+         * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the
+         * loop.
+         */
+        for (int ii = 0, jj = 0; ii < l_raw.length; ii++, jj += 8) {
+            for (int bits = 0; bits < mask.length; ++bits) {
+                if (ascii[jj + bits] == '1') {
+                    l_raw[ii] |= mask[bits];
+                }
+            }
+        }
+        return l_raw;
+    }
+	
+	public static String toBooleanString(byte[] bytes) {
+	        StringBuilder sb = new StringBuilder(bytes.length);
+	        for (int i = 0; i < bytes.length*8;i++) {
+	            sb.append(AsnUtils.get(bytes,i) ? "1" : "0");
+	        }
+	        return sb.toString();
+	}
+	
+	public static boolean get(byte[] bytes, int index) {
+	        
+		if (index < 0) {
+	            throw new IndexOutOfBoundsException("Index " + index + " is less than 0");
+	    } else if (index >= bytes.length * 8) {
+	            throw new IndexOutOfBoundsException("Index " + index + " violates the limit " + bytes.length*8);
+	    }
+	    boolean result = (bytes[index / 8] & mask[index % 8]) != 0;
+	    return result;
+	}
+
+}
diff --git a/src/main/java/org/uic/barcode/asn1/uper/BitBuffer.java b/src/main/java/org/uic/barcode/asn1/uper/BitBuffer.java
index bba0de7..21d0e03 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/BitBuffer.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/BitBuffer.java
@@ -19,6 +19,7 @@ public interface BitBuffer {
     BitBuffer flip();
     String toBooleanString(int startIndex, int length);
     String toBooleanStringFromPosition(int startIndex);
+    byte[] fromBooleanString(String s);
     byte[] array();
     BitBuffer putByte(byte element);
     byte getByte();
diff --git a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
index 19aac9b..6f435c4 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
@@ -97,7 +97,7 @@ class BitStringCoder implements Decoder, Encoder {
 
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(),
                 extraAnnotations);
         if (!Asn1VarSizeBitstring.class.isAssignableFrom(classOfT)) {
diff --git a/src/main/java/org/uic/barcode/asn1/uper/BooleanCoder.java b/src/main/java/org/uic/barcode/asn1/uper/BooleanCoder.java
index 3bd7a38..892f851 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/BooleanCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/BooleanCoder.java
@@ -22,7 +22,7 @@ class BooleanCoder implements Decoder, Encoder {
     @SuppressWarnings("unchecked")
 	@Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
     	Boolean result = new Boolean(bitbuffer.get());
         UperEncoder.logger.debug(String.format("BOOL: decoded as %s",result));
         return (T) result;
diff --git a/src/main/java/org/uic/barcode/asn1/uper/ByteBitBuffer.java b/src/main/java/org/uic/barcode/asn1/uper/ByteBitBuffer.java
index 3ed3eed..e409005 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/ByteBitBuffer.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/ByteBitBuffer.java
@@ -3,7 +3,7 @@ package org.uic.barcode.asn1.uper;
 
 
 public class ByteBitBuffer implements BitBuffer {
-
+	
     byte[] bytes;
     byte[] mask = new byte[] {
      (byte) 0b1000_0000,
@@ -45,7 +45,8 @@ public class ByteBitBuffer implements BitBuffer {
         bytes = newbytes;
     }
 
-    @Override public BitBuffer put(int index, boolean element) {
+    @Override 
+    public BitBuffer put(int index, boolean element) {
         if (bytes.length <= index / 8) {
             if (isFinite) { throw new IndexOutOfBoundsException(); }
             else { grow(); }
@@ -58,21 +59,24 @@ public class ByteBitBuffer implements BitBuffer {
         return this;
     }
 
-    @Override public BitBuffer put(boolean element) {
+    @Override 
+    public BitBuffer put(boolean element) {
         put(position, element);
         position++;
         limit = limit < position ? position : limit;  // TODO: should it be here?
         return this;
     }
 
-    @Override public BitBuffer putByte(byte element) {
+    @Override 
+    public BitBuffer putByte(byte element) {
         for (int i = 0; i < 8; i++) {
             put((element & mask[i]) != 0);
         }
         return this;
     }
     
-    @Override public BitBuffer putByteArray(int index, byte[] data) {
+    @Override 
+    public BitBuffer putByteArray(int index, byte[] data) {
     	
     	for (int l = 0; l < data.length;l++) {
     		for (int i = 0; i < 8; i++) {
@@ -83,7 +87,8 @@ public class ByteBitBuffer implements BitBuffer {
     }
     
 
-    @Override public byte getByte() {
+    @Override 
+    public byte getByte() {
         byte result = 0;
         for (int i = 0; i < 8; i++) {
             result |= (get() ? 1 : 0) << (7 - i);
@@ -91,11 +96,13 @@ public class ByteBitBuffer implements BitBuffer {
         return result;
     }
 
-    @Override public int limit() {
+    @Override 
+    public int limit() {
         return limit;
     }
 
-    @Override public String toBooleanString(int startIndex, int length) {
+    @Override 
+    public String toBooleanString(int startIndex, int length) {
         StringBuilder sb = new StringBuilder(length);
         for (int i = startIndex; i < startIndex + length; i++) {
             sb.append(get(i) ? "1" : "0");
@@ -267,5 +274,12 @@ public class ByteBitBuffer implements BitBuffer {
 
 		return stringBuilder.toString().trim();
 	}
+	
+	public byte[] fromBooleanString(final String s) {
+		
+		return AsnUtils.fromBooleanString(s);
+
+    }
+
 
 }
diff --git a/src/main/java/org/uic/barcode/asn1/uper/ByteCoder.java b/src/main/java/org/uic/barcode/asn1/uper/ByteCoder.java
index f26a598..5ecb925 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/ByteCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/ByteCoder.java
@@ -21,7 +21,7 @@ class ByteCoder implements Decoder, Encoder {
     @SuppressWarnings("unchecked")
 	@Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
         UperEncoder.logger.debug("BYTE");
         return (T) new Byte((byte) UperEncoder.decodeConstrainedInt(bitbuffer, UperEncoder.newRange(0, 255, false)));
     }
diff --git a/src/main/java/org/uic/barcode/asn1/uper/ChoiceCoder.java b/src/main/java/org/uic/barcode/asn1/uper/ChoiceCoder.java
index d17a813..0bbce73 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/ChoiceCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/ChoiceCoder.java
@@ -95,7 +95,7 @@ class ChoiceCoder implements Decoder, Encoder {
 
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field1,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(),extraAnnotations);
         UperEncoder.logger.debug(String.format("CHOICE: %s", classOfT.getName()));
         T result = UperEncoder.instantiate(classOfT);
@@ -120,7 +120,7 @@ class ChoiceCoder implements Decoder, Encoder {
                 Class<?> classOfElement = field != null ? field.getType() : null;                
                 if (field != null) {
                 	try {
-                		Object decodedValue = UperEncoder.decodeAsOpenType(bitbuffer, classOfElement,field, field.getAnnotations());
+                		Object decodedValue = UperEncoder.decodeAsOpenType(bitbuffer, classOfElement,field, field.getAnnotations(),extractor);
                 		if (field != null) {
                 			field.set(result, decodedValue);
                 		}
@@ -144,7 +144,7 @@ class ChoiceCoder implements Decoder, Encoder {
                 UperEncoder.newRange(0, sorter.ordinaryFields.size() - 1, false));
         Field f = sorter.ordinaryFields.get(index);
         UperEncoder.logger.debug(String.format("CHOICE: selected %s", f.getName()));
-        Object fieldValue = UperEncoder.decodeAny(bitbuffer, f.getType(),f, f.getAnnotations());
+        Object fieldValue = UperEncoder.decodeAny(bitbuffer, f.getType(),f, f.getAnnotations(),extractor);
         try {
             f.set(result, fieldValue);
         } catch (IllegalArgumentException | IllegalAccessException e) {
diff --git a/src/main/java/org/uic/barcode/asn1/uper/Decoder.java b/src/main/java/org/uic/barcode/asn1/uper/Decoder.java
index 947a752..3140443 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/Decoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/Decoder.java
@@ -5,6 +5,6 @@ import java.lang.reflect.Field;
 
 public interface Decoder {
     <T> boolean canDecode(Class<T> classOfT, Annotation[] extraAnnotations);
-    <T> T decode(BitBuffer bitbuffer, Class<T> classOfT,Field f, Annotation[] extraAnnotations);
+    <T> T decode(BitBuffer bitbuffer, Class<T> classOfT,Field f, Annotation[] extraAnnotations,AsnExtractor extractor);
     <T> T getDefault(Class<T> classOfT, Annotation[] extraAnnotations);
 }
diff --git a/src/main/java/org/uic/barcode/asn1/uper/EnumCoder.java b/src/main/java/org/uic/barcode/asn1/uper/EnumCoder.java
index 5d78bc7..3bfdec9 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/EnumCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/EnumCoder.java
@@ -82,7 +82,7 @@ class EnumCoder implements Decoder, Encoder {
 
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations);
         UperEncoder.logger.debug("ENUM");
         boolean extensionPresent = false;
diff --git a/src/main/java/org/uic/barcode/asn1/uper/IntCoder.java b/src/main/java/org/uic/barcode/asn1/uper/IntCoder.java
index 5964a64..e5e48c1 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/IntCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/IntCoder.java
@@ -27,7 +27,7 @@ class IntCoder implements Encoder, Decoder {
     
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations)  {
+            Annotation[] extraAnnotations, AsnExtractor extractor)  {
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(),extraAnnotations);
     	String pos = String.format("Position: %d.%d", bitbuffer.position()/8 , bitbuffer.position() % 8);
         UperEncoder.logger.debug(String.format("%s: INTEGER",pos));
diff --git a/src/main/java/org/uic/barcode/asn1/uper/SeqOfCoder.java b/src/main/java/org/uic/barcode/asn1/uper/SeqOfCoder.java
index a7ae7ba..d0ce782 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/SeqOfCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/SeqOfCoder.java
@@ -96,7 +96,7 @@ class SeqOfCoder implements Decoder, Encoder {
     @SuppressWarnings("unchecked")
 	@Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT,Field field,
-            Annotation[] extraAnnotations)  {
+            Annotation[] extraAnnotations, AsnExtractor extractor)  {
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(),
                 extraAnnotations);
         UperEncoder.logger.debug(String.format("SEQUENCE OF for %s", classOfT));
@@ -135,7 +135,7 @@ class SeqOfCoder implements Decoder, Encoder {
         	}
         }        
         for (int i = 0; i < size; i++) {
-            coll.add(UperEncoder.decodeAny(bitbuffer, classOfElements,field,  annotationArray));
+            coll.add(UperEncoder.decodeAny(bitbuffer, classOfElements,field,  annotationArray, extractor));
         }
         
         T result = null;
diff --git a/src/main/java/org/uic/barcode/asn1/uper/SequenceCoder.java b/src/main/java/org/uic/barcode/asn1/uper/SequenceCoder.java
index ce89a3e..3af7217 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/SequenceCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/SequenceCoder.java
@@ -150,13 +150,24 @@ class SequenceCoder implements Decoder, Encoder {
 
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT,Field f1,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations,
+            AsnExtractor extractor) {
         UperEncoder.logger.debug(String.format("decode SEQUENCE %s",classOfT.getSimpleName()));
         AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(),extraAnnotations);
         T result = UperEncoder.instantiate(classOfT);
-        Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT);
+        Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT);        
         boolean hasExtensionMarker = UperEncoder.hasExtensionMarker(annotations);
         boolean extensionPresent = false;
+        
+        //check Extraction
+        boolean extract = false;
+        if (extractor != null && !extractor.isStarted() && extractor.found(classOfT.getCanonicalName())) {
+        	extractor.startExtraction(bitbuffer.position());
+        	extract = true;
+        }
+        
+        
+        //start decodong
         if (hasExtensionMarker) {
             extensionPresent = bitbuffer.get();
             UperEncoder.logger.debug(String.format("with extension marker, extension %s", extensionPresent ? "present!" : "absent"));
@@ -175,7 +186,7 @@ class SequenceCoder implements Decoder, Encoder {
                 (UperEncoder.isOptional(f) && optionalFieldsMask.pop()))) {
                 UperEncoder.logger.debug(String.format("Field : %s", f.getName()));
                 try {
-                    f.set(result, UperEncoder.decodeAny(bitbuffer,f.getType(),f, f.getAnnotations()));
+                    f.set(result, UperEncoder.decodeAny(bitbuffer,f.getType(),f, f.getAnnotations(),extractor));
                 } catch (IllegalAccessException e) {
                     throw new IllegalArgumentException("can't access 'set method' for field " + f + " of class " + classOfT + " " + e, e);
                 }
@@ -196,6 +207,11 @@ class SequenceCoder implements Decoder, Encoder {
         if (!hasExtensionMarker) {
         	//done
         	sorter.revertAccess();
+        	
+            if (extract) {
+            	extractor.endExtraction(bitbuffer.position());
+            }
+            
         	return result; 
         }
         
@@ -222,7 +238,7 @@ class SequenceCoder implements Decoder, Encoder {
         				Class<?> classOfElement = field != null ? field.getType() : null;
         				if (field != null) {
         					try {
-        						Object decodedValue = UperEncoder.decodeAsOpenType(bitbuffer, classOfElement,field, field.getAnnotations());
+        						Object decodedValue = UperEncoder.decodeAsOpenType(bitbuffer, classOfElement,field, field.getAnnotations(),extractor);
         						if (field != null) {
         							field.set(result, decodedValue);
         						}
@@ -269,6 +285,11 @@ class SequenceCoder implements Decoder, Encoder {
         	} // end of extension handling
         }
         sorter.revertAccess();
+        
+        if (extract) {
+        	extractor.endExtraction(bitbuffer.position());
+        }
+        
         return result;       
     }
 
diff --git a/src/main/java/org/uic/barcode/asn1/uper/StringCoder.java b/src/main/java/org/uic/barcode/asn1/uper/StringCoder.java
index 349e988..a504096 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/StringCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/StringCoder.java
@@ -150,7 +150,7 @@ class StringCoder implements Decoder, Encoder {
 
     @Override public <T> T decode(BitBuffer bitbuffer,
             Class<T> classOfT, Field field,
-            Annotation[] extraAnnotations) {
+            Annotation[] extraAnnotations, AsnExtractor extractor) {
         UperEncoder.logger.debug("decode String");
     	AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations);
         RestrictedString restrictionAnnotation = annotations.getAnnotation(RestrictedString.class);
diff --git a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java
index d5c5d1e..c256b4f 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java
@@ -66,7 +66,7 @@ public final class UperEncoder {
     public static <T> T decode(byte[] bytes, Class<T> classOfT) throws IllegalArgumentException,
     UnsupportedOperationException {
     		BitBuffer bitQueue = bitBufferFromBinaryString(binaryStringFromBytes(bytes));
-    		T result = decodeAny(bitQueue, classOfT,null, new Annotation[] {});
+    		T result = decodeAny(bitQueue, classOfT,null, new Annotation[] {}, null);
     		if (bitQueue.remaining() > 7) {
     				throw new IllegalArgumentException("Can't fully decode "
     						+ classOfT.getName() + ", got (" + result.getClass().getName() + "): " + result
@@ -74,11 +74,43 @@ public final class UperEncoder {
     		}
     		return result;
     }
+    
+    public static <T> T decode(byte[] bytes, Class<T> classOfT,AsnExtractor extractor) throws IllegalArgumentException,
+    UnsupportedOperationException {
+    		BitBuffer bitQueue = bitBufferFromBinaryString(binaryStringFromBytes(bytes));
+    		T result = decodeAny(bitQueue, classOfT,null, new Annotation[] {}, extractor);
+    		if (bitQueue.remaining() > 7) {
+    				throw new IllegalArgumentException("Can't fully decode "
+    						+ classOfT.getName() + ", got (" + result.getClass().getName() + "): " + result
+    						+ "; remaining " + bitQueue.remaining() + "  bits: " + bitQueue);
+    		}
+    		return result;
+    }
+    
+    
+    public static <T> byte[] extract(byte[] bytes,String path,Class<T> classOfT) throws IllegalArgumentException, UnsupportedOperationException {
+ 
+    	    BitBuffer bitQueue = bitBufferFromBinaryString(binaryStringFromBytes(bytes));
+    	    
+    	    AsnExtractor extractor = new AsnExtractor(path,bitQueue);
+    	    
+    		T result = decodeAny(bitQueue, classOfT,null, new Annotation[] {}, extractor);
+    		if (bitQueue.remaining() > 7) {
+    				throw new IllegalArgumentException("Can't fully decode "
+    						+ classOfT.getName() + ", got (" + result.getClass().getName() + "): " + result
+    						+ "; remaining " + bitQueue.remaining() + "  bits: " + bitQueue);
+    		}
+    		return extractor.getResult();
+    }
+    
+    
+    
+    
 
-    public static <T> T decode(byte[] bytes, Class<T> classOfT, Field f) throws IllegalArgumentException,
+    public static <T> T decode(byte[] bytes, Class<T> classOfT, Field f,AsnExtractor extractor) throws IllegalArgumentException,
             UnsupportedOperationException {
         BitBuffer bitQueue = bitBufferFromBinaryString(binaryStringFromBytes(bytes));
-        T result = decodeAny(bitQueue, classOfT, f, new Annotation[] {});
+        T result = decodeAny(bitQueue, classOfT, f, new Annotation[] {}, extractor);
         if (bitQueue.remaining() > 7) {
             throw new IllegalArgumentException("Can't fully decode "
                 + classOfT.getName() + ", got (" + result.getClass().getName() + "): " + result
@@ -108,13 +140,13 @@ public final class UperEncoder {
                 + " with extra annotations " + Arrays.asList(extraAnnotations));
     }
 
-    static <T> T decodeAny(BitBuffer bitbuffer,Class<T> classOfT, Field f, Annotation[] extraAnnotations) {
+    static <T> T decodeAny(BitBuffer bitbuffer,Class<T> classOfT, Field f, Annotation[] extraAnnotations, AsnExtractor extractor) {
     	   	
         logger.debug(String.format(String.format("Decoding classOfT : %s",classOfT.getCanonicalName())));
         
         for (Decoder e : decoders) {
             if (e.canDecode(classOfT, extraAnnotations)) {
-                return e.decode(bitbuffer, classOfT,f, extraAnnotations);
+                return e.decode(bitbuffer, classOfT,f, extraAnnotations,extractor);
             }
         }
         
@@ -216,7 +248,7 @@ public final class UperEncoder {
         
     }
 
-    static <T> T decodeAsOpenType(BitBuffer bitbuffer, Class<T> classOfT,Field f, Annotation[] extraAnnotations) {
+    static <T> T decodeAsOpenType(BitBuffer bitbuffer, Class<T> classOfT,Field f, Annotation[] extraAnnotations,AsnExtractor extractor) {
         logger.debug(String.format("OPEN TYPE for %s. Encoding preceedes length determinant", classOfT != null ? classOfT.getName() : "null"));
         long numBytes = decodeLengthDeterminant(bitbuffer);
         BitBuffer openTypeBitBuffer = ByteBitBuffer.allocate((int)numBytes * 8);
@@ -225,7 +257,7 @@ public final class UperEncoder {
         }
         openTypeBitBuffer.flip();
         if (classOfT != null) {
-            T result = decodeAny(openTypeBitBuffer, classOfT, f, extraAnnotations);
+            T result = decodeAny(openTypeBitBuffer, classOfT, f, extraAnnotations, extractor);
             // Assert that padding bits are all 0.
             logger.debug(String.format("open type had padding bits"));
             for (int i = 0; i < openTypeBitBuffer.remaining(); i++) {
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 f357c4d..1e8a0ff 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
@@ -89,21 +89,23 @@ public interface IDynamicFrame{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
-	 * @return the int
+	 * @param data the data content
+	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2() throws EncodingFormatException;
+	public int validateLevel2(byte[] data) throws EncodingFormatException;
 	
 	/**
 	 * Verify the level 2 signature
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
-	 * @param prov the prov
-	 * @return the int
+	 * @param prov the registered security provider
+     * @param data the data content
+	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2(Provider prov) throws EncodingFormatException;
+	public int validateLevel2(Provider prov, byte[] data) throws EncodingFormatException;
 
 	/**
 	 * Verify the level 1 signature
@@ -111,23 +113,25 @@ public interface IDynamicFrame{
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
 	 * @param key the key
-	 * @param prov the prov
-	 * @return the int
+	 * @param data the data content
+	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */
-	public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException;
+	public int validateLevel1(PublicKey key, byte[] data) throws EncodingFormatException;
 	
-  
 	/**
 	 * Verify the level 1 signature
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
 	 * @param key the key
-	 * @return the int
+	 * @param prov the registered security provider 
+	 * @param the data content
+	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */
-	public int validateLevel1(PublicKey key) throws EncodingFormatException;
+	public int validateLevel1(PublicKey key, Provider prov,  byte[] data) throws EncodingFormatException;
+ 
 	
 	/**
 	 * Sign level 2 data without a specific security provider.
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 4c5c879..ec52758 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
@@ -12,6 +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.dynamicContent.api.DynamicContentCoder;
 import org.uic.barcode.dynamicContent.api.IUicDynamicContent;
 import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
@@ -143,6 +144,22 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		return null;
 	}
 	
+	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_1.equals(format)) {
+			
+			return DynamicFrameCoderV2.getEncoded(path, data);
+			
+		}
+		
+		return null;
+	}
+	
+	
 	private byte[] encode(ILevel2Data level2SignedData2) throws EncodingFormatException {
 		
 		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
@@ -213,9 +230,9 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the int
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2() throws EncodingFormatException {
+	public int validateLevel2(byte[] data) throws EncodingFormatException {
 
-		return validateLevel2(null);
+		return validateLevel2(null, data);
 	
 	}
 	
@@ -224,11 +241,11 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
-	 * @param prov the prov
-	 * @return the int
+	 * @param prov the registered security provider
+	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2(Provider prov) throws EncodingFormatException {
+	public int validateLevel2(Provider prov, byte[] data) throws EncodingFormatException {
 		
 		
 		String level2KeyAlg = this.getLevel2Data().getLevel1Data().getLevel2KeyAlg();
@@ -244,7 +261,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 					
 		String keyAlgName = null;
 		try {
-			keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg);
+			keyAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, level2KeyAlg,prov);
 		} catch (Exception e1) {
 			return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;	
 		}
@@ -268,7 +285,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 
 		String sigAlgName = null;
 		try {
-			sigAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,level2SigAlg);
+			sigAlgName = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,level2SigAlg,prov);
 		} catch (Exception e1) {
 			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		}
@@ -293,8 +310,14 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		}
 		
 		try {
-			byte[] data = encode(level2Data);
-			sig.update(data);
+			//TODO
+			//byte[] signedData = encode(level2Data);
+			//String s1 = AsnUtils.toBooleanString(signedData);
+			
+			byte[] signedData2 = getEncoded("Level2Data", data);
+			//String s2 = AsnUtils.toBooleanString(signedData);
+			
+			sig.update(signedData2);
 		} catch (SignatureException e) {
 			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		} catch (IllegalArgumentException e) {
@@ -325,7 +348,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the int
 	 * @throws EncodingFormatException 
 	 */
-	public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException {
+	public int validateLevel1(PublicKey key, Provider prov, byte[] data) throws EncodingFormatException {
 		
 		if (level2Data == null) {
 			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
@@ -342,7 +365,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		//find the algorithm name for the signature OID
 		String algo = null;
 		try {
-			algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel2Data().getLevel1Data().getLevel1SigningAlg());
+			algo = AlgorithmNameResolver.getSignatureAlgorithmName(getLevel2Data().getLevel1Data().getLevel1SigningAlg(), prov);
 		} catch (Exception e1) {
 			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		}	
@@ -368,7 +391,15 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		}
 		
 		try {
-			sig.update(encode(level2Data.getLevel1Data()));
+			
+			//byte[] encodedData = encode(level2Data.getLevel1Data());
+			//String s1 = AsnUtils.toBooleanString(encodedData);
+			//TODO
+			byte[]  encodedData2 = getEncoded("Level1Data", data);
+			//String s2 = AsnUtils.toBooleanString(encodedData2);
+			
+			sig.update(encodedData2);	
+			
 		} catch (SignatureException e) {
 			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		} catch (IllegalArgumentException e) {
@@ -402,9 +433,9 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the int
 	 * @throws EncodingFormatException 
 	 */
-	public int validateLevel1(PublicKey key) throws EncodingFormatException {
+	public int validateLevel1(PublicKey key, byte[] data) throws EncodingFormatException {
 		
-		return validateLevel1(key, null);
+		return validateLevel1(key, null,data);
 
   	}
 	
@@ -416,13 +447,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 */
 	public void signLevel2(PrivateKey key) throws Exception {
 		
-		//find the algorithm name for the signature OID
-		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level2Data.getLevel1Data().getLevel2SigningAlg());
-		Signature sig = Signature.getInstance(algo);
-		sig.initSign(key);
-		byte[] data = encode(level2Data);
-		sig.update(data);
-		level2Signature = sig.sign();
+		signLevel2(key, null);
 		
 	}
 
@@ -430,17 +455,22 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * Sign level 2 data.
 	 *
 	 * @param key the key
-	 * @param prov the security Provider
+	 * @param prov the registered 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.getLevel2Data().getLevel1Data().getLevel2SigningAlg());
-		Signature sig = Signature.getInstance(algo,prov);
+		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[] data = encode(level2Data);
-		sig.update(data);
+		byte[] signedData = encode(level2Data);
+		sig.update(signedData);
 		level2Signature = sig.sign();
 		
 	}
@@ -453,8 +483,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @throws EncodingFormatException the encoding format exception
 	 */
 	public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
-		
-		
+				
 		level2Data.setLevel2Data(new SimpleData());
 		
 		level2Data.getLevel2Data().setFormat(DynamicContentCoder.dynamicContentDataFDC1);
@@ -501,19 +530,8 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 */
 	public void signLevel1(PrivateKey key) throws Exception {
 		
-		if (level2Data == null) return;
-		
-		ILevel1Data level1Data = level2Data.getLevel1Data();
-		
-		if (level1Data == null) return;
+		signLevel1(key, null);
 		
-		//find the algorithm name for the signature OID
-		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level1Data.getLevel1SigningAlg());
-		Signature sig = Signature.getInstance(algo);
-		sig.initSign(key);
-		byte[] data = encode(level1Data);
-		sig.update(data);
-		level2Data.setLevel1Signature(sig.sign());
 	}
 
 	/**
@@ -538,16 +556,17 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		
 		//find the algorithm name for the signature OID
 		String algo = AlgorithmNameResolver.getSignatureAlgorithmName(level1Data.getLevel1SigningAlg());
-		Signature sig = Signature.getInstance(algo, prov);
+		Signature sig = null;
+		if (prov != null) {
+			sig = Signature.getInstance(algo, prov);
+		} else {
+			sig = Signature.getInstance(algo);
+		}
 		sig.initSign(key);
 				
 		byte[] data = encode(level1Data);
 		sig.update(data);
 		level2Data.setLevel1Signature(sig.sign());	
 	}
-
-
-
-	
 	
 }
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 f7b3f3d..1cffa12 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
@@ -100,6 +100,19 @@ public class DynamicFrameCoderV1 {
 		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[] encode(ILevel2Data level2SignedData) throws EncodingFormatException {
 		
        Level2DataType asn = populateAsn(level2SignedData);
@@ -183,6 +196,8 @@ public class DynamicFrameCoderV1 {
 		
 		return asnLevel1;
 	}
+
+	
 	
 
 
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 8987f59..bdaa31a 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
@@ -197,6 +197,17 @@ public class DynamicFrameCoderV2 {
 		
 		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;
+	}
 	
 
 
diff --git a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
index 4491358..a3154f3 100644
--- a/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
+++ b/src/main/java/org/uic/barcode/utils/AlgorithmNameResolver.java
@@ -24,6 +24,26 @@ public class AlgorithmNameResolver {
     	
     }
     
+    public static String getSignatureAlgorithmName (String oid, Provider provider) throws Exception {
+    	
+    	if (provider != null) {
+    		 Service service = provider.getService(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid);
+    		 return service.getAlgorithm();
+    	}
+    	
+    	
+ 		Provider[] provs = Security.getProviders();
+ 		for (Provider prov : provs) {
+ 		       Service service = prov.getService(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,oid);
+ 		       if (service != null) {
+	    		   return service.getAlgorithm();
+ 		       }
+ 		}
+ 		return null;
+     	
+     }
+    
+    
     public static String getName (String type, String oid) throws Exception {
     	
 		Provider[] provs = Security.getProviders();
@@ -45,9 +65,22 @@ public class AlgorithmNameResolver {
     }
     	
     
-   public static String getName(String type, String oid, Provider prov) throws Exception {
+   public static String getName(String type, String oid, Provider provider) throws Exception {
+	   
+	   Service service = null;
+	   if (provider == null) {
+		   
+			Provider[] provs = Security.getProviders();
+			for (Provider prov : provs) {
+			       service = prov.getService(type,oid);
+			}	   
+		   
+	   } else {
+		   service = provider.getService(type,oid);
+	   }
+	   
 	   
-       	Service service = prov.getService(type,oid);
+       	
        	if (service != null) {
     	   return service.getAlgorithm();
        	}
-- 
cgit v1.2.3


From 7af6c4ca50322258bbd23214920c4c9122482966 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Tue, 25 Jan 2022 13:33:37 +0100
Subject: test for the new dynamic header version 2

---
 .../java/org/uic/barcode/asn1/uper/AsnUtils.java   | 16 +++++
 .../org/uic/barcode/dynamicFrame/Constants.java    |  3 +
 .../barcode/dynamicFrame/api/IDynamicFrame.java    |  3 +-
 .../uic/barcode/dynamicFrame/api/SimpleData.java   |  7 ---
 .../dynamicFrame/api/SimpleDynamicFrame.java       | 68 ++++++++++++++--------
 .../barcode/dynamicFrame/api/SimpleLevel1Data.java |  1 -
 .../dynamicFrame/v1/DynamicFrameCoderV1.java       | 12 ++--
 .../dynamicFrame/v2/DynamicFrameCoderV2.java       |  2 +-
 .../barcode/dynamicFrame/v2/Level1DataType.java    | 25 +++++---
 9 files changed, 88 insertions(+), 49 deletions(-)

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java b/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java
index dbb95c9..414f181 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/AsnUtils.java
@@ -1,5 +1,7 @@
 package org.uic.barcode.asn1.uper;
 
+import java.math.BigInteger;
+
 public class AsnUtils {
 	
 
@@ -55,5 +57,19 @@ public class AsnUtils {
 	    boolean result = (bytes[index / 8] & mask[index % 8]) != 0;
 	    return result;
 	}
+	
+	public static byte[] shiftBytesToLeft(byte[] bytes, int shift) {
+		
+		// create from array
+		BigInteger bigInt = new BigInteger(bytes);
+
+		// shift
+		BigInteger shiftInt = bigInt.shiftLeft(shift);
+
+		// back to array
+		return shiftInt.toByteArray();
+
+	}
+	
 
 }
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
index ba15f3f..3623817 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java
@@ -38,4 +38,7 @@ public class Constants {
 	
 	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/api/IDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
index 1e8a0ff..d901a6e 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
@@ -79,8 +79,9 @@ public interface IDynamicFrame{
 	 *
 	 * @param bytes the bytes
 	 * @return the dynamic header
+	 * @throws EncodingFormatException 
 	 */
-	public void decode(byte[] bytes);
+	public void decode(byte[] bytes) throws EncodingFormatException;
 	
 
 	
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
index cb762de..d6e1410 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleData.java
@@ -1,12 +1,5 @@
 package org.uic.barcode.dynamicFrame.api;
 
-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;
-import org.uic.barcode.asn1.uper.UperEncoder;
-
 /**
  * The Class DataType.
  */
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 ec52758..65b81d6 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java
@@ -120,7 +120,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 			
 			return DynamicFrameCoderV1.encode(this);
 			
-		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
 			
 			return DynamicFrameCoderV2.encode(this);
 			
@@ -135,13 +135,12 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 			
 			return DynamicFrameCoderV1.encode(level1Data);
 			
-		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
 			
 			return DynamicFrameCoderV2.encode(level1Data);
 			
 		}
-		
-		return null;
+		throw new EncodingFormatException("Dynamic Header Version not supported: " + format);
 	}
 	
 	private byte[] getEncoded(String path, byte[] data) throws EncodingFormatException {
@@ -150,29 +149,29 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 			
 			return DynamicFrameCoderV1.getEncoded(path, data);
 			
-		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
 			
 			return DynamicFrameCoderV2.getEncoded(path, data);
 			
 		}
 		
-		return null;
+		throw new EncodingFormatException("Dynamic Header Version not supported: " + format);
 	}
 	
 	
-	private byte[] encode(ILevel2Data level2SignedData2) throws EncodingFormatException {
+	private byte[] encode(ILevel2Data level2Data) throws EncodingFormatException {
 		
 		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
 			
-			return DynamicFrameCoderV1.encode(level2SignedData2);
+			return DynamicFrameCoderV1.encode(level2Data);
 			
-		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
+		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
 			
-			return DynamicFrameCoderV2.encode(level2SignedData2);
+			return DynamicFrameCoderV2.encode(level2Data);
 			
 		}
 		
-		return null;
+		throw new EncodingFormatException("Dynamic Header Version not supported: " + format);
 	}
 	
 	/**
@@ -182,22 +181,24 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @param bytes the bytes
 	 * @return the dynamic header
+	 * @throws EncodingFormatException 
 	 */
-	public void decode(byte[] bytes) {
+	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;
 			
 		} else if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2.equals(format)) {
 		
 			DynamicFrameCoderV2.decode(this,bytes);
-			
+			return;
 		}
 		
-		
+		throw new EncodingFormatException("Dynamic Header Version not supported");
 
 	}
 	
@@ -211,12 +212,35 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return true, if is static header
 	 */
 	private static String getFormat(byte[] data) {
-		byte[] start = "U1".getBytes();
-		if (start[0] != data[0] || start[1]!= start[1]) {
+		
+		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;
 		}
-		start = "U2".getBytes();
-		if (start[0] != data[0] || start[1]!= start[1]) {
+		
+		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2_BIN.equals(start.substring(10, 24))) {
 			return Constants.DYNAMIC_BARCODE_FORMAT_VERSION_2;
 		}
 		return null;
@@ -392,13 +416,9 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		
 		try {
 			
-			//byte[] encodedData = encode(level2Data.getLevel1Data());
-			//String s1 = AsnUtils.toBooleanString(encodedData);
-			//TODO
-			byte[]  encodedData2 = getEncoded("Level1Data", data);
-			//String s2 = AsnUtils.toBooleanString(encodedData2);
+			byte[]  encodedData = getEncoded("Level1Data", data);
 			
-			sig.update(encodedData2);	
+			sig.update(encodedData);	
 			
 		} catch (SignatureException e) {
 			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
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 241cf6d..e9b1d4e 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleLevel1Data.java
@@ -3,7 +3,6 @@ package org.uic.barcode.dynamicFrame.api;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import org.uic.barcode.asn1.uper.UperEncoder;
 
 /**
  * The Class SignedDataType.
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 1cffa12..39fcf32 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrameCoderV1.java
@@ -113,9 +113,9 @@ public class DynamicFrameCoderV1 {
 	}
 	
 	
-	public static byte[] encode(ILevel2Data level2SignedData) throws EncodingFormatException {
+	public static byte[] encode(ILevel2Data level2Data) throws EncodingFormatException {
 		
-       Level2DataType asn = populateAsn(level2SignedData);
+       Level2DataType asn = populateAsn(level2Data);
 		
 		return UperEncoder.encode(asn);
 	}
@@ -150,10 +150,10 @@ public class DynamicFrameCoderV1 {
 		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);
+			DataType asnData = new DataType();
+			asnData.setFormat(level2.getLevel2Data().getFormat());
+			asnData.setData(new OctetString(level2.getLevel2Data().getData()));
+			asnLevel2.setLevel2Data(asnData);
 		}
 
 		return asnLevel2;
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 bdaa31a..de475a9 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrameCoderV2.java
@@ -120,7 +120,7 @@ public class DynamicFrameCoderV2 {
 		
 		DynamicFrame asnFrame = new DynamicFrame();
 		
-		frame.setFormat(frame.getFormat());
+		asnFrame.setFormat(frame.getFormat());
 		
 		if (frame.getLevel2Signature() != null && frame.getLevel2Signature().length > 0) {
 			asnFrame.setLevel2Signature(new OctetString(frame.getLevel2Signature()));
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 1dff709..63db364 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/Level1DataType.java
@@ -100,16 +100,16 @@ public class Level1DataType {
 	/** The End of validity year. */
 	@FieldOrder(order = 9)
 	@IntRange(minValue=2016,maxValue=2269)
-	public Long EndOfValidityYear;
+	@Asn1Optional public Long EndOfValidityYear;
 
 	/** The End of validity day. */
 	@FieldOrder(order = 10)
 	@IntRange(minValue=1,maxValue=366)
-	public Long EndOfValidityDay;
+	@Asn1Optional public Long EndOfValidityDay;
 
 	/** The End of validity time. */
 	@FieldOrder(order = 11)
-	@IntRange(minValue=0,maxValue=1440)
+	@IntRange(minValue=0,maxValue=1439)
 	@Asn1Optional public Long EndOfValidityTime;
 	
 	
@@ -309,25 +309,26 @@ public class Level1DataType {
 	}
 	
 	/**
-	 * Sets the end of validity date. The validity date has to be provided in UTC.
-	 *
+	 * Sets the end of validity date. 
 	 * @param date the new end of validity date
 	 */
 	public void setEndOfValidityDate(Date date){
 		
-		if (date == null) {
-			date = Calendar.getInstance().getTime();
-		}
+		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);
 		
 	}
 	
@@ -340,6 +341,9 @@ public class Level1DataType {
 		
 		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"));
@@ -356,6 +360,9 @@ public class Level1DataType {
 		}
 		
 		Date d = cal.getTime();
+		
+		TimeZone.setDefault(local);
+		
 		return d;
 	}
 
-- 
cgit v1.2.3


From 7410ac59ba8e1994254a872104ea660b992cba9a Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Fri, 28 Jan 2022 17:06:47 +0100
Subject: new dynamic header version

---
 src/main/java/org/uic/barcode/Decoder.java         |  44 ++++-
 src/main/java/org/uic/barcode/Encoder.java         |  59 ++++++-
 .../dynamicContent/api/IUicDynamicContent.java     |   1 -
 .../fdc1/GeoCoordinateSystemType.java              |   1 -
 .../barcode/dynamicContent/fdc1/GeoUnitType.java   |   1 -
 .../fdc1/HemisphereLatitudeType.java               |   1 -
 .../fdc1/HemisphereLongitudeType.java              |   1 -
 .../dynamicFrame/api/DynamicFrameCoder.java        | 107 ++++++++++++
 .../barcode/dynamicFrame/api/IDynamicFrame.java    |  75 +++++----
 .../uic/barcode/dynamicFrame/api/ILevel1Data.java  |  60 +++++--
 .../dynamicFrame/api/SimpleDynamicFrame.java       | 183 ++++++---------------
 .../barcode/dynamicFrame/api/SimpleLevel1Data.java |  11 ++
 .../barcode/dynamicFrame/api/SimpleLevel2Data.java |  19 ---
 .../dynamicFrame/v1/DynamicFrameCoderV1.java       |  19 ++-
 .../org/uic/barcode/dynamicFrame/v2/DataType.java  |   2 -
 .../uic/barcode/dynamicFrame/v2/DynamicFrame.java  |   2 -
 .../dynamicFrame/v2/DynamicFrameCoderV2.java       |  25 ++-
 .../barcode/dynamicFrame/v2/Level1DataType.java    |  41 +++--
 .../barcode/dynamicFrame/v2/Level2DataType.java    |   2 -
 19 files changed, 412 insertions(+), 242 deletions(-)
 create mode 100644 src/main/java/org/uic/barcode/dynamicFrame/api/DynamicFrameCoder.java

(limited to 'src/main/java')

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)
-- 
cgit v1.2.3


From 2f72a6419dd1e20acf6e77a9276a6055892e732a Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Tue, 1 Feb 2022 12:45:04 +0100
Subject: - missing fieldOrder added - validation of level1 when the signature
 algorithm is missing

---
 src/main/java/org/uic/barcode/Decoder.java         |  35 +++-
 .../barcode/dynamicFrame/api/IDynamicFrame.java    |  45 +++--
 .../dynamicFrame/api/SimpleDynamicFrame.java       | 144 +++++++--------
 .../org/uic/barcode/dynamicFrame/v1/DataType.java  |   3 +
 .../uic/barcode/dynamicFrame/v1/DynamicFrame.java  | 203 ---------------------
 .../org/uic/barcode/dynamicFrame/v2/DataType.java  |   3 +
 .../uic/barcode/dynamicFrame/v2/DynamicFrame.java  | 202 --------------------
 7 files changed, 137 insertions(+), 498 deletions(-)

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java
index 3d97e0a..9f5ea82 100644
--- a/src/main/java/org/uic/barcode/Decoder.java
+++ b/src/main/java/org/uic/barcode/Decoder.java
@@ -65,6 +65,32 @@ public class Decoder {
 		decode(data);
 	}
 	
+	/**
+	 * Validate level 1.
+	 *
+	 * @param key the public key
+	 * @param signingAlg the signing algorithm OID
+	 * @return the return code indicating errors
+	 * @throws InvalidKeyException the invalid key exception
+	 * @throws NoSuchAlgorithmException the no such algorithm exception
+	 * @throws SignatureException the signature exception
+	 * @throws IllegalArgumentException the illegal argument exception
+	 * @throws UnsupportedOperationException the unsupported operation exception
+	 * @throws IOException Signals that an I/O exception has occurred.
+	 * @throws EncodingFormatException the encoding format exception
+	 */
+	public int validateLevel1(PublicKey key) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
+		if (dynamicFrame != null) {
+			return dynamicFrame.validateLevel1(key) ;
+		} else {
+			if (staticFrame != null) {
+				return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+			} else {
+				return Constants.LEVEL1_VALIDATION_FRAUD;
+			}
+		}
+	}
+	
 	/**
 	 * Validate level 1.
 	 *
@@ -81,7 +107,7 @@ public class Decoder {
 	 */
 	public int validateLevel1(PublicKey key, String signingAlg) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
 		if (dynamicFrame != null) {
-			return dynamicFrame.validateLevel1(key, data) ;
+			return dynamicFrame.validateLevel1(key, signingAlg) ;
 		} else {
 			if (staticFrame.verifyByAlgorithmOid(key,signingAlg)) {
 				return Constants.LEVEL1_VALIDATION_OK;
@@ -108,7 +134,7 @@ public class Decoder {
 	 */
 	public int validateLevel1(PublicKey key, String signingAlg, Provider provider) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel1(key, provider, data) ;
+			return dynamicFrame.validateLevel1(key, provider) ;
 		} else {
 			if (staticFrame.verifyByAlgorithmOid(key,signingAlg, provider)) {
 				return Constants.LEVEL1_VALIDATION_OK;
@@ -126,7 +152,7 @@ public class Decoder {
 	 */
 	public int validateLevel2() throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel2(null, data) ;
+			return dynamicFrame.validateLevel2() ;
 		} else {
 			return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
 		}
@@ -139,7 +165,7 @@ public class Decoder {
 	 */
 	public int validateLevel2(Provider prov) throws EncodingFormatException {
 		if (!isStaticHeader(data)) {
-			return dynamicFrame.validateLevel2(prov,data) ;
+			return dynamicFrame.validateLevel2(prov) ;
 		} else {
 			return Constants.LEVEL2_VALIDATION_NO_SIGNATURE;
 		}
@@ -164,7 +190,6 @@ public class Decoder {
 			
 			ILevel1Data level1 = level2.getLevel1Data();
 			
-			
 			for (IData level1Content : level1.getData()) {
 				
 				uicTicketCoder = new UicRailTicketCoder();
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 c917b6a..4b2d1f4 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/api/IDynamicFrame.java
@@ -66,12 +66,10 @@ public interface IDynamicFrame{
 	 * Verify the level 2 signature
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param data the data content
 	 * @return the return error code
 	 * @throws EncodingFormatException the encoding format exception
 	 */	
-	public int validateLevel2(byte[] data) throws EncodingFormatException;
+	public int validateLevel2() throws EncodingFormatException;
 	
 	/**
 	 * Verify the level 2 signature
@@ -79,11 +77,10 @@ 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
 	 * @return the return error code
 	 * @throws EncodingFormatException the encoding format exception
 	 */	
-	public int validateLevel2(Provider prov, byte[] data) throws EncodingFormatException;
+	public int validateLevel2(Provider prov) throws EncodingFormatException;
 
 	/**
 	 * Verify the level 1 signature
@@ -95,7 +92,20 @@ public interface IDynamicFrame{
 	 * @return the return error code
 	 * @throws EncodingFormatException the encoding format exception
 	 */
-	public int validateLevel1(PublicKey key, byte[] data) throws EncodingFormatException;
+	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
@@ -104,12 +114,22 @@ public interface IDynamicFrame{
 	 *
 	 * @param key the key
 	 * @param prov the registered security provider
-	 * @param data the data
 	 * @return the return error code
 	 * @throws EncodingFormatException the encoding format exception
 	 */
-	public int validateLevel1(PublicKey key, Provider prov,  byte[] data) throws EncodingFormatException;
+	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.
@@ -159,8 +179,8 @@ public interface IDynamicFrame{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
-	 * @param key the key
-	 * @return the byte[]
+	 * @param key the private key
+	 * @return the signature
 	 * @throws Exception the exception
 	 */
 	public void signLevel1(PrivateKey key) throws Exception;
@@ -170,8 +190,8 @@ public interface IDynamicFrame{
 	 * 
 	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
 	 *
-	 * @param key the key
-	 * @param prov the prov
+	 * @param key the private key
+	 * @param prov the security provider providing the signature implementation
 	 * @return the byte[]
 	 * @throws Exception the exception
 	 */
@@ -185,7 +205,6 @@ public interface IDynamicFrame{
 	 */
 	public byte[] getLevel1Signature();
 
-
 	/**
 	 * Gets the level 1 data in binary as they are signed by the level 1 signature.
 	 *
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 8d53f9a..a05a936 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,6 @@ import java.security.spec.InvalidKeySpecException;
 import java.security.spec.X509EncodedKeySpec;
 import java.util.Date;
 
-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;
@@ -57,6 +56,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @return the format
 	 */
+	@Override
 	public String getFormat() {
 		return format;
 	}
@@ -66,6 +66,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @param format the new format
 	 */
+	@Override
 	public void setFormat(String format) {
 		this.format = format;
 	}
@@ -75,6 +76,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @return the level 2 signed data
 	 */
+	@Override
 	public ILevel2Data getLevel2Data() {
 		return level2Data;
 	}
@@ -84,6 +86,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @param level2SignedData the new level 2 signed data
 	 */
+	@Override
 	public void setLevel2Data(ILevel2Data level2SignedData) {
 		this.level2Data = level2SignedData;
 	}
@@ -93,6 +96,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @return the level 2 signature
 	 */
+	@Override
 	public byte[] getLevel2Signature() {
 		return level2Signature;
 	}
@@ -102,29 +106,13 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @param level2Signature the new level 2 signature
 	 */
+	@Override
 	public void setLevel2Signature(byte[] level2Signature) {
 		this.level2Signature = level2Signature;
 	}
 
-	/**
-	 * Encode.
-	 * 
-	 * Encode the header as ASN.1 PER UNALIGNED byte array
-	 *
-	 * @return the byte[]
-	 * @throws EncodingFormatException 
-	 */
-	public byte[] encode() throws EncodingFormatException {
-		
-		return DynamicFrameCoder.encode(this);
-			
-
-		
-	}
-	
 
 	
-	
 	/**
 	 * Verify the level 2 signature
 	 * 
@@ -133,9 +121,9 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the int
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2(byte[] data) throws EncodingFormatException {
-
-		return validateLevel2(null, data);
+	@Override
+	public int validateLevel2() throws EncodingFormatException {
+		return validateLevel2(null);
 	
 	}
 	
@@ -148,10 +136,17 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the return error code
 	 * @throws EncodingFormatException 
 	 */	
-	public int validateLevel2(Provider prov, byte[] data) 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 = this.getLevel2Data().getLevel1Data().getLevel2KeyAlg();
+		String level2KeyAlg = getLevel2Data().getLevel1Data().getLevel2KeyAlg();
 
 	 
 		if (level2KeyAlg == null || level2KeyAlg.length() == 0) {
@@ -235,34 +230,53 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 		}
   	}
 	
-	/**
-	 * Verify the level 1 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param key the key
-	 * @param prov the prov
-	 * @return the int
-	 * @throws EncodingFormatException 
-	 */
-	public int validateLevel1(PublicKey key, Provider prov, byte[] data) throws EncodingFormatException {
-		
-		if (level2Data == null) {
-			return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
-		}
-		
+	@Override
+	public int validateLevel1(PublicKey key, Provider prov) throws EncodingFormatException {
+		return validateLevel1(key, prov, null);
+
+  	}
 	
-		if (level2Data == null || 
-			level2Data.getLevel1Signature().length == 0) {
+	@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(getLevel2Data().getLevel1Data().getLevel1SigningAlg(), prov);
+			algo = AlgorithmNameResolver.getSignatureAlgorithmName(signingAlgorithmOid, prov);
 		} catch (Exception e1) {
 			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		}	
@@ -301,47 +315,20 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 			return Constants.LEVEL1_VALIDATION_ENCODING_ERROR;
 		}
 		
-
 		try {
 			if (sig.verify(signature)){
-				return Constants.LEVEL2_VALIDATION_OK;
+				return Constants.LEVEL1_VALIDATION_OK;
 			} else {
-				return Constants.LEVEL2_VALIDATION_FRAUD;
+				return Constants.LEVEL1_VALIDATION_FRAUD;
 			}
 		} catch (SignatureException e) {
-			return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+			return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
 		}
-  	}
-	
-
-
-
-
-	/**
-	 * Verify the level 1 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param key the key
-	 * @return the int
-	 * @throws EncodingFormatException 
-	 */
-	public int validateLevel1(PublicKey key, byte[] data) throws EncodingFormatException {
-		
-		return validateLevel1(key, null,data);
-
-  	}
+	}
 	
-	/**
-	 * Sign level 2 data without a specific security provider.
-	 *
-	 * @param key the key
-	 * @throws Exception the exception
-	 */
+	@Override
 	public void signLevel2(PrivateKey key) throws Exception {
-		
 		signLevel2(key, null);
-		
 	}
 
 	/**
@@ -351,6 +338,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @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
@@ -375,6 +363,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @param content the dynamic content
 	 * @throws EncodingFormatException the encoding format exception
 	 */
+	@Override
 	public void addDynamicContent(IUicDynamicContent content) throws EncodingFormatException {
 				
 		level2Data.setLevel2Data(new SimpleData());
@@ -390,6 +379,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @param dynamicData the dynamic data
 	 */
+	@Override
 	public void addLevel2DynamicData(UicDynamicContentDataFDC1 dynamicData) {
 		this.getLevel2Data().setLevel2Data(dynamicData.getApiDataType());	
 	}
@@ -399,6 +389,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 *
 	 * @return the dynamic content
 	 */
+	@Override
 	public IUicDynamicContent getDynamicContent() {
 		
 		if (this.getLevel2Data() == null || 
@@ -421,6 +412,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 	 * @return the byte[]
 	 * @throws Exception 
 	 */
+	@Override
 	public void signLevel1(PrivateKey key) throws Exception {
 		
 		signLevel1(key, null);
@@ -484,7 +476,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 
 	}
 	
-	
+	@Override
 	public byte[] getLevel2DataBin() throws EncodingFormatException {
 		
 		if (Constants.DYNAMIC_BARCODE_FORMAT_VERSION_1.equals(format)) {
@@ -501,5 +493,7 @@ public class SimpleDynamicFrame implements IDynamicFrame {
 
 	}
 
+
+
 	
 }
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
index 6195b3c..e8cfc50 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DataType.java
@@ -1,6 +1,7 @@
 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
index 3af9c8f..3bfcbf5 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v1/DynamicFrame.java
@@ -1,16 +1,8 @@
 package org.uic.barcode.dynamicFrame.v1;
 
-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;
@@ -21,7 +13,6 @@ 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.dynamicFrame.Constants;
 import org.uic.barcode.ticket.EncodingFormatException;
 import org.uic.barcode.utils.AlgorithmNameResolver;
 
@@ -131,200 +122,6 @@ public class DynamicFrame extends Object{
 		return UperEncoder.decode(bytes, DynamicFrame.class);	
 	}
 	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @return the int
-	 */	
-	public int validateLevel2() {
-
-		return validateLevel2(null);
-	
-	}
-	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param prov the prov
-	 * @return the int
-	 */	
-	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 
-	 *
-	 * @param key the key
-	 * @param prov the prov
-	 * @return the int
-	 */
-	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 
-	 *
-	 * @param key the key
-	 * @return the int
-	 */
-	public int validateLevel1(PublicKey key) {
-		
-		return validateLevel1(key, null);
-
-  	}
-	
 	/**
 	 * Sign level 2 data without a specific security provider.
 	 *
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 d4f3c15..beceda9 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DataType.java
@@ -1,6 +1,7 @@
 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;
@@ -20,9 +21,11 @@ public class DataType {
 	 *  -- RICS  company code + ...
 	 **/
 	@RestrictedString(CharacterRestriction.IA5String)
+	@FieldOrder(order = 0)
 	public String format;
 	
 	/** The data. */
+	@FieldOrder(order = 1)
 	public OctetString data;
 
 	/**
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 4831c6a..55af066 100644
--- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
+++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java
@@ -1,16 +1,8 @@
 package org.uic.barcode.dynamicFrame.v2;
 
-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;
@@ -21,7 +13,6 @@ 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.dynamicFrame.Constants;
 import org.uic.barcode.ticket.EncodingFormatException;
 import org.uic.barcode.utils.AlgorithmNameResolver;
 
@@ -131,199 +122,6 @@ public class DynamicFrame extends Object{
 		return UperEncoder.decode(bytes, DynamicFrame.class);	
 	}
 	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @return the int
-	 */	
-	public int validateLevel2() {
-
-		return validateLevel2(null);
-	
-	}
-	
-	/**
-	 * Verify the level 2 signature
-	 * 
-	 * Note:  an appropriate security provider (e.g. BC) must be registered before 
-	 *
-	 * @param prov the prov
-	 * @return the int
-	 */	
-	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 
-	 *
-	 * @param key the key
-	 * @param prov the prov
-	 * @return the int
-	 */
-	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 
-	 *
-	 * @param key the key
-	 * @return the int
-	 */
-	public int validateLevel1(PublicKey key) {
-		
-		return validateLevel1(key, null);
-
-  	}
 	
 	/**
 	 * Sign level 2 data without a specific security provider.
-- 
cgit v1.2.3


From 9ff0dde49e818348df5ba9c7bca91d165227234b Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Tue, 1 Feb 2022 14:16:00 +0100
Subject: - smplified api for level 2 signature

---
 src/main/java/org/uic/barcode/Encoder.java | 52 ++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

(limited to 'src/main/java')

diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java
index 51e86a2..9afddce 100644
--- a/src/main/java/org/uic/barcode/Encoder.java
+++ b/src/main/java/org/uic/barcode/Encoder.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
+import java.util.zip.DataFormatException;
 
 import org.uic.barcode.dynamicContent.api.IUicDynamicContent;
 import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1;
@@ -163,6 +164,57 @@ public class Encoder {
 	}
 	
 	
+	/**
+	 * Instantiates a new encoder for a level 2 encoding with tan encoded dynamic frame containing the level 1 data and signature.
+	 *
+	 * @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
+	 * @throws DataFormatException 
+	 */
+	public Encoder(byte[] encoded, int version) throws IOException, EncodingFormatException, DataFormatException {
+		
+		Decoder decoder = new Decoder(encoded);
+		
+		if (decoder.getDynamicFrame() == null) {
+			throw new EncodingFormatException("No dynamic frame included");
+		}
+		
+			
+		dynamicFrame = decoder.getDynamicFrame();
+		byte[] level1DataBin = decoder.getEncodedLevel1Data();
+		byte[] signatureLevel1 = decoder.getLevel1Signature();
+			
+		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");
+		}
+		
+				
+	}
+	
+	
 	
 	/**
 	 * Signing level 2 of a dynamic bar code
-- 
cgit v1.2.3