fix build issues - improve amplitude logs

This commit is contained in:
turnoffthiscomputer
2024-12-29 23:00:33 +01:00
parent ce6c61e27d
commit 667c993ee3
16 changed files with 232 additions and 78 deletions

View File

@@ -36,9 +36,9 @@ const MockDataScreen: React.FC<MockDataScreenProps> = ({
const { toast } = useNavigationStore();
const signatureAlgorithmToStrictSignatureAlgorithm = {
"rsa sha256": "rsa_sha256",
"rsa sha1": "rsa_sha1",
"rsapss sha256": "rsapss_sha256"
"rsa sha256": "rsa_sha256_65537_2048",
"rsa sha1": "rsa_sha1_65537_2048",
"rsapss sha256": "rsapss_sha256_65537_2048"
} as const;
const handleGenerate = useCallback(async () => {

View File

@@ -9,7 +9,7 @@ import { DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/ap
import CustomButton from '../components/CustomButton';
import { generateProof } from '../utils/prover';
import io, { Socket } from 'socket.io-client';
import { getCircuitName, parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
import { getCircuitNameOld, parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
import { CircuitName } from '../utils/zkeyDownload';
import { generateCircuitInputsInApp } from '../utils/generateInputsInApp';
import { buildAttestation } from '../../../common/src/utils/openPassportAttestation';
@@ -45,7 +45,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
const [isConnecting, setIsConnecting] = useState(false);
const { signatureAlgorithm, hashFunction, authorityKeyIdentifier } = parseCertificate(passportData.dsc);
const { secret, dscSecret } = useUserStore.getState();
const circuitName = getCircuitName(selectedApp.mode, signatureAlgorithm, hashFunction);
const circuitName = getCircuitNameOld(selectedApp.mode, signatureAlgorithm, hashFunction);
const waitForSocketConnection = (socket: Socket): Promise<void> => {
return new Promise((resolve) => {

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { YStack, Text, XStack, Separator } from 'tamagui';
import { YStack, Text, XStack, Separator, ScrollView } from 'tamagui';
import useUserStore from '../stores/userStore';
import { textBlack, separatorColor } from '../utils/colors';
import { parsePassportData } from '../utils/parsePassportData';
@@ -16,33 +16,60 @@ const UserInfo: React.FC = () => {
);
return (
<YStack f={1} p="$0" gap="$2" jc="flex-start" mt="$10">
<Text fontSize="$8" color={textBlack} mb="$4">Passport Data Info</Text>
<Separator borderColor={separatorColor} />
<ScrollView>
<YStack f={1} p="$0" gap="$2" jc="flex-start" py="$2" >
<Text fontSize="$8" color={textBlack} mb="$4">Passport Data Info</Text>
<Separator borderColor={separatorColor} />
<InfoRow label="Data Groups" value={passportMetaData?.dataGroups || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Data Groups" value={passportMetaData?.dataGroups || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="DG1 Hash Function" value={passportMetaData?.dg1HashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="DG1 Hash Function" value={passportMetaData?.dg1HashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="DG1 Hash Offset" value={passportMetaData?.dg1HashOffset || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="DG1 Hash Offset" value={passportMetaData?.dg1HashOffset || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Size" value={passportMetaData?.eContentSize || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Size" value={passportMetaData?.eContentSize || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Hash Function" value={passportMetaData?.eContentHashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Hash Function" value={passportMetaData?.eContentHashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Hash Offset" value={passportMetaData?.eContentHashOffset || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="eContent Hash Offset" value={passportMetaData?.eContentHashOffset || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signed Attributes Size" value={passportMetaData?.signedAttrSize || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signed Attributes Size" value={passportMetaData?.signedAttrSize || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signed Attributes Hash Function" value={passportMetaData?.signedAttrHashFunction || 'None'} />
</YStack>
<InfoRow label="Signed Attributes Hash Function" value={passportMetaData?.signedAttrHashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signature Algorithm" value={passportMetaData?.signatureAlgorithm || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signature Algorithm Details" value={passportMetaData?.curveOrExponent || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="Signature Algorithm Bits" value={passportMetaData?.signatureAlgorithmBits || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="CSCA Found" value={passportMetaData?.cscaFound ? 'Yes' : 'No'} />
<Separator borderColor={separatorColor} />
<InfoRow label="CSCA Hash Function" value={passportMetaData?.cscaHashFunction || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="CSCA Signature Algorithm" value={passportMetaData?.cscaSignature || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="CSCA Signature Algorithm Details" value={passportMetaData?.cscaCurveOrExponent || 'None'} />
<Separator borderColor={separatorColor} />
<InfoRow label="CSCA Signature Algorithm Bits" value={passportMetaData?.cscaSignatureAlgorithmBits || 'None'} />
<Separator borderColor={separatorColor} />
</YStack>
</ScrollView>
);
};

View File

@@ -13,6 +13,7 @@ interface UserState {
passportNumber: string
dateOfBirth: string
dateOfExpiry: string
countryCode: string
registered: boolean
passportData: PassportData | null
secret: string
@@ -39,6 +40,7 @@ const useUserStore = create<UserState>((set, get) => ({
passportNumber: DEFAULT_PNUMBER ?? "",
dateOfBirth: DEFAULT_DOB ?? "",
dateOfExpiry: DEFAULT_DOE ?? "",
countryCode: "",
dscSecret: null,
registered: false,
passportData: null,

View File

@@ -46,7 +46,7 @@ export async function contribute(passportData: any): Promise<void> {
console.log("Data to be sent:", JSON.stringify(data));
const response = await axios.post('https://contribute.proofofpassport.com', {
const response = await axios.post('https://contribute.openpassport.app', {
nullifier: forge.md.sha256.create().update(passportData.encryptedDigest.toString()).digest().toHex(),
data: data
});

View File

@@ -8,6 +8,7 @@ import { Buffer } from 'buffer';
import * as amplitude from '@amplitude/analytics-react-native';
import useUserStore from '../stores/userStore';
import useNavigationStore from '../stores/navigationStore';
import { parsePassportData } from './parsePassportData';
export const scan = async (setModalProofStep: (modalProofStep: number) => void) => {
const {
@@ -177,17 +178,17 @@ const handleResponseIOS = async (
const encryptedDigestArray = Array.from(Buffer.from(signatureBase64, 'base64')).map(byte => byte > 127 ? byte - 256 : byte);
amplitude.track('nfc_response_parsed', {
dataGroupsPresent: parsed?.dataGroupsPresent,
eContentLength: signedEContentArray?.length,
concatenatedDataHashesLength: concatenatedDataHashesArraySigned?.length,
encryptedDigestLength: encryptedDigestArray?.length,
activeAuthenticationPassed: parsed?.activeAuthenticationPassed,
isPACESupported: parsed?.isPACESupported,
isChipAuthenticationSupported: parsed?.isChipAuthenticationSupported,
encapsulatedContentDigestAlgorithm: parsed?.encapsulatedContentDigestAlgorithm,
dsc: pem,
});
// amplitude.track('nfc_response_parsed', {
// dataGroupsPresent: parsed?.dataGroupsPresent,
// eContentLength: signedEContentArray?.length,
// concatenatedDataHashesLength: concatenatedDataHashesArraySigned?.length,
// encryptedDigestLength: encryptedDigestArray?.length,
// activeAuthenticationPassed: parsed?.activeAuthenticationPassed,
// isPACESupported: parsed?.isPACESupported,
// isChipAuthenticationSupported: parsed?.isChipAuthenticationSupported,
// encapsulatedContentDigestAlgorithm: parsed?.encapsulatedContentDigestAlgorithm,
// dsc: pem,
// });
const passportData = {
mrz,
@@ -201,6 +202,8 @@ const handleResponseIOS = async (
photoBase64: "data:image/jpeg;base64," + parsed.passportPhoto,
mockUser: false
};
const parsedPassportData = parsePassportData(passportData);
amplitude.track('nfc_response_parsed', parsedPassportData);
try {
useUserStore.getState().registerPassportData(passportData)
@@ -280,16 +283,18 @@ const handleResponseAndroid = async (
console.log("encapContent", encapContent)
console.log("documentSigningCertificate", documentSigningCertificate)
amplitude.track('nfc_response_parsed', {
dataGroupHashesLength: passportData?.eContent?.length,
eContentLength: passportData?.eContent?.length,
encryptedDigestLength: passportData?.encryptedDigest?.length,
digestAlgorithm: digestAlgorithm,
signerInfoDigestAlgorithm: signerInfoDigestAlgorithm,
digestEncryptionAlgorithm: digestEncryptionAlgorithm,
dsc: pem,
mockUser: false
});
const parsedPassportData = parsePassportData(passportData);
amplitude.track('nfc_response_parsed', parsedPassportData);
// amplitude.track('nfc_response_parsed', {
// dataGroupHashesLength: passportData?.eContent?.length,
// eContentLength: passportData?.eContent?.length,
// encryptedDigestLength: passportData?.encryptedDigest?.length,
// digestAlgorithm: digestAlgorithm,
// signerInfoDigestAlgorithm: signerInfoDigestAlgorithm,
// digestEncryptionAlgorithm: digestEncryptionAlgorithm,
// dsc: pem,
// mockUser: false
// });
try {
await useUserStore.getState().registerPassportData(passportData)

View File

@@ -1,6 +1,8 @@
import { PassportData } from '../../../common/src/utils/types';
import { findSubarrayIndex, formatMrz, hash } from '../../../common/src/utils/utils';
import { parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
import { parseCertificateSimple } from '../../../common/src/utils/certificate_parsing/parseCertificateSimple';
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA, PublicKeyDetailsRSAPSS } from '../../../common/src/utils/certificate_parsing/dataStructure';
import { getCSCAFromSKI } from '../../../common/src/utils/csca';
export interface PassportMetadata {
dataGroups: string;
@@ -11,7 +13,18 @@ export interface PassportMetadata {
eContentHashOffset: number;
signedAttrSize: number;
signedAttrHashFunction: string;
countryCode?: string;
signatureAlgorithm: string;
signatureAlgorithmDetails: string;
curveOrExponent: string;
signatureAlgorithmBits: number;
countryCode: string;
cscaFound: boolean;
cscaHashFunction: string;
cscaSignature: string;
cscaSignatureAlgorithmDetails: string;
cscaCurveOrExponent: string;
cscaSignatureAlgorithmBits: number;
dsc: string;
}
export function findHashSizeOfEContent(eContent: number[], signedAttr: number[]) {
@@ -45,6 +58,35 @@ export function getCountryCodeFromMrz(mrz: string): string {
return mrz.substring(2, 5);
}
export function getCurveOrExponent(certData: CertificateData): string {
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
return (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
}
return (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
}
export function getSimplePublicKeyDetails(certData: CertificateData): string {
interface SimplePublicKeyDetails {
exponent?: string;
curve?: string;
hashAlgorithm?: string;
saltLength?: string;
}
const simplePublicKeyDetails: SimplePublicKeyDetails = {};
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
simplePublicKeyDetails.exponent = (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
if (certData.signatureAlgorithm === 'rsapss') {
simplePublicKeyDetails.hashAlgorithm = (certData.publicKeyDetails as PublicKeyDetailsRSAPSS).hashAlgorithm;
simplePublicKeyDetails.saltLength = (certData.publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength;
}
}
else if (certData.signatureAlgorithm === 'ecdsa') {
simplePublicKeyDetails.curve = (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
}
return JSON.stringify(simplePublicKeyDetails);
}
export function parsePassportData(passportData: PassportData): PassportMetadata {
// Extract DG1 hash info
const dg1HashInfo = passportData.mrz ?
@@ -65,10 +107,55 @@ export function parsePassportData(passportData: PassportData): PassportMetadata
const { hashFunction: eContentHashFunction, offset: eContentHashOffset } =
findHashSizeOfEContent(passportData.eContent, passportData.signedAttr);
const dscHashFunction = passportData.dsc ?
parseCertificate(passportData.dsc).hashFunction :
const parsedDsc: CertificateData | null = passportData.dsc ?
parseCertificateSimple(passportData.dsc) :
null;
const dscHashFunction = parsedDsc ?
parsedDsc.hashAlgorithm :
'unknown';
const dscSignature = parsedDsc ?
parsedDsc.signatureAlgorithm :
'unknown';
const dscSignatureAlgorithmDetails = parsedDsc ?
getSimplePublicKeyDetails(parsedDsc) :
'unknown';
const dscSignatureAlgorithmBits = parsedDsc ?
parsedDsc.publicKeyDetails?.bits :
'unknown';
const dscAKI = parsedDsc ?
parsedDsc.authorityKeyIdentifier :
'unknown';
let csca: string | null = null;
if (dscAKI) {
csca = getCSCAFromSKI(dscAKI, true);
}
const parsedCsca = csca ?
parseCertificateSimple(csca) :
null;
const cscaHashFunction = parsedCsca ?
parsedCsca.hashAlgorithm :
'unknown';
const cscaSignature = parsedCsca ?
parsedCsca.signatureAlgorithm :
'unknown';
const cscaSignatureAlgorithmDetails = parsedCsca ?
getCurveOrExponent(parsedCsca) :
'unknown';
const cscaSignatureAlgorithmBits = parsedCsca ?
parsedCsca.publicKeyDetails?.bits :
'unknown';
return {
dataGroups: passportData.dgPresents?.toString().split(',').map(item => item.replace('DG', '')).join(',') || 'None',
dg1HashFunction,
@@ -78,6 +165,17 @@ export function parsePassportData(passportData: PassportData): PassportMetadata
eContentHashOffset,
signedAttrSize: passportData.signedAttr?.length || 0,
signedAttrHashFunction: dscHashFunction,
countryCode: passportData.mrz ? getCountryCodeFromMrz(passportData.mrz) : undefined
signatureAlgorithm: dscSignature,
signatureAlgorithmDetails: dscSignatureAlgorithmDetails,
curveOrExponent: parsedDsc ? getCurveOrExponent(parsedDsc) : 'unknown',
signatureAlgorithmBits: dscSignatureAlgorithmBits ? parseInt(dscSignatureAlgorithmBits) : 0,
countryCode: passportData.mrz ? getCountryCodeFromMrz(passportData.mrz) : 'unknown',
cscaFound: !!csca,
cscaHashFunction,
cscaSignature,
cscaSignatureAlgorithmDetails,
cscaCurveOrExponent: parsedCsca ? getCurveOrExponent(parsedCsca) : 'unknown',
cscaSignatureAlgorithmBits: cscaSignatureAlgorithmBits ? parseInt(cscaSignatureAlgorithmBits) : 0,
dsc: passportData.dsc
};
}

View File

@@ -1,12 +1,13 @@
import { NativeModules, Platform, Linking } from "react-native";
// import { AppType, reconstructAppType } from "../../../common/src/utils/appType";
import useNavigationStore from '../stores/navigationStore';
import { getCircuitName, parseDSC } from "../../../common/src/utils/certificates/handleCertificate";
import { getCircuitName, getCircuitNameOld, parseDSC } from "../../../common/src/utils/certificates/handleCertificate";
import useUserStore from "../stores/userStore";
import { downloadZkey } from "./zkeyDownload";
import msgpack from "msgpack-lite";
import pako from "pako";
import { Mode, OpenPassportApp } from "../../../common/src/utils/appType";
import { parseCertificateSimple } from "../../../common/src/utils/certificate_parsing/parseCertificateSimple";
const parseUrlParams = (url: string): Map<string, string> => {
const [, queryString] = url.split('?');
@@ -98,11 +99,11 @@ const handleQRCodeScan = (result: string, toast: any, setSelectedApp: any, setSe
const openPassportApp: OpenPassportApp = unpackedData;
setSelectedApp(openPassportApp);
const sigAlgName = parseDSC(dsc);
const parsedDsc = parseCertificateSimple(dsc);
const circuitName = openPassportApp.mode === 'vc_and_disclose'
? 'vc_and_disclose'
: getCircuitName("prove" as Mode, sigAlgName.signatureAlgorithm, sigAlgName.hashFunction);
: getCircuitNameOld("prove" as Mode, parsedDsc.signatureAlgorithm, parsedDsc.hashAlgorithm);
downloadZkey(circuitName as any);
setSelectedTab("prove");

View File

@@ -2,6 +2,7 @@
import { countryCodes } from "../../../common/src/constants/constants";
import { Proof } from "../../../common/src/utils/types";
import { getCountryCodeFromMrz } from "./parsePassportData";
// The actual parsing would depend on the standard being used (TD1, TD2, TD3, MRVA, MRVB).
export function extractMRZInfo(mrzString: string) {
@@ -18,7 +19,7 @@ export function extractMRZInfo(mrzString: string) {
return {
documentNumber,
birthDate,
expiryDate
expiryDate,
};
}