Coverage for src/ansible_sign/signing/gpg/signer.py: 97%
26 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-05 08:12 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-05 08:12 +0000
1"""
2This module handles GPG signature generation for Ansible content. It makes use
3of python-gnupg (which ultimately shells out to GPG).
4"""
6import gnupg
8from ansible_sign.signing.base import (
9 SignatureSigner,
10 SignatureSigningResult,
11)
13__author__ = "Rick Elrod"
14__copyright__ = "(c) 2022 Red Hat, Inc."
15__license__ = "MIT"
18class GPGSigner(SignatureSigner):
19 def __init__(
20 self,
21 manifest_path,
22 output_path,
23 privkey=None,
24 passphrase=None,
25 gpg_home=None,
26 ):
27 super(GPGSigner, self).__init__()
29 if manifest_path is None:
30 raise RuntimeError("manifest_path must not be None")
31 self.manifest_path = manifest_path
33 if output_path is None:
34 raise RuntimeError("output_path must not be None")
35 self.output_path = output_path
37 self.privkey = privkey
38 self.passphrase = passphrase
39 self.gpg_home = gpg_home
41 def sign(self) -> SignatureSigningResult:
42 # TODO: We currently use the default GPG home directory in the signing
43 # case and assume the secret key exists in it. Is there a better way to
44 # do this?
45 gpg = gnupg.GPG(gnupghome=self.gpg_home)
46 with open(self.manifest_path, "rb") as f:
47 sign_result = gpg.sign_file(
48 f,
49 keyid=self.privkey,
50 passphrase=self.passphrase,
51 detach=True,
52 output=self.output_path,
53 )
55 extra_information = {}
56 for k in ("stderr", "fingerprint", "hash_algo", "timestamp", "returncode"):
57 if hasattr(sign_result, k): 57 ↛ 56line 57 didn't jump to line 56 because the condition on line 57 was always true
58 extra_information[k] = getattr(sign_result, k)
60 return SignatureSigningResult(
61 success=sign_result.returncode == 0 and sign_result.status is not None,
62 summary=sign_result.status,
63 extra_information=extra_information,
64 )