Skip to content

Commit fbd96d1

Browse files
committed
fix: unable to find crx key for translate extension
1 parent 007410b commit fbd96d1

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

packages/electron-chrome-web-store/src/browser/crx3.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function readAsymmetricKeyProofField(tag: any, obj: any, pbf: Pbf) {
4747
else if (tag === 2) obj.signature = pbf.readBytes()
4848
}
4949

50-
export function readSignedData(pbf: Pbf, end: any) {
50+
export function readSignedData(pbf: Pbf, end?: any): { crx_id?: Buffer } {
5151
return pbf.readFields(readSignedDataField, { crx_id: undefined }, end)
5252
}
5353
function readSignedDataField(tag: any, obj: any, pbf: Pbf) {

packages/electron-chrome-web-store/src/browser/id.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { createHash } from 'node:crypto'
77
*
88
* @param id - The hexadecimal string to convert. This is modified in place.
99
*/
10-
function convertHexadecimalToIDAlphabet(id: string) {
10+
export function convertHexadecimalToIDAlphabet(id: string) {
1111
let result = ''
1212
for (const ch of id) {
1313
const val = parseInt(ch, 16)

packages/electron-chrome-web-store/src/browser/index.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as path from 'path'
44
import * as fs from 'fs'
55
import { Readable } from 'stream'
66
import { pipeline } from 'stream/promises'
7-
import { readCrxFileHeader } from './crx3'
7+
import { readCrxFileHeader, readSignedData } from './crx3'
88
import Pbf from 'pbf'
99
import {
1010
ExtensionInstallStatus,
@@ -13,6 +13,7 @@ import {
1313
WebGlStatus,
1414
} from '../common/constants'
1515
import { loadAllExtensions } from './loader'
16+
import { convertHexadecimalToIDAlphabet, generateId } from './id'
1617
export { loadAllExtensions } from './loader'
1718

1819
const d = require('debug')('electron-chrome-web-store')
@@ -153,13 +154,27 @@ function parseCrx(buffer: Buffer): CrxInfo {
153154
} else {
154155
// For CRX3, extract public key from header
155156
// CRX3 header contains a protocol buffer message
156-
const pbf = new Pbf(header)
157-
const crxFileHeader = readCrxFileHeader(pbf)
158-
publicKey = crxFileHeader.sha256_with_rsa[1]?.public_key
157+
const crxFileHeader = readCrxFileHeader(new Pbf(header))
158+
const crxSignedData = readSignedData(new Pbf(crxFileHeader.signed_header_data))
159+
const declaredCrxId = crxSignedData.crx_id
160+
? convertHexadecimalToIDAlphabet(crxSignedData.crx_id.toString('hex'))
161+
: null
162+
163+
if (!declaredCrxId) {
164+
throw new Error('Invalid CRX signed data')
165+
}
166+
167+
// Need to find store key proof which matches the declared ID
168+
const keyProof = crxFileHeader.sha256_with_rsa.find((proof) => {
169+
const crxId = proof.public_key ? generateId(proof.public_key.toString('base64')) : null
170+
return crxId === declaredCrxId
171+
})
159172

160-
if (!publicKey) {
161-
throw new Error('Invalid CRX header')
173+
if (!keyProof) {
174+
throw new Error('Invalid CRX key')
162175
}
176+
177+
publicKey = keyProof.public_key
163178
}
164179

165180
return {

0 commit comments

Comments
 (0)