@@ -4,7 +4,7 @@ import * as path from 'path'
44import * as fs from 'fs'
55import { Readable } from 'stream'
66import { pipeline } from 'stream/promises'
7- import { readCrxFileHeader } from './crx3'
7+ import { readCrxFileHeader , readSignedData } from './crx3'
88import Pbf from 'pbf'
99import {
1010 ExtensionInstallStatus ,
@@ -13,6 +13,7 @@ import {
1313 WebGlStatus ,
1414} from '../common/constants'
1515import { loadAllExtensions } from './loader'
16+ import { convertHexadecimalToIDAlphabet , generateId } from './id'
1617export { loadAllExtensions } from './loader'
1718
1819const 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