$Id: use-cases.txt,v 1.16 2005/07/28 16:45:06 droggo Exp $ Use cases document - BSD Privacy Guard ====================================== This is an attempt to sketch out some of the use cases for PGP encryption, along with interface ideas and notes about problems with other programs. 1. OpenPGP message processing use cases ======================================= ---------------------------------------- Hybrid encryption ---------------------------------------- BPG must be able to encrypt and decrypt data with both symmetric and asymmetric algorithms, using enveloping as defined in OpenPGP. The public asymmetric key must be previously imported (key servers, or direct import). When a user wants to encrypt data: 1. Chooses a key via the key management library: * If the key is a signing key, the library searchs for the encryption key attached to it. * The library checks if the key has expired. * The key management library checks the trust of that key with the trust library (with searches in the trust database, which can be local or remote). * The library returns: a) An error state (ok / key not found / key expired / ambiguous ID ...). b) Trust level. c) The key if the error state was "ok". 2. Selects cryptographic algorithms to be used (asymmetric and symmetric). If this step is skipped, the default algorithms will be used. 3. Selects compression method (algorithm and compression level). If this step is skipped, the default method will be used. 4. Selects armoring flag (whether to perform radix-64 conversion or not). If this step is skipped, the output will be armored. 5. Calls data securizing library to perform the encryption, passing as arguments the key and the symmetric and asymmetric algorithms that must be used. The encrypted PGP data is returned. ---------------------------------------- Symmetric-only encryption ---------------------------------------- BPG will also support symmetric-only encryption. This is performed by symmetrically encrypting the session key (instead of asymmetrically as usual). When a user wants to encrypt data with symmetric-only encryption: 1. Asks the key management library to get the key. This library asks the user for the password that generate the key. 2. Selects symmetric algorithm to be used. If this step is skipped, the default algorithm will be used. 3. Selects the compression method (algorithm and compression level). If this step is skipped, the default method will be used. 4. Selects armoring flag (whether to perform radix-64 conversion or not). If this step is skipped, the output will be armored. 5. Calls data securizing library to perform the encryption, passing as arguments the key and the symmetric algorithm to be used. The encrypted PGP data is returned. ---------------------------------------- Decryption ---------------------------------------- When a user wants to decrypt data: 1. Calls data securizing library to perform the decryption. * The library dearmors data if necessary. * If it's not a symmetric-only package, the library locates in the PGP info of the data the key ID, algorithms and compression method used in the encryption. * If it's not a symmetric-only package, the library asks the key management library for the key, who asks the user for the passphrase to unlock the private key. * If it's a symmetric-only package, the library asks the key management library to obtain the passphrase from the user. * The library performs the decryption of the data. * It returns: a) An error state (ok / key not found / key expired / unknown algorithms / malformed PGP message / PGP data not found / ...). b) Decrypted data if error state was "ok". ---------------------------------------- Digital signing ---------------------------------------- BPG must be able to make digital signatures of data with private keys. The user selects the key to use (or use the default one), and BPG asks for the passphrase to unlock it. If the passphrase is correct, the data is signed as defined in OpenPGP. If not, an error occurs. When a user wants to sign data: 1. Chooses a key via the key management library: * The library checks if the key has expired. * The library returns: a) An error state (ok / key not found / key expired / ambiguous ID ...). b) The key if the error state was "ok". 2. Selects cryptographic algorithms to be used (asymmetric and hashing). If this step is skipped, the default algorithms will be used. 3. Selects armoring flag (whether to perform radix-64 conversion or not). If this step is skipped, the output will be armored. 4. Calls data securizing library to perform the signing, passing as arguments the key and the algorithms that must be used. The signed PGP data is returned (digital signature + plaintext). ---------------------------------------- Signature verification ---------------------------------------- For verifying a signature, BPG receives the signed data, and checks the digital signature by calculating the hash function as defined in OpenPGP. When a user wants to verify data: 1. Calls data securizing library to perform the verification. * The library dearmors data if necessary. * The library locates in the PGP info of the data the key ID and algorithms used in the signature. * The key management library checks the trust of that key with the trust library (with searches in the trust database, which can be local or remote). * The library performs the verification: a) It takes the digital signature, decrypting it with the sender's public key. b) It calculates the hash of the plaintext. * It returns: a) An error state (ok / key not found / key expired / unknown algorithms / malformed PGP message / PGP data not found / ...). b) If the error state was "ok", returns the verification result: KU(digital signature) == H(plaintext)? ---------------------------------------- Compression ---------------------------------------- BPG will be able to compress data as defined in OpenPGP. The supported algorithms will be ZIP and ZLIB. ---------------------------------------- Radix-64 armor/dearmor ---------------------------------------- BPG will handle radix-64 armor and dearmor of data, as defined in OpenPGP. 2. Key management use cases =========================== ---------------------------------------- Keys from Arbitrary Sources ---------------------------------------- Rather than have this keyring thing from which all keys must come, it would be nice to be able to specify arbitrary sources for keys, such as a key export file. I currently have to set up an entire keyring, import keys, set up a trustdb, etc. for my backup scripts, since they encrypt the backups. I'd like to just have a bunch of keys in a directory, or a keyring in an arbitrary file, and say "encrypt to all of these." ---------------------------------------- Delegated Trust Model ---------------------------------------- I'd like to have an external interface into the keyring that's usable by scripts, and have the encryption and signature verification programs call a program script of my chosing in order to determine how much I trust a particular key. That way I'm not stuck with the built-in trust model, but can design my own. There is the question of how we deal with the trust database. Maybe we could use some sort of keyword/value system with a standardized set of basic keywords ("trust=low/medium/high/ultimate", a la gnupg) but the ability to add other things ("mycompany.com=it_dept/security_dept") for specialized applications. The trust database owner would be able to add, change and delete these as he wished. Security considerations: The trust database entries need to be signed by the trust database owner to prevent attackers from changing trust. (Or maybe the whole trust database should be.) The trust database also probably wants something like signed hashes of external programs it relies on, so it can detect when those are changed. ---------------------------------------- Management of Keys on Encrypted Files ---------------------------------------- An encrypted file, if I'm not totally out to lunch on this, consists of a symmetrically encrypted data chunk and the key for that encryption, encrypted once for each key that can decrypt the file, encrypted with that key's private component. I ought to be able easily list all of the keys on this list, and to add and delete keys from this list, without doing a symmetric re-encryption of every file. For example, when I decide to trust a new systems administrator, I ought to be able to go to my directory full of encrypted backups and say, "Allow this additional key to decrypt all of these," and have it quickly and painlessly do that. ---------------------------------------- Key Agent ---------------------------------------- [Someone fill this in.] ---------------------------------------- Trusting Your Trust Database ---------------------------------------- One thing bugging me about a lot of the scenarios above is that a lot of operations rely on my trust database. For example, listing the keys that decrypt a file: I want to know not only that a 2048 bit RSA key with self-signed identity 'Curt Sampson ' can decrypt that file, but I want to know that it's the same key that I have in my trust database marked as "very trusted", rather than any random key with the parameters above. I use my trust database to do that. But how do I know that an attacker has not substituted my trust database? I wonder if I don't want to check the fingerprint of the trust database signer every time. What ways are there of verifying the key that signed a trust database against external information (a card in my wallet, information on a USB key, someting fetched from several places on the net, etc.) when I use it? What are the security implications of these? What does an attacker have to do to compromise them? Can we verify against multiple sources (say, stuff on my USB key, which never leaves my physical presence, and against a download from my company's SSL-signed page, and against signed information from The NetBSD Foundation) to make an attacker's life harder? 3. Extensibility use cases ========================== ---------------------------------------- User-defined algorithms ---------------------------------------- Support for dynamic load of user-defined algorithms would be a very interesting feature for encouraging researchers and cryptographers to test their algorithms in our framework. We may want to use the same system for our own internal algorithms, and make the whole thing pluggable. But it would also be interesting to have ways to plug in new algorithms that are not written in C, e.g., in Perl for example. (See the note above regarding trust calculations, as well.) There are security and performance issues yet to be studied, but an initial approach of its working would be something like this: * The library receives a call for registering an algorithm with its location and interpreter ("register algorithm foo, written in Perl, located in /algorithms/foo_v1.pl"). * It receives a function call, with the input and the algorithm 'foo' in the parameters. * It searches for the library, returning an error if not found. * Selects interpreter, in this case the Perl intepreter. * Executes algorithm. * Returns output. 4. External systems use cases ============================= ---------------------------------------- Use of Library by External Programs ---------------------------------------- A program wants to be able to add PGP signing and encryption to something it does. Take for example, archangel, an archiver similar to tar. It wants to allow users to sign and encrypt archive entries. It might look something like this: clear: aatar cvf archive.aa file1 file2 dir1 signed: aatar cvf archive.aa -o signed file1 file2 dir1 encrypted: aatar cvf archive.aa -o encrypted file1 file2 dir1 both: aatar cvf archive.aa -o signed -o encrypted file1 file2 dir1 Presumably you want to use existing bpg keyrings, trust databases, etc. So: 1. How do you chose the key with which to sign, when there is a choice? ? Program gets information about the key to use, and provides that to the library. Program needs to deal with error conditions (key not found, etc.) Program may need to get a list of choices to offer the user. ? bpg uses default values (from user's config file, perhaps) and fails if those don't work. ? bpg takes over the terminal and asks the user, without the knowledge of the calling program 2. How do provide the passphrase to decrypt the key, or otherwise let the library get access to the key? ? bpg uses some default (e.g., gets it from a running key agent that has the key), and returns an error if that doesn't work ? bpg takes over the terminal and asks the user, without the knowledge of the calling program 3. When chosing an encryption key, how do you chose it, and how do you deal with the trust model, interacting with it if necessary? ? Environment variable specifies which key file to use ? Program specifies, as per #1 above. ---------------------------------------- Generic Archive Signer ---------------------------------------- Given a file that pax understands, and a key, bpg generates a list of filenames, sizes and hashes (probably multiple ones--SHA1 and others), signs this, and includes this and the public key of the signer in a file that it appends to the archive. bpg can then later be used to verify the signature and hashes and, in conjuction with your trust database, tell you how much you trust this archive. This level of trust would range anywhere from "has a valid signature, but Lord knows who signed it" to "you signed this yourself, and it's not been modified since." Or perhaps pax should be modified to do this. Security notes: 1. We need to make sure that this is defined well enough that it's as secure as a detached signature of the entire archive. 2. It is an error if any files are included in the archive that are not included in the signed list of files and hashes. Otherwise someone might add something like /root/.profile to the archive. 3. We need to verify all of the hashes before extraction, to ensure that we don't partly extract a known-corrupt archive. However, this makes streaming use of this (i.e., "cat foo.tar | tar xf -") impossible, unless we have a mode where we'd warn after extracting a known-bad archive that it is indeed bad. Do we want to allow this? 4. For duplicate files, failure will be automatic if they differ, and if they're the same, it's no consequence. ---------------------------------------- Signing Packages ---------------------------------------- 1. We include the signature in the package itself. This might be a list of all of the files in the archive (excepting the signature file itself), their sizes and hashes (multiple ones), the signature itself, and the public key used to sign the package, all as an ascii-armored file. 2. When pkg_add detects a signature, it verifies the signature and the hashes of all of the files. It then does something undefined (probably involving invoking bpg routines) to decide if the signature is trusted, and if not, it issues appropriate warnings and asks if it should continue, or abandons the install, or whatever. 3. Something is added either to BPG (a generic tar file signer?) or to the package creation tools to create this signature. (See also the "generic archive signer" use case. (This is entirely orthogonal to pkg_add's "-s" option.) 5. Miscellaneous use cases ========================== ---------------------------------------- Encryption/Signing Beyond Files and E-mail ---------------------------------------- There are things beyond files and e-mail that I'd like to be able to encrypt and sign. For example: * Since my web server asks for the full credit card number every time it wants to charge a card, it doesn't need access to the credit card numbers in the database. I'd like to be able to encrypt the data for the credit-card-number column before insert it, or looking it up to get the credit card ID. * I'd like to be able to sign my ssh authorized_keys file, to make it harder for attackers to replace it. (Where ssh gets a key to verify that signature is an interesting issue, but it could at least be changable only by the root user, so that an attacker who gets enough access to append to a file that I own cannot from that gain unlimited login rights.) * I'd like to be able to present a key to sudo rather than using a password. Ssh keys would seem, offhand, more suitable for this but given that there's no mechanism for that now, I could live with using my PGP key. * I currently keep a few files with lists of passwords and the like; ought not a nice modular PGP-based system be able to have extensions that would deal with things such as automatically filling in passwords in web pages? * I'd like to be able to sign CVS or other revision control commits. This might work something like: 1. Make a bunch of changes to my checkout. 2. cvs update, and verify that the checkout without my changes has a valid signature of the previous committer. 3. Examine my diffs and, if I'm happy with them, commit both them and a new signature from me verifying that the commit is correct. ---------------------------------------- SSH Encryption/Signing/Key Management ---------------------------------------- A wild idea: why do have two completely different and incompatable programs (right now, ssh and gpg) for doing asymetric cryptographic operations, with separate key storage and all of that? Couldn't all this be managed by one modular system? What would be some scenarios for this? * Put my SSH private keys in my private keyring with all the rest of my keys, so I need only one keyring and one passphrase. (I might carry this around on a USB key.) Have a bpg utility that can add a key or keys (with a default time limit of, say 1 hour) to a running ssh-agent. * Put my SSH public keys in with the other stuff on my public key, so people can get my SSH public keys (signed with my signing key, of course!) from a keyserver just as they can get my PGP public keys. (Does/can the OpenSSH format support this?) ---------------------------------------- Lint Tool / Expert System ---------------------------------------- A tool that looks at various option choices and provides an expert analysis of the security tradeoffs of these choices. For example, looking at a key and its related information (encryption keys, identities, trust information), or at the parameters proposed for generating a key, it could say things like: * A 4096-bit key is more secure than a 2048-bit or smaller key, but it is not compatable with the following other implementations of PGP: [insert list here]. * A DSA primary key is not as secure as an RSA primary key because at the same key length, it takes less computational effort to be able to forge messages with a DSA than an RSA key; and if you can forge messages in the primary key, you can make as many (bogus) subkeys as you want. We recommend usingt an RSA primary key whenever possible. ---------------------------------------- API tester ---------------------------------------- There must be a command-line application for testing the API. This program, bpgtool, has to able to manage: * get plaintext from file "input" * searching the file "keylist" (this is not the keyring, just a PGP file), find the list of primary keys that are: 1. Not expired, 2. Associated with an ID containing cjs@cynic.net or droggo@gmail.com * From primary keys get the most recent non-expired encryption keys, or use the primary key if there are no encryption keys at all * create a new session key, encrypt it with the encryption keys generated above, and encrypt the plaintext with it * fetch the private key 2048R/25808B3A (which will require a passprhase to load) from the keyring * Use that private key to sign the encrypted document (backwards from the usual PGP behaviour--do we want to allow this? or is it completely out of spec?) * ascii-armor the encrypted document * write the encrypted document to the file "output" This tester would be accesible via an scripting language, probably (but not definitely) Ruby. ---------------------------------------- Default algorithms ---------------------------------------- * Default symmetric algorithm: AES (?) [reasons]. * Default asymmetric algorithm for encryption: RSA (?) [reasons]. * Default asymmetric algorithm for signing: RSA (?) [reasons]. * Default hashing algorithm will be SHA-256 (?) [reasons]. * Default compression algorithm will be ZIP (?) [reasons]. ---------------------------------------- Internal data storage ---------------------------------------- * Messages: we can have an in-memory data structure for buffers, and always work with it. We can also provide functions to work with files, but internally taking them into the in-memory data structure (transparent to the user). [Cons?] * Keys: in-memory data structure. The key management library maps the key to that data structure. The data structure would include the private key, public key, trust level (?), key length, algorithm, ID... [Cons?]