Jiri Simsa | d7616c9 | 2015-03-24 23:44:30 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Vanadium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Asim Shankar | ae8d4c5 | 2014-10-08 13:03:31 -0700 | [diff] [blame] | 5 | package security |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 6 | |
Asim Shankar | b07ec69 | 2015-02-27 23:40:44 -0800 | [diff] [blame] | 7 | // TODO(ashankar,ataly): This file is a bit of a mess!! Define a serialization |
| 8 | // format for the blessing store and rewrite this file before release! |
| 9 | |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 10 | import ( |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 11 | "bytes" |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 12 | "crypto/sha256" |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 13 | "fmt" |
| 14 | "reflect" |
Cosmos Nicolaou | 3bdf637 | 2014-12-10 09:53:52 -0800 | [diff] [blame] | 15 | "sort" |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 16 | "strings" |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 17 | "sync" |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 18 | "time" |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 19 | |
Jiri Simsa | 6ac9522 | 2015-02-23 16:11:49 -0800 | [diff] [blame] | 20 | "v.io/v23/security" |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 21 | "v.io/v23/verror" |
Jiri Simsa | 337af23 | 2015-02-27 14:36:46 -0800 | [diff] [blame] | 22 | "v.io/x/lib/vlog" |
Todd Wang | b351149 | 2015-04-07 23:32:34 -0700 | [diff] [blame] | 23 | "v.io/x/ref/lib/security/serialization" |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 24 | ) |
| 25 | |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 26 | var ( |
| 27 | errStoreAddMismatch = verror.Register(pkgPath+".errStoreAddMismatch", verror.NoRetry, "{1:}{2:} blessing's public key does not match store's public key{:_}") |
| 28 | errBadBlessingPattern = verror.Register(pkgPath+".errBadBlessingPattern", verror.NoRetry, "{1:}{2:} {3} is an invalid BlessingPattern{:_}") |
| 29 | errBlessingsNotForKey = verror.Register(pkgPath+".errBlessingsNotForKey", verror.NoRetry, "{1:}{2:} read Blessings: {3} that are not for provided PublicKey{:_}") |
| 30 | errDataOrSignerUnspecified = verror.Register(pkgPath+".errDataOrSignerUnspecified", verror.NoRetry, "{1:}{2:} persisted data or signer is not specified{:_}") |
| 31 | ) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 32 | |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 33 | const cacheKeyFormat = uint32(1) |
| 34 | |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 35 | // blessingStore implements security.BlessingStore. |
| 36 | type blessingStore struct { |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 37 | publicKey security.PublicKey |
| 38 | serializer SerializerReaderWriter |
| 39 | signer serialization.Signer |
| 40 | mu sync.RWMutex |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 41 | state blessingStoreState // GUARDED_BY(mu) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 42 | } |
| 43 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 44 | func (bs *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) { |
Ankur | 9e8500a | 2014-09-17 12:05:32 -0700 | [diff] [blame] | 45 | if !forPeers.IsValid() { |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 46 | return security.Blessings{}, verror.New(errBadBlessingPattern, nil, forPeers) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 47 | } |
Asim Shankar | 2bf7b1e | 2015-02-27 00:45:12 -0800 | [diff] [blame] | 48 | if !blessings.IsZero() && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) { |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 49 | return security.Blessings{}, verror.New(errStoreAddMismatch, nil) |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 50 | } |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 51 | bs.mu.Lock() |
| 52 | defer bs.mu.Unlock() |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 53 | old, hadold := bs.state.PeerBlessings[forPeers] |
Asim Shankar | 2bf7b1e | 2015-02-27 00:45:12 -0800 | [diff] [blame] | 54 | if !blessings.IsZero() { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 55 | bs.state.PeerBlessings[forPeers] = blessings |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 56 | } else { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 57 | delete(bs.state.PeerBlessings, forPeers) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 58 | } |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 59 | if err := bs.save(); err != nil { |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 60 | if hadold { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 61 | bs.state.PeerBlessings[forPeers] = old |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 62 | } else { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 63 | delete(bs.state.PeerBlessings, forPeers) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 64 | } |
Asim Shankar | 2bf7b1e | 2015-02-27 00:45:12 -0800 | [diff] [blame] | 65 | return security.Blessings{}, err |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 66 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 67 | return old, nil |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 68 | } |
| 69 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 70 | func (bs *blessingStore) ForPeer(peerBlessings ...string) security.Blessings { |
| 71 | bs.mu.RLock() |
| 72 | defer bs.mu.RUnlock() |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 73 | |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 74 | var ret security.Blessings |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 75 | for pattern, b := range bs.state.PeerBlessings { |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 76 | if pattern.MatchedBy(peerBlessings...) { |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 77 | if union, err := security.UnionOfBlessings(ret, b); err != nil { |
| 78 | vlog.Errorf("UnionOfBlessings(%v, %v) failed: %v, dropping the latter from BlessingStore.ForPeers(%v)", ret, b, err, peerBlessings) |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 79 | } else { |
| 80 | ret = union |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 81 | } |
| 82 | } |
| 83 | } |
Asim Shankar | 48bf0e6 | 2014-10-03 16:27:05 -0700 | [diff] [blame] | 84 | return ret |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 85 | } |
| 86 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 87 | func (bs *blessingStore) Default() security.Blessings { |
| 88 | bs.mu.RLock() |
| 89 | defer bs.mu.RUnlock() |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 90 | return bs.state.DefaultBlessings |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 91 | } |
| 92 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 93 | func (bs *blessingStore) SetDefault(blessings security.Blessings) error { |
| 94 | bs.mu.Lock() |
| 95 | defer bs.mu.Unlock() |
Asim Shankar | 2bf7b1e | 2015-02-27 00:45:12 -0800 | [diff] [blame] | 96 | if !blessings.IsZero() && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) { |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 97 | return verror.New(errStoreAddMismatch, nil) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 98 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 99 | oldDefault := bs.state.DefaultBlessings |
| 100 | bs.state.DefaultBlessings = blessings |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 101 | if err := bs.save(); err != nil { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 102 | bs.state.DefaultBlessings = oldDefault |
| 103 | return err |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 104 | } |
| 105 | return nil |
| 106 | } |
| 107 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 108 | func (bs *blessingStore) PublicKey() security.PublicKey { |
| 109 | return bs.publicKey |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 110 | } |
| 111 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 112 | func (bs *blessingStore) String() string { |
| 113 | return fmt.Sprintf("{state: %v, publicKey: %v}", bs.state, bs.publicKey) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 114 | } |
| 115 | |
gauthamt | f826393 | 2014-12-16 10:59:09 -0800 | [diff] [blame] | 116 | func (bs *blessingStore) PeerBlessings() map[security.BlessingPattern]security.Blessings { |
| 117 | m := make(map[security.BlessingPattern]security.Blessings) |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 118 | for pattern, b := range bs.state.PeerBlessings { |
| 119 | m[pattern] = b |
gauthamt | f826393 | 2014-12-16 10:59:09 -0800 | [diff] [blame] | 120 | } |
| 121 | return m |
| 122 | } |
| 123 | |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 124 | func (bs *blessingStore) CacheDischarge(discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) { |
| 125 | id := discharge.ID() |
| 126 | tp := caveat.ThirdPartyDetails() |
| 127 | // Only add to the cache if the caveat did not require arguments. |
| 128 | if id == "" || tp == nil || tp.Requirements().ReportArguments { |
| 129 | return |
| 130 | } |
| 131 | key := dcacheKey(tp, impetus) |
| 132 | bs.mu.Lock() |
| 133 | defer bs.mu.Unlock() |
| 134 | old, hadold := bs.state.DischargeCache[key] |
| 135 | bs.state.DischargeCache[key] = discharge |
| 136 | if err := bs.save(); err != nil { |
| 137 | if hadold { |
| 138 | bs.state.DischargeCache[key] = old |
| 139 | } else { |
| 140 | delete(bs.state.DischargeCache, key) |
| 141 | } |
| 142 | } |
| 143 | return |
| 144 | } |
| 145 | |
| 146 | func (bs *blessingStore) ClearDischarges(discharges ...security.Discharge) { |
| 147 | bs.mu.Lock() |
| 148 | bs.clearDischargesLocked(discharges...) |
| 149 | bs.mu.Unlock() |
| 150 | return |
| 151 | } |
| 152 | |
| 153 | func (bs *blessingStore) clearDischargesLocked(discharges ...security.Discharge) { |
| 154 | for _, d := range discharges { |
| 155 | for k, cached := range bs.state.DischargeCache { |
| 156 | if cached.Equivalent(d) { |
| 157 | delete(bs.state.DischargeCache, k) |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | func (bs *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) (out security.Discharge) { |
| 164 | defer bs.mu.Unlock() |
| 165 | bs.mu.Lock() |
| 166 | tp := caveat.ThirdPartyDetails() |
| 167 | if tp == nil || tp.Requirements().ReportArguments { |
| 168 | return |
| 169 | } |
| 170 | key := dcacheKey(tp, impetus) |
| 171 | if cached, exists := bs.state.DischargeCache[key]; exists { |
| 172 | out = cached |
| 173 | // If the discharge has expired, purge it from the cache. |
| 174 | if hasDischargeExpired(out) { |
| 175 | out = security.Discharge{} |
| 176 | bs.clearDischargesLocked(cached) |
| 177 | } |
| 178 | } |
| 179 | return |
| 180 | } |
| 181 | |
| 182 | func hasDischargeExpired(dis security.Discharge) bool { |
| 183 | expiry := dis.Expiry() |
| 184 | if expiry.IsZero() { |
| 185 | return false |
| 186 | } |
| 187 | return expiry.Before(time.Now()) |
| 188 | } |
| 189 | |
| 190 | func dcacheKey(tp security.ThirdPartyCaveat, impetus security.DischargeImpetus) dischargeCacheKey { |
| 191 | // If the algorithm for computing dcacheKey changes, cacheKeyFormat must be changed as well. |
| 192 | id := tp.ID() |
| 193 | r := tp.Requirements() |
| 194 | var method, servers string |
| 195 | // We currently do not cache on impetus.Arguments because there it seems there is no |
| 196 | // general way to generate a key from them. |
| 197 | if r.ReportMethod { |
| 198 | method = impetus.Method |
| 199 | } |
| 200 | if r.ReportServer && len(impetus.Server) > 0 { |
| 201 | // Sort the server blessing patterns to increase cache usage. |
| 202 | var bps []string |
| 203 | for _, bp := range impetus.Server { |
| 204 | bps = append(bps, string(bp)) |
| 205 | } |
| 206 | sort.Strings(bps) |
| 207 | servers = strings.Join(bps, ",") |
| 208 | } |
| 209 | h := sha256.New() |
| 210 | h.Write(hashString(id)) |
| 211 | h.Write(hashString(method)) |
| 212 | h.Write(hashString(servers)) |
| 213 | var key [sha256.Size]byte |
| 214 | copy(key[:], h.Sum(nil)) |
| 215 | return key |
| 216 | } |
| 217 | |
| 218 | func hashString(d string) []byte { |
| 219 | h := sha256.Sum256([]byte(d)) |
| 220 | return h[:] |
| 221 | } |
| 222 | |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 223 | // DebugString return a human-readable string encoding of the store |
| 224 | // in the following format |
Suharsh Sivakumar | 4bbe8ed | 2015-04-09 14:21:44 -0700 | [diff] [blame] | 225 | // Default Blessings <blessings> |
| 226 | // Peer pattern Blessings |
| 227 | // <pattern> <blessings> |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 228 | // ... |
Suharsh Sivakumar | 4bbe8ed | 2015-04-09 14:21:44 -0700 | [diff] [blame] | 229 | // <pattern> <blessings> |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 230 | func (bs *blessingStore) DebugString() string { |
Suharsh Sivakumar | 4bbe8ed | 2015-04-09 14:21:44 -0700 | [diff] [blame] | 231 | const format = "%-30s %s\n" |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 232 | buff := bytes.NewBufferString(fmt.Sprintf(format, "Default Blessings", bs.state.DefaultBlessings)) |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 233 | |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 234 | buff.WriteString(fmt.Sprintf(format, "Peer pattern", "Blessings")) |
Cosmos Nicolaou | 3bdf637 | 2014-12-10 09:53:52 -0800 | [diff] [blame] | 235 | |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 236 | sorted := make([]string, 0, len(bs.state.PeerBlessings)) |
| 237 | for k, _ := range bs.state.PeerBlessings { |
Cosmos Nicolaou | 3bdf637 | 2014-12-10 09:53:52 -0800 | [diff] [blame] | 238 | sorted = append(sorted, string(k)) |
| 239 | } |
| 240 | sort.Strings(sorted) |
| 241 | for _, pattern := range sorted { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 242 | buff.WriteString(fmt.Sprintf(format, pattern, bs.state.PeerBlessings[security.BlessingPattern(pattern)])) |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 243 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 244 | return buff.String() |
Ankur | 1615a7d | 2014-10-09 11:58:02 -0700 | [diff] [blame] | 245 | } |
| 246 | |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 247 | func (bs *blessingStore) save() error { |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 248 | if (bs.signer == nil) && (bs.serializer == nil) { |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 249 | return nil |
| 250 | } |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 251 | data, signature, err := bs.serializer.Writers() |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 252 | if err != nil { |
| 253 | return err |
| 254 | } |
| 255 | return encodeAndStore(bs.state, data, signature, bs.signer) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 256 | } |
| 257 | |
Ankur | 7c89059 | 2014-10-02 11:36:28 -0700 | [diff] [blame] | 258 | // newInMemoryBlessingStore returns an in-memory security.BlessingStore for a |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 259 | // principal with the provided PublicKey. |
| 260 | // |
| 261 | // The returned BlessingStore is initialized with an empty set of blessings. |
Ankur | 7c89059 | 2014-10-02 11:36:28 -0700 | [diff] [blame] | 262 | func newInMemoryBlessingStore(publicKey security.PublicKey) security.BlessingStore { |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 263 | return &blessingStore{ |
| 264 | publicKey: publicKey, |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 265 | state: blessingStoreState{ |
| 266 | PeerBlessings: make(map[security.BlessingPattern]security.Blessings), |
| 267 | DischargeCache: make(map[dischargeCacheKey]security.Discharge), |
| 268 | }, |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 269 | } |
| 270 | } |
| 271 | |
Ankur | 5748301 | 2014-11-19 13:17:37 -0800 | [diff] [blame] | 272 | func (bs *blessingStore) verifyState() error { |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 273 | for _, b := range bs.state.PeerBlessings { |
| 274 | if !reflect.DeepEqual(b.PublicKey(), bs.publicKey) { |
| 275 | return verror.New(errBlessingsNotForKey, nil, b, bs.publicKey) |
Ankur | 5748301 | 2014-11-19 13:17:37 -0800 | [diff] [blame] | 276 | } |
| 277 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 278 | if !bs.state.DefaultBlessings.IsZero() && !reflect.DeepEqual(bs.state.DefaultBlessings.PublicKey(), bs.publicKey) { |
| 279 | return verror.New(errBlessingsNotForKey, nil, bs.state.DefaultBlessings, bs.publicKey) |
Ankur | 5748301 | 2014-11-19 13:17:37 -0800 | [diff] [blame] | 280 | } |
| 281 | return nil |
| 282 | } |
| 283 | |
Ankur | 27c56fd | 2014-11-17 19:30:34 -0800 | [diff] [blame] | 284 | func (bs *blessingStore) deserialize() error { |
| 285 | data, signature, err := bs.serializer.Readers() |
| 286 | if err != nil { |
| 287 | return err |
| 288 | } |
| 289 | if data == nil && signature == nil { |
| 290 | return nil |
| 291 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 292 | if err := decodeFromStorage(&bs.state, data, signature, bs.signer.PublicKey()); err != nil { |
Suharsh Sivakumar | 911c81a | 2015-05-18 16:58:28 -0700 | [diff] [blame] | 293 | return err |
Ankur | 27c56fd | 2014-11-17 19:30:34 -0800 | [diff] [blame] | 294 | } |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 295 | if bs.state.CacheKeyFormat != cacheKeyFormat { |
| 296 | bs.state.CacheKeyFormat = cacheKeyFormat |
| 297 | bs.state.DischargeCache = make(map[dischargeCacheKey]security.Discharge) |
| 298 | } |
Ankur | cc04385 | 2015-04-14 13:10:28 -0700 | [diff] [blame] | 299 | return bs.verifyState() |
Ankur | 27c56fd | 2014-11-17 19:30:34 -0800 | [diff] [blame] | 300 | } |
| 301 | |
Ankur | 7c89059 | 2014-10-02 11:36:28 -0700 | [diff] [blame] | 302 | // newPersistingBlessingStore returns a security.BlessingStore for a principal |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 303 | // that is initialized with the persisted data. The returned security.BlessingStore |
| 304 | // also persists any updates to its state. |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 305 | func newPersistingBlessingStore(serializer SerializerReaderWriter, signer serialization.Signer) (security.BlessingStore, error) { |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 306 | if serializer == nil || signer == nil { |
Mike Burrows | 7f7088d | 2015-03-25 13:05:00 -0700 | [diff] [blame] | 307 | return nil, verror.New(errDataOrSignerUnspecified, nil) |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 308 | } |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 309 | bs := &blessingStore{ |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 310 | publicKey: signer.PublicKey(), |
Ankur | ee0aa81 | 2014-11-14 10:56:52 -0800 | [diff] [blame] | 311 | serializer: serializer, |
| 312 | signer: signer, |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 313 | } |
Ankur | 27c56fd | 2014-11-17 19:30:34 -0800 | [diff] [blame] | 314 | if err := bs.deserialize(); err != nil { |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 315 | return nil, err |
| 316 | } |
Suharsh Sivakumar | d7d4e22 | 2015-06-22 11:10:44 -0700 | [diff] [blame] | 317 | if bs.state.PeerBlessings == nil { |
| 318 | bs.state.PeerBlessings = make(map[security.BlessingPattern]security.Blessings) |
| 319 | } |
| 320 | if bs.state.DischargeCache == nil { |
| 321 | bs.state.DischargeCache = make(map[dischargeCacheKey]security.Discharge) |
| 322 | } |
gauthamt | 1e313bc | 2014-11-10 15:45:56 -0800 | [diff] [blame] | 323 | return bs, nil |
Ankur | 100eb27 | 2014-09-15 16:48:12 -0700 | [diff] [blame] | 324 | } |