	getkeybyname() library release notes
	Very Preliminary Release
	John Gilmore, gnu@toad.com
	September 3, 1996

This code is provided so you can try fitting it into your programs
and see how well it integrates.  The interface may change before final
release.

We provide a library routine, getkeybyname(), which permits cryptographic
keys to be obtained from the Domain Name System from wherever people have
published them.  This library routine is designed to be portable to
many environments that include a domain resolver library (please send
any changes that you have to make, back to me at gnu@toad.com).  You
link this routine into your application, and it calls the resolver
to do DNS queries.  It processes the results of the queries and returns
the keys to your application in a convenient form.

Usage:

	count = getkeybyname(dnskeys, maxcount, options);

	dnskeys is a "struct dnskey *" which points to one or more
	structures in which keys will be returned.  Maxcount is the
	number of "struct dnskey"s pointed to by dnskeys.  Options
	is a set of option flags; DNSKEYS_NO_OPTIONS is the default
	value to pass.

	The first dnskey structure must have its dname, flags, protocol,
	and algorithm fields set before the call:

		dname is a char * which points to a domain name,
		e.g. "dnssec.toad.com".

		flags contains any DNS key flag bits which your
		application requires to be on.  Only keys in which
		these bits are set will be returned.  Zero is the
		default value.  See the DNS Security RFC for details.

		protocol specifies what DNS protocol field values 
		your application requires.  Zero is the default
		value, permitting any protocol.  See the DNS Security
		RFC for details.

		algorithm specifies what DNS algorithm type your
		application requires.  Zero is the default value,
		permitting any algorithm.  See the DNS Security
		RFC for details.

	ALL of the dnskey structures must have their keylen (and, if
	nonzero, key) fields initialized.  If keylen is nonzero, key is
	assumed to point to pre-allocated memory of that length, where
	a key will be returned (and keylen will be set to its actual
	length).  If keylen is zero, memory will be allocated with
	malloc() for any key returned in that structure, and its length
	will be stored into keylen.  It is the caller's responsibility
	to free this memory.

	The returned value, count, is negative if an error occurs, and
	an error code is returned in h_errno (as is usual for DNS
	resolver subroutines).  The returned value is zero if no keys
	were published at that domain name (which match your specified
	criteria).  If the return value is positive, it says how many
	dnskey structures have been filled in with valid key
	information.  The dnskey structures beyond the count have not
	been altered.

	The getkeybyname() routine contains an internal select() loop
	and may result in significant delay -- seconds or minutes --
	particularly when the domain being queried is not reachable on
	the Internet at that moment.  A suggestion for your user
	interface is that you let your user know before you call it,
	and when it returns, so that they will understand what the
	problem is if there is a significant hang.  In a text-based
	interface, a message like "Getting key for dnssec.toad.com..."
	then "OK.\n" would be great.

	In the future I hope to have an asynchronous interface to 
	it, which would permit you to include it in your own select()
	loop so that your application remains interactive during the
	potentially lengthy lookup process.  If your application needs
	this, please let me know what kind of interface you would
	like to see.

******

The "getkey" program

Getkey.c is a very simple program for testing the getkeybyname() interface.
If you run `getkey dnssec.toad.com' you will get and print all the keys
for that domain address.  Run it against "frodo.dnssec.toad.com" to see
several keys with different protocol and algorithm numbers.


******

In order to use DNS keying in your applications, you will need to:

  (0)  Define how to map the entities that your application cares about
(e.g. users or hosts) into Domain Name System names.  Hosts are
straightforward.  User email addresses have a proposed mapping in the
Secure DNS RFC, such that e.g. "gnu@toad.com" becomes "gnu.toad.com".

  (1)  Define a format for storing the public keys used by your
application in DNS Resource Records, if an existing published format is
not already suitable.  Be sure to require key flag bit #5 to be set if
your mapping is for a user name, or bit #6 if your mapping is for a
host or similar entity.  Publish this format (and the name
mapping above) as an Internet-Draft, and get an algorithm number
assigned for it by the Internet Assigned Numbers Authority
(IANA@usc-isi.edu).  Today, the two existing published formats are for
raw RSA public key values, and for X.500 Objects with an Object ID
number.

  (2)  Write code as part of your application that permits public keys
to be output as textual DNS Resource Records in the format defined above.
Document for your users how to give these resource records to their
system administrator to be inserted into their domain's published
DNS records.  An example output resource record might be:

    dnssec.toad.com.	10000	KEY	0x0140 255 1 (
	    AQPAdr+bHGqBNfAQEvGLepslJQbt9Qu4iyAZ6FQIEjFtxcfv5GjSLY8/kLTEBGbC
	    p3xQsSK1jdbcevovOcEB5qnNF3C6IjNxs/HlVW9IS7/SMQ== )

  (3)  Write code as part of your application that permits public keys
to be retrieved as DNS Resource Records in the format defined above.

You're done -- you have a worldwide global replicated high-availability
cached high-performance distributed database for your keys.  Congratulations!


References:

Domain Name System Security Extensions, Internet-Draft
draft-ietf-dnssec-secext-10.txt, included in this distribution.
Also available wherever Internet-Drafts are found.  This will
become the DNS Security RFC when the RFC Editor is done with it.
