Sign a composition with a trusted key and compose one by hand with mesh-compose (issue 1943, S5)
The node-engine applies only a composition signed by the controller or the operator, and when the controller cannot compose its own fix the operator composes, signs and writes one at the terminal (ADR 0539 clauses 3 and 10).
This commit is contained in:
@@ -46,6 +46,9 @@ type Composed struct {
|
||||
Resources []json.RawMessage
|
||||
Filled []string
|
||||
Own NodeOwn
|
||||
// Signature is the controller's or, made by hand, the operator's (ADR 0539 clause 3, SignComposed); it signs the
|
||||
// digest and is never part of it.
|
||||
Signature *Signature
|
||||
}
|
||||
|
||||
// composedWire is a composition as it is written.
|
||||
@@ -58,6 +61,7 @@ type composedWire struct {
|
||||
Resources []json.RawMessage `json:"resources"`
|
||||
Filled []string `json:"filled_files,omitempty"`
|
||||
Own *NodeOwn `json:"own,omitempty"`
|
||||
Signature *Signature `json:"signature,omitempty"`
|
||||
}
|
||||
|
||||
// canonicalJSON is raw with its object keys sorted and its spacing dropped, its numbers kept as written.
|
||||
@@ -126,6 +130,11 @@ func (c Composed) check() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.Signature != nil {
|
||||
if err := c.Signature.check(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -135,7 +144,7 @@ func (c Composed) wire() (composedWire, error) {
|
||||
return composedWire{}, err
|
||||
}
|
||||
w := composedWire{V: Version, Node: c.Node, Module: c.Module, FP: c.FP, Data: c.Data, Filled: c.Filled,
|
||||
Resources: make([]json.RawMessage, len(c.Resources))}
|
||||
Signature: c.Signature, Resources: make([]json.RawMessage, len(c.Resources))}
|
||||
for i, r := range c.Resources {
|
||||
canon, err := canonicalJSON(r)
|
||||
if err != nil {
|
||||
@@ -174,7 +183,7 @@ func DecodeComposed(data []byte) (Composed, error) {
|
||||
return Composed{}, fmt.Errorf("delivery: a composition does not fit its shape: %w", err)
|
||||
}
|
||||
c := Composed{V: w.V, Node: w.Node, Module: w.Module, FP: w.FP, Data: w.Data, Resources: w.Resources,
|
||||
Filled: w.Filled}
|
||||
Filled: w.Filled, Signature: w.Signature}
|
||||
if w.Own != nil {
|
||||
c.Own = *w.Own
|
||||
}
|
||||
@@ -184,9 +193,10 @@ func DecodeComposed(data []byte) (Composed, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ComposedDigestOf is a composition's digest, "sha256:<hex>", of its encoding. A want names it (ADR 0539 clause 1),
|
||||
// and the controller writes it beside the composition.
|
||||
// ComposedDigestOf is a composition's digest, "sha256:<hex>", of its encoding without its signature. A want names it
|
||||
// (ADR 0539 clause 1), the controller writes it beside the composition, and the signature signs it.
|
||||
func ComposedDigestOf(c Composed) (string, error) {
|
||||
c.Signature = nil
|
||||
raw, err := EncodeComposed(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -195,7 +205,7 @@ func ComposedDigestOf(c Composed) (string, error) {
|
||||
return "sha256:" + hex.EncodeToString(sum[:]), nil
|
||||
}
|
||||
|
||||
// SameComposed says whether two compositions are the same value, so the controller writes
|
||||
// SameComposed says whether two compositions are the same value, their signatures included, so the controller writes
|
||||
// only when they differ.
|
||||
func SameComposed(a, b Composed) bool {
|
||||
ra, errA := EncodeComposed(a)
|
||||
|
||||
Reference in New Issue
Block a user