Skip to content

Commit

Permalink
OpenPGP: Check PIN lengths.
Browse files Browse the repository at this point in the history
  • Loading branch information
dainnilsson committed Jan 12, 2024
1 parent ccebc66 commit 6b04f84
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions yubikit/openpgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,8 +1173,19 @@ def set_kdf(self, kdf: Kdf) -> None:
self.put_data(DO.KDF, kdf)
logger.info("KDF settings changed")

def _process_pin(self, kdf: Kdf, pw: PW, pin: str) -> bytes:
pin_bytes = kdf.process(pin, pw)
pin_len = len(pin_bytes)
min_len = 6 if pw is PW.USER else 8
max_len = self._app_data.discretionary.pw_status.get_max_len(pw)
if not (min_len <= pin_len <= max_len):
raise ValueError(
f"{pw.name} PIN length must be in the range {min_len}-{max_len}"
)
return pin_bytes

def _verify(self, pw: PW, pin: str, mode: int = 0) -> None:
pin_enc = self.get_kdf().process(pw, pin)
pin_enc = self._process_pin(self.get_kdf(), pw, pin)
try:
self.protocol.send_apdu(0, INS.VERIFY, 0, pw + mode, pin_enc)
except ApduError as e:
Expand Down Expand Up @@ -1225,7 +1236,7 @@ def _change(self, pw: PW, pin: str, new_pin: str) -> None:
INS.CHANGE_PIN,
0,
pw,
kdf.process(pw, pin) + kdf.process(pw, new_pin),
self._process_pin(kdf, pw, pin) + self._process_pin(kdf, pw, new_pin),
)
except ApduError as e:
if e.sw == SW.SECURITY_CONDITION_NOT_SATISFIED:
Expand Down Expand Up @@ -1262,7 +1273,7 @@ def set_reset_code(self, reset_code: str) -> None:
:param reset_code: The Reset Code for User PIN.
"""
logger.debug("Setting a new PIN Reset Code")
data = self.get_kdf().process(PW.RESET, reset_code)
data = self._process_pin(self.get_kdf(), PW.RESET, reset_code)
self.put_data(DO.RESETTING_CODE, data)
logger.info("New Reset Code has been set")

Expand All @@ -1277,10 +1288,10 @@ def reset_pin(self, new_pin: str, reset_code: Optional[str] = None) -> None:
logger.debug("Resetting User PIN")
p1 = 2
kdf = self.get_kdf()
data = kdf.process(PW.USER, new_pin)
data = self._process_pin(kdf, PW.USER, new_pin)
if reset_code:
logger.debug("Using Reset Code")
data = kdf.process(PW.RESET, reset_code) + data
data = self._process_pin(kdf, PW.RESET, reset_code) + data
p1 = 0

try:
Expand Down

0 comments on commit 6b04f84

Please sign in to comment.