1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package libkb 5 6import ( 7 "strings" 8 9 "github.com/keybase/client/go/kbcrypto" 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11) 12 13type VerifyContext interface { 14 Debug(format string, args ...interface{}) 15} 16 17type RawPublicKey []byte 18type RawPrivateKey []byte 19 20type GenericKey interface { 21 GetKID() keybase1.KID 22 GetBinaryKID() keybase1.BinaryKID 23 GetAlgoType() kbcrypto.AlgoType 24 25 // Sign to an ASCII signature (which includes the message 26 // itself) and return it, along with a derived ID. 27 SignToString(msg []byte) (sig string, id keybase1.SigIDBase, err error) 28 29 // Verify that the given signature is valid and extracts the 30 // embedded message from it. Also returns the signature ID. 31 VerifyStringAndExtract(ctx VerifyContext, sig string) (msg []byte, id keybase1.SigIDBase, err error) 32 33 // Verify that the given signature is valid and that its 34 // embedded message matches the given one. Also returns the 35 // signature ID. 36 VerifyString(ctx VerifyContext, sig string, msg []byte) (id keybase1.SigIDBase, err error) 37 38 // Encrypt to an ASCII armored encryption; optionally include a sender's 39 // (private) key so that we can provably see who sent the message. 40 EncryptToString(plaintext []byte, sender GenericKey) (ciphertext string, err error) 41 42 // Decrypt the output of Encrypt above; provide the plaintext and also 43 // the KID of the key that sent the message (if applicable). 44 DecryptFromString(ciphertext string) (msg []byte, sender keybase1.KID, err error) 45 46 // Derive a secret key from a DH secret key 47 SecretSymmetricKey(reason EncryptionReason) (NaclSecretBoxKey, error) 48 49 VerboseDescription() string 50 CheckSecretKey() error 51 CanSign() bool 52 CanEncrypt() bool 53 CanDecrypt() bool 54 HasSecretKey() bool 55 Encode() (string, error) // encode public key to string 56 57 // ExportPublicAndPrivate to special-purpose types so there is no way we can 58 // accidentally reverse them. 59 ExportPublicAndPrivate() (public RawPublicKey, private RawPrivateKey, err error) 60} 61 62func CanEncrypt(key GenericKey) bool { 63 switch key.(type) { 64 case NaclDHKeyPair: 65 return true 66 case *PGPKeyBundle: 67 return true 68 default: 69 return false 70 } 71} 72 73func skbPushAndSave(m MetaContext, skb *SKB) (err error) { 74 defer m.Trace("skbPushAndSave", &err)() 75 ring, err := m.Keyring() 76 if err != nil { 77 return err 78 } 79 err = ring.PushAndSave(skb) 80 if err != nil { 81 return err 82 } 83 return nil 84} 85 86// Any valid key matches the empty string. 87func KeyMatchesQuery(key GenericKey, q string, exact bool) bool { 88 if key.GetKID().Match(q, exact) { 89 return true 90 } 91 return GetPGPFingerprintFromGenericKey(key).Match(q, exact) 92} 93 94func IsPGP(key GenericKey) bool { 95 _, ok := key.(*PGPKeyBundle) 96 return ok 97} 98 99func ParseGenericKey(bundle string) (GenericKey, *Warnings, error) { 100 if isPGPBundle(bundle) { 101 // PGP key 102 return ReadOneKeyFromStringLiberal(bundle) 103 } 104 // NaCl key 105 key, err := ImportKeypairFromKID(keybase1.KIDFromString(bundle)) 106 return key, &Warnings{}, err 107} 108 109func isPGPBundle(armored string) bool { 110 return strings.HasPrefix(armored, "-----BEGIN PGP") 111} 112 113func GenericKeyEqual(k1, k2 GenericKey) bool { 114 return k1.GetKID().Equal(k2.GetKID()) 115} 116