Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: tools/crx_id/crx_id.py

Issue 9693014: Add support for unpacked extensions to crx_id tool. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/crx_id/crx_id_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """ Read a CRX file and write out the App ID and the Full Hash of the ID. 6 """ Read a CRX file and write out the App ID and the Full Hash of the ID.
7 See: http://code.google.com/chrome/extensions/crx.html 7 See: http://code.google.com/chrome/extensions/crx.html
8 and 'http://stackoverflow.com/questions/' 8 and 'http://stackoverflow.com/questions/'
9 + '1882981/google-chrome-alphanumeric-hashes-to-identify-extensions' 9 + '1882981/google-chrome-alphanumeric-hashes-to-identify-extensions'
10 for docs on the format. 10 for docs on the format.
11 """ 11 """
12 12
13 import base64
14 import os
13 import sys 15 import sys
14 import hashlib 16 import hashlib
15 17
18 try:
19 import json
20 except Exception:
21 import simplejson as json
16 22
17 EXPECTED_CRX_MAGIC_NUM = 'Cr24' 23 EXPECTED_CRX_MAGIC_NUM = 'Cr24'
18 EXPECTED_CRX_VERSION = 2 24 EXPECTED_CRX_VERSION = 2
19 25
20
21 def usage(argv): 26 def usage(argv):
22 print "%s: crx_file" % argv[0] 27 print "%s: crx_file" % argv[0]
23 28
24 def HexToInt(hex_chars): 29 def HexToInt(hex_chars):
25 """ Convert bytes like \xab -> 171 """ 30 """ Convert bytes like \xab -> 171 """
26 val = 0 31 val = 0
27 for i in xrange(len(hex_chars)): 32 for i in xrange(len(hex_chars)):
28 val += pow(256, i) * ord(hex_chars[i]) 33 val += pow(256, i) * ord(hex_chars[i])
29 return val 34 return val
30 35
(...skipping 16 matching lines...) Expand all
47 The format is taylored for copy and paste into C code: 52 The format is taylored for copy and paste into C code:
48 const uint8 sha256_hash[] = { ... }; """ 53 const uint8 sha256_hash[] = { ... }; """
49 result = [] 54 result = []
50 for i in xrange(len(hex_chars)): 55 for i in xrange(len(hex_chars)):
51 value = ord(hex_chars[i]) 56 value = ord(hex_chars[i])
52 dig1 = value / 16 57 dig1 = value / 16
53 dig2 = value % 16 58 dig2 = value % 16
54 result.append('0x' + hex(dig1)[2:] + hex(dig2)[2:]) 59 result.append('0x' + hex(dig1)[2:] + hex(dig2)[2:])
55 return '{%s}' % ', '.join(result) 60 return '{%s}' % ', '.join(result)
56 61
57 def GetPublicKey(f): 62 def GetPublicKeyPacked(f):
58 magic_num = f.read(4) 63 magic_num = f.read(4)
59 if magic_num != EXPECTED_CRX_MAGIC_NUM: 64 if magic_num != EXPECTED_CRX_MAGIC_NUM:
60 raise 'Invalid magic number: %s (expecting %s)' % (magic_num, 65 raise Exception('Invalid magic number: %s (expecting %s)' %
61 EXPECTED_CRX_MAGIC_NUM) 66 (magic_num,
67 EXPECTED_CRX_MAGIC_NUM))
62 version = f.read(4) 68 version = f.read(4)
63 if not version[0] != EXPECTED_CRX_VERSION: 69 if not version[0] != EXPECTED_CRX_VERSION:
64 raise 'Invalid version number: %s (expecting %s)' % (version, 70 raise Exception('Invalid version number: %s (expecting %s)' %
65 EXPECTED_CRX_VERSION) 71 (version,
72 EXPECTED_CRX_VERSION))
66 pub_key_len_bytes = HexToInt(f.read(4)) 73 pub_key_len_bytes = HexToInt(f.read(4))
67 sig_len_bytes = HexToInt(f.read(4)) 74 sig_len_bytes = HexToInt(f.read(4))
68 pub_key = f.read(pub_key_len_bytes) 75 pub_key = f.read(pub_key_len_bytes)
69 return pub_key 76 return pub_key
70 77
78 def GetPublicKeyUnpacked(f):
79 manifest = json.load(f)
80 if 'key' not in manifest:
jstritar 2012/03/13 16:55:52 I wonder if you can generate the ID from the file
81 raise Exception(
82 'Unpacked extension manifest has no key. Cannot compute AppID!')
83 pub_key = base64.standard_b64decode(manifest['key'])
84 return pub_key
85
86 def GetPublicKey(filename):
87 pub_key = ''
88 if os.path.isdir(filename):
89 # Assume it's an unpacked extension
90 f = open(os.path.join(filename, 'manifest.json'), 'rb')
91 pub_key = GetPublicKeyUnpacked(f)
92 f.close()
93 else:
94 # Assume it's a packed extension.
95 f = open(filename, 'rb')
96 pub_key = GetPublicKeyPacked(f)
97 f.close()
98 return pub_key
99
71 def GetCRXHash(filename): 100 def GetCRXHash(filename):
72 f = open(filename, 'rb') 101 pub_key = GetPublicKey(filename)
73 pub_key = GetPublicKey(f)
74 f.close()
75 pub_key_hash = hashlib.sha256(pub_key).digest() 102 pub_key_hash = hashlib.sha256(pub_key).digest()
76 return HexTo256(pub_key_hash) 103 return HexTo256(pub_key_hash)
77 104
78 def GetCRXAppID(filename): 105 def GetCRXAppID(filename):
79 f = open(filename, 'rb') 106 pub_key = GetPublicKey(filename)
80 pub_key = GetPublicKey(f)
81 f.close()
82 pub_key_hash = hashlib.sha256(pub_key).digest() 107 pub_key_hash = hashlib.sha256(pub_key).digest()
83 # AppID is the MPDecimal of only the first 128 bits of the hash. 108 # AppID is the MPDecimal of only the first 128 bits of the hash.
84 return HexToMPDecimal(pub_key_hash[:128/8]) 109 return HexToMPDecimal(pub_key_hash[:128/8])
85 110
86
87 def main(argv): 111 def main(argv):
88 if len(argv) != 2: 112 if len(argv) != 2:
89 usage(argv) 113 usage(argv)
90 return 1 114 return 1
91 print 'Raw Bytes: %s' % GetCRXHash(sys.argv[1]) 115 print 'Raw Bytes: %s' % GetCRXHash(sys.argv[1])
92 print 'AppID: %s' % GetCRXAppID(sys.argv[1]) 116 print 'AppID: %s' % GetCRXAppID(sys.argv[1])
93 117
94 118
95 if __name__ == '__main__': 119 if __name__ == '__main__':
96 sys.exit(main(sys.argv)) 120 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | tools/crx_id/crx_id_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698