github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/keylock.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import "fmt" 7 8 type PassphraseType string 9 10 const ( 11 PassphraseTypeKeybase PassphraseType = "Keybase" 12 PassphraseTypePGP PassphraseType = "PGP" 13 ) 14 15 type UnlockerFunc func(pw string, storeSecret bool) (ret GenericKey, err error) 16 17 type KeyUnlocker struct { 18 tries int 19 reason string 20 keyDesc string 21 which PassphraseType 22 useSecretStore bool 23 ui SecretUI 24 unlocker UnlockerFunc 25 } 26 27 func NewKeyUnlocker(tries int, reason string, keyDesc string, which PassphraseType, useSecretStore bool, ui SecretUI, unlocker UnlockerFunc) KeyUnlocker { 28 return KeyUnlocker{ 29 tries: tries, 30 reason: reason, 31 keyDesc: keyDesc, 32 which: which, 33 useSecretStore: useSecretStore, 34 ui: ui, 35 unlocker: unlocker, 36 } 37 } 38 39 func (arg KeyUnlocker) Run(m MetaContext) (ret GenericKey, err error) { 40 var emsg string 41 42 if arg.ui == nil { 43 err = NoUIError{"secret"} 44 return nil, err 45 } 46 47 prompt := "Please enter your " + string(arg.which) + " passphrase to unlock the secret key for:\n" + 48 arg.keyDesc + "\n" 49 if len(arg.reason) > 0 { 50 prompt = prompt + "\nReason: " + arg.reason 51 } 52 53 title := "Your " + string(arg.which) + " passphrase" 54 55 for i := 0; arg.tries <= 0 || i < arg.tries; i++ { 56 res, err := GetSecret(m, arg.ui, title, prompt, emsg, arg.useSecretStore) 57 if err != nil { 58 // probably canceled 59 return nil, err 60 } 61 ret, err = arg.unlocker(res.Passphrase, res.StoreSecret) 62 if err == nil { 63 // success 64 return ret, nil 65 } 66 if _, ok := err.(PassphraseError); ok { 67 // keep trying 68 emsg = "Failed to unlock key; bad passphrase" 69 } else { 70 // unretryable error 71 return nil, err 72 } 73 } 74 75 return nil, fmt.Errorf("Too many failures; giving up") 76 }