Skip to content

Commit 308b46c

Browse files
taneltmmrts
authored andcommitted
fix: Backwards compatibility issue when hash length doesn't match algo
Resolves WE2-620 Signed-off-by: Tanel Metsar <tanel.metsar@cgi.com>
1 parent 029272f commit 308b46c

File tree

4 files changed

+74
-23
lines changed

4 files changed

+74
-23
lines changed

src/background/actions/TokenSigning/digestCommands.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/background/actions/TokenSigning/sign.ts

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,34 @@ import {
3232
import ByteArray from "../../../shared/ByteArray";
3333
import NativeAppService from "../../services/NativeAppService";
3434
import config from "../../../config";
35-
import digestCommands from "./digestCommands";
3635
import errorToResponse from "./errorToResponse";
3736
import threeLetterLanguageCodes from "./threeLetterLanguageCodes";
3837
import { throwAfterTimeout } from "../../../shared/utils/timing";
3938
import tokenSigningResponse from "../../../shared/tokenSigningResponse";
4039

40+
41+
const digestCommandToHashFunction = {
42+
"sha224": "SHA-224",
43+
"sha256": "SHA-256",
44+
"sha384": "SHA-384",
45+
"sha512": "SHA-512",
46+
"sha3-224": "SHA3-224",
47+
"sha3-256": "SHA3-256",
48+
"sha3-384": "SHA3-384",
49+
"sha3-512": "SHA3-512",
50+
} as Record<string, string>;
51+
52+
const hashFunctionToLength = {
53+
"SHA-224": 28,
54+
"SHA-256": 32,
55+
"SHA-384": 48,
56+
"SHA-512": 64,
57+
"SHA3-224": 28,
58+
"SHA3-256": 32,
59+
"SHA3-384": 48,
60+
"SHA3-512": 64,
61+
} as Record<string, number>;
62+
4163
export default async function sign(
4264
nonce: string,
4365
sourceUrl: string,
@@ -53,18 +75,54 @@ export default async function sign(
5375
const nativeAppService = new NativeAppService();
5476

5577
try {
78+
const warnings: Array<string> = [];
5679
const nativeAppStatus = await nativeAppService.connect();
5780

5881
config.DEBUG && console.log("Sign: connected to native", nativeAppStatus);
5982

83+
let hashFunction = (
84+
Object.keys(digestCommandToHashFunction).includes(algorithm)
85+
? digestCommandToHashFunction[algorithm]
86+
: algorithm
87+
);
88+
89+
const expectedHashByteLength = (
90+
Object.keys(hashFunctionToLength).includes(hashFunction)
91+
? hashFunctionToLength[hashFunction]
92+
: undefined
93+
);
94+
95+
const hashByteArray = new ByteArray().fromHex(hash);
96+
97+
if (hashByteArray.length !== expectedHashByteLength) {
98+
warnings.push(
99+
`${algorithm} hash must be ${expectedHashByteLength} bytes long.\n` +
100+
`The provided hash was ${hashByteArray.length} bytes long.\n` +
101+
"See further details at https://github.com/web-eid/web-eid-webextension#hwcrypto-compatibility"
102+
);
103+
104+
const autodetectedHashFunction = Object.keys(hashFunctionToLength).find((hashFunctionName) => (
105+
hashFunctionToLength[hashFunctionName] == hashByteArray.length)
106+
);
107+
108+
if (autodetectedHashFunction) {
109+
warnings.push(
110+
`Changed the algorithm from ${hashFunction} to ${autodetectedHashFunction} in order to match the hash length`
111+
);
112+
113+
hashFunction = autodetectedHashFunction;
114+
}
115+
}
116+
60117
const message: NativeSignRequest = {
61118
command: "sign",
62119

63120
arguments: {
64-
hash: new ByteArray().fromHex(hash).toBase64(),
65-
hashFunction: Object.keys(digestCommands).includes(algorithm) ? digestCommands[algorithm] : algorithm,
66-
origin: (new URL(sourceUrl)).origin,
67-
certificate: new ByteArray().fromHex(certificate).toBase64(),
121+
hashFunction,
122+
123+
hash: hashByteArray.toBase64(),
124+
origin: (new URL(sourceUrl)).origin,
125+
certificate: new ByteArray().fromHex(certificate).toBase64(),
68126

69127
...(lang ? { lang } : {}),
70128
},
@@ -80,6 +138,8 @@ export default async function sign(
80138
} else {
81139
return tokenSigningResponse<TokenSigningSignResponse>("ok", nonce, {
82140
signature: new ByteArray().fromBase64(response.signature).toHex(),
141+
142+
warnings,
83143
});
84144
}
85145
} catch (error) {

src/content/content.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ window.addEventListener("message", async (event) => {
108108

109109
window.postMessage(response, event.origin);
110110
} else {
111-
window.postMessage(await send(event.data), event.origin);
111+
const response = await send(event.data) as { warnings?: [], [key: string]: any } | void;
112+
113+
response?.warnings?.forEach((warning) => console.warn(warning));
114+
115+
window.postMessage(response, event.origin);
112116
}
113117
}
114118
});

src/shared/ByteArray.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
export default class ByteArray {
3333
data: number[];
3434

35+
get length(): number {
36+
return this.data.length;
37+
}
38+
3539
constructor(byteArray?: number[]) {
3640
this.data = byteArray || [];
3741
}

0 commit comments

Comments
 (0)