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)
12
13// SaltpackSign is an engine.
14type SaltpackSign struct {
15	libkb.Contextified
16	arg *SaltpackSignArg
17	key libkb.NaclSigningKeyPair
18}
19
20type SaltpackSignArg struct {
21	Sink   io.WriteCloser
22	Source io.ReadCloser
23	Opts   keybase1.SaltpackSignOptions
24}
25
26// NewSaltpackSign creates a SaltpackSign engine.
27func NewSaltpackSign(g *libkb.GlobalContext, arg *SaltpackSignArg) *SaltpackSign {
28	return &SaltpackSign{
29		arg:          arg,
30		Contextified: libkb.NewContextified(g),
31	}
32}
33
34// Name is the unique engine name.
35func (e *SaltpackSign) Name() string {
36	return "SaltpackSign"
37}
38
39// GetPrereqs returns the engine prereqs.
40func (e *SaltpackSign) Prereqs() Prereqs {
41	return Prereqs{
42		Device: true,
43	}
44}
45
46// RequiredUIs returns the required UIs.
47func (e *SaltpackSign) RequiredUIs() []libkb.UIKind {
48	return []libkb.UIKind{
49		libkb.SecretUIKind,
50	}
51}
52
53// SubConsumers returns the other UI consumers for this engine.
54func (e *SaltpackSign) SubConsumers() []libkb.UIConsumer {
55	return nil
56}
57
58// Run starts the engine.
59func (e *SaltpackSign) Run(m libkb.MetaContext) error {
60	if err := e.loadKey(m); err != nil {
61		return err
62	}
63
64	saltpackVersion, err := libkb.SaltpackVersionFromArg(e.arg.Opts.SaltpackVersion)
65	if err != nil {
66		return err
67	}
68
69	if e.arg.Opts.Detached {
70		return libkb.SaltpackSignDetached(e.G(), e.arg.Source, e.arg.Sink, e.key, e.arg.Opts.Binary, saltpackVersion)
71	}
72
73	return libkb.SaltpackSign(e.G(), e.arg.Source, e.arg.Sink, e.key, e.arg.Opts.Binary, saltpackVersion)
74}
75
76func (e *SaltpackSign) loadKey(m libkb.MetaContext) error {
77	loggedIn, uid, err := isLoggedInWithUIDAndError(m)
78	if err != nil {
79		return err
80	}
81	if !loggedIn {
82		return libkb.NewLoginRequiredError("login required for signing")
83	}
84	key, err := m.G().ActiveDevice.SigningKeyWithUID(uid)
85	if err != nil {
86		return err
87	}
88	kp, ok := key.(libkb.NaclSigningKeyPair)
89	if !ok || kp.Private == nil {
90		return libkb.KeyCannotSignError{}
91	}
92	e.key = kp
93	return nil
94}
95