...
1 package in_toto
2
3 import (
4 "context"
5 "encoding/base64"
6 "encoding/json"
7 "errors"
8 "fmt"
9 "os"
10
11 "github.com/secure-systems-lab/go-securesystemslib/cjson"
12 "github.com/secure-systems-lab/go-securesystemslib/dsse"
13 "github.com/secure-systems-lab/go-securesystemslib/signerverifier"
14 )
15
16
17 const PayloadType = "application/vnd.in-toto+json"
18
19
20 var ErrInvalidPayloadType = errors.New("unknown payload type")
21
22 type Envelope struct {
23 envelope *dsse.Envelope
24 payload any
25 }
26
27 func loadEnvelope(env *dsse.Envelope) (*Envelope, error) {
28 e := &Envelope{envelope: env}
29
30 contentBytes, err := env.DecodeB64Payload()
31 if err != nil {
32 return nil, err
33 }
34
35 payload, err := loadPayload(contentBytes)
36 if err != nil {
37 return nil, err
38 }
39 e.payload = payload
40
41 return e, nil
42 }
43
44 func (e *Envelope) SetPayload(payload any) error {
45 encodedBytes, err := cjson.EncodeCanonical(payload)
46 if err != nil {
47 return err
48 }
49
50 e.payload = payload
51 e.envelope = &dsse.Envelope{
52 Payload: base64.StdEncoding.EncodeToString(encodedBytes),
53 PayloadType: PayloadType,
54 }
55
56 return nil
57 }
58
59 func (e *Envelope) GetPayload() any {
60 return e.payload
61 }
62
63 func (e *Envelope) VerifySignature(key Key) error {
64 verifier, err := getSignerVerifierFromKey(key)
65 if err != nil {
66 return err
67 }
68
69 ev, err := dsse.NewEnvelopeVerifier(verifier)
70 if err != nil {
71 return err
72 }
73
74 _, err = ev.Verify(context.Background(), e.envelope)
75 return err
76 }
77
78 func (e *Envelope) Sign(key Key) error {
79 signer, err := getSignerVerifierFromKey(key)
80 if err != nil {
81 return err
82 }
83
84 es, err := dsse.NewEnvelopeSigner(signer)
85 if err != nil {
86 return err
87 }
88
89 payload, err := e.envelope.DecodeB64Payload()
90 if err != nil {
91 return err
92 }
93
94 env, err := es.SignPayload(context.Background(), e.envelope.PayloadType, payload)
95 if err != nil {
96 return err
97 }
98
99 e.envelope = env
100 return nil
101 }
102
103 func (e *Envelope) Sigs() []Signature {
104 sigs := []Signature{}
105 for _, s := range e.envelope.Signatures {
106 sigs = append(sigs, Signature{
107 KeyID: s.KeyID,
108 Sig: s.Sig,
109 })
110 }
111 return sigs
112 }
113
114 func (e *Envelope) GetSignatureForKeyID(keyID string) (Signature, error) {
115 for _, s := range e.Sigs() {
116 if s.KeyID == keyID {
117 return s, nil
118 }
119 }
120
121 return Signature{}, fmt.Errorf("no signature found for key '%s'", keyID)
122 }
123
124 func (e *Envelope) Dump(path string) error {
125 jsonBytes, err := json.MarshalIndent(e.envelope, "", " ")
126 if err != nil {
127 return err
128 }
129
130
131 err = os.WriteFile(path, jsonBytes, 0644)
132 if err != nil {
133 return err
134 }
135
136 return nil
137 }
138
139 func getSignerVerifierFromKey(key Key) (dsse.SignerVerifier, error) {
140 sslibKey := getSSLibKeyFromKey(key)
141
142 switch sslibKey.KeyType {
143 case signerverifier.RSAKeyType:
144 return signerverifier.NewRSAPSSSignerVerifierFromSSLibKey(&sslibKey)
145 case signerverifier.ED25519KeyType:
146 return signerverifier.NewED25519SignerVerifierFromSSLibKey(&sslibKey)
147 case signerverifier.ECDSAKeyType:
148 return signerverifier.NewECDSASignerVerifierFromSSLibKey(&sslibKey)
149 }
150
151 return nil, ErrUnsupportedKeyType
152 }
153
154 func getSSLibKeyFromKey(key Key) signerverifier.SSLibKey {
155 return signerverifier.SSLibKey{
156 KeyType: key.KeyType,
157 KeyIDHashAlgorithms: key.KeyIDHashAlgorithms,
158 KeyID: key.KeyID,
159 Scheme: key.Scheme,
160 KeyVal: signerverifier.KeyVal{
161 Public: key.KeyVal.Public,
162 Private: key.KeyVal.Private,
163 Certificate: key.KeyVal.Certificate,
164 },
165 }
166 }
167
View as plain text