File: root.go

package info (click to toggle)
golang-github-endophage-gotuf 0.0~git20151020.0.2df1c8e-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 436 kB
  • ctags: 504
  • sloc: makefile: 27
file content (89 lines) | stat: -rw-r--r-- 2,226 bytes parent folder | download
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
package data

import (
	"time"

	"github.com/jfrazelle/go/canonical/json"
)

type SignedRoot struct {
	Signatures []Signature
	Signed     Root
	Dirty      bool
}

type Root struct {
	Type    string    `json:"_type"`
	Version int       `json:"version"`
	Expires time.Time `json:"expires"`
	// These keys are public keys. We use TUFKey instead of PublicKey to
	// support direct JSON unmarshaling.
	Keys               map[string]*TUFKey   `json:"keys"`
	Roles              map[string]*RootRole `json:"roles"`
	ConsistentSnapshot bool                 `json:"consistent_snapshot"`
}

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:               make(map[string]*TUFKey),
			Roles:              roles,
			ConsistentSnapshot: consistent,
		},
		Dirty: true,
	}

	// Convert PublicKeys to TUFKey structures
	// The Signed.Keys map needs to have *TUFKey values, since this
	// structure gets directly unmarshalled from JSON, and it's not
	// possible to unmarshal into an interface type. But this function
	// takes a map with PublicKey values to avoid exposing this ugliness.
	// The loop below converts to the TUFKey type.
	for k, v := range keys {
		signedRoot.Signed.Keys[k] = &TUFKey{
			Type: v.Algorithm(),
			Value: KeyPair{
				Public:  v.Public(),
				Private: nil,
			},
		}
	}

	return signedRoot, nil
}

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
}

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
}