A composition is applied only when the controller or the operator signed it; the node agent's integration tests on an embedded bus (R6-A A9, A1, A5)
This commit is contained in:
+19
-16
@@ -12,6 +12,7 @@ package agent
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -87,10 +88,11 @@ type Env struct {
|
||||
// Kept is the resources the node last applied for a module from the declaration it kept before the switch (ADR 0539
|
||||
// §9), as JSON, and whether it held the module. Nil when the node kept none.
|
||||
Kept func(module string) ([]json.RawMessage, bool)
|
||||
// Verify judges a composition's bytes before anything of it is read: a composition whose signer is not trusted is
|
||||
// refused (ADR 0539 §3). Nil trusts the bucket, which only the controller and the operator can write.
|
||||
Verify func(key string, raw []byte) error
|
||||
Say func(string)
|
||||
// Trusted is the public keys a composition may be signed by: the controller's and the operator's (ADR 0539 §3). A
|
||||
// composition unsigned, signed by another key, or changed after it was signed is refused and nothing of it is
|
||||
// applied. Nil trusts no key, so nothing is applied.
|
||||
Trusted func() []ed25519.PublicKey
|
||||
Say func(string)
|
||||
}
|
||||
|
||||
// Agent follows the wants.
|
||||
@@ -281,23 +283,24 @@ func (a *Agent) takeComposition(u Update) string {
|
||||
return module
|
||||
}
|
||||
now := compNow{Raw: u.Value, Rev: u.Revision}
|
||||
if a.env.Verify != nil {
|
||||
if err := a.env.Verify(u.Key, u.Value); err != nil {
|
||||
now.Err = fmt.Errorf("refused: %w", err)
|
||||
a.comps[u.Key] = now
|
||||
a.sayOnce("verify:"+u.Key, fmt.Sprintf("the composition %s is refused and nothing of it is applied: %v", u.Key, err))
|
||||
return module
|
||||
}
|
||||
}
|
||||
c, err := delivery.DecodeComposed(u.Value)
|
||||
if err == nil {
|
||||
var trusted []ed25519.PublicKey
|
||||
if a.env.Trusted != nil {
|
||||
trusted = a.env.Trusted()
|
||||
}
|
||||
// The signature before anything of the composition is used: its digest is what the want names.
|
||||
now.C = c
|
||||
now.Dig, err = delivery.ComposedDigestOf(c)
|
||||
}
|
||||
now.Err = err
|
||||
if err != nil {
|
||||
now.Dig, err = delivery.VerifyComposed(c, trusted)
|
||||
if err != nil {
|
||||
now.C = delivery.Composed{}
|
||||
a.sayOnce("verify:"+u.Key, fmt.Sprintf("the composition %s is refused and nothing of it is applied: %v", u.Key, err))
|
||||
err = fmt.Errorf("refused: %w", err)
|
||||
}
|
||||
} else {
|
||||
a.sayOnce("decode:"+u.Key, fmt.Sprintf("the composition %s cannot be read, and nothing of it is applied: %v", u.Key, err))
|
||||
}
|
||||
now.Err = err
|
||||
a.comps[u.Key] = now
|
||||
return module
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user