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

Side by Side Diff: third_party/google-endpoints/rsa/cli.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « third_party/google-endpoints/rsa/bigfile.py ('k') | third_party/google-endpoints/rsa/common.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # https://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """Commandline scripts.
18
19 These scripts are called by the executables defined in setup.py.
20 """
21
22 from __future__ import with_statement, print_function
23
24 import abc
25 import sys
26 from optparse import OptionParser
27
28 import rsa
29 import rsa.bigfile
30 import rsa.pkcs1
31
32 HASH_METHODS = sorted(rsa.pkcs1.HASH_METHODS.keys())
33
34
35 def keygen():
36 """Key generator."""
37
38 # Parse the CLI options
39 parser = OptionParser(usage='usage: %prog [options] keysize',
40 description='Generates a new RSA keypair of "keysize" bits.')
41
42 parser.add_option('--pubout', type='string',
43 help='Output filename for the public key. The public key i s '
44 'not saved if this option is not present. You can use '
45 'pyrsa-priv2pub to create the public key file later.' )
46
47 parser.add_option('-o', '--out', type='string',
48 help='Output filename for the private key. The key is '
49 'written to stdout if this option is not present.')
50
51 parser.add_option('--form',
52 help='key format of the private and public keys - default PEM',
53 choices=('PEM', 'DER'), default='PEM')
54
55 (cli, cli_args) = parser.parse_args(sys.argv[1:])
56
57 if len(cli_args) != 1:
58 parser.print_help()
59 raise SystemExit(1)
60
61 try:
62 keysize = int(cli_args[0])
63 except ValueError:
64 parser.print_help()
65 print('Not a valid number: %s' % cli_args[0], file=sys.stderr)
66 raise SystemExit(1)
67
68 print('Generating %i-bit key' % keysize, file=sys.stderr)
69 (pub_key, priv_key) = rsa.newkeys(keysize)
70
71 # Save public key
72 if cli.pubout:
73 print('Writing public key to %s' % cli.pubout, file=sys.stderr)
74 data = pub_key.save_pkcs1(format=cli.form)
75 with open(cli.pubout, 'wb') as outfile:
76 outfile.write(data)
77
78 # Save private key
79 data = priv_key.save_pkcs1(format=cli.form)
80
81 if cli.out:
82 print('Writing private key to %s' % cli.out, file=sys.stderr)
83 with open(cli.out, 'wb') as outfile:
84 outfile.write(data)
85 else:
86 print('Writing private key to stdout', file=sys.stderr)
87 sys.stdout.write(data)
88
89
90 class CryptoOperation(object):
91 """CLI callable that operates with input, output, and a key."""
92
93 __metaclass__ = abc.ABCMeta
94
95 keyname = 'public' # or 'private'
96 usage = 'usage: %%prog [options] %(keyname)s_key'
97 description = None
98 operation = 'decrypt'
99 operation_past = 'decrypted'
100 operation_progressive = 'decrypting'
101 input_help = 'Name of the file to %(operation)s. Reads from stdin if ' \
102 'not specified.'
103 output_help = 'Name of the file to write the %(operation_past)s file ' \
104 'to. Written to stdout if this option is not present.'
105 expected_cli_args = 1
106 has_output = True
107
108 key_class = rsa.PublicKey
109
110 def __init__(self):
111 self.usage = self.usage % self.__class__.__dict__
112 self.input_help = self.input_help % self.__class__.__dict__
113 self.output_help = self.output_help % self.__class__.__dict__
114
115 @abc.abstractmethod
116 def perform_operation(self, indata, key, cli_args=None):
117 """Performs the program's operation.
118
119 Implement in a subclass.
120
121 :returns: the data to write to the output.
122 """
123
124 def __call__(self):
125 """Runs the program."""
126
127 (cli, cli_args) = self.parse_cli()
128
129 key = self.read_key(cli_args[0], cli.keyform)
130
131 indata = self.read_infile(cli.input)
132
133 print(self.operation_progressive.title(), file=sys.stderr)
134 outdata = self.perform_operation(indata, key, cli_args)
135
136 if self.has_output:
137 self.write_outfile(outdata, cli.output)
138
139 def parse_cli(self):
140 """Parse the CLI options
141
142 :returns: (cli_opts, cli_args)
143 """
144
145 parser = OptionParser(usage=self.usage, description=self.description)
146
147 parser.add_option('-i', '--input', type='string', help=self.input_help)
148
149 if self.has_output:
150 parser.add_option('-o', '--output', type='string', help=self.output_ help)
151
152 parser.add_option('--keyform',
153 help='Key format of the %s key - default PEM' % self.k eyname,
154 choices=('PEM', 'DER'), default='PEM')
155
156 (cli, cli_args) = parser.parse_args(sys.argv[1:])
157
158 if len(cli_args) != self.expected_cli_args:
159 parser.print_help()
160 raise SystemExit(1)
161
162 return cli, cli_args
163
164 def read_key(self, filename, keyform):
165 """Reads a public or private key."""
166
167 print('Reading %s key from %s' % (self.keyname, filename), file=sys.stde rr)
168 with open(filename, 'rb') as keyfile:
169 keydata = keyfile.read()
170
171 return self.key_class.load_pkcs1(keydata, keyform)
172
173 def read_infile(self, inname):
174 """Read the input file"""
175
176 if inname:
177 print('Reading input from %s' % inname, file=sys.stderr)
178 with open(inname, 'rb') as infile:
179 return infile.read()
180
181 print('Reading input from stdin', file=sys.stderr)
182 return sys.stdin.read()
183
184 def write_outfile(self, outdata, outname):
185 """Write the output file"""
186
187 if outname:
188 print('Writing output to %s' % outname, file=sys.stderr)
189 with open(outname, 'wb') as outfile:
190 outfile.write(outdata)
191 else:
192 print('Writing output to stdout', file=sys.stderr)
193 sys.stdout.write(outdata)
194
195
196 class EncryptOperation(CryptoOperation):
197 """Encrypts a file."""
198
199 keyname = 'public'
200 description = ('Encrypts a file. The file must be shorter than the key '
201 'length in order to be encrypted. For larger files, use the '
202 'pyrsa-encrypt-bigfile command.')
203 operation = 'encrypt'
204 operation_past = 'encrypted'
205 operation_progressive = 'encrypting'
206
207 def perform_operation(self, indata, pub_key, cli_args=None):
208 """Encrypts files."""
209
210 return rsa.encrypt(indata, pub_key)
211
212
213 class DecryptOperation(CryptoOperation):
214 """Decrypts a file."""
215
216 keyname = 'private'
217 description = ('Decrypts a file. The original file must be shorter than '
218 'the key length in order to have been encrypted. For larger '
219 'files, use the pyrsa-decrypt-bigfile command.')
220 operation = 'decrypt'
221 operation_past = 'decrypted'
222 operation_progressive = 'decrypting'
223 key_class = rsa.PrivateKey
224
225 def perform_operation(self, indata, priv_key, cli_args=None):
226 """Decrypts files."""
227
228 return rsa.decrypt(indata, priv_key)
229
230
231 class SignOperation(CryptoOperation):
232 """Signs a file."""
233
234 keyname = 'private'
235 usage = 'usage: %%prog [options] private_key hash_method'
236 description = ('Signs a file, outputs the signature. Choose the hash '
237 'method from %s' % ', '.join(HASH_METHODS))
238 operation = 'sign'
239 operation_past = 'signature'
240 operation_progressive = 'Signing'
241 key_class = rsa.PrivateKey
242 expected_cli_args = 2
243
244 output_help = ('Name of the file to write the signature to. Written '
245 'to stdout if this option is not present.')
246
247 def perform_operation(self, indata, priv_key, cli_args):
248 """Signs files."""
249
250 hash_method = cli_args[1]
251 if hash_method not in HASH_METHODS:
252 raise SystemExit('Invalid hash method, choose one of %s' %
253 ', '.join(HASH_METHODS))
254
255 return rsa.sign(indata, priv_key, hash_method)
256
257
258 class VerifyOperation(CryptoOperation):
259 """Verify a signature."""
260
261 keyname = 'public'
262 usage = 'usage: %%prog [options] public_key signature_file'
263 description = ('Verifies a signature, exits with status 0 upon success, '
264 'prints an error message and exits with status 1 upon error.' )
265 operation = 'verify'
266 operation_past = 'verified'
267 operation_progressive = 'Verifying'
268 key_class = rsa.PublicKey
269 expected_cli_args = 2
270 has_output = False
271
272 def perform_operation(self, indata, pub_key, cli_args):
273 """Verifies files."""
274
275 signature_file = cli_args[1]
276
277 with open(signature_file, 'rb') as sigfile:
278 signature = sigfile.read()
279
280 try:
281 rsa.verify(indata, signature, pub_key)
282 except rsa.VerificationError:
283 raise SystemExit('Verification failed.')
284
285 print('Verification OK', file=sys.stderr)
286
287
288 class BigfileOperation(CryptoOperation):
289 """CryptoOperation that doesn't read the entire file into memory."""
290
291 def __init__(self):
292 CryptoOperation.__init__(self)
293
294 self.file_objects = []
295
296 def __del__(self):
297 """Closes any open file handles."""
298
299 for fobj in self.file_objects:
300 fobj.close()
301
302 def __call__(self):
303 """Runs the program."""
304
305 (cli, cli_args) = self.parse_cli()
306
307 key = self.read_key(cli_args[0], cli.keyform)
308
309 # Get the file handles
310 infile = self.get_infile(cli.input)
311 outfile = self.get_outfile(cli.output)
312
313 # Call the operation
314 print(self.operation_progressive.title(), file=sys.stderr)
315 self.perform_operation(infile, outfile, key, cli_args)
316
317 def get_infile(self, inname):
318 """Returns the input file object"""
319
320 if inname:
321 print('Reading input from %s' % inname, file=sys.stderr)
322 fobj = open(inname, 'rb')
323 self.file_objects.append(fobj)
324 else:
325 print('Reading input from stdin', file=sys.stderr)
326 fobj = sys.stdin
327
328 return fobj
329
330 def get_outfile(self, outname):
331 """Returns the output file object"""
332
333 if outname:
334 print('Will write output to %s' % outname, file=sys.stderr)
335 fobj = open(outname, 'wb')
336 self.file_objects.append(fobj)
337 else:
338 print('Will write output to stdout', file=sys.stderr)
339 fobj = sys.stdout
340
341 return fobj
342
343
344 class EncryptBigfileOperation(BigfileOperation):
345 """Encrypts a file to VARBLOCK format."""
346
347 keyname = 'public'
348 description = ('Encrypts a file to an encrypted VARBLOCK file. The file '
349 'can be larger than the key length, but the output file is on ly '
350 'compatible with Python-RSA.')
351 operation = 'encrypt'
352 operation_past = 'encrypted'
353 operation_progressive = 'encrypting'
354
355 def perform_operation(self, infile, outfile, pub_key, cli_args=None):
356 """Encrypts files to VARBLOCK."""
357
358 return rsa.bigfile.encrypt_bigfile(infile, outfile, pub_key)
359
360
361 class DecryptBigfileOperation(BigfileOperation):
362 """Decrypts a file in VARBLOCK format."""
363
364 keyname = 'private'
365 description = ('Decrypts an encrypted VARBLOCK file that was encrypted '
366 'with pyrsa-encrypt-bigfile')
367 operation = 'decrypt'
368 operation_past = 'decrypted'
369 operation_progressive = 'decrypting'
370 key_class = rsa.PrivateKey
371
372 def perform_operation(self, infile, outfile, priv_key, cli_args=None):
373 """Decrypts a VARBLOCK file."""
374
375 return rsa.bigfile.decrypt_bigfile(infile, outfile, priv_key)
376
377
378 encrypt = EncryptOperation()
379 decrypt = DecryptOperation()
380 sign = SignOperation()
381 verify = VerifyOperation()
382 encrypt_bigfile = EncryptBigfileOperation()
383 decrypt_bigfile = DecryptBigfileOperation()
OLDNEW
« no previous file with comments | « third_party/google-endpoints/rsa/bigfile.py ('k') | third_party/google-endpoints/rsa/common.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698