-
Notifications
You must be signed in to change notification settings - Fork 0
/
ticket.go
107 lines (89 loc) · 2.53 KB
/
ticket.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
package keeper
import (
"context"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/furynet/furynetwork/x/dvm/types"
)
// VerifyTicket validates a ticket.
// For JWT see https://datatracker.ietf.org/doc/html/rfc7519
// * exp is required.
func (k Keeper) VerifyTicket(goCtx context.Context, ticket string) error {
ctx := sdk.UnwrapSDKContext(goCtx)
t, err := types.NewJwtTicket(ticket)
if err != nil {
return err
}
// check the expiration of ticket
err = t.ValidateExpiry(ctx)
if err != nil {
return err
}
// get pub keys from KV-Store
keys, found := k.GetKeyVault(ctx)
if !found {
return types.ErrNoPublicKeysFound
}
// validate the ticket by the keys
err = t.Verify(keys.GetLeader())
if err != nil {
return err
}
return nil
}
// VerifyTicketUnmarshal verifies the ticket first, then if the token was verified, it unmarshal the data of ticket into clm.
func (k Keeper) VerifyTicketUnmarshal(goCtx context.Context, ticketStr string, clm interface{}) error {
return k.verifyTicketWithKeyUnmarshal(goCtx, ticketStr, clm)
}
// verifyTicketWithKeyUnmarshal verifies the ticket using the provided publiv key first, then if the token was verified, it unmarshal the data of ticket into clm.
func (k Keeper) verifyTicketWithKeyUnmarshal(goCtx context.Context, ticketStr string, clm interface{}, pubKeys ...string) error {
ctx := sdk.UnwrapSDKContext(goCtx)
// construct new ticket object from string ticket
ticket, err := types.NewJwtTicket(ticketStr)
if err != nil {
return err
}
// check the expiration of ticket
err = ticket.ValidateExpiry(ctx)
if err != nil {
return err
}
// get key vault from module state
keyVault, found := k.GetKeyVault(ctx)
if !found {
return types.ErrNoPublicKeysFound
}
for _, pk := range pubKeys {
// check if the provided pubkey is registered or not
isRegistered := false
for _, registereedPubKey := range keyVault.PublicKeys {
if registereedPubKey == pk {
isRegistered = true
}
}
// pubkey is not registered so it is invalid
if !isRegistered {
return fmt.Errorf("the provided public key is not registered in the blockchain store: %s", pk)
}
}
if len(pubKeys) == 0 {
// validate ticket by the keys with the leader public key
leader := keyVault.GetLeader()
err = ticket.Verify(leader)
if err != nil {
return err
}
} else {
// validate ticket by the keys with provided pubkeys
err = ticket.VerifyAny(pubKeys)
if err != nil {
return err
}
}
// unmarshal ticket
err = ticket.Unmarshal(clm)
if err != nil {
return err
}
return nil
}