aboutsummaryrefslogtreecommitdiff
path: root/metadata/checks.go
diff options
context:
space:
mode:
Diffstat (limited to 'metadata/checks.go')
-rw-r--r--metadata/checks.go193
1 files changed, 96 insertions, 97 deletions
diff --git a/metadata/checks.go b/metadata/checks.go
index 5d0ce59..074d79e 100644
--- a/metadata/checks.go
+++ b/metadata/checks.go
@@ -20,178 +20,177 @@
package metadata
import (
- "log"
-
"github.com/golang/protobuf/proto"
+ "github.com/pkg/errors"
"fscrypt/util"
)
+var errNotInitialized = errors.New("not initialized")
+
// Metadata is the interface to all of the protobuf structures that can be
-// checked with the IsValid method.
+// checked for validity.
type Metadata interface {
- IsValid() bool
+ CheckValidity() error
proto.Message
}
-// checkValidLength returns true if expected == actual, otherwise it logs an
-// InvalidLengthError.
-func checkValidLength(name string, expected int, actual int) bool {
- if expected != actual {
- log.Print(util.InvalidLengthError(name, expected, actual))
- return false
+// CheckValidity ensures the mode has a name and isn't empty.
+func (m EncryptionOptions_Mode) CheckValidity() error {
+ if m == EncryptionOptions_default {
+ return errNotInitialized
}
- return true
-}
-
-// IsValid ensures the mode has a name and isn't empty.
-func (m EncryptionOptions_Mode) IsValid() bool {
if m.String() == "" {
- log.Print("Encryption mode cannot be the empty string")
- return false
- }
- if m == EncryptionOptions_default {
- log.Print("Encryption mode must be set to a non-default value")
- return false
+ return errors.Errorf("unknown %d", m)
}
- return true
+ return nil
}
-// IsValid ensures the source has a name and isn't empty.
-func (s SourceType) IsValid() bool {
- if s.String() == "" {
- log.Print("SourceType cannot be the empty string")
- return false
- }
+// CheckValidity ensures the source has a name and isn't empty.
+func (s SourceType) CheckValidity() error {
if s == SourceType_default {
- log.Print("SourceType must be set to a non-default value")
- return false
+ return errNotInitialized
+ }
+ if s.String() == "" {
+ return errors.Errorf("unknown %d", s)
}
- return true
+ return nil
}
-// IsValid ensures the hash costs will be accepted by Argon2.
-func (h *HashingCosts) IsValid() bool {
+// CheckValidity ensures the hash costs will be accepted by Argon2.
+func (h *HashingCosts) CheckValidity() error {
if h == nil {
- log.Print("HashingCosts not initialized")
- return false
+ return errNotInitialized
}
- if h.Time == 0 {
- log.Print("Hashing time cost not initialized")
- return false
+ if h.Time <= 0 {
+ return errors.Errorf("time=%d is not positive", h.Time)
}
- if h.Parallelism == 0 {
- log.Print("Hashing parallelism cost not initialized")
- return false
+ if h.Parallelism <= 0 {
+ return errors.Errorf("parallelism=%d is not positive", h.Parallelism)
}
minMemory := 8 * h.Parallelism
if h.Memory < minMemory {
- log.Printf("Hashing memory cost must be at least %d", minMemory)
- return false
+ return errors.Errorf("memory=%d is less than minimum (%d)", h.Memory, minMemory)
}
- return true
+ return nil
}
-// IsValid ensures our buffers are the correct length (or just exist).
-func (w *WrappedKeyData) IsValid() bool {
+// CheckValidity ensures our buffers are the correct length.
+func (w *WrappedKeyData) CheckValidity() error {
if w == nil {
- log.Print("WrappedKeyData not initialized")
- return false
+ return errNotInitialized
}
if len(w.EncryptedKey) == 0 {
- log.Print("EncryptedKey not initialized")
- return false
+ return errors.Wrap(errNotInitialized, "encrypted key")
+ }
+ if err := util.CheckValidLength(IVLen, len(w.IV)); err != nil {
+ return errors.Wrap(err, "IV")
}
- return checkValidLength("IV", IVLen, len(w.IV)) &&
- checkValidLength("HMAC", HMACLen, len(w.Hmac))
+ return errors.Wrap(util.CheckValidLength(HMACLen, len(w.Hmac)), "HMAC")
}
-// IsValid ensures our ProtectorData has the correct fields for its source.
-func (p *ProtectorData) IsValid() bool {
+// CheckValidity ensures our ProtectorData has the correct fields for its source.
+func (p *ProtectorData) CheckValidity() error {
if p == nil {
- log.Print("ProtectorData not initialized")
- return false
+ return errNotInitialized
+ }
+
+ if err := p.Source.CheckValidity(); err != nil {
+ return errors.Wrap(err, "protector source")
}
// Source specific checks
switch p.Source {
case SourceType_pam_passphrase:
if p.Uid < 0 {
- log.Print("The UID should never be negative")
- return false
+ return errors.Errorf("UID=%d is negative", p.Uid)
}
fallthrough
case SourceType_custom_passphrase:
- if !p.Costs.IsValid() || !checkValidLength("Salt", SaltLen, len(p.Salt)) {
- return false
+ if err := p.Costs.CheckValidity(); err != nil {
+ return errors.Wrap(err, "passphrase hashing costs")
+ }
+ if err := util.CheckValidLength(SaltLen, len(p.Salt)); err != nil {
+ return errors.Wrap(err, "passphrase hashing salt")
}
}
// Generic checks
- return p.Source.IsValid() &&
- p.WrappedKey.IsValid() &&
- checkValidLength("EncryptedKey", InternalKeyLen, len(p.WrappedKey.EncryptedKey)) &&
- checkValidLength("ProtectorDescriptor", DescriptorLen, len(p.ProtectorDescriptor))
+ if err := p.WrappedKey.CheckValidity(); err != nil {
+ return errors.Wrap(err, "wrapped protector key")
+ }
+ if err := util.CheckValidLength(DescriptorLen, len(p.ProtectorDescriptor)); err != nil {
+ return errors.Wrap(err, "protector descriptor")
+ }
+ err := util.CheckValidLength(InternalKeyLen, len(p.WrappedKey.EncryptedKey))
+ return errors.Wrap(err, "encrypted protector key")
}
-// IsValid ensures each of the options is valid.
-func (e *EncryptionOptions) IsValid() bool {
+// CheckValidity ensures each of the options is valid.
+func (e *EncryptionOptions) CheckValidity() error {
if e == nil {
- log.Print("EncryptionOptions not initialized")
- return false
+ return errNotInitialized
}
if _, ok := util.Index(e.Padding, paddingArray); !ok {
- log.Printf("Padding of %d is invalid", e.Padding)
- return false
+ return errors.Errorf("padding of %d is invalid", e.Padding)
}
-
- return e.Contents.IsValid() && e.Filenames.IsValid()
+ if err := e.Contents.CheckValidity(); err != nil {
+ return errors.Wrap(err, "contents encryption mode")
+ }
+ return errors.Wrap(e.Filenames.CheckValidity(), "filenames encryption mode")
}
-// IsValid ensures the fields are valid and have the correct lengths.
-func (w *WrappedPolicyKey) IsValid() bool {
+// CheckValidity ensures the fields are valid and have the correct lengths.
+func (w *WrappedPolicyKey) CheckValidity() error {
if w == nil {
- log.Print("WrappedPolicyKey not initialized")
- return false
+ return errNotInitialized
}
- return w.WrappedKey.IsValid() &&
- checkValidLength("EncryptedKey", PolicyKeyLen, len(w.WrappedKey.EncryptedKey)) &&
- checkValidLength("ProtectorDescriptor", DescriptorLen, len(w.ProtectorDescriptor))
+ if err := w.WrappedKey.CheckValidity(); err != nil {
+ return errors.Wrap(err, "wrapped key")
+ }
+ if err := util.CheckValidLength(PolicyKeyLen, len(w.WrappedKey.EncryptedKey)); err != nil {
+ return errors.Wrap(err, "encrypted key")
+ }
+ err := util.CheckValidLength(DescriptorLen, len(w.ProtectorDescriptor))
+ return errors.Wrap(err, "wrapping protector descriptor")
}
-// IsValid ensures the fields and each wrapped key are valid.
-func (p *PolicyData) IsValid() bool {
+// CheckValidity ensures the fields and each wrapped key are valid.
+func (p *PolicyData) CheckValidity() error {
if p == nil {
- log.Print("PolicyData not initialized")
- return false
+ return errNotInitialized
}
// Check each wrapped key
- for _, w := range p.WrappedPolicyKeys {
- if !w.IsValid() {
- return false
+ for i, w := range p.WrappedPolicyKeys {
+ if err := w.CheckValidity(); err != nil {
+ return errors.Wrapf(err, "policy key slot %d", i)
}
}
- return p.Options.IsValid() &&
- checkValidLength("KeyDescriptor", DescriptorLen, len(p.KeyDescriptor))
+ if err := util.CheckValidLength(DescriptorLen, len(p.KeyDescriptor)); err != nil {
+ return errors.Wrap(err, "policy key descriptor")
+ }
+
+ return errors.Wrap(p.Options.CheckValidity(), "policy options")
}
-// IsValid ensures the Config has all the necessary info for its Source.
-func (c *Config) IsValid() bool {
+// CheckValidity ensures the Config has all the necessary info for its Source.
+func (c *Config) CheckValidity() error {
// General checks
if c == nil {
- log.Print("Config not initialized")
- return false
+ return errNotInitialized
}
- if !c.Source.IsValid() || !c.Options.IsValid() {
- return false
+ if err := c.Source.CheckValidity(); err != nil {
+ return errors.Wrap(err, "default config source")
}
// Source specific checks
switch c.Source {
case SourceType_pam_passphrase, SourceType_custom_passphrase:
- return c.HashCosts.IsValid()
- default:
- return true
+ if err := c.HashCosts.CheckValidity(); err != nil {
+ return errors.Wrap(err, "config hashing costs")
+ }
}
+
+ return errors.Wrap(c.Options.CheckValidity(), "config options")
}