$Id: key-management.txt,v 1.1.1.1 2008/09/10 09:32:57 agcrooks Exp $

Key management in BPG - BSD Privacy Guard
=========================================

1. Introduction
---------------

Key management divides up into several different parts:

    * Interpreting the key format--basically, being able to read
    OpenPGP packets containing keys. Covered by sections 4 and 5 of
    RFC 2440.

    * Specifying from where we should try to fetch keys, and how we
    should fetch them. Examples:
	- Use a keyring in a given format, in some sort of default
	place (such as defined by the GNUPGHOME environment variable).
	- Read OpenPGP packets from an arbitrary file
	- Fetch the key from a keyserver, using a given protocol

    * Specifying how we search for keys, and what to do when the
    search does not produce an unambiguous result. E.g.,
        - specify a specific key ID, using that key if only one match
	is found, or offering the user a choice if more than one match
	is found
	- specify a substring to match within a UserID, and use all
	top-level keys that have a matching UserID.

    * Specifying how we determine our level of trust in a selected
    key, what minimum level of trust we require to use the key for the
    given purpose, and and what to do if we cannot achieve that level
    of trust (warn? fail?).

We'll separate this tasks into several submodules. We'll try to make
the things "pluggable," so that code to parse PGP packets and
construct the key information doesn't need to know if the key itself
came from a file, a keyring or a key server.


2. Submodules
-------------

2.1. Key fetcher

It receives petitions for obtaining a key given an ID. Then it uses
the other modules to take a decission and return the requested key.


2.2. Key generator

This module receives petitions for generating asymmetric and symmetric
keys. For symmetric keys the work is pretty simple: it only expands a
given password. For asymmetric keys there are more elements that come
to scene (read 3.2).


2.3. Key importer/exporter

This module receives petitions from the user to take a key from a
location A and insert it into location B, where A and B can be files,
keyrings or key servers.


2.4. Key interpreter

Reads/writes OpenPGP packets containing keys and translates them
into/from the internal data structures.


2.5. Key deliverer

With no public functions, this module performs the internal checkouts
and commits of keys from and to a file, keyring or key server.


3. Internal working
-------------------

3.1. Fetching

* The user asks the key fetcher for a key, passing the user ID, the
  sources to search it (by default, the user keyring) and the minimum
  accepted level of trust (by default, [FILL THIS]).

* The key fetcher asks the key deliverer to find keys with the given
  user ID and in the given sources.

* The key deliverer returns the keys found in a buffer or temporary
  file, and the number of keys found.

* If the number of keys found is zero, the fetcher ends this operation
  returning a "key not found" error value to the user.

* The key fetcher asks the trust library to determine the trust level
  of found key.

* The key fetcher selects the most trusted key. If there are more than
  one in the highest obtained level, [FILL THIS].

* The key fetcher asks the key interpreter to fill the in-memory data
  structure of the key.

* If interpreter returns a "key locked" error state, ask the user for
  the passphrase [HOW?]. Then repeat the call to the key interpreter.

* The key fetcher returns the key in its data structure, ready to be
  used with other BPG modules.


3.2. Generation (asymmetric keys)

* The user asks the key generator to create a new key pair, passing
  the algorithm, the size and the location where the key will be
  stored.

* The key generator asks the BPG algorithms library to generate a key
  pair passing the algorithm and the size.

* The key generator fills the in-memory key data structure with the
  new data.

* The key generator encrypts the private key by asking the user for a
  passphrase [HOW?].

* The key generator asks the key interpreter to translate the
  in-memory key to a string suitable for being stored.

* The key generator asks the key deliverer to store the new key in the
  given location.

* The key generator returns the error state (ok / location not found /
  unknown algorithm / invalid size / ...).


3.3. Generation (symmetric keys)

* The user asks the key generator to create a new key, passing the
  size of the key and a flag that determines if the key is
  password-dependent (user-defined keys vs session keys).

* If the key is password-dependent, the key generator asks the user
  for a password [HOW?].

* If the key is not password-dependent, the key generator creates a
  random session key [HOW? INCLUDE A RANDOM GENERATOR IN THE
  ALGORITHMS LIBRARY?]

* The key generator expands the key.

* The key generator returns the key and an error state.


3.4. Importing

* The user asks the key importer/exporter to import the key with ID
  'x', from location A, and store it location B (by default the user
  keyring).

* It asks the key deliverer to take the key out of the source
  location.

* It asks the key deliverer to insert the key into the destination.

* The key importer/exporter returns an error state (ok / key not found
  / ambiguous ID / source location not found / destination not found /
  ...).


3.5. Exporting

* The user asks the key importer/exporter to export the key with ID
  'y', from location C (by default, the user keyring), and store it
  location D.

* It asks the key deliverer to take the key out of the source
  location.

* It asks the key deliverer to insert the key into the destination.

* The key importer/exporter returns an error state (ok / key not found
  / ambiguous ID / source location not found / destination not found /
  ...).


4. Key storage
--------------

[How will the keys be stored in the system.]

All the BPG configuration will be placed in the .bpg directory in the
home directory of the user. So, user keyrings and trust databases will
be stored in this directory.


4.1. Keyrings

A keyring is an entity that contains keys.

In BPG, a keyring is a directory that contains a list of files,
containing one key each [MORE EXPERIENCED REVISORS, PLEASE TELL ME IF
THIS IS A GOOD THING].

Public and private keys are separated in public an private keyrings.

For example, Alice has three keyrings:

* ~/.bpg/keyrings/private/alice, for her private keys.
* ~/.bpg/keyrings/public/alice, for her public keys.
* ~/.bpg/keyrings/public/world, for alt public keys.

[ANOTHER OPTION IS HAVING ONLY TWO KEYRINGS, ONE FOR PRIVATE KEYS AND
ANOTHER FOR PUBLIC KEYS, LIKE GPG DOES. IS THERE ANY ADVANTADGE IN
ALLOWING MULTIPLE KEYRINGS?.]

Then, inside each keyring directory, there will be a bunch of files,
named each with the key ID. The name thing just for having a uniform
nomenclature, the program must read all the files in the keyring
directory (if two keys have the same key ID, which can happen
according to OpenPGP, BPG will consider both with no problem, just add
a "[2]" or something like that to the key filename).

For adding new keys to the keyring we must use the "import" function
of the key management library (via the command-line interface or
whatever). If the user is more confortable copying the key files
directly to the keyring, it's ok.

Finally, the private keyrings will have one difference from public
ones, and it's that private keys are symmetrically encrypted with a
passphrase that the user must enter once he/she wants to use the key.


4.2. Keys

Each key inside a keyring is a public or private key packet as defined
in OpenPGP.

The keys can be signed.


5. Trust model
--------------

How much we trust a key is resolved by asking how much we trust the
person who signed that key.

BPG implements trust via the BPG trust library. That library defines
the policy of the trust system. The trust library interacts with the
trust database, which contains how much a user trusts another.


5.1. Trust database

Trust of the system is stored in the trust database, placed in
.bpg/trustdb.

This database contains a pair of values, userID - trust level. [WOULD
IT BE BETTER TO MAKE THE DATABASE MULTI-USER AND HAVE THREE VALUES PER
ROW: SOURCE USER, DESTINATION USER, TRUST LEVEL?]

The trust database must be signed by the user that trusts it. This
signature will be verified by the trust library each time the database
is accesed. The signer's user ID will always be trusted with level
"ultimate".

TrustDB example:

Dst		Level
---		-----
alice@foo.com	high
alice@bar.com	high
bob@yuhuu.com	low


5.2. Policy

The trust database only stores how much we trust in somebody. But what
does this means? How do we define how much we trust *a key* from this
information?

For this BPG implements the trust policy.

The trust policy is a set of rules that defines the trust level of a
key depending on how much we trust its signer.

Policies are interchangeable. By default, BPG uses the OpenPGP web of
trust policy (i.e. if we trust bob@foo.com and we have a key signed by
bob@foo.com, we trust that key). Other policies can be implemented in
the future, as the X.509 hierarchical trust model.


5.3. A trust query

* The user calls the trust library for obtaining the level of trust in
  the key 0x389A2E82 from bob@foo.com, which is placed on our keyring
  and signed by trend@trust.com.

* The trust library checks the signature of the trust database.

* The trust library queries the trust database on how much we trust
  trend@trust.com.

* The trust library processes the response with the trust policy (in
  this case, OpenPGP policy).

* The trust library returns to the user the final level of trust for
  that key.
