From 58bafb860b060c609a01815657b4df22ce8fbffc Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 12 Apr 2022 12:54:16 +0200 Subject: test on algorithm name resolver --- .../dynamicFrame/api/SimpleDynamicFrame.java | 15 +- .../uic/barcode/dynamicFrame/v2/DynamicFrame.java | 56 ------ .../barcode/ticket/api/impl/SimpleTraveler.java | 2 +- .../ticket/api/utils/OpenAsn2ApiDecoder.java | 4 +- .../ticket/api/utils/OpenAsn2ApiDecoderV2.java | 4 +- .../ticket/api/utils/OpenAsn2ApiDecoderV3.java | 6 +- .../java/org/uic/barcode/utils/SecurityUtils.java | 57 +++++- .../uic/barcode/asn1/test/BinaryStringTest.java | 66 ++++++ .../barcode/test/AlgorithmNameResolverTest.java | 122 +++++++++++ .../org/uic/barcode/test/BinaryStringTest.java | 66 ------ .../DynamicFrameDoubleSignatureBCelipticTest2.java | 167 ++++++++++++++++ .../DynamicFrameDoubleSignatureCurve2Test.java | 167 ++++++++++++++++ .../org/uic/barcode/test/SecurityUtilsTest.java | 222 +++++++++++++++++++++ .../ticket/api/test/DelayConfirmationTestV3.java | 180 +++++++++++++++++ .../api/test/testtickets/DelayTestTicketV3.java | 10 + 15 files changed, 997 insertions(+), 147 deletions(-) create mode 100644 src/test/java/org/uic/barcode/asn1/test/BinaryStringTest.java create mode 100644 src/test/java/org/uic/barcode/test/AlgorithmNameResolverTest.java delete mode 100644 src/test/java/org/uic/barcode/test/BinaryStringTest.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureBCelipticTest2.java create mode 100644 src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureCurve2Test.java create mode 100644 src/test/java/org/uic/barcode/test/SecurityUtilsTest.java create mode 100644 src/test/java/org/uic/barcode/ticket/api/test/DelayConfirmationTestV3.java diff --git a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java index a8d7a0f..59ccd52 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/api/SimpleDynamicFrame.java @@ -150,6 +150,7 @@ public class SimpleDynamicFrame implements IDynamicFrame { } String level2KeyAlg = getLevel2Data().getLevel1Data().getLevel2KeyAlg(); + String level2SigAlg = this.getLevel2Data().getLevel1Data().getLevel2SigningAlg(); if (level2KeyAlg == null || level2KeyAlg.length() == 0) { @@ -173,16 +174,13 @@ public class SimpleDynamicFrame implements IDynamicFrame { PublicKey key = null; try { byte[] keyBytes = this.getLevel2Data().getLevel1Data().getLevel2publicKey(); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = null; if (provider == null) { - keyFactory = SecurityUtils.findKeyFactory(level2KeyAlg, keyBytes); - provider = keyFactory.getProvider(); - } else { - keyFactory = KeyFactory.getInstance(keyAlgName,provider); - } + provider = SecurityUtils.findPublicKeyProvider(level2KeyAlg,keyBytes); + } + KeyFactory keyFactory = KeyFactory.getInstance(keyAlgName,provider); if (keyFactory != null) { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); key = keyFactory.generatePublic(keySpec); } else { return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED; @@ -194,9 +192,8 @@ public class SimpleDynamicFrame implements IDynamicFrame { return Constants.LEVEL2_VALIDATION_KEY_ALG_NOT_IMPLEMENTED; } - //find the algorithm name for the signature OID - String level2SigAlg = this.getLevel2Data().getLevel1Data().getLevel2SigningAlg(); + //find the algorithm name for the signature OID String sigAlgName = null; try { sigAlgName = AlgorithmNameResolver.getSignatureAlgorithmName(level2SigAlg,provider); diff --git a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java index 55af066..30043c0 100644 --- a/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java +++ b/src/main/java/org/uic/barcode/dynamicFrame/v2/DynamicFrame.java @@ -123,43 +123,6 @@ public class DynamicFrame extends Object{ } - /** - * Sign level 2 data without a specific security provider. - * - * @param key the key - * @throws Exception the exception - */ - public void signLevel2(PrivateKey key) throws Exception { - - //find the algorithm name for the signature OID - String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg); - Signature sig = Signature.getInstance(algo); - sig.initSign(key); - byte[] data = level2SignedData.encode(); - sig.update(data); - byte[] signature = sig.sign(); - this.level2Signature = new OctetString(signature); - - } - - /** - * Sign level 2 data. - * - * @param key the key - * @param prov the security Provider - * @throws Exception the exception - */ - public void signLevel2(PrivateKey key, Provider prov) throws Exception { - - //find the algorithm name for the signature OID - String algo = AlgorithmNameResolver.getSignatureAlgorithmName(this.getLevel2SignedData().getLevel1Data().level2SigningAlg); - Signature sig = Signature.getInstance(algo,prov); - sig.initSign(key); - byte[] data = level2SignedData.encode(); - sig.update(data); - this.level2Signature = new OctetString(sig.sign()); - - } /** @@ -207,24 +170,5 @@ public class DynamicFrame extends Object{ } - /** - * Gets the dynamic data FDC 1. - * - * @return the dynamic data FDC 1 - */ - public UicDynamicContentDataFDC1 getDynamicDataFDC1() { - - if (this.getLevel2SignedData() == null || - this.getLevel2SignedData().getLevel2Data() == null){ - return null; - } - - if ( UicDynamicContentDataFDC1.getFormat().equals(this.getLevel2SignedData().getLevel2Data().getFormat())) { - return UperEncoder.decode(this.getLevel2SignedData().getLevel2Data().getByteData(), UicDynamicContentDataFDC1.class); - } - return null; - - } - } diff --git a/src/main/java/org/uic/barcode/ticket/api/impl/SimpleTraveler.java b/src/main/java/org/uic/barcode/ticket/api/impl/SimpleTraveler.java index afc351d..e7edd45 100644 --- a/src/main/java/org/uic/barcode/ticket/api/impl/SimpleTraveler.java +++ b/src/main/java/org/uic/barcode/ticket/api/impl/SimpleTraveler.java @@ -53,7 +53,7 @@ public class SimpleTraveler implements ITraveler { protected IPassengerType passengerType; /** The passenger with reduced mobility. */ - protected boolean passengerWithReducedMobility; + protected Boolean passengerWithReducedMobility; /** The country of residence. */ protected int countryOfResidence = 0; 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 031d5b3..f4e041f 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 @@ -356,12 +356,14 @@ public class OpenAsn2ApiDecoder implements Asn2ApiDecoder { private IDelayConfirmation convertDelayConfirmation(DelayConfirmation asnDocument, Date issuingDate) { IDelayConfirmation document = factory.createDelayConfirmation(); - document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum().longValue(),asnDocument.getReferenceIA5())); + document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum(),asnDocument.getReferenceIA5())); document.setExtension(convertExtension(asnDocument.getExtension())); document.setInfoText(asnDocument.getInfoText()); + document.setTrain(UicEncoderUtils.mapToString(asnDocument.getTrainNum(), asnDocument.getTrainIA5())); + if (asnDocument.getStationCodeTable()!=null){ document.setStationCodeTable(IStationCodeTable.valueOf(asnDocument.getStationCodeTable().name())); } 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 1d50cb8..57d2366 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 @@ -358,12 +358,14 @@ public class OpenAsn2ApiDecoderV2 implements Asn2ApiDecoder { private IDelayConfirmation convertDelayConfirmation(DelayConfirmation asnDocument, Date issuingDate) { IDelayConfirmation document = factory.createDelayConfirmation(); - document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum().longValue(),asnDocument.getReferenceIA5())); + document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum(),asnDocument.getReferenceIA5())); document.setExtension(convertExtension(asnDocument.getExtension())); document.setInfoText(asnDocument.getInfoText()); + document.setTrain(UicEncoderUtils.mapToString(asnDocument.getTrainNum(), asnDocument.getTrainIA5())); + if (asnDocument.getStationCodeTable()!=null){ document.setStationCodeTable(IStationCodeTable.valueOf(asnDocument.getStationCodeTable().toString())); } 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 20d2319..9521858 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 @@ -361,12 +361,14 @@ public class OpenAsn2ApiDecoderV3 implements Asn2ApiDecoder { private IDelayConfirmation convertDelayConfirmation(DelayConfirmation asnDocument, Date issuingDate) { IDelayConfirmation document = factory.createDelayConfirmation(); - document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum().longValue(),asnDocument.getReferenceIA5())); + document.setReference(UicEncoderUtils.mapToString(asnDocument.getReferenceNum(),asnDocument.getReferenceIA5())); document.setExtension(convertExtension(asnDocument.getExtension())); - document.setInfoText(asnDocument.getInfoText()); + document.setInfoText(asnDocument.getInfoText()); + document.setTrain(UicEncoderUtils.mapToString(asnDocument.getTrainNum(), asnDocument.getTrainIA5())); + if (asnDocument.getStationCodeTable()!=null){ document.setStationCodeTable(IStationCodeTable.valueOf(asnDocument.getStationCodeTable().toString())); } diff --git a/src/main/java/org/uic/barcode/utils/SecurityUtils.java b/src/main/java/org/uic/barcode/utils/SecurityUtils.java index af1a65a..1fcc18a 100644 --- a/src/main/java/org/uic/barcode/utils/SecurityUtils.java +++ b/src/main/java/org/uic/barcode/utils/SecurityUtils.java @@ -11,22 +11,30 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +/** + * The Class SecurityUtils. + */ public class SecurityUtils { - public static KeyFactory findKeyFactory(String oid, byte[] keyBytes) { + /** + * Find provider by public key. + * + * @param algorithmOid the algorithm oid used to generate the key + * @param keyBytes the encoded bytes of the public key + * @return the provider + */ + public static Provider findPublicKeyProvider(String keyAlgorithmOid, byte[] keyBytes) { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - String name = null; + String name; try { - name = AlgorithmNameResolver.getName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, oid); + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, keyAlgorithmOid, null); } catch (Exception e2) { return null; } - if (name == null || name.length() == 0) { - return null; - } - + KeyFactory keyFactory = null; Provider[] provs = Security.getProviders(); @@ -39,17 +47,23 @@ public class SecurityUtils { if (keyFactory != null) { try { keyFactory.generatePublic(keySpec); - return keyFactory; + return provider; } catch (Exception e) { + provider = null; //try next } } } - return null; - + + return null; } - + /** + * Find private key provider. + * + * @param key the private key + * @return the provider + */ public static Provider findPrivateKeyProvider(PrivateKey key) { String name = key.getAlgorithm(); @@ -84,6 +98,13 @@ public class SecurityUtils { + /** + * Convert. + * + * @param key the key + * @param provider the provider + * @return the public key + */ public static PublicKey convert(PublicKey key, Provider provider) { PublicKey publicKey; @@ -108,6 +129,13 @@ public class SecurityUtils { } + /** + * Convert. + * + * @param key the key + * @param provider the provider + * @return the private key + */ public static PrivateKey convert(PrivateKey key, Provider provider) { PrivateKey privateKey; @@ -131,6 +159,13 @@ public class SecurityUtils { } + /** + * Find signature provider. + * + * @param encoded the encoded + * @param oid the oid + * @return the provider + */ public static Provider findSignatureProvider(byte[] encoded, String oid) { KeyFactory keyFactory = null; diff --git a/src/test/java/org/uic/barcode/asn1/test/BinaryStringTest.java b/src/test/java/org/uic/barcode/asn1/test/BinaryStringTest.java new file mode 100644 index 0000000..bb06eae --- /dev/null +++ b/src/test/java/org/uic/barcode/asn1/test/BinaryStringTest.java @@ -0,0 +1,66 @@ +package org.uic.barcode.asn1.test; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.asn1.uper.AsnUtils; +import org.uic.barcode.logger.LoggerFactory; +import org.uic.barcode.ticket.EncodingFormatException; + +public class BinaryStringTest { + + @Before public void prepare() { + LoggerFactory.setActivateConsoleLog(true); + } + + + @Test public void testBinaryString() throws IOException, EncodingFormatException{ + + String bs1 = "01000000"; + String ms1 = "1000000001000000001000000001000000001000000001000000001000000001"; + String ms2 = "10000000010000000010000000010000"; + + + //String bs1 = "1011111100001000011011100000000000000001000000010000010010000000"; + + byte[] bytes = AsnUtils.fromBooleanString(bs1); + + String bs2 = AsnUtils.toBooleanString(bytes); + + + + byte[] mask = new byte[] { + (byte) 0b1000_0000, + 0b0100_0000, + 0b0010_0000, + 0b0001_0000, + 0b0000_1000, + 0b0000_0100, + 0b0000_0010, + 0b0000_0001, + }; + String bs3 = AsnUtils.toBooleanString(mask); + byte[] bytes2 = AsnUtils.fromBooleanString(bs3); + + + byte[] mask2 = new byte[] { + (byte) 0b1000_0000, + 0b0100_0000, + 0b0010_0000, + 0b0001_0000, + }; + String bs4 = AsnUtils.toBooleanString(mask2); + byte[] bytes3 = AsnUtils.fromBooleanString(bs4); + + + assert(bs4.equals(ms2)); + + assert(bs3.equals(ms1)); + + assert(bs1.equals(bs2)); + + } + + +} \ No newline at end of file diff --git a/src/test/java/org/uic/barcode/test/AlgorithmNameResolverTest.java b/src/test/java/org/uic/barcode/test/AlgorithmNameResolverTest.java new file mode 100644 index 0000000..6e245e8 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/AlgorithmNameResolverTest.java @@ -0,0 +1,122 @@ +package org.uic.barcode.test; + +import java.security.Provider; +import java.security.Security; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.utils.AlgorithmNameResolver; + +public class AlgorithmNameResolverTest { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + + public Provider provider = null; + + + @Before public void initialize() { + + + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + + provider = new BouncyCastleProvider(); + Security.addProvider(new BouncyCastleProvider()); + + } + + + + @Test public void testSignatureAlgorithmName() { + + String name = null; + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, signatureAlgorithmOID, null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("SHA256withECDSA")); + + //default values: + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, "1.2.840.10045", null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("ECDSA")); + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, "1.2.840.10040", null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("DSA")); + + //custom value + + AlgorithmNameResolver.addMap(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, "1.2.3.4.5", "TEST"); + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, "1.2.3.4.5", null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("TEST")); + + + } + + @Test public void testKeyGeneratorAlgorithmName() { + + String name = null; + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, keyPairAlgorithmOID, null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("EC")); + + //default values: + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_SIGNATURE_ALG, "1.2.840.10045.3", null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("EC")); + + + + //custom value + + AlgorithmNameResolver.addMap(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, "1.2.3.4.5", "TEST"); + + try { + name = AlgorithmNameResolver.getAlgorithmName(AlgorithmNameResolver.TYPE_KEY_GENERATOR_ALG, "1.2.3.4.5", null); + } catch (Exception e) { + assert(false); + } + + assert(name.equals("TEST")); + + + } + + +} diff --git a/src/test/java/org/uic/barcode/test/BinaryStringTest.java b/src/test/java/org/uic/barcode/test/BinaryStringTest.java deleted file mode 100644 index 11fc3c8..0000000 --- a/src/test/java/org/uic/barcode/test/BinaryStringTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.uic.barcode.test; - -import java.io.IOException; - -import org.junit.Before; -import org.junit.Test; -import org.uic.barcode.asn1.uper.AsnUtils; -import org.uic.barcode.logger.LoggerFactory; -import org.uic.barcode.ticket.EncodingFormatException; - -public class BinaryStringTest { - - @Before public void prepare() { - LoggerFactory.setActivateConsoleLog(true); - } - - - @Test public void testBinaryString() throws IOException, EncodingFormatException{ - - String bs1 = "01000000"; - String ms1 = "1000000001000000001000000001000000001000000001000000001000000001"; - String ms2 = "10000000010000000010000000010000"; - - - //String bs1 = "1011111100001000011011100000000000000001000000010000010010000000"; - - byte[] bytes = AsnUtils.fromBooleanString(bs1); - - String bs2 = AsnUtils.toBooleanString(bytes); - - - - byte[] mask = new byte[] { - (byte) 0b1000_0000, - 0b0100_0000, - 0b0010_0000, - 0b0001_0000, - 0b0000_1000, - 0b0000_0100, - 0b0000_0010, - 0b0000_0001, - }; - String bs3 = AsnUtils.toBooleanString(mask); - byte[] bytes2 = AsnUtils.fromBooleanString(bs3); - - - byte[] mask2 = new byte[] { - (byte) 0b1000_0000, - 0b0100_0000, - 0b0010_0000, - 0b0001_0000, - }; - String bs4 = AsnUtils.toBooleanString(mask2); - byte[] bytes3 = AsnUtils.fromBooleanString(bs4); - - - assert(bs4.equals(ms2)); - - assert(bs3.equals(ms1)); - - assert(bs1.equals(bs2)); - - } - - -} \ No newline at end of file diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureBCelipticTest2.java b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureBCelipticTest2.java new file mode 100644 index 0000000..f5d0729 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureBCelipticTest2.java @@ -0,0 +1,167 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.security.spec.ECGenParameterSpec; +import java.util.Arrays; +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.dynamicFrame.api.IData; +import org.uic.barcode.logger.LoggerFactory; +import org.uic.barcode.test.utils.Level2TestDataFactory; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; +import org.uic.barcode.utils.SecurityUtils; + +public class DynamicFrameDoubleSignatureBCelipticTest2 { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPairLevel1 = null; + public KeyPair keyPairLevel2 = null; + + public IUicRailTicket testFCBticket = null; + + public Provider provider = null; + + + @Before public void initialize() { + + LoggerFactory.setActivateConsoleLog(true); + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256k1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + provider = new BouncyCastleProvider(); + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPairLevel1 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + keyPairLevel2 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + } catch (Exception e) { + assert(false); + } + + assert(keyPairLevel1 != null); + + assert(keyPairLevel2 != null); + + } + + + + @Test public void testDynamicHeaderBarcodeDecoding() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 13); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.setLevel1Algs(signatureAlgorithmOID, keyPairAlgorithmOID); + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID,keyPairLevel2.getPublic()); + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + assert(enc != null); + + + IData level2Data = Level2TestDataFactory.getLevel2SimpleTestData(); + try { + enc.setLevel2Data(level2Data); + enc.signLevel2(keyPairLevel2.getPrivate()); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(), null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + signatureCheck = 0; + try { + signatureCheck = dec.validateLevel2(); + } catch (Exception e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL2_VALIDATION_OK); + + IData level2DataDec = dec.getLevel2Data(); + + assert(level2Data.getFormat().equals(level2DataDec.getFormat())); + assert(Arrays.equals(level2Data.getData(),level2DataDec.getData())); + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + } + + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + //ECNamedCurveGenParameterSpec namedParamSpec = new ECNamedCurveGenParameterSpec(elipticCurve); + + ECGenParameterSpec namedParamSpec = new ECGenParameterSpec(elipticCurve); + KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("ECDSA", "BC"); + ecKPGen.initialize(namedParamSpec, new SecureRandom()); + KeyPair keyPair = ecKPGen.generateKeyPair(); + KeyPair kp = new KeyPair(SecurityUtils.convert(keyPair.getPublic(), provider),SecurityUtils.convert(keyPair.getPrivate(), provider)); + return kp; + } + + +} diff --git a/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureCurve2Test.java b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureCurve2Test.java new file mode 100644 index 0000000..f118026 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/DynamicFrameDoubleSignatureCurve2Test.java @@ -0,0 +1,167 @@ +package org.uic.barcode.test; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SignatureException; +import java.security.spec.ECGenParameterSpec; +import java.util.Arrays; +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.dynamicFrame.api.IData; +import org.uic.barcode.logger.LoggerFactory; +import org.uic.barcode.test.utils.Level2TestDataFactory; +import org.uic.barcode.test.utils.SimpleUICTestTicket; +import org.uic.barcode.ticket.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; +import org.uic.barcode.utils.SecurityUtils; + +public class DynamicFrameDoubleSignatureCurve2Test { + + public String signatureAlgorithmOID = null; + public String elipticCurve = null; + public String keyPairAlgorithmOID = null; + + public KeyPair keyPairLevel1 = null; + public KeyPair keyPairLevel2 = null; + + public IUicRailTicket testFCBticket = null; + + public Provider provider = null; + + + @Before public void initialize() { + + LoggerFactory.setActivateConsoleLog(true); + + signatureAlgorithmOID = Constants.ECDSA_SHA256; + keyPairAlgorithmOID = Constants.KG_EC_256; + elipticCurve = "secp256r1"; + + testFCBticket = SimpleUICTestTicket.getUicTestTicket(); + + provider = new BouncyCastleProvider(); + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPairLevel1 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + keyPairLevel2 = generateECKeys(keyPairAlgorithmOID, elipticCurve); + } catch (Exception e) { + assert(false); + } + + assert(keyPairLevel1 != null); + + assert(keyPairLevel2 != null); + + } + + + + @Test public void testDynamicHeaderBarcodeDecoding() { + + IUicRailTicket ticket = testFCBticket; + + Encoder enc = null; + + try { + enc = new Encoder(ticket, null, Encoder.UIC_BARCODE_TYPE_DOSIPAS, 1, 13); + } catch (IOException | EncodingFormatException e1) { + assert(false); + } + + assert(enc != null); + + try { + enc.setLevel1Algs(signatureAlgorithmOID, keyPairAlgorithmOID); + enc.setLevel2Algs(signatureAlgorithmOID, keyPairAlgorithmOID,keyPairLevel2.getPublic()); + enc.signLevel1("1080", keyPairLevel1.getPrivate(), signatureAlgorithmOID, "1"); + } catch (Exception e) { + assert(false); + } + + assert(enc != null); + + + IData level2Data = Level2TestDataFactory.getLevel2SimpleTestData(); + try { + enc.setLevel2Data(level2Data); + enc.signLevel2(keyPairLevel2.getPrivate()); + } catch (Exception e) { + assert(false); + } + + + byte[] encoded = null; + try { + encoded = enc.encode(); + } catch (Exception e) { + assert(false); + } + + assert(encoded != null); + + Decoder dec = null; + try { + dec = new Decoder(encoded); + } catch (IOException e) { + assert(false); + } catch (EncodingFormatException e) { + assert(false); + } catch (DataFormatException e) { + assert(false); + } + assert(dec != null); + + int signatureCheck = 0; + try { + signatureCheck = dec.validateLevel1(keyPairLevel1.getPublic(), null); + } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException | IllegalArgumentException + | UnsupportedOperationException | IOException | EncodingFormatException e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL1_VALIDATION_OK); + + signatureCheck = 0; + try { + signatureCheck = dec.validateLevel2(); + } catch (Exception e) { + assert(false); + } + assert(signatureCheck == Constants.LEVEL2_VALIDATION_OK); + + IData level2DataDec = dec.getLevel2Data(); + + assert(level2Data.getFormat().equals(level2DataDec.getFormat())); + assert(Arrays.equals(level2Data.getData(),level2DataDec.getData())); + + SimpleUICTestTicket.compare(ticket, dec.getUicTicket()); + + } + + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + //ECNamedCurveGenParameterSpec namedParamSpec = new ECNamedCurveGenParameterSpec(elipticCurve); + + ECGenParameterSpec namedParamSpec = new ECGenParameterSpec(elipticCurve); + KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("EC", "BC"); + ecKPGen.initialize(namedParamSpec, new SecureRandom()); + KeyPair keyPair = ecKPGen.generateKeyPair(); + KeyPair kp = new KeyPair(SecurityUtils.convert(keyPair.getPublic(), provider),SecurityUtils.convert(keyPair.getPrivate(), provider)); + return kp; + } + + +} diff --git a/src/test/java/org/uic/barcode/test/SecurityUtilsTest.java b/src/test/java/org/uic/barcode/test/SecurityUtilsTest.java new file mode 100644 index 0000000..e500523 --- /dev/null +++ b/src/test/java/org/uic/barcode/test/SecurityUtilsTest.java @@ -0,0 +1,222 @@ +package org.uic.barcode.test; + +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.ECGenParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Before; +import org.junit.Test; +import org.uic.barcode.dynamicFrame.Constants; +import org.uic.barcode.utils.AlgorithmNameResolver; +import org.uic.barcode.utils.SecurityUtils; + +public class SecurityUtilsTest { + + + + public KeyPair keyPairCk = null; + public KeyPair keyPairCr = null; + public KeyPair keyPairDsa = null; + public KeyPair keyPairECDSACk = null; + public KeyPair keyPairECDSACr = null; + + + public Provider provider = null; + + + @Before public void initialize() { + + provider = new BouncyCastleProvider(); + Security.addProvider(new BouncyCastleProvider()); + + try { + keyPairCk = generateECKeys(Constants.KG_EC_256, "secp256k1"); + keyPairCr = generateECKeys(Constants.KG_EC_256, "secp256r1"); + keyPairECDSACk = generateECDSAKeys(Constants.KG_EC_256, "secp256k1"); + keyPairECDSACr = generateECDSAKeys(Constants.KG_EC_256, "secp256r1"); + keyPairDsa = generateDsaKeys(); + } catch (Exception e) { + assert(false); + } + + assert(keyPairCk != null); + + assert(keyPairCr != null); + + assert(keyPairDsa != null); + + } + + + + + + + @Test public void testFindPublicKeyProvider() { + + + Provider p = null; + boolean canSign = false; + + p = SecurityUtils.findPublicKeyProvider(Constants.KG_EC_256,keyPairCk.getPublic().getEncoded()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairCk.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPublicKeyProvider(Constants.KG_EC_256,keyPairCr.getPublic().getEncoded()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairCr.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPublicKeyProvider(Constants.KG_EC_256,keyPairECDSACk.getPublic().getEncoded()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairECDSACk.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPublicKeyProvider(Constants.KG_EC_256,keyPairECDSACr.getPublic().getEncoded()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairECDSACr.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPublicKeyProvider("1.2.840.10040",keyPairDsa.getPublic().getEncoded()); + assert (p != null); + canSign = testSignature(p,Constants.DSA_SHA256,keyPairDsa.getPrivate()); + assert(canSign == true); + + } + + + + + + + @Test public void testFindSignatureAlgorithmProvider() { + + Provider p = null; + boolean canSign = false; + + p = SecurityUtils.findPrivateKeyProvider(keyPairCk.getPrivate()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairCk.getPrivate()); + assert(canSign == true); + + + p = SecurityUtils.findPrivateKeyProvider(keyPairCr.getPrivate()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairCr.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPrivateKeyProvider(keyPairECDSACk.getPrivate()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairECDSACk.getPrivate()); + assert(canSign == true); + + + p = SecurityUtils.findPrivateKeyProvider(keyPairECDSACr.getPrivate()); + assert (p != null); + canSign = testSignature(p,Constants.ECDSA_SHA256,keyPairECDSACr.getPrivate()); + assert(canSign == true); + + p = SecurityUtils.findPrivateKeyProvider(keyPairDsa.getPrivate()); + assert (p != null); + canSign = testSignature(p,Constants.DSA_SHA256,keyPairDsa.getPrivate()); + assert(canSign == true); + + + } + + + public KeyPair generateECKeys(String keyAlgorithmOid, String curve) throws Exception{ + + //ECNamedCurveGenParameterSpec namedParamSpec = new ECNamedCurveGenParameterSpec(elipticCurve); + + ECGenParameterSpec namedParamSpec = new ECGenParameterSpec(curve); + KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("EC", "BC"); + ecKPGen.initialize(namedParamSpec, new SecureRandom()); + KeyPair keyPair = ecKPGen.generateKeyPair(); + KeyPair kp = new KeyPair(SecurityUtils.convert(keyPair.getPublic(), provider),SecurityUtils.convert(keyPair.getPrivate(), provider)); + return kp; + } + + public KeyPair generateECDSAKeys(String keyAlgorithmOid, String curve) throws Exception{ + + //ECNamedCurveGenParameterSpec namedParamSpec = new ECNamedCurveGenParameterSpec(elipticCurve); + + ECGenParameterSpec namedParamSpec = new ECGenParameterSpec(curve); + KeyPairGenerator ecKPGen = KeyPairGenerator.getInstance("ECDSA", "BC"); + ecKPGen.initialize(namedParamSpec, new SecureRandom()); + KeyPair keyPair = ecKPGen.generateKeyPair(); + KeyPair kp = new KeyPair(SecurityUtils.convert(keyPair.getPublic(), provider),SecurityUtils.convert(keyPair.getPrivate(), provider)); + return kp; + } + + private KeyPair generateDsaKeys() { + + KeyPairGenerator g = null; + try { + g = KeyPairGenerator.getInstance("DSA", "BC"); + } catch (NoSuchAlgorithmException e) { + assert(false); + } catch (NoSuchProviderException e) { + assert(false); + } + g.initialize(1024, new SecureRandom()); + + KeyPair keyPair = g.generateKeyPair(); + KeyPair kp = new KeyPair(SecurityUtils.convert(keyPair.getPublic(), provider),SecurityUtils.convert(keyPair.getPrivate(), provider)); + return kp; + + } + + private boolean testSignature(Provider provider, String signatureAlgorithmOid, PrivateKey privateKey) { + + String sigAlgName = null; + try { + sigAlgName = AlgorithmNameResolver.getSignatureAlgorithmName(signatureAlgorithmOid,provider); + } catch (Exception e) { + assert(false); + } + assert(sigAlgName != null); + + + Signature sig = null; + try { + sig = Signature.getInstance(sigAlgName,provider); + } catch (Exception e) { + assert (false); + } + + try { + sig.initSign(privateKey); + } catch (InvalidKeyException e) { + assert(false); + } + try { + sig.update("ABCDEFGHI".getBytes()); + } catch (SignatureException e) { + assert(false); + } + byte[] signature = null; + try { + signature = sig.sign(); + } catch (SignatureException e) { + assert(false); + } + + assert(signature != null); + assert(signature.length > 5); + + return true; + } + + +} diff --git a/src/test/java/org/uic/barcode/ticket/api/test/DelayConfirmationTestV3.java b/src/test/java/org/uic/barcode/ticket/api/test/DelayConfirmationTestV3.java new file mode 100644 index 0000000..840c4c7 --- /dev/null +++ b/src/test/java/org/uic/barcode/ticket/api/test/DelayConfirmationTestV3.java @@ -0,0 +1,180 @@ +package org.uic.barcode.ticket.api.test; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +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.EncodingFormatException; +import org.uic.barcode.ticket.api.spec.IDelayConfirmation; +import org.uic.barcode.ticket.api.spec.IDocumentData; +import org.uic.barcode.ticket.api.spec.ILinkMode; +import org.uic.barcode.ticket.api.spec.ITicketLink; +import org.uic.barcode.ticket.api.spec.ITicketType; +import org.uic.barcode.ticket.api.spec.IUicRailTicket; +import org.uic.barcode.ticket.api.test.testtickets.DelayTestTicketV3; +import org.uic.barcode.ticket.api.utils.Api2AsnEncoder; +import org.uic.barcode.ticket.api.utils.Api2OpenAsnEncoderV3; +import org.uic.barcode.ticket.api.utils.Asn2ApiDecoder; +import org.uic.barcode.ticket.api.utils.OpenAsn2ApiDecoderV3; + + +/** + * The Class VoucherTestV1. + * + * + * + */ +public class DelayConfirmationTestV3 { + + + /** The decoder. */ + Asn2ApiDecoder decoder = new OpenAsn2ApiDecoderV3(); + + /** The encoder. */ + Api2AsnEncoder encoder = new Api2OpenAsnEncoderV3(); + + /** The API ticket low level encoded for case 1. */ + IUicRailTicket iTicketDecodedFromAsn1Case1 = null; + + + /** The ticket decoded 1. */ + IUicRailTicket iTicketDecodedCase1 = null; + + byte[] encodedInTimeZone1 = null; + + + TimeZone defaulttimeZone = null; + + /** + * Prepare tickets. + */ + @Before public void prepare() { + + LoggerFactory.setActivateConsoleLog(true); + + defaulttimeZone = TimeZone.getDefault(); + + + } + + /** + * 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 testDelayConfirmation() throws IllegalArgumentException, IllegalAccessException, ParseException { + + //get tickets + + defaulttimeZone = TimeZone.getDefault(); + + //encode in UTC time zone + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + IUicRailTicket ticketDecoded = null; + try { + ticketDecoded = decoder.decodeFromAsn(DelayTestTicketV3.getEncodingBytes()); + } catch (IOException e) { + assert(false); + } + + IDocumentData document = ticketDecoded.getDocumentData().iterator().next(); + assert(document != null); + assert(document instanceof IDelayConfirmation); + + IDelayConfirmation del = (IDelayConfirmation) document; + assert(del.getDelay() == 31); + + /* + * + referenceIA5 "ABDJ12345", + trainNum 100, + departureYear 2022, + departureDay 12, + departureTime 1000, + stationCodeTable stationUIC, + stationNum 8000001, + delay 31, + trainCancelled FALSE, + confirmationType travelerDelayConfirmation, + affectedTickets { + { + referenceNum 801234567890, + productOwnerNum 1080, + ticketType openTicket, + linkMode issuedTogether + } + }, + infoText "delay confirmation" + */ + + assert(del.getLinkedTickets().size() == 1); + assert(del.getDelay() == 31L); + assert(del.isTrainCancelled() == false); + assert(del.getInfoText().equals("delay confirmation")); + assert(del.getReference().equals("ABDJ12345")); + assert(del.getTrain().equals("100")); + + + ITicketLink tl = del.getLinkedTickets().iterator().next(); + assert(tl.getReference().equals("801234567890")); + assert(tl.getProductOwner().equals("1080")); + assert(tl.getTicketType().equals(ITicketType.openTicket)); + assert(tl.getLinkMode().equals(ILinkMode.issuedTogether)); + + TimeZone current = TimeZone.getDefault(); + DateFormat dateFormat = new SimpleDateFormat( "yyyy.MM.dd-HH:mm" ); + String pd = dateFormat.format(del.getArrivalDate()); + assert(pd.equals("2022.01.12-16:40")); + TimeZone.setDefault(current); + + //encode in UTC time zone + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + byte[] encoded = null; + try { + encoded = encoder.encode(ticketDecoded); + } catch (EncodingFormatException e) { + assert(false); + } + + + IUicRailTicket ticketDecoded2 = null; + try { + ticketDecoded2 = decoder.decodeFromAsn(encoded); + } catch (IOException e) { + assert(false); + } + + assert (ticketDecoded2 != null); + + String hex1 = UperEncoder.hexStringFromBytes(encoded); + String hex2 = DelayTestTicketV3.getEncodingHex(); + assert(hex1.equals(hex2)); + + + + + TimeZone.setDefault(defaulttimeZone); + } + + + +} diff --git a/src/test/java/org/uic/barcode/ticket/api/test/testtickets/DelayTestTicketV3.java b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/DelayTestTicketV3.java index a74ad18..5285f03 100644 --- a/src/test/java/org/uic/barcode/ticket/api/test/testtickets/DelayTestTicketV3.java +++ b/src/test/java/org/uic/barcode/ticket/api/test/testtickets/DelayTestTicketV3.java @@ -1,6 +1,7 @@ package org.uic.barcode.ticket.api.test.testtickets; import org.uic.barcode.asn1.datatypes.Asn1BigInteger; +import org.uic.barcode.asn1.uper.UperEncoder; 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; @@ -121,6 +122,15 @@ value UicRailTicketData ::= { } + public static byte[] getEncodingBytes() { + + String hex = getEncodingHex(); + + return UperEncoder.bytesFromHexString(hex); + + + } + private static void populateTicket(UicRailTicketData ticket) { -- cgit v1.2.3