From 229063d4f52bfac2c0fa0ea27df4de5561de30d6 Mon Sep 17 00:00:00 2001 From: 0xturboblitz Date: Wed, 14 Feb 2024 16:01:55 +0100 Subject: [PATCH] android photo --- app/App.tsx | 8 +- .../io/tradle/nfc/RNPassportReaderModule.kt | 143 +++++++++--------- app/src/screens/ProveScreen.tsx | 2 +- common/src/utils/types.ts | 5 + 4 files changed, 83 insertions(+), 75 deletions(-) diff --git a/app/App.tsx b/app/App.tsx index 5979708dd..c4bfed7ac 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -194,6 +194,7 @@ function App(): JSX.Element { dataGroupHashes, eContent, encryptedDigest, + photo } = response; const passportData: PassportData = { @@ -207,6 +208,7 @@ function App(): JSX.Element { dataGroupHashes: dataHashesObjToArray(JSON.parse(dataGroupHashes)), eContent: JSON.parse(eContent), encryptedDigest: JSON.parse(encryptedDigest), + photo: photo, }; console.log('mrz', passportData.mrz); @@ -215,6 +217,10 @@ function App(): JSX.Element { console.log('dataGroupHashes', passportData.dataGroupHashes); console.log('eContent', passportData.eContent); console.log('encryptedDigest', passportData.encryptedDigest); + console.log("photo", { + ...passportData.photo, + base64: passportData.photo.base64.substring(0, 100) + '...' + }) setPassportData(passportData); setStep(Steps.NFC_SCAN_COMPLETED); @@ -247,7 +253,7 @@ function App(): JSX.Element { dateOfBirth: dateOfBirth, dateOfExpiry: dateOfExpiry, }); - console.log('response', response); + // console.log('response', response); console.log('scanned'); handleResponseAndroid(response); } catch (e: any) { diff --git a/app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/RNPassportReaderModule.kt b/app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/RNPassportReaderModule.kt index 70f0eb7d7..79a706eed 100644 --- a/app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/RNPassportReaderModule.kt +++ b/app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/RNPassportReaderModule.kt @@ -495,87 +495,84 @@ class RNPassportReaderModule(private val reactContext: ReactApplicationContext) } override fun onPostExecute(result: Exception?) { - if (scanPromise == null) return + if (scanPromise == null) return - if (result != null) { - // Log.w(TAG, exceptionStack(result)) - if (result is IOException) { - scanPromise?.reject("E_SCAN_FAILED_DISCONNECT", "Lost connection to chip on card") - } else { - scanPromise?.reject("E_SCAN_FAILED", result) - } + if (result != null) { + // Log.w(TAG, exceptionStack(result)) + if (result is IOException) { + scanPromise?.reject("E_SCAN_FAILED_DISCONNECT", "Lost connection to chip on card") + } else { + scanPromise?.reject("E_SCAN_FAILED", result) + } - resetState() - return - } + resetState() + return + } - val mrzInfo = dg1File.mrzInfo + val mrzInfo = dg1File.mrzInfo - // var quality = 100 - // if (opts?.hasKey("quality") == true) { - // quality = (opts?.getDouble("quality") ?: 1.0 * 100).toInt() - // } - val gson = Gson() + val gson = Gson() - val signedDataField = SODFile::class.java.getDeclaredField("signedData") - signedDataField.isAccessible = true - - // val signedData = signedDataField.get(sodFile) as SignedData - - val eContentAsn1InputStream = ASN1InputStream(sodFile.eContent.inputStream()) - // val eContentDecomposed: ASN1Primitive = eContentAsn1InputStream.readObject() - - val passport = Arguments.createMap() - passport.putString("mrz", mrzInfo.toString()) - passport.putString("signatureAlgorithm", sodFile.docSigningCertificate.sigAlgName) // this one is new - - val publicKey = sodFile.docSigningCertificate.publicKey - if (publicKey is RSAPublicKey) { - passport.putString("modulus", publicKey.modulus.toString()) - } else if (publicKey is ECPublicKey) { - // Handle the elliptic curve public key case + val signedDataField = SODFile::class.java.getDeclaredField("signedData") + signedDataField.isAccessible = true - // val w = publicKey.getW() - // passport.putString("publicKeyW", w.toString()) + // val signedData = signedDataField.get(sodFile) as SignedData - // val ecParams = publicKey.getParams() - // passport.putInt("cofactor", ecParams.getCofactor()) - // passport.putString("curve", ecParams.getCurve().toString()) - // passport.putString("generator", ecParams.getGenerator().toString()) - // passport.putString("order", ecParams.getOrder().toString()) - // if (ecParams is ECNamedCurveSpec) { - // passport.putString("curveName", ecParams.getName()) - // } + val eContentAsn1InputStream = ASN1InputStream(sodFile.eContent.inputStream()) + // val eContentDecomposed: ASN1Primitive = eContentAsn1InputStream.readObject() + + val passport = Arguments.createMap() + passport.putString("mrz", mrzInfo.toString()) + passport.putString("signatureAlgorithm", sodFile.docSigningCertificate.sigAlgName) // this one is new + + val publicKey = sodFile.docSigningCertificate.publicKey + if (publicKey is RSAPublicKey) { + passport.putString("modulus", publicKey.modulus.toString()) + } else if (publicKey is ECPublicKey) { + // Handle the elliptic curve public key case + + // val w = publicKey.getW() + // passport.putString("publicKeyW", w.toString()) + + // val ecParams = publicKey.getParams() + // passport.putInt("cofactor", ecParams.getCofactor()) + // passport.putString("curve", ecParams.getCurve().toString()) + // passport.putString("generator", ecParams.getGenerator().toString()) + // passport.putString("order", ecParams.getOrder().toString()) + // if (ecParams is ECNamedCurveSpec) { + // passport.putString("curveName", ecParams.getName()) + // } + + // Old one, probably wrong: + // passport.putString("curveName", (publicKey.parameters as ECNamedCurveSpec).name) + // passport.putString("curveName", (publicKey.parameters.algorithm)) or maybe this + passport.putString("publicKeyQ", publicKey.q.toString()) + } - // Old one, probably wrong: - // passport.putString("curveName", (publicKey.parameters as ECNamedCurveSpec).name) - // passport.putString("curveName", (publicKey.parameters.algorithm)) or maybe this - passport.putString("publicKeyQ", publicKey.q.toString()) - } - - passport.putString("dataGroupHashes", gson.toJson(sodFile.dataGroupHashes)) - passport.putString("eContent", gson.toJson(sodFile.eContent)) - passport.putString("encryptedDigest", gson.toJson(sodFile.encryptedDigest)) - - - // Another way to get signing time is to get into signedData.signerInfos, then search for the ICO identifier 1.2.840.113549.1.9.5 - // passport.putString("signerInfos", gson.toJson(signedData.signerInfos)) - - // Log.d(TAG, "signedData.digestAlgorithms: ${gson.toJson(signedData.digestAlgorithms)}") - // Log.d(TAG, "signedData.signerInfos: ${gson.toJson(signedData.signerInfos)}") - // Log.d(TAG, "signedData.certificates: ${gson.toJson(signedData.certificates)}") - - // val base64 = bitmap?.let { toBase64(it, quality) } - // val photo = Arguments.createMap() - // photo.putString("base64", base64 ?: "") - // photo.putInt("width", bitmap?.width ?: 0) - // photo.putInt("height", bitmap?.height ?: 0) - // passport.putMap("photo", photo) - // passport.putString("dg2File", gson.toJson(dg2File)) - - scanPromise?.resolve(passport) - resetState() - } + passport.putString("dataGroupHashes", gson.toJson(sodFile.dataGroupHashes)) + passport.putString("eContent", gson.toJson(sodFile.eContent)) + passport.putString("encryptedDigest", gson.toJson(sodFile.encryptedDigest)) + + + // Another way to get signing time is to get into signedData.signerInfos, then search for the ICO identifier 1.2.840.113549.1.9.5 + // passport.putString("signerInfos", gson.toJson(signedData.signerInfos)) + + // Log.d(TAG, "signedData.digestAlgorithms: ${gson.toJson(signedData.digestAlgorithms)}") + // Log.d(TAG, "signedData.signerInfos: ${gson.toJson(signedData.signerInfos)}") + // Log.d(TAG, "signedData.certificates: ${gson.toJson(signedData.certificates)}") + + var quality = 100 + val base64 = bitmap?.let { toBase64(it, quality) } + val photo = Arguments.createMap() + photo.putString("base64", base64 ?: "") + photo.putInt("width", bitmap?.width ?: 0) + photo.putInt("height", bitmap?.height ?: 0) + passport.putMap("photo", photo) + // passport.putString("dg2File", gson.toJson(dg2File)) + + scanPromise?.resolve(passport) + resetState() + } } private fun convertDate(input: String?): String? { diff --git a/app/src/screens/ProveScreen.tsx b/app/src/screens/ProveScreen.tsx index daf1bc950..b5eff35e4 100644 --- a/app/src/screens/ProveScreen.tsx +++ b/app/src/screens/ProveScreen.tsx @@ -143,7 +143,7 @@ const ProveScreen: React.FC = ({ h="$12" borderRadius="$10" source={{ - uri: USER + uri: passportData.photo.base64 ?? USER }} /> diff --git a/common/src/utils/types.ts b/common/src/utils/types.ts index 5379310b9..5a34623c1 100644 --- a/common/src/utils/types.ts +++ b/common/src/utils/types.ts @@ -7,4 +7,9 @@ export type PassportData = { dataGroupHashes: DataHash[] | number[]; eContent: number[]; encryptedDigest: number[]; + photo: { + base64: string; + height: number; + width: number; + } };