diff --git a/app/App.tsx b/app/App.tsx index 5979708dd..2ae10590a 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -143,6 +143,7 @@ function App(): JSX.Element { console.log('isPACESupported', parsed.isPACESupported) console.log('isChipAuthenticationSupported', parsed.isChipAuthenticationSupported) console.log('residenceAddress', parsed.residenceAddress) + console.log('passportPhoto', parsed.passportPhoto.substring(0, 100) + '...') console.log('parsed.documentSigningCertificate', parsed.documentSigningCertificate) const pem = JSON.parse(parsed.documentSigningCertificate).PEM.replace(/\\\\n/g, '\n') @@ -171,6 +172,7 @@ function App(): JSX.Element { dataGroupHashes: concatenatedDataHashesArraySigned, eContent: signedEContentArray, encryptedDigest: encryptedDigestArray, + photoBase64: "data:image/jpeg;base64," + parsed.passportPhoto, }; console.log('mrz', passportData.mrz); @@ -194,6 +196,7 @@ function App(): JSX.Element { dataGroupHashes, eContent, encryptedDigest, + photo } = response; const passportData: PassportData = { @@ -207,6 +210,7 @@ function App(): JSX.Element { dataGroupHashes: dataHashesObjToArray(JSON.parse(dataGroupHashes)), eContent: JSON.parse(eContent), encryptedDigest: JSON.parse(encryptedDigest), + photoBase64: photo.base64, }; console.log('mrz', passportData.mrz); @@ -215,6 +219,7 @@ function App(): JSX.Element { console.log('dataGroupHashes', passportData.dataGroupHashes); console.log('eContent', passportData.eContent); console.log('encryptedDigest', passportData.encryptedDigest); + console.log("photoBase64", passportData.photoBase64.substring(0, 100) + '...') setPassportData(passportData); setStep(Steps.NFC_SCAN_COMPLETED); @@ -247,7 +252,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/index.js b/app/index.js index 7b16ad0c3..c19eabe5f 100644 --- a/app/index.js +++ b/app/index.js @@ -2,7 +2,7 @@ * @format */ -import { AppRegistry } from 'react-native'; +import { AppRegistry, LogBox } from 'react-native'; import App from './App'; import { name as appName } from './app.json'; import { TamaguiProvider } from 'tamagui'; @@ -13,6 +13,9 @@ import myAppConfig from './tamagui.config'; const tamaguiConfig = createTamagui(config) +LogBox.ignoreLogs([ + /bad setState/, +]) const Root = () => ( diff --git a/app/ios/PassportReader.swift b/app/ios/PassportReader.swift index 96a82876f..ad24dfada 100644 --- a/app/ios/PassportReader.swift +++ b/app/ios/PassportReader.swift @@ -118,6 +118,14 @@ class PassportReader: NSObject{ ret["phoneNumber"] = passport.phoneNumber ret["personalNumber"] = passport.personalNumber + let passportPhotoData = passport.passportPhoto // [UInt8] + if let passportPhotoData = passport.passportPhoto { + let data = Data(passportPhotoData) + let base64String = data.base64EncodedString() + + ret["passportPhoto"] = base64String + } + // documentSigningCertificate // countrySigningCertificate diff --git a/app/ios/Podfile b/app/ios/Podfile index 54addf801..2782ec758 100644 --- a/app/ios/Podfile +++ b/app/ios/Podfile @@ -34,7 +34,7 @@ target 'ProofOfPassport' do flags = get_default_flags() use_frameworks! - pod 'NFCPassportReader', git: 'https://github.com/0xturboblitz/NFCPassportReader.git', commit: 'd36952eeaa2025ff1a9c9abbc244bd5ff53eb0f9' + pod 'NFCPassportReader', git: 'https://github.com/0xturboblitz/NFCPassportReader.git', commit: '310ecb519655d9ed8b1afc5eb490b2f51a4d3595' pod 'MoproKit', :path => './MoproKit' use_react_native!( diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock index 52045f070..a40b47114 100644 --- a/app/ios/Podfile.lock +++ b/app/ios/Podfile.lock @@ -403,7 +403,7 @@ DEPENDENCIES: - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - MoproKit (from `./MoproKit`) - - NFCPassportReader (from `https://github.com/0xturboblitz/NFCPassportReader.git`, commit `d36952eeaa2025ff1a9c9abbc244bd5ff53eb0f9`) + - NFCPassportReader (from `https://github.com/0xturboblitz/NFCPassportReader.git`, commit `310ecb519655d9ed8b1afc5eb490b2f51a4d3595`) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) @@ -460,7 +460,7 @@ EXTERNAL SOURCES: MoproKit: :path: "./MoproKit" NFCPassportReader: - :commit: d36952eeaa2025ff1a9c9abbc244bd5ff53eb0f9 + :commit: 310ecb519655d9ed8b1afc5eb490b2f51a4d3595 :git: https://github.com/0xturboblitz/NFCPassportReader.git RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" @@ -533,7 +533,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: NFCPassportReader: - :commit: d36952eeaa2025ff1a9c9abbc244bd5ff53eb0f9 + :commit: 310ecb519655d9ed8b1afc5eb490b2f51a4d3595 :git: https://github.com/0xturboblitz/NFCPassportReader.git SPEC CHECKSUMS: @@ -555,13 +555,13 @@ SPEC CHECKSUMS: React-Core: 8293312ad137ea82fd2c29deb163dbc24aa4e00e React-CoreModules: 32fab1d62416849a3b6dac6feff9d54e5ddc2d1e React-cxxreact: 55d0f7cb6b4cc09ba9190797f1da87182d1a2fb6 - React-debug: 878f0c4026b30a6240f7a15f8612efcf5d8c3df9 + React-debug: 7e61555c8158126c6cd98c3154381ad3821aaaca React-jsc: 0db8e8cc2074d979c37ffa7b8d7c914833960497 React-jsi: 58677ff4848ceb6aeb9118fe03448a843ea5e16a React-jsiexecutor: 2c15ba1bace70177492368d5180b564f165870fd React-jsinspector: b511447170f561157547bc0bef3f169663860be7 React-logger: c5b527272d5f22eaa09bb3c3a690fee8f237ae95 - React-NativeModulesApple: 3a49a4bc38b979b804525816b781eb6612dba5fa + React-NativeModulesApple: 0438665fc7473be6edc496e823e6ea0b0537b46c React-perflogger: 6bd153e776e6beed54c56b0847e1220a3ff92ba5 React-RCTActionSheet: c0b62af44e610e69d9a2049a682f5dba4e9dff17 React-RCTAnimation: fe7005136b58f58871cab2f70732343b6e330d30 @@ -575,13 +575,13 @@ SPEC CHECKSUMS: React-RCTVibration: ea3a68a49873a54ced927c90923fc6932baf344a React-rncore: 9672a017af4a7da7495d911f0b690cbcae9dd18d React-runtimeexecutor: 369ae9bb3f83b65201c0c8f7d50b72280b5a1dbc - React-runtimescheduler: 116fb55732ddfd96298350528cf13ceaf94759c8 - React-utils: a8681f0d721ff080373ae9e4afb1f380707b55f9 - ReactCommon: df6a7f5665621529ee01b89fb0c3c93eb014f276 + React-runtimescheduler: ec1066a4f2d1152eb1bc3fb61d69376b3bc0dde0 + React-utils: d55ba834beb39f01b0b470ae43478c0a3a024abe + ReactCommon: 68e3a815fbb69af3bb4196e04c6ae7abb306e7a8 RNSVG: 07dbd870b0dcdecc99b3a202fa37c8ca163caec2 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce -PODFILE CHECKSUM: d401e6efe0c933985349c8c115c7edca8fef3182 +PODFILE CHECKSUM: 7568291077da8ee6387464cd1a7e01559a46ab1f -COCOAPODS: 1.15.0 +COCOAPODS: 1.14.3 diff --git a/app/src/screens/ProveScreen.tsx b/app/src/screens/ProveScreen.tsx index 50afb5c0b..63c862128 100644 --- a/app/src/screens/ProveScreen.tsx +++ b/app/src/screens/ProveScreen.tsx @@ -136,7 +136,7 @@ const ProveScreen: React.FC = ({ h="$12" borderRadius="$10" source={{ - uri: USER + uri: passportData.photoBase64 ?? USER }} /> diff --git a/common/src/utils/types.ts b/common/src/utils/types.ts index 5379310b9..21c2c0f59 100644 --- a/common/src/utils/types.ts +++ b/common/src/utils/types.ts @@ -7,4 +7,5 @@ export type PassportData = { dataGroupHashes: DataHash[] | number[]; eContent: number[]; encryptedDigest: number[]; + photoBase64: string; };