Skip to content

Module gnupg.handlers.list_keys_handler

View Source
from __future__ import annotations

from typing import TYPE_CHECKING

from .helper import _set_fields

from .search_keys_handler import SearchKeysHandler

if TYPE_CHECKING:

    from gnupg.gnupg import GPG

class ListKeysHandler(SearchKeysHandler):

    """

    This class handles status messages during listing keys and signatures.

    Handle pub and uid (relating the latter to the former).

    We don't care about (info from GnuPG DETAILS file):

    crt = X.509 certificate

    crs = X.509 certificate and private key available

    uat = user attribute (same as user id except for field 10).

    sig = signature

    rev = revocation signature

    pkd = public key data (special field format, see below)

    grp = reserved for gpgsm

    rvk = revocation key

    """

    UID_INDEX = 9

    FIELDS = (

        "type trust length algo keyid date expires dummy ownertrust uid sig"

        " cap issuer flag token hash curve compliance updated origin keygrip"

    ).split()

    def __init__(self, gpg: GPG) -> None:

        super().__init__(gpg)

        self.in_subkey = False

        self.key_map = {}

    def key(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        self.curkey = curkey = self.get_fields(args)

        if curkey["uid"]:  # pragma: no cover

            curkey["uids"].append(curkey["uid"])

        del curkey["uid"]

        curkey["subkeys"] = []

        self.append(curkey)

        self.in_subkey = False

    pub = sec = key

    def fpr(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        fp = args[9]

        if fp in self.key_map and self.gpg.check_fingerprint_collisions:  # pragma: no cover

            msg = f"Unexpected fingerprint collision: {fp}"

            raise ValueError(msg)

        if not self.in_subkey:

            self.curkey["fingerprint"] = fp

            self.fingerprints.append(fp)

            self.key_map[fp] = self.curkey

        else:

            self.curkey["subkeys"][-1][2] = fp

            self.key_map[fp] = self.curkey

    def grp(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        grp = args[9]

        if not self.in_subkey:

            self.curkey["keygrip"] = grp

        else:

            self.curkey["subkeys"][-1][3] = grp

    def _collect_subkey_info(

        self,

        curkey: dict[

            str,

            str | list[str] | list[list[str | None]] | dict[str, dict[str, str]] | list[tuple[str, str, str]],

        ],

        args: list[str],

    ) -> None:

        info_map = curkey.setdefault("subkey_info", {})

        info = {}

        _set_fields(info, self.FIELDS, args)

        info_map[args[4]] = info

    def sub(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # See issue #81. We create a dict with more information about

        # subkeys, but for backward compatibility reason, have to add it in

        # as a separate entry 'subkey_info'

        subkey = [args[4], args[11], None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

    def ssb(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        subkey = [args[4], None, None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

    def sig(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # keyid, uid, sigclass

        self.curkey["sigs"].append((args[4], args[9], args[10]))

Variables

TYPE_CHECKING

Classes

ListKeysHandler

class ListKeysHandler(
    gpg: 'GPG'
)

This class handles status messages during listing keys and signatures.

Handle pub and uid (relating the latter to the former).

We don't care about (info from GnuPG DETAILS file):

crt = X.509 certificate crs = X.509 certificate and private key available uat = user attribute (same as user id except for field 10). sig = signature rev = revocation signature pkd = public key data (special field format, see below) grp = reserved for gpgsm rvk = revocation key

View Source
class ListKeysHandler(SearchKeysHandler):

    """

    This class handles status messages during listing keys and signatures.

    Handle pub and uid (relating the latter to the former).

    We don't care about (info from GnuPG DETAILS file):

    crt = X.509 certificate

    crs = X.509 certificate and private key available

    uat = user attribute (same as user id except for field 10).

    sig = signature

    rev = revocation signature

    pkd = public key data (special field format, see below)

    grp = reserved for gpgsm

    rvk = revocation key

    """

    UID_INDEX = 9

    FIELDS = (

        "type trust length algo keyid date expires dummy ownertrust uid sig"

        " cap issuer flag token hash curve compliance updated origin keygrip"

    ).split()

    def __init__(self, gpg: GPG) -> None:

        super().__init__(gpg)

        self.in_subkey = False

        self.key_map = {}

    def key(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        self.curkey = curkey = self.get_fields(args)

        if curkey["uid"]:  # pragma: no cover

            curkey["uids"].append(curkey["uid"])

        del curkey["uid"]

        curkey["subkeys"] = []

        self.append(curkey)

        self.in_subkey = False

    pub = sec = key

    def fpr(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        fp = args[9]

        if fp in self.key_map and self.gpg.check_fingerprint_collisions:  # pragma: no cover

            msg = f"Unexpected fingerprint collision: {fp}"

            raise ValueError(msg)

        if not self.in_subkey:

            self.curkey["fingerprint"] = fp

            self.fingerprints.append(fp)

            self.key_map[fp] = self.curkey

        else:

            self.curkey["subkeys"][-1][2] = fp

            self.key_map[fp] = self.curkey

    def grp(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        grp = args[9]

        if not self.in_subkey:

            self.curkey["keygrip"] = grp

        else:

            self.curkey["subkeys"][-1][3] = grp

    def _collect_subkey_info(

        self,

        curkey: dict[

            str,

            str | list[str] | list[list[str | None]] | dict[str, dict[str, str]] | list[tuple[str, str, str]],

        ],

        args: list[str],

    ) -> None:

        info_map = curkey.setdefault("subkey_info", {})

        info = {}

        _set_fields(info, self.FIELDS, args)

        info_map[args[4]] = info

    def sub(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # See issue #81. We create a dict with more information about

        # subkeys, but for backward compatibility reason, have to add it in

        # as a separate entry 'subkey_info'

        subkey = [args[4], args[11], None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

    def ssb(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        subkey = [args[4], None, None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

    def sig(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # keyid, uid, sigclass

        self.curkey["sigs"].append((args[4], args[9], args[10]))

Ancestors (in MRO)

  • gnupg.handlers.search_keys_handler.SearchKeysHandler
  • gnupg.handlers.status_handler.StatusHandler
  • builtins.list

Descendants

  • gnupg.handlers.scan_keys_handler.ScanKeysHandler

Class variables

FIELDS
UID_INDEX
returncode

Methods

append

def append(
    self,
    object,
    /
)

Append object to the end of the list.

clear

def clear(
    self,
    /
)

Remove all items from list.

copy

def copy(
    self,
    /
)

Return a shallow copy of the list.

count

def count(
    self,
    value,
    /
)

Return number of occurrences of value.

extend

def extend(
    self,
    iterable,
    /
)

Extend list by appending elements from the iterable.

fpr

def fpr(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def fpr(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        fp = args[9]

        if fp in self.key_map and self.gpg.check_fingerprint_collisions:  # pragma: no cover

            msg = f"Unexpected fingerprint collision: {fp}"

            raise ValueError(msg)

        if not self.in_subkey:

            self.curkey["fingerprint"] = fp

            self.fingerprints.append(fp)

            self.key_map[fp] = self.curkey

        else:

            self.curkey["subkeys"][-1][2] = fp

            self.key_map[fp] = self.curkey

get_fields

def get_fields(
    self,
    args: 'list[str]'
) -> 'dict[str, str]'

Internal method used to update the instance from a gpg status message.

View Source
    def get_fields(self, args: list[str]) -> dict[str, str]:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        result = {}

        _set_fields(result, self.FIELDS, args)

        result["uids"] = []

        result["sigs"] = []

        return result

grp

def grp(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def grp(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        grp = args[9]

        if not self.in_subkey:

            self.curkey["keygrip"] = grp

        else:

            self.curkey["subkeys"][-1][3] = grp

handle_status

def handle_status(
    self,
    key: 'str',
    value: 'str'
) -> 'None'

Handle status messages from the gpg child process. These are lines of the format

[GNUPG:]

Parameters:

Name Type Description Default
key str Identifies what the status message is. None
value str Identifies additional data, which differs depending on the key. None
View Source
    def handle_status(self, key: str, value: str) -> None:  # pragma: no cover

        pass

index

def index(
    self,
    value,
    start=0,
    stop=9223372036854775807,
    /
)

Return first index of value.

Raises ValueError if the value is not present.

insert

def insert(
    self,
    index,
    object,
    /
)

Insert object before index.

key

def key(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def key(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        self.curkey = curkey = self.get_fields(args)

        if curkey["uid"]:  # pragma: no cover

            curkey["uids"].append(curkey["uid"])

        del curkey["uid"]

        curkey["subkeys"] = []

        self.append(curkey)

        self.in_subkey = False

pop

def pop(
    self,
    index=-1,
    /
)

Remove and return item at index (default last).

Raises IndexError if list is empty or index is out of range.

pub

def pub(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def key(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        self.curkey = curkey = self.get_fields(args)

        if curkey["uid"]:  # pragma: no cover

            curkey["uids"].append(curkey["uid"])

        del curkey["uid"]

        curkey["subkeys"] = []

        self.append(curkey)

        self.in_subkey = False

remove

def remove(
    self,
    value,
    /
)

Remove first occurrence of value.

Raises ValueError if the value is not present.

reverse

def reverse(
    self,
    /
)

Reverse IN PLACE.

sec

def sec(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def key(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        self.curkey = curkey = self.get_fields(args)

        if curkey["uid"]:  # pragma: no cover

            curkey["uids"].append(curkey["uid"])

        del curkey["uid"]

        curkey["subkeys"] = []

        self.append(curkey)

        self.in_subkey = False

sig

def sig(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def sig(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # keyid, uid, sigclass

        self.curkey["sigs"].append((args[4], args[9], args[10]))

sort

def sort(
    self,
    /,
    *,
    key=None,
    reverse=False
)

Sort the list in ascending order and return None.

The sort is in-place (i.e. the list itself is modified) and stable (i.e. the order of two equal elements is maintained).

If a key function is given, apply it once to each list item and sort them, ascending or descending, according to their function values.

The reverse flag can be set to sort in descending order.

ssb

def ssb(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def ssb(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        subkey = [args[4], None, None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

sub

def sub(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def sub(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        # See issue #81. We create a dict with more information about

        # subkeys, but for backward compatibility reason, have to add it in

        # as a separate entry 'subkey_info'

        subkey = [args[4], args[11], None, None]  # keyid, type, fp, grp

        self.curkey["subkeys"].append(subkey)

        self._collect_subkey_info(self.curkey, args)

        self.in_subkey = True

uid

def uid(
    self,
    args: 'list[str]'
) -> 'None'

Internal method used to update the instance from a gpg status message.

View Source
    def uid(self, args: list[str]) -> None:

        """

        Internal method used to update the instance from a `gpg` status message.

        """

        uid = args[self.UID_INDEX]

        uid = ESCAPE_PATTERN.sub(lambda m: chr(int(m.group(1), 16)), uid)

        for k, v in BASIC_ESCAPES.items():

            uid = uid.replace(k, v)

        self.curkey["uids"].append(uid)

        self.uids.append(uid)