github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/teams/oracle.go (about) 1 package teams 2 3 import ( 4 "github.com/keybase/client/go/libkb" 5 "github.com/keybase/client/go/protocol/keybase1" 6 "golang.org/x/crypto/nacl/box" 7 ) 8 9 func TryDecryptWithTeamKey(mctx libkb.MetaContext, arg keybase1.TryDecryptWithTeamKeyArg) (ret []byte, err error) { 10 loadArg := keybase1.LoadTeamArg{ 11 ID: arg.TeamID, 12 Public: arg.TeamID.IsPublic(), 13 ForceRepoll: false, 14 Refreshers: keybase1.TeamRefreshers{ 15 NeedKeyGeneration: arg.MinGeneration, 16 }, 17 } 18 team, err := Load(mctx.Ctx(), mctx.G(), loadArg) 19 if err != nil { 20 return nil, err 21 } 22 23 mctx.Debug("Loaded team %q, max key generation is %d", team.ID, team.Generation()) 24 25 tryKeys := func(min keybase1.PerTeamKeyGeneration) (ret []byte, found bool, err error) { 26 if min == 0 { 27 // per team keys start from generation 1. 28 min = 1 29 } 30 for gen := team.Generation(); gen >= min; gen-- { 31 key, err := team.encryptionKeyAtGen(mctx.Ctx(), gen) 32 if err != nil { 33 mctx.Debug("Failed to get key gen %d: %v", gen, err) 34 switch err.(type) { 35 case libkb.NotFoundError: 36 continue 37 default: 38 return nil, false, err 39 } 40 } 41 42 mctx.Debug("Trying to unbox with key gen %d", gen) 43 decryptedData, ok := box.Open(nil, arg.EncryptedData, (*[24]byte)(&arg.Nonce), 44 (*[32]byte)(&arg.PeersPublicKey), (*[32]byte)(key.Private)) 45 if !ok { 46 continue 47 } 48 49 mctx.Debug("Success! Decrypted using encryption key gen=%d", gen) 50 return decryptedData, true, nil 51 } 52 53 // No error, but didn't find the right key either. 54 return nil, false, nil 55 } 56 57 ret, found, err := tryKeys(arg.MinGeneration) 58 if err != nil { 59 // Error during key searching. 60 return nil, err 61 } 62 if found { 63 // Success - found the right key. 64 return ret, nil 65 } 66 67 mctx.Debug("Repolling team") 68 69 // Repoll the team and if we get more keys, try again. 70 loadArg.Refreshers = keybase1.TeamRefreshers{} 71 loadArg.ForceRepoll = true 72 team, err = Load(mctx.Ctx(), mctx.G(), loadArg) 73 if err != nil { 74 return nil, err 75 } 76 mctx.Debug("Reloaded team %q, max key generation is %d", team.ID, team.Generation()) 77 ret, found, err = tryKeys(1) 78 if err != nil { 79 return nil, err 80 } 81 if found { 82 return ret, nil 83 } 84 return nil, libkb.DecryptionError{} 85 }