Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: packagerSafari.py

Issue 29349869: Issue 4339 - Replace M2Crypto by PyCrypto (Closed)
Left Patch Set: Created Aug. 16, 2016, 2:59 p.m.
Right Patch Set: Addressed more nits Created Aug. 17, 2016, 7:20 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « packagerChrome.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import base64 5 import base64
6 import ConfigParser 6 import ConfigParser
7 import json 7 import json
8 import math
9 import os 8 import os
10 import re 9 import re
11 from urlparse import urlparse 10 from urlparse import urlparse
12 11
13 from packager import readMetadata, getDefaultFileName, getBuildVersion, getTempl ate, Files 12 from packager import readMetadata, getDefaultFileName, getBuildVersion, getTempl ate, Files
14 from packagerChrome import convertJS, importGeckoLocales, getIgnoredFiles, getPa ckageFiles, defaultLocale, createScriptPage 13 from packagerChrome import convertJS, importGeckoLocales, getIgnoredFiles, getPa ckageFiles, defaultLocale, createScriptPage
15 14
16 15
17 def processFile(path, data, params): 16 def processFile(path, data, params):
18 return data 17 return data
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 files[filename] = re.sub( 106 files[filename] = re.sub(
108 r'(<[^<>]*?\b(?:href|src)\s*=\s*["\']?)\/+', 107 r'(<[^<>]*?\b(?:href|src)\s*=\s*["\']?)\/+',
109 r'\1' + '/'.join(['..'] * filename.count('/') + ['']), 108 r'\1' + '/'.join(['..'] * filename.count('/') + ['']),
110 content, re.S | re.I 109 content, re.S | re.I
111 ) 110 )
112 111
113 112
114 def get_certificates_and_key(keyfile): 113 def get_certificates_and_key(keyfile):
115 from Crypto.PublicKey import RSA 114 from Crypto.PublicKey import RSA
116 115
117 certs = []
118 with open(keyfile, 'r') as file: 116 with open(keyfile, 'r') as file:
119 data = file.read() 117 data = file.read()
120 keydata = re.sub(r'(-+END PRIVATE KEY-+).*', r'\1', data, flags=re.S) 118
Sebastian Noack 2016/08/16 16:32:05 Is this even necessary? I would expect RSA.importK
Wladimir Palant 2016/08/16 17:06:04 Yes, I would expect that as well. However, I get "
Sebastian Noack 2016/08/17 08:43:07 I just noticed that this code assumes the key to b
Wladimir Palant 2016/08/17 10:03:15 True, PyCrypto seems to be angry about certificate
121 key = RSA.importKey(keydata) 119 certificates = []
122 120 key = None
123 for match in re.finditer(r'-+BEGIN CERTIFICATE-+(.*?)-+END CERTIFICATE-+', d ata, re.S): 121 for match in re.finditer(r'-+BEGIN (.*?)-+(.*?)-+END \1-+', data, re.S):
124 certs.append(base64.b64decode(match.group(1))) 122 section = match.group(1)
125 123 if section == 'CERTIFICATE':
126 return certs, key 124 certificates.append(base64.b64decode(match.group(2)))
125 elif section == 'PRIVATE KEY':
126 key = RSA.importKey(match.group(0))
127 if not key:
128 raise Exception('Could not find private key in file')
129
130 return certificates, key
131
132
133 def _get_sequence(data):
134 from Crypto.Util import asn1
135 sequence = asn1.DerSequence()
136 sequence.decode(data)
137 return sequence
127 138
128 139
129 def get_developer_identifier(certs): 140 def get_developer_identifier(certs):
130 from Crypto.Util import asn1
131 def get_sequence(data):
Sebastian Noack 2016/08/16 16:32:05 Any reason this is a nested function, and not just
Wladimir Palant 2016/08/16 17:06:04 It isn't exactly a general-purpose function - mere
Sebastian Noack 2016/08/17 08:43:07 It doesn't need to be general-purpose to go on the
Wladimir Palant 2016/08/17 10:03:15 Done.
132 sequence = asn1.DerSequence()
133 sequence.decode(data)
134 return sequence
135
136 for cert in certs: 141 for cert in certs:
137 # See https://tools.ietf.org/html/rfc5280#section-4 142 # See https://tools.ietf.org/html/rfc5280#section-4
138 tbsCertificate = get_sequence(cert)[0] 143 tbscertificate = _get_sequence(cert)[0]
Sebastian Noack 2016/08/16 16:32:05 Nit: camel case
Wladimir Palant 2016/08/16 17:06:04 I know. But that's how this field is named in the
Sebastian Noack 2016/08/17 08:43:07 That doesn't seem a reason to me, to violate PEP-8
Wladimir Palant 2016/08/17 10:03:15 Done.
139 subject = get_sequence(tbsCertificate)[5] 144 subject = _get_sequence(tbscertificate)[5]
140 145
141 # We could decode the subject but since we have to apply a regular 146 # We could decode the subject but since we have to apply a regular
142 # expression on CN entry anyway we can just skip that. 147 # expression on CN entry anyway we can just skip that.
143 m = re.search(r'Safari Developer: \((\S*?)\)', subject) 148 m = re.search(r'Safari Developer: \((\S*?)\)', subject)
144 if m: 149 if m:
145 return m.group(1) 150 return m.group(1)
146 151
147 raise Exception('No Safari developer certificate found in chain') 152 raise Exception('No Safari developer certificate found in chain')
148 153
149 154
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 os.close(fd) 203 os.close(fd)
199 204
200 # add certificates and placeholder signature 205 # add certificates and placeholder signature
201 # to the xar archive, and get data to sign 206 # to the xar archive, and get data to sign
202 fd, digest_filename = tempfile.mkstemp() 207 fd, digest_filename = tempfile.mkstemp()
203 os.close(fd) 208 os.close(fd)
204 try: 209 try:
205 subprocess.check_call( 210 subprocess.check_call(
206 [ 211 [
207 'xar', '--sign', '-f', outFile, 212 'xar', '--sign', '-f', outFile,
208 '--data-to-sign', digest_filename, 213 '--data-to-sign', digest_filename,
Wladimir Palant 2016/08/16 15:12:08 For reference: despite the misleading name, --data
Wladimir Palant 2016/08/16 15:37:38 Actually, I finally realized what's going on there
209 '--sig-size', str(len(sign_digest(key, ''))) 214 '--sig-size', str(len(sign_digest(key, '')))
210 ] + [ 215 ] + [
211 arg for cert in certificate_filenames for arg in ('--cert-lo c', cert) 216 arg for cert in certificate_filenames for arg in ('--cert-lo c', cert)
212 ] 217 ]
213 ) 218 )
214 219
215 with open(digest_filename, 'rb') as file: 220 with open(digest_filename, 'rb') as file:
216 digest = file.read() 221 digest = file.read()
217 finally: 222 finally:
218 os.unlink(digest_filename) 223 os.unlink(digest_filename)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 fixAbsoluteUrls(files) 288 fixAbsoluteUrls(files)
284 289
285 dirname = metadata.get('general', 'basename') + '.safariextension' 290 dirname = metadata.get('general', 'basename') + '.safariextension'
286 for filename in files.keys(): 291 for filename in files.keys():
287 files[os.path.join(dirname, filename)] = files.pop(filename) 292 files[os.path.join(dirname, filename)] = files.pop(filename)
288 293
289 if not devenv and keyFile: 294 if not devenv and keyFile:
290 createSignedXarArchive(outFile, files, certs, key) 295 createSignedXarArchive(outFile, files, certs, key)
291 else: 296 else:
292 files.zip(outFile) 297 files.zip(outFile)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld