diff options
Diffstat (limited to 'cloudinit/gpg.py')
-rw-r--r-- | cloudinit/gpg.py | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/cloudinit/gpg.py b/cloudinit/gpg.py index 3780326c..8daa5e37 100644 --- a/cloudinit/gpg.py +++ b/cloudinit/gpg.py @@ -7,19 +7,28 @@ """gpg.py - Collection of gpg key related functions""" +import time + from cloudinit import log as logging from cloudinit import subp -import time - LOG = logging.getLogger(__name__) +GPG_LIST = [ + "gpg", + "--with-fingerprint", + "--no-default-keyring", + "--list-keys", + "--keyring", +] + def export_armour(key): """Export gpg key, armoured key gets returned""" try: - (armour, _) = subp.subp(["gpg", "--export", "--armour", key], - capture=True) + (armour, _) = subp.subp( + ["gpg", "--export", "--armour", key], capture=True + ) except subp.ProcessExecutionError as error: # debug, since it happens for any key not on the system initially LOG.debug('Failed to export armoured key "%s": %s', key, error) @@ -27,6 +36,33 @@ def export_armour(key): return armour +def dearmor(key): + """Dearmor gpg key, dearmored key gets returned + + note: man gpg(1) makes no mention of an --armour spelling, only --armor + """ + return subp.subp(["gpg", "--dearmor"], data=key, decode=False)[0] + + +def list(key_file, human_output=False): + """List keys from a keyring with fingerprints. Default to a stable machine + parseable format. + + @param key_file: a string containing a filepath to a key + @param human_output: return output intended for human parsing + """ + cmd = [] + cmd.extend(GPG_LIST) + if not human_output: + cmd.append("--with-colons") + + cmd.append(key_file) + (stdout, stderr) = subp.subp(cmd, capture=True) + if stderr: + LOG.warning('Failed to export armoured key "%s": %s', key_file, stderr) + return stdout + + def recv_key(key, keyserver, retries=(1, 1)): """Receive gpg key from the specified keyserver. @@ -52,8 +88,12 @@ def recv_key(key, keyserver, retries=(1, 1)): trynum += 1 try: subp.subp(cmd, capture=True) - LOG.debug("Imported key '%s' from keyserver '%s' on try %d", - key, keyserver, trynum) + LOG.debug( + "Imported key '%s' from keyserver '%s' on try %d", + key, + keyserver, + trynum, + ) return except subp.ProcessExecutionError as e: error = e @@ -61,25 +101,28 @@ def recv_key(key, keyserver, retries=(1, 1)): naplen = next(sleeps) LOG.debug( "Import failed with exit code %d, will try again in %ss", - error.exit_code, naplen) + error.exit_code, + naplen, + ) time.sleep(naplen) except StopIteration as e: raise ValueError( - ("Failed to import key '%s' from keyserver '%s' " - "after %d tries: %s") % (key, keyserver, trynum, error) + "Failed to import key '%s' from keyserver '%s' " + "after %d tries: %s" % (key, keyserver, trynum, error) ) from e def delete_key(key): """Delete the specified key from the local gpg ring""" try: - subp.subp(["gpg", "--batch", "--yes", "--delete-keys", key], - capture=True) + subp.subp( + ["gpg", "--batch", "--yes", "--delete-keys", key], capture=True + ) except subp.ProcessExecutionError as error: LOG.warning('Failed delete key "%s": %s', key, error) -def getkeybyid(keyid, keyserver='keyserver.ubuntu.com'): +def getkeybyid(keyid, keyserver="keyserver.ubuntu.com"): """get gpg keyid from keyserver""" armour = export_armour(keyid) if not armour: @@ -87,7 +130,7 @@ def getkeybyid(keyid, keyserver='keyserver.ubuntu.com'): recv_key(keyid, keyserver=keyserver) armour = export_armour(keyid) except ValueError: - LOG.exception('Failed to obtain gpg key %s', keyid) + LOG.exception("Failed to obtain gpg key %s", keyid) raise finally: # delete just imported key to leave environment as it was before @@ -95,4 +138,5 @@ def getkeybyid(keyid, keyserver='keyserver.ubuntu.com'): return armour + # vi: ts=4 expandtab |