summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java')
-rw-r--r--src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
new file mode 100644
index 0000000..9605a0d
--- /dev/null
+++ b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java
@@ -0,0 +1,266 @@
+package org.uic.barcode.dynamicFrame;
+
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+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.utils.AlgorithmNameResolver;
+
+
+/**
+ * The DynamicHeader for bar codes
+ *
+ * Implementation of the Draft under discussion, not final.
+ */
+@Sequence
+@HasExtensionMarker
+public class DynamicFrame extends Object{
+
+ public DynamicFrame() {}
+
+ /** The format. */
+ @FieldOrder(order = 0)
+ @RestrictedString(CharacterRestriction.IA5String)
+ public String format;
+
+ /*level 2 data*/
+ @FieldOrder(order = 1)
+ Level2DataType level2SignedData;
+
+
+ /** The signature of level 2 data*/
+ @FieldOrder(order = 2)
+ @Asn1Optional public OctetString level2Signature;
+
+ /**
+ * Gets the format.
+ *
+ * @return the format
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Sets the format.
+ *
+ * @param format the new format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public Level2DataType getLevel2SignedData() {
+ return level2SignedData;
+ }
+
+ public void setLevel2SignedData(Level2DataType level2SignedData) {
+ this.level2SignedData = level2SignedData;
+ }
+
+ public OctetString getLevel2Signature() {
+ return level2Signature;
+ }
+
+ public void setLevel2Signature(OctetString level2Signature) {
+ this.level2Signature = level2Signature;
+ }
+
+ /**
+ * Encode.
+ *
+ * Encode the header as ASN.1 PER UNALIGNED byte array
+ *
+ * @return the byte[]
+ */
+ public byte[] encode() {
+ return UperEncoder.encode(this);
+ }
+
+ /**
+ * Decode.
+ *
+ * Decode the header from an ASN.1 PER UNALIGNED encoded byte array
+ *
+ * @param bytes the bytes
+ * @return the dynamic header
+ */
+ public static DynamicFrame decode(byte[] bytes) {
+ return UperEncoder.decode(bytes, DynamicFrame.class);
+ }
+
+ /**
+ * Verify the level 2 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ */
+ public int validateLevel2() {
+
+
+ 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 {
+ key = KeyFactory.getInstance(keyAlgName).generatePublic(new X509EncodedKeySpec(this.getLevel2SignedData().getLevel1Data().level2publicKey.toByteArray()));
+ } catch (InvalidKeySpecException | NoSuchAlgorithmException e1) {
+ return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED;
+ }
+
+ //find the algorithm name for the signature OID
+ String algo = null;
+ try {
+ algo = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG,this.getLevel2SignedData().getLevel1Data().level2SigningAlg);
+ } catch (Exception e1) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ if (algo == null) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+
+ Signature sig;
+ try {
+ sig = Signature.getInstance(algo);
+ } 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 {
+ sig.update(UperEncoder.encode(level2SignedData));
+ } catch (SignatureException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ } catch (IllegalArgumentException e) {
+ return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
+ } catch (UnsupportedOperationException e) {
+ return Constants.LEVEL2_VALIDATION_ENCODING_ERROR;
+ }
+
+ byte[] signature = level2Signature.toByteArray();
+ try {
+ if (sig.verify(signature)){
+ return Constants.LEVEL2_VALIDATION_OK;
+ } else {
+ return Constants.LEVEL2_VALIDATION_FRAUD;
+ }
+ } catch (SignatureException e) {
+ return Constants.LEVEL2_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ }
+ }
+
+ /**
+ * Verify the level 1 signature
+ *
+ * Note: an appropriate security provider (e.g. BC) must be registered before
+ *
+ */
+ public int validateLevel1(PublicKey key) {
+
+ 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 {
+ 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;
+ }
+ }
+
+ 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);
+ this.level2Signature = new OctetString(sig.sign());
+
+ }
+
+
+}