From 07b455f49c05f68b27f44f8991eb831d63d15c12 Mon Sep 17 00:00:00 2001 From: Andrea Franz Date: Fri, 22 Oct 2021 11:47:47 +0200 Subject: [PATCH] add UnblockPIN command --- command_set.go | 25 ++++++++++++++++++++++++- commands.go | 11 +++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/command_set.go b/command_set.go index 4851dd5..1e78ed9 100644 --- a/command_set.go +++ b/command_set.go @@ -26,6 +26,14 @@ func (e *WrongPINError) Error() string { return fmt.Sprintf("wrong pin. remaining attempts: %d", e.RemainingAttempts) } +type WrongPUKError struct { + RemainingAttempts int +} + +func (e *WrongPUKError) Error() string { + return fmt.Sprintf("wrong puk. remaining attempts: %d", e.RemainingAttempts) +} + type CommandSet struct { c types.Channel sc *SecureChannel @@ -205,10 +213,25 @@ func (cs *CommandSet) VerifyPIN(pin string) error { func (cs *CommandSet) ChangePIN(pin string) error { cmd := NewCommandChangePIN(pin) resp, err := cs.sc.Send(cmd) - return cs.checkOK(resp, err) } +func (cs *CommandSet) UnblockPIN(puk string, newPIN string) error { + cmd := NewCommandUnblockPIN(puk, newPIN) + resp, err := cs.sc.Send(cmd) + if err = cs.checkOK(resp, err); err != nil { + if resp.Sw&0x63C0 == 0x63C0 { + remainingAttempts := resp.Sw & 0x000F + return &WrongPUKError{ + RemainingAttempts: int(remainingAttempts), + } + } + return err + } + + return nil +} + func (cs *CommandSet) ChangePUK(puk string) error { cmd := NewCommandChangePUK(puk) resp, err := cs.sc.Send(cmd) diff --git a/commands.go b/commands.go index a1b26ea..1373716 100644 --- a/commands.go +++ b/commands.go @@ -21,6 +21,7 @@ const ( InsRemoveKey = 0xD3 InsVerifyPIN = 0x20 InsChangePIN = 0x21 + InsUnblockPIN = 0x22 InsDeriveKey = 0xD1 InsExportKey = 0xC2 InsSign = 0xC0 @@ -172,6 +173,16 @@ func NewCommandChangePIN(pin string) *apdu.Command { ) } +func NewCommandUnblockPIN(puk string, newPIN string) *apdu.Command { + return apdu.NewCommand( + globalplatform.ClaGp, + InsUnblockPIN, + 0, + 0, + []byte(puk+newPIN), + ) +} + func NewCommandChangePUK(puk string) *apdu.Command { return apdu.NewCommand( globalplatform.ClaGp,