Skip to content

Commit

Permalink
piv: fix pin prompt (again)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericchiang committed Apr 26, 2020
1 parent 39806f7 commit bf7b630
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 22 deletions.
34 changes: 14 additions & 20 deletions piv/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,27 +534,21 @@ func isAuthErr(err error) bool {
}

func (k KeyAuth) do(yk *YubiKey, f func(tx *scTx) ([]byte, error)) ([]byte, error) {
data, err := f(yk.tx)
if err == nil {
return data, nil
}
if !isAuthErr(err) {
return nil, err
}

pin := k.PIN
if pin == "" && k.PINPrompt != nil {
p, err := k.PINPrompt()
if err != nil {
return nil, fmt.Errorf("pin prompt: %v", err)
if ykLoginNeeded(yk.tx) {
pin := k.PIN
if pin == "" && k.PINPrompt != nil {
p, err := k.PINPrompt()
if err != nil {
return nil, fmt.Errorf("pin prompt: %v", err)
}
pin = p
}
pin = p
}
if pin == "" {
return nil, err
}
if err := ykLogin(yk.tx, pin); err != nil {
return nil, err
if pin != "" {
if err := ykLogin(yk.tx, pin); err != nil {
return nil, err
}
}
// If PIN isn't provided, assume this is for a PINPolicyNever key.
}
return f(yk.tx)
}
Expand Down
4 changes: 2 additions & 2 deletions piv/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ func TestYubiKeyPrivateKeyPINError(t *testing.T) {
key := Key{
Algorithm: alg,
TouchPolicy: TouchPolicyNever,
PINPolicy: PINPolicyNever,
PINPolicy: PINPolicyAlways,
}
pub, err := yk.GenerateKey(DefaultManagementKey, slot, key)
if err != nil {
Expand All @@ -548,7 +548,7 @@ func TestYubiKeyPrivateKeyPINError(t *testing.T) {

b := sha256.Sum256([]byte("hello"))
hash := b[:]
if _, err := signer.Sign(rand.Reader, hash, crypto.SHA256); err != nil {
if _, err := signer.Sign(rand.Reader, hash, crypto.SHA256); err == nil {
t.Errorf("expected sign to fail with pin prompt that returned error")
}
}
6 changes: 6 additions & 0 deletions piv/piv.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ func ykLogin(tx *scTx, pin string) error {
return nil
}

func ykLoginNeeded(tx *scTx) bool {
cmd := apdu{instruction: insVerify, param2: 0x80}
_, err := tx.Transmit(cmd)
return err != nil
}

// Retries returns the number of attempts remaining to enter the correct PIN.
func (yk *YubiKey) Retries() (int, error) {
return ykPINRetries(yk.tx)
Expand Down
14 changes: 14 additions & 0 deletions piv/piv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,20 @@ func TestYubiKeySerial(t *testing.T) {
}
}

func TestYubiKeyLoginNeeded(t *testing.T) {
yk, close := newTestYubiKey(t)
defer close()
if !ykLoginNeeded(yk.tx) {
t.Errorf("expected login needed")
}
if err := ykLogin(yk.tx, DefaultPIN); err != nil {
t.Fatalf("login: %v", err)
}
if ykLoginNeeded(yk.tx) {
t.Errorf("expected no login needed")
}
}

func TestYubiKeyPINRetries(t *testing.T) {
yk, close := newTestYubiKey(t)
defer close()
Expand Down

0 comments on commit bf7b630

Please sign in to comment.