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 "crypto/sha256" 8 "errors" 9 10 "github.com/keybase/client/go/kbcrypto" 11 keybase1 "github.com/keybase/client/go/protocol/keybase1" 12 "golang.org/x/net/context" 13) 14 15// GPGKey is a shell around gpg cli commands that implements the 16// GenericKey interface. 17type GPGKey struct { 18 fp *PGPFingerprint 19 kid keybase1.KID 20 ui GPGUI 21 ct keybase1.ClientType 22 Contextified 23} 24 25// GPGKey implements the GenericKey interface. 26var _ GenericKey = (*GPGKey)(nil) 27 28func NewGPGKey(g *GlobalContext, fp *PGPFingerprint, kid keybase1.KID, ui GPGUI, ct keybase1.ClientType) *GPGKey { 29 return &GPGKey{Contextified: NewContextified(g), fp: fp, kid: kid, ui: ui, ct: ct} 30} 31 32func (g *GPGKey) GetKID() keybase1.KID { 33 return g.kid 34} 35 36func (g *GPGKey) GetBinaryKID() keybase1.BinaryKID { 37 return g.GetKID().ToBinaryKID() 38} 39 40func (g *GPGKey) GetFingerprintP() *PGPFingerprint { 41 return g.fp 42} 43 44func (g *GPGKey) GetAlgoType() kbcrypto.AlgoType { 45 return kbcrypto.KIDPGPBase 46} 47 48func (g *GPGKey) SignToString(msg []byte) (sig string, id keybase1.SigIDBase, err error) { 49 return g.SignToStringMctx(NewMetaContext(context.TODO(), g.G()), msg) 50} 51 52func (g *GPGKey) SignToStringMctx(mctx MetaContext, msg []byte) (sig string, id keybase1.SigIDBase, err error) { 53 mctx.Debug("+ GPGKey Signing %s", string(msg)) 54 defer func() { 55 mctx.Debug("- GPGKey Signing -> %s", err) 56 }() 57 58 if g.ct == keybase1.ClientType_CLI { 59 mctx.Debug("| GPGKey reverse delegate to CLI") 60 sig, err = g.ui.Sign(mctx.Ctx(), keybase1.SignArg{Fingerprint: (*g.fp)[:], Msg: msg}) 61 } else { 62 mctx.Debug("| GPGKey sign in-process; let's hope for the best!") 63 sig, err = g.G().GetGpgClient().Sign(mctx, *g.fp, msg) 64 } 65 66 if err != nil { 67 return sig, id, err 68 } 69 70 // compute sig id: 71 h := sha256.New() 72 _, err = h.Write(msg) 73 if err != nil { 74 return sig, id, err 75 } 76 var hsh [32]byte 77 var tmp = h.Sum(nil) 78 copy(hsh[:], tmp) 79 id = keybase1.SigIDBaseFromBytes(hsh) 80 return sig, id, nil 81} 82 83func (g *GPGKey) VerifyStringAndExtract(ctx VerifyContext, sig string) (msg []byte, id keybase1.SigIDBase, err error) { 84 return msg, id, errors.New("VerifyStringAndExtract not implemented") 85} 86 87func (g *GPGKey) VerifyString(ctx VerifyContext, sig string, msg []byte) (id keybase1.SigIDBase, err error) { 88 return id, errors.New("VerifyString not implemented") 89} 90 91func (g *GPGKey) EncryptToString(plaintext []byte, sender GenericKey) (ciphertext string, err error) { 92 return ciphertext, errors.New("EncryptToString not implemented") 93} 94 95func (g *GPGKey) DecryptFromString(ciphertext string) (msg []byte, sender keybase1.KID, err error) { 96 return msg, sender, errors.New("DecryptFromString not implemented") 97} 98 99func (g *GPGKey) ExportPublicAndPrivate() (RawPublicKey, RawPrivateKey, error) { 100 return nil, nil, errors.New("ExportPublicAndPrivate not implemented for GPGKey") 101} 102 103func (g *GPGKey) VerboseDescription() string { 104 return "" 105} 106 107func (g *GPGKey) CheckSecretKey() error { 108 return nil 109} 110 111func (g *GPGKey) CanSign() bool { 112 return true 113} 114 115func (g *GPGKey) CanEncrypt() bool { 116 return false 117} 118 119func (g *GPGKey) CanDecrypt() bool { 120 return false 121} 122 123func (g *GPGKey) HasSecretKey() bool { 124 return true 125} 126 127func (g *GPGKey) Encode() (string, error) { 128 return "", errors.New("Encode not implemented") 129} 130 131func (g *GPGKey) SecretSymmetricKey(reason EncryptionReason) (NaclSecretBoxKey, error) { 132 return NaclSecretBoxKey{}, KeyCannotEncryptError{} 133} 134