diff options
Diffstat (limited to 'src/gnunet/service/revocation/module.go')
-rw-r--r-- | src/gnunet/service/revocation/module.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/gnunet/service/revocation/module.go b/src/gnunet/service/revocation/module.go new file mode 100644 index 0000000..b5c8a16 --- /dev/null +++ b/src/gnunet/service/revocation/module.go | |||
@@ -0,0 +1,124 @@ | |||
1 | // This file is part of gnunet-go, a GNUnet-implementation in Golang. | ||
2 | // Copyright (C) 2019, 2020 Bernd Fix >Y< | ||
3 | // | ||
4 | // gnunet-go is free software: you can redistribute it and/or modify it | ||
5 | // under the terms of the GNU Affero General Public License as published | ||
6 | // by the Free Software Foundation, either version 3 of the License, | ||
7 | // or (at your option) any later version. | ||
8 | // | ||
9 | // gnunet-go is distributed in the hope that it will be useful, but | ||
10 | // WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | // Affero General Public License for more details. | ||
13 | // | ||
14 | // You should have received a copy of the GNU Affero General Public License | ||
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | // | ||
17 | // SPDX-License-Identifier: AGPL3.0-or-later | ||
18 | |||
19 | package revocation | ||
20 | |||
21 | import ( | ||
22 | "gnunet/config" | ||
23 | "gnunet/service" | ||
24 | "gnunet/util" | ||
25 | |||
26 | "github.com/bfix/gospel/crypto/ed25519" | ||
27 | "github.com/bfix/gospel/data" | ||
28 | "github.com/bfix/gospel/logger" | ||
29 | ) | ||
30 | |||
31 | //====================================================================== | ||
32 | // "GNUnet Revocation" implementation | ||
33 | //====================================================================== | ||
34 | |||
35 | // RevocationModule handles the revocation-related calls to other modules. | ||
36 | type RevocationModule struct { | ||
37 | bloomf *data.BloomFilter // bloomfilter for fast revocation check | ||
38 | kvs util.KeyValueStore // storage for known revocations | ||
39 | } | ||
40 | |||
41 | // Init a revocation module | ||
42 | func (m *RevocationModule) Init() error { | ||
43 | // Initialize access to revocation data storage | ||
44 | var err error | ||
45 | if m.kvs, err = util.OpenKVStore(config.Cfg.Revocation.Storage); err != nil { | ||
46 | return err | ||
47 | } | ||
48 | // traverse the storage and build bloomfilter for all keys | ||
49 | m.bloomf = data.NewBloomFilter(1000000, 1e-8) | ||
50 | keys, err := m.kvs.List() | ||
51 | if err != nil { | ||
52 | return err | ||
53 | } | ||
54 | for _, key := range keys { | ||
55 | buf, err := util.DecodeStringToBinary(key, 32) | ||
56 | if err != nil { | ||
57 | return err | ||
58 | } | ||
59 | m.bloomf.Add(buf) | ||
60 | } | ||
61 | return nil | ||
62 | } | ||
63 | |||
64 | // NewRevocationModule returns an initialized revocation module | ||
65 | func NewRevocationModule() *RevocationModule { | ||
66 | m := new(RevocationModule) | ||
67 | if err := m.Init(); err != nil { | ||
68 | logger.Printf(logger.ERROR, "[revocation] Failed to initialize module: %s\n", err.Error()) | ||
69 | return nil | ||
70 | } | ||
71 | return m | ||
72 | } | ||
73 | |||
74 | // Query return true if the pkey is valid (not revoked) and false | ||
75 | // if the pkey has been revoked. | ||
76 | func (s *RevocationModule) Query(ctx *service.SessionContext, pkey *ed25519.PublicKey) (valid bool, err error) { | ||
77 | // fast check first: is the key in the bloomfilter? | ||
78 | data := pkey.Bytes() | ||
79 | if !s.bloomf.Contains(data) { | ||
80 | // no: it is valid (not revoked) | ||
81 | return true, nil | ||
82 | } | ||
83 | // check in store to detect false-positives | ||
84 | key := util.EncodeBinaryToString(data) | ||
85 | if _, err = s.kvs.Get(key); err != nil { | ||
86 | logger.Printf(logger.ERROR, "[revocation] Failed to locate key '%s' in store: %s\n", key, err.Error()) | ||
87 | // assume not revoked... | ||
88 | return true, err | ||
89 | } | ||
90 | // key seems to be revoked | ||
91 | return false, nil | ||
92 | } | ||
93 | |||
94 | // Revoke | ||
95 | func (s *RevocationModule) Revoke(ctx *service.SessionContext, rd *RevData) (success bool, err error) { | ||
96 | // verify the revocation data | ||
97 | rc := rd.Verify() | ||
98 | switch { | ||
99 | case rc == -1: | ||
100 | logger.Println(logger.WARN, "[revocation] Revoke: Missing/invalid signature") | ||
101 | return false, nil | ||
102 | case rc == -2: | ||
103 | logger.Println(logger.WARN, "[revocation] Revoke: Expired revocation") | ||
104 | return false, nil | ||
105 | case rc == -3: | ||
106 | logger.Println(logger.WARN, "[revocation] Revoke: Wrong PoW sequence order") | ||
107 | return false, nil | ||
108 | case rc < 25: | ||
109 | logger.Println(logger.WARN, "[revocation] Revoke: Difficulty to small") | ||
110 | return false, nil | ||
111 | } | ||
112 | // store the revocation data | ||
113 | // (1) add it to the bloomfilter | ||
114 | s.bloomf.Add(rd.ZoneKey) | ||
115 | // (2) add it to the store | ||
116 | var buf []byte | ||
117 | key := util.EncodeBinaryToString(rd.ZoneKey) | ||
118 | if buf, err = data.Marshal(rd); err != nil { | ||
119 | return false, err | ||
120 | } | ||
121 | value := util.EncodeBinaryToString(buf) | ||
122 | err = s.kvs.Put(key, value) | ||
123 | return true, err | ||
124 | } | ||