aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Richey joerichey@google.com <joerichey@google.com>2017-06-08 10:51:04 -0700
committerJoe Richey joerichey@google.com <joerichey@google.com>2017-06-15 22:32:35 -0700
commitea3e258610340de0dd585c221f4e18a199f16bca (patch)
tree6619b0564b988803346d09e211ea400d02b3161d
parentd5f89f8fcc5172be183fb02b802fa23ed3e9f8fa (diff)
crypto: add in additional keyring functionality
This commit adds in the FindPolicyKey and RemovePolicyKey functions to complement the InsertPolicyKey function. The existing functions were also refactored slightly. Change-Id: Iabd275f2186a9e3023d5efd44c772966123e3657
-rw-r--r--crypto/crypto.go2
-rw-r--r--crypto/crypto_test.go10
-rw-r--r--crypto/key.go45
3 files changed, 49 insertions, 8 deletions
diff --git a/crypto/crypto.go b/crypto/crypto.go
index a226f26..c6d6619 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -63,6 +63,8 @@ var (
ErrKeyFree = util.SystemError("could not free memory of key")
ErrKeyringLocate = util.SystemError("could not locate the session keyring")
ErrKeyringInsert = util.SystemError("could not insert key into the session keyring")
+ ErrKeyringSearch = util.SystemError("could not find key in the session keyring")
+ ErrKeyringDelete = util.SystemError("could not delete key from the session keyring")
ErrRecoveryCode = errors.New("provided recovery code had incorrect format")
ErrLowEntropy = util.SystemError("insufficient entropy in pool to generate random bytes")
ErrRandNotSupported = util.SystemError("getrandom() not implemented; kernel must be v3.17 or later")
diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go
index 674baeb..2141fb8 100644
--- a/crypto/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -234,24 +234,30 @@ func TestKeyLargeResize(t *testing.T) {
}
}
-// Adds a key with and without legacy (check keyctl to see the key identifiers).
-func TestAddKeys(t *testing.T) {
+// Adds and removes a key with various services.
+func TestAddRemoveKeys(t *testing.T) {
for _, service := range []string{ServiceDefault, ServiceExt4, ServiceF2FS} {
if err := InsertPolicyKey(fakeValidPolicyKey, fakeValidDescriptor, service); err != nil {
t.Error(err)
}
+ if err := RemovePolicyKey(fakeValidDescriptor, service); err != nil {
+ t.Error(err)
+ }
}
}
// Makes sure a key fails with bad descriptor, policy, or service
func TestBadAddKeys(t *testing.T) {
if InsertPolicyKey(fakeInvalidPolicyKey, fakeValidDescriptor, ServiceDefault) == nil {
+ RemovePolicyKey(fakeValidDescriptor, ServiceDefault)
t.Error("InsertPolicyKey should fail with bad policy key")
}
if InsertPolicyKey(fakeValidPolicyKey, fakeInvalidDescriptor, ServiceDefault) == nil {
+ RemovePolicyKey(fakeInvalidDescriptor, ServiceDefault)
t.Error("InsertPolicyKey should fail with bad descriptor")
}
if InsertPolicyKey(fakeValidPolicyKey, fakeValidDescriptor, "ext4") == nil {
+ RemovePolicyKey(fakeValidDescriptor, "ext4")
t.Error("InsertPolicyKey should fail with bad service")
}
}
diff --git a/crypto/key.go b/crypto/key.go
index bc5ec0f..eefe08a 100644
--- a/crypto/key.go
+++ b/crypto/key.go
@@ -45,6 +45,8 @@ const (
ServiceExt4 = "ext4:"
// ServiceExt4 was used before v4.6 for F2FS filesystem encryption.
ServiceF2FS = "f2fs:"
+ // keyType is always logon as required by filesystem encryption
+ keyType = "logon"
)
/*
@@ -237,24 +239,55 @@ func addPayloadToSessionKeyring(payload []byte, description string) error {
// of the KEY_SPEC_SESSION_KEYRING, which will return the user session
// keyring if a session keyring does not exist.
keyringID, err := unix.KeyctlGetKeyringID(unix.KEY_SPEC_SESSION_KEYRING, 0)
+ log.Printf("unix.KeyctlGetKeyringID(KEY_SPEC_SESSION_KEYRING) = %d, %v", keyringID, err)
if err != nil {
- log.Printf("unix.KeyctlGetKeyringID failed: %v", err)
- log.Print("could not get keyring ID of KEY_SPEC_SESSION_KEYRING")
return ErrKeyringLocate
}
- if _, err = unix.AddKey("logon", description, payload, keyringID); err != nil {
- log.Printf("unix.AddKey failed: %v", err)
- log.Printf("could not insert %q into keyring (ID = %d)", description, keyringID)
+ keyID, err := unix.AddKey(keyType, description, payload, keyringID)
+ log.Printf("unix.AddKey(%s, %s, <payload>, %d) = %d, %v",
+ keyType, description, keyringID, keyID, err)
+ if err != nil {
return ErrKeyringInsert
}
return nil
}
+// FindPolicyKey tries to locate a policy key in the kernel keyring with the
+// provided descriptor and service. The key id is returned if we can find the
+// key. An error is returned if the key does not exist.
+func FindPolicyKey(descriptor, service string) (int, error) {
+ description := service + descriptor
+ keyID, err := unix.KeyctlSearch(unix.KEY_SPEC_SESSION_KEYRING, keyType, description, 0)
+ log.Printf("unix.KeyctlSearch(KEY_SPEC_SESSION_KEYRING, %s, %s, 0) = %d, %v",
+ keyType, description, keyID, err)
+ if err != nil {
+ return 0, ErrKeyringSearch
+ }
+ return keyID, nil
+}
+
+// RemovePolicyKey tries to remove a policy key from the kernel keyring with the
+// provided descriptor and service. An error is returned if the key does not
+// exist.
+func RemovePolicyKey(descriptor, service string) error {
+ keyID, err := FindPolicyKey(descriptor, service)
+ if err != nil {
+ return err
+ }
+
+ err = unix.KeyctlUnlink(keyID, unix.KEY_SPEC_SESSION_KEYRING)
+ log.Printf("unix.KeyctlUnlink(%d, KEY_SPEC_SESSION_KEYRING) = %v", keyID, err)
+ if err != nil {
+ return ErrKeyringDelete
+ }
+ return nil
+}
+
// InsertPolicyKey puts the provided policy key into the kernel keyring with the
// provided descriptor, provided service prefix, and type logon. The key and
// descriptor must have the appropriate lengths.
-func InsertPolicyKey(key *Key, descriptor string, service string) error {
+func InsertPolicyKey(key *Key, descriptor, service string) error {
if key.Len() != metadata.PolicyKeyLen {
return util.InvalidLengthError("Policy Key", metadata.PolicyKeyLen, key.Len())
}