2004-09-07 18:40:37

by David Howells

[permalink] [raw]
Subject: Re: Where's the key management patchset at?


> First, I can't find the patch.
> http://people.redhat.com/~dhowells/keys/keys-268rc4mm1.diff seems to be
> a diff between two diff between two different versions of the key stuff.

My patches are currently residing in Andrew Morton's kernel, so if you grab
his 2.6.9-rc1-mm4 patch you'll find them there. Look in:

ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.9-rc1/2.6.9-rc1-mm4/

The patch includes documentation in Documentation/keys.txt.

> Second, is there a way for a process/user to have "use but not read"
> access so it could pass the key to a different _userspace_ process
> (probably a daemon running as root) that wants to read it? This would
> be nice for all kinds of things (like ssh agents and such).

That depends on what you mean by "use but not read" access.

Keys now have five permissions (View, Link, Write, Read, Search) and these can
be applied to user, group or other.

An in-kernel service just requires Search (Use) permission to be able to use a
key. It calls request_key() to come up with a key from the process's keyrings
or from userspace.

"Using" a key from userspace is tricky. We want to stop random processes from
reading your keys if they don't have Read permission, but it might be
necessary to _read_ the key to make use of it:-/

Although userspace could find a key given that that's governed by Search
permission it can't necessarily read it. I've added in a "bypass" so that if a
key is Searchable from one of a userspace process's process keyrings then it's
allowed to read it, even if it doesn't have Read permission. This allows keys
to be added through to SUID programs - you create your keyrings and your key
with Search permission and the SUID programs can then access them in
userspace.

I haven't yet created a method for one process to hand a key to another, short
of linking the key directly into one of the target process's keyrings.

I'll probably have to do it by passing a new type of SCM message over AF_UNIX
sockets - one that attaches a key and can drop it into the process's thread
keyring.

I may also need to follow up on Kyle Moffett's suggestion and make a
distinction between a key and its handle:

HANDLE KEY

+---------+
| Serial# |
| UID/GID |--------+
| Perm | |
+---------+ |
| +----------+
+---------+ | | Owner |
| Serial# | +-------->| Type |
| UID/GID |----------------->| Desc |
| Perm | +-------->| Payload |
+---------+ | | |
| +----------+
+---------+ |
| Serial# | |
| UID/GID |--------+
| Perm |
+---------+

Handles would then be clonable and individually revokable, giving the
opportunity to create handles for specific purposes, possibly even
"personalised" for specific processes rather than UID/GID. I'd then add a
"Clone" permission to the permissions mask.

The "number of keys" quota value would then count handles instead.

I've tried to implement this once before... it adds quite a bit of complexity
to the code, and makes locking interesting in places.

David


2004-09-11 04:55:55

by Andy Lutomirski

[permalink] [raw]
Subject: Re: Where's the key management patchset at?

David Howells wrote:

>>Second, is there a way for a process/user to have "use but not read"
>>access so it could pass the key to a different _userspace_ process
>>(probably a daemon running as root) that wants to read it? This would
>>be nice for all kinds of things (like ssh agents and such).
>
>
> That depends on what you mean by "use but not read" access.
>
> Keys now have five permissions (View, Link, Write, Read, Search) and these can
> be applied to user, group or other.
>
> An in-kernel service just requires Search (Use) permission to be able to use a
> key. It calls request_key() to come up with a key from the process's keyrings
> or from userspace.
>
> I'll probably have to do it by passing a new type of SCM message over
AF_UNIX
> sockets - one that attaches a key and can drop it into the process's
thread
> keyring.
>

I mean that a process would have be permitted to "use" a key (whatever
that means) but have no right to read the contents, delegating the
reading to a second process. This way a process could delegate the act
of seeing the key contents (computing a signature, for example) to a
trusted process, limiting the damage if the key-holding program is
compromised. This also might allow smart-cards to fit into the model
(where "use" makes sense but "read" is meant to be physically impossible).

Maybe one way to do this is to have a second UID attached to the key
(with its corresponding permission mask), the restriction that Read
without Search is forbidden and the exception that Search is implied by
a key's presence in a keyring. You'd also need to prevent the key owner
from changing the key's permissions if the owner doesn't have Read.

So my hypothetical ssh agent-like program has a key with UID 500: VLS /
GID whatever: - / 2nd UID 100: R and a setuid-100 program that does
public-key ops on it. Then if the user's account is compromised, no one
gets the private key.

I'm out of town now, so I haven't actually tried any of this. I'll take
a look at the code next week.

--Andy