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

     1  // Copyright 2015 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  	"errors"
     8  	"fmt"
     9  
    10  	"github.com/keybase/client/go/libkb"
    11  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    12  )
    13  
    14  type RevokeSigsEngine struct {
    15  	libkb.Contextified
    16  	sigIDQueries []string
    17  }
    18  
    19  func NewRevokeSigsEngine(g *libkb.GlobalContext, sigIDQueries []string) *RevokeSigsEngine {
    20  	return &RevokeSigsEngine{
    21  		sigIDQueries: sigIDQueries,
    22  		Contextified: libkb.NewContextified(g),
    23  	}
    24  }
    25  
    26  func (e *RevokeSigsEngine) Name() string {
    27  	return "RevokeSigs"
    28  }
    29  
    30  func (e *RevokeSigsEngine) Prereqs() Prereqs {
    31  	return Prereqs{
    32  		Device: true,
    33  	}
    34  }
    35  
    36  func (e *RevokeSigsEngine) RequiredUIs() []libkb.UIKind {
    37  	return []libkb.UIKind{
    38  		libkb.LogUIKind,
    39  		libkb.SecretUIKind,
    40  	}
    41  }
    42  
    43  func (e *RevokeSigsEngine) SubConsumers() []libkb.UIConsumer {
    44  	return []libkb.UIConsumer{}
    45  }
    46  
    47  func (e *RevokeSigsEngine) getSigIDsToRevoke(me *libkb.User) ([]keybase1.SigID, error) {
    48  	ret := make([]keybase1.SigID, len(e.sigIDQueries))
    49  	for i, query := range e.sigIDQueries {
    50  		if len(query) < keybase1.SigIDQueryMin {
    51  			return nil, errors.New("sigID query too short")
    52  		}
    53  		sigID, err := me.SigIDSearch(query)
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  		ret[i] = sigID
    58  	}
    59  	return ret, nil
    60  }
    61  
    62  func (e *RevokeSigsEngine) Run(m libkb.MetaContext) error {
    63  	m.G().LocalSigchainGuard().Set(m.Ctx(), "RevokeSigsEngine")
    64  	defer m.G().LocalSigchainGuard().Clear(m.Ctx(), "RevokeSigsEngine")
    65  
    66  	me, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m))
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	sigIDsToRevoke, err := e.getSigIDsToRevoke(me)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	lease, merkleRoot, err := libkb.RequestDowngradeLeaseBySigIDs(m.Ctx(), m.G(), sigIDsToRevoke)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	ska := libkb.SecretKeyArg{
    82  		Me:      me,
    83  		KeyType: libkb.DeviceSigningKeyType,
    84  	}
    85  	sigKey, err := e.G().Keyrings.GetSecretKeyWithPrompt(m, m.SecretKeyPromptArg(ska, "to revoke a signature"))
    86  	if err != nil {
    87  		return err
    88  	}
    89  	if sigKey == nil {
    90  		return fmt.Errorf("Revocation signing key is nil.")
    91  	}
    92  	if err = sigKey.CheckSecretKey(); err != nil {
    93  		return err
    94  	}
    95  	proof, err := me.RevokeSigsProof(m, sigKey, sigIDsToRevoke, merkleRoot)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	sig, _, linkID, err := libkb.SignJSON(proof.J, sigKey)
   100  	if err != nil {
   101  		return err
   102  	}
   103  	kid := sigKey.GetKID()
   104  	_, err = m.G().API.Post(m, libkb.APIArg{
   105  		Endpoint:    "sig/revoke",
   106  		SessionType: libkb.APISessionTypeREQUIRED,
   107  		Args: libkb.HTTPArgs{
   108  			"signing_kid":        libkb.S{Val: kid.String()},
   109  			"sig":                libkb.S{Val: sig},
   110  			"downgrade_lease_id": libkb.S{Val: string(lease.LeaseID)},
   111  		},
   112  	})
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	return libkb.MerkleCheckPostedUserSig(m, me.GetUID(), proof.Seqno, linkID)
   118  }