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 --- .../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 + 27 files changed, 3666 insertions(+), 903 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/org/uic/barcode/dynamicFrame') 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{ - - /** - * Instantiates a new sequence of data type. - */ - public SequenceOfDataType() { super(); } - - /** - * Instantiates a new sequence of data type. - * - * @param coll the coll - */ - public SequenceOfDataType(Collection 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 getData(); + + + /** + * Sets the data. + * + * @param data the new data + */ + public void setData(Collection 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 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 getData() { + return dataList; + } + + /** + * Sets the data. + * + * @param data the new data + */ + public void setData(Collection 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(); + } + + 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 @@ - - - - - -

drafted new header for dynamic content

-

Provides a decoding and encoding of the header data frame. (Draft for UIC IRS 90918-9).

- - \ 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{ + + /** + * Instantiates a new sequence of data type. + */ + public SequenceOfDataType() { super(); } + + /** + * Instantiates a new sequence of data type. + * + * @param coll the coll + */ + public SequenceOfDataType(Collection 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{ + + /** + * Instantiates a new sequence of data type. + */ + public SequenceOfDataType() { super(); } + + /** + * Instantiates a new sequence of data type. + * + * @param coll the coll + */ + public SequenceOfDataType(Collection coll) { super(coll); } + +} -- cgit v1.2.3