Skip to content

Commit 6403cba

Browse files
authored
Fix onlykey.py defects: None-crash in get_sk_dk, fragile slot parser, NotFoundError format string
1 parent 0e57011 commit 6403cba

1 file changed

Lines changed: 51 additions & 37 deletions

File tree

libagent/device/onlykey.py

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ def connect(self):
5050
if self.okversion[0] == 'v':
5151
break
5252
except Exception as exc:
53-
raise interface.NotFoundError('{} not connected: "{}"') from exc
53+
raise interface.NotFoundError(
54+
'{} not connected: "{}"'.format(self.device_name, exc)) from exc
5455

5556
def set_skey(self, skey):
5657
"""Set signing key to use."""
@@ -94,45 +95,58 @@ def get_key_by_keygrip(self, keygrip):
9495
raise KeyError('keygrip %s not found' % keygriplong)
9596
return None
9697

98+
DEFAULT_SLOT = 132
99+
100+
_SKEY_SLOT_RE = re.compile(r'--skey-slot=(\S+)')
101+
_DKEY_SLOT_RE = re.compile(r'--dkey-slot=(\S+)')
102+
103+
@staticmethod
104+
def _parse_slot_value(value):
105+
"""Convert a --(s|d)key-slot=VALUE token (e.g. 'ECC1', 'RSA2', '132').
106+
107+
Returns an int slot number, or None if VALUE can't be parsed.
108+
"""
109+
if not value:
110+
return None
111+
try:
112+
if value.startswith('ECC'):
113+
return int(value[3:]) + 100
114+
if value.startswith('RSA'):
115+
return int(value[3:])
116+
return int(value)
117+
except ValueError:
118+
log.warning('Unrecognized key-slot value %r in run-agent.sh', value)
119+
return None
120+
97121
def get_sk_dk(self):
98122
"""Get signing key and decryption key slots from config."""
99-
fpath = os.path.join(os.environ.get(
100-
'AGENTHOMEDIR', os.environ.get('GNUPGHOME')), 'run-agent.sh')
123+
homedir = os.environ.get('AGENTHOMEDIR') or os.environ.get('GNUPGHOME')
124+
if not homedir:
125+
log.debug(
126+
'Neither AGENTHOMEDIR nor GNUPGHOME set; using default slot %d',
127+
self.DEFAULT_SLOT)
128+
self.set_skey(self.DEFAULT_SLOT)
129+
self.set_dkey(self.DEFAULT_SLOT)
130+
return
131+
132+
fpath = os.path.join(homedir, 'run-agent.sh')
101133
log.debug('Path to run-agent.sh = %s', fpath)
102-
if path.exists(fpath):
103-
with open(fpath) as f:
104-
s = f.read()
105-
if '--skey-slot=ECC' in s:
106-
if s[s.find('--skey-slot=')+16:s.find('--skey-slot=')+17] == ' ':
107-
self.set_skey(
108-
int(s[s.find('--skey-slot=')+15:s.find('--skey-slot=')+16])+100)
109-
else:
110-
self.set_skey(
111-
int(s[s.find('--skey-slot=')+15:s.find('--skey-slot=')+17])+100)
112-
elif '--skey-slot=RSA' in s:
113-
self.set_skey(int(s[s.find('--skey-slot=')+15:s.find('--skey-slot=')+16]))
114-
elif '--skey-slot=' in s:
115-
if s[s.find('--skey-slot=')+13:s.find('--skey-slot=')+14] == ' ':
116-
self.set_skey(int(s[s.find('--skey-slot=')+12:s.find('--skey-slot=')+13]))
117-
else:
118-
self.set_skey(int(s[s.find('--skey-slot=')+12:s.find('--skey-slot=')+15]))
119-
if '--dkey-slot=ECC' in s:
120-
if s[s.find('--dkey-slot=')+16:s.find('--dkey-slot=')+17] == ' ':
121-
self.set_dkey(
122-
int(s[s.find('--dkey-slot=')+15:s.find('--dkey-slot=')+16])+100)
123-
else:
124-
self.set_dkey(
125-
int(s[s.find('--dkey-slot=')+15:s.find('--dkey-slot=')+17])+100)
126-
elif '--dkey-slot=RSA' in s:
127-
self.set_dkey(int(s[s.find('--dkey-slot=')+15:s.find('--dkey-slot=')+16]))
128-
elif '--dkey-slot=' in s:
129-
if s[s.find('--dkey-slot=')+13:s.find('--dkey-slot=')+14] == ' ':
130-
self.set_dkey(int(s[s.find('--dkey-slot=')+12:s.find('--dkey-slot=')+13]))
131-
else:
132-
self.set_dkey(int(s[s.find('--dkey-slot=')+12:s.find('--dkey-slot=')+15]))
133-
else:
134-
self.set_skey(132)
135-
self.set_dkey(132)
134+
if not path.exists(fpath):
135+
self.set_skey(self.DEFAULT_SLOT)
136+
self.set_dkey(self.DEFAULT_SLOT)
137+
return
138+
139+
with open(fpath) as f:
140+
content = f.read()
141+
142+
skey_match = self._SKEY_SLOT_RE.search(content)
143+
dkey_match = self._DKEY_SLOT_RE.search(content)
144+
145+
skey = self._parse_slot_value(skey_match.group(1)) if skey_match else None
146+
dkey = self._parse_slot_value(dkey_match.group(1)) if dkey_match else None
147+
148+
self.set_skey(skey if skey is not None else self.DEFAULT_SLOT)
149+
self.set_dkey(dkey if dkey is not None else self.DEFAULT_SLOT)
136150

137151
def sig_hash(self, sighash):
138152
"""Set signature hashing algorithm to use."""

0 commit comments

Comments
 (0)