Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions website/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@noble/curves": "^2.0.1",
"@noble/hashes": "^2.0.1",
"bwip-js": "^4.5.1",
"dosipas-ts": "^3.0.0",
"dosipas-ts": "^4.0.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"zxing-wasm": "^2.2.1"
Expand Down
19 changes: 11 additions & 8 deletions website/src/components/EncodeTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,10 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
// Generate Level 1 signature
// -------------------------------------------------------------------------

const handleGenerateL1Sig = useCallback(() => {
const handleGenerateL1Sig = useCallback(async () => {
try {
const prepared = buildPreparedTicket();
const sig = signLevel1Data(prepared, l1PrivKey, l1Curve);
const sig = await signLevel1Data(prepared, l1PrivKey, l1Curve);
const sigHex = bytesToHex(sig);
setL1SigHex(sigHex);
setL1SigStale(false);
Expand All @@ -448,7 +448,7 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
// Generate Level 2 signature
// -------------------------------------------------------------------------

const handleGenerateL2Sig = useCallback(() => {
const handleGenerateL2Sig = useCallback(async () => {
if (!l1SigHex) {
setL2SigError('Level 1 signature must be generated first');
return;
Expand All @@ -462,7 +462,7 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
level1Signature: hexToBytes(l1SigHex),
},
};
const sig = signLevel2Data(withL1Sig, l2PrivKey, l2Curve);
const sig = await signLevel2Data(withL1Sig, l2PrivKey, l2Curve);
const sigHex = bytesToHex(sig);
setL2SigHex(sigHex);
setL2SigStale(false);
Expand Down Expand Up @@ -579,7 +579,9 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
regenRef.current = { ...params, ticket: updatedTicket };
setTicket(updatedTicket);

// Full sign+encode for dynamic refresh
// Full sign+encode for dynamic refresh (async, outside the
// synchronous state updater)
void (async () => {
try {
const level1Key: KeyPair = {
privateKey: hexToBytes(params.l1PrivKey),
Expand All @@ -591,7 +593,7 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
publicKey: getPublicKey(params.l2PrivKey, params.l2Curve),
curve: params.l2Curve as CurveName,
};
const refreshedBytes = signTicket(updatedTicket, level1Key, level2Key);
const refreshedBytes = await signTicket(updatedTicket, level1Key, level2Key);
const refreshedHex = bytesToHex(refreshedBytes);
setHex(refreshedHex);
setBytes(refreshedBytes);
Expand All @@ -611,7 +613,7 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
},
},
};
const l1Sig = signLevel1Data(prepTicket, params.l1PrivKey, params.l1Curve);
const l1Sig = await signLevel1Data(prepTicket, params.l1PrivKey, params.l1Curve);
setL1SigHex(bytesToHex(l1Sig));
setL1SigStale(false);
const withL1Sig: UicBarcodeTicket = {
Expand All @@ -621,13 +623,14 @@ export default function EncodeTab({ onDecode, onControl, prefillInput, onPrefill
level1Signature: l1Sig,
},
};
const l2Sig = signLevel2Data(withL1Sig, params.l2PrivKey, params.l2Curve);
const l2Sig = await signLevel2Data(withL1Sig, params.l2PrivKey, params.l2Curve);
setL2SigHex(bytesToHex(l2Sig));
setL2SigStale(false);
setEncodeError(null);
} catch (e) {
setEncodeError(e instanceof Error ? e.message : 'Dynamic refresh failed');
}
})();
}
return dynamicRefreshInterval;
}
Expand Down
4 changes: 2 additions & 2 deletions website/src/hooks/useTicketEncode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function useTicketEncode() {
});

const encode = useCallback(
(
async (
ticket: UicBarcodeTicket,
level1PrivateKeyHex: string,
level1Curve: string,
Expand All @@ -49,7 +49,7 @@ export function useTicketEncode() {
};
}

const bytes = signTicket(ticket, level1Key, level2Key);
const bytes = await signTicket(ticket, level1Key, level2Key);
const hex = bytesToHex(bytes);

setResult({ hex, bytes, error: null, loading: false });
Expand Down
2 changes: 1 addition & 1 deletion website/src/lib/keys.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
parseKeysXml,
findKeyInXml,
getPublicKey as derivePublicKey,
derivePublicKey,
CAR_JAUNE_SIGNATURES,
} from 'dosipas-ts';
import type { Level1KeyProvider, Level1KeyMaterial, UicPublicKeyEntry } from 'dosipas-ts';
Expand Down
20 changes: 12 additions & 8 deletions website/src/lib/signing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {
signLevel1 as libSignLevel1,
signLevel2 as libSignLevel2,
encodeTicketToBytes as libEncodeTicketToBytes,
getPublicKey as libGetPublicKey,
derivePublicKey,
generateKeyPair as libGenerateKeyPair,
localSigner,
CURVES,
} from 'dosipas-ts';
import type { UicBarcodeTicket, CurveName, SigningKeyPair } from 'dosipas-ts';
Expand All @@ -17,7 +18,7 @@ export function generateKeyPair(curve: string): SigningKeyPair {
}

export function getPublicKey(privateKeyHex: string, curve: string): Uint8Array {
return libGetPublicKey(hexToBytes(privateKeyHex), curve as CurveName);
return derivePublicKey(hexToBytes(privateKeyHex), curve as CurveName);
}

/**
Expand All @@ -29,26 +30,29 @@ export function signTicket(
ticket: UicBarcodeTicket,
level1Key: SigningKeyPair,
level2Key?: SigningKeyPair,
): Uint8Array {
return signAndEncodeTicket(ticket, level1Key, level2Key);
): Promise<Uint8Array> {
return signAndEncodeTicket(ticket, {
level1: localSigner(level1Key.privateKey, level1Key.curve),
...(level2Key ? { level2: localSigner(level2Key.privateKey, level2Key.curve) } : {}),
});
}

/** Sign Level 1 data and return the DER-encoded signature bytes. */
export function signLevel1Data(
ticket: UicBarcodeTicket,
privateKeyHex: string,
curve: string,
): Uint8Array {
return libSignLevel1(ticket, hexToBytes(privateKeyHex), curve as CurveName);
): Promise<Uint8Array> {
return libSignLevel1(ticket, localSigner(hexToBytes(privateKeyHex), curve as CurveName));
}

/** Sign Level 2 data and return the DER-encoded signature bytes. */
export function signLevel2Data(
ticket: UicBarcodeTicket,
privateKeyHex: string,
curve: string,
): Uint8Array {
return libSignLevel2(ticket, hexToBytes(privateKeyHex), curve as CurveName);
): Promise<Uint8Array> {
return libSignLevel2(ticket, localSigner(hexToBytes(privateKeyHex), curve as CurveName));
}

/** Encode a ticket to bytes (with signatures already set). */
Expand Down
Loading