From 3439ff611093d54368826b59515659f04c5788e3 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Mon, 22 Nov 2021 16:20:23 +0100 Subject: bug fixes on dynamic frame - ExtensionMarker removed - default on format removed - keyId starting from 0 --- pom.xml | 2 +- src/main/java/org/uic/barcode/dynamicFrame/DataType.java | 2 -- src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java | 6 +++--- src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 97460c1..5a4313c 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.uic.barcode org.uic.barcode - 1.2.7-SNAPSHOT + 1.2.8-SNAPSHOT jar UIC barcode encoding and decoding of bar code content according to UIC IRS 90918-9 diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/DataType.java index 2d6d984..2ea63ca 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/DataType.java @@ -1,6 +1,5 @@ package org.uic.barcode.dynamicFrame; -import org.uic.barcode.asn1.datatypes.Asn1Default; import org.uic.barcode.asn1.datatypes.CharacterRestriction; import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; @@ -20,7 +19,6 @@ public class DataType { * -- FCB2 FCB version 2 * -- RICS company code + ... **/ - @Asn1Default("FCB1") @RestrictedString(CharacterRestriction.IA5String) public String format; diff --git a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java index 6cc1eaa..c74215d 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/DynamicFrame.java @@ -14,7 +14,6 @@ import java.security.spec.X509EncodedKeySpec; import org.uic.barcode.asn1.datatypes.Asn1Optional; import org.uic.barcode.asn1.datatypes.CharacterRestriction; import org.uic.barcode.asn1.datatypes.FieldOrder; -import org.uic.barcode.asn1.datatypes.HasExtensionMarker; import org.uic.barcode.asn1.datatypes.RestrictedString; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.datatypesimpl.OctetString; @@ -29,7 +28,6 @@ import org.uic.barcode.utils.AlgorithmNameResolver; * Implementation of the Draft under discussion, not final. */ @Sequence -@HasExtensionMarker public class DynamicFrame extends Object{ public DynamicFrame() {} @@ -152,7 +150,9 @@ public class DynamicFrame extends Object{ byte[] keyBytes = this.getLevel2SignedData().getLevel1Data().level2publicKey.toByteArray(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); key = KeyFactory.getInstance(keyAlgName).generatePublic(keySpec); - } catch (InvalidKeySpecException | NoSuchAlgorithmException e1) { + } catch (InvalidKeySpecException e1) { + return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED; + } catch (NoSuchAlgorithmException e1) { return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED; } diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java b/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java index aac0188..958cafc 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/Level1DataType.java @@ -34,7 +34,7 @@ public class Level1DataType { /** The key id. */ @FieldOrder(order = 2) - @IntRange(minValue=1,maxValue=99999) + @IntRange(minValue=0,maxValue=99999) @Asn1Optional public Long keyId; -- cgit v1.2.3 From ecdc5505218d71ba365ff729f11a1b504a71c986 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 09:59:31 +0100 Subject: added fcb version 3 data type to the DOSIPAS encoding and decoding --- src/main/java/org/uic/barcode/Decoder.java | 2 + src/main/java/org/uic/barcode/Encoder.java | 8 +- .../org/uic/barcode/dynamicFrame/Constants.java | 1 + .../ticket/api/spec/uicBarcodeHeader0.1.asn | 151 --------------------- 4 files changed, 10 insertions(+), 152 deletions(-) delete mode 100644 src/main/java/org/uic/barcode/ticket/api/spec/uicBarcodeHeader0.1.asn diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java index 09ee839..9f102d3 100644 --- a/src/main/java/org/uic/barcode/Decoder.java +++ b/src/main/java/org/uic/barcode/Decoder.java @@ -172,6 +172,8 @@ public class Decoder { uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 1); } else if (level1Content.getFormat().equals("FCB2")) { uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 2); + } else if (level1Content.getFormat().equals("FCB3")) { + uicTicket = uicTicketCoder.decodeFromAsn(level1Content.getByteData(), 3); } } diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java index e906881..9463548 100644 --- a/src/main/java/org/uic/barcode/Encoder.java +++ b/src/main/java/org/uic/barcode/Encoder.java @@ -100,7 +100,13 @@ public class Encoder { DataType ticketData = new DataType(); UicRailTicketCoder uicTicketCoder = new UicRailTicketCoder(); - ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_1); + if (fcbVersion == 1) { + ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_1); + } else if (fcbVersion == 2) { + ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_2); + } else if (fcbVersion == 3) { + ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_3); + } ticketData.setData(new OctetString(uicTicketCoder.encode(ticket, fcbVersion))); dynamicFrame.getLevel2SignedData().getLevel1Data().getData().add(ticketData); diff --git a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java index 774475a..8f47986 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/Constants.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/Constants.java @@ -16,6 +16,7 @@ public class Constants { public static String DATA_TYPE_FCB_VERSION_1 = "FCB1"; public static String DATA_TYPE_FCB_VERSION_2 = "FCB2"; + public static String DATA_TYPE_FCB_VERSION_3 = "FCB3"; public static String DYNAMIC_BARCODE_FORMAT_DEFAULT = "U1"; diff --git a/src/main/java/org/uic/barcode/ticket/api/spec/uicBarcodeHeader0.1.asn b/src/main/java/org/uic/barcode/ticket/api/spec/uicBarcodeHeader0.1.asn deleted file mode 100644 index 2999d18..0000000 --- a/src/main/java/org/uic/barcode/ticket/api/spec/uicBarcodeHeader0.1.asn +++ /dev/null @@ -1,151 +0,0 @@ --- Creator: ASN.1 Editor (http://asneditor.sourceforge.net) --- Author: ClemensGantert --- Created: Tue Aug 11 11:40:28 CEST 2015 -ASN-Module DEFINITIONS AUTOMATIC TAGS ::= BEGIN - --- imports and exports --- EXPORTS ALL; - - --- ############################################################################################## --- # --- # UIC barcode header - first draft --- # --- ############################################################################################## - - --- ############################################################################################## --- # --- # Naming and encoding conventions --- # --- # Elements included as String and as Numeric values: --- # Some elements are included in different formats to reduce the data size. --- # These elements must be included only once. --- # These elements are named with the same name and appendix --- # Num (numeric values) --- # IA5 (String values according to ASN IA5String (7Bit)) --- # --- # RICS codes must be used to encode companies (issuer, product owner, ...) where available --- # other codes are possible based on bilateral agreements --- # the format is kept more flexible to cover upcoming extensions of the RICS code by ERA --- # --- # Stations can be coded using the UIC and upcoming ERA code lists. Proprietary codes are --- # possible based on bilateral agreements. Format: 1..9999999 or alphanumeric without --- # special character (IA5String) --- # --- # --- # ! INTEGERS must not exceed the value of 9,223,372,036,854,775,807 (64 bit) even in case --- # ! they are unrestricted!!! --- # ! --- # ! Some elements like ReferenceNum or cardIdNum are defined as an unrestricted integer. --- # ! Unlike other numerical values the cardIdNum and referenceNum can be larger than a usual 32 bit Integer --- # ! Some ASN.1 implementation tools are limited to 32 bit integers which is too small. --- # ! Please ensure to use a tool capable of dealing with larger numbers. --- # --- # BOOLEAN is always non optional --- # --- # Encoding of time: --- # time is encoded as the number of minutes of the day 0 = 00:00, 1440 = 24:00, --- # time data elements end with "time" in their name --- # --- # Encoding of date: --- # ......................................................................................................... --- # The issuing date is given in UTC, but some other date values are given in local time where the exact time zone is not known. --- # --- # --- # --- # ASN.1 Extensions: --- # --- # The specification makes use of extension (",..."). --- # These extesions might be defined in future versions of the UIC specification --- # Implementations must support the extension feature of ASN.1, at least they must be able to ignore extensions while decoding the data --- # ASN.1 extensions will be defined by UIC. It is not allowed to define bilateral extensions. --- # --- # Bilateral Extensions: --- # Bilateral extensions can be included in the data element "ExtensionData". --- # --- # --- # --- ######################################################################################### - - --- ############################################################################################ - - --- type assignments - - -- ######################################################################################### - -- the basic entry point of the data structure - -- the data include: - -- -issuer informations - -- -the details of the transport document - -- -informations required for the control process - -- -informations on the travelers independent from the transport document - -- -proprietary extensions - -- - -- ########################################################################################## - UicBarcodeHeader ::= SEQUENCE { - -- format type - format IA5String, - -- "UIC" = UIC ticket - - version Integer (1..16), - - -- provider of the signature (RICS code) - securityProviderNum INTEGER (1..32000) OPTIONAL, - securityProviderIA5 IA5String OPTIONAL, - - - staticData SEQUENCE OF DataType, - staticSignature SignatureType OPTIONAL, - - - - -- additional dynamic data i.e. phone number, IMEI, timestamp , .... --> To be defined separately - dynamicDataFormat IA5String OPTIONAL, - dynamicData OCTET STRING OPTIONAL, - dynamicPublicKey OCTET STRING OPTIONAL, - dynamicSignature SignatureType OPTIONAL - - -- proprietary data defined bilaterally - extension SEQUENCE OF ExtensionData OPTIONAL - ,... - - } - - DataType ::= SEQUENCE { - staticDataFormat IA5String DEFAULT "FCB1", - -- FCB1 FCB version 1 - -- 1080XYZ - staticData OCTET STRING - } - - - - SignatureType ::= SEQUENCE { - signingAlg IA5String, - keyId IA5String (SIZE(1..5)), - signature OCTET STRING, - } - - - - -- ########################################################################################### - -- generic non standard extension element - -- the generic non - standard element contains: - -- - an extension id to distinguish different extensions - -- - the extension data as binary data - -- proprietary extensions are by definition proprietary. This standard provides - -- the means to identify these extensions - -- within the data and to skip these data. - -- the evaluation of these data and the unique identification of the extensions - -- via the extension id is in the - -- responsibility of the railways which use these extensions. - -- ########################################################################################### - ExtensionData ::= SEQUENCE { - extensionId IA5String, - extensionData OCTET STRING - } - - -END \ No newline at end of file -- cgit v1.2.3 From cd76118fb6737eb241cab60207262617e12d237d Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:16:40 +0100 Subject: test added --- src/main/java/org/uic/barcode/Encoder.java | 2 +- .../org/uic/barcode/test/DynamicFrameFCB3Test.java | 175 +++++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java diff --git a/src/main/java/org/uic/barcode/Encoder.java b/src/main/java/org/uic/barcode/Encoder.java index 9463548..f0f8d14 100644 --- a/src/main/java/org/uic/barcode/Encoder.java +++ b/src/main/java/org/uic/barcode/Encoder.java @@ -100,7 +100,7 @@ public class Encoder { DataType ticketData = new DataType(); UicRailTicketCoder uicTicketCoder = new UicRailTicketCoder(); - if (fcbVersion == 1) { + if (fcbVersion == 1 || fcbVersion == 13) { ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_1); } else if (fcbVersion == 2) { ticketData.setFormat(Constants.DATA_TYPE_FCB_VERSION_2); diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java new file mode 100644 index 0000000..2ac7353 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java @@ -0,0 +1,175 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameFCB3Test { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPair = null; + + public IUicRailTicket testFCBticket = null; + + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPair = generateECKeys(Constants.KG_EC, elipticCurve); + //keyPair = generateECDSAKeys("ECDSA", "B-571"); + } catch (Exception e) { + assert(false); + } + + assert(keyPair != null); + + } + + + @Test public void testDynamicHeaderBarcodeEncodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + + + } + + @Test public void testDynamicHeaderBarcodeDecodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + assert(dec.getDynamicHeader().getFormat().equals("U1")); + + assert(dec.getDynamicHeader().getDynamicDataFDC1().getDataType().getFormat().equals("FCB3")); + + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + + + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} -- cgit v1.2.3 From 47133b358a65723b1b131f66d2e340a12685f9e6 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:23:55 +0100 Subject: renamed --- .../org/uic/barcode/test/DynamicFrameFCB3Test.java | 175 --------------------- .../org/uic/barcode/test/DynamicFrameFcb3Test.java | 175 +++++++++++++++++++++ 2 files changed, 175 insertions(+), 175 deletions(-) delete mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java deleted file mode 100644 index 2ac7353..0000000 --- a/src/test/java/org/uic/barcode/test/DynamicFrameFCB3Test.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.uic.barcode.test; - -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SecureRandom; -import java.security.Security; -import java.security.SignatureException; -import java.util.zip.DataFormatException; - -import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.junit.Before; -import org.junit.Test; -import org.uic.barcode.Decoder; -import org.uic.barcode.Encoder; -import org.uic.barcode.dynamicFrame.Constants; -import org.uic.barcode.test.utils.SimpleUICTestTicket; -import org.uic.barcode.ticket.EncodingFormatException; -import org.uic.barcode.ticket.api.spec.IUicRailTicket; - -public class DynamicFrameFCB3Test { - - public String signatureAlgorithmOID = null; - public String elipticCurve = null; - public String keyPairAlgorithmOID = null; - - public KeyPair keyPair = null; - - public IUicRailTicket testFCBticket = null; - - - @Before public void initialize() { - - signatureAlgorithmOID = Constants.ECDSA_SHA256; - keyPairAlgorithmOID = Constants.KG_EC_256; - elipticCurve = "secp256k1"; - - testFCBticket = SimpleUICTestTicket.getUicTestTicket(); - - Security.addProvider(new BouncyCastleProvider()); - - try { - keyPair = generateECKeys(Constants.KG_EC, elipticCurve); - //keyPair = generateECDSAKeys("ECDSA", "B-571"); - } catch (Exception e) { - assert(false); - } - - assert(keyPair != null); - - } - - - @Test public void testDynamicHeaderBarcodeEncodingFCB3() { - - IUicRailTicket ticket = testFCBticket; - - Encoder enc = null; - - try { - enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); - } catch (IOException | EncodingFormatException e1) { - assert(false); - } - - assert(enc != null); - - try { - enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); - } catch (Exception e) { - assert(false); - } - - - byte[] encoded = null; - try { - encoded = enc.encode(); - } catch (Exception e) { - assert(false); - } - - assert(encoded != null); - - - - } - - @Test public void testDynamicHeaderBarcodeDecodingFCB3() { - - IUicRailTicket ticket = testFCBticket; - - Encoder enc = null; - - try { - enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); - } catch (IOException | EncodingFormatException e1) { - assert(false); - } - - assert(enc != null); - - try { - enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); - } catch (Exception e) { - assert(false); - } - - - byte[] encoded = null; - try { - encoded = enc.encode(); - } catch (Exception e) { - assert(false); - } - - assert(encoded != null); - - Decoder dec = null; - try { - dec = new Decoder(encoded); - } catch (IOException e) { - assert(false); - } catch (EncodingFormatException e) { - assert(false); - } catch (DataFormatException e) { - assert(false); - } - assert(dec != null); - - int signatureCheck = 0; - try { - signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); - } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException - | UnsupportedOperationException | IOException | EncodingFormatException e) { - assert(false); - } - - assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - - assert(dec.getDynamicHeader().getFormat().equals("U1")); - - assert(dec.getDynamicHeader().getDynamicDataFDC1().getDataType().getFormat().equals("FCB3")); - - - SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); - - - - - } - - public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ - ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); - KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); - g.initialize(ecSpec, new SecureRandom()); - return g.generateKeyPair(); - } - - public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ - - String keyAlgorithmName = "ECDSA"; - ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); - KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); - g.initialize(ecSpec, new SecureRandom()); - return g.generateKeyPair(); - } - - -} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java new file mode 100644 index 0000000..cb252a2 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java @@ -0,0 +1,175 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameFcb3Test { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPair = null; + + public IUicRailTicket testFCBticket = null; + + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPair = generateECKeys(Constants.KG_EC, elipticCurve); + //keyPair = generateECDSAKeys("ECDSA", "B-571"); + } catch (Exception e) { + assert(false); + } + + assert(keyPair != null); + + } + + + @Test public void testDynamicHeaderBarcodeEncodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + + + } + + @Test public void testDynamicHeaderBarcodeDecodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + assert(dec.getDynamicHeader().getFormat().equals("U1")); + + assert(dec.getDynamicHeader().getDynamicDataFDC1().getDataType().getFormat().equals("FCB3")); + + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + + + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} -- cgit v1.2.3 From 900acb165c53e9801112c3f1b8f57ff4d9ad531d Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 13:28:56 +0100 Subject: additional tests for DOSIPAS --- .../org/uic/barcode/ticket/UicRailTicketCoder.java | 2 +- .../test/DynamicFrameDynamicContentTest.java | 208 +++++++++++++++++++++ .../org/uic/barcode/test/DynamicFrameFcb3Test.java | 175 ----------------- .../barcode/test/DynamicFrameFcbVersion1Test.java | 174 +++++++++++++++++ .../barcode/test/DynamicFrameFcbVersion3Test.java | 174 +++++++++++++++++ 5 files changed, 557 insertions(+), 176 deletions(-) create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java delete mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java diff --git a/src/main/java/org/uic/barcode/ticket/UicRailTicketCoder.java b/src/main/java/org/uic/barcode/ticket/UicRailTicketCoder.java index e9d2eb4..0586ed4 100644 --- a/src/main/java/org/uic/barcode/ticket/UicRailTicketCoder.java +++ b/src/main/java/org/uic/barcode/ticket/UicRailTicketCoder.java @@ -33,7 +33,7 @@ public class UicRailTicketCoder { public byte[] encode (IUicRailTicket uicRailTicket, int version) throws IOException, EncodingFormatException{ - if (version == 13) { + if (version == 13 || version == 1) { Api2OpenAsnEncoder uicEncoder = new Api2OpenAsnEncoder(); diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java new file mode 100644 index 0000000..93ecdfb --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java @@ -0,0 +1,208 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameDynamicContentTest { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPairLevel1 = null; + public KeyPair keyPairLevel2 = null; + + public IUicRailTicket testFCBticket = null; + + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPairLevel1 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + keyPairLevel2 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + } catch (Exception e) { + assert(false); + } + + assert(keyPairLevel1 != null); + + assert(keyPairLevel2 != null); + + } + + + @Test public void testDynamicContentEncoding() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 13); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID, keyPairLevel2.getPublic()); + + try { + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + try { + UicDynamicContentDataFDC1 dcd = new UicDynamicContentDataFDC1(); + dcd.setChallengeString("CHALLENGE"); + dcd.setAppId("MyApp"); + enc.setDynamicContentDataUIC1(dcd); + enc.signLevel2(keyPairLevel2.getPrivate()); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + + + } + + @Test public void testDynamicContentDecoding() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 13); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID, keyPairLevel2.getPublic()); + + try { + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + try { + UicDynamicContentDataFDC1 dcd = new UicDynamicContentDataFDC1(); + dcd.setChallengeString("CHALLENGE"); + dcd.setAppId("MyApp"); + enc.setDynamicContentDataUIC1(dcd); + enc.signLevel2(keyPairLevel2.getPrivate()); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + int level2check = 0; + try { + level2check = dec.validateLevel2(); + } catch (Exception e) { + assert(false); + } + + assert(level2check == Constants.LEVEL2_VALIDATION_OK); + + assert(dec.getDynamicHeader().getDynamicDataFDC1().getChallengeString().equals("CHALLENGE")); + + assert(dec.getDynamicHeader().getDynamicDataFDC1().getAppId().equals("MyApp")); + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java deleted file mode 100644 index cb252a2..0000000 --- a/src/test/java/org/uic/barcode/test/DynamicFrameFcb3Test.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.uic.barcode.test; - -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SecureRandom; -import java.security.Security; -import java.security.SignatureException; -import java.util.zip.DataFormatException; - -import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.junit.Before; -import org.junit.Test; -import org.uic.barcode.Decoder; -import org.uic.barcode.Encoder; -import org.uic.barcode.dynamicFrame.Constants; -import org.uic.barcode.test.utils.SimpleUICTestTicket; -import org.uic.barcode.ticket.EncodingFormatException; -import org.uic.barcode.ticket.api.spec.IUicRailTicket; - -public class DynamicFrameFcb3Test { - - public String signatureAlgorithmOID = null; - public String elipticCurve = null; - public String keyPairAlgorithmOID = null; - - public KeyPair keyPair = null; - - public IUicRailTicket testFCBticket = null; - - - @Before public void initialize() { - - signatureAlgorithmOID = Constants.ECDSA_SHA256; - keyPairAlgorithmOID = Constants.KG_EC_256; - elipticCurve = "secp256k1"; - - testFCBticket = SimpleUICTestTicket.getUicTestTicket(); - - Security.addProvider(new BouncyCastleProvider()); - - try { - keyPair = generateECKeys(Constants.KG_EC, elipticCurve); - //keyPair = generateECDSAKeys("ECDSA", "B-571"); - } catch (Exception e) { - assert(false); - } - - assert(keyPair != null); - - } - - - @Test public void testDynamicHeaderBarcodeEncodingFCB3() { - - IUicRailTicket ticket = testFCBticket; - - Encoder enc = null; - - try { - enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); - } catch (IOException | EncodingFormatException e1) { - assert(false); - } - - assert(enc != null); - - try { - enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); - } catch (Exception e) { - assert(false); - } - - - byte[] encoded = null; - try { - encoded = enc.encode(); - } catch (Exception e) { - assert(false); - } - - assert(encoded != null); - - - - } - - @Test public void testDynamicHeaderBarcodeDecodingFCB3() { - - IUicRailTicket ticket = testFCBticket; - - Encoder enc = null; - - try { - enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); - } catch (IOException | EncodingFormatException e1) { - assert(false); - } - - assert(enc != null); - - try { - enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); - } catch (Exception e) { - assert(false); - } - - - byte[] encoded = null; - try { - encoded = enc.encode(); - } catch (Exception e) { - assert(false); - } - - assert(encoded != null); - - Decoder dec = null; - try { - dec = new Decoder(encoded); - } catch (IOException e) { - assert(false); - } catch (EncodingFormatException e) { - assert(false); - } catch (DataFormatException e) { - assert(false); - } - assert(dec != null); - - int signatureCheck = 0; - try { - signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); - } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException - | UnsupportedOperationException | IOException | EncodingFormatException e) { - assert(false); - } - - assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); - - assert(dec.getDynamicHeader().getFormat().equals("U1")); - - assert(dec.getDynamicHeader().getDynamicDataFDC1().getDataType().getFormat().equals("FCB3")); - - - SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); - - - - - } - - public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ - ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); - KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); - g.initialize(ecSpec, new SecureRandom()); - return g.generateKeyPair(); - } - - public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ - - String keyAlgorithmName = "ECDSA"; - ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); - KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); - g.initialize(ecSpec, new SecureRandom()); - return g.generateKeyPair(); - } - - -} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java new file mode 100644 index 0000000..63ba68e --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion1Test.java @@ -0,0 +1,174 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameFcbVersion1Test { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPair = null; + + public IUicRailTicket testFCBticket = null; + + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPair = generateECKeys(Constants.KG_EC, elipticCurve); + //keyPair = generateECDSAKeys("ECDSA", "B-571"); + } catch (Exception e) { + assert(false); + } + + assert(keyPair != null); + + } + + + @Test public void testDynamicHeaderBarcodeEncodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 1); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + + } + + @Test public void testDynamicHeaderBarcodeDecodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 1); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + assert(dec.getDynamicHeader().getFormat().equals("U1")); + + assert(dec.getDynamicHeader().getLevel2SignedData().getLevel1Data().getData().get(0).getFormat().equals("FCB1")); + + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + + + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java new file mode 100644 index 0000000..4f0897e --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameFcbVersion3Test.java @@ -0,0 +1,174 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameFcbVersion3Test { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPair = null; + + public IUicRailTicket testFCBticket = null; + + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPair = generateECKeys(Constants.KG_EC, elipticCurve); + //keyPair = generateECDSAKeys("ECDSA", "B-571"); + } catch (Exception e) { + assert(false); + } + + assert(keyPair != null); + + } + + + @Test public void testDynamicHeaderBarcodeEncodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + + } + + @Test public void testDynamicHeaderBarcodeDecodingFCB3() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPair.getPublic(),null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + assert(dec.getDynamicHeader().getFormat().equals("U1")); + + assert(dec.getDynamicHeader().getLevel2SignedData().getLevel1Data().getData().get(0).getFormat().equals("FCB3")); + + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + + + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} -- cgit v1.2.3 From 12ca8d77e0a0d63ce03886d38c079c686122253a Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 15:39:05 +0100 Subject: dynamic content time stamp fixed and test added --- pom.xml | 4 +- .../uic/barcode/dynamicContent/fdc1/TimeStamp.java | 63 ++++++++++------------ .../fdc1/UicDynamicContentDataFDC1.java | 4 +- .../test/DynamicFrameDynamicContentTest.java | 38 ++++++++++++- 4 files changed, 69 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index 5a4313c..f82b70b 100644 --- a/pom.xml +++ b/pom.xml @@ -23,8 +23,8 @@ maven-compiler-plugin 2.3.2 - ${jdk.version} - ${jdk.version} + 1.8 + 1.8 diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java index 32cce65..ecbb226 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/TimeStamp.java @@ -1,16 +1,17 @@ package org.uic.barcode.dynamicContent.fdc1; import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.time.temporal.ChronoField; -import java.util.Calendar; import java.util.Date; -import java.util.TimeZone; import org.uic.barcode.asn1.datatypes.FieldOrder; import org.uic.barcode.asn1.datatypes.IntRange; import org.uic.barcode.asn1.datatypes.Sequence; -// TODO: Auto-generated Javadoc + /** * The Class TimeStamp. */ @@ -20,16 +21,10 @@ public class TimeStamp { /* -- Moment of generation of the dynamic content, expressed in UTC : - -- * dynamicContentDay is the number of days from issuing date - -- (UicRailTicketData.issuingDetail.issuingYear and issuingDay) - -- The range 0..1070 allows a validity equal to that of the validFrom (700) plus - -- validUntil (370) elements of the different transport documents of UicRailTicketData. + -- * dynamicContentDay is the number of day in the year -- * dynamicContentTime is the number of seconds of the day -- (from 0 = 0:00:00 to 86399 = 23:59:59) - -- These two elements shall be either both present, either both absent - dynamicContentDay INTEGER (0..366), - * - */ + */ @FieldOrder(order = 0) @IntRange(minValue=1, maxValue=366) public Long day; @@ -46,7 +41,7 @@ public class TimeStamp { * Instantiates a new time stamp and sets the time-stamp to now. */ public TimeStamp() { - Instant now = Instant.now(); + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); day = new Long(now.get(ChronoField.DAY_OF_YEAR)); secondOfDay = new Long(now.get(ChronoField.SECOND_OF_DAY)); } @@ -55,7 +50,7 @@ public class TimeStamp { * Sets the the time-stamp to now. */ public void setNow() { - Instant now = Instant.now(); + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); day = new Long(now.get(ChronoField.DAY_OF_YEAR)); secondOfDay = new Long(now.get(ChronoField.SECOND_OF_DAY)); } @@ -102,25 +97,26 @@ public class TimeStamp { * @return the date and time of content creation in UTC */ public Date getTimeAsDate() { - - Calendar cal = Calendar.getInstance(); - int dayOfYear = cal.get(Calendar.DAY_OF_YEAR); - + + ZonedDateTime now = Instant.now().atZone(ZoneOffset.UTC); + int dayOfYear = now.getDayOfYear(); + if (dayOfYear - day.intValue() > 250) { - cal.add(Calendar.YEAR, 1); + now = now.plusDays(1); } if (day.intValue() - dayOfYear > 250) { - cal.add(Calendar.YEAR, -1); + now = now.minusDays(1); } - - cal.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.set(Calendar.SECOND,0); - cal.set(Calendar.HOUR,0); - cal.set(Calendar.MINUTE,0); - cal.set(Calendar.DAY_OF_YEAR, day.intValue()); - cal.add(Calendar.SECOND, secondOfDay.intValue()); + + now = now.withDayOfYear(1); + now = now.withSecond(0); + now = now.withHour(0); + now = now.withMinute(0); + now = now.withDayOfYear(dayOfYear); + now = now.plusSeconds(secondOfDay); - return cal.getTime(); + return Date.from(now.toInstant()); + } /** @@ -129,15 +125,14 @@ public class TimeStamp { * @param dateUTC the current date and time in UTC */ public void setDateTime(Date dateUTC) { - - Calendar cal = Calendar.getInstance(); - cal.setTime(dateUTC); - day = Long.valueOf(cal.get(Calendar.DAY_OF_YEAR)); + ZonedDateTime date = dateUTC.toInstant().atZone(ZoneOffset.UTC); + + day = (long) date.getDayOfYear(); - secondOfDay = (long) cal.get(Calendar.SECOND); - secondOfDay = secondOfDay + 60 * (long) cal.get(Calendar.MINUTE); - secondOfDay = secondOfDay + 60 * 60 * (long) cal.get(Calendar.HOUR_OF_DAY); + secondOfDay = (long) date.getSecond(); + secondOfDay = secondOfDay + 60 * (long) date.getMinute(); + secondOfDay = secondOfDay + 60 * 60 * (long) date.getHour(); } diff --git a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java index ae352d1..c658448 100644 --- a/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java +++ b/src/main/java/org/uic/barcode/dynamicContent/fdc1/UicDynamicContentDataFDC1.java @@ -161,13 +161,13 @@ public class UicDynamicContentDataFDC1 { return null; } - public void setPassIdHash(byte[] phoneIdHash) { + public void setPassIdHash(byte[] passIdHash) { if (extensions == null) { extensions = new SequenceOfExtension(); }; ExtensionData ed = new ExtensionData(); ed.setExtensionId("pass"); - ed.setExtensionData(phoneIdHash); + ed.setExtensionData(passIdHash); extensions.add(ed); } diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java index 93ecdfb..53b6af8 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java @@ -10,6 +10,11 @@ import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.security.SignatureException; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Date; import java.util.zip.DataFormatException; import org.bouncycastle.jce.ECNamedCurveTable; @@ -19,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.uic.barcode.Decoder; import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicContent.fdc1.TimeStamp; import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; import org.uic.barcode.dynamicFrame.Constants; import org.uic.barcode.test.utils.SimpleUICTestTicket; @@ -34,6 +40,11 @@ public class DynamicFrameDynamicContentTest { public KeyPair keyPairLevel1 = null; public KeyPair keyPairLevel2 = null; + public byte[] passIdHash = "PassId".getBytes(); + public byte[] phoneIdHash = "myPhone".getBytes(); + + ZonedDateTime originalTimeStamp = ZonedDateTime.now(ZoneId.of("UTC")); + public IUicRailTicket testFCBticket = null; @@ -87,6 +98,12 @@ public class DynamicFrameDynamicContentTest { UicDynamicContentDataFDC1 dcd = new UicDynamicContentDataFDC1(); dcd.setChallengeString("CHALLENGE"); dcd.setAppId("MyApp"); + dcd.setPhoneIdHash(phoneIdHash); + dcd.setPassIdHash(passIdHash); + TimeStamp ts = new TimeStamp(); + ts.setDateTime(Date.from(originalTimeStamp.toInstant())); + dcd.setTimeStamp(ts); + enc.setDynamicContentDataUIC1(dcd); enc.signLevel2(keyPairLevel2.getPrivate()); } catch (Exception e) { @@ -133,6 +150,12 @@ public class DynamicFrameDynamicContentTest { UicDynamicContentDataFDC1 dcd = new UicDynamicContentDataFDC1(); dcd.setChallengeString("CHALLENGE"); dcd.setAppId("MyApp"); + dcd.setPhoneIdHash(phoneIdHash); + dcd.setPassIdHash(passIdHash); + TimeStamp ts = new TimeStamp(); + ts.setDateTime(Date.from(originalTimeStamp.toInstant())); + dcd.setTimeStamp(ts); + enc.setDynamicContentDataUIC1(dcd); enc.signLevel2(keyPairLevel2.getPrivate()); } catch (Exception e) { @@ -182,10 +205,21 @@ public class DynamicFrameDynamicContentTest { assert(level2check == Constants.LEVEL2_VALIDATION_OK); - assert(dec.getDynamicHeader().getDynamicDataFDC1().getChallengeString().equals("CHALLENGE")); + UicDynamicContentDataFDC1 dynamicData = dec.getDynamicHeader().getDynamicDataFDC1(); + + assert(dynamicData.getChallengeString().equals("CHALLENGE")); + + assert(dynamicData.getAppId().equals("MyApp")); + + assert(Arrays.equals(dynamicData.getPassIdHash(),passIdHash)); - assert(dec.getDynamicHeader().getDynamicDataFDC1().getAppId().equals("MyApp")); + assert(Arrays.equals(dynamicData.getPhoneIdHash(),phoneIdHash)); + Date timeStamp = dynamicData.getTimeStamp().getTimeAsDate(); + ZonedDateTime retrievedTimeStamp = timeStamp.toInstant().atZone(ZoneId.of("UTC")); + long diff = ChronoUnit.SECONDS.between(originalTimeStamp, retrievedTimeStamp); + + assert(diff == 0); } public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ -- cgit v1.2.3 From b51f825080e3535b259c673af7053ad43fc1e674 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 23 Nov 2021 16:44:15 +0100 Subject: unused code removed test on security with designated provider --- .../org/uic/barcode/asn1/uper/UperEncoder.java | 11 -- ...cFrameDoubleSignatureProviderSelectionTest.java | 169 +++++++++++++++++++++ 2 files changed, 169 insertions(+), 11 deletions(-) create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureProviderSelectionTest.java diff --git a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java index a5ef5c5..5956054 100644 --- a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java +++ b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java @@ -691,17 +691,6 @@ public final class UperEncoder { return sb.toString(); } - public static byte[] bytesFromBinaryString(String s) { - int len = s.length(); - byte[] result = new byte[(len + Byte.SIZE - 1) / Byte.SIZE]; - char c; - for (int i = 0; i < len; i++) - if ((c = s.charAt(i)) == '1') result[i / Byte.SIZE] = (byte) (result[i / Byte.SIZE] | (0x80 >>> (i % Byte.SIZE))); - else if (c != '0') - throw new IllegalArgumentException(); - return result; - } - private static BitBuffer bitBufferFromBinaryString(String s) { ByteBitBuffer result = ByteBitBuffer.allocate(s.length()); for (int i = 0; i < s.length(); i++) { diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureProviderSelectionTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureProviderSelectionTest.java new file mode 100644 index 0000000..84f7795 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureProviderSelectionTest.java @@ -0,0 +1,169 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.Arrays; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.dynamicFrame.DataType; +import org.uic.barcode.test.utils.Level2TestDataFactory; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +public class DynamicFrameDoubleSignatureProviderSelectionTest { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPairLevel1 = null; + public KeyPair keyPairLevel2 = null; + + public IUicRailTicket testFCBticket = null; + + public Provider prov = null; + + @Before public void initialize() { + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + prov = new BouncyCastleProvider(); + + Security.addProvider(prov); + + try { + keyPairLevel1 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + keyPairLevel2 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + } catch (Exception e) { + assert(false); + } + + assert(keyPairLevel1 != null); + + assert(keyPairLevel2 != null); + + } + + + + @Test public void testDynamicHeaderBarcodeDecoding() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 13); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.setLevel1Algs(signatureAlgorithmOID, keyPairAlgorithmOID); + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID,keyPairLevel2.getPublic()); + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1",prov); + } catch (Exception e) { + assert(false); + } + + assert(enc != null); + + + DataType level2Data = Level2TestDataFactory.getLevel2SimpleTestData(); + try { + enc.setLevel2Data(level2Data); + enc.signLevel2(keyPairLevel2.getPrivate(),prov); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(), null, prov); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + signatureCheck = 0; + try { + signatureCheck = dec.validateLevel2(prov); + } catch (IllegalArgumentException | UnsupportedOperationException e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL2_VALIDATION_OK); + + DataType level2DataDec = dec.getLevel2Data(); + + assert(level2Data.getFormat().equals(level2DataDec.getFormat())); + assert(Arrays.equals(level2Data.getData().toByteArray(),level2DataDec.getData().toByteArray())); + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + } + + public KeyPair generateECDSAKeys(String keyAlgorithmName, String paramName) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(paramName); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + String keyAlgorithmName = "ECDSA"; + ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curve); + KeyPairGenerator g = KeyPairGenerator.getInstance(keyAlgorithmName, "BC"); + g.initialize(ecSpec, new SecureRandom()); + return g.generateKeyPair(); + } + + +} -- cgit v1.2.3 From 2949fbd789fc3c35d340d17cb96e26a7a2ef7d02 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Wed, 24 Nov 2021 11:54:10 +0100 Subject: extended tests --- .../test/DynamicFrameDynamicContentTest.java | 16 ++ .../barcode/test/StaticFrameBarcodeTestFCB3.java | 193 +++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/test/java/org/uic/barcode/test/StaticFrameBarcodeTestFCB3.java diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java index 53b6af8..f3e4f54 100644 --- a/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDynamicContentTest.java @@ -24,6 +24,8 @@ import org.junit.Before; import org.junit.Test; import org.uic.barcode.Decoder; import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicContent.fdc1.GeoCoordinateSystemType; +import org.uic.barcode.dynamicContent.fdc1.GeoCoordinateType; import org.uic.barcode.dynamicContent.fdc1.TimeStamp; import org.uic.barcode.dynamicContent.fdc1.UicDynamicContentDataFDC1; import org.uic.barcode.dynamicFrame.Constants; @@ -104,6 +106,11 @@ public class DynamicFrameDynamicContentTest { ts.setDateTime(Date.from(originalTimeStamp.toInstant())); dcd.setTimeStamp(ts); + GeoCoordinateType geo = new GeoCoordinateType(); + geo.setLatitude(123456L); + geo.setLongitude(823456L); + dcd.setGeoCoordinate(geo); + enc.setDynamicContentDataUIC1(dcd); enc.signLevel2(keyPairLevel2.getPrivate()); } catch (Exception e) { @@ -152,6 +159,12 @@ public class DynamicFrameDynamicContentTest { dcd.setAppId("MyApp"); dcd.setPhoneIdHash(phoneIdHash); dcd.setPassIdHash(passIdHash); + + GeoCoordinateType geo = new GeoCoordinateType(); + geo.setLatitude(123456L); + geo.setLongitude(823456L); + dcd.setGeoCoordinate(geo); + TimeStamp ts = new TimeStamp(); ts.setDateTime(Date.from(originalTimeStamp.toInstant())); dcd.setTimeStamp(ts); @@ -215,6 +228,9 @@ public class DynamicFrameDynamicContentTest { assert(Arrays.equals(dynamicData.getPhoneIdHash(),phoneIdHash)); + assert(dynamicData.getGeoCoordinate().getLatitude() == 123456L); + assert(dynamicData.getGeoCoordinate().getLongitude() == 823456L); + Date timeStamp = dynamicData.getTimeStamp().getTimeAsDate(); ZonedDateTime retrievedTimeStamp = timeStamp.toInstant().atZone(ZoneId.of("UTC")); long diff = ChronoUnit.SECONDS.between(originalTimeStamp, retrievedTimeStamp); diff --git a/src/test/java/org/uic/barcode/test/StaticFrameBarcodeTestFCB3.java b/src/test/java/org/uic/barcode/test/StaticFrameBarcodeTestFCB3.java new file mode 100644 index 0000000..41ce365 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/StaticFrameBarcodeTestFCB3.java @@ -0,0 +1,193 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.util.zip.DataFormatException; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.Decoder; +import org.uic.barcode.Encoder; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.staticFrame.ticketLayoutBarcode.TicketLayout; +import org.uic.barcode.test.utils.SimpleTestTicketLayout; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; + +/** + * The Class StaticFrameBarcodeTest. + */ +public class StaticFrameBarcodeTestFCB3 { + + /** The algorithm OID. */ + public String algorithmOID = Constants.DSA_SHA224; + + public int keySize = 2048; + + /** The key pair. */ + public KeyPair keyPair = null; + + + public IUicRailTicket testFCBticket = null; + + public TicketLayout testLayout = null; + + + /** + * Initialize. + * + * set the signature algorithm + * generate a key pair + * set the test content + * for ticket and layout + */ + @Before public void initialize() { + + algorithmOID = Constants.DSA_SHA224; + keySize = 2048; + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + testLayout = SimpleTestTicketLayout.getSimpleTestTicketLayout(); + + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPair = generateDSAKeys(keySize); + } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + + assert(keyPair != null); + + } + + + /** + * Test dynamic header barcode encoding. + */ + @Test public void testStaticHeaderBarcodeEncoding() { + + IUicRailTicket ticket = testFCBticket; + + TicketLayout layout = testLayout; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, layout, Encoder.UIC_BARCODE_TYPE_CLASSIC, 2, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + enc.setStaticHeaderParams("123456789012", "de"); + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), algorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + } + + /** + * Test dynamic header barcode decoding. + */ + @Test public void testStaticHeaderBarcodeDecoding() { + + + IUicRailTicket ticket = testFCBticket; + + TicketLayout layout = testLayout; + + + Encoder enc = null; + + try { + enc = new Encoder(ticket, layout, Encoder.UIC_BARCODE_TYPE_CLASSIC, 2, 3); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + enc.setStaticHeaderParams("123456789012", "de"); + + assert(enc != null); + + try { + enc.signLevel1("1080", keyPair.getPrivate(), algorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPair.getPublic(),algorithmOID); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + SimpleTestTicketLayout.compare(layout, dec.getLayout()); + + } + + /** + * Generate DSA keys. + * + * @return the key pair + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchProviderException the no such provider exception + * @throws InvalidAlgorithmParameterException the invalid algorithm parameter exception + */ + public KeyPair generateDSAKeys(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException{ + KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC"); + g.initialize(keySize, new SecureRandom()); + return g.generateKeyPair(); + } + +} -- cgit v1.2.3 From 3062dbc6b6df9c7ef824eeea8d31ad5702506518 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Wed, 24 Nov 2021 12:40:11 +0100 Subject: more tests --- .../barcode/asn1/test/UperEncodeBitStringTest.java | 81 ++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java new file mode 100644 index 0000000..574a9cf --- /dev/null +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java @@ -0,0 +1,81 @@ +package org.uic.barcode.asn1.test; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import org.junit.Test; +import org.uic.barcode.asn1.datatypes.Asn1Optional; +import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring; +import org.uic.barcode.asn1.datatypes.FieldOrder; +import org.uic.barcode.asn1.datatypes.Sequence; +import org.uic.barcode.asn1.uper.UperEncoder; + + +public class UperEncodeBitStringTest { + + /** + * Example from the Standard on UPER. +
+         World-Schema DEFINITIONS AUTOMATIC TAGS ::= 
+         BEGIN
+         TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+            value BIT STRING OPTIONAL,
+         }
+         END
+         
+         
+         rec1value TestRecord ::= {
+             value '001'B
+         }
+    
+ + + + */ + @Sequence + public static class TestRecord { + + @FieldOrder(order = 0) + @Asn1Optional() Asn1VarSizeBitstring value; + + public TestRecord() { + this(false,false,true); + } + + public TestRecord(Boolean value1,Boolean value2,Boolean value3 ) { + List booleans = new ArrayList(); + booleans.add(value1); + booleans.add(value2); + booleans.add(value3); + this.value = new Asn1VarSizeBitstring(booleans); + + } + } + + + @Test public void testEncode() throws IllegalArgumentException, IllegalAccessException { + TestRecord record = new TestRecord(false,false,true); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("8190",hex); + } + + + @Test public void testDecode() throws IllegalArgumentException, IllegalAccessException { + TestRecord record = new TestRecord(false,false,true); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("8190",hex); + TestRecord result = UperEncoder.decode(encoded, TestRecord.class); + assertEquals(result.value.get(0),record.value.get(0)); + assertEquals(result.value.get(1),record.value.get(1)); + assertEquals(result.value.get(2),record.value.get(2)); + + } + +} -- cgit v1.2.3 From ff7e3432dc2db58aed49eca8b9a1fa22ad2a822b Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Wed, 24 Nov 2021 12:42:11 +0100 Subject: removed obsolete code --- .../org/uic/barcode/asn1/uper/BigIntCoder.java | 97 ---------------------- .../org/uic/barcode/asn1/uper/UperEncoder.java | 2 - 2 files changed, 99 deletions(-) delete mode 100644 src/main/java/org/uic/barcode/asn1/uper/BigIntCoder.java diff --git a/src/main/java/org/uic/barcode/asn1/uper/BigIntCoder.java b/src/main/java/org/uic/barcode/asn1/uper/BigIntCoder.java deleted file mode 100644 index 94e4b05..0000000 --- a/src/main/java/org/uic/barcode/asn1/uper/BigIntCoder.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.uic.barcode.asn1.uper; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.math.BigInteger; - -import org.uic.barcode.asn1.datatypes.Asn1BigInteger; -import org.uic.barcode.asn1.datatypes.Asn1Default; -import org.uic.barcode.asn1.datatypes.IntRange; - -class BigIntCoder implements Encoder, Decoder { - - @Override public boolean canDecode(Class classOfT, Annotation[] extraAnnotations) { - return Asn1BigInteger.class.isAssignableFrom(classOfT); - } - - @Override public T decode(BitBuffer bitbuffer, - Class classOfT, Field f, - Annotation[] extraAnnotations) { - AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), - extraAnnotations); - - String pos = String.format("%d.%d", bitbuffer.position()/8 , bitbuffer.position() % 8); - UperEncoder.logger.debug(String.format("Position %s BIG INT",pos)); - IntRange intRange = annotations.getAnnotation(IntRange.class); - if (intRange != null && intRange.maxValue() > 0) { - throw new UnsupportedOperationException("Big int with upper range is not supported yet"); - } - - int lengthInOctets = (int) UperEncoder.decodeLengthDeterminant(bitbuffer); - BitBuffer valueBits = ByteBitBuffer.allocate(lengthInOctets * 8); - for (int i = 0; i < lengthInOctets * 8; i++) { - valueBits.put(bitbuffer.get()); - } - valueBits.flip(); - BigInteger resultValue = new BigInteger(+1, valueBits.array()); - UperEncoder.logger.debug(String.format("big int Decoded as %s", resultValue)); - - - //CG support for int range - if (intRange != null){ - resultValue.add(BigInteger.valueOf(intRange.minValue())); - } - - - return UperEncoder.instantiate(classOfT, resultValue); - } - - @Override public boolean canEncode(T obj, Annotation[] extraAnnotations) { - return obj instanceof Asn1BigInteger; - } - - @Override public void encode(BitBuffer bitbuffer, T obj, Annotation[] extraAnnotations) throws Asn1EncodingException { - Class type = obj.getClass(); - AnnotationStore annotations = new AnnotationStore(type.getAnnotations(), extraAnnotations); - IntRange range = annotations.getAnnotation(IntRange.class); - - //CG implementation with lower range limit added - BigInteger bint = ((Asn1BigInteger) obj).toBigInteger(); - if (range != null) { - throw new UnsupportedOperationException("Asn1 BigInteger with range is not supported"); - } - byte[] array = bint.toByteArray(); - int lengthInOctets = array.length; - int position1 = bitbuffer.position(); - try { - UperEncoder.encodeLengthDeterminant(bitbuffer, lengthInOctets); - } catch (Asn1EncodingException e) { - throw new Asn1EncodingException(" length determinant of " + type.getName(), e); - } - int position2 = bitbuffer.position(); - for (byte b : array) { - bitbuffer.putByte(b); - } - UperEncoder.logger.debug(String.format("Big Int(%s): len %s, val %s", obj, - bitbuffer.toBooleanString(position1, position2 - position1), - bitbuffer.toBooleanStringFromPosition(position2))); - return; - } - - @Override - public T getDefault(Class classOfT, Annotation[] extraAnnotations) { - AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations); - Asn1Default defaultAnnotation = annotations.getAnnotation(Asn1Default.class); - if (defaultAnnotation == null) return null; - //check whether the class has a constructor for numeric types - String valueString = defaultAnnotation.value(); - long value = Long.parseLong(valueString); - UperEncoder.logger.debug(String.format("Default INTEGER: %d",value )); - - @SuppressWarnings("unchecked") - T t = (T) new Asn1BigInteger(value); - return t; - - } - -} \ No newline at end of file diff --git a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java index 5956054..bba64e2 100644 --- a/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java +++ b/src/main/java/org/uic/barcode/asn1/uper/UperEncoder.java @@ -162,7 +162,6 @@ public final class UperEncoder { static { encoders.add(new IntCoder()); - //encoders.add(new BigIntCoder()); encoders.add(new ByteCoder()); encoders.add(new BooleanCoder()); encoders.add(new SequenceCoder()); @@ -173,7 +172,6 @@ public final class UperEncoder { encoders.add(new StringCoder()); decoders.add(new IntCoder()); - //decoders.add(new BigIntCoder()); decoders.add(new ByteCoder()); decoders.add(new BooleanCoder()); decoders.add(new SequenceCoder()); -- cgit v1.2.3 From 6ecc7c805df718b2093cd8639cf0bbf5e52054cc Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Wed, 24 Nov 2021 17:01:50 +0100 Subject: more tests removed unused classes --- .../org/uic/barcode/asn1/datatypes/Alphabet.java | 1 - .../barcode/asn1/datatypes/AlphabetBuilder.java | 32 -------- .../org/uic/barcode/asn1/datatypes/Bitstring.java | 2 +- .../org/uic/barcode/asn1/datatypes/Optional.java | 96 ---------------------- .../org/uic/barcode/asn1/uper/BitStringCoder.java | 50 ++++++----- .../org/uic/barcode/asn1/test/GenAlphabet.java | 11 +++ .../barcode/asn1/test/UperEncodeBitStringTest.java | 27 +++--- .../test/UperEncodeStringCustomAlphabetTest.java | 82 ++++++++++++++++++ .../asn1/test/UperEncodeVarBitStringTest.java | 81 ++++++++++++++++++ 9 files changed, 218 insertions(+), 164 deletions(-) delete mode 100644 src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java delete mode 100644 src/main/java/org/uic/barcode/asn1/datatypes/Optional.java create mode 100644 src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java create mode 100644 src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java create mode 100644 src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java b/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java index 2b153ae..0202e16 100644 --- a/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java +++ b/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java @@ -3,7 +3,6 @@ package org.uic.barcode.asn1.datatypes; /** * Alphabet class for Restricted Strings. * - * Use {@link AlphabetBuilder} for convenient construction of restriction alphabets. */ public abstract class Alphabet { diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java b/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java deleted file mode 100644 index b768897..0000000 --- a/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.uic.barcode.asn1.datatypes; - - -public class AlphabetBuilder { - - private final StringBuilder sb = new StringBuilder(); - - public AlphabetBuilder() {} - - public String chars() { - return sb.toString(); - } - - public AlphabetBuilder withRange(char from, char to) { - for (char c = from; c <= to; c++) { - sb.append(c); - } - return this; - } - - public AlphabetBuilder withChars(String str) { - sb.append(str); - return this; - } - - public AlphabetBuilder withChars(Character... chars) { - for (char c : chars) { - sb.append(c); - } - return this; - } -} diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java b/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java index 1543f64..4771931 100644 --- a/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java +++ b/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java @@ -9,7 +9,7 @@ import java.lang.annotation.Target; * In UPER, a SEQUENCE OF Booleans would look exactly as bitstring, so this annotation can be * omitted for {@code List}. */ -@Target({ElementType.TYPE}) +@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Bitstring { diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java b/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java deleted file mode 100644 index 757ba29..0000000 --- a/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.uic.barcode.asn1.datatypes; - -import java.util.NoSuchElementException; -import java.util.Objects; - -/** Represents optional values. - * - * Should be replaced by java.util.Optional from Java 8, when project moves to Java 8. - * - * @param type of contained elements */ -public class Optional { - - private final T element; - private final boolean isPresent; - - private Optional(T element, boolean isPresent) { - this.element = element; - this.isPresent = isPresent; - } - - /** @return true if the Option contains a value */ - public boolean isPresent() { - return isPresent; - } - - /** @return the element if the option is not empty - * @throws java.util.NoSuchElementException if the option is empty */ - public T get() { - if (isPresent) { - return element; - } else { - throw new NoSuchElementException("None.get"); - } - } - - /** @return the value, if present, otherwise return {@code other} - * @param other the value to be returned if there is no value present */ - public T orElse(T other) { - return isPresent() ? get() : other; - } - - /** - * Indicates whether some other object is "equal to" this Optional. The - * other object is considered equal if: - *
    - *
  • it is also an {@code Optional} and; - *
  • both instances have no value present or; - *
  • the present values are "equal to" each other via {@code equals()}. - *
- * - * @param obj an object to be tested for equality - * @return {code true} if the other object is "equal to" this object - * otherwise {@code false} - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!(obj instanceof Optional)) { - return false; - } - - Optional other = (Optional) obj; - return Objects.equals(element, other.element); - } - - /** - * Returns the hash code value of the present value, if any, or 0 (zero) if - * no value is present. - * - * @return hash code value of the present value or 0 if no value is present - */ - @Override - public int hashCode() { - return Objects.hashCode(element); - } - - /** Returns an Option containing the value. - * - * @param the type of the value - * @param element contained value - * @return a new Option that contains the value */ - public static Optional of(final A element) { - return new Optional(element, true); - } - - /** Returns an empty option. - * - * @param - * @return an empty Option */ - public static Optional empty() { - return new Optional(null, false); - } -} diff --git a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java index ba1692c..19aac9b 100644 --- a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java +++ b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java @@ -4,12 +4,12 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.List; import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring; import org.uic.barcode.asn1.datatypes.Bitstring; import org.uic.barcode.asn1.datatypes.FixedSize; import org.uic.barcode.asn1.datatypes.SizeRange; -import org.uic.barcode.asn1.uper.UperEncoder.Asn1ContainerFieldSorter; class BitStringCoder implements Decoder, Encoder { @@ -29,18 +29,24 @@ class BitStringCoder implements Decoder, Encoder { throw new UnsupportedOperationException( "Bitstring with extensions is not implemented yet"); } - FixedSize size = type.getAnnotation(FixedSize.class); + FixedSize size = annotations.getAnnotation(FixedSize.class); int position = bitbuffer.position(); if (size != null) { - Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(type); - if (sorter.ordinaryFields.size() != size.value()) { throw new AssertionError( + if (!List.class.isAssignableFrom(type)) { + throw new AssertionError("Field should be a list of booleans!"); + } + + List list = (List)obj; + if (list.size() != size.value()) { + throw new AssertionError( "Declared size (" + size.value() + - ") and number of fields (" + sorter.ordinaryFields.size() + - ") do not match!"); } - for (Field f : sorter.ordinaryFields) { + ") and number of fields (" + list.size() + + ") do not match!"); + } + for (Boolean f : list) { try { - bitbuffer.put(f.getBoolean(obj)); - } catch (IllegalArgumentException | IllegalAccessException e) { + bitbuffer.put(f); + } catch (IllegalArgumentException e) { throw new IllegalArgumentException("can't encode" + obj, e); } } @@ -100,26 +106,28 @@ class BitStringCoder implements Decoder, Encoder { if (fixedSize == null) { throw new UnsupportedOperationException( "bitstrings of non-fixed size that do not extend Asn1VarSizeBitstring are not supported yet"); } - Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT); - if (fixedSize.value() != sorter.ordinaryFields.size()) { throw new IllegalArgumentException( - "Fixed size annotation " + fixedSize.value() - + " does not match the number of fields " - + sorter.ordinaryFields.size() + " in " + classOfT.getName()); } if (UperEncoder.hasExtensionMarker(annotations)) { boolean extensionPresent = bitbuffer.get(); if (extensionPresent) { throw new UnsupportedOperationException( "extensions in fixed-size bitlist are not supported yet"); } } T result = UperEncoder.instantiate(classOfT); - for (Field f : sorter.ordinaryFields) { - boolean value = bitbuffer.get(); - UperEncoder.logger.debug(String.format("Field %s set to %s", f.getName(), value)); + + Method addBooleanMethod; + try { + addBooleanMethod = classOfT.getDeclaredMethod("add", Object.class); + addBooleanMethod.setAccessible(true); + } catch (SecurityException | NoSuchMethodException e) { + throw new AssertionError("Can't find/access add " + e); + } + + for (int i = 0; i < fixedSize.value(); i++) { try { - f.set(result, value); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new IllegalArgumentException("can't decode " + classOfT, e); + addBooleanMethod.invoke(result, bitbuffer.get()); + } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { + throw new IllegalArgumentException("Can't invoke add", e); } - } + } return result; } else { UperEncoder.logger.debug("Bitlist(var-size)"); diff --git a/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java b/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java new file mode 100644 index 0000000..a08392e --- /dev/null +++ b/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java @@ -0,0 +1,11 @@ +package org.uic.barcode.asn1.test; + +import org.uic.barcode.asn1.datatypes.Alphabet; + +public class GenAlphabet extends Alphabet { + + public GenAlphabet() { + super("ACGT"); + } + +} diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java index 574a9cf..94f29c2 100644 --- a/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java @@ -3,13 +3,13 @@ package org.uic.barcode.asn1.test; import static org.junit.Assert.assertEquals; import java.util.ArrayList; -import java.util.List; import java.util.logging.Level; import org.junit.Test; import org.uic.barcode.asn1.datatypes.Asn1Optional; -import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring; +import org.uic.barcode.asn1.datatypes.Bitstring; import org.uic.barcode.asn1.datatypes.FieldOrder; +import org.uic.barcode.asn1.datatypes.FixedSize; import org.uic.barcode.asn1.datatypes.Sequence; import org.uic.barcode.asn1.uper.UperEncoder; @@ -22,7 +22,7 @@ public class UperEncodeBitStringTest { World-Schema DEFINITIONS AUTOMATIC TAGS ::= BEGIN TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE { - value BIT STRING OPTIONAL, + value BIT STRING (SIZE(3)) OPTIONAL } END @@ -39,19 +39,20 @@ public class UperEncodeBitStringTest { public static class TestRecord { @FieldOrder(order = 0) - @Asn1Optional() Asn1VarSizeBitstring value; + @Asn1Optional() + @Bitstring() + @FixedSize(3) + ArrayList booleans = null; public TestRecord() { this(false,false,true); } public TestRecord(Boolean value1,Boolean value2,Boolean value3 ) { - List booleans = new ArrayList(); + booleans = new ArrayList(); booleans.add(value1); booleans.add(value2); - booleans.add(value3); - this.value = new Asn1VarSizeBitstring(booleans); - + booleans.add(value3); } } @@ -61,7 +62,7 @@ public class UperEncodeBitStringTest { byte[] encoded = UperEncoder.encode(record); String hex = UperEncoder.hexStringFromBytes(encoded); UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); - assertEquals("8190",hex); + assertEquals("90",hex); } @@ -70,11 +71,11 @@ public class UperEncodeBitStringTest { byte[] encoded = UperEncoder.encode(record); String hex = UperEncoder.hexStringFromBytes(encoded); UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); - assertEquals("8190",hex); + assertEquals("90",hex); TestRecord result = UperEncoder.decode(encoded, TestRecord.class); - assertEquals(result.value.get(0),record.value.get(0)); - assertEquals(result.value.get(1),record.value.get(1)); - assertEquals(result.value.get(2),record.value.get(2)); + assertEquals(result.booleans.get(0),record.booleans.get(0)); + assertEquals(result.booleans.get(1),record.booleans.get(1)); + assertEquals(result.booleans.get(2),record.booleans.get(2)); } diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java new file mode 100644 index 0000000..03b8bac --- /dev/null +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java @@ -0,0 +1,82 @@ +package org.uic.barcode.asn1.test; + +import static org.junit.Assert.assertEquals; + +import java.util.logging.Level; + +import org.junit.Test; +import org.uic.barcode.asn1.datatypes.Asn1Optional; +import org.uic.barcode.asn1.datatypes.CharacterRestriction; +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.uper.UperEncoder; + + +public class UperEncodeStringCustomAlphabetTest { + + /** + * Example from the Standard on UPER. +
+        World-Schema DEFINITIONS AUTOMATIC TAGS ::= 
+        BEGIN
+        TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+            value1 PrintableString ( FROM ("ACGT") ) OPTIONAL,
+            value2 PrintableString ( FROM ("ACGT") ) OPTIONAL
+         }                                   
+        END
+        
+        rec1value TestRecord ::= {
+          value1 "ACGT",
+          value2 "ACTGCATCGA"
+        }
+    
+ */ + @Sequence + public static class TestRecord { + + @FieldOrder(order = 0) + @RestrictedString(value = CharacterRestriction.VisibleString, alphabet = GenAlphabet.class) + @Asn1Optional() String value1; + + @FieldOrder(order = 1) + @RestrictedString(value = CharacterRestriction.VisibleString, alphabet = GenAlphabet.class) + @Asn1Optional() String value2; + + public TestRecord() { + } + + public TestRecord(String v1, String v2) { + this.value1 = v1; + this.value2 = v2; + } + } + + + @Test public void testEncode() throws IllegalArgumentException, IllegalAccessException { + + + TestRecord record = new TestRecord("ACGT", "ACTGCATCGA"); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("C106C2879360",hex); + + } + + + @Test public void testDecode() throws IllegalArgumentException, IllegalAccessException { + + TestRecord record = new TestRecord("ACGT", "ACTGCATCGA"); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("C106C2879360",hex); + TestRecord result = UperEncoder.decode(encoded, TestRecord.class); + assertEquals(result.value1,record.value1); + assertEquals(result.value2,record.value2); + } + + + +} diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java new file mode 100644 index 0000000..d6212e2 --- /dev/null +++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java @@ -0,0 +1,81 @@ +package org.uic.barcode.asn1.test; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import org.junit.Test; +import org.uic.barcode.asn1.datatypes.Asn1Optional; +import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring; +import org.uic.barcode.asn1.datatypes.FieldOrder; +import org.uic.barcode.asn1.datatypes.Sequence; +import org.uic.barcode.asn1.uper.UperEncoder; + + +public class UperEncodeVarBitStringTest { + + /** + * Example from the Standard on UPER. +
+         World-Schema DEFINITIONS AUTOMATIC TAGS ::= 
+         BEGIN
+         TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+            value BIT STRING OPTIONAL,
+         }
+         END
+         
+         
+         rec1value TestRecord ::= {
+             value '001'B
+         }
+    
+ + + + */ + @Sequence + public static class TestRecord { + + @FieldOrder(order = 0) + @Asn1Optional() Asn1VarSizeBitstring value; + + public TestRecord() { + this(false,false,true); + } + + public TestRecord(Boolean value1,Boolean value2,Boolean value3 ) { + List booleans = new ArrayList(); + booleans.add(value1); + booleans.add(value2); + booleans.add(value3); + this.value = new Asn1VarSizeBitstring(booleans); + + } + } + + + @Test public void testEncode() throws IllegalArgumentException, IllegalAccessException { + TestRecord record = new TestRecord(false,false,true); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("8190",hex); + } + + + @Test public void testDecode() throws IllegalArgumentException, IllegalAccessException { + TestRecord record = new TestRecord(false,false,true); + byte[] encoded = UperEncoder.encode(record); + String hex = UperEncoder.hexStringFromBytes(encoded); + UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex)); + assertEquals("8190",hex); + TestRecord result = UperEncoder.decode(encoded, TestRecord.class); + assertEquals(result.value.get(0),record.value.get(0)); + assertEquals(result.value.get(1),record.value.get(1)); + assertEquals(result.value.get(2),record.value.get(2)); + + } + +} -- cgit v1.2.3 From 7f96cbde68c325719d08282cc850e4a704b43100 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Thu, 25 Nov 2021 16:28:36 +0100 Subject: test and bug fix on countermark and viaStation --- .../ticket/api/asn/omv1/CountermarkData.java | 6 +- .../ticket/api/asn/omv1/ViaStationType.java | 2 +- .../ticket/api/asn/omv2/CountermarkData.java | 6 +- .../ticket/api/asn/omv2/ViaStationType.java | 2 +- .../ticket/api/asn/omv3/CountermarkData.java | 6 +- .../ticket/api/asn/omv3/ViaStationType.java | 2 +- .../ticket/api/test/CountermarkComplexTestV1.java | 95 ++++ .../ticket/api/test/CountermarkComplexTestV3.java | 111 +++++ .../CountermarkTestComplexTicketV1.java | 509 +++++++++++++++++++ .../CountermarkTestComplexTicketV3.java | 544 +++++++++++++++++++++ 10 files changed, 1271 insertions(+), 12 deletions(-) create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV1.java create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV3.java create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV1.java create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV3.java diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CountermarkData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CountermarkData.java index 76625d4..579342e 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CountermarkData.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CountermarkData.java @@ -72,15 +72,15 @@ public class CountermarkData extends Object { @FieldOrder(order = 8) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long numberOfCountermark; + public Long numberOfCountermark; @FieldOrder(order = 9) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long totalOfCountermarks; + public Long totalOfCountermarks; @FieldOrder(order = 10) @RestrictedString(CharacterRestriction.UTF8String) - @Asn1Optional public String groupName; + public String groupName; @FieldOrder(order = 11) @Asn1Default("stationUIC") diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ViaStationType.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ViaStationType.java index dfc1e56..ddabf0b 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ViaStationType.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ViaStationType.java @@ -55,7 +55,7 @@ public class ViaStationType extends Object { @Asn1Optional public SequenceOfViaStationType route; @FieldOrder(order = 5) - @Asn1Optional public Boolean border = false; + public Boolean border = false; @FieldOrder(order = 6) @Asn1Optional public SequenceOfCarrierNum carriersNum; diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv2/CountermarkData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv2/CountermarkData.java index aefdc3b..4c5a961 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv2/CountermarkData.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv2/CountermarkData.java @@ -72,15 +72,15 @@ public class CountermarkData extends Object { @FieldOrder(order = 8) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long numberOfCountermark; + public Long numberOfCountermark; @FieldOrder(order = 9) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long totalOfCountermarks; + public Long totalOfCountermarks; @FieldOrder(order = 10) @RestrictedString(CharacterRestriction.UTF8String) - @Asn1Optional public String groupName; + public String groupName; @FieldOrder(order = 11) @Asn1Default("stationUIC") diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv2/ViaStationType.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv2/ViaStationType.java index 0e2ca6c..f7aa1bb 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv2/ViaStationType.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv2/ViaStationType.java @@ -55,7 +55,7 @@ public class ViaStationType extends Object { @Asn1Optional public SequenceOfViaStationType route; @FieldOrder(order = 5) - @Asn1Optional public Boolean border = false; + public Boolean border = false; @FieldOrder(order = 6) @Asn1Optional public SequenceOfCarrierNum carriersNum; diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv3/CountermarkData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv3/CountermarkData.java index 733ccf0..510ec6f 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv3/CountermarkData.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv3/CountermarkData.java @@ -72,15 +72,15 @@ public class CountermarkData extends Object { @FieldOrder(order = 8) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long numberOfCountermark; + public Long numberOfCountermark; @FieldOrder(order = 9) @IntRange(minValue=1,maxValue=200) - @Asn1Optional public Long totalOfCountermarks; + public Long totalOfCountermarks; @FieldOrder(order = 10) @RestrictedString(CharacterRestriction.UTF8String) - @Asn1Optional public String groupName; + String groupName; @FieldOrder(order = 11) @Asn1Default("stationUIC") diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv3/ViaStationType.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv3/ViaStationType.java index d47bd98..2d8b751 100644 --- a/src/main/java/org/uic/barcode/ticket/api/asn/omv3/ViaStationType.java +++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv3/ViaStationType.java @@ -55,7 +55,7 @@ public class ViaStationType extends Object { @Asn1Optional public SequenceOfViaStationType route; @FieldOrder(order = 5) - @Asn1Optional public Boolean border = false; + public Boolean border = false; @FieldOrder(order = 6) @Asn1Optional public SequenceOfCarrierNum carriersNum; diff --git a/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV1.java b/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV1.java new file mode 100644 index 0000000..5226880 --- /dev/null +++ b/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV1.java @@ -0,0 +1,95 @@ +package org.uic.barcode.ticket.api.test; + +import java.text.ParseException; +import java.util.TimeZone; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.asn1.uper.UperEncoder; +import org.uic.barcode.ticket.api.asn.omv1.UicRailTicketData; +import org.uic.barcode.ticket.api.test.testtickets.CountermarkTestComplexTicketV1; + + +/** + * The Class FipTimeZoneTestV3. + * + * + * + */ +public class CountermarkComplexTestV1 { + + + + /** The ticket decoded 1. */ + UicRailTicketData ticket = null; + + byte[] encodedInTimeZone1 = null; + + + TimeZone defaulttimeZone = null; + + /** + * Prepare tickets. + */ + @Before public void prepare() { + + defaulttimeZone = TimeZone.getDefault(); + + //encode in UTC time zone + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + + } + + /** + * clean up + */ + @After public void resetTimeZone() { + TimeZone.setDefault(defaulttimeZone); + } + + + /** + * Test encode test tickets in UTC and decode in CET. + * + * @throws IllegalArgumentException the illegal argument exception + * @throws IllegalAccessException the illegal access exception + * @throws ParseException + */ + @Test public void decoding() { + + //get tickets + String hex = CountermarkTestComplexTicketV1.getEncodingHex(); + byte[] content = UperEncoder.bytesFromHexString(hex); + ticket = UperEncoder.decode(content, UicRailTicketData.class); + + assert(ticket != null); + + } + + @Test public void encoding() throws IllegalArgumentException, IllegalAccessException, ParseException { + + //get tickets + String hex = CountermarkTestComplexTicketV1.getEncodingHex(); + byte[] content = UperEncoder.bytesFromHexString(hex); + ticket = UperEncoder.decode(content, UicRailTicketData.class); + + + //ticket = OpenTestComplexTicketV2.getUicTestTicket(); + byte[] encoded = UperEncoder.encode(ticket); + + + + assert(encoded != null); + assert(encoded.length > 20); + + String encodedHex = UperEncoder.hexStringFromBytes(encoded); + String expectedHex = CountermarkTestComplexTicketV1.getEncodingHex(); + + assert(expectedHex.equals(encodedHex)); + + } + + +} diff --git a/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV3.java b/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV3.java new file mode 100644 index 0000000..86495f0 --- /dev/null +++ b/src/test/java/org/uic/barcode/ticket/api/test/CountermarkComplexTestV3.java @@ -0,0 +1,111 @@ +package org.uic.barcode.ticket.api.test; + +import java.text.ParseException; +import java.util.TimeZone; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.asn1.uper.UperEncoder; +import org.uic.barcode.ticket.api.asn.omv3.UicRailTicketData; +import org.uic.barcode.ticket.api.test.testtickets.CountermarkTestComplexTicketV3; + + +/** + * The Class FipTimeZoneTestV3. + * + * + * + */ +public class CountermarkComplexTestV3 { + + + + /** The ticket decoded 1. */ + UicRailTicketData ticket = null; + + byte[] encodedInTimeZone1 = null; + + + TimeZone defaulttimeZone = null; + + /** + * Prepare tickets. + */ + @Before public void prepare() { + + defaulttimeZone = TimeZone.getDefault(); + + //encode in UTC time zone + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + + } + + /** + * clean up + */ + @After public void resetTimeZone() { + TimeZone.setDefault(defaulttimeZone); + } + + + /** + * Test encode test tickets in UTC and decode in CET. + * + * @throws IllegalArgumentException the illegal argument exception + * @throws IllegalAccessException the illegal access exception + * @throws ParseException + */ + @Test public void decoding() { + + //get tickets + String hex = CountermarkTestComplexTicketV3.getEncodingHex(); + byte[] content = UperEncoder.bytesFromHexString(hex); + ticket = UperEncoder.decode(content, UicRailTicketData.class); + + assert(ticket != null); + + } + + @Test public void encoding() throws IllegalArgumentException, IllegalAccessException, ParseException { + + //get tickets + String hex = CountermarkTestComplexTicketV3.getEncodingHex(); + byte[] content = UperEncoder.bytesFromHexString(hex); + ticket = UperEncoder.decode(content, UicRailTicketData.class); + + + //ticket = OpenTestComplexTicketV2.getUicTestTicket(); + byte[] encoded = UperEncoder.encode(ticket); + + + + assert(encoded != null); + assert(encoded.length > 20); + + String encodedHex = UperEncoder.hexStringFromBytes(encoded); + String expectedHex = CountermarkTestComplexTicketV3.getEncodingHex(); + + assert(expectedHex.equals(encodedHex)); + + } + + @Test public void encodingDecoding() throws IllegalArgumentException, IllegalAccessException, ParseException { + + //get tickets + ticket = CountermarkTestComplexTicketV3.getUicTestTicket(); + byte[] encoded = UperEncoder.encode(ticket); + + + + assert(encoded != null); + assert(encoded.length > 20); + + String encodedHex = UperEncoder.hexStringFromBytes(encoded); + String expectedHex = CountermarkTestComplexTicketV3.getEncodingHex(); + + assert(expectedHex.equals(encodedHex)); + + } +} diff --git a/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV1.java b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV1.java new file mode 100644 index 0000000..4e6fd8e --- /dev/null +++ b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV1.java @@ -0,0 +1,509 @@ +package org.uic.barcode.ticket.api.test.testtickets; + +import org.uic.barcode.asn1.datatypesimpl.SequenceOfUnrestrictedLong; +import org.uic.barcode.ticket.api.asn.omv1.CardReferenceType; +import org.uic.barcode.ticket.api.asn.omv1.ControlData; +import org.uic.barcode.ticket.api.asn.omv1.CountermarkData; +import org.uic.barcode.ticket.api.asn.omv1.CustomerStatusType; +import org.uic.barcode.ticket.api.asn.omv1.DocumentData; +import org.uic.barcode.ticket.api.asn.omv1.ExtensionData; +import org.uic.barcode.ticket.api.asn.omv1.IssuingData; +import org.uic.barcode.ticket.api.asn.omv1.LinkMode; +import org.uic.barcode.ticket.api.asn.omv1.RegionalValidityType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfCardReferenceType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfCustomerStatusType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfDocumentData; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfExtensionData; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfRegionalValidityType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfTicketLinkType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfTravelerType; +import org.uic.barcode.ticket.api.asn.omv1.SequenceOfViaStationType; +import org.uic.barcode.ticket.api.asn.omv1.TicketDetailData; +import org.uic.barcode.ticket.api.asn.omv1.TicketLinkType; +import org.uic.barcode.ticket.api.asn.omv1.TicketType; +import org.uic.barcode.ticket.api.asn.omv1.TravelClassType; +import org.uic.barcode.ticket.api.asn.omv1.TravelerData; +import org.uic.barcode.ticket.api.asn.omv1.TravelerType; +import org.uic.barcode.ticket.api.asn.omv1.UicRailTicketData; +import org.uic.barcode.ticket.api.asn.omv1.ViaStationType; +import org.uic.barcode.ticket.api.asn.omv1.ZoneType; + + + public class CountermarkTestComplexTicketV1 { + + public static UicRailTicketData getUicTestTicket() { + UicRailTicketData ticket = new UicRailTicketData(); + populateTicket(ticket); + return ticket; + } + + /* +value UicRailTicketData ::= { + issuingDetail { + issuingYear 2018 + issuingDay 1 + issuingTime 600 + specimen TRUE, + securePaperTicket FALSE, + activated TRUE, + issuerPNR "issuerTestPNR", + issuedOnLine 12 + } + ,travelerDetail{ + traveler { + { + firstName "John" + ,secondName "Dow" + ,idCard "12345" + ,ticketHolder TRUE + ,status {{customerStatusDescr "senior" }} + } + } + ,groupName "myGroup" + } + ,transportDocument { + { + ticket counterMark : { + numberOfCountermark 12 + ,totalOfCountermarks 24 + ,groupName "groupName" + ,validRegion + { viaStations { + route { + { stationNum 123455, border FALSE } + ,{ stationNum 123456, border FALSE } + ,{ alternativeRoutes { + { route { {stationNum 23455, border FALSE},{stationNum 23456, border FALSE }}, border FALSE } + ,{ route { {stationNum 3455, border FALSE },{stationNum 3456, border FALSE }}, border FALSE } + } + ,border FALSE + } + ,{ stationNum 123457, border FALSE } + } + ,border FALSE + ,seriesId 999 + } + ,zones { zoneId {100,200}} + } + ,returnIncluded FALSE + ,classCode first + ,infoText "counterMark" + } + } + } + ,controlDetail { + identificationByCardReference {{ trailingCardIdNum 100 } } + ,identificationByIdCard FALSE + ,identificationByPassportId FALSE + ,passportValidationRequired FALSE + ,onlineValidationRequired FALSE + ,ageCheckRequired FALSE + ,reductionCardCheckRequired FALSE + ,infoText "cd" + ,includedTickets { + { referenceIA5 "UED12435867" + ,issuerName "OEBB" + ,issuerPNR "PNR" + ,productOwnerIA5 "test" + ,ticketType pass + ,linkMode onlyValidInCombination + } + } + } + ,extension { + { extensionId "1", extensionData '82DA'H } + ,{ extensionId "2", extensionData '83DA'H } + } + } + +Encoding to the file 'data.uper' using PER UNALIGNED encoding rule... +UicRailTicketData SEQUENCE [root fieldcount (not encoded) = 5] + issuingDetail IssuingData SEQUENCE [root fieldcount (not encoded) = 8] + issuingYear INTEGER [length (not encoded) = 1.0] + 2018 + issuingDay INTEGER [length (not encoded) = 1.1] + 1 + issuingTime INTEGER [length (not encoded) = 1.3] + 600 + specimen BOOLEAN [length (not encoded) = 0.1] + TRUE + securePaperTicket BOOLEAN [length (not encoded) = 0.1] + FALSE + activated BOOLEAN [length (not encoded) = 0.1] + TRUE + issuerPNR IA5String [length = 13.0] + "issuerTestPNR" + issuedOnLine INTEGER [length = 1.0] + 12 + travelerDetail TravelerData SEQUENCE [root fieldcount (not encoded) = 2] + traveler SEQUENCE OF [count = 1] + TravelerType SEQUENCE [root fieldcount (not encoded) = 5] + firstName UTF8String [length = 4.0] + 0x4a6f686e + secondName UTF8String [length = 3.0] + 0x446f77 + idCard IA5String [length = 5.0] + "12345" + ticketHolder BOOLEAN [length (not encoded) = 0.1] + TRUE + status SEQUENCE OF [count = 1] + CustomerStatusType SEQUENCE [fieldcount (not encoded) = 1] + customerStatusDescr IA5String [length = 6.0] + "senior" + groupName UTF8String [length = 7.0] + 0x6d7947726f7570 + transportDocument SEQUENCE OF [count = 1] + DocumentData SEQUENCE [root fieldcount (not encoded) = 1] + ticket CHOICE [index = 6] + counterMark CountermarkData SEQUENCE [root fieldcount (not encoded) = 7] + numberOfCountermark INTEGER [length (not encoded) = 1.0] + 12 + totalOfCountermarks INTEGER [length (not encoded) = 1.0] + 24 + groupName UTF8String [length = 9.0] + 0x67726f75704e616d65 + validRegion SEQUENCE OF [count = 2] + RegionalValidityType CHOICE [index = 1] + viaStations ViaStationType SEQUENCE [root fieldcount (not encoded) = 3] + route SEQUENCE OF [count = 4] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + alternativeRoutes SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + route SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 23455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 23456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + route SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 3455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 3456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123457 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + seriesId INTEGER [length = 2.0] + 999 + RegionalValidityType CHOICE [index = 2] + zones ZoneType SEQUENCE [root fieldcount (not encoded) = 1] + zoneId SEQUENCE OF [count = 2] + INTEGER [length = 1.0] + 100 + INTEGER [length = 2.0] + 200 + returnIncluded BOOLEAN [length (not encoded) = 0.1] + FALSE + classCode TravelClassType ENUMERATED [length (not encoded) = 0.3] + 1 + infoText UTF8String [length = 11.0] + 0x636f756e7465724d61726b + controlDetail ControlData SEQUENCE [root fieldcount (not encoded) = 9] + identificationByCardReference SEQUENCE OF [count = 1] + CardReferenceType SEQUENCE [root fieldcount (not encoded) = 1] + trailingCardIdNum INTEGER [length = 1.0] + 100 + identificationByIdCard BOOLEAN [length (not encoded) = 0.1] + FALSE + identificationByPassportId BOOLEAN [length (not encoded) = 0.1] + FALSE + passportValidationRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + onlineValidationRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + ageCheckRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + reductionCardCheckRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + infoText UTF8String [length = 2.0] + 0x6364 + includedTickets SEQUENCE OF [count = 1] + TicketLinkType SEQUENCE [root fieldcount (not encoded) = 6] + referenceIA5 IA5String [length = 11.0] + "UED12435867" + issuerName UTF8String [length = 4.0] + 0x4f454242 + issuerPNR IA5String [length = 3.0] + "PNR" + productOwnerIA5 IA5String [length = 4.0] + "test" + ticketType TicketType ENUMERATED [length (not encoded) = 0.2] + 1 + linkMode LinkMode ENUMERATED [length (not encoded) = 0.1] + 1 + extension SEQUENCE OF [count = 2] + ExtensionData SEQUENCE [fieldcount (not encoded) = 2] + extensionId IA5String [length = 1.0] + "1" + extensionData OCTET STRING [length = 2.0] + 0x82da + ExtensionData SEQUENCE [fieldcount (not encoded) = 2] + extensionId IA5String [length = 1.0] + "2" + extensionData OCTET STRING [length = 2.0] + 0x83da +Total encoded length = 184.1 +Encoded successfully in 185 bytes: +78222020 0258A1BA 79F3EB97 954CBCFA 509D4804 31405A00 1044A6F6 86E03446 +F770562C 99B46B01 106E7977 69DFC81D B5E51DC9 BDD5C004 30000202 1058B84B +3B937BAB 82730B6B 28108240 84000F11 F08001E2 3F040040 80110000 B73C2000 +16E7C040 0880000D 7E100001 AFE08001 E2400080 F9C80100 80590080 320216C6 +DEEADCE8 CAE49AC2 E4D69804 0100B200 04C6C802 B70BAB16 23164D19 B570D9B8 +227A2A12 101D09D4 813A65E7 D0A0402C 40A0B680 590141ED 00 + + */ + + + + public static String getEncodingHex() { + return + "782220200258A1BA79F3EB97954CBCFA509D480431405A001044A6F686E03446" + + "F770562C99B46B01106E797769DFC81DB5E51DC9BDD5C004300002021058B84B" + + "3B937BAB82730B6B2810824084000F11F08001E23F04004080110000B73C2000" + + "16E7C0400880000D7E100001AFE08001E2400080F9C8010080590080320216C6" + + "DEEADCE8CAE49AC2E4D698040100B20004C6C802B70BAB1623164D19B570D9B8" + + "227A2A12101D09D4813A65E7D0A0402C40A0B680590141ED00"; + } + + + + private static void populateTicket(UicRailTicketData ticket) { + + ticket.setControlDetail(new ControlData()); + populate(ticket.getControlDetail()); + + + ticket.setIssuingDetail(new IssuingData()); + populateIssuingData(ticket.getIssuingDetail()); + + TravelerData td = new TravelerData(); + populateTravelerData(td); + ticket.setTravelerDetail(td); + + SequenceOfDocumentData ds = new SequenceOfDocumentData(); + + + //OpenTicket + DocumentData do1 = new DocumentData(); + addCounterMark(do1); + ds.add(do1); + ticket.setTransportDocument(ds); + + SequenceOfExtensionData ed = new SequenceOfExtensionData(); + populateExtensionSequence(ed); + ticket.setExtension(ed); + + } + + + private static void addCounterMark(DocumentData dd) { + + TicketDetailData tdd = new TicketDetailData(); + CountermarkData otd = new CountermarkData(); + otd.setInfoText("counterMark"); + otd.setClassCode(TravelClassType.first); + otd.setReturnIncluded(false); + + otd.setNumberOfCountermark(12L); + otd.setTotalOfCountermarks(24L);; + otd.setGroupName("groupName"); + + otd.setValidRegion(getValidRegion()); + + tdd.setCounterMark(otd); + dd.setTicket(tdd); + + } + + private static SequenceOfRegionalValidityType getValidRegion() { + SequenceOfRegionalValidityType sr = new SequenceOfRegionalValidityType(); + sr.add(getRegionalValidity()); + sr.add(getZone()); + return sr; + } + + private static RegionalValidityType getRegionalValidity() { + RegionalValidityType r = new RegionalValidityType(); + r.setViaStations(getRoute()); + return r; + } + + private static ViaStationType getRoute() { + ViaStationType m = new ViaStationType(); + m.setRoute(getMainRoute()); + m.setSeriesId(999L); + return m; + } + + + + private static ViaStationType getAlternativeRoute() { + ViaStationType s = new ViaStationType(); + s.setAlternativeRoutes(new SequenceOfViaStationType()); + s.getAlternativeRoutes().add(getAltRoute1()); + s.getAlternativeRoutes().add(getAltRoute2()); + return s; + } + + /* + * { route { {stationNum 23455, border FALSE},{stationNum 23456, border FALSE }}, border FALSE } + */ + private static ViaStationType getAltRoute1() { + ViaStationType m = new ViaStationType(); + m.setRoute(new SequenceOfViaStationType()); + m.getRoute().add(getViaStation(23455L)); + m.getRoute().add(getViaStation(23456L)); + return m; + } + + /* + * { route { {stationNum 3455, border FALSE },{stationNum 3456, border FALSE }}, border FALSE } + */ + + + private static ViaStationType getAltRoute2() { + ViaStationType m = new ViaStationType(); + m.setRoute(new SequenceOfViaStationType()); + m.getRoute().add(getViaStation(3455L)); + m.getRoute().add(getViaStation(3456L)); + return m; + } + + + private static ViaStationType getViaStation(long i) { + ViaStationType s = new ViaStationType(); + s.setStationNum(i); + return s; + } + + private static SequenceOfViaStationType getMainRoute() { + SequenceOfViaStationType s = new SequenceOfViaStationType(); + s.add(getViaStation(123455L)); + s.add(getViaStation(123456L)); + s.add(getAlternativeRoute()); + s.add(getViaStation(123457L)); + return s; + } + + private static RegionalValidityType getZone() { + RegionalValidityType r = new RegionalValidityType(); + ZoneType z = new ZoneType(); + z.setZoneId(new SequenceOfUnrestrictedLong()); + z.getZoneId().add(100L); + z.getZoneId().add(200L); + r.setZones(z); + return r; + } + + private static void populateTravelerData(TravelerData td) { + td.setGroupName("myGroup"); + SequenceOfTravelerType trs = new SequenceOfTravelerType(); + TravelerType tr = new TravelerType(); + tr.setIdCard("12345"); + tr.setFirstName("John"); + tr.setSecondName("Dow"); + tr.setTicketHolder(true); + SequenceOfCustomerStatusType ts = new SequenceOfCustomerStatusType(); + CustomerStatusType cst = new CustomerStatusType(); + cst.setCustomerStatusDescr("senior"); + ts.add(cst); + tr.setStatus(ts); + trs.add(tr); + td.setTraveler(trs); + } + + private static void populateIssuingData(IssuingData issuingDetail) { + issuingDetail.setIssuingYear(2018L); + issuingDetail.setIssuingDay(1L); + issuingDetail.setIssuingTime(600L); + issuingDetail.setIssuerPNR("issuerTestPNR"); + issuingDetail.setSpecimen(true); + issuingDetail.setSecurePaperTicket(false); + issuingDetail.setActivated(true); + issuingDetail.setIssuedOnLine(12L); + } + + + private static void populateExtensionSequence(SequenceOfExtensionData ed) { + ExtensionData ed1 = new ExtensionData(); + ed1.setExtensionId("1"); + byte[] ba1 = { (byte) 0x82, (byte) 0xDA }; + ed1.setExtensionData(ba1); + ExtensionData ed2 = new ExtensionData(); + ed2.setExtensionId("2"); + byte[] ba2 = { (byte) 0x83, (byte) 0xDA }; + ed2.setExtensionData(ba2); + ed.add(ed1); + ed.add(ed2); + } + + + private static void populate(ControlData controlDetail) { + controlDetail.infoText = "cd"; + controlDetail.setAgeCheckRequired(false); + controlDetail.setIdentificationByIdCard(false); + controlDetail.setIdentificationByPassportId(false); + controlDetail.setOnlineValidationRequired(false); + controlDetail.setPassportValidationRequired(false); + controlDetail.setReductionCardCheckRequired(false); + controlDetail.setIdentificationByCardReference(new SequenceOfCardReferenceType()); + controlDetail.getIdentificationByCardReference().add(populateCardRefrence()); + SequenceOfTicketLinkType sit = new SequenceOfTicketLinkType(); + populateLinkedTickets(sit); + controlDetail.setIncludedTickets(sit); + } + + + /* + * + */ + private static void populateLinkedTickets(SequenceOfTicketLinkType sequenceOfTicketLinkType) { + TicketLinkType tlt = new TicketLinkType(); + tlt.productOwnerIA5="test"; + tlt.setTicketType(TicketType.pass); + tlt.setIssuerPNR("PNR"); + tlt.setReferenceIA5("UED12435867"); + tlt.setLinkMode(LinkMode.onlyValidInCombination); + tlt.setIssuerName("OEBB"); + sequenceOfTicketLinkType.add(tlt); + } + + private static CardReferenceType populateCardRefrence() { + CardReferenceType cr = new CardReferenceType(); + cr.setTrailingCardIdNum(100L); + return cr; + } + + } diff --git a/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV3.java b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV3.java new file mode 100644 index 0000000..1843ec3 --- /dev/null +++ b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/CountermarkTestComplexTicketV3.java @@ -0,0 +1,544 @@ +package org.uic.barcode.ticket.api.test.testtickets; + +import org.uic.barcode.asn1.datatypesimpl.SequenceOfUnrestrictedLong; +import org.uic.barcode.ticket.api.asn.omv3.CardReferenceType; +import org.uic.barcode.ticket.api.asn.omv3.ControlData; +import org.uic.barcode.ticket.api.asn.omv3.CountermarkData; +import org.uic.barcode.ticket.api.asn.omv3.CustomerStatusType; +import org.uic.barcode.ticket.api.asn.omv3.DocumentData; +import org.uic.barcode.ticket.api.asn.omv3.ExtensionData; +import org.uic.barcode.ticket.api.asn.omv3.IssuingData; +import org.uic.barcode.ticket.api.asn.omv3.LinkMode; +import org.uic.barcode.ticket.api.asn.omv3.RegionalValidityType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfCardReferenceType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfCustomerStatusType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfDocumentData; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfExtensionData; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfRegionalValidityType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfTicketLinkType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfTravelerType; +import org.uic.barcode.ticket.api.asn.omv3.SequenceOfViaStationType; +import org.uic.barcode.ticket.api.asn.omv3.TicketDetailData; +import org.uic.barcode.ticket.api.asn.omv3.TicketLinkType; +import org.uic.barcode.ticket.api.asn.omv3.TicketType; +import org.uic.barcode.ticket.api.asn.omv3.TravelClassType; +import org.uic.barcode.ticket.api.asn.omv3.TravelerData; +import org.uic.barcode.ticket.api.asn.omv3.TravelerType; +import org.uic.barcode.ticket.api.asn.omv3.UicRailTicketData; +import org.uic.barcode.ticket.api.asn.omv3.ViaStationType; +import org.uic.barcode.ticket.api.asn.omv3.ZoneType; + + + public class CountermarkTestComplexTicketV3 { + + public static UicRailTicketData getUicTestTicket() { + UicRailTicketData ticket = new UicRailTicketData(); + populateTicket(ticket); + return ticket; + } + + /* +value UicRailTicketData ::= { + issuingDetail { + issuingYear 2018 + issuingDay 1 + issuingTime 600 + specimen TRUE, + securePaperTicket FALSE, + activated TRUE, + issuerPNR "issuerTestPNR", + issuedOnLine 12 + } + ,travelerDetail{ + traveler { + { + firstName "John" + ,secondName "Dow" + ,idCard "12345" + ,ticketHolder TRUE + ,status {{customerStatusDescr "senior" }} + } + } + ,groupName "myGroup" + } + ,transportDocument { + { + ticket counterMark : { + numberOfCountermark 12 + ,totalOfCountermarks 24 + ,groupName "groupName" + ,validRegion + { viaStations { + route { + { stationNum 123455, border FALSE } + ,{ stationNum 123456, border FALSE } + ,{ alternativeRoutes { + { route { {stationNum 23455, border FALSE},{stationNum 23456, border FALSE }}, border FALSE } + ,{ route { {stationNum 3455, border FALSE },{stationNum 3456, border FALSE }}, border FALSE } + } + ,border FALSE + } + ,{ stationNum 123457, border FALSE } + } + ,border FALSE + ,seriesId 999 + } + ,zones { zoneId {100,200}} + } + ,returnIncluded FALSE + ,classCode first + ,infoText "counterMark" + } + } + } + ,controlDetail { + identificationByCardReference {{ trailingCardIdNum 100 } } + ,identificationByIdCard FALSE + ,identificationByPassportId FALSE + ,passportValidationRequired FALSE + ,onlineValidationRequired FALSE + ,ageCheckRequired FALSE + ,reductionCardCheckRequired FALSE + ,infoText "cd" + ,includedTickets { + { referenceIA5 "UED12435867" + ,issuerName "OEBB" + ,issuerPNR "PNR" + ,productOwnerIA5 "test" + ,ticketType pass + ,linkMode onlyValidInCombination + } + } + } + ,extension { + { extensionId "1", extensionData '82DA'H } + ,{ extensionId "2", extensionData '83DA'H } + } + } + +Encoding to the file 'data.uper' using PER UNALIGNED encoding rule... +UicRailTicketData SEQUENCE [root fieldcount (not encoded) = 5] + issuingDetail IssuingData SEQUENCE [root fieldcount (not encoded) = 8] + issuingYear INTEGER [length (not encoded) = 1.0] + 2018 + issuingDay INTEGER [length (not encoded) = 1.1] + 1 + issuingTime INTEGER [length (not encoded) = 1.3] + 600 + specimen BOOLEAN [length (not encoded) = 0.1] + TRUE + securePaperTicket BOOLEAN [length (not encoded) = 0.1] + FALSE + activated BOOLEAN [length (not encoded) = 0.1] + TRUE + issuerPNR IA5String [length = 13.0] + "issuerTestPNR" + issuedOnLine INTEGER [length = 1.0] + 12 + travelerDetail TravelerData SEQUENCE [root fieldcount (not encoded) = 2] + traveler SEQUENCE OF [count = 1] + TravelerType SEQUENCE [root fieldcount (not encoded) = 5] + firstName UTF8String [length = 4.0] + 0x4a6f686e + secondName UTF8String [length = 3.0] + 0x446f77 + idCard IA5String [length = 5.0] + "12345" + ticketHolder BOOLEAN [length (not encoded) = 0.1] + TRUE + status SEQUENCE OF [count = 1] + CustomerStatusType SEQUENCE [fieldcount (not encoded) = 1] + customerStatusDescr IA5String [length = 6.0] + "senior" + groupName UTF8String [length = 7.0] + 0x6d7947726f7570 + transportDocument SEQUENCE OF [count = 1] + DocumentData SEQUENCE [root fieldcount (not encoded) = 1] + ticket CHOICE [index = 6] + counterMark CountermarkData SEQUENCE [root fieldcount (not encoded) = 7] + numberOfCountermark INTEGER [length (not encoded) = 1.0] + 12 + totalOfCountermarks INTEGER [length (not encoded) = 1.0] + 24 + groupName UTF8String [length = 9.0] + 0x67726f75704e616d65 + validRegion SEQUENCE OF [count = 2] + RegionalValidityType CHOICE [index = 1] + viaStations ViaStationType SEQUENCE [root fieldcount (not encoded) = 3] + route SEQUENCE OF [count = 4] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + alternativeRoutes SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + route SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 23455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 23456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + route SEQUENCE OF [count = 2] + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 3455 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 3456 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + ViaStationType SEQUENCE [root fieldcount (not encoded) = 2] + stationNum INTEGER [length (not encoded) = 3.0] + 123457 + border BOOLEAN [length (not encoded) = 0.1] + FALSE + border BOOLEAN [length (not encoded) = 0.1] + FALSE + seriesId INTEGER [length = 2.0] + 999 + RegionalValidityType CHOICE [index = 2] + zones ZoneType SEQUENCE [root fieldcount (not encoded) = 1] + zoneId SEQUENCE OF [count = 2] + INTEGER [length = 1.0] + 100 + INTEGER [length = 2.0] + 200 + returnIncluded BOOLEAN [length (not encoded) = 0.1] + FALSE + classCode TravelClassType ENUMERATED [length (not encoded) = 0.4] + 1 + infoText UTF8String [length = 11.0] + 0x636f756e7465724d61726b + controlDetail ControlData SEQUENCE [root fieldcount (not encoded) = 9] + identificationByCardReference SEQUENCE OF [count = 1] + CardReferenceType SEQUENCE [root fieldcount (not encoded) = 1] + trailingCardIdNum INTEGER [length = 1.0] + 100 + identificationByIdCard BOOLEAN [length (not encoded) = 0.1] + FALSE + identificationByPassportId BOOLEAN [length (not encoded) = 0.1] + FALSE + passportValidationRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + onlineValidationRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + ageCheckRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + reductionCardCheckRequired BOOLEAN [length (not encoded) = 0.1] + FALSE + infoText UTF8String [length = 2.0] + 0x6364 + includedTickets SEQUENCE OF [count = 1] + TicketLinkType SEQUENCE [root fieldcount (not encoded) = 6] + referenceIA5 IA5String [length = 11.0] + "UED12435867" + issuerName UTF8String [length = 4.0] + 0x4f454242 + issuerPNR IA5String [length = 3.0] + "PNR" + productOwnerIA5 IA5String [length = 4.0] + "test" + ticketType TicketType ENUMERATED [length (not encoded) = 0.2] + 1 + linkMode LinkMode ENUMERATED [length (not encoded) = 0.1] + 1 + extension SEQUENCE OF [count = 2] + ExtensionData SEQUENCE [fieldcount (not encoded) = 2] + extensionId IA5String [length = 1.0] + "1" + extensionData OCTET STRING [length = 2.0] + 0x82da + ExtensionData SEQUENCE [fieldcount (not encoded) = 2] + extensionId IA5String [length = 1.0] + "2" + extensionData OCTET STRING [length = 2.0] + 0x83da +Total encoded length = 187.0 +Encoded successfully in 187 bytes: +78044040 04B14374 F3E7D72F 2A9979F4 A13A9008 6280B400 1044A6F6 86E03446 +F770562C 99B46B01 106E7977 69DFC81D B5E51DC9 BDD5C004 30000202 1058B84B +3B937BAB 82730B6B 28108240 210000F1 1F080007 88FC1000 40800440 000B73C2 +00005B9F 01000880 00035F84 00001AFE 08000789 000203E7 20040201 640200C8 +042D8DBD D5B9D195 C93585C9 AD300802 01640009 8D90056E 17562C46 2C9A336A +E1B37044 F4542420 3A13A902 74CBCFA1 40805881 416D00B2 0283DA + + */ + + + + public static String getEncodingHex() { + return + "7804404004B14374F3E7D72F2A9979F4A13A90086280B4001044A6F686E03446" + + "F770562C99B46B01106E797769DFC81DB5E51DC9BDD5C004300002021058B84B" + + "3B937BAB82730B6B28108240210000F11F08000788FC100040800440000B73C2" + + "00005B9F0100088000035F8400001AFE08000789000203E720040201640200C8" + + "042D8DBDD5B9D195C93585C9AD300802016400098D90056E17562C462C9A336A" + + "E1B37044F45424203A13A90274CBCFA140805881416D00B20283DA"; + } + + + + private static void populateTicket(UicRailTicketData ticket) { + + ticket.setControlDetail(new ControlData()); + populate(ticket.getControlDetail()); + + + ticket.setIssuingDetail(new IssuingData()); + populateIssuingData(ticket.getIssuingDetail()); + + TravelerData td = new TravelerData(); + populateTravelerData(td); + ticket.setTravelerDetail(td); + + SequenceOfDocumentData ds = new SequenceOfDocumentData(); + + + //OpenTicket + DocumentData do1 = new DocumentData(); + addCounterMark(do1); + ds.add(do1); + ticket.setTransportDocument(ds); + + SequenceOfExtensionData ed = new SequenceOfExtensionData(); + populateExtensionSequence(ed); + ticket.setExtension(ed); + + } + + + private static void addCounterMark(DocumentData dd) { + + TicketDetailData tdd = new TicketDetailData(); + CountermarkData otd = new CountermarkData(); + otd.setInfoText("counterMark"); + otd.setClassCode(TravelClassType.first); + otd.setReturnIncluded(false); + + otd.setNumberOfCountermark(12L); + otd.setTotalOfCountermarks(24L); + otd.setGroupName("groupName"); + + otd.setValidRegion(getValidRegion()); + + tdd.setCounterMark(otd); + dd.setTicket(tdd); + + } + + private static SequenceOfRegionalValidityType getValidRegion() { + SequenceOfRegionalValidityType sr = new SequenceOfRegionalValidityType(); + sr.add(getRegionalValidity()); + sr.add(getZone()); + return sr; + } + + private static RegionalValidityType getRegionalValidity() { + RegionalValidityType r = new RegionalValidityType(); + r.setViaStations(getRoute()); + return r; + } + + private static ViaStationType getRoute() { + ViaStationType m = new ViaStationType(); + m.setRoute(getMainRoute()); + m.setSeriesId(999L); + return m; + } + + + + private static ViaStationType getAlternativeRoute() { + ViaStationType s = new ViaStationType(); + s.setAlternativeRoutes(new SequenceOfViaStationType()); + s.getAlternativeRoutes().add(getAltRoute1()); + s.getAlternativeRoutes().add(getAltRoute2()); + return s; + } + + /* + * { route { {stationNum 23455, border FALSE},{stationNum 23456, border FALSE }}, border FALSE } + */ + private static ViaStationType getAltRoute1() { + ViaStationType m = new ViaStationType(); + m.setRoute(new SequenceOfViaStationType()); + m.getRoute().add(getViaStation(23455L)); + m.getRoute().add(getViaStation(23456L)); + return m; + } + + /* + * { route { {stationNum 3455, border FALSE },{stationNum 3456, border FALSE }}, border FALSE } + */ + + + private static ViaStationType getAltRoute2() { + ViaStationType m = new ViaStationType(); + m.setRoute(new SequenceOfViaStationType()); + m.getRoute().add(getViaStation(3455L)); + m.getRoute().add(getViaStation(3456L)); + return m; + } + + private static ViaStationType getViaStation(long i) { + ViaStationType s = new ViaStationType(); + s.setStationNum(i); + return s; + } + + private static SequenceOfViaStationType getMainRoute() { + SequenceOfViaStationType s = new SequenceOfViaStationType(); + s.add(getViaStation(123455L)); + s.add(getViaStation(123456L)); + s.add(getAlternativeRoute()); + s.add(getViaStation(123457L)); + return s; + } + + private static RegionalValidityType getZone() { + RegionalValidityType r = new RegionalValidityType(); + ZoneType z = new ZoneType(); + z.setZoneId(new SequenceOfUnrestrictedLong()); + z.getZoneId().add(100L); + z.getZoneId().add(200L); + r.setZones(z); + return r; + } + + private static void populateTravelerData(TravelerData td) { + td.setGroupName("myGroup"); + SequenceOfTravelerType trs = new SequenceOfTravelerType(); + TravelerType tr = new TravelerType(); + tr.setIdCard("12345"); + tr.setFirstName("John"); + tr.setSecondName("Dow"); + tr.setTicketHolder(true); + SequenceOfCustomerStatusType ts = new SequenceOfCustomerStatusType(); + CustomerStatusType cst = new CustomerStatusType(); + cst.setCustomerStatusDescr("senior"); + ts.add(cst); + tr.setStatus(ts); + trs.add(tr); + td.setTraveler(trs); + } + + /* + * issuingDetail { + issuingYear 2018 + issuingDay 1 + issuingTime 600 + specimen TRUE, + securePaperTicket FALSE, + activated TRUE, + issuerPNR "issuerTestPNR", + issuedOnLine 12 + */ + private static void populateIssuingData(IssuingData issuingDetail) { + issuingDetail.setIssuingYear(2018L); + issuingDetail.setIssuingDay(1L); + issuingDetail.setIssuingTime(600L); + issuingDetail.setIssuerPNR("issuerTestPNR"); + issuingDetail.setSpecimen(true); + issuingDetail.setSecurePaperTicket(false); + issuingDetail.setActivated(true); + issuingDetail.setIssuedOnLine(12L); + } + + /* + *extension { + { extensionId "1", extensionData '82DA'H } + ,{ extensionId "2", extensionData '83DA'H } + } + */ + private static void populateExtensionSequence(SequenceOfExtensionData ed) { + ExtensionData ed1 = new ExtensionData(); + ed1.setExtensionId("1"); + byte[] ba1 = { (byte) 0x82, (byte) 0xDA }; + ed1.setExtensionData(ba1); + ExtensionData ed2 = new ExtensionData(); + ed2.setExtensionId("2"); + byte[] ba2 = { (byte) 0x83, (byte) 0xDA }; + ed2.setExtensionData(ba2); + ed.add(ed1); + ed.add(ed2); + } + + + /* + *controlDetail { + identificationByCardReference {{ trailingCardIdNum 100 } } + ,identificationByIdCard FALSE + ,identificationByPassportId FALSE + ,passportValidationRequired FALSE + ,onlineValidationRequired FALSE + ,ageCheckRequired FALSE + ,reductionCardCheckRequired FALSE + ,infoText "cd" + } + } + */ + private static void populate(ControlData controlDetail) { + controlDetail.infoText = "cd"; + controlDetail.setAgeCheckRequired(false); + controlDetail.setIdentificationByIdCard(false); + controlDetail.setIdentificationByPassportId(false); + controlDetail.setOnlineValidationRequired(false); + controlDetail.setPassportValidationRequired(false); + controlDetail.setReductionCardCheckRequired(false); + controlDetail.setIdentificationByCardReference(new SequenceOfCardReferenceType()); + controlDetail.getIdentificationByCardReference().add(populateCardRefrence()); + SequenceOfTicketLinkType sit = new SequenceOfTicketLinkType(); + populateLinkedTickets(sit); + controlDetail.setIncludedTickets(sit); + } + + + /* + * includedTickets { + { referenceIA5 "UED12435867" + ,issuerName "OEBB" + ,issuerPNR "PNR" + ,productOwnerIA5 "test" + ,ticketType pass + ,linkMode onlyValidInCombination + } + */ + private static void populateLinkedTickets(SequenceOfTicketLinkType sequenceOfTicketLinkType) { + TicketLinkType tlt = new TicketLinkType(); + tlt.setProductOwnerIA5("test"); + tlt.setTicketType(TicketType.pass); + tlt.setIssuerPNR("PNR"); + tlt.setReferenceIA5("UED12435867"); + tlt.setLinkMode(LinkMode.onlyValidInCombination); + tlt.setIssuerName("OEBB"); + sequenceOfTicketLinkType.add(tlt); + } + + private static CardReferenceType populateCardRefrence() { + CardReferenceType cr = new CardReferenceType(); + cr.setTrailingCardIdNum(100L); + return cr; + } + + } -- cgit v1.2.3