From 95fa96f1a8fd3faaa71001a41efb55dd7dbe701b Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Mon, 9 Jan 2023 17:56:32 -0800 Subject: [PATCH] add support for KEYCTL_MOVE --- keyring.go | 8 +++++++ keyring_test.go | 35 +++++++++++++++++++++++++++++ sys_linux.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/keyring.go b/keyring.go index 6761087..a71e4f6 100644 --- a/keyring.go +++ b/keyring.go @@ -197,3 +197,11 @@ func Unlink(parent Keyring, child Id) error { func UnlinkKeyring(kr NamedKeyring) error { return keyctl_Unlink(keyId(kr.Id()), kr.(*namedKeyring).parent) } + +func Move(source Keyring, dest Keyring, child Id, excl bool) error { + var flags uint + if excl { + flags = keyctlMoveExcl + } + return keyctl_Move(keyId(child.Id()), keyId(source.Id()), keyId(dest.Id()), flags) +} diff --git a/keyring_test.go b/keyring_test.go index a78d43c..2f33721 100644 --- a/keyring_test.go +++ b/keyring_test.go @@ -170,3 +170,38 @@ func TestUnlinkKeyring(t *testing.T) { t.Logf("unlinked keyring %v [%s]", nring.Id(), nring.Name()) } + +func TestMoveKey(t *testing.T) { + ring, err := SessionKeyring() + if err != nil { + t.Fatal(err) + } + + nring, err := CreateKeyring(ring, "testring") + if err != nil { + t.Fatal(err) + } + t.Logf("created keyring %v named %q", nring.Id(), nring.Name()) + defer UnlinkKeyring(nring) + + key, err := ring.Add("move-test", []byte("test")) + if err != nil { + t.Fatal(err) + } + t.Logf("added test key as: %v\n", key.Id()) + defer key.Unlink() + + err = Move(ring, nring, key, false) + if err != nil { + t.Fatal(err) + } + + movedKey, err := nring.Search("move-test") + if err != nil { + t.Fatal(err) + } + t.Logf("found key in keyring: %v\n", movedKey.Id()) + if movedKey.Id() != key.Id() { + t.Fatal("IDs don't match\n") + } +} diff --git a/sys_linux.go b/sys_linux.go index 0c4c194..6c6bc2c 100644 --- a/sys_linux.go +++ b/sys_linux.go @@ -19,6 +19,10 @@ const ( keySpecReqKeyAuthKey keyId = -7 ) +const ( + keyctlMoveExcl uint = 1 +) + const ( keyctlGetKeyringId keyctlCommand = iota keyctlJoinSessionKeyring @@ -37,6 +41,22 @@ const ( keyctlSetReqKeyKeyring keyctlSetTimeout keyctlAssumeAuthority + keyctlGetSecurity + keyctlSessionToParent + keyctlReject + keyctlInstantiateIov + keyctlInvalidate + keyctlGetPersistent + keyctlDhCompute + keyctlPkeyQuery + keyctlPkeyEncrypt + keyctlPkeyDecrypt + keyctlPkeySign + keyctlPkeyVerify + keyctlRestrictKeyring + keyctlMove + keyctlCapabilities + keyctlWatchKey ) var debugSyscalls bool @@ -81,6 +101,38 @@ func (cmd keyctlCommand) String() string { return "keyctlSetTimeout" case keyctlAssumeAuthority: return "keyctlAssumeAuthority" + case keyctlGetSecurity: + return "keyctlGetSecurity" + case keyctlSessionToParent: + return "keyctlSessionToParent" + case keyctlReject: + return "keyctlReject" + case keyctlInstantiateIov: + return "keyctlInstantiateIov" + case keyctlInvalidate: + return "keyctlInvalidate" + case keyctlGetPersistent: + return "keyctlGetPersistent" + case keyctlDhCompute: + return "keyctlDhCompute" + case keyctlPkeyQuery: + return "keyctlPkeyQuery" + case keyctlPkeyEncrypt: + return "keyctlPkeyEncrypt" + case keyctlPkeyDecrypt: + return "keyctlPkeyDecrypt" + case keyctlPkeySign: + return "keyctlPkeySign" + case keyctlPkeyVerify: + return "keyctlPkeyVerify" + case keyctlRestrictKeyring: + return "keyctlRestrictKeyring" + case keyctlMove: + return "keyctlMove" + case keyctlCapabilities: + return "keyctlCapabilities" + case keyctlWatchKey: + return "keyctlWatchKey" } panic("bad arg") } @@ -294,3 +346,11 @@ func updateKey(id keyId, payload []byte) error { } return nil } + +func keyctl_Move(id, from_ring keyId, to_ring keyId, flags uint) error { + _, _, errno := syscall.Syscall6(syscall_keyctl, uintptr(keyctlMove), uintptr(id), uintptr(from_ring), uintptr(to_ring), uintptr(flags), 0) + if errno != 0 { + return errno + } + return nil +}