Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/securesystemslib/_gpg/constants.py: 67%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

60 statements  

1""" 

2<Module Name> 

3 constants.py 

4 

5<Author> 

6 Santiago Torres-Arias <santiago@nyu.edu> 

7 

8<Started> 

9 Nov 15, 2017 

10 

11<Copyright> 

12 See LICENSE for licensing information. 

13 

14<Purpose> 

15 aggregates all the constant definitions and lookup structures for signature 

16 handling 

17""" 

18 

19from __future__ import annotations 

20 

21import functools 

22import logging 

23import os 

24import shlex 

25import subprocess 

26 

27log = logging.getLogger(__name__) 

28 

29GPG_TIMEOUT = 10 

30 

31 

32@functools.lru_cache(maxsize=3) 

33def is_available_gnupg(gnupg: str, timeout: int | None = None) -> bool: 

34 """Returns whether gnupg points to a gpg binary.""" 

35 if timeout is None: 

36 timeout = GPG_TIMEOUT 

37 

38 gpg_version_cmd = shlex.split(f"{gnupg} --version") 

39 try: 

40 subprocess.run( # noqa: S603 

41 gpg_version_cmd, 

42 capture_output=True, 

43 timeout=timeout, 

44 check=True, 

45 ) 

46 return True 

47 except (OSError, subprocess.TimeoutExpired): 

48 return False 

49 

50 

51GPG_ENV_COMMAND = os.environ.get("GNUPG") 

52GPG2_COMMAND = "gpg2" 

53GPG1_COMMAND = "gpg" 

54 

55 

56def gpg_command() -> str: 

57 """Returns command to run GPG, or ``""``` if not found).""" 

58 # By default, we allow providing GPG client through the environment 

59 # assuming gpg2 as default value and test if exists. Otherwise, we assume gpg 

60 # exists. 

61 if GPG_ENV_COMMAND: 

62 if is_available_gnupg(GPG_ENV_COMMAND): 

63 return GPG_ENV_COMMAND 

64 elif is_available_gnupg(GPG2_COMMAND): 

65 return GPG2_COMMAND 

66 elif is_available_gnupg(GPG1_COMMAND): 

67 return GPG1_COMMAND 

68 return "" 

69 

70 

71def have_gpg() -> bool: 

72 """Returns True if a gpg_command is available.""" 

73 return bool(gpg_command()) 

74 

75 

76def gpg_version_command() -> list[str]: 

77 """Returns the command to get the current GPG version.""" 

78 return shlex.split(f"{gpg_command()} --version") 

79 

80 

81FULLY_SUPPORTED_MIN_VERSION = "2.1.0" 

82NO_GPG_MSG = ( 

83 f"GPG support requires a GPG client. 'gpg2' or 'gpg' with version " 

84 f"{FULLY_SUPPORTED_MIN_VERSION} or newer is fully supported." 

85) 

86 

87 

88def gpg_sign_command(keyarg: str, homearg: str) -> list[str]: 

89 """Returns the command to use GPG to sign STDIN.""" 

90 return shlex.split( 

91 f"{gpg_command()} --detach-sign --digest-algo SHA256 {keyarg} {homearg}" 

92 ) 

93 

94 

95def gpg_export_pubkey_command(homearg: str, keyid: str) -> list[str]: 

96 """Returns the GPG command to export a public key.""" 

97 return shlex.split(f"{gpg_command()} {homearg} --export {keyid}") 

98 

99 

100# See RFC4880 section 4.3. Packet Tags for a list of all packet types The 

101# relevant packets defined below are described in sections 5.2 (signature), 

102# 5.5.1.1 (primary pubkey) and 5.5.1.2 (pub subkey), 5.12 (user id) and 5.13 

103# (user attribute) 

104PACKET_TYPE_SIGNATURE = 0x02 

105PACKET_TYPE_PRIMARY_KEY = 0x06 

106PACKET_TYPE_USER_ID = 0x0D 

107PACKET_TYPE_USER_ATTR = 0x11 

108PACKET_TYPE_SUB_KEY = 0x0E 

109 

110 

111# See sections 5.2.3 (signature) and 5.5.2 (public key) of RFC4880 

112SUPPORTED_SIGNATURE_PACKET_VERSIONS = {0x04} 

113SUPPORTED_PUBKEY_PACKET_VERSIONS = {0x04} 

114 

115# The constants for hash algorithms are taken from section 9.4 of RFC4880. 

116SHA1 = 0x02 

117SHA256 = 0x08 

118SHA512 = 0x0A 

119 

120# See section 5.2.1 of RFC4880 

121SIGNATURE_TYPE_BINARY = 0x00 

122SIGNATURE_TYPE_SUB_KEY_BINDING = 0x18 

123SIGNATURE_TYPE_CERTIFICATES = {0x10, 0x11, 0x12, 0x13} 

124 

125# See section 5.2.3.4 (Signature Creation Time) of RFC4880 

126SIG_CREATION_SUBPACKET = 0x02 

127# See section 5.2.3.5. (Issuer) of RFC4880 

128PARTIAL_KEYID_SUBPACKET = 0x10 

129# See section 5.2.3.6 (Key Expiration Time) of RFC4880 

130KEY_EXPIRATION_SUBPACKET = 0x09 

131# See section 5.2.3.19 (Primary User ID) of RFC4880 

132PRIMARY_USERID_SUBPACKET = 0x19 

133# See section 5.2.3.28. (Issuer Fingerprint) of rfc4880bis-06 

134FULL_KEYID_SUBPACKET = 0x21 

135 

136GPG_HASH_ALGORITHM_STRING = "pgp+SHA2"