From 62a1d25fa350f1c38f5d47be87d47b615eeb5949 Mon Sep 17 00:00:00 2001 From: Tobias Senger Date: Sat, 2 Nov 2024 15:23:54 +0100 Subject: [PATCH] changed getFeature method, prepared v0.6.0 --- README.md | 16 ++--- pom.xml | 2 +- .../de/tsenger/vdstools/vds/DigitalSeal.java | 7 +- .../java/de/tsenger/vdstools/vds/Feature.java | 33 +++++++++ .../de/tsenger/vdstools/vds/VdsMessage.java | 25 ++++--- .../tsenger/vdstools/vds/DigitalSealTest.java | 72 +++++++++++-------- src/test/resources/SealCodings.json | 23 ++++++ 7 files changed, 128 insertions(+), 50 deletions(-) create mode 100644 src/main/java/de/tsenger/vdstools/vds/Feature.java diff --git a/README.md b/README.md index e1dcae1..f34141f 100644 --- a/README.md +++ b/README.md @@ -18,19 +18,19 @@ Here is a quick overview how to use the VDS parser and verifier. When you have the decoded raw string or raw bytes from your favorite datamatrix decoder, just put them to the VDS Tools Dataparser like this: ```java -import de.tsenger.vdstools.DataParser; import de.tsenger.vdstools.Verifier; -import de.tsenger.vdstools.seals.DigitalSeal; -import de.tsenger.vdstools.seals.VdsType; -import de.tsenger.vdstools.seals.Feature; +import de.tsenger.vdstools.vds.DigitalSeal; ... DigitalSeal digitalSeal = DigitalSeal.fromByteArray(rawBytes); String vdsType = digitalSeal.getVdsType() - // Depending on the returned VDS type you can access the seals content - String mrz = seal.getFeature("MRZ"); - String azr = seal.getFeature("AZR"); + // getFeature() returns an Optional which can be used as follows + String mrz = digitalSeal.getFeature("MRZ").get().asString(); + String azr = digitalSeal.getFeature("AZR").get().asString(); + if (seal.getFeature("FACE_IMAGE").isPresent()) { + byte[] imgBytes = digitalSeal.getFeature("FACE_IMAGE").get().asByteArray(); + } // Get the VDS signer certificate reference String signerCertRef = digitalSeal.getSignerCertRef(); @@ -43,7 +43,7 @@ import de.tsenger.vdstools.seals.Feature; ``` -Also have a look at [DataParserTest.java](https://github.com/tsenger/vdstools/blob/main/src/test/java/de/tsenger/vdstools/DataParserTest.java) and [VerifierTest.java](https://github.com/tsenger/vdstools/blob/main/src/test/java/de/tsenger/vdstools/VerifierTest.java) for some more examples. +Also have a look at [DigitalSealTest.java](https://github.com/tsenger/vdstools/blob/main/src/test/java/de/tsenger/vdstools/vds/DigitalSealTest.java) and [VerifierTest.java](https://github.com/tsenger/vdstools/blob/main/src/test/java/de/tsenger/vdstools/VerifierTest.java) for some more examples. ## Build a new VDS Since version 0.3.0 you can also generate VDS with this library. Here is an example on how to use the DateEncoder and Signer classes: diff --git a/pom.xml b/pom.xml index ed2d515..228d5c1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ de.tsenger vdstools - 0.5.1 + 0.6.0 Visible Digital Seal Tools Java library A Java library to encode/sign and decode/verify Visible Digital Seals jar diff --git a/src/main/java/de/tsenger/vdstools/vds/DigitalSeal.java b/src/main/java/de/tsenger/vdstools/vds/DigitalSeal.java index 8529619..5fe2376 100644 --- a/src/main/java/de/tsenger/vdstools/vds/DigitalSeal.java +++ b/src/main/java/de/tsenger/vdstools/vds/DigitalSeal.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; @@ -107,11 +108,11 @@ public String getRawString() throws IOException { return DataEncoder.encodeBase256(getEncoded()); } - public Map getFeatures() { - return vdsMessage.getFeatures(); + public Map getFeatureMap() { + return vdsMessage.getFeatureMap(); } - public T getFeature(String feature) { + public Optional getFeature(String feature) { return vdsMessage.getFeature(feature); } diff --git a/src/main/java/de/tsenger/vdstools/vds/Feature.java b/src/main/java/de/tsenger/vdstools/vds/Feature.java new file mode 100644 index 0000000..668d7f7 --- /dev/null +++ b/src/main/java/de/tsenger/vdstools/vds/Feature.java @@ -0,0 +1,33 @@ +package de.tsenger.vdstools.vds; + +import java.nio.charset.StandardCharsets; + +public class Feature { + private final Object value; + + public Feature(Object value) { + this.value = value; + } + + public boolean isEmpty() { + return value == null; + } + + public String asString() { + if (value instanceof String) { + return (String) value; + } else if (value instanceof byte[]) { + // Konvertiere byte[] in UTF-8-String + return new String((byte[]) value, StandardCharsets.UTF_8); + } + return null; + } + + public byte[] asByteArray() { + return (byte[]) value; + } + + public int asInteger() { + return ((byte[]) value)[0]; + } +} diff --git a/src/main/java/de/tsenger/vdstools/vds/VdsMessage.java b/src/main/java/de/tsenger/vdstools/vds/VdsMessage.java index 6d6b4d3..ad3e478 100644 --- a/src/main/java/de/tsenger/vdstools/vds/VdsMessage.java +++ b/src/main/java/de/tsenger/vdstools/vds/VdsMessage.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.tinylog.Logger; @@ -53,25 +54,29 @@ public List getDerTlvList() { return this.derTlvList; } - public Map getFeatures() { - Map featureMap = new HashMap(); + public Map getFeatureMap() { + Map featureMap = new HashMap(); for (DerTlv derTlv : derTlvList) { - T value = DataEncoder.getFeatureEncoder().decodeFeature(vdsType, derTlv); + Object value = DataEncoder.getFeatureEncoder().decodeFeature(vdsType, derTlv); String key = DataEncoder.getFeatureEncoder().getFeatureName(vdsType, derTlv); - featureMap.put(key, value); + if (value != null) + featureMap.put(key, new Feature(value)); } return featureMap; } - public T getFeature(String feature) { - T value = null; + public Optional getFeature(String feature) { + Object value = null; byte tag = DataEncoder.getFeatureEncoder().getTag(vdsType, feature); - for (DerTlv derTlv : derTlvList) { - if (derTlv.getTag() == tag) { - value = DataEncoder.getFeatureEncoder().decodeFeature(vdsType, derTlv); + if (tag != 0) { + for (DerTlv derTlv : derTlvList) { + if (derTlv.getTag() == tag) { + value = DataEncoder.getFeatureEncoder().decodeFeature(vdsType, derTlv); + break; + } } } - return value; + return Optional.ofNullable(value != null ? new Feature(value) : null); } public static VdsMessage fromByteArray(byte[] rawBytes, String vdsType) { diff --git a/src/test/java/de/tsenger/vdstools/vds/DigitalSealTest.java b/src/test/java/de/tsenger/vdstools/vds/DigitalSealTest.java index 0e976f2..92fcd8f 100644 --- a/src/test/java/de/tsenger/vdstools/vds/DigitalSealTest.java +++ b/src/test/java/de/tsenger/vdstools/vds/DigitalSealTest.java @@ -1,8 +1,8 @@ package de.tsenger.vdstools.vds; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.FileInputStream; @@ -47,89 +47,105 @@ public static void loadKeyStore() throws NoSuchAlgorithmException, CertificateEx public void testParseSocialInsurranceCard() throws IOException { DigitalSeal seal = DigitalSeal.fromByteArray(VdsRawBytes.socialInsurance); assertEquals("SOCIAL_INSURANCE_CARD", seal.getVdsType()); - assertEquals("65170839J003", seal.getFeature("SOCIAL_INSURANCE_NUMBER")); - assertEquals("Perschweiß", seal.getFeature("SURNAME")); - assertEquals("Oscar", seal.getFeature("FIRST_NAME")); - assertEquals("Jâcobénidicturius", seal.getFeature("BIRTH_NAME")); + assertEquals("65170839J003", seal.getFeature("SOCIAL_INSURANCE_NUMBER").get().asString()); + assertEquals("Perschweiß", seal.getFeature("SURNAME").get().asString()); + assertEquals("Oscar", seal.getFeature("FIRST_NAME").get().asString()); + assertEquals("Jâcobénidicturius", seal.getFeature("BIRTH_NAME").get().asString()); } @Test public void testParseArrivalAttestationV02() throws IOException { DigitalSeal seal = DigitalSeal.fromByteArray(VdsRawBytes.arrivalAttestationV02); assertEquals("MED<