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

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: typo 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
71 def GetCRXHash(filename): 78 def GetPublicKeyFromPath(filepath):
72 f = open(filename, 'rb') 79 # Normalize the path for windows to have capital drive letters.
73 pub_key = GetPublicKey(f) 80 # We intentionally don't check if sys.platform == 'win32' and just
74 f.close() 81 # check if this looks like drive letter so that we can test this
82 # even on posix systems.
83 if (len(filepath) >= 2 and
84 filepath[0].islower() and
85 filepath[1] == ':'):
86 return filepath[0].upper() + filepath[1:]
87 return filepath
88
89 def GetPublicKeyUnpacked(f, filepath):
90 manifest = json.load(f)
91 if 'key' not in manifest:
92 # Use the path as the public key.
93 # See Extension::GenerateIdForPath in extension.cc
94 return GetPublicKeyFromPath(filepath)
95 else:
96 return base64.standard_b64decode(manifest['key'])
97
98 def GetPublicKey(filename, from_test_path):
99 if from_test_path:
100 return GetPublicKeyFromPath(filename)
101
102 pub_key = ''
103 if os.path.isdir(filename):
104 # Assume it's an unpacked extension
105 f = open(os.path.join(filename, 'manifest.json'), 'rb')
106 pub_key = GetPublicKeyUnpacked(f, filename)
107 f.close()
108 else:
109 # Assume it's a packed extension.
110 f = open(filename, 'rb')
111 pub_key = GetPublicKeyPacked(f)
112 f.close()
113 return pub_key
114
115 def GetCRXHash(filename, from_test_path=False):
116 pub_key = GetPublicKey(filename, from_test_path)
75 pub_key_hash = hashlib.sha256(pub_key).digest() 117 pub_key_hash = hashlib.sha256(pub_key).digest()
76 return HexTo256(pub_key_hash) 118 return HexTo256(pub_key_hash)
77 119
78 def GetCRXAppID(filename): 120 def GetCRXAppID(filename, from_test_path=False):
79 f = open(filename, 'rb') 121 pub_key = GetPublicKey(filename, from_test_path)
80 pub_key = GetPublicKey(f)
81 f.close()
82 pub_key_hash = hashlib.sha256(pub_key).digest() 122 pub_key_hash = hashlib.sha256(pub_key).digest()
83 # AppID is the MPDecimal of only the first 128 bits of the hash. 123 # AppID is the MPDecimal of only the first 128 bits of the hash.
84 return HexToMPDecimal(pub_key_hash[:128/8]) 124 return HexToMPDecimal(pub_key_hash[:128/8])
85 125
86
87 def main(argv): 126 def main(argv):
88 if len(argv) != 2: 127 if len(argv) != 2:
89 usage(argv) 128 usage(argv)
90 return 1 129 return 1
91 print 'Raw Bytes: %s' % GetCRXHash(sys.argv[1]) 130 print 'Raw Bytes: %s' % GetCRXHash(sys.argv[1])
92 print 'AppID: %s' % GetCRXAppID(sys.argv[1]) 131 print 'AppID: %s' % GetCRXAppID(sys.argv[1])
93 132
94 133
95 if __name__ == '__main__': 134 if __name__ == '__main__':
96 sys.exit(main(sys.argv)) 135 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