This repository has been archived by the owner on Jul 7, 2020. It is now read-only.
forked from keybase/client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
upak.go
115 lines (106 loc) · 3.75 KB
/
upak.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package libkb
// UPAK = "User Plus All Keys"
import (
"fmt"
keybase1 "github.com/keybase/client/go/protocol/keybase1"
)
// BaseProofSet creates a basic proof set for a user with their
// keybase and uid proofs and any pgp fingerprint proofs.
func BaseProofSet(u *keybase1.UserPlusAllKeys) *ProofSet {
proofs := []Proof{
{Key: "keybase", Value: u.GetName()},
{Key: "uid", Value: u.GetUID().String()},
}
for _, key := range u.PGPKeys {
proofs = append(proofs, Proof{Key: PGPAssertionKey, Value: key.PGPFingerprint})
}
return NewProofSet(proofs)
}
// checkKIDPGP checks that the user has the given PGP KID valid *now*. Note that it doesn't
// check for revoked PGP keys, and it also does not check key expiration.
func checkKIDPGP(u *keybase1.UserPlusKeysV2AllIncarnations, kid keybase1.KID) (found bool) {
for _, key := range u.Current.PGPKeys {
if key.Base.Kid.Equal(kid) {
return true
}
}
return false
}
func checkKIDKeybase(u *keybase1.UserPlusKeysV2AllIncarnations, kid keybase1.KID) (found bool, revokedAt *keybase1.KeybaseTime, deleted bool) {
exportRevokedAt := func(key keybase1.PublicKeyV2NaCl) *keybase1.KeybaseTime {
if key.Base.Revocation != nil {
// This is the inverse of the marshalling we do in rpc_exim.go.
return &keybase1.KeybaseTime{
Unix: key.Base.Revocation.Time,
Chain: key.Base.Revocation.PrevMerkleRootSigned.Seqno,
}
}
return nil
}
for _, key := range u.Current.DeviceKeys {
if key.Base.Kid.Equal(kid) {
found = true
revokedAt = exportRevokedAt(key)
}
}
for _, pastIncarnation := range u.PastIncarnations {
for _, key := range pastIncarnation.DeviceKeys {
if key.Base.Kid.Equal(kid) {
found = true
deleted = true
revokedAt = exportRevokedAt(key)
}
}
}
return
}
func CheckKID(u *keybase1.UserPlusKeysV2AllIncarnations, kid keybase1.KID) (found bool, revokedAt *keybase1.KeybaseTime, deleted bool) {
if IsPGPAlgo(AlgoType(kid.GetKeyType())) {
found = checkKIDPGP(u, kid)
return found, nil, false
}
return checkKIDKeybase(u, kid)
}
func GetRemoteChainLinkFor(u *keybase1.UserPlusAllKeys, username NormalizedUsername, uid keybase1.UID, g *GlobalContext) (ret *TrackChainLink, err error) {
defer g.Trace(fmt.Sprintf("UPAK#GetRemoteChainLinkFor(%s,%s,%s)", u.Base.Uid, username, uid), func() error { return err })()
g.VDL.Log(VLog1, "| Full user: %+v\n", *u)
rtl := u.GetRemoteTrack(username.String())
if rtl == nil {
g.VDL.Log(VLog0, "| no remote track found")
return nil, nil
}
if !rtl.Uid.Equal(uid) {
return nil, UIDMismatchError{Msg: fmt.Sprintf("UIDs didn't match for (%s,%q); got %s", uid, username.String(), rtl.Uid)}
}
var lid LinkID
g.VDL.Log(VLog0, "| remote track found with linkID=%s", rtl.LinkID)
lid, err = ImportLinkID(rtl.LinkID)
if err != nil {
g.Log.Debug("| Failed to import link ID")
return nil, err
}
var link *ChainLink
link, err = ImportLinkFromStorage(lid, u.Base.Uid, g)
if err != nil {
g.Log.Debug("| failed to import link from storage")
return nil, err
}
if link == nil {
g.Log.Debug("| no cached chainlink found")
// Such a bug is only possible if the DB cache was reset after
// this user was originally loaded in; otherwise, all of this
// UPAK's chain links should be available on disk.
return nil, InconsistentCacheStateError{}
}
ret, err = ParseTrackChainLink(GenericChainLink{link})
g.VDL.Log(VLog0, "| ParseTrackChainLink -> found=%v", (ret != nil))
return ret, err
}
func TrackChainLinkFromUserPlusAllKeys(u *keybase1.UserPlusAllKeys, username NormalizedUsername, uid keybase1.UID, g *GlobalContext) (*TrackChainLink, error) {
tcl, err := GetRemoteChainLinkFor(u, username, uid, g)
if _, ok := err.(InconsistentCacheStateError); ok {
return nil, err
}
tcl, err = TrackChainLinkFor(u.Base.Uid, uid, tcl, err, g)
return tcl, err
}