github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/pgp_keygen.go (about)

     1  // Copyright 2016 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package engine
     5  
     6  import (
     7  	"github.com/keybase/client/go/libkb"
     8  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
     9  )
    10  
    11  // PGPKeyGen is an engine.
    12  type PGPKeyGen struct {
    13  	libkb.Contextified
    14  	arg    keybase1.PGPKeyGenDefaultArg
    15  	genArg *libkb.PGPGenArg
    16  }
    17  
    18  // NewPGPKeyGen creates a PGPKeyGen engine.
    19  func NewPGPKeyGen(g *libkb.GlobalContext, arg keybase1.PGPKeyGenDefaultArg) *PGPKeyGen {
    20  	return &PGPKeyGen{
    21  		Contextified: libkb.NewContextified(g),
    22  		arg:          arg,
    23  	}
    24  }
    25  
    26  // Name is the unique engine name.
    27  func (e *PGPKeyGen) Name() string {
    28  	return "PGPKeyGen"
    29  }
    30  
    31  // GetPrereqs returns the engine prereqs.
    32  func (e *PGPKeyGen) Prereqs() Prereqs {
    33  	return Prereqs{
    34  		Device: true,
    35  	}
    36  }
    37  
    38  // RequiredUIs returns the required UIs.
    39  func (e *PGPKeyGen) RequiredUIs() []libkb.UIKind {
    40  	return []libkb.UIKind{
    41  		libkb.PgpUIKind,
    42  		libkb.SecretUIKind,
    43  	}
    44  }
    45  
    46  // SubConsumers returns the other UI consumers for this engine.
    47  func (e *PGPKeyGen) SubConsumers() []libkb.UIConsumer {
    48  	return []libkb.UIConsumer{
    49  		&PGPKeyImportEngine{},
    50  	}
    51  }
    52  
    53  // Run starts the engine.
    54  func (e *PGPKeyGen) Run(m libkb.MetaContext) error {
    55  
    56  	// generate a new pgp key with defaults (and no push)
    57  	var genArg libkb.PGPGenArg
    58  	if e.genArg != nil {
    59  		genArg = *e.genArg
    60  	}
    61  	genArg.Ids = libkb.ImportPGPIdentities(e.arg.CreateUids.Ids)
    62  	arg := PGPKeyImportEngineArg{
    63  		AllowMulti: true,
    64  		OnlySave:   true,
    65  		Gen:        &genArg,
    66  	}
    67  	eng := NewPGPKeyImportEngine(m.G(), arg)
    68  	if err := RunEngine2(m, eng); err != nil {
    69  		return err
    70  	}
    71  
    72  	// tell the UI about the key
    73  	m.Debug("generated pgp key: %s", eng.bundle.GetFingerprint())
    74  	pub, err := eng.bundle.Encode()
    75  	if err != nil {
    76  		return err
    77  	}
    78  	keyArg := keybase1.KeyGeneratedArg{
    79  		Kid: eng.bundle.GetKID(),
    80  		Key: keybase1.KeyInfo{
    81  			Fingerprint: eng.bundle.GetFingerprint().String(),
    82  			Key:         pub,
    83  			Desc:        eng.bundle.VerboseDescription(),
    84  		},
    85  	}
    86  	if err := m.UIs().PgpUI.KeyGenerated(m.Ctx(), keyArg); err != nil {
    87  		return err
    88  	}
    89  
    90  	// ask if we should push private key to api server if user has a password
    91  	passphraseState, err := libkb.LoadPassphraseState(m)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	pushPrivate, err := m.UIs().PgpUI.ShouldPushPrivate(m.Ctx(), keybase1.ShouldPushPrivateArg{
    96  		SessionID: m.UIs().SessionID,
    97  		Prompt:    passphraseState == keybase1.PassphraseState_KNOWN,
    98  	})
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	m.Debug("push private generated pgp key to API server? %v", pushPrivate)
   104  	if err := e.push(m, eng.bundle, pushPrivate); err != nil {
   105  		return err
   106  	}
   107  
   108  	// tell ui everything finished
   109  	return m.UIs().PgpUI.Finished(m.Ctx(), m.UIs().SessionID)
   110  }
   111  
   112  func (e *PGPKeyGen) push(m libkb.MetaContext, bundle *libkb.PGPKeyBundle, pushPrivate bool) (err error) {
   113  	defer m.Trace("PGPKeyGen.push", &err)()
   114  
   115  	me, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m).WithPublicKeyOptional())
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	del := &libkb.Delegator{
   121  		Me:             me,
   122  		Expire:         libkb.KeyExpireIn,
   123  		DelegationType: libkb.DelegationTypeSibkey,
   124  		Contextified:   libkb.NewContextified(m.G()),
   125  	}
   126  	if err := del.LoadSigningKey(m, m.UIs().SecretUI); err != nil {
   127  		return err
   128  	}
   129  	del.NewKey = bundle
   130  
   131  	if pushPrivate {
   132  		tsec, gen, err := libkb.GetTriplesecMaybePrompt(m)
   133  		if err != nil {
   134  			return err
   135  		}
   136  
   137  		skb, err := bundle.ToServerSKB(m.G(), tsec, gen)
   138  		if err != nil {
   139  			return err
   140  		}
   141  
   142  		armored, err := skb.ArmoredEncode()
   143  		if err != nil {
   144  			return err
   145  		}
   146  		del.EncodedPrivateKey = armored
   147  	}
   148  
   149  	return del.Run(m)
   150  }