1
1
package gnosisaccessnode
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"math"
6
7
7
8
pubsub "github.com/libp2p/go-libp2p-pubsub"
8
9
"github.com/pkg/errors"
9
10
11
+ "github.com/shutter-network/shutter/shlib/shcrypto"
12
+
10
13
obskeyperdatabase "github.com/shutter-network/rolling-shutter/rolling-shutter/chainobserver/db/keyper"
11
14
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/gnosis"
12
15
"github.com/shutter-network/rolling-shutter/rolling-shutter/p2pmsg"
13
16
)
14
17
15
18
type DecryptionKeysHandler struct {
16
- config * Config
19
+ config * Config
20
+ storage * Storage
17
21
}
18
22
19
- func NewDecryptionKeysHandler (config * Config ) * DecryptionKeysHandler {
23
+ func NewDecryptionKeysHandler (config * Config , storage * Storage ) * DecryptionKeysHandler {
20
24
return & DecryptionKeysHandler {
21
- config : config ,
25
+ config : config ,
26
+ storage : storage ,
22
27
}
23
28
}
24
29
@@ -39,25 +44,49 @@ func (handler *DecryptionKeysHandler) ValidateMessage(_ context.Context, msg p2p
39
44
return pubsub .ValidationAccept , nil
40
45
}
41
46
42
- func (handler * DecryptionKeysHandler ) validateCommonFields (key * p2pmsg.DecryptionKeys ) (pubsub.ValidationResult , error ) {
43
- if key .InstanceID != handler .config .InstanceID {
47
+ func (handler * DecryptionKeysHandler ) validateCommonFields (keys * p2pmsg.DecryptionKeys ) (pubsub.ValidationResult , error ) {
48
+ if keys .InstanceID != handler .config .InstanceID {
44
49
return pubsub .ValidationReject ,
45
- errors .Errorf ("instance ID mismatch (want=%d, have=%d)" , handler .config .InstanceID , key .GetInstanceID ())
50
+ errors .Errorf ("instance ID mismatch (want=%d, have=%d)" , handler .config .InstanceID , keys .GetInstanceID ())
46
51
}
47
- if key .Eon > math .MaxInt64 {
48
- return pubsub .ValidationReject , errors .Errorf ("eon %d overflows int64" , key .Eon )
52
+ if keys .Eon > math .MaxInt64 {
53
+ return pubsub .ValidationReject , errors .Errorf ("eon %d overflows int64" , keys .Eon )
49
54
}
50
55
51
- if len (key .Keys ) == 0 {
56
+ if len (keys .Keys ) == 0 {
52
57
return pubsub .ValidationReject , errors .New ("no keys in message" )
53
58
}
54
- if len (key .Keys ) > int (handler .config .MaxNumKeysPerMessage ) {
59
+ if len (keys .Keys ) > int (handler .config .MaxNumKeysPerMessage ) {
55
60
return pubsub .ValidationReject , errors .Errorf (
56
61
"too many keys in message (%d > %d)" ,
57
- len (key .Keys ),
62
+ len (keys .Keys ),
58
63
handler .config .MaxNumKeysPerMessage ,
59
64
)
60
65
}
66
+
67
+ eonKey , ok := handler .storage .GetEonKey (keys .Eon )
68
+ if ! ok {
69
+ return pubsub .ValidationReject , errors .Errorf ("no eon key found for eon %d" , keys .Eon )
70
+ }
71
+
72
+ for i , k := range keys .Keys {
73
+ epochSecretKey , err := k .GetEpochSecretKey ()
74
+ if err != nil {
75
+ return pubsub .ValidationReject , err
76
+ }
77
+ ok , err := shcrypto .VerifyEpochSecretKey (epochSecretKey , eonKey , k .Identity )
78
+ if err != nil {
79
+ return pubsub .ValidationReject , errors .Wrapf (err , "error while checking epoch secret key for identity %x" , k .Identity )
80
+ }
81
+ if ! ok {
82
+ return pubsub .ValidationReject , errors .Errorf ("epoch secret key for identity %x is not valid" , k .Identity )
83
+ }
84
+
85
+ if i > 0 && bytes .Compare (k .Identity , keys .Keys [i - 1 ].Identity ) < 0 {
86
+ return pubsub .ValidationReject , errors .Errorf ("keys not ordered" )
87
+ }
88
+ }
89
+
61
90
return pubsub .ValidationAccept , nil
62
91
}
63
92
0 commit comments