Skip to content

Commit a822967

Browse files
Berend Sliedrechtberendsliedrecht
Berend Sliedrecht
authored andcommitted
fix: also compress key on iOS when fallback secure environment is used
Signed-off-by: Berend Sliedrecht <[email protected]>
1 parent 2532b32 commit a822967

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

src/index.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,42 @@ export async function generateKeypair(id: string, biometricsBacked = true): Prom
1717

1818
export async function getPublicBytesForKeyId(keyId: string): Promise<Uint8Array> {
1919
const publicBytes = await getSecureEnvironment().getPublicBytesForKeyId(keyId)
20-
let uncompressedKey = publicBytes
20+
let key = publicBytes
2121

22-
if (Platform.OS === 'android' && publicBytes.length > 65) {
22+
if (key.length > 65) {
2323
// Try to parse it from the ASN.1 SPKI format
2424
const spki = AsnParser.parse(publicBytes, SubjectPublicKeyInfo)
25-
uncompressedKey = new Uint8Array(spki.subjectPublicKey)
25+
key = new Uint8Array(spki.subjectPublicKey)
2626
}
2727

28-
if (Platform.OS === 'android') {
29-
if (uncompressedKey.length !== 65 || uncompressedKey[0] !== 0x04) {
30-
throw new Error('Invalid uncompressed key format')
31-
}
28+
if (key.length === 65 && key[0] !== 0x04) {
29+
throw new Error('Invalid uncompressed key prefix')
30+
}
3231

32+
if (key.length === 65) {
3333
// Extract the X and Y coordinates
34-
const x = uncompressedKey.slice(1, 33) // bytes 1 to 32 (X coordinate)
35-
const y = uncompressedKey.slice(33, 65) // bytes 33 to 64 (Y coordinate)
36-
34+
const x = key.slice(1, 33) // bytes 1 to 32 (X coordinate)
35+
const y = key.slice(33, 65) // bytes 33 to 64 (Y coordinate)
3736
// Determine the parity of the Y coordinate
3837
const prefix = y[y.length - 1] % 2 === 0 ? 0x02 : 0x03
39-
4038
// Return the compressed key (prefix + X coordinate)
4139
const compressedKey = new Uint8Array(33)
4240
compressedKey[0] = prefix
4341
compressedKey.set(x, 1)
44-
return compressedKey
42+
key = compressedKey
43+
}
44+
45+
if (key.length === 33 && key[0] !== 0x03 && key[0] !== 0x02) {
46+
throw new Error('Invalid compressed key prefix')
47+
}
48+
49+
if (key.length !== 33) {
50+
throw new Error(
51+
`After attempting key compression, the key has an invalid length. Expected: '33', Received: '${key.length}'`
52+
)
4553
}
4654

47-
return publicBytes
55+
return key
4856
}
4957

5058
export async function sign(keyId: string, message: Uint8Array, biometricsBacked = true): Promise<Uint8Array> {

0 commit comments

Comments
 (0)