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 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 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 --- pom.xml | 2 +- src/main/java/org/uic/barcode/staticFrame/UHEADDataRecord.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cdc6c2c..213ef70 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.uic.barcode org.uic.barcode - 1.4.0 + 1.4.1 jar UIC barcode encoding and decoding of Aztec barcode content according to UIC IRS 90918-9 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(-) 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