| package data |
| |
| import ( |
| "time" |
| |
| "github.com/jfrazelle/go/canonical/json" |
| ) |
| |
| // SignedRoot is a fully unpacked root.json |
| type SignedRoot struct { |
| Signatures []Signature |
| Signed Root |
| Dirty bool |
| } |
| |
| // Root is the Signed component of a root.json |
| type Root struct { |
| Type string `json:"_type"` |
| Version int `json:"version"` |
| Expires time.Time `json:"expires"` |
| Keys Keys `json:"keys"` |
| Roles map[string]*RootRole `json:"roles"` |
| ConsistentSnapshot bool `json:"consistent_snapshot"` |
| } |
| |
| // NewRoot initializes a new SignedRoot with a set of keys, roles, and the consistent flag |
| func NewRoot(keys map[string]PublicKey, roles map[string]*RootRole, consistent bool) (*SignedRoot, error) { |
| signedRoot := &SignedRoot{ |
| Signatures: make([]Signature, 0), |
| Signed: Root{ |
| Type: TUFTypes["root"], |
| Version: 0, |
| Expires: DefaultExpires("root"), |
| Keys: keys, |
| Roles: roles, |
| ConsistentSnapshot: consistent, |
| }, |
| Dirty: true, |
| } |
| |
| return signedRoot, nil |
| } |
| |
| // ToSigned partially serializes a SignedRoot for further signing |
| func (r SignedRoot) ToSigned() (*Signed, error) { |
| s, err := json.MarshalCanonical(r.Signed) |
| if err != nil { |
| return nil, err |
| } |
| signed := json.RawMessage{} |
| err = signed.UnmarshalJSON(s) |
| if err != nil { |
| return nil, err |
| } |
| sigs := make([]Signature, len(r.Signatures)) |
| copy(sigs, r.Signatures) |
| return &Signed{ |
| Signatures: sigs, |
| Signed: signed, |
| }, nil |
| } |
| |
| // RootFromSigned fully unpacks a Signed object into a SignedRoot |
| func RootFromSigned(s *Signed) (*SignedRoot, error) { |
| r := Root{} |
| err := json.Unmarshal(s.Signed, &r) |
| if err != nil { |
| return nil, err |
| } |
| sigs := make([]Signature, len(s.Signatures)) |
| copy(sigs, s.Signatures) |
| return &SignedRoot{ |
| Signatures: sigs, |
| Signed: r, |
| }, nil |
| } |