Skip to content

Commit 8c000d9

Browse files
authored
chore: signing bug (#315)
1 parent 9b0ec98 commit 8c000d9

File tree

3 files changed

+130
-6
lines changed

3 files changed

+130
-6
lines changed

infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
requestPermissions,
1717
scan,
1818
} from "@tauri-apps/plugin-barcode-scanner";
19+
import {
20+
exists,
21+
generate,
22+
getPublicKey,
23+
signPayload,
24+
// verifySignature
25+
} from "@auvo/tauri-plugin-crypto-hw-api";
1926
import axios from "axios";
2027
import { getContext, onDestroy, onMount } from "svelte";
2128
import type { SVGAttributes } from "svelte/elements";
@@ -401,15 +408,40 @@
401408
});
402409
}
403410
404-
// In a real implementation, you would use the vault's signing capabilities
405-
// For now, we'll simulate the signing process
406-
await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate signing delay
411+
// 🔐 REAL CRYPTOGRAPHIC SIGNING using Tauri crypto plugin
412+
console.log("🔐 Starting cryptographic signing process...");
413+
414+
// Check if crypto hardware exists
415+
const cryptoExists = await exists("default");
416+
if (!cryptoExists) {
417+
throw new Error("Cryptographic hardware not available");
418+
}
419+
420+
// Generate default key if it doesn't exist
421+
try {
422+
await generate("default");
423+
console.log("✅ Default key generated/verified");
424+
} catch (error) {
425+
console.log(
426+
"Default key already exists or generation failed:",
427+
error,
428+
);
429+
}
430+
431+
// Get the public key
432+
const publicKey = await getPublicKey("default");
433+
console.log("🔑 Public key retrieved:", publicKey);
434+
435+
// Sign the message payload
436+
console.log("✍️ Signing message:", messageToSign);
437+
const signature = await signPayload("default", messageToSign);
438+
console.log("✅ Message signed successfully");
407439
408-
// Create the signed payload
440+
// Create the signed payload with real signature
409441
const signedPayload = {
410442
sessionId: signingSessionId,
411-
signature: "simulated_signature_" + Date.now(), // In real implementation, this would be the actual signature
412-
publicKey: vault?.ename || "unknown_public_key", // Use eName as public key for now
443+
signature: signature,
444+
publicKey: vault?.ename || "unknown_public_key", // Use eName as public key
413445
message: messageToSign,
414446
};
415447
@@ -560,6 +592,36 @@
560592
throw new Error("No vault available for blind voting");
561593
}
562594
595+
// 🔐 Get the real public key for voter identification
596+
let voterPublicKey: string;
597+
try {
598+
const cryptoExists = await exists("default");
599+
if (!cryptoExists) {
600+
throw new Error("Cryptographic hardware not available");
601+
}
602+
603+
// Generate default key if it doesn't exist
604+
try {
605+
await generate("default");
606+
console.log(
607+
"✅ Default key generated/verified for blind voting",
608+
);
609+
} catch (edit) {
610+
console.log(
611+
"Default key already exists or generation failed:",
612+
edit,
613+
);
614+
}
615+
616+
// Get the public key
617+
voterPublicKey = await getPublicKey("default");
618+
console.log("🔑 Voter public key retrieved:", voterPublicKey);
619+
} catch (error) {
620+
console.error("Failed to get cryptographic public key:", error);
621+
// Fallback to ename if crypto fails
622+
voterPublicKey = vault.ename || "unknown_public_key";
623+
}
624+
563625
// Dynamically import the blindvote library
564626
const { VotingSystem } = await import("blindvote");
565627

platforms/evoting-api/src/services/SigningService.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,37 @@ export class SigningService {
128128
}
129129

130130
try {
131+
// 🔐 SECURITY ASSERTION: Verify that the publicKey matches the user's ename who created the session
132+
try {
133+
const { UserService } = await import('./UserService');
134+
const userService = new UserService();
135+
const user = await userService.getUserById(session.userId);
136+
137+
if (!user) {
138+
return { success: false, error: "User not found for session" };
139+
}
140+
141+
// Strip @ prefix from both enames before comparison
142+
const cleanPublicKey = publicKey.replace(/^@/, '');
143+
const cleanUserEname = user.ename.replace(/^@/, '');
144+
145+
if (cleanPublicKey !== cleanUserEname) {
146+
console.error(`🔒 SECURITY VIOLATION: publicKey mismatch!`, {
147+
publicKey,
148+
userEname: user.ename,
149+
cleanPublicKey,
150+
cleanUserEname,
151+
sessionUserId: session.userId
152+
});
153+
return { success: false, error: "Public key does not match the user who created this signing session" };
154+
}
155+
156+
console.log(`✅ Public key verification passed: ${cleanPublicKey} matches ${cleanUserEname}`);
157+
} catch (error) {
158+
console.error("Error during public key verification:", error);
159+
return { success: false, error: "Failed to verify public key: " + (error instanceof Error ? error.message : "Unknown error") };
160+
}
161+
131162
// Verify the signature (basic verification for now)
132163
// In production, you'd want proper cryptographic verification
133164
const expectedMessage = JSON.stringify({

platforms/group-charter-manager-api/src/services/CharterSigningService.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,37 @@ export class CharterSigningService {
114114
throw new Error("Invalid signature data");
115115
}
116116

117+
// 🔐 SECURITY ASSERTION: Verify that the publicKey matches the user's ename who created the session
118+
try {
119+
const { UserService } = await import('./UserService');
120+
const userService = new UserService();
121+
const user = await userService.getUserById(session.userId);
122+
123+
if (!user) {
124+
throw new Error("User not found for session");
125+
}
126+
127+
// Strip @ prefix from both enames before comparison
128+
const cleanPublicKey = publicKey.replace(/^@/, '');
129+
const cleanUserEname = user.ename.replace(/^@/, '');
130+
131+
if (cleanPublicKey !== cleanUserEname) {
132+
console.error(`🔒 SECURITY VIOLATION: publicKey mismatch!`, {
133+
publicKey,
134+
userEname: user.ename,
135+
cleanPublicKey,
136+
cleanUserEname,
137+
sessionUserId: session.userId
138+
});
139+
throw new Error("Public key does not match the user who created this signing session");
140+
}
141+
142+
console.log(`✅ Public key verification passed: ${cleanPublicKey} matches ${cleanUserEname}`);
143+
} catch (error) {
144+
console.error("Error during public key verification:", error);
145+
throw new Error("Failed to verify public key: " + (error instanceof Error ? error.message : "Unknown error"));
146+
}
147+
117148
// Record the signature in the database
118149
try {
119150
await this.signatureService.recordSignature(

0 commit comments

Comments
 (0)