boolpolicy

package
v0.14.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package boolpolicy provides an identity type whose ownership is governed by a boolean expression over a set of component identities.

Wire representation

A PolicyIdentity is serialised as a DER SEQUENCE carrying two fields:

PolicyIdentity ::= SEQUENCE {
    policy     UTF8String,           -- e.g. "$0 OR ($1 AND $2)"
    identities SEQUENCE OF OCTET STRING
}

The serialised bytes are then wrapped in the standard TypedIdentity envelope (type tag PolicyIdentityType = 6) before being placed on the wire, exactly as MultiIdentity is wrapped with MultiSigIdentityType = 5.

Signature representation

A PolicySignature is serialised as:

PolicySignature ::= SEQUENCE OF OCTET STRING

Entries are ordered to match the identities slice. An entry may be nil / empty to represent an absent signature (valid when the policy only requires the other branch of an OR).

Package boolpolicy implements a recursive-descent parser for boolean expressions of the form "$0 OR ($1 AND $2)", where $N is an index reference into a caller-supplied slice of bool values.

Grammar (OR binds less tightly than AND):

expr      = or_expr

or_expr   = and_expr ( 'OR' and_expr )*
and_expr  = primary  ( 'AND' primary  )*
primary   = '$' digits | '(' expr ')'

Index

Constants

View Source
const (
	// Policy is the IdentityType tag for policy identities.
	// It is stored in the TypedIdentity envelope and must be unique across all
	// identity types registered in token/driver/wallet.go.
	Policy       = tdriver.PolicyIdentityType       // 6
	PolicyString = tdriver.PolicyIdentityTypeString // "policy"
)

Variables

View Source
var (
	// ErrNoRecipients is returned by WrapAuditInfo when the recipients slice is empty.
	ErrNoRecipients = errors.New("no recipients provided")
	// ErrMismatch is returned by InfoMatcher when the identity count or a
	// component identity does not match the corresponding audit info.
	ErrMismatch = errors.New("policy identity mismatch")
)

Functions

func JoinSignatures

func JoinSignatures(identities []token.Identity, sigmas map[string][]byte) ([]byte, error)

JoinSignatures builds a PolicySignature from a map of per-identity signatures. Identities not present in sigmas receive a nil entry, which is valid as long as the policy does not require them. The order of the entries matches the order of identities.

func UnwrapAuditInfo

func UnwrapAuditInfo(info []byte) (bool, [][]byte, error)

UnwrapAuditInfo extracts the per-component audit info bytes from a packed blob.

func WrapAuditInfo

func WrapAuditInfo(recipients [][]byte) ([]byte, error)

WrapAuditInfo packs per-component audit info bytes into a single blob.

func WrapPolicyIdentity

func WrapPolicyIdentity(policy string, ids ...token.Identity) (token.Identity, error)

WrapPolicyIdentity encodes policy and identities into a fully-enveloped token.Identity (TypedIdentity with type tag Policy).

Types

type AndNode

type AndNode struct {
	Left, Right Node
}

AndNode represents Left AND Right.

func (*AndNode) Eval

func (a *AndNode) Eval(refs []bool) bool

func (*AndNode) String

func (a *AndNode) String() string

type AuditInfo

type AuditInfo struct {
	IdentityAuditInfos []IdentityAuditInfo
}

AuditInfo represents the audit info of a policy identity. It is a sequence of per-component audit infos in the same order as Identities.

func (*AuditInfo) Bytes

func (a *AuditInfo) Bytes() ([]byte, error)

func (*AuditInfo) EnrollmentID

func (a *AuditInfo) EnrollmentID() string

func (*AuditInfo) RevocationHandle

func (a *AuditInfo) RevocationHandle() string

type AuditInfoDeserializer

type AuditInfoDeserializer struct{}

AuditInfoDeserializer deserialises raw audit info bytes into the AuditInfo struct for the enrollment-ID / revocation-handle path.

func (*AuditInfoDeserializer) DeserializeAuditInfo

func (a *AuditInfoDeserializer) DeserializeAuditInfo(_ context.Context, _ driver.Identity, raw []byte) (driver2.AuditInfo, error)

type AuditInfoMatcher

type AuditInfoMatcher interface {
	GetAuditInfoMatcher(ctx context.Context, owner driver.Identity, auditInfo []byte) (driver.Matcher, error)
}

AuditInfoMatcher builds a Matcher for a single component identity.

type IdentityAuditInfo

type IdentityAuditInfo struct {
	AuditInfo []byte
}

IdentityAuditInfo holds the audit info bytes for one component identity.

type InfoMatcher

type InfoMatcher struct {
	AuditInfoMatcher []tdriver.Matcher
}

InfoMatcher matches a policy identity against its own audit info.

func (*InfoMatcher) Match

func (e *InfoMatcher) Match(ctx context.Context, raw []byte) error

type Node

type Node interface {
	// Eval evaluates the node against a slice of resolved boolean values.
	// A RefNode with index i returns refs[i]; out-of-range indices return false.
	Eval(refs []bool) bool
	String() string
}

Node is the common interface for all AST nodes produced by Parse.

func Parse

func Parse(input string) (Node, error)

Parse parses a boolean expression string and returns the root AST node. It returns an error for any lexical or syntactic problems.

Parse enforces two hard limits to prevent resource exhaustion:

  • input longer than maxPolicyLen bytes is rejected immediately.
  • parenthesis nesting deeper than maxParseDepth levels is rejected; this bounds the Go call-stack depth of the recursive descent and prevents goroutine stack exhaustion from attacker-supplied input.

type OrNode

type OrNode struct {
	Left, Right Node
}

OrNode represents Left OR Right.

func (*OrNode) Eval

func (o *OrNode) Eval(refs []bool) bool

func (*OrNode) String

func (o *OrNode) String() string

type PolicyIdentity

type PolicyIdentity struct {
	// Policy is the policy expression string, e.g. "$0 OR ($1 AND $2)".
	// It is parsed at verification time via the boolexpr package.
	Policy string `asn1:"utf8"`
	// Identities is the ordered slice of component identities.
	// $0 refers to Identities[0], $1 to Identities[1], and so on.
	Identities [][]byte
}

PolicyIdentity holds a boolean policy expression and the ordered list of component identities that the $N references index into.

func Unwrap

func Unwrap(raw []byte) (pi *PolicyIdentity, ok bool, err error)

Unwrap decodes a token.Identity into its policy string and component identities. It returns (nil, false, nil) when raw is not a policy identity.

func (*PolicyIdentity) Bytes

func (p *PolicyIdentity) Bytes() ([]byte, error)

Bytes is an alias for Serialize, provided for symmetry with MultiIdentity.

func (*PolicyIdentity) Deserialize

func (p *PolicyIdentity) Deserialize(raw []byte) error

Deserialize decodes raw DER bytes into the receiver.

func (*PolicyIdentity) Serialize

func (p *PolicyIdentity) Serialize() ([]byte, error)

Serialize returns the ASN.1 DER encoding of the PolicyIdentity.

type PolicySignature

type PolicySignature struct {
	Signatures [][]byte
}

PolicySignature is the on-wire signature envelope for a policy identity. It carries one slot per component identity; slots for parties that did not sign are left nil/empty. This allows OR policies to be satisfied by a strict subset of the component signers.

Wire format: ASN.1 SEQUENCE OF OCTET STRING (mirrors MultiSignature).

func (*PolicySignature) Bytes

func (s *PolicySignature) Bytes() ([]byte, error)

Bytes serialises the PolicySignature to ASN.1 DER.

func (*PolicySignature) FromBytes

func (s *PolicySignature) FromBytes(raw []byte) error

FromBytes deserialises raw ASN.1 DER into the receiver.

type PolicyVerifier

type PolicyVerifier struct {
	// Policy is the parsed boolean AST, produced by Parse.
	Policy Node
	// Verifiers is indexed by $N; each entry verifies the corresponding
	// component identity's individual signature.
	Verifiers []driver.Verifier
}

PolicyVerifier verifies a PolicySignature against a parsed policy AST. It implements driver.Verifier.

Verification walks the policy AST:

  • RefNode{i}: sigs[i] must be non-empty and Verifiers[i].Verify must succeed.
  • AndNode: both sub-trees must verify successfully.
  • OrNode: at least one sub-tree must verify successfully.

This means a valid PolicySignature need only carry signatures for the identities actually required by the satisfied policy branch.

func (*PolicyVerifier) Verify

func (v *PolicyVerifier) Verify(msg, sigBytes []byte) error

Verify implements driver.Verifier. sigBytes must be a PolicySignature ASN.1 DER blob produced by JoinSignatures.

type RefNode

type RefNode struct {
	Index int
}

RefNode references a single boolean value by its index (e.g. $3).

func (*RefNode) Eval

func (r *RefNode) Eval(refs []bool) bool

func (*RefNode) String

func (r *RefNode) String() string

type TypedIdentityDeserializer

type TypedIdentityDeserializer struct {
	VerifierDeserializer VerifierDES
	AuditInfoMatcher     AuditInfoMatcher
}

TypedIdentityDeserializer handles the Policy identity type for both verifier deserialization and audit-info operations. It mirrors multisig.TypedIdentityDeserializer exactly.

func NewTypedIdentityDeserializer

func NewTypedIdentityDeserializer(verifierDeserializer VerifierDES, auditInfoMatcher AuditInfoMatcher) *TypedIdentityDeserializer

NewTypedIdentityDeserializer returns a TypedIdentityDeserializer. Both arguments are typically the parent multiplex deserializer (des, des), matching the recursive pattern used for multisig.

func (*TypedIdentityDeserializer) DeserializeVerifier

func (d *TypedIdentityDeserializer) DeserializeVerifier(ctx context.Context, typ identity.Type, raw []byte) (driver.Verifier, error)

DeserializeVerifier deserialises raw (the inner PolicyIdentity bytes, not the full envelope) into a PolicyVerifier that evaluates the stored policy AST.

func (*TypedIdentityDeserializer) GetAuditInfo

func (d *TypedIdentityDeserializer) GetAuditInfo(ctx context.Context, id driver.Identity, typ identity.Type, rawIdentity []byte, p driver.AuditInfoProvider) ([]byte, error)

GetAuditInfo builds the composite AuditInfo for a policy identity. If audit info is already stored for id it is returned directly; otherwise it is assembled from the per-component audit infos.

func (*TypedIdentityDeserializer) GetAuditInfoMatcher

func (d *TypedIdentityDeserializer) GetAuditInfoMatcher(ctx context.Context, owner driver.Identity, auditInfo []byte) (driver.Matcher, error)

GetAuditInfoMatcher returns an InfoMatcher that checks each component identity against its own per-component audit info.

func (*TypedIdentityDeserializer) Recipients

func (d *TypedIdentityDeserializer) Recipients(id driver.Identity, typ identity.Type, raw []byte) ([]driver.Identity, error)

Recipients returns the component identities of a policy identity so that the framework can enumerate the underlying owners.

type VerifierDES

type VerifierDES interface {
	DeserializeVerifier(ctx context.Context, id driver.Identity) (driver.Verifier, error)
}

VerifierDES deserializes a single component identity into a driver.Verifier. The concrete implementation is the parent multiplex deserializer, so that policy identities containing any registered sub-type are handled correctly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL