Merge branch 'fix/5-genkeyinput-default-type' into develop
* FIXES issues #5 and #11 https://github.com/isislovecruft/python-gnupg/issues/5 https://github.com/isislovecruft/python-gnupg/issues/11 * ADD checks for and attribute GPG.binary_version * CHANGE to generating RSA keys for GnuPG 1.x, and 'default' keys for GnuPG 2.x, because GnuPG 1.x doesn't understand the 'Key-Type: default' batch file directive.fix/24-enc-to-file
commit
8f01040fa1
22
TODO
22
TODO
|
@ -19,7 +19,15 @@ see :compatibility:gen__key_input:
|
||||||
|
|
||||||
* Compatibility between GnuPG versions :compatibility:
|
* Compatibility between GnuPG versions :compatibility:
|
||||||
** TODO GnuPG>=2.1.0 won't allow key generation with preset passphrase
|
** TODO GnuPG>=2.1.0 won't allow key generation with preset passphrase
|
||||||
*** TODO in GPG.gen__key_input() :compatibility:gen_key_input:
|
*** DONE add version detection for GPG.gen_key_input() :compatibility:gen_key_input:
|
||||||
|
DONE: use gnupg._util._is_gpg2() and gnupg.util._is_gpg1() to check versions
|
||||||
|
|
||||||
|
If we add a GnuPG version detection feature (the version string is already
|
||||||
|
obtained in GPG.___init___() [[gnupg.py:407]]), then we can automatically chain
|
||||||
|
GPG.gen__key_input() to another new feature for '--edit-key'. This chaining
|
||||||
|
would likely need to happen here [[gnupg.py:1146]].
|
||||||
|
|
||||||
|
*** TODO passphase setting for GnuPGv2.x in GPG.gen__key_input() :compatibility:gen_key_input:
|
||||||
In the docstring of GPG.gen__key_input() [[gnupg.py:1068]], for the parameter
|
In the docstring of GPG.gen__key_input() [[gnupg.py:1068]], for the parameter
|
||||||
'passphrase', it is explained that:
|
'passphrase', it is explained that:
|
||||||
|
|
||||||
|
@ -34,16 +42,16 @@ In the docstring of GPG.gen__key_input() [[gnupg.py:1068]], for the parameter
|
||||||
passwordless key to be created, which can then
|
passwordless key to be created, which can then
|
||||||
have its passphrase set later with '--edit-key'.
|
have its passphrase set later with '--edit-key'.
|
||||||
|
|
||||||
If we add a GnuPG version detection feature (the version string is already
|
|
||||||
obtained in GPG.___init___() [[gnupg.py:407]]), then we can automatically chain
|
|
||||||
GPG.gen__key_input() to another new feature for '--edit-key'. This chaining
|
|
||||||
would likely need to happen here [[gnupg.py:1146]].
|
|
||||||
|
|
||||||
*** TODO add '--edit-key' feature :editkey:
|
*** TODO add '--edit-key' feature :editkey:
|
||||||
This would be necessary for adding a passphrase to the key after passwordless
|
This would be necessary for adding a passphrase to the key after passwordless
|
||||||
generation in GnuPG>=2.1.0.
|
generation in GnuPG>=2.1.0.
|
||||||
|
|
||||||
** TODO GnuPG==1.4.12 doesn't process "Key-Type: default" in batch files
|
** DONE GnuPG==1.4.12 doesn't process "Key-Type: default" in batch files
|
||||||
|
|
||||||
|
DONE: GnuPG version detection in gen_key_input() was added in commits
|
||||||
|
6eccbe704841cca90573dc554019712528d927a0 and
|
||||||
|
1e867d6e117f603cd9f2238641a1fb9cb87d4b51
|
||||||
|
|
||||||
(python-gnupg)∃!isisⒶwintermute:~/code/riseup/python-gnupg ∴ ipython
|
(python-gnupg)∃!isisⒶwintermute:~/code/riseup/python-gnupg ∴ ipython
|
||||||
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
|
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import encodings
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import random
|
import random
|
||||||
|
import re
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -295,6 +296,28 @@ def _is_list_or_tuple(instance):
|
||||||
"""
|
"""
|
||||||
return isinstance(instance, (list, tuple,))
|
return isinstance(instance, (list, tuple,))
|
||||||
|
|
||||||
|
def _is_gpg1(version):
|
||||||
|
"""Returns True if using GnuPG version 1.x.
|
||||||
|
|
||||||
|
:param tuple version: A tuple of three integers indication major, minor,
|
||||||
|
and micro version numbers.
|
||||||
|
"""
|
||||||
|
(major, minor, micro) = _match_version_string(version)
|
||||||
|
if major == 1:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _is_gpg2(version):
|
||||||
|
"""Returns True if using GnuPG version 2.x.
|
||||||
|
|
||||||
|
:param tuple version: A tuple of three integers indication major, minor,
|
||||||
|
and micro version numbers.
|
||||||
|
"""
|
||||||
|
(major, minor, micro) = _match_version_string(version)
|
||||||
|
if major == 2:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _make_binary_stream(s, encoding):
|
def _make_binary_stream(s, encoding):
|
||||||
"""
|
"""
|
||||||
xxx fill me in
|
xxx fill me in
|
||||||
|
@ -356,6 +379,17 @@ def _make_random_string(length):
|
||||||
chars = string.ascii_lowercase + string.ascii_uppercase + string.digits
|
chars = string.ascii_lowercase + string.ascii_uppercase + string.digits
|
||||||
return ''.join(random.choice(chars) for x in range(length))
|
return ''.join(random.choice(chars) for x in range(length))
|
||||||
|
|
||||||
|
def _match_version_string(version):
|
||||||
|
"""Sort a binary version string into major, minor, and micro integers.
|
||||||
|
|
||||||
|
:param str version: A version string in the form x.x.x
|
||||||
|
"""
|
||||||
|
regex = re.compile('(\d)*(\.)*(\d)*(\.)*(\d)*')
|
||||||
|
matched = regex.match(version)
|
||||||
|
g = matched.groups()
|
||||||
|
major, minor, micro = int(g[0]), int(g[2]), int(g[4])
|
||||||
|
return (major, minor, micro)
|
||||||
|
|
||||||
def _next_year():
|
def _next_year():
|
||||||
"""Get the date of today plus one year.
|
"""Get the date of today plus one year.
|
||||||
|
|
||||||
|
|
|
@ -137,14 +137,20 @@ class GPG(GPGBase):
|
||||||
self.temp_keyring = None
|
self.temp_keyring = None
|
||||||
#: The secring used in the most recently created batch file
|
#: The secring used in the most recently created batch file
|
||||||
self.temp_secring = None
|
self.temp_secring = None
|
||||||
|
#: The version string of our GnuPG binary
|
||||||
|
self.binary_version = str()
|
||||||
|
|
||||||
## check that everything runs alright:
|
## check that everything runs alright, and grab the gpg binary's
|
||||||
|
## version number while we're at it:
|
||||||
proc = self._open_subprocess(["--list-config", "--with-colons"])
|
proc = self._open_subprocess(["--list-config", "--with-colons"])
|
||||||
result = self._result_map['list'](self)
|
result = self._result_map['list'](self)
|
||||||
self._collect_output(proc, result, stdin=proc.stdin)
|
self._read_data(proc.stdout, result)
|
||||||
if proc.returncode != 0:
|
if proc.returncode:
|
||||||
raise RuntimeError("Error invoking gpg: %s: %s"
|
raise RuntimeError("Error invoking gpg: %s" % result.data)
|
||||||
% (proc.returncode, result.stderr))
|
|
||||||
|
version_line = str(result.data).partition(':version:')[2]
|
||||||
|
self.binary_version = version_line.split('\n')[0]
|
||||||
|
log.debug("Using GnuPG version %s" % self.binary_version)
|
||||||
|
|
||||||
def sign(self, data, **kwargs):
|
def sign(self, data, **kwargs):
|
||||||
"""Create a signature for a message string or file.
|
"""Create a signature for a message string or file.
|
||||||
|
@ -603,13 +609,14 @@ class GPG(GPGBase):
|
||||||
user ID is created.
|
user ID is created.
|
||||||
|
|
||||||
:param str key_type: One of 'RSA', 'DSA', 'ELG-E', or 'default'.
|
:param str key_type: One of 'RSA', 'DSA', 'ELG-E', or 'default'.
|
||||||
(default: 'default') Starts a new parameter block by giving the
|
(default: 'RSA', if using GnuPG v1.x, otherwise 'default') Starts
|
||||||
type of the primary key. The algorithm must be capable of
|
a new parameter block by giving the type of the primary key. The
|
||||||
signing. This is a required parameter. The algorithm may either be
|
algorithm must be capable of signing. This is a required
|
||||||
an OpenPGP algorithm number or a string with the algorithm
|
parameter. The algorithm may either be an OpenPGP algorithm number
|
||||||
name. The special value ‘default’ may be used for algo to create
|
or a string with the algorithm name. The special value ‘default’
|
||||||
the default key type; in this case a ``key_usage`` should not be
|
may be used for algo to create the default key type; in this case
|
||||||
given and 'default' must also be used for ``subkey_type``.
|
a ``key_usage`` should not be given and 'default' must also be
|
||||||
|
used for ``subkey_type``.
|
||||||
|
|
||||||
:param int key_length: The requested length of the generated key in
|
:param int key_length: The requested length of the generated key in
|
||||||
bits. (Default: 4096)
|
bits. (Default: 4096)
|
||||||
|
@ -694,18 +701,24 @@ class GPG(GPGBase):
|
||||||
http://www.gnupg.org/documentation/manuals/gnupg-devel/Unattended-GPG-key-generation.html
|
http://www.gnupg.org/documentation/manuals/gnupg-devel/Unattended-GPG-key-generation.html
|
||||||
for more details.
|
for more details.
|
||||||
"""
|
"""
|
||||||
parms = {}
|
|
||||||
|
|
||||||
#: A boolean for determining whether to set subkey_type to 'default'
|
#: A boolean for determining whether to set subkey_type to 'default'
|
||||||
default_type = False
|
default_type = False
|
||||||
|
|
||||||
name_email = kwargs.get('name_email')
|
parms = {}
|
||||||
uidemail = _util.create_uid_email(name_email)
|
|
||||||
|
|
||||||
|
## if using GnuPG version 1.x, then set the default 'Key-Type' to
|
||||||
|
## 'RSA' because it doesn't understand 'default'
|
||||||
parms.setdefault('Key-Type', 'default')
|
parms.setdefault('Key-Type', 'default')
|
||||||
|
if _util._is_gpg1(self.binary_version):
|
||||||
|
parms.setdefault('Key-Type', 'RSA')
|
||||||
|
log.debug("GnuPG v%s detected: setting default key type to %s."
|
||||||
|
% (self.binary_version, parms['Key-Type']))
|
||||||
parms.setdefault('Key-Length', 4096)
|
parms.setdefault('Key-Length', 4096)
|
||||||
parms.setdefault('Name-Real', "Autogenerated Key")
|
parms.setdefault('Name-Real', "Autogenerated Key")
|
||||||
parms.setdefault('Expire-Date', _util._next_year())
|
parms.setdefault('Expire-Date', _util._next_year())
|
||||||
|
|
||||||
|
name_email = kwargs.get('name_email')
|
||||||
|
uidemail = _util.create_uid_email(name_email)
|
||||||
parms.setdefault('Name-Email', uidemail)
|
parms.setdefault('Name-Email', uidemail)
|
||||||
|
|
||||||
if testing:
|
if testing:
|
||||||
|
|
Loading…
Reference in New Issue