This repository has been archived by the owner on Jul 7, 2020. It is now read-only.
forked from keybase/client
/
special_keys.go
116 lines (96 loc) · 2.86 KB
/
special_keys.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
116
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package libkb
import (
keybase1 "github.com/keybase/client/go/protocol/keybase1"
)
// SpecialKeyRing holds blessed keys, like the one Keybase uses to sign
// its Merkle Root.
type SpecialKeyRing struct {
Contextified
// Cache of keys that are used in verifying the root
keys map[keybase1.KID]GenericKey
// The only ones allowed for this purpose
validKIDs map[keybase1.KID]bool
}
// NewSpecialKeyRing allocates a new SpecialKeyRing with the given
// vector of KIDs. For NaCl keys, it will actually import those
// keys into the Keyring.
func NewSpecialKeyRing(v []keybase1.KID, g *GlobalContext) *SpecialKeyRing {
ret := &SpecialKeyRing{
keys: make(map[keybase1.KID]GenericKey),
validKIDs: make(map[keybase1.KID]bool),
Contextified: NewContextified(g),
}
for _, kid := range v {
if key, _ := ImportKeypairFromKID(kid); key != nil {
ret.keys[kid] = key
}
ret.validKIDs[kid] = true
}
return ret
}
// IsValidKID returns if this KID is valid (blessed) according to this Keyring
func (sk *SpecialKeyRing) IsValidKID(kid keybase1.KID) bool {
val, found := sk.validKIDs[kid]
return val && found
}
func LoadPGPKeyFromLocalDB(k keybase1.KID, g *GlobalContext) (*PGPKeyBundle, error) {
dbobj, err := g.LocalDb.Get(DbKey{
Typ: DBPGPKey,
Key: k.String(),
})
if err != nil {
return nil, err
}
if dbobj == nil {
return nil, nil
}
kb, w, err := GetOneKey(dbobj)
w.Warn(g)
return kb, err
}
// Load takes a blessed KID and returns, if possible, the GenericKey
// associated with that KID, for signature verification. If the key isn't
// found in memory or on disk (in the case of PGP), then it will attempt
// to fetch the key from the keybase server.
func (sk *SpecialKeyRing) Load(kid keybase1.KID) (GenericKey, error) {
sk.G().Log.Debug("+ SpecialKeyRing.Load(%s)", kid)
if !sk.IsValidKID(kid) {
err := UnknownSpecialKIDError{kid}
return nil, err
}
if key, found := sk.keys[kid]; found {
sk.G().Log.Debug("- SpecialKeyRing.Load(%s) -> hit inmem cache", kid)
return key, nil
}
key, err := LoadPGPKeyFromLocalDB(kid, sk.G())
if err != nil || key == nil {
sk.G().Log.Debug("| Load(%s) going to network", kid)
var res *APIRes
res, err = sk.G().API.Get(APIArg{
Endpoint: "key/special",
SessionType: APISessionTypeNONE,
Args: HTTPArgs{
"kid": S{kid.String()},
},
})
var w *Warnings
if err == nil {
key, w, err = GetOneKey(res.Body.AtKey("bundle"))
}
if err == nil {
w.Warn(sk.G())
if e2 := key.StoreToLocalDb(sk.G()); e2 != nil {
sk.G().Log.Warning("Failed to store key: %s", e2)
}
}
} else {
sk.G().Log.Debug("| Load(%s) hit DB-backed cache", kid)
}
if err == nil && key != nil {
sk.keys[kid] = key
}
sk.G().Log.Debug("- SpecialKeyRing.Load(%s)", kid)
return key, err
}