/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/saltpack_encrypt.go
204 строки
6 KB
zoom-ua
enable linters: ineffassign, unused, staticcheck (#28735)
23 дек 2025, 02:24
Не верифицирован
23 дек 2025, 02:24
e0e297e
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package engine import ( "fmt" "io" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" "github.com/keybase/saltpack" ) type SaltpackEncryptArg struct { Opts keybase1.SaltpackEncryptOptions Source io.Reader Sink io.WriteCloser } // SaltpackEncrypt encrypts data read from a source into a sink // for a set of users. It will track them if necessary. type SaltpackEncrypt struct { arg *SaltpackEncryptArg me keybase1.UID newKeyfinderHook (func(arg libkb.SaltpackRecipientKeyfinderArg) libkb.SaltpackRecipientKeyfinderEngineInterface) // keep track if an SBS recipient was used so callers can tell the user UsedSBS bool SBSAssertion string // Legacy encryption-only messages include a lot more information about // receivers, and it's nice to keep the helpful errors working while those // messages are still around. visibleRecipientsForTesting bool } // NewSaltpackEncrypt creates a SaltpackEncrypt engine. func NewSaltpackEncrypt(arg *SaltpackEncryptArg, newKeyfinderHook func(arg libkb.SaltpackRecipientKeyfinderArg) libkb.SaltpackRecipientKeyfinderEngineInterface) *SaltpackEncrypt { return &SaltpackEncrypt{ arg: arg, newKeyfinderHook: newKeyfinderHook, } } // Name is the unique engine name. func (e *SaltpackEncrypt) Name() string { return "SaltpackEncrypt" } // Prereqs returns the engine prereqs. func (e *SaltpackEncrypt) Prereqs() Prereqs { return Prereqs{} } // RequiredUIs returns the required UIs. func (e *SaltpackEncrypt) RequiredUIs() []libkb.UIKind { return []libkb.UIKind{ libkb.SecretUIKind, } } // SubConsumers returns the other UI consumers for this engine. func (e *SaltpackEncrypt) SubConsumers() []libkb.UIConsumer { // Note that potentially KeyfinderHook might return a different UIConsumer depending on its arguments, // which might make this call problematic, but all the hooks currently in use are not doing that. return []libkb.UIConsumer{ e.newKeyfinderHook(libkb.SaltpackRecipientKeyfinderArg{}), } } func (e *SaltpackEncrypt) loadMe(m libkb.MetaContext) error { loggedIn, uid, err := isLoggedInWithUIDAndError(m) if err != nil && !e.arg.Opts.NoSelfEncrypt { return err } if !loggedIn { return nil } e.me = uid return nil } // Run starts the engine. func (e *SaltpackEncrypt) Run(m libkb.MetaContext) (err error) { defer m.Trace("SaltpackEncrypt::Run", &err)() if err = e.loadMe(m); err != nil { return err } if !e.arg.Opts.UseEntityKeys && !e.arg.Opts.UseDeviceKeys && !e.arg.Opts.UsePaperKeys && !e.arg.Opts.UseKBFSKeysOnlyForTesting { return fmt.Errorf("no key type for encryption was specified") } kfarg := libkb.SaltpackRecipientKeyfinderArg{ Recipients: e.arg.Opts.Recipients, TeamRecipients: e.arg.Opts.TeamRecipients, NoSelfEncrypt: e.arg.Opts.NoSelfEncrypt, UseEntityKeys: e.arg.Opts.UseEntityKeys, UsePaperKeys: e.arg.Opts.UsePaperKeys, UseDeviceKeys: e.arg.Opts.UseDeviceKeys, UseRepudiableAuth: e.arg.Opts.AuthenticityType == keybase1.AuthenticityType_REPUDIABLE, NoForcePoll: e.arg.Opts.NoForcePoll, } kf := e.newKeyfinderHook(kfarg) if err := RunEngine2(m, kf); err != nil { return err } var receivers []libkb.NaclDHKeyPublic for _, KID := range kf.GetPublicKIDs() { gk, err := libkb.ImportKeypairFromKID(KID) if err != nil { return err } kp, ok := gk.(libkb.NaclDHKeyPair) if !ok { return libkb.KeyCannotEncryptError{} } receivers = append(receivers, kp.Public) } var symmetricReceivers []saltpack.ReceiverSymmetricKey for _, key := range kf.GetSymmetricKeys() { symmetricReceivers = append(symmetricReceivers, saltpack.ReceiverSymmetricKey{ Key: saltpack.SymmetricKey(key.Key), Identifier: key.Identifier, }) } e.UsedSBS, e.SBSAssertion = kf.UsedUnresolvedSBSAssertion() if e.UsedSBS { actx := m.G().MakeAssertionContext(m) expr, err := libkb.AssertionParse(actx, e.SBSAssertion) if err == nil { social, err := expr.ToSocialAssertion() if err == nil && social.Service == "email" { // email assertions are pretty ugly, so just return // the "User" part for easier handling upstream. e.SBSAssertion = social.User } } } // This flag determines whether saltpack is used in signcryption (false) // vs encryption (true) format. encryptionOnlyMode := false var senderDH libkb.NaclDHKeyPair if e.arg.Opts.AuthenticityType == keybase1.AuthenticityType_REPUDIABLE && !e.me.IsNil() { encryptionOnlyMode = true dhKey, err := m.G().ActiveDevice.EncryptionKeyWithUID(e.me) if err != nil { return err } dhKeypair, ok := dhKey.(libkb.NaclDHKeyPair) if !ok || dhKeypair.Private == nil { return libkb.KeyCannotEncryptError{} } senderDH = dhKeypair } var senderSigning libkb.NaclSigningKeyPair if e.arg.Opts.AuthenticityType == keybase1.AuthenticityType_SIGNED && !e.me.IsNil() { signingKey, err := m.G().ActiveDevice.SigningKeyWithUID(e.me) if err != nil { return err } signingKeypair, ok := signingKey.(libkb.NaclSigningKeyPair) if !ok || signingKeypair.Private == nil { // Perhaps a KeyCannotEncrypt error, although less accurate, would be more intuitive for the user. return libkb.KeyCannotSignError{} } senderSigning = signingKeypair } if e.arg.Opts.AuthenticityType != keybase1.AuthenticityType_ANONYMOUS && e.me.IsNil() { return libkb.NewLoginRequiredError("authenticating a message requires login. Either login or use --auth-type=anonymous") } saltpackVersion, err := libkb.SaltpackVersionFromArg(e.arg.Opts.SaltpackVersion) if err != nil { return err } encarg := libkb.SaltpackEncryptArg{ Source: e.arg.Source, Sink: e.arg.Sink, Receivers: receivers, Sender: senderDH, SenderSigning: senderSigning, Binary: e.arg.Opts.Binary, EncryptionOnlyMode: encryptionOnlyMode, SymmetricReceivers: symmetricReceivers, SaltpackVersion: saltpackVersion, VisibleRecipientsForTesting: e.visibleRecipientsForTesting, } return libkb.SaltpackEncrypt(m, &encarg) }