summaryrefslogtreecommitdiff
path: root/rsa/cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'rsa/cli.py')
-rw-r--r--rsa/cli.py207
1 files changed, 118 insertions, 89 deletions
diff --git a/rsa/cli.py b/rsa/cli.py
index c7a24f4..5a9c797 100644
--- a/rsa/cli.py
+++ b/rsa/cli.py
@@ -34,21 +34,33 @@ def keygen() -> None:
"""Key generator."""
# Parse the CLI options
- parser = optparse.OptionParser(usage='usage: %prog [options] keysize',
- description='Generates a new RSA keypair of "keysize" bits.')
-
- parser.add_option('--pubout', type='string',
- help='Output filename for the public key. The public key is '
- 'not saved if this option is not present. You can use '
- 'pyrsa-priv2pub to create the public key file later.')
-
- parser.add_option('-o', '--out', type='string',
- help='Output filename for the private key. The key is '
- 'written to stdout if this option is not present.')
-
- parser.add_option('--form',
- help='key format of the private and public keys - default PEM',
- choices=('PEM', 'DER'), default='PEM')
+ parser = optparse.OptionParser(
+ usage="usage: %prog [options] keysize",
+ description='Generates a new RSA keypair of "keysize" bits.',
+ )
+
+ parser.add_option(
+ "--pubout",
+ type="string",
+ help="Output filename for the public key. The public key is "
+ "not saved if this option is not present. You can use "
+ "pyrsa-priv2pub to create the public key file later.",
+ )
+
+ parser.add_option(
+ "-o",
+ "--out",
+ type="string",
+ help="Output filename for the private key. The key is "
+ "written to stdout if this option is not present.",
+ )
+
+ parser.add_option(
+ "--form",
+ help="key format of the private and public keys - default PEM",
+ choices=("PEM", "DER"),
+ default="PEM",
+ )
(cli, cli_args) = parser.parse_args(sys.argv[1:])
@@ -60,44 +72,45 @@ def keygen() -> None:
keysize = int(cli_args[0])
except ValueError as ex:
parser.print_help()
- print('Not a valid number: %s' % cli_args[0], file=sys.stderr)
+ print("Not a valid number: %s" % cli_args[0], file=sys.stderr)
raise SystemExit(1) from ex
- print('Generating %i-bit key' % keysize, file=sys.stderr)
+ print("Generating %i-bit key" % keysize, file=sys.stderr)
(pub_key, priv_key) = rsa.newkeys(keysize)
# Save public key
if cli.pubout:
- print('Writing public key to %s' % cli.pubout, file=sys.stderr)
+ print("Writing public key to %s" % cli.pubout, file=sys.stderr)
data = pub_key.save_pkcs1(format=cli.form)
- with open(cli.pubout, 'wb') as outfile:
+ with open(cli.pubout, "wb") as outfile:
outfile.write(data)
# Save private key
data = priv_key.save_pkcs1(format=cli.form)
if cli.out:
- print('Writing private key to %s' % cli.out, file=sys.stderr)
- with open(cli.out, 'wb') as outfile:
+ print("Writing private key to %s" % cli.out, file=sys.stderr)
+ with open(cli.out, "wb") as outfile:
outfile.write(data)
else:
- print('Writing private key to stdout', file=sys.stderr)
+ print("Writing private key to stdout", file=sys.stderr)
sys.stdout.buffer.write(data)
class CryptoOperation(metaclass=abc.ABCMeta):
"""CLI callable that operates with input, output, and a key."""
- keyname = 'public' # or 'private'
- usage = 'usage: %%prog [options] %(keyname)s_key'
- description = ''
- operation = 'decrypt'
- operation_past = 'decrypted'
- operation_progressive = 'decrypting'
- input_help = 'Name of the file to %(operation)s. Reads from stdin if ' \
- 'not specified.'
- output_help = 'Name of the file to write the %(operation_past)s file ' \
- 'to. Written to stdout if this option is not present.'
+ keyname = "public" # or 'private'
+ usage = "usage: %%prog [options] %(keyname)s_key"
+ description = ""
+ operation = "decrypt"
+ operation_past = "decrypted"
+ operation_progressive = "decrypting"
+ input_help = "Name of the file to %(operation)s. Reads from stdin if " "not specified."
+ output_help = (
+ "Name of the file to write the %(operation_past)s file "
+ "to. Written to stdout if this option is not present."
+ )
expected_cli_args = 1
has_output = True
@@ -109,8 +122,9 @@ class CryptoOperation(metaclass=abc.ABCMeta):
self.output_help = self.output_help % self.__class__.__dict__
@abc.abstractmethod
- def perform_operation(self, indata: bytes, key: rsa.key.AbstractKey,
- cli_args: Indexable) -> typing.Any:
+ def perform_operation(
+ self, indata: bytes, key: rsa.key.AbstractKey, cli_args: Indexable
+ ) -> typing.Any:
"""Performs the program's operation.
Implement in a subclass.
@@ -141,14 +155,17 @@ class CryptoOperation(metaclass=abc.ABCMeta):
parser = optparse.OptionParser(usage=self.usage, description=self.description)
- parser.add_option('-i', '--input', type='string', help=self.input_help)
+ parser.add_option("-i", "--input", type="string", help=self.input_help)
if self.has_output:
- parser.add_option('-o', '--output', type='string', help=self.output_help)
+ parser.add_option("-o", "--output", type="string", help=self.output_help)
- parser.add_option('--keyform',
- help='Key format of the %s key - default PEM' % self.keyname,
- choices=('PEM', 'DER'), default='PEM')
+ parser.add_option(
+ "--keyform",
+ help="Key format of the %s key - default PEM" % self.keyname,
+ choices=("PEM", "DER"),
+ default="PEM",
+ )
(cli, cli_args) = parser.parse_args(sys.argv[1:])
@@ -161,8 +178,8 @@ class CryptoOperation(metaclass=abc.ABCMeta):
def read_key(self, filename: str, keyform: str) -> rsa.key.AbstractKey:
"""Reads a public or private key."""
- print('Reading %s key from %s' % (self.keyname, filename), file=sys.stderr)
- with open(filename, 'rb') as keyfile:
+ print("Reading %s key from %s" % (self.keyname, filename), file=sys.stderr)
+ with open(filename, "rb") as keyfile:
keydata = keyfile.read()
return self.key_class.load_pkcs1(keydata, keyform)
@@ -171,37 +188,39 @@ class CryptoOperation(metaclass=abc.ABCMeta):
"""Read the input file"""
if inname:
- print('Reading input from %s' % inname, file=sys.stderr)
- with open(inname, 'rb') as infile:
+ print("Reading input from %s" % inname, file=sys.stderr)
+ with open(inname, "rb") as infile:
return infile.read()
- print('Reading input from stdin', file=sys.stderr)
+ print("Reading input from stdin", file=sys.stderr)
return sys.stdin.buffer.read()
def write_outfile(self, outdata: bytes, outname: str) -> None:
"""Write the output file"""
if outname:
- print('Writing output to %s' % outname, file=sys.stderr)
- with open(outname, 'wb') as outfile:
+ print("Writing output to %s" % outname, file=sys.stderr)
+ with open(outname, "wb") as outfile:
outfile.write(outdata)
else:
- print('Writing output to stdout', file=sys.stderr)
+ print("Writing output to stdout", file=sys.stderr)
sys.stdout.buffer.write(outdata)
class EncryptOperation(CryptoOperation):
"""Encrypts a file."""
- keyname = 'public'
- description = ('Encrypts a file. The file must be shorter than the key '
- 'length in order to be encrypted.')
- operation = 'encrypt'
- operation_past = 'encrypted'
- operation_progressive = 'encrypting'
-
- def perform_operation(self, indata: bytes, pub_key: rsa.key.AbstractKey,
- cli_args: Indexable = ()) -> bytes:
+ keyname = "public"
+ description = (
+ "Encrypts a file. The file must be shorter than the key " "length in order to be encrypted."
+ )
+ operation = "encrypt"
+ operation_past = "encrypted"
+ operation_progressive = "encrypting"
+
+ def perform_operation(
+ self, indata: bytes, pub_key: rsa.key.AbstractKey, cli_args: Indexable = ()
+ ) -> bytes:
"""Encrypts files."""
assert isinstance(pub_key, rsa.key.PublicKey)
return rsa.encrypt(indata, pub_key)
@@ -210,16 +229,19 @@ class EncryptOperation(CryptoOperation):
class DecryptOperation(CryptoOperation):
"""Decrypts a file."""
- keyname = 'private'
- description = ('Decrypts a file. The original file must be shorter than '
- 'the key length in order to have been encrypted.')
- operation = 'decrypt'
- operation_past = 'decrypted'
- operation_progressive = 'decrypting'
+ keyname = "private"
+ description = (
+ "Decrypts a file. The original file must be shorter than "
+ "the key length in order to have been encrypted."
+ )
+ operation = "decrypt"
+ operation_past = "decrypted"
+ operation_progressive = "decrypting"
key_class = rsa.PrivateKey
- def perform_operation(self, indata: bytes, priv_key: rsa.key.AbstractKey,
- cli_args: Indexable = ()) -> bytes:
+ def perform_operation(
+ self, indata: bytes, priv_key: rsa.key.AbstractKey, cli_args: Indexable = ()
+ ) -> bytes:
"""Decrypts files."""
assert isinstance(priv_key, rsa.key.PrivateKey)
return rsa.decrypt(indata, priv_key)
@@ -228,28 +250,32 @@ class DecryptOperation(CryptoOperation):
class SignOperation(CryptoOperation):
"""Signs a file."""
- keyname = 'private'
- usage = 'usage: %%prog [options] private_key hash_method'
- description = ('Signs a file, outputs the signature. Choose the hash '
- 'method from %s' % ', '.join(HASH_METHODS))
- operation = 'sign'
- operation_past = 'signature'
- operation_progressive = 'Signing'
+ keyname = "private"
+ usage = "usage: %%prog [options] private_key hash_method"
+ description = (
+ "Signs a file, outputs the signature. Choose the hash "
+ "method from %s" % ", ".join(HASH_METHODS)
+ )
+ operation = "sign"
+ operation_past = "signature"
+ operation_progressive = "Signing"
key_class = rsa.PrivateKey
expected_cli_args = 2
- output_help = ('Name of the file to write the signature to. Written '
- 'to stdout if this option is not present.')
+ output_help = (
+ "Name of the file to write the signature to. Written "
+ "to stdout if this option is not present."
+ )
- def perform_operation(self, indata: bytes, priv_key: rsa.key.AbstractKey,
- cli_args: Indexable) -> bytes:
+ def perform_operation(
+ self, indata: bytes, priv_key: rsa.key.AbstractKey, cli_args: Indexable
+ ) -> bytes:
"""Signs files."""
assert isinstance(priv_key, rsa.key.PrivateKey)
hash_method = cli_args[1]
if hash_method not in HASH_METHODS:
- raise SystemExit('Invalid hash method, choose one of %s' %
- ', '.join(HASH_METHODS))
+ raise SystemExit("Invalid hash method, choose one of %s" % ", ".join(HASH_METHODS))
return rsa.sign(indata, priv_key, hash_method)
@@ -257,33 +283,36 @@ class SignOperation(CryptoOperation):
class VerifyOperation(CryptoOperation):
"""Verify a signature."""
- keyname = 'public'
- usage = 'usage: %%prog [options] public_key signature_file'
- description = ('Verifies a signature, exits with status 0 upon success, '
- 'prints an error message and exits with status 1 upon error.')
- operation = 'verify'
- operation_past = 'verified'
- operation_progressive = 'Verifying'
+ keyname = "public"
+ usage = "usage: %%prog [options] public_key signature_file"
+ description = (
+ "Verifies a signature, exits with status 0 upon success, "
+ "prints an error message and exits with status 1 upon error."
+ )
+ operation = "verify"
+ operation_past = "verified"
+ operation_progressive = "Verifying"
key_class = rsa.PublicKey
expected_cli_args = 2
has_output = False
- def perform_operation(self, indata: bytes, pub_key: rsa.key.AbstractKey,
- cli_args: Indexable) -> None:
+ def perform_operation(
+ self, indata: bytes, pub_key: rsa.key.AbstractKey, cli_args: Indexable
+ ) -> None:
"""Verifies files."""
assert isinstance(pub_key, rsa.key.PublicKey)
signature_file = cli_args[1]
- with open(signature_file, 'rb') as sigfile:
+ with open(signature_file, "rb") as sigfile:
signature = sigfile.read()
try:
rsa.verify(indata, signature, pub_key)
except rsa.VerificationError as ex:
- raise SystemExit('Verification failed.') from ex
+ raise SystemExit("Verification failed.") from ex
- print('Verification OK', file=sys.stderr)
+ print("Verification OK", file=sys.stderr)
encrypt = EncryptOperation()