forked from endophage/gotuf
/
targets.go
126 lines (115 loc) · 3.18 KB
/
targets.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
117
118
119
120
121
122
123
124
125
126
package data
import (
"crypto/sha256"
"encoding/hex"
"github.com/jfrazelle/go/canonical/json"
)
// SignedTargets is a fully unpacked targets.json, or target delegation
// json file
type SignedTargets struct {
Signatures []Signature
Signed Targets
Dirty bool
}
// Targets is the Signed components of a targets.json or delegation json file
type Targets struct {
SignedCommon
Targets Files `json:"targets"`
Delegations Delegations `json:"delegations,omitempty"`
}
// NewTargets intiializes a new empty SignedTargets object
func NewTargets() *SignedTargets {
return &SignedTargets{
Signatures: make([]Signature, 0),
Signed: Targets{
SignedCommon: SignedCommon{
Type: TUFTypes["targets"],
Version: 0,
Expires: DefaultExpires("targets"),
},
Targets: make(Files),
Delegations: *NewDelegations(),
},
Dirty: true,
}
}
// GetMeta attempts to find the targets entry for the path. It
// will return nil in the case of the target not being found.
func (t SignedTargets) GetMeta(path string) *FileMeta {
for p, meta := range t.Signed.Targets {
if p == path {
return &meta
}
}
return nil
}
// GetDelegations filters the roles and associated keys that may be
// the signers for the given target path. If no appropriate roles
// can be found, it will simply return nil for the return values.
// The returned slice of Role will have order maintained relative
// to the role slice on Delegations per TUF spec proposal on using
// order to determine priority.
func (t SignedTargets) GetDelegations(path string) []*Role {
var roles []*Role
pathHashBytes := sha256.Sum256([]byte(path))
pathHash := hex.EncodeToString(pathHashBytes[:])
for _, r := range t.Signed.Delegations.Roles {
if !r.IsValid() {
// Role has both Paths and PathHashPrefixes.
continue
}
if r.CheckPaths(path) {
roles = append(roles, r)
continue
}
if r.CheckPrefixes(pathHash) {
roles = append(roles, r)
continue
}
//keysDB.AddRole(r)
}
return roles
}
// AddTarget adds or updates the meta for the given path
func (t *SignedTargets) AddTarget(path string, meta FileMeta) {
t.Signed.Targets[path] = meta
t.Dirty = true
}
// AddDelegation will add a new delegated role with the given keys,
// ensuring the keys either already exist, or are added to the map
// of delegation keys
func (t *SignedTargets) AddDelegation(role *Role, keys []*PublicKey) error {
return nil
}
// ToSigned partially serializes a SignedTargets for further signing
func (t SignedTargets) ToSigned() (*Signed, error) {
s, err := json.MarshalCanonical(t.Signed)
if err != nil {
return nil, err
}
signed := json.RawMessage{}
err = signed.UnmarshalJSON(s)
if err != nil {
return nil, err
}
sigs := make([]Signature, len(t.Signatures))
copy(sigs, t.Signatures)
return &Signed{
Signatures: sigs,
Signed: signed,
}, nil
}
// TargetsFromSigned fully unpacks a Signed object into a SignedTargets
func TargetsFromSigned(s *Signed) (*SignedTargets, error) {
t := Targets{}
err := json.Unmarshal(s.Signed, &t)
if err != nil {
return nil, err
}
sigs := make([]Signature, len(s.Signatures))
copy(sigs, s.Signatures)
return &SignedTargets{
Signatures: sigs,
Signed: t,
}, nil
}