Maintainer: Messaging Team
(messaging-team@zks.net)
Author(s): Christian Paquin, Graydon Hoare
$Revision: 1.2 $
$Date: 2000/10/04 12:55:28 $
$Author: marcp $
Authentication between a nym and the cacophonix mail system happens using a custom certificate format and protocol, embedded in the standard esmtp AUTH LOGIN command. see links below (and the detailed discussion in frmailaccount) for more details.
The frmailauth library can build, serialize, deserialize, and verify said email certificates. These are not related to PKI certificates. The messaging team wanted to work with PKI on this but were told essentially that they would not be ready on our timeframe (Q3-4 of 2000). It is still possible in the future that we will switch to some cert code shared with PKI.
A mail certificate object is defined in "frMailAuth.c". The Nym Server and the Pop Server share a mac key k (a FrCryptMacKey object). When a nym is created, the Nym Server generates a mail certificate and macs it with k. The nym then receives a buffer containing the certificate. The buffer is of the form:
pkt-vers
(1)pkt-type
(1)ent
(entsize + 1)vers
(2)exp
(8)type
(1)
(4)vol
(4)size
(4)cross
(4)mac
(10)
where the fields are:
- pkt-vers
- A 1 byte value indicating the version of this packet format, currently 1
- pkt-vers
- A 1 byte value indicating the type of this packet, currently 1.
- ent
- The name of the entity, precede by a 1-byte type (as in an FrEntExpId, execpt that we only keep the name, not the following empty blanks). For now, only nym have mail certificate.
- vers
- The version of the mail certificate.
- exp
- The expiration date of the certificate (from a ZkClock object).
- type
- The type of the account of the entity, e.g. trial, pro, free.
- The mail-limit (maximum number of mail a user can send).
- vol
- The volume-limit (maximum number of bytes a user can send).
- size
- The pop-quota (maximum size, in bytes, of the owner's mail box).
- cross
- The cross-post limit (maximum number of simultaneous newsgroup the user can send).
- mac
- The 10-byte mac over the preceeding bytes.
Here are the function calls to generate and verify the certificates. Check "/test/exMailAuth.c" for actual code.
FrMailAuth cert; /* certificate to be created */ FrCryptMacKey mkey; /* the key shared with the Pop Server */ FrEntIdExp ent; /* the nym entity */ ZkClock exp; /* expiration time */ char *buf; /* buffer to give to the nym */ size_t bsz; /* size of buf */ /* generate the ent from nym name */ ... /* get the mac key in mkey */ ... /* set expiration in exp */ ... /* generate the mail certificate */ frMailAuthNew(err,&cert); frMailAuthSetEnt(err,cert,&ent); frMailAuthSetVersion(err,cert,VERS); frMailAuthSetExpiration(err,cert,exp); frMailAuthSetNymType(err,cert,NYM_TYPE); frMailAuthSetMailLimit(err,cert,MAIL_LIMIT); frMailAuthSetVolLimit(err,cert,VOL_LIMIT); frMailAuthSetSizeLimit(err,cert,SIZE_LIMIT); frmailAuthSetCrossLimit(err,cert,CROSS_LIMIT); frMailAuthMac(err, cert, mkey); /* generate the buffer, which is given to the client */ frMailAuthToBuf(err, cert, &buf, &bsz);
FrMailAuth cert; /* cert to be created from buf */ FrCryptMacKey mkey; /* the key shared with the Pop Server */ FrEnt ent; /* entity generated from USER field */ ZkClock clk; /* current time */ char *buf; /* buffer received as PASS field */ size_t bsz; /* size of buf */ int ok; /* buf points to a buffer containing the certificate of size bsz */ ... /* generate an entity ent from nym name */ ... /* get the mac key in mkey */ ... /* set current time in clk */ /* generate the mail certificate from the buffer */ frMailAuthNewFromBuf(err, &cert, buf, bsz); /* check owner and verify the mac */ frMailAuthCheckOwnerAndMac(err, cert, &ent, mkey, &ok); if ( ! ok) { /* authentication failed */ } frMailAuthCheckExpiration(err, cert, clk, &ok); if ( ! ok) { /* cert expired */ }
For the moment, the library stands midway between being a real cert and a password. Its components are pretty much fixed, thus limiting its use as a general certificate. We may want to replace the actual mail cert by a more general cert currently developed by the PKI team.
The program /prog/genpasswd.c can generate a mail certificate for a nym. The program /prog/checkpasswd.c is used to verify a cert. This program replace the checkpasswd program in qmail.
Any modification to the library must be reflected in the programs checkpasswd and genpasswd.
there are a number of tools in the prog/ subdirectory of this library (frmailauth), which can be used on command-line to integrate with the remainder of the mail system (both operationally and during testing).
Opens a shared secret key (between the mail system and the nym server), and uses this as a MAC key to generate an email certificate for the nym, which it then dumps to standard out, base64 encoded. this can be used verbatim as a password string to be sent via the esmtp AUTH LOGIN command. no communication with the nym server needs to take place: the shared secret key can be any binary data; we only assume it is shared with the nym server to simplify the nym creation process (the nym server can give out email certs)
Reads a triple of <base64-nym>\0<base64-cert>\0<base64-timestamp> on file descriptor 3. it then opens and reads the shared secret key and checks that the supplied cert is valid under that key. the timestamp is ignored (it's part of the normal qmail checkpassword interface). if there are additional arguments to checkpasswd, it will change to the home directory of nym and change its userid to that of the owner of the pop boxes, then exec the args. if there are no arguments, checkpasswd will simply exit with an error code indicating the verification of the cert. checkpasswd must be run as root, if it is to change its uid and execute a subprocess. if it has no subprocess it can safely be run as anyone.
Checks to see if the nym already has a home directory and a maildir, and if not it will atomically create one for them. it's run as a subprocess half way through checkpasswd.
A drop-in replacement for the qmail-getpw that comes with qmail; its purpose is to inform qmail-local of the home directory, uid, gid, dash and ext of a given nym's local delivery.
Each nym must share a mac key with the mail system. The function frGenSharedNymMailMacKey() will generate it. In the mail system, the program /prog/genMacKey.cpp will generate it.
A number of small config files must be in place for all this to work:
- /var/qmail/control/mailroot
- path name of the root of all the nym's mail directories (no trailing slash)
- /var/qmail/control/mailowner
- name of the user owning all the nym's mail directories (usually "nym")
- /var/qmail/control/tmpmailroot
- temporary directory, also owned by the mail dir owner, in which to create new accounts temporarily. must be on the same filesystem as mailroot.
- /var/qmail/control/mailmackey
- the mac key known by both the nym server and the mail system, which is used to authenticate mail certificates.
Copyright © 2000 Zero-Knowledge Systems Inc.
All Rights Reserved