diff options
| author | Eric Biggers <ebiggers@google.com> | 2019-12-15 19:31:39 -0800 |
|---|---|---|
| committer | Eric Biggers <ebiggers@google.com> | 2020-01-05 10:02:13 -0800 |
| commit | 462d166d5355d33a05271d24de4d52f30dd62f67 (patch) | |
| tree | 9bf53558105694002d442e0d997a9bb2b95140e2 /crypto/key.go | |
| parent | 80654f23ebfd552277ed217a2c5e1d0bb1374189 (diff) | |
Add keyring package
In preparation for introducing support for the new filesystem-level
keyrings, move the existing user keyring management code from
security/keyring.go and crypto/crypto.go into a new package, 'keyring'.
This package provides functions AddEncryptionKey, RemoveEncryptionKey,
and GetEncryptionKeyStatus which delegate to either the filesystem
keyring (added by a later patch) or to the user keyring. This provides
a common interface to both types of keyrings, to the extent possible.
Diffstat (limited to 'crypto/key.go')
| -rw-r--r-- | crypto/key.go | 56 |
1 files changed, 21 insertions, 35 deletions
diff --git a/crypto/key.go b/crypto/key.go index 52efb54..2220652 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -33,7 +33,6 @@ import ( "io" "log" "os" - "os/user" "runtime" "unsafe" @@ -41,7 +40,6 @@ import ( "golang.org/x/sys/unix" "github.com/google/fscrypt/metadata" - "github.com/google/fscrypt/security" "github.com/google/fscrypt/util" ) @@ -94,9 +92,9 @@ type Key struct { data []byte } -// newBlankKey constructs a blank key of a specified length and returns an error +// NewBlankKey constructs a blank key of a specified length and returns an error // if we are unable to allocate or lock the necessary memory. -func newBlankKey(length int) (*Key, error) { +func NewBlankKey(length int) (*Key, error) { if length == 0 { return &Key{data: nil}, nil } else if length < 0 { @@ -167,7 +165,7 @@ func (key *Key) resize(requestedSize int) (*Key, error) { } defer key.Wipe() - resizedKey, err := newBlankKey(requestedSize) + resizedKey, err := NewBlankKey(requestedSize) if err != nil { return nil, err } @@ -175,6 +173,18 @@ func (key *Key) resize(requestedSize int) (*Key, error) { return resizedKey, nil } +// Data returns a slice of the key's underlying data. Note that this may become +// outdated if the key is resized. +func (key *Key) Data() []byte { + return key.data +} + +// UnsafePtr returns an unsafe pointer to the key's underlying data. Note that +// this will only be valid as long as the key is not resized. +func (key *Key) UnsafePtr() unsafe.Pointer { + return util.Ptr(key.data) +} + // UnsafeToCString makes a copy of the string's data into a null-terminated C // string allocated by C. Note that this method is unsafe as this C copy has no // locking or wiping functionality. The key shouldn't contain any `\0` bytes. @@ -190,7 +200,7 @@ func (key *Key) UnsafeToCString() unsafe.Pointer { // ensure that this original copy is secured. func NewKeyFromCString(str unsafe.Pointer) (*Key, error) { size := C.strlen((*C.char)(str)) - key, err := newBlankKey(int(size)) + key, err := NewBlankKey(int(size)) if err != nil { return nil, err } @@ -203,7 +213,7 @@ func NewKeyFromCString(str unsafe.Pointer) (*Key, error) { func NewKeyFromReader(reader io.Reader) (*Key, error) { // Use an initial key size of a page. As Mmap allocates a page anyway, // there isn't much additional overhead from starting with a whole page. - key, err := newBlankKey(os.Getpagesize()) + key, err := NewBlankKey(os.Getpagesize()) if err != nil { return nil, err } @@ -235,7 +245,7 @@ func NewKeyFromReader(reader io.Reader) (*Key, error) { // NewFixedLengthKeyFromReader constructs a key with a specified length by // reading exactly length bytes from reader. func NewFixedLengthKeyFromReader(reader io.Reader, length int) (*Key, error) { - key, err := newBlankKey(length) + key, err := NewBlankKey(length) if err != nil { return nil, err } @@ -246,30 +256,6 @@ func NewFixedLengthKeyFromReader(reader io.Reader, length int) (*Key, error) { return key, nil } -// InsertPolicyKey puts the provided policy key into the kernel keyring with the -// provided description, and type logon. The key must be a policy key. -func InsertPolicyKey(key *Key, description string, targetUser *user.User) error { - if err := util.CheckValidLength(metadata.PolicyKeyLen, key.Len()); err != nil { - return errors.Wrap(err, "policy key") - } - - // Create our payload (containing an FscryptKey) - payload, err := newBlankKey(int(unsafe.Sizeof(unix.FscryptKey{}))) - if err != nil { - return err - } - defer payload.Wipe() - - // Cast the payload to an FscryptKey so we can initialize the fields. - fscryptKey := (*unix.FscryptKey)(util.Ptr(payload.data)) - // Mode is ignored by the kernel - fscryptKey.Mode = 0 - fscryptKey.Size = metadata.PolicyKeyLen - copy(fscryptKey.Raw[:], key.data) - - return security.InsertKey(payload.data, description, targetUser) -} - var ( // The recovery code is base32 with a dash between each block of 8 characters. encoding = base32.StdEncoding @@ -290,7 +276,7 @@ func WriteRecoveryCode(key *Key, writer io.Writer) error { } // We store the base32 encoded data (without separators) in a temp key - encodedKey, err := newBlankKey(encodedLength) + encodedKey, err := NewBlankKey(encodedLength) if err != nil { return err } @@ -318,7 +304,7 @@ func WriteRecoveryCode(key *Key, writer io.Writer) error { // be given the same level of protection as a raw cryptographic key. func ReadRecoveryCode(reader io.Reader) (*Key, error) { // We store the base32 encoded data (without separators) in a temp key - encodedKey, err := newBlankKey(encodedLength) + encodedKey, err := NewBlankKey(encodedLength) if err != nil { return nil, err } @@ -347,7 +333,7 @@ func ReadRecoveryCode(reader io.Reader) (*Key, error) { } // Now we decode the key, resizing if necessary - decodedKey, err := newBlankKey(decodedLength) + decodedKey, err := NewBlankKey(decodedLength) if err != nil { return nil, err } |