From 82cc7f2de863e18168b8def02411dbdbf0c577b7 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Thu, 10 Oct 2024 09:57:43 -0500 Subject: [PATCH 01/15] docs: add changelog --- CHANGELOG.md | 36 ++++++++++++++++++++++++++++++++++++ README.md | 9 --------- pom.xml | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3d79a47 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +## [2.0.12](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.12) (2024-10-11) + + +### Features + +* Add eMRTD commands to NFC reading ([a0bc1a4]()) + +## [2.0.11](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.11) (2024-10-07) + + +### Features + +* Add I18n manager ([a0bc1a4](https://github.com/2060-io/2060-service-agent-java-client/commit/a0bc1a4dd265abe4670afa14a5c2003a5a248621)) + +## [2.0.10](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.10) (2024-10-02) + + +### Features + +* Add mrz message parameters ([5dc9cd1](https://github.com/2060-io/2060-service-agent-java-client/commit/5dc9cd16635bcc3605b9ee66d1e2425d37396117)) + +## [2.0.9](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.9) (2024-10-01) + + +### Features + +* Add profile message parameters ([63d65f3](https://github.com/2060-io/2060-service-agent-java-client/commit/63d65f3143ade06b8c2f3c571d34b589bde76699)) + +## [2.0.8](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.8) (2024-09-27) + + +### Features + +* Add call's command ([471ed0f](https://github.com/2060-io/2060-service-agent-java-client/commit/471ed0f17f89ae8906de9c5e6299396fc9cacce2)) \ No newline at end of file diff --git a/README.md b/README.md index 6b3ea0e..1e8419c 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,6 @@ Client tools for building Quarkus java DIDcomm Verifiable Credential powered con - On dev mode use the command `mvn clean install -Dgpg.skip` to run the project - To apply format run `mvn fmt:format` -## Releases - -| Version | Release Date | Type of Change | Description | -|---------|--------------|---------------------|-----------------------------------------------------------------------------| -| 2.0.11 | 2024-10-07 | Patch | - add I18n manager | -| 2.0.10 | 2024-10-02 | Patch | - add mrz message parameters | -| 2.0.9 | 2024-10-01 | Patch | - add profile message parameters | -| 2.0.8 | 2024-09-27 | Patch | - add call's command | - ## License diff --git a/pom.xml b/pom.xml index 0e784af..39c3e8f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.2060 service-agent-java-client - 2.0.11 + 2.0.12 UTF-8 17 From 55b79378c9416c8b1aee6f98e2ee3eb29d268fbb Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Thu, 10 Oct 2024 10:29:23 -0500 Subject: [PATCH 02/15] feat: add new messages --- .../sa/client/model/message/BaseMessage.java | 6 ++++- .../message/mrtd/EMrtdDataRequestMessage.java | 21 +++++++++++++++++ .../message/mrtd/EMrtdDataSubmitMessage.java | 23 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java create mode 100644 src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java diff --git a/src/main/java/io/twentysixty/sa/client/model/message/BaseMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/BaseMessage.java index d7be6be..dd4c577 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/BaseMessage.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/BaseMessage.java @@ -13,6 +13,8 @@ import io.twentysixty.sa.client.model.message.calls.CallEndRequestMessage; import io.twentysixty.sa.client.model.message.calls.CallOfferRequestMessage; import io.twentysixty.sa.client.model.message.calls.CallRejectRequestMessage; +import io.twentysixty.sa.client.model.message.mrtd.EMrtdDataRequestMessage; +import io.twentysixty.sa.client.model.message.mrtd.EMrtdDataSubmitMessage; import io.twentysixty.sa.client.model.message.mrtd.MrzDataRequestMessage; import io.twentysixty.sa.client.model.message.mrtd.MrzDataSubmitMessage; import io.twentysixty.sa.client.util.InstantDeserializer; @@ -47,7 +49,9 @@ @Type(value = CallOfferRequestMessage.class, name = "call-offer"), @Type(value = CallRejectRequestMessage.class, name = "call-reject"), @Type(value = MrzDataRequestMessage.class, name = "mrz-data-request"), - @Type(value = MrzDataSubmitMessage.class, name = "mrz-data-submit") + @Type(value = MrzDataSubmitMessage.class, name = "mrz-data-submit"), + @Type(value = EMrtdDataRequestMessage.class, name = "emrtd-data-request"), + @Type(value = EMrtdDataSubmitMessage.class, name = "emrtd-data-submit") }) public abstract class BaseMessage implements Serializable { diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java new file mode 100644 index 0000000..2abc9cf --- /dev/null +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java @@ -0,0 +1,21 @@ +package io.twentysixty.sa.client.model.message.mrtd; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import io.twentysixty.sa.client.model.message.BaseMessage; +import java.util.UUID; + +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class EMrtdDataRequestMessage extends BaseMessage { + + private static final long serialVersionUID = -2840211856886673672L; + + public static EMrtdDataRequestMessage build(UUID connectionId, UUID threadId) { + EMrtdDataRequestMessage mrzr = new EMrtdDataRequestMessage(); + mrzr.setConnectionId(connectionId); + mrzr.setThreadId(threadId); + return mrzr; + } +} diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java new file mode 100644 index 0000000..ab5f945 --- /dev/null +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java @@ -0,0 +1,23 @@ +package io.twentysixty.sa.client.model.message.mrtd; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import io.twentysixty.sa.client.model.message.BaseMessage; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter +@ToString +public class EMrtdDataSubmitMessage extends BaseMessage { + + private static final long serialVersionUID = -2840411856886673672L; + + private Map dataGroups; +} From c3781492cd84f6f2eade5d59f3686b35f0bc8906 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Thu, 10 Oct 2024 10:30:42 -0500 Subject: [PATCH 03/15] fix: add clean phase to fmt --- pom.xml | 1 + .../sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 39c3e8f..d86f295 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,7 @@ format + clean diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java index ab5f945..06b50ae 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java @@ -1,11 +1,10 @@ package io.twentysixty.sa.client.model.message.mrtd; -import java.util.Map; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import io.twentysixty.sa.client.model.message.BaseMessage; +import java.util.Map; import lombok.Getter; import lombok.Setter; import lombok.ToString; From ebde40bcbb9ce76968e53f02d4c020edcd7cd72c Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Thu, 10 Oct 2024 20:06:41 -0500 Subject: [PATCH 04/15] feat: add randomCipheringData --- .../sa/client/model/message/Ciphering.java | 27 +++++-------------- .../sa/client/model/message/Parameters.java | 27 +++++-------------- .../twentysixty/sa/client/util/Aes256cbc.java | 21 +++++++++++++++ 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/Ciphering.java b/src/main/java/io/twentysixty/sa/client/model/message/Ciphering.java index 8996835..3d68e35 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/Ciphering.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/Ciphering.java @@ -1,31 +1,16 @@ package io.twentysixty.sa.client.model.message; import java.io.Serializable; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +@Setter +@Getter +@ToString public class Ciphering implements Serializable { private static final long serialVersionUID = -8660299956191649637L; private String algorithm; private Parameters parameters; - - public String getAlgorithm() { - return algorithm; - } - - public void setAlgorithm(String algorithm) { - this.algorithm = algorithm; - } - - public Parameters getParameters() { - return parameters; - } - - public void setParameters(Parameters parameters) { - this.parameters = parameters; - } - - @Override - public String toString() { - return "Ciphering [algorithm=" + algorithm + ", parameters=" + parameters + "]"; - } } diff --git a/src/main/java/io/twentysixty/sa/client/model/message/Parameters.java b/src/main/java/io/twentysixty/sa/client/model/message/Parameters.java index a053af0..86e83d4 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/Parameters.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/Parameters.java @@ -1,31 +1,16 @@ package io.twentysixty.sa.client.model.message; import java.io.Serializable; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +@Setter +@Getter +@ToString public class Parameters implements Serializable { private static final long serialVersionUID = -3591319454008944749L; private String key; private String iv; - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getIv() { - return iv; - } - - public void setIv(String iv) { - this.iv = iv; - } - - @Override - public String toString() { - return "Parameters [key=" + key + ", iv=" + iv + "]"; - } } diff --git a/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java b/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java index 65502f2..e4ad753 100644 --- a/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java +++ b/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java @@ -1,6 +1,10 @@ package io.twentysixty.sa.client.util; +import io.twentysixty.sa.client.model.message.Ciphering; +import io.twentysixty.sa.client.model.message.Parameters; import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.jboss.logging.Logger; @@ -40,4 +44,21 @@ public static byte[] decrypt(String key, String iv, byte[] encrypted) throws Exc byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } + + public static Ciphering randomCipheringData() throws Exception { + Ciphering c = new Ciphering(); + Parameters p = new Parameters(); + p.setKey(randomKey(32)); + p.setIv(randomKey(16)); + c.setAlgorithm(cI); + c.setParameters(p); + return c; + } + + private static String randomKey(int size) throws Exception { + KeyGenerator keyGen = KeyGenerator.getInstance(alg); + keyGen.init(size * 8); + SecretKey secretKey = keyGen.generateKey(); + return ISOUtil.dumpString(secretKey.getEncoded()); + } } From c7d85f5c80f890c9c8c0cc8b2cf54fb5d09ef6b2 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Fri, 18 Oct 2024 08:34:17 -0500 Subject: [PATCH 05/15] fix: add randomCipheringData --- src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java b/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java index e4ad753..3de2893 100644 --- a/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java +++ b/src/main/java/io/twentysixty/sa/client/util/Aes256cbc.java @@ -59,6 +59,6 @@ private static String randomKey(int size) throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance(alg); keyGen.init(size * 8); SecretKey secretKey = keyGen.generateKey(); - return ISOUtil.dumpString(secretKey.getEncoded()); + return ISOUtil.hexString(secretKey.getEncoded()); } } From 00b3fba41e62ec481e977b0be32056d66efb6a2f Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Fri, 18 Oct 2024 08:39:02 -0500 Subject: [PATCH 06/15] docs: changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d79a47..344c485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Changelog -## [2.0.12](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.12) (2024-10-11) +## [2.0.12](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.12) (2024-10-18) ### Features -* Add eMRTD commands to NFC reading ([a0bc1a4]()) +* Add eMRTD commands to NFC reading ([55b7937](https://github.com/2060-io/2060-service-agent-java-client/pull/19/commits/55b79378c9416c8b1aee6f98e2ee3eb29d268fbb)) +* Add randomCipheringData method ([c7d85f5](https://github.com/2060-io/2060-service-agent-java-client/pull/19/commits/c7d85f5c80f890c9c8c0cc8b2cf54fb5d09ef6b2)) ## [2.0.11](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.11) (2024-10-07) From 468ea4934be6e778346667374a6ff21871c0eee1 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 15:34:59 -0500 Subject: [PATCH 07/15] feat: implement EMrtdData in dataGroups --- .../client/model/message/mrtd/EMrtdData.java | 33 ++ .../message/mrtd/EMrtdDataSubmitMessage.java | 3 +- .../model/message/mrtd/ParsedEMrtdData.java | 339 ++++++++++++++++++ 3 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java create mode 100644 src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java new file mode 100644 index 0000000..f3561e5 --- /dev/null +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java @@ -0,0 +1,33 @@ +package io.twentysixty.sa.client.model.message.mrtd; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import java.io.Serializable; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter +@ToString +public class EMrtdData implements Serializable { + + private static final long serialVersionUID = -5234275638176689315L; + + private Map raw; + private ParsedData parsed; + + @Getter + @Setter + @ToString + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ParsedData { + private ParsedEMrtdData fields; + private boolean valid; + } +} diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java index 06b50ae..8042cc1 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataSubmitMessage.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import io.twentysixty.sa.client.model.message.BaseMessage; -import java.util.Map; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -18,5 +17,5 @@ public class EMrtdDataSubmitMessage extends BaseMessage { private static final long serialVersionUID = -2840411856886673672L; - private Map dataGroups; + private EMrtdData dataGroups; } diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java new file mode 100644 index 0000000..d62977e --- /dev/null +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java @@ -0,0 +1,339 @@ +package io.twentysixty.sa.client.model.message.mrtd; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ParsedEMrtdData { + private DecodedCom com; + private String mrzData; + private List images; + private List fingerprints; + private List iris; + private List displayedImages; + private List signatureImages; + private DecodedAdditionalPersonalData additionalPersonalData; + private DecodedAdditionalDocumentData additionalDocumentData; + private Map securityInfos; + private Map subjectPublicKeyInfo; + private DecodedSecurtyObjectOfDocument securityObjectOfDocument; + private CSCAMasterList cscaMasterList; + + public List getImagesAsBytes() { + return convertToBytesList(images, DecodedImage::getImageData); + } + + public String getImageType(Object image) { + if (image instanceof DecodedImage) { + return getMimeType(((DecodedImage) image).getImageType()); + } else if (image instanceof DecodedFingerprint) { + return getMimeType(((DecodedFingerprint) image).getFingerImageType()); + } + return "image/jpg"; +} + +private String getMimeType(Object imageType) { + if (imageType instanceof FingerprintImageType && imageType == FingerprintImageType.JPEG2000 + || imageType instanceof ImageType && imageType == ImageType.JPEG2000) { + return "image/jp2"; + } else if (imageType instanceof FingerprintImageType && imageType == FingerprintImageType.PNG) { + return "image/png"; + } + return "image/jpg"; +} + + + public List getFingerprintsAsBytes() { + return convertToBytesList(fingerprints, DecodedFingerprint::getImageData); + } + + private List convertToBytesList(List list, Function getter) { + if (list == null) return Collections.emptyList(); + return list.stream().map(item -> BufferToByte(getter.apply(item))).collect(Collectors.toList()); + } + + private byte[] BufferToByte(Buffer buffer) { + if (buffer.getData() != null) { + return buffer.getData(); + } + return null; + } +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class AbstractBioTemplate { + // Standart Biometric Header. Described by ICAO 9303 p.10 section 4.7.2.1 + private Map sbh; + // Length of record + private int lengthOfRecord; + // Image Data Type + private int imageType; + // Image width + private int imageWidth; + // Image height + private int imageHeight; + // Image quality + private int quality; + // Raw image data + private Buffer imageData; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedCom { + // Version of LDS structure + private String ldsVersion; + // Version of Unicode table + private String unicodeVersion; + // Datagroups defined in MRTD + private Buffer tags; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedImage extends AbstractBioTemplate { + // Number of facial images + private int numberOfFacialImages; + // Length of facial record data + private int facialRecordDataLength; + // Number of control points + private int nrFeaturePoints; + // Gender + private int gender; + // Eye color + private int eyeColor; + // Hair color + private int hairColor; + // Features Mask + private int featureMask; + // Facial expression + private int expression; + // Angular coordinates + private int poseAngle; + // Error of angular coordinates + private int poseAngleUncertainty; + // Type of face image + private int faceImageType; + // Image color space + private int imageColorSpace; + // Image source type + private int sourceType; + // Image device type + private int deviceType; + // Image Data Type + private int imageType; +} + +enum ImageType { + JPEG(0), + JPEG2000(1); + + private final int value; + + ImageType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} + +/** ISO/IEC 19794-4. Image compression algorithm */ +enum FingerprintImageType { + UNCOMPRESSED(0), + UNCOMPRESSEDPACKED(1), + WSQ(2), + JPEG(3), + JPEG2000(4), + PNG(5); + + private final int value; + FingerprintImageType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + +} + + + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedFingerprint extends AbstractBioTemplate { + // ID of the biometric scanner + private int captureDeviceId; + // Level of image acquisition settings + private int acquisitionLevel; + // Number of finger/palm images + private int count; + // Unit of measurement of resolution + private int scaleUnits; + // Scan resolution (horizontal) + private int scanResolutionHorizontal; + // Scan resolution (vertical) + private int scanResolutionVertical; + // Image resolution (horizontal) + private int imageResolutionHorizontal; + // Image resolution (vertical) + private int imageResolutionVertical; + // Bit depth of the grayscale scale + private int depth; + // Length of fingerprint/palm image data block + private int fingerprintRecordLength; + // Type of fingerprint and palm image + private int fingerImageType; + // Count of fingerprint representations + private int lengthOfRepresentations; + // Number of fingerprint representation + private int nrOfRepresention; + // Name of finger/part of palm + private int fingerType; + // Image Data Type + private int imageType; + +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedIris extends AbstractBioTemplate { + // ID of Biometric scanner (by manufacturer) + private int captureDeviceId; + // Bit field of image properties. ISO/IEC 19794-6, table 2 + private int imagePropertiesBits; + // Iris diameter (in points) + private int irisDiameter; + // Bit depth of the grayscale scale + private int depth; + // Converting image to polar coordinate system + private int imageTransformation; + // ID of Biometric scanner (by issuing authority) + private int deviceUniqueId; + // Eye type + private int biometricSubtype; + // Rotation angle of image + private int rotationAngle; + // Error of rotation angle + private int rotationAngleUncertainty; + // Image Data Type + private int imageType; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedAdditionalPersonalData { + // Full name of document holder + private String nameOfHolder; + // Other names of document holder + private List otherNames; + // Personal number + private String personalNumber; + // Full date of birth (CCYYMMDD) + private int fullDateOfBirth; + // Place of birth + private List placeOfBirth; + // Permanent residence address + private List permanentAddress; + // Phone number + private String telephone; + // Profession + private String profession; + // Position + private String title; + // Personal resume + private String personalSummary; + // Proof of citizenship + private Buffer proofOfCitizenship; + // Numbers of other valid TDs + private List otherValidTDNumbers; + // Information about detention + private String custodyInformation; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedAdditionalDocumentData { + // Full date of issue (YYYYMMDD) + private int dateOfIssue; + // Issuing authority + private String issuingAuthority; + // Name of another person + private List namesOfOtherPersons; + // Endorsements and observations + private String endorsements; + // Tax and exit requirements + private String taxAndExitReqs; + // Image of front of document + private Buffer imageOfFront; + // Image of rear of document + private Buffer imageOfRear; + // Date and time of document personalization (YYYYMMDDHHMMSS) + private int dateOfPersonalization; + // Serial number of personalization system + private String personalizationNumber; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class DecodedSecurtyObjectOfDocument { + // Included certificates (ex. Document Signer Certificate) + private List certificates; + // LDS object with datagroup's hashes + private Map ldsObject; + // SOD signatures + private List signatures; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class CSCAMasterList { + /** Master list version */ + private int version; + + /** CSCA certificates */ + private List certificates; +} + +@Getter +@Setter +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class Buffer { + private String type; + private byte[] data; +} From 49bd3c9253301f0ea8c6b4422c830a228c916c5a Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 15:50:25 -0500 Subject: [PATCH 08/15] fix: implement EMrtdData in dataGroups --- .../model/message/mrtd/ParsedEMrtdData.java | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java index d62977e..68bf366 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java @@ -37,24 +37,18 @@ public List getImagesAsBytes() { } public String getImageType(Object image) { - if (image instanceof DecodedImage) { - return getMimeType(((DecodedImage) image).getImageType()); - } else if (image instanceof DecodedFingerprint) { - return getMimeType(((DecodedFingerprint) image).getFingerImageType()); + if (image instanceof DecodedImage + && ((DecodedImage) image).getImageType() == ImageType.JPEG2000.getValue() + || image instanceof DecodedFingerprint + && ((DecodedFingerprint) image).getImageType() + == FingerprintImageType.JPEG2000.getValue()) { + return "image/jp2"; + } else if (image instanceof DecodedFingerprint + && ((DecodedFingerprint) image).getImageType() == FingerprintImageType.PNG.getValue()) { + return "image/png"; } return "image/jpg"; -} - -private String getMimeType(Object imageType) { - if (imageType instanceof FingerprintImageType && imageType == FingerprintImageType.JPEG2000 - || imageType instanceof ImageType && imageType == ImageType.JPEG2000) { - return "image/jp2"; - } else if (imageType instanceof FingerprintImageType && imageType == FingerprintImageType.PNG) { - return "image/png"; - } - return "image/jpg"; -} - + } public List getFingerprintsAsBytes() { return convertToBytesList(fingerprints, DecodedFingerprint::getImageData); @@ -151,11 +145,11 @@ enum ImageType { private final int value; ImageType(int value) { - this.value = value; + this.value = value; } public int getValue() { - return value; + return value; } } @@ -169,18 +163,16 @@ enum FingerprintImageType { PNG(5); private final int value; + FingerprintImageType(int value) { - this.value = value; + this.value = value; } public int getValue() { - return value; + return value; } - } - - @Getter @Setter @JsonInclude(Include.NON_NULL) @@ -216,7 +208,6 @@ class DecodedFingerprint extends AbstractBioTemplate { private int fingerType; // Image Data Type private int imageType; - } @Getter From 4024f3fc862676a590bc356375ea2143206bb99c Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 16:47:10 -0500 Subject: [PATCH 09/15] fix:change visibility in methods --- .../model/message/mrtd/ParsedEMrtdData.java | 525 +++++++++--------- 1 file changed, 255 insertions(+), 270 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java index 68bf366..659e6b4 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java @@ -3,11 +3,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -32,299 +29,287 @@ public class ParsedEMrtdData { private DecodedSecurtyObjectOfDocument securityObjectOfDocument; private CSCAMasterList cscaMasterList; - public List getImagesAsBytes() { - return convertToBytesList(images, DecodedImage::getImageData); - } + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + abstract class AbstractBioTemplate { + // Standart Biometric Header. Described by ICAO 9303 p.10 section 4.7.2.1 + private Map sbh; + // Length of record + private int lengthOfRecord; + // Image Data Type + private int imageType; + // Image width + private int imageWidth; + // Image height + private int imageHeight; + // Image quality + private int quality; + // Raw image data + private Buffer imageData; - public String getImageType(Object image) { - if (image instanceof DecodedImage - && ((DecodedImage) image).getImageType() == ImageType.JPEG2000.getValue() - || image instanceof DecodedFingerprint - && ((DecodedFingerprint) image).getImageType() - == FingerprintImageType.JPEG2000.getValue()) { - return "image/jp2"; - } else if (image instanceof DecodedFingerprint - && ((DecodedFingerprint) image).getImageType() == FingerprintImageType.PNG.getValue()) { - return "image/png"; + public byte[] convertToByte() { + return this.bufferToByte(imageData); } - return "image/jpg"; - } - public List getFingerprintsAsBytes() { - return convertToBytesList(fingerprints, DecodedFingerprint::getImageData); + private byte[] bufferToByte(Buffer buffer) { + if (buffer.getData() != null) { + return buffer.getData(); + } + return null; + } } - private List convertToBytesList(List list, Function getter) { - if (list == null) return Collections.emptyList(); - return list.stream().map(item -> BufferToByte(getter.apply(item))).collect(Collectors.toList()); + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedCom { + // Version of LDS structure + private String ldsVersion; + // Version of Unicode table + private String unicodeVersion; + // Datagroups defined in MRTD + private Buffer tags; } - private byte[] BufferToByte(Buffer buffer) { - if (buffer.getData() != null) { - return buffer.getData(); + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedImage extends AbstractBioTemplate { + // Number of facial images + private int numberOfFacialImages; + // Length of facial record data + private int facialRecordDataLength; + // Number of control points + private int nrFeaturePoints; + // Gender + private int gender; + // Eye color + private int eyeColor; + // Hair color + private int hairColor; + // Features Mask + private int featureMask; + // Facial expression + private int expression; + // Angular coordinates + private int poseAngle; + // Error of angular coordinates + private int poseAngleUncertainty; + // Type of face image + private int faceImageType; + // Image color space + private int imageColorSpace; + // Image source type + private int sourceType; + // Image device type + private int deviceType; + // Image Data Type + private int imageType; + + public String getStringImageType() { + if (imageType == ImageType.JPEG2000.getValue()) return "image/jp2"; + return "image/jpg"; } - return null; } -} - -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -abstract class AbstractBioTemplate { - // Standart Biometric Header. Described by ICAO 9303 p.10 section 4.7.2.1 - private Map sbh; - // Length of record - private int lengthOfRecord; - // Image Data Type - private int imageType; - // Image width - private int imageWidth; - // Image height - private int imageHeight; - // Image quality - private int quality; - // Raw image data - private Buffer imageData; -} -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedCom { - // Version of LDS structure - private String ldsVersion; - // Version of Unicode table - private String unicodeVersion; - // Datagroups defined in MRTD - private Buffer tags; -} - -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedImage extends AbstractBioTemplate { - // Number of facial images - private int numberOfFacialImages; - // Length of facial record data - private int facialRecordDataLength; - // Number of control points - private int nrFeaturePoints; - // Gender - private int gender; - // Eye color - private int eyeColor; - // Hair color - private int hairColor; - // Features Mask - private int featureMask; - // Facial expression - private int expression; - // Angular coordinates - private int poseAngle; - // Error of angular coordinates - private int poseAngleUncertainty; - // Type of face image - private int faceImageType; - // Image color space - private int imageColorSpace; - // Image source type - private int sourceType; - // Image device type - private int deviceType; - // Image Data Type - private int imageType; -} + enum ImageType { + JPEG(0), + JPEG2000(1); -enum ImageType { - JPEG(0), - JPEG2000(1); + private final int value; - private final int value; + ImageType(int value) { + this.value = value; + } - ImageType(int value) { - this.value = value; + public int getValue() { + return value; + } } - public int getValue() { - return value; - } -} + /** ISO/IEC 19794-4. Image compression algorithm */ + enum FingerprintImageType { + UNCOMPRESSED(0), + UNCOMPRESSEDPACKED(1), + WSQ(2), + JPEG(3), + JPEG2000(4), + PNG(5); -/** ISO/IEC 19794-4. Image compression algorithm */ -enum FingerprintImageType { - UNCOMPRESSED(0), - UNCOMPRESSEDPACKED(1), - WSQ(2), - JPEG(3), - JPEG2000(4), - PNG(5); + private final int value; - private final int value; + FingerprintImageType(int value) { + this.value = value; + } - FingerprintImageType(int value) { - this.value = value; + public int getValue() { + return value; + } } - public int getValue() { - return value; - } -} + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedFingerprint extends AbstractBioTemplate { + // ID of the biometric scanner + private int captureDeviceId; + // Level of image acquisition settings + private int acquisitionLevel; + // Number of finger/palm images + private int count; + // Unit of measurement of resolution + private int scaleUnits; + // Scan resolution (horizontal) + private int scanResolutionHorizontal; + // Scan resolution (vertical) + private int scanResolutionVertical; + // Image resolution (horizontal) + private int imageResolutionHorizontal; + // Image resolution (vertical) + private int imageResolutionVertical; + // Bit depth of the grayscale scale + private int depth; + // Length of fingerprint/palm image data block + private int fingerprintRecordLength; + // Type of fingerprint and palm image + private int fingerImageType; + // Count of fingerprint representations + private int lengthOfRepresentations; + // Number of fingerprint representation + private int nrOfRepresention; + // Name of finger/part of palm + private int fingerType; + // Image Data Type + private int imageType; -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedFingerprint extends AbstractBioTemplate { - // ID of the biometric scanner - private int captureDeviceId; - // Level of image acquisition settings - private int acquisitionLevel; - // Number of finger/palm images - private int count; - // Unit of measurement of resolution - private int scaleUnits; - // Scan resolution (horizontal) - private int scanResolutionHorizontal; - // Scan resolution (vertical) - private int scanResolutionVertical; - // Image resolution (horizontal) - private int imageResolutionHorizontal; - // Image resolution (vertical) - private int imageResolutionVertical; - // Bit depth of the grayscale scale - private int depth; - // Length of fingerprint/palm image data block - private int fingerprintRecordLength; - // Type of fingerprint and palm image - private int fingerImageType; - // Count of fingerprint representations - private int lengthOfRepresentations; - // Number of fingerprint representation - private int nrOfRepresention; - // Name of finger/part of palm - private int fingerType; - // Image Data Type - private int imageType; -} + public String getStringImageType() { + if (imageType == FingerprintImageType.JPEG2000.getValue()) return "image/jp2"; + else if (imageType == FingerprintImageType.JPEG2000.getValue()) return "image/png"; + return "image/jpg"; + } + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedIris extends AbstractBioTemplate { - // ID of Biometric scanner (by manufacturer) - private int captureDeviceId; - // Bit field of image properties. ISO/IEC 19794-6, table 2 - private int imagePropertiesBits; - // Iris diameter (in points) - private int irisDiameter; - // Bit depth of the grayscale scale - private int depth; - // Converting image to polar coordinate system - private int imageTransformation; - // ID of Biometric scanner (by issuing authority) - private int deviceUniqueId; - // Eye type - private int biometricSubtype; - // Rotation angle of image - private int rotationAngle; - // Error of rotation angle - private int rotationAngleUncertainty; - // Image Data Type - private int imageType; -} + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedIris extends AbstractBioTemplate { + // ID of Biometric scanner (by manufacturer) + private int captureDeviceId; + // Bit field of image properties. ISO/IEC 19794-6, table 2 + private int imagePropertiesBits; + // Iris diameter (in points) + private int irisDiameter; + // Bit depth of the grayscale scale + private int depth; + // Converting image to polar coordinate system + private int imageTransformation; + // ID of Biometric scanner (by issuing authority) + private int deviceUniqueId; + // Eye type + private int biometricSubtype; + // Rotation angle of image + private int rotationAngle; + // Error of rotation angle + private int rotationAngleUncertainty; + // Image Data Type + private int imageType; + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedAdditionalPersonalData { - // Full name of document holder - private String nameOfHolder; - // Other names of document holder - private List otherNames; - // Personal number - private String personalNumber; - // Full date of birth (CCYYMMDD) - private int fullDateOfBirth; - // Place of birth - private List placeOfBirth; - // Permanent residence address - private List permanentAddress; - // Phone number - private String telephone; - // Profession - private String profession; - // Position - private String title; - // Personal resume - private String personalSummary; - // Proof of citizenship - private Buffer proofOfCitizenship; - // Numbers of other valid TDs - private List otherValidTDNumbers; - // Information about detention - private String custodyInformation; -} + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedAdditionalPersonalData { + // Full name of document holder + private String nameOfHolder; + // Other names of document holder + private List otherNames; + // Personal number + private String personalNumber; + // Full date of birth (CCYYMMDD) + private int fullDateOfBirth; + // Place of birth + private List placeOfBirth; + // Permanent residence address + private List permanentAddress; + // Phone number + private String telephone; + // Profession + private String profession; + // Position + private String title; + // Personal resume + private String personalSummary; + // Proof of citizenship + private Buffer proofOfCitizenship; + // Numbers of other valid TDs + private List otherValidTDNumbers; + // Information about detention + private String custodyInformation; + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedAdditionalDocumentData { - // Full date of issue (YYYYMMDD) - private int dateOfIssue; - // Issuing authority - private String issuingAuthority; - // Name of another person - private List namesOfOtherPersons; - // Endorsements and observations - private String endorsements; - // Tax and exit requirements - private String taxAndExitReqs; - // Image of front of document - private Buffer imageOfFront; - // Image of rear of document - private Buffer imageOfRear; - // Date and time of document personalization (YYYYMMDDHHMMSS) - private int dateOfPersonalization; - // Serial number of personalization system - private String personalizationNumber; -} + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedAdditionalDocumentData { + // Full date of issue (YYYYMMDD) + private int dateOfIssue; + // Issuing authority + private String issuingAuthority; + // Name of another person + private List namesOfOtherPersons; + // Endorsements and observations + private String endorsements; + // Tax and exit requirements + private String taxAndExitReqs; + // Image of front of document + private Buffer imageOfFront; + // Image of rear of document + private Buffer imageOfRear; + // Date and time of document personalization (YYYYMMDDHHMMSS) + private int dateOfPersonalization; + // Serial number of personalization system + private String personalizationNumber; + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class DecodedSecurtyObjectOfDocument { - // Included certificates (ex. Document Signer Certificate) - private List certificates; - // LDS object with datagroup's hashes - private Map ldsObject; - // SOD signatures - private List signatures; -} + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class DecodedSecurtyObjectOfDocument { + // Included certificates (ex. Document Signer Certificate) + private List certificates; + // LDS object with datagroup's hashes + private Map ldsObject; + // SOD signatures + private List signatures; + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class CSCAMasterList { - /** Master list version */ - private int version; + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public class CSCAMasterList { + /** Master list version */ + private int version; - /** CSCA certificates */ - private List certificates; -} + /** CSCA certificates */ + private List certificates; + } -@Getter -@Setter -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -class Buffer { - private String type; - private byte[] data; + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + class Buffer { + private String type; + private byte[] data; + } } From 8f1d68d3aab15b4667b83aa176963a6e94b147c7 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 17:42:44 -0500 Subject: [PATCH 10/15] fix: update to static --- .../model/message/mrtd/ParsedEMrtdData.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java index 659e6b4..8515d92 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java @@ -33,7 +33,7 @@ public class ParsedEMrtdData { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - abstract class AbstractBioTemplate { + abstract static class AbstractBioTemplate { // Standart Biometric Header. Described by ICAO 9303 p.10 section 4.7.2.1 private Map sbh; // Length of record @@ -65,7 +65,7 @@ private byte[] bufferToByte(Buffer buffer) { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedCom { + public static class DecodedCom { // Version of LDS structure private String ldsVersion; // Version of Unicode table @@ -78,7 +78,7 @@ public class DecodedCom { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedImage extends AbstractBioTemplate { + public static class DecodedImage extends AbstractBioTemplate { // Number of facial images private int numberOfFacialImages; // Length of facial record data @@ -155,7 +155,7 @@ public int getValue() { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedFingerprint extends AbstractBioTemplate { + public static class DecodedFingerprint extends AbstractBioTemplate { // ID of the biometric scanner private int captureDeviceId; // Level of image acquisition settings @@ -198,7 +198,7 @@ public String getStringImageType() { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedIris extends AbstractBioTemplate { + public static class DecodedIris extends AbstractBioTemplate { // ID of Biometric scanner (by manufacturer) private int captureDeviceId; // Bit field of image properties. ISO/IEC 19794-6, table 2 @@ -225,7 +225,7 @@ public class DecodedIris extends AbstractBioTemplate { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedAdditionalPersonalData { + public static class DecodedAdditionalPersonalData { // Full name of document holder private String nameOfHolder; // Other names of document holder @@ -258,7 +258,7 @@ public class DecodedAdditionalPersonalData { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedAdditionalDocumentData { + public static class DecodedAdditionalDocumentData { // Full date of issue (YYYYMMDD) private int dateOfIssue; // Issuing authority @@ -283,7 +283,7 @@ public class DecodedAdditionalDocumentData { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class DecodedSecurtyObjectOfDocument { + public static class DecodedSecurtyObjectOfDocument { // Included certificates (ex. Document Signer Certificate) private List certificates; // LDS object with datagroup's hashes @@ -296,7 +296,7 @@ public class DecodedSecurtyObjectOfDocument { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public class CSCAMasterList { + public static class CSCAMasterList { /** Master list version */ private int version; @@ -308,7 +308,7 @@ public class CSCAMasterList { @Setter @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - class Buffer { + static class Buffer { private String type; private byte[] data; } From a8a76beb9673a37fd53f56bbcd3c41f691a92665 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 17:48:31 -0500 Subject: [PATCH 11/15] docs: update --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 344c485..7a4424c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # Changelog -## [2.0.12](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.12) (2024-10-18) +## [2.0.12](https://central.sonatype.com/artifact/io.2060/service-agent-java-client/2.0.12) (2024-10-22) ### Features +* feat: implement EMrtdData in dataGroups ([468ea49](https://github.com/2060-io/2060-service-agent-java-client/pull/19/commits/468ea4934be6e778346667374a6ff21871c0eee1)) * Add eMRTD commands to NFC reading ([55b7937](https://github.com/2060-io/2060-service-agent-java-client/pull/19/commits/55b79378c9416c8b1aee6f98e2ee3eb29d268fbb)) * Add randomCipheringData method ([c7d85f5](https://github.com/2060-io/2060-service-agent-java-client/pull/19/commits/c7d85f5c80f890c9c8c0cc8b2cf54fb5d09ef6b2)) From 4b93d9660bcfe3869e1b79b53d756a1bc8e717d3 Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Mon, 21 Oct 2024 17:51:27 -0500 Subject: [PATCH 12/15] fix: typing --- .../model/message/mrtd/EMrtdDataRequestMessage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java index 2abc9cf..91a4c42 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdDataRequestMessage.java @@ -13,9 +13,9 @@ public class EMrtdDataRequestMessage extends BaseMessage { private static final long serialVersionUID = -2840211856886673672L; public static EMrtdDataRequestMessage build(UUID connectionId, UUID threadId) { - EMrtdDataRequestMessage mrzr = new EMrtdDataRequestMessage(); - mrzr.setConnectionId(connectionId); - mrzr.setThreadId(threadId); - return mrzr; + EMrtdDataRequestMessage emrtd = new EMrtdDataRequestMessage(); + emrtd.setConnectionId(connectionId); + emrtd.setThreadId(threadId); + return emrtd; } } From 7e5a50a305dd7f0234c0405f7602a42d20b885fc Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Tue, 22 Oct 2024 16:28:33 -0500 Subject: [PATCH 13/15] feat: remove old typing --- .../client/model/message/mrtd/EMrtdData.java | 23 +- .../model/message/mrtd/ParsedEMrtdData.java | 315 ------------------ 2 files changed, 19 insertions(+), 319 deletions(-) delete mode 100644 src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java index f3561e5..c92202b 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java @@ -19,15 +19,30 @@ public class EMrtdData implements Serializable { private static final long serialVersionUID = -5234275638176689315L; private Map raw; - private ParsedData parsed; + private EMrtdProcessedData processed; @Getter @Setter @ToString @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public static class ParsedData { - private ParsedEMrtdData fields; - private boolean valid; + public static class EMrtdProcessedData { + private ProcessedData fields; + } + + @Getter + @Setter + @ToString + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ProcessedData { + private String mrzData; + private String firstName; + private String lastName; + private String faceDataUrl; + private String fingerprintDataUrl; + private long birthDate; + private String placeOfBirth; + private long issuanceDate; } } diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java deleted file mode 100644 index 8515d92..0000000 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/ParsedEMrtdData.java +++ /dev/null @@ -1,315 +0,0 @@ -package io.twentysixty.sa.client.model.message.mrtd; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import java.util.List; -import java.util.Map; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class ParsedEMrtdData { - private DecodedCom com; - private String mrzData; - private List images; - private List fingerprints; - private List iris; - private List displayedImages; - private List signatureImages; - private DecodedAdditionalPersonalData additionalPersonalData; - private DecodedAdditionalDocumentData additionalDocumentData; - private Map securityInfos; - private Map subjectPublicKeyInfo; - private DecodedSecurtyObjectOfDocument securityObjectOfDocument; - private CSCAMasterList cscaMasterList; - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - abstract static class AbstractBioTemplate { - // Standart Biometric Header. Described by ICAO 9303 p.10 section 4.7.2.1 - private Map sbh; - // Length of record - private int lengthOfRecord; - // Image Data Type - private int imageType; - // Image width - private int imageWidth; - // Image height - private int imageHeight; - // Image quality - private int quality; - // Raw image data - private Buffer imageData; - - public byte[] convertToByte() { - return this.bufferToByte(imageData); - } - - private byte[] bufferToByte(Buffer buffer) { - if (buffer.getData() != null) { - return buffer.getData(); - } - return null; - } - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedCom { - // Version of LDS structure - private String ldsVersion; - // Version of Unicode table - private String unicodeVersion; - // Datagroups defined in MRTD - private Buffer tags; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedImage extends AbstractBioTemplate { - // Number of facial images - private int numberOfFacialImages; - // Length of facial record data - private int facialRecordDataLength; - // Number of control points - private int nrFeaturePoints; - // Gender - private int gender; - // Eye color - private int eyeColor; - // Hair color - private int hairColor; - // Features Mask - private int featureMask; - // Facial expression - private int expression; - // Angular coordinates - private int poseAngle; - // Error of angular coordinates - private int poseAngleUncertainty; - // Type of face image - private int faceImageType; - // Image color space - private int imageColorSpace; - // Image source type - private int sourceType; - // Image device type - private int deviceType; - // Image Data Type - private int imageType; - - public String getStringImageType() { - if (imageType == ImageType.JPEG2000.getValue()) return "image/jp2"; - return "image/jpg"; - } - } - - enum ImageType { - JPEG(0), - JPEG2000(1); - - private final int value; - - ImageType(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } - - /** ISO/IEC 19794-4. Image compression algorithm */ - enum FingerprintImageType { - UNCOMPRESSED(0), - UNCOMPRESSEDPACKED(1), - WSQ(2), - JPEG(3), - JPEG2000(4), - PNG(5); - - private final int value; - - FingerprintImageType(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedFingerprint extends AbstractBioTemplate { - // ID of the biometric scanner - private int captureDeviceId; - // Level of image acquisition settings - private int acquisitionLevel; - // Number of finger/palm images - private int count; - // Unit of measurement of resolution - private int scaleUnits; - // Scan resolution (horizontal) - private int scanResolutionHorizontal; - // Scan resolution (vertical) - private int scanResolutionVertical; - // Image resolution (horizontal) - private int imageResolutionHorizontal; - // Image resolution (vertical) - private int imageResolutionVertical; - // Bit depth of the grayscale scale - private int depth; - // Length of fingerprint/palm image data block - private int fingerprintRecordLength; - // Type of fingerprint and palm image - private int fingerImageType; - // Count of fingerprint representations - private int lengthOfRepresentations; - // Number of fingerprint representation - private int nrOfRepresention; - // Name of finger/part of palm - private int fingerType; - // Image Data Type - private int imageType; - - public String getStringImageType() { - if (imageType == FingerprintImageType.JPEG2000.getValue()) return "image/jp2"; - else if (imageType == FingerprintImageType.JPEG2000.getValue()) return "image/png"; - return "image/jpg"; - } - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedIris extends AbstractBioTemplate { - // ID of Biometric scanner (by manufacturer) - private int captureDeviceId; - // Bit field of image properties. ISO/IEC 19794-6, table 2 - private int imagePropertiesBits; - // Iris diameter (in points) - private int irisDiameter; - // Bit depth of the grayscale scale - private int depth; - // Converting image to polar coordinate system - private int imageTransformation; - // ID of Biometric scanner (by issuing authority) - private int deviceUniqueId; - // Eye type - private int biometricSubtype; - // Rotation angle of image - private int rotationAngle; - // Error of rotation angle - private int rotationAngleUncertainty; - // Image Data Type - private int imageType; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedAdditionalPersonalData { - // Full name of document holder - private String nameOfHolder; - // Other names of document holder - private List otherNames; - // Personal number - private String personalNumber; - // Full date of birth (CCYYMMDD) - private int fullDateOfBirth; - // Place of birth - private List placeOfBirth; - // Permanent residence address - private List permanentAddress; - // Phone number - private String telephone; - // Profession - private String profession; - // Position - private String title; - // Personal resume - private String personalSummary; - // Proof of citizenship - private Buffer proofOfCitizenship; - // Numbers of other valid TDs - private List otherValidTDNumbers; - // Information about detention - private String custodyInformation; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedAdditionalDocumentData { - // Full date of issue (YYYYMMDD) - private int dateOfIssue; - // Issuing authority - private String issuingAuthority; - // Name of another person - private List namesOfOtherPersons; - // Endorsements and observations - private String endorsements; - // Tax and exit requirements - private String taxAndExitReqs; - // Image of front of document - private Buffer imageOfFront; - // Image of rear of document - private Buffer imageOfRear; - // Date and time of document personalization (YYYYMMDDHHMMSS) - private int dateOfPersonalization; - // Serial number of personalization system - private String personalizationNumber; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class DecodedSecurtyObjectOfDocument { - // Included certificates (ex. Document Signer Certificate) - private List certificates; - // LDS object with datagroup's hashes - private Map ldsObject; - // SOD signatures - private List signatures; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class CSCAMasterList { - /** Master list version */ - private int version; - - /** CSCA certificates */ - private List certificates; - } - - @Getter - @Setter - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - static class Buffer { - private String type; - private byte[] data; - } -} From 4a0fe2919d7026a02036876ab9608fe687cce6fe Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Wed, 23 Oct 2024 02:04:38 -0500 Subject: [PATCH 14/15] fix: new typing --- .../client/model/message/mrtd/EMrtdData.java | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java index c92202b..fe3f172 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import java.io.Serializable; +import java.util.List; import java.util.Map; import lombok.Getter; import lombok.Setter; @@ -27,7 +28,9 @@ public class EMrtdData implements Serializable { @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public static class EMrtdProcessedData { - private ProcessedData fields; + private EF_DG1 ef_dg1; + private EF_DG2 ef_dg2; + private EF_DG11 ef_dg11; } @Getter @@ -35,14 +38,45 @@ public static class EMrtdProcessedData { @ToString @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) - public static class ProcessedData { - private String mrzData; - private String firstName; + public static class EF_DG1 { + private String documentType; + private String documentNumber; + private String issuingState; + private String dateOfBirth; + private String dateOfExpiry; + private String sex; + private String nationality; private String lastName; - private String faceDataUrl; - private String fingerprintDataUrl; - private long birthDate; - private String placeOfBirth; - private long issuanceDate; + private String firstName; + private String nameOfHolder; + private String mrzOptionalData; + } + + @Getter + @Setter + @ToString + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class EF_DG2 { + private List faceImages; + } + + @Getter + @Setter + @ToString + @JsonInclude(Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class EF_DG11 { + private String nameOfHolder; + private Long dateOfBirth; + private List otherNames; + private String personalNumber; + private List placeOfBirth; + private List permanentAddress; + private String telephone; + private String profession; + private String title; + private String personalSummary; + private String custodyInformation; } } From dcb6d4566ab67ee5a1c05a8b5815f18cfcbad27a Mon Sep 17 00:00:00 2001 From: Andres Vallecilla Date: Wed, 23 Oct 2024 11:53:40 -0500 Subject: [PATCH 15/15] fix: new typing --- .../client/model/message/mrtd/EMrtdData.java | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java index fe3f172..b6e31dd 100644 --- a/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java +++ b/src/main/java/io/twentysixty/sa/client/model/message/mrtd/EMrtdData.java @@ -28,17 +28,6 @@ public class EMrtdData implements Serializable { @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public static class EMrtdProcessedData { - private EF_DG1 ef_dg1; - private EF_DG2 ef_dg2; - private EF_DG11 ef_dg11; - } - - @Getter - @Setter - @ToString - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class EF_DG1 { private String documentType; private String documentNumber; private String issuingState; @@ -48,27 +37,9 @@ public static class EF_DG1 { private String nationality; private String lastName; private String firstName; - private String nameOfHolder; private String mrzOptionalData; - } - - @Getter - @Setter - @ToString - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class EF_DG2 { private List faceImages; - } - - @Getter - @Setter - @ToString - @JsonInclude(Include.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown = true) - public static class EF_DG11 { private String nameOfHolder; - private Long dateOfBirth; private List otherNames; private String personalNumber; private List placeOfBirth;