From 74d19c0493d7bf464d466b2dff2305021d911c27 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Wed, 17 May 2023 13:57:03 +0200
Subject: SSB tests
---
src/main/java/org/uic/barcode/Decoder.java | 15 +-
.../java/org/uic/barcode/ssbFrame/SsbFrame.java | 25 +-
.../org/uic/barcode/staticFrame/StaticFrame.java | 16 +-
.../OpenLuggageRestrictionTestTicketV3.java | 518 ---------------------
.../java/org/uic/barcode/utils/SecurityUtils.java | 41 +-
...rameBarcodeSignatureAlgorithmDetectionTest.java | 330 +++++++++++++
.../OpenLuggageRestrictionTestTicketV3.java | 518 +++++++++++++++++++++
7 files changed, 927 insertions(+), 536 deletions(-)
delete mode 100644 src/main/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
create mode 100644 src/test/java/org/uic/barcode/test/StaticFrameBarcodeSignatureAlgorithmDetectionTest.java
create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
(limited to 'src')
diff --git a/src/main/java/org/uic/barcode/Decoder.java b/src/main/java/org/uic/barcode/Decoder.java
index 85faa4a..637bbf6 100644
--- a/src/main/java/org/uic/barcode/Decoder.java
+++ b/src/main/java/org/uic/barcode/Decoder.java
@@ -84,15 +84,22 @@ public class Decoder {
* @throws EncodingFormatException the encoding format exception
*/
public int validateLevel1(PublicKey key) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
- if (dynamicFrame != null && dynamicFrame != null) {
+ if (dynamicFrame != null) {
return dynamicFrame.validateLevel1(key) ;
- } else {
- if (staticFrame != null) {
- return Constants.LEVEL1_VALIDATION_SIG_ALG_NOT_IMPLEMENTED;
+ } else if (staticFrame != null) {
+ if (staticFrame.verifyByAlgorithmOid(key,null)) {
+ return Constants.LEVEL1_VALIDATION_OK;
+ } else {
+ return Constants.LEVEL1_VALIDATION_FRAUD;
+ }
+ } else if (ssbFrame!= null) {
+ if (ssbFrame.verifyByAlgorithmOid(key,null, null)) {
+ return Constants.LEVEL1_VALIDATION_OK;
} else {
return Constants.LEVEL1_VALIDATION_FRAUD;
}
}
+ return Constants.LEVEL1_VALIDATION_NO_SIGNATURE;
}
/**
diff --git a/src/main/java/org/uic/barcode/ssbFrame/SsbFrame.java b/src/main/java/org/uic/barcode/ssbFrame/SsbFrame.java
index b473c1e..2c8f66f 100644
--- a/src/main/java/org/uic/barcode/ssbFrame/SsbFrame.java
+++ b/src/main/java/org/uic/barcode/ssbFrame/SsbFrame.java
@@ -1,6 +1,5 @@
package org.uic.barcode.ssbFrame;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
@@ -14,7 +13,6 @@ import java.security.SignatureException;
import java.security.Provider.Service;
import java.util.Arrays;
-
import org.uic.barcode.ticket.EncodingFormatException;
import org.uic.barcode.utils.AlgorithmNameResolver;
import org.uic.barcode.utils.SecurityUtils;
@@ -83,7 +81,7 @@ public class SsbFrame {
try {
//check for non-standard signature encoding
BigInteger[] bInts = SecurityUtils.decodeSignatureIntegerSequence(signatureBytes);
- byte[] sig = SecurityUtils.encodeSignatureIntegerSequence(bInts[0],bInts[1]);
+ SecurityUtils.encodeSignatureIntegerSequence(bInts[0],bInts[1]);
signaturePart1 = bInts[0].toByteArray();
signaturePart2 = bInts[1].toByteArray();
//decoding the entire signature was ok, so there was no split
@@ -334,8 +332,20 @@ public class SsbFrame {
//find the algorithm name for the signature OID
String algo = null;
+
+ BigInteger r = new BigInteger(1,signaturePart1);
+ BigInteger s = new BigInteger(1,signaturePart2);
+ byte[] signature = SecurityUtils.encodeSignatureIntegerSequence(r,s);
+
+ String signatureAlgorithmOid = signingAlg;
+
+ // guess the signature algorithm based on the signature size
+ if ((signingAlg == null || signingAlg.length() < 1) && signature != null) {
+ signatureAlgorithmOid = SecurityUtils.getDsaAlgorithm(signature);
+ }
+
if (prov != null) {
- Service service = prov.getService("Signature",signingAlg);
+ Service service = prov.getService("Signature",signatureAlgorithmOid);
if (service != null) {
algo = service.getAlgorithm();
}
@@ -343,7 +353,7 @@ public class SsbFrame {
Provider[] provs = Security.getProviders();
for (Provider p : provs) {
if (algo == null) {
- Service service = p.getService("Signature",signingAlg);
+ Service service = p.getService("Signature",signatureAlgorithmOid);
if (service != null) {
algo = service.getAlgorithm();
}
@@ -359,11 +369,6 @@ public class SsbFrame {
sig.initVerify(key);
sig.update(getDataForSignature());
- BigInteger r = new BigInteger(1,signaturePart1);
- BigInteger s = new BigInteger(1,signaturePart2);
-
- byte[] signature = SecurityUtils.encodeSignatureIntegerSequence(r,s);
-
return sig.verify(signature);
}
diff --git a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
index 8dc1adb..25649df 100644
--- a/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
+++ b/src/main/java/org/uic/barcode/staticFrame/StaticFrame.java
@@ -19,7 +19,9 @@ import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
+import org.uic.barcode.dynamicFrame.Constants;
import org.uic.barcode.ticket.EncodingFormatException;
+import org.uic.barcode.utils.SecurityUtils;
/**
@@ -660,11 +662,20 @@ public class StaticFrame {
* @throws IOException
*/
public boolean verifyByAlgorithmOid(PublicKey key, String signingAlg) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IllegalArgumentException, UnsupportedOperationException, IOException, EncodingFormatException {
+
+ String signatureAlgorithmOid = signingAlg;
+
+
+ // guess the signature algorithm based on the signature size
+ if ((signingAlg == null || signingAlg.length() < 1) && this.getSignature() != null) {
+ signatureAlgorithmOid = SecurityUtils.getDsaAlgorithm(this.getSignature());
+ }
+
//find the algorithm name for the signature OID
String algo = null;
Provider[] provs = Security.getProviders();
for (Provider prov : provs) {
- Service service = prov.getService("Signature",signingAlg);
+ Service service = prov.getService("Signature",signatureAlgorithmOid);
if (service != null) {
algo = service.getAlgorithm();
}
@@ -776,7 +787,8 @@ public class StaticFrame {
if (algo == null) {
throw new NoSuchAlgorithmException("No service for algorthm found: " + signingAlg);
}
- Signature sig = Signature.getInstance(algo);
+ Signature sig = Signature.getInstance(algo,prov);
+
sig.initSign(key);
signedData = getDataForSignature();
sig.update(signedData);
diff --git a/src/main/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java b/src/main/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
deleted file mode 100644
index f14acfa..0000000
--- a/src/main/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
- *
- * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
- *
- * openASN.1 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * openASN.1 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with openASN.1. If not, see .
- *
- */
-package org.uic.barcode.ticket.api.test.testtickets;
-
-import org.uic.barcode.asn1.datatypesimpl.SequenceOfStringUTF8;
-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.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.IncludedOpenTicketType;
-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.OpenTicketData;
-import org.uic.barcode.ticket.api.asn.omv3.PassengerType;
-import org.uic.barcode.ticket.api.asn.omv3.RegionalValidityType;
-import org.uic.barcode.ticket.api.asn.omv3.RegisteredLuggageType;
-import org.uic.barcode.ticket.api.asn.omv3.RouteSectionType;
-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.SequenceOfIncludedOpenTicketType;
-import org.uic.barcode.ticket.api.asn.omv3.SequenceOfRegionalValidityType;
-import org.uic.barcode.ticket.api.asn.omv3.SequenceOfRegisteredLuggageType;
-import org.uic.barcode.ticket.api.asn.omv3.SequenceOfTariffType;
-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.SequenceOfVatDetail;
-import org.uic.barcode.ticket.api.asn.omv3.StationPassageData;
-import org.uic.barcode.ticket.api.asn.omv3.TariffType;
-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.TokenType;
-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.VatDetailType;
-import org.uic.barcode.ticket.api.asn.omv3.ZoneType;
-import org.uic.barcode.ticket.api.asn.omv3.LuggageRestrictionType;
-
- public class OpenLuggageRestrictionTestTicketV3 {
-
- 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,
- currency "EUR",
- currencyFract 2,
- issuerPNR "issuerTestPNR",
- issuedOnLine 12
- },
- travelerDetail {
- traveler {
- {
- firstName "John",
- secondName "Dow",
- idCard "12345",
- ticketHolder TRUE,
- status {
- {
- customerStatusDescr "senior"
- }
- }
- }
- },
- groupName "myGroup"
- },
- transportDocument {
- {
- token {
- tokenProviderIA5 "VDV",
- token '82DA'H
- },
- ticket openTicket : {
- returnIncluded FALSE,
- stationCodeTable stationUIC,
- validFromDay 0,
- validUntilDay 0,
- classCode first,
- vatDetail {
- {
- country 80,
- percentage 70,
- amount 10,
- vatId "IUDGTE"
- }
- },
- infoText "openTicketInfo",
- includedAddOns {
- {
- productOwnerNum 1080,
- stationCodeTable stationUIC,
- validRegion {
- zones : {
- stationCodeTable stationUIC,
- zoneId {
- 100
- }
- }
- },
- validFromDay 0,
- validFromTime 1000,
- validUntilDay 1,
- validUntilTime 1000,
- classCode second,
- tariffs {
- {
- numberOfPassengers 2,
- passengerType adult,
- restrictedToCountryOfResidence FALSE,
- restrictedToRouteSection {
- stationCodeTable stationUIC,
- fromStationNum 8000001,
- toStationNum 8010000
- }
- }
- },
- infoText "included ticket"
- }
- },
- luggage {
- maxHandLuggagePieces 2,
- maxNonHandLuggagePieces 1,
- registeredLuggage {
- {
- registrationId "IODHUV",
- maxWeight 20,
- maxSize 100
- },
- {
- registrationId "XXDHUV",
- maxWeight 21,
- maxSize 101
- }
- }
- }
- }
- },
- {
- ticket stationPassage : {
- productName "passage",
- stationCodeTable stationUIC,
- stationNameUTF8 {
- "Amsterdam"
- },
- validFromDay 0,
- validUntilDay 0,
- numberOfDaysValid 123
- }
- }
- },
- 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
- }
- }
-}
-
- */
-
-
-
- public static String getEncodingHex() {
- return
- "7804404004B14374F3E7D72F2A9979F4A13A90086280B4001044A6F686"
- + "E03446F770562C99B46B01106E797769DFC81DB5E51DC9BDD5C00940"
- + "75A2560282DA1000000101E0101C4F11804281A4D5891EA450E6F706"
- + "56E5469636B6574496E666F0140AD06021B8090020080B23E8013E81"
- + "00B10008143D09003D1C8787B4B731B63AB232B2103A34B1B5B2BA28"
- + "202706933E248AB58998DC1AC588922AD62864120220103B830B9B9B"
- + "0B3B28084A0B6B9BA32B93230B696F017B4C0200805900026364015B"
- + "85D58B118B268CDAB86CDC113D1509080E84EA409D32F3E850201620"
- + "505B402C80A0F680";
-
- }
-
-
-
- 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();
- addOpenTicketData(do1);
- ds.add(do1);
-
- //StationPassage
- DocumentData do2 = new DocumentData();
- addStationPassage(do2);
- ds.add(do2);
-
- ticket.setTransportDocument(ds);
-
- SequenceOfExtensionData ed = new SequenceOfExtensionData();
- populateExtensionSequence(ed);
- ticket.setExtension(ed);
-
- }
-
- private static void addStationPassage(DocumentData dd) {
- TicketDetailData tdd = new TicketDetailData();
- StationPassageData sp = new StationPassageData();
- sp.setProductName("passage");
- sp.setValidFromDay(0L);
- sp.setNumberOfDaysValid(123L);
- SequenceOfStringUTF8 ss = new SequenceOfStringUTF8();
- ss.add("Amsterdam");
- sp.setStationNameUTF8(ss);
- tdd.setStationPassage(sp);
- dd.setTicket(tdd);
- }
-
- /*
- *
- * returnIncluded FALSE
- ,classCode first
- ,vatDetail {
- { country 80
- ,percentage 70
- ,amount 10
- ,vatId "IUDGTE"
- }
- }
- ,infoText "openTicketInfo"
- */
- private static void addOpenTicketData(DocumentData dd) {
- TokenType to = new TokenType();
- to.setTokenProviderIA5("VDV");
- byte[] ba = { (byte) 0x82, (byte) 0xDA };
- to.setToken(ba);
- dd.setToken(to);
-
- TicketDetailData tdd = new TicketDetailData();
- OpenTicketData otd = new OpenTicketData();
- otd.setInfoText("openTicketInfo");
- otd.setClassCode(TravelClassType.first);
- otd.setReturnIncluded(false);
-
- otd.setIncludedAddOns(new SequenceOfIncludedOpenTicketType());
- otd.getIncludedAddOns().add(getIncludedOpenTicket());
-
- otd.setVatDetails(new SequenceOfVatDetail());
- otd.getVatDetails().add(getVatDetail());
-
- otd.setLuggage(getLuggage());
-
- tdd.setOpenTicket(otd);
- dd.setTicket(tdd);
-
- }
-
- private static LuggageRestrictionType getLuggage() {
- LuggageRestrictionType l = new LuggageRestrictionType();
- l.setMaxHandLuggagePieces(2L);
- l.setMaxNonHandLuggagePieces(1L);
- l.setRegisteredLuggage(getRegisteredLuggage());
- return l;
- }
-
- private static SequenceOfRegisteredLuggageType getRegisteredLuggage() {
- SequenceOfRegisteredLuggageType sl = new SequenceOfRegisteredLuggageType();
- sl.add(getRegisteredLuggage1());
- sl.add(getRegisteredLuggage2());
- return sl;
- }
-
- private static RegisteredLuggageType getRegisteredLuggage1() {
- RegisteredLuggageType rl = new RegisteredLuggageType();
- rl.setMaxSize(100L);
- rl.setMaxWeight(20L);
- rl.setRegistrationId("IODHUV");
- return rl;
- }
-
- private static RegisteredLuggageType getRegisteredLuggage2() {
- RegisteredLuggageType rl = new RegisteredLuggageType();
- rl.setMaxSize(101L);
- rl.setMaxWeight(21L);
- rl.setRegistrationId("XXDHUV");
- return rl;
- }
-
- private static VatDetailType getVatDetail() {
- VatDetailType v = new VatDetailType();
- v.setAmount(10L);
- v.setCountry(80L);
- v.setPercentage(70L);
- v.setVatId("IUDGTE");
- return v;
- }
-
- /*
- { productOwnerNum 1080
- ,validRegion { zones : { zoneId { 100 } } }
- ,validFromDay 0
- ,validFromTime 1000
- ,validUntilDay 1
- ,validUntilTime 1000
- ,classCode second
- ,tariffs {
- { numberOfPassengers 2
- ,passengerType adult
- ,restrictedToCountryOfResidence FALSE
- ,restrictedToRouteSection { fromStationNum 8000001 , toStationNum 8010000 }
- }
- }
- ,infoText "included ticket"
- }
- */
-
- private static IncludedOpenTicketType getIncludedOpenTicket() {
- IncludedOpenTicketType t = new IncludedOpenTicketType();
- t.setClassCode(TravelClassType.second);
- t.setInfoText("included ticket");
- t.setProductOwnerNum(1080L);
- t.setValidRegion(new SequenceOfRegionalValidityType());
- t.getValidRegion().add(getZone());
- t.setValidFromDay(0L);
- t.setValidFromTime(1000L);
- t.setValidUntilDay(1L);
- t.setValidUntilTime(1000L);
- t.setTariffs(new SequenceOfTariffType());
- t.getTariffs().add(getTariff());
- return t;
- }
-
-
-
-
- private static RegionalValidityType getZone() {
-
- RegionalValidityType r = new RegionalValidityType();
- ZoneType z = new ZoneType();
- z.setZoneId(new SequenceOfUnrestrictedLong());
- z.getZoneId().add(100L);
- 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);
- }
-
- /*
- {
- trailingCardIdNum 100
- }
- */
- private static CardReferenceType populateCardRefrence() {
- CardReferenceType cr = new CardReferenceType();
- cr.setTrailingCardIdNum(100L);
- return cr;
- }
-
- private static TariffType getTariff() {
- TariffType t = new TariffType();
- t.setNumberOfPassengers(2L);
- t.setPassengerType(PassengerType.adult);
- t.setRestrictedToRouteSection(getRouteSection());
- t.setRestrictedToCountryOfResidence(false);
- return t;
- }
-
- private static RouteSectionType getRouteSection() {
- RouteSectionType r = new RouteSectionType();
- r.setFromStationNum(8000001L);
- r.setToStationNum(8010000L);
-
- return r;
- }
-
- }
diff --git a/src/main/java/org/uic/barcode/utils/SecurityUtils.java b/src/main/java/org/uic/barcode/utils/SecurityUtils.java
index 8c981af..8f19e4b 100644
--- a/src/main/java/org/uic/barcode/utils/SecurityUtils.java
+++ b/src/main/java/org/uic/barcode/utils/SecurityUtils.java
@@ -15,6 +15,8 @@ import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
+import org.uic.barcode.dynamicFrame.Constants;
+
/**
* The Class SecurityUtils.
*/
@@ -23,8 +25,8 @@ public class SecurityUtils {
/**
* Find provider by public key.
*
- * @param algorithmOid the algorithm oid used to generate the key
- * @param keyBytes the encoded bytes of the public key
+ * @param keyAlgorithmOid the key algorithm oid
+ * @param keyBytes the encoded bytes of the public key
* @return the provider
*/
public static Provider findPublicKeyProvider(String keyAlgorithmOid, byte[] keyBytes) {
@@ -263,6 +265,13 @@ public class SecurityUtils {
return out.toByteArray();
}
+ /**
+ * Recombine dsa signature.
+ *
+ * @param sealdata the sealdata
+ * @return the byte[]
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
public static byte[] recombineDsaSignature(byte[] sealdata) throws IOException {
//check whether the encoding is wrong and the sealdata contain a signature
@@ -311,4 +320,32 @@ public class SecurityUtils {
return out.toByteArray();
}
+
+ /**
+ * Gets the dsa algorithm allowed for ssb or static frame.
+ *
+ * @param bs the size of the signature
+ * @return the dsa algorithm OID
+ */
+ public static String getDsaAlgorithm(byte[] bs) {
+
+ BigInteger[] bInts = null;
+ int size = 0;
+ try {
+ bInts = decodeSignatureIntegerSequence(bs);
+ int sizeR = bInts[0].bitLength();
+ int sizeS = bInts[1].bitLength();
+ size = Math.max(sizeR,sizeS);
+ } catch (Exception e) {
+ return null;
+ }
+
+ if (size > 224) {
+ return Constants.DSA_SHA256;
+ } else if (size > 160) {
+ return Constants.DSA_SHA224;
+ } else {
+ return Constants.DSA_SHA1;
+ }
+ }
}
diff --git a/src/test/java/org/uic/barcode/test/StaticFrameBarcodeSignatureAlgorithmDetectionTest.java b/src/test/java/org/uic/barcode/test/StaticFrameBarcodeSignatureAlgorithmDetectionTest.java
new file mode 100644
index 0000000..be3db95
--- /dev/null
+++ b/src/test/java/org/uic/barcode/test/StaticFrameBarcodeSignatureAlgorithmDetectionTest.java
@@ -0,0 +1,330 @@
+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.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.logger.LoggerFactory;
+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 StaticFrameBarcodeSignatureAlgorithmDetectionTest {
+
+ /** 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;
+
+ public Provider prov = null;
+
+ /**
+ * Initialize.
+ *
+ * set the signature algorithm
+ * generate a key pair
+ * set the test content
+ * for ticket and layout
+ */
+ @Before public void initialize() {
+
+ LoggerFactory.setActivateConsoleLog(true);
+
+ prov = new BouncyCastleProvider();
+
+ Security.addProvider(prov);
+
+ }
+
+
+ /**
+ * Test DSA signature algorithm detection DSA SHA1
+ */
+ @Test public void testDsaSha1() {
+
+ LoggerFactory.setActivateConsoleLog(true);
+
+ algorithmOID = Constants.DSA_SHA1;
+ keySize = 512;
+ testFCBticket = SimpleUICTestTicket.getUicTestTicket();
+ testLayout = SimpleTestTicketLayout.getSimpleTestTicketLayout();
+
+
+ try {
+ keyPair = generateDSAKeys(keySize);
+ } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ }
+
+ assert(keyPair != null);
+
+
+ IUicRailTicket ticket = testFCBticket;
+
+ TicketLayout layout = testLayout;
+
+ Encoder enc = null;
+
+ try {
+ enc = new Encoder(ticket, layout, Encoder.UIC_BARCODE_TYPE_CLASSIC, 2, 13);
+ } catch (IOException | EncodingFormatException e1) {
+ assert(false);
+ }
+
+ enc.setStaticHeaderParams("123456789012", "de");
+
+ assert(enc != null);
+
+ try {
+ enc.signLevel1("1080", keyPair.getPrivate(), algorithmOID, "1", 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(keyPair.getPublic());
+ } 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());
+
+
+ }
+
+ /**
+ * Test DSA signature algorithm detection DSA SHA224
+ * DSAwithSHA224 is outdated an most provides don't support it properly!
+
+ @Test public void testDsaSha224() {
+
+ LoggerFactory.setActivateConsoleLog(true);
+
+ algorithmOID = Constants.DSA_SHA224;
+ keySize = 1024;
+ testFCBticket = SimpleUICTestTicket.getUicTestTicket();
+ testLayout = SimpleTestTicketLayout.getSimpleTestTicketLayout();
+
+
+ try {
+ keyPair = generateDSAKeys(keySize);
+ } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ }
+
+ assert(keyPair != null);
+
+
+ IUicRailTicket ticket = testFCBticket;
+
+ TicketLayout layout = testLayout;
+
+ Encoder enc = null;
+
+ try {
+ enc = new Encoder(ticket, layout, Encoder.UIC_BARCODE_TYPE_CLASSIC, 2, 13);
+ } catch (IOException | EncodingFormatException e1) {
+ assert(false);
+ }
+
+ enc.setStaticHeaderParams("123456789012", "de");
+
+ assert(enc != null);
+
+ try {
+ enc.signLevel1("1080", keyPair.getPrivate(), algorithmOID, "1", 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(keyPair.getPublic());
+ } 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());
+
+
+ }
+ */
+
+ /**
+ * Test DSA signature algorithm detection DSA SHA256
+ */
+ @Test public void testDsaSha256() {
+
+ LoggerFactory.setActivateConsoleLog(true);
+
+ algorithmOID = Constants.DSA_SHA256;
+ keySize = 2048;
+ testFCBticket = SimpleUICTestTicket.getUicTestTicket();
+ testLayout = SimpleTestTicketLayout.getSimpleTestTicketLayout();
+
+
+ try {
+ keyPair = generateDSAKeys(keySize);
+ } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
+ e.printStackTrace();
+ }
+
+ assert(keyPair != null);
+
+
+ IUicRailTicket ticket = testFCBticket;
+
+ TicketLayout layout = testLayout;
+
+ Encoder enc = null;
+
+ try {
+ enc = new Encoder(ticket, layout, Encoder.UIC_BARCODE_TYPE_CLASSIC, 2, 13);
+ } catch (IOException | EncodingFormatException e1) {
+ assert(false);
+ }
+
+ enc.setStaticHeaderParams("123456789012", "de");
+
+ assert(enc != null);
+
+ try {
+ enc.signLevel1("1080", keyPair.getPrivate(), algorithmOID, "1", 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(keyPair.getPublic());
+ } 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();
+ }
+
+}
diff --git a/src/test/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
new file mode 100644
index 0000000..f14acfa
--- /dev/null
+++ b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/OpenLuggageRestrictionTestTicketV3.java
@@ -0,0 +1,518 @@
+/*
+ * This file was generated by openASN.1 - an open source ASN.1 toolkit for java
+ *
+ * openASN.1 is Copyright (C) 2007 Clayton Hoss, Marc Weyland
+ *
+ * openASN.1 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * openASN.1 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with openASN.1. If not, see .
+ *
+ */
+package org.uic.barcode.ticket.api.test.testtickets;
+
+import org.uic.barcode.asn1.datatypesimpl.SequenceOfStringUTF8;
+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.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.IncludedOpenTicketType;
+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.OpenTicketData;
+import org.uic.barcode.ticket.api.asn.omv3.PassengerType;
+import org.uic.barcode.ticket.api.asn.omv3.RegionalValidityType;
+import org.uic.barcode.ticket.api.asn.omv3.RegisteredLuggageType;
+import org.uic.barcode.ticket.api.asn.omv3.RouteSectionType;
+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.SequenceOfIncludedOpenTicketType;
+import org.uic.barcode.ticket.api.asn.omv3.SequenceOfRegionalValidityType;
+import org.uic.barcode.ticket.api.asn.omv3.SequenceOfRegisteredLuggageType;
+import org.uic.barcode.ticket.api.asn.omv3.SequenceOfTariffType;
+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.SequenceOfVatDetail;
+import org.uic.barcode.ticket.api.asn.omv3.StationPassageData;
+import org.uic.barcode.ticket.api.asn.omv3.TariffType;
+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.TokenType;
+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.VatDetailType;
+import org.uic.barcode.ticket.api.asn.omv3.ZoneType;
+import org.uic.barcode.ticket.api.asn.omv3.LuggageRestrictionType;
+
+ public class OpenLuggageRestrictionTestTicketV3 {
+
+ 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,
+ currency "EUR",
+ currencyFract 2,
+ issuerPNR "issuerTestPNR",
+ issuedOnLine 12
+ },
+ travelerDetail {
+ traveler {
+ {
+ firstName "John",
+ secondName "Dow",
+ idCard "12345",
+ ticketHolder TRUE,
+ status {
+ {
+ customerStatusDescr "senior"
+ }
+ }
+ }
+ },
+ groupName "myGroup"
+ },
+ transportDocument {
+ {
+ token {
+ tokenProviderIA5 "VDV",
+ token '82DA'H
+ },
+ ticket openTicket : {
+ returnIncluded FALSE,
+ stationCodeTable stationUIC,
+ validFromDay 0,
+ validUntilDay 0,
+ classCode first,
+ vatDetail {
+ {
+ country 80,
+ percentage 70,
+ amount 10,
+ vatId "IUDGTE"
+ }
+ },
+ infoText "openTicketInfo",
+ includedAddOns {
+ {
+ productOwnerNum 1080,
+ stationCodeTable stationUIC,
+ validRegion {
+ zones : {
+ stationCodeTable stationUIC,
+ zoneId {
+ 100
+ }
+ }
+ },
+ validFromDay 0,
+ validFromTime 1000,
+ validUntilDay 1,
+ validUntilTime 1000,
+ classCode second,
+ tariffs {
+ {
+ numberOfPassengers 2,
+ passengerType adult,
+ restrictedToCountryOfResidence FALSE,
+ restrictedToRouteSection {
+ stationCodeTable stationUIC,
+ fromStationNum 8000001,
+ toStationNum 8010000
+ }
+ }
+ },
+ infoText "included ticket"
+ }
+ },
+ luggage {
+ maxHandLuggagePieces 2,
+ maxNonHandLuggagePieces 1,
+ registeredLuggage {
+ {
+ registrationId "IODHUV",
+ maxWeight 20,
+ maxSize 100
+ },
+ {
+ registrationId "XXDHUV",
+ maxWeight 21,
+ maxSize 101
+ }
+ }
+ }
+ }
+ },
+ {
+ ticket stationPassage : {
+ productName "passage",
+ stationCodeTable stationUIC,
+ stationNameUTF8 {
+ "Amsterdam"
+ },
+ validFromDay 0,
+ validUntilDay 0,
+ numberOfDaysValid 123
+ }
+ }
+ },
+ 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
+ }
+ }
+}
+
+ */
+
+
+
+ public static String getEncodingHex() {
+ return
+ "7804404004B14374F3E7D72F2A9979F4A13A90086280B4001044A6F686"
+ + "E03446F770562C99B46B01106E797769DFC81DB5E51DC9BDD5C00940"
+ + "75A2560282DA1000000101E0101C4F11804281A4D5891EA450E6F706"
+ + "56E5469636B6574496E666F0140AD06021B8090020080B23E8013E81"
+ + "00B10008143D09003D1C8787B4B731B63AB232B2103A34B1B5B2BA28"
+ + "202706933E248AB58998DC1AC588922AD62864120220103B830B9B9B"
+ + "0B3B28084A0B6B9BA32B93230B696F017B4C0200805900026364015B"
+ + "85D58B118B268CDAB86CDC113D1509080E84EA409D32F3E850201620"
+ + "505B402C80A0F680";
+
+ }
+
+
+
+ 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();
+ addOpenTicketData(do1);
+ ds.add(do1);
+
+ //StationPassage
+ DocumentData do2 = new DocumentData();
+ addStationPassage(do2);
+ ds.add(do2);
+
+ ticket.setTransportDocument(ds);
+
+ SequenceOfExtensionData ed = new SequenceOfExtensionData();
+ populateExtensionSequence(ed);
+ ticket.setExtension(ed);
+
+ }
+
+ private static void addStationPassage(DocumentData dd) {
+ TicketDetailData tdd = new TicketDetailData();
+ StationPassageData sp = new StationPassageData();
+ sp.setProductName("passage");
+ sp.setValidFromDay(0L);
+ sp.setNumberOfDaysValid(123L);
+ SequenceOfStringUTF8 ss = new SequenceOfStringUTF8();
+ ss.add("Amsterdam");
+ sp.setStationNameUTF8(ss);
+ tdd.setStationPassage(sp);
+ dd.setTicket(tdd);
+ }
+
+ /*
+ *
+ * returnIncluded FALSE
+ ,classCode first
+ ,vatDetail {
+ { country 80
+ ,percentage 70
+ ,amount 10
+ ,vatId "IUDGTE"
+ }
+ }
+ ,infoText "openTicketInfo"
+ */
+ private static void addOpenTicketData(DocumentData dd) {
+ TokenType to = new TokenType();
+ to.setTokenProviderIA5("VDV");
+ byte[] ba = { (byte) 0x82, (byte) 0xDA };
+ to.setToken(ba);
+ dd.setToken(to);
+
+ TicketDetailData tdd = new TicketDetailData();
+ OpenTicketData otd = new OpenTicketData();
+ otd.setInfoText("openTicketInfo");
+ otd.setClassCode(TravelClassType.first);
+ otd.setReturnIncluded(false);
+
+ otd.setIncludedAddOns(new SequenceOfIncludedOpenTicketType());
+ otd.getIncludedAddOns().add(getIncludedOpenTicket());
+
+ otd.setVatDetails(new SequenceOfVatDetail());
+ otd.getVatDetails().add(getVatDetail());
+
+ otd.setLuggage(getLuggage());
+
+ tdd.setOpenTicket(otd);
+ dd.setTicket(tdd);
+
+ }
+
+ private static LuggageRestrictionType getLuggage() {
+ LuggageRestrictionType l = new LuggageRestrictionType();
+ l.setMaxHandLuggagePieces(2L);
+ l.setMaxNonHandLuggagePieces(1L);
+ l.setRegisteredLuggage(getRegisteredLuggage());
+ return l;
+ }
+
+ private static SequenceOfRegisteredLuggageType getRegisteredLuggage() {
+ SequenceOfRegisteredLuggageType sl = new SequenceOfRegisteredLuggageType();
+ sl.add(getRegisteredLuggage1());
+ sl.add(getRegisteredLuggage2());
+ return sl;
+ }
+
+ private static RegisteredLuggageType getRegisteredLuggage1() {
+ RegisteredLuggageType rl = new RegisteredLuggageType();
+ rl.setMaxSize(100L);
+ rl.setMaxWeight(20L);
+ rl.setRegistrationId("IODHUV");
+ return rl;
+ }
+
+ private static RegisteredLuggageType getRegisteredLuggage2() {
+ RegisteredLuggageType rl = new RegisteredLuggageType();
+ rl.setMaxSize(101L);
+ rl.setMaxWeight(21L);
+ rl.setRegistrationId("XXDHUV");
+ return rl;
+ }
+
+ private static VatDetailType getVatDetail() {
+ VatDetailType v = new VatDetailType();
+ v.setAmount(10L);
+ v.setCountry(80L);
+ v.setPercentage(70L);
+ v.setVatId("IUDGTE");
+ return v;
+ }
+
+ /*
+ { productOwnerNum 1080
+ ,validRegion { zones : { zoneId { 100 } } }
+ ,validFromDay 0
+ ,validFromTime 1000
+ ,validUntilDay 1
+ ,validUntilTime 1000
+ ,classCode second
+ ,tariffs {
+ { numberOfPassengers 2
+ ,passengerType adult
+ ,restrictedToCountryOfResidence FALSE
+ ,restrictedToRouteSection { fromStationNum 8000001 , toStationNum 8010000 }
+ }
+ }
+ ,infoText "included ticket"
+ }
+ */
+
+ private static IncludedOpenTicketType getIncludedOpenTicket() {
+ IncludedOpenTicketType t = new IncludedOpenTicketType();
+ t.setClassCode(TravelClassType.second);
+ t.setInfoText("included ticket");
+ t.setProductOwnerNum(1080L);
+ t.setValidRegion(new SequenceOfRegionalValidityType());
+ t.getValidRegion().add(getZone());
+ t.setValidFromDay(0L);
+ t.setValidFromTime(1000L);
+ t.setValidUntilDay(1L);
+ t.setValidUntilTime(1000L);
+ t.setTariffs(new SequenceOfTariffType());
+ t.getTariffs().add(getTariff());
+ return t;
+ }
+
+
+
+
+ private static RegionalValidityType getZone() {
+
+ RegionalValidityType r = new RegionalValidityType();
+ ZoneType z = new ZoneType();
+ z.setZoneId(new SequenceOfUnrestrictedLong());
+ z.getZoneId().add(100L);
+ 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);
+ }
+
+ /*
+ {
+ trailingCardIdNum 100
+ }
+ */
+ private static CardReferenceType populateCardRefrence() {
+ CardReferenceType cr = new CardReferenceType();
+ cr.setTrailingCardIdNum(100L);
+ return cr;
+ }
+
+ private static TariffType getTariff() {
+ TariffType t = new TariffType();
+ t.setNumberOfPassengers(2L);
+ t.setPassengerType(PassengerType.adult);
+ t.setRestrictedToRouteSection(getRouteSection());
+ t.setRestrictedToCountryOfResidence(false);
+ return t;
+ }
+
+ private static RouteSectionType getRouteSection() {
+ RouteSectionType r = new RouteSectionType();
+ r.setFromStationNum(8000001L);
+ r.setToStationNum(8010000L);
+
+ return r;
+ }
+
+ }
--
cgit v1.2.3
From 0ce9bdf9480e30e81ed9285d7f10ceb0502072cc Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Thu, 25 May 2023 11:37:18 +0200
Subject: bug fix on passport validation required
---
.../ticket/api/utils/OpenAsn2ApiDecoder.java | 6 ++
.../ticket/api/utils/OpenAsn2ApiDecoderV2.java | 7 ++
.../ticket/api/utils/OpenAsn2ApiDecoderV3.java | 7 ++
.../test/PassComplexPassportValidationTestV3.java | 109 +++++++++++++++++++++
4 files changed, 129 insertions(+)
create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/PassComplexPassportValidationTestV3.java
(limited to 'src')
diff --git a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoder.java b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoder.java
index 4cccb18..f9c6b7e 100644
--- a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoder.java
+++ b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoder.java
@@ -2132,6 +2132,12 @@ public class OpenAsn2ApiDecoder implements Asn2ApiDecoder {
controlDetails.setOnlineValidationRequired(asnControlDetails.getOnlineValidationRequired());
}
+ if (asnControlDetails.getPassportValidationRequired() !=null){
+ controlDetails.setPassportValidationRequired(asnControlDetails.getPassportValidationRequired());
+ } else {
+ controlDetails.setPassportValidationRequired(true);
+ }
+
if (asnControlDetails.getRandomDetailedValidationRequired()!= null){
controlDetails.setRandomDetailedValidationRequired(asnControlDetails.getRandomDetailedValidationRequired().intValue());
}
diff --git a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV2.java b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV2.java
index 70017aa..f21a592 100644
--- a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV2.java
+++ b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV2.java
@@ -2140,6 +2140,13 @@ public class OpenAsn2ApiDecoderV2 implements Asn2ApiDecoder {
controlDetails.setIdentificationByPassportId(asnControlDetails.getIdentificationByPassportId());
}
+
+ if (asnControlDetails.getPassportValidationRequired() !=null){
+ controlDetails.setPassportValidationRequired(asnControlDetails.getPassportValidationRequired());
+ } else {
+ controlDetails.setPassportValidationRequired(true);
+ }
+
if(asnControlDetails.getIdentificationItem()!=null){
controlDetails.setIdentificationItem(asnControlDetails.getIdentificationItem().intValue());
}
diff --git a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV3.java b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV3.java
index a9cc0d3..66a0d22 100644
--- a/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV3.java
+++ b/src/main/java/org/uic/barcode/ticket/api/utils/OpenAsn2ApiDecoderV3.java
@@ -2216,6 +2216,13 @@ public class OpenAsn2ApiDecoderV3 implements Asn2ApiDecoder {
controlDetails.setIdentificationByPassportId(asnControlDetails.getIdentificationByPassportId());
}
+
+ if (asnControlDetails.getPassportValidationRequired() !=null){
+ controlDetails.setPassportValidationRequired(asnControlDetails.getPassportValidationRequired());
+ } else {
+ controlDetails.setPassportValidationRequired(true);
+ }
+
if(asnControlDetails.getIdentificationItem()!=null){
controlDetails.setIdentificationItem(asnControlDetails.getIdentificationItem().intValue());
}
diff --git a/src/test/java/org/uic/barcode/ticket/api/test/PassComplexPassportValidationTestV3.java b/src/test/java/org/uic/barcode/ticket/api/test/PassComplexPassportValidationTestV3.java
new file mode 100644
index 0000000..a7b3087
--- /dev/null
+++ b/src/test/java/org/uic/barcode/ticket/api/test/PassComplexPassportValidationTestV3.java
@@ -0,0 +1,109 @@
+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.logger.LoggerFactory;
+import org.uic.barcode.ticket.api.asn.omv3.BoardingOrArrivalType;
+import org.uic.barcode.ticket.api.asn.omv3.PassData;
+import org.uic.barcode.ticket.api.asn.omv3.UicRailTicketData;
+import org.uic.barcode.ticket.api.test.testtickets.PassComplexTicketV3;
+
+
+/**
+ * The Class Test asn.1 encoding of a pass.
+ *
+ *
+ *
+ */
+public class PassComplexPassportValidationTestV3 {
+
+
+ /** The ticket decoded 1. */
+ UicRailTicketData ticket = null;
+
+ byte[] encodedInTimeZone1 = null;
+
+
+ TimeZone defaulttimeZone = null;
+
+ /**
+ * Prepare tickets.
+ */
+ @Before public void prepare() {
+
+ LoggerFactory.setActivateConsoleLog(true);
+
+ 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 = PassComplexTicketV3.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 = PassComplexTicketV3.getEncodingHex();
+ byte[] content = UperEncoder.bytesFromHexString(hex);
+ ticket = UperEncoder.decode(content, UicRailTicketData.class);
+ ticket.getControlDetail().setPassportValidationRequired(true);
+
+
+ byte[] encoded = UperEncoder.encode(ticket);
+
+
+
+ assert(encoded != null);
+ assert(encoded.length > 20);
+
+
+ assert(ticket.getTransportDocument().get(0).getTicket().getPass() != null);
+
+ PassData p = ticket.getTransportDocument().get(0).getTicket().getPass();
+
+
+ assert(p.getTrainValidity().getBordingOrArrival().equals(BoardingOrArrivalType.boarding));
+ assert(p.getTrainValidity().getIncludedCarriersNum().contains(1234L));
+ assert(p.getTrainValidity().getIncludedCarriersNum().contains(5678L));
+ assert(p.getTrainValidity().getValidFromDay() == 0L);
+ assert(p.getTrainValidity().getValidFromTime() == 1000L);
+ assert(p.getTrainValidity().getValidUntilDay() == 1L);
+ assert(p.getTrainValidity().getValidUntilTime() == 1000L);
+ assert(ticket.getControlDetail().getPassportValidationRequired() == true);
+
+
+ }
+
+}
--
cgit v1.2.3
From 91507261d564cb2a8b7dd338f92d80738d4646f1 Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Thu, 25 May 2023 12:03:47 +0200
Subject: fix on head with wrong month
---
src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java b/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
index 31a664b..30777a5 100644
--- a/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
+++ b/src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java
@@ -255,7 +255,7 @@ public class UHEADDataRecord extends DataRecord{
String timeElement = String.format("%02d%02d%04d%02d%02d",
now.get(Calendar.DAY_OF_MONTH),
- now.get(Calendar.MONTH),
+ now.get(Calendar.MONTH) + 1,
now.get(Calendar.YEAR),
now.get(Calendar.HOUR),
now.get(Calendar.MINUTE));
--
cgit v1.2.3
From b2b1ccfc41495353dbbf211abc3ae8da2967a05f Mon Sep 17 00:00:00 2001
From: CGantert345 <57003061+CGantert345@users.noreply.github.com>
Date: Thu, 25 May 2023 13:32:43 +0200
Subject: fix on productId in version 1 FCB
---
.../org/uic/barcode/ticket/api/asn/omv1/CarCarriageReservationData.java | 2 +-
src/main/java/org/uic/barcode/ticket/api/asn/omv1/CountermarkData.java | 2 +-
src/main/java/org/uic/barcode/ticket/api/asn/omv1/FIPTicketData.java | 2 +-
.../org/uic/barcode/ticket/api/asn/omv1/IncludedOpenTicketType.java | 2 +-
src/main/java/org/uic/barcode/ticket/api/asn/omv1/OpenTicketData.java | 2 +-
.../java/org/uic/barcode/ticket/api/asn/omv1/ParkingGroundData.java | 2 +-
src/main/java/org/uic/barcode/ticket/api/asn/omv1/PassData.java | 2 +-
src/main/java/org/uic/barcode/ticket/api/asn/omv1/ReservationData.java | 2 +-
.../java/org/uic/barcode/ticket/api/asn/omv1/StationPassageData.java | 2 +-
9 files changed, 9 insertions(+), 9 deletions(-)
(limited to 'src')
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CarCarriageReservationData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CarCarriageReservationData.java
index 1eb0533..6729d08 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CarCarriageReservationData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/CarCarriageReservationData.java
@@ -84,7 +84,7 @@ public class CarCarriageReservationData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 10)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 11)
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 c7d0557..a31f56d 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
@@ -56,7 +56,7 @@ public class CountermarkData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 4)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 5)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/FIPTicketData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/FIPTicketData.java
index b1cc30c..b9d5a50 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/FIPTicketData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/FIPTicketData.java
@@ -58,7 +58,7 @@ public class FIPTicketData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 4)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 5)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/IncludedOpenTicketType.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/IncludedOpenTicketType.java
index 51afa05..c3cc557 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/IncludedOpenTicketType.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/IncludedOpenTicketType.java
@@ -50,7 +50,7 @@ public class IncludedOpenTicketType extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 2)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 3)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/OpenTicketData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/OpenTicketData.java
index 29047b3..6f90f6f 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/OpenTicketData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/OpenTicketData.java
@@ -59,7 +59,7 @@ public class OpenTicketData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 4)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 5)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ParkingGroundData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ParkingGroundData.java
index 53cb4c0..daddc7b 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ParkingGroundData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ParkingGroundData.java
@@ -59,7 +59,7 @@ public class ParkingGroundData extends Object {
@Asn1Optional public Long toParkingDate;
@FieldOrder(order = 5)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productOwnerNum;
@FieldOrder(order = 6)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/PassData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/PassData.java
index 63f9292..74e8e4d 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/PassData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/PassData.java
@@ -71,7 +71,7 @@ public class PassData extends Object {
/** The product id num. */
@FieldOrder(order = 4)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
/** The product id IA 5. */
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ReservationData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ReservationData.java
index ecf1d5a..b1b2be4 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ReservationData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/ReservationData.java
@@ -69,7 +69,7 @@ public class ReservationData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 7)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 8)
diff --git a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/StationPassageData.java b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/StationPassageData.java
index 36dc6bf..f04a835 100644
--- a/src/main/java/org/uic/barcode/ticket/api/asn/omv1/StationPassageData.java
+++ b/src/main/java/org/uic/barcode/ticket/api/asn/omv1/StationPassageData.java
@@ -58,7 +58,7 @@ public class StationPassageData extends Object {
@Asn1Optional public String productOwnerIA5;
@FieldOrder(order = 4)
- @IntRange(minValue=1,maxValue=32000)
+ @IntRange(minValue=0,maxValue=32000)
@Asn1Optional public Long productIdNum;
@FieldOrder(order = 5)
--
cgit v1.2.3