On Sun, Sep 30, 2007 at 07:56:59AM +0200, Alon Bar-Lev wrote:
> I see you have gone a long way since I last updated [1].
> 
> I offer my help in implementing and supporting the PKCS#11 key
> module.

Great; the more hands, the merrier.

> I maintain some PKCS#11 implementation in different projects, you can view
> some of my activity at [2].

I have maintained/hacked on OpenCryptoki on and off over the last 3
years. For instance, I brought OpenCryptoki up to the v2.20 spec last
year. That does not necessarily mean that I would prefer OpenCryptoki
for this specific task, but the implementation should not matter
anyway.

> The quickest solution would be based on current OpenSSL key module
> and my pkcs11-helper library [3], as it already support PKCS#11 and
> OpenSSL engine, the only issue is that the RSA_PKCS1_OAEP_PADDING is
> not supported by most PKCS#11 implementation, so RSA_PKCS1_PADDING
> should be used.

The whole point of having an API spec that it should not matter what
implementation we use. I would want to make sure that we could drop in
pkcs11-helper+OpenSSL, OpenCryptoki, or OpenSC interchangeably, and
the PKCS#11 key module would function just the same.

> I can also drop OpenSSL usage to an extent of the ability to extract
> e, n from X.509 certificate and calculate hash int
> *generate_signature().
> 
> Do you prefer one over the other?

I would prefer the more general solution of being able to work with a
PKCS#11 interface.

> Also I don't really understand the *generate_key() and its relevance
> to key module, I don't think this should be implemented for PKCS#11,
> as there utilities to do exactly that.

generate_key() is no longer really a call in the API, and any key
generation functions are an optional feature for any given key
module. For instance, take a look at
ecryptfs-utils-23/src/key_mod/ecryptfs_key_mod_tspi.c; that module
just sets the key gen function pointers to NULL.

> Unlike file based cryptography, smartcard based cryptography is
> dynamic, smartcard can be removed and inserted at any time. From
> what I understand from quick review of the source, the key module is
> doing private key decryption when a file is opened.  If this is so,
> what happens when the smartcard is not available or PKCS#11 session
> disconnects or expires? Do we fail the system call? prompt the user?

Keys are not strictly "file"-based, in the sense that two hard links
to the same inode can have two different keys. Keys are really
inode-based. Once eCryptfs has extracted
(decrypted/unsealed/unwrapped/whatever) the File Encryption Key, it is
in the eCryptfs inode's crypt_stat->key[] byte array in memory, where
it remains until the inode is destroyed
(fs/ecryptfs/super.c::ecryptfs_destroy_inode() ->
fs/ecryptfs/crypto.c::ecryptfs_destroy_crypt_stat()). Inodes are
destroyed at the discretion of the kernel VFS; preconditions that must
be met include having no process with a claim on any region of the
inode's address space (via mmap's and what not). There is no mechanism
in the kernel for forcing a revocation of mmap's over regions of the
address space on any given event, so I think it makes the most sense
to allow these categories of reads and writes to continue as usual
even after the removal of the token.

I do not think we really want to go down the path of removing the
ECRYPTFS_KEY_VALID flag and wiping the key[] octets directly on
crypt_stat's that happen to get a revoked key_sig in its keysig_list
since FEK's can be protected with multiple FEKEK's; things get
semantically hairy. For instance, if a file is protected by both a
smartcard *and* a passphrase, and if I lose the smartcard, then I want
the fallback to the passphrase to be seamless. Right now, that only
happens when you open the file again in the future, but the case of
already mapped memory regions will be problematic. The attempt to use
the FEK on the fs/ecryptfs/mmap.c::ecryptfs_readpage()/writepage()
paths will fail *for pages that happen to not be uptodate on read*,
and the only way to make sure that we can't fall back on another FEKEK
would be to re-run fs/ecryptfs/crypto.c::ecryptfs_read_metadata() on
the persistent lower file (and this wasn't even a possibility a few
weeks ago before I completed the persistent lower file patch
set). Then the PageUptodate status suddenly becomes visible to the
task holding an mmap (uptodate pages will still be read just fine even
if there is no longer any valid key; only pages that are not uptodate
that get ecryptfs_readpage() called on them would get an EIO on read
attempts). That would be bad. eCryptfs might be able to carpet-bomb
the entire address space's uptodate status on key revocation, but I
really do not know whether this is feasible under all circumstances
(or *any* circumstances, for that matter).

So there is no easy answer about exactly what to do *with existing
inodes* when a token is no longer available; I am leaning toward just
letting existing file accesses continue until the inode gets released
by the VFS in its natural due course. When it comes to *new* inodes,
the answer is easy: just have the key module in userspace figure it
out when it gets the decrypt request packet from the kernel. It can
prompt the user, or it can just return an error code, and the syscall
will wind up returning an -EIO if it can't find any other FEKEK to use
for the inode.

> How we notify the user that he is unable to access files because he
> needs to insert his XXXX smartcard, or re-type his passphrase? Where
> does the user re-type his passphrase?

You are in the userspace key module at this point. We can do whatever
we want. ecryptfsd can have a handle to the X server, which is used to
get a dialog box on the screen (I actually did that for my OLS demo in
'04). Or the key module might be able to talk to something in the
window manager (for those running GNOME/KDE). I don't think it's a
good idea to try to butt in with a prompt for users on terminal
sessions, so it would just fail at that point if ecryptfsd doesn't
have a handle to the X server. When it comes to interactive prompting
of the user in the midst of syscalls, there is really no solution that
I am particularly thrilled with.

> Usually smartcard enabled applications have the following user
> prompts:
> 
> a. Token prompt (Please insert token XXXX).
> b. Passphrase prompt (Please type passphrase for token XXXX)
> 
> Both of these can be called at anytime during session in blocking
> mode, so that the system call may proceed. For these we need to have
> some mechanism for user interaction, I hope this is what the daemon
> is all about. But in order to interact with user desktop we should
> also register DISPLAY variable or something with the mount command.

Right; it seems you already have the idea.

> What do you think? Have I gotten this right?
> Are you interested in my help?

At the moment, a PKCS#11 key module is beneath several other work
items in my queue, so if you have the desire to implement it, I would
welcome your contributions. Please let me know what you think of the
current key module API
(ecryptfs-utils-23/src/include/ecryptfs.h::ecryptfs_key_mod_ops). 

Thanks,
Mike

Attachment: signature.asc
Description: Digital signature

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
eCryptfs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ecryptfs-devel

Reply via email to