1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package engine 5 6import ( 7 "io" 8 9 "github.com/keybase/client/go/libkb" 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 "github.com/keybase/saltpack" 12) 13 14// SaltpackVerify is an engine. 15type SaltpackVerify struct { 16 libkb.Contextified 17 arg *SaltpackVerifyArg 18} 19 20// SaltpackVerifyArg are engine args. 21type SaltpackVerifyArg struct { 22 Sink io.WriteCloser 23 Source io.Reader 24 Opts keybase1.SaltpackVerifyOptions 25} 26 27// NewSaltpackVerify creates a SaltpackVerify engine. 28func NewSaltpackVerify(g *libkb.GlobalContext, arg *SaltpackVerifyArg) *SaltpackVerify { 29 return &SaltpackVerify{ 30 arg: arg, 31 Contextified: libkb.NewContextified(g), 32 } 33} 34 35// Name is the unique engine name. 36func (e *SaltpackVerify) Name() string { 37 return "SaltpackVerify" 38} 39 40// Prereqs returns the engine prereqs. 41func (e *SaltpackVerify) Prereqs() Prereqs { 42 return Prereqs{} 43} 44 45// RequiredUIs returns the required UIs. 46func (e *SaltpackVerify) RequiredUIs() []libkb.UIKind { 47 return []libkb.UIKind{ 48 libkb.SaltpackUIKind, 49 } 50} 51 52// SubConsumers returns the other UI consumers for this engine. 53func (e *SaltpackVerify) SubConsumers() []libkb.UIConsumer { 54 return []libkb.UIConsumer{&SaltpackSenderIdentify{}} 55} 56 57// Run starts the engine. 58func (e *SaltpackVerify) Run(m libkb.MetaContext) error { 59 if len(e.arg.Opts.Signature) > 0 { 60 return e.detached(m) 61 } 62 return e.attached(m) 63} 64 65func (e *SaltpackVerify) attached(m libkb.MetaContext) error { 66 hook := func(key saltpack.SigningPublicKey) error { 67 return e.identifySender(m, key) 68 } 69 return libkb.SaltpackVerify(m.G(), e.arg.Source, e.arg.Sink, hook) 70} 71 72func (e *SaltpackVerify) detached(m libkb.MetaContext) error { 73 hook := func(key saltpack.SigningPublicKey) error { 74 return e.identifySender(m, key) 75 } 76 return libkb.SaltpackVerifyDetached(m.G(), e.arg.Source, e.arg.Opts.Signature, hook) 77} 78 79func (e *SaltpackVerify) identifySender(m libkb.MetaContext, key saltpack.SigningPublicKey) (err error) { 80 defer m.Trace("SaltpackVerify#identifySender", &err)() 81 82 kid := libkb.SigningPublicKeyToKeybaseKID(key) 83 spsiArg := SaltpackSenderIdentifyArg{ 84 publicKey: kid, 85 reason: keybase1.IdentifyReason{ 86 Reason: "Identify who signed this message", 87 Type: keybase1.IdentifyReasonType_VERIFY, 88 }, 89 userAssertion: e.arg.Opts.SignedBy, 90 } 91 92 spsiEng := NewSaltpackSenderIdentify(m.G(), &spsiArg) 93 if err = RunEngine2(m, spsiEng); err != nil { 94 return err 95 } 96 97 if senderTypeIsSuccessful(spsiEng.Result().SenderType) { 98 arg := keybase1.SaltpackVerifySuccessArg{ 99 Sender: spsiEng.Result(), 100 SigningKID: kid, 101 } 102 return m.UIs().SaltpackUI.SaltpackVerifySuccess(m.Ctx(), arg) 103 } 104 105 arg := keybase1.SaltpackVerifyBadSenderArg{ 106 Sender: spsiEng.Result(), 107 SigningKID: kid, 108 } 109 // This will return an error if --force is not given. 110 return m.UIs().SaltpackUI.SaltpackVerifyBadSender(m.Ctx(), arg) 111} 112 113func senderTypeIsSuccessful(senderType keybase1.SaltpackSenderType) bool { 114 return (senderType == keybase1.SaltpackSenderType_NOT_TRACKED || 115 senderType == keybase1.SaltpackSenderType_UNKNOWN || 116 senderType == keybase1.SaltpackSenderType_ANONYMOUS || 117 senderType == keybase1.SaltpackSenderType_TRACKING_OK || 118 senderType == keybase1.SaltpackSenderType_SELF) 119} 120