[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

No Subject

I'm heading a team here at Electric Communities that is working
on an initial pass at the problem of signatures, signature
semantics and trust management issues for Java and our Java
extension language, E. (http://www.communities.com/e/index.html)
I thought I might summarize the current state of our work, which
provides both an example of what some people would like to do
with certificates, as well as what one group came up with when
ease of implementation was one of the primary goals.

Although it is not a part of the current developer's release of
E, our work will appear Real Soon Now in a more feature-complete
version. For various reasons, including the sheer complexity of
X.509 and the lack of a decent API for PGP, we decided to
roll our own format that captured the semantics that we needed
and subsequently figure out how to obtain those semantics in
a more standard fashion. (Also, since we're obviously not the
only ones concerned with this problem, we'll hopefully be working
with EIT, Sun, etc. to reach some standardization as well.)

For cryptographic primitives we are using a set of Java classes
built on top of RSAREF (largely based on JCrypt, written by Amanda
Chou last fall.) We are sticking entirely to the published RSA
interfaces for the time being. This work will all be made
freely available in some fashion, although the details are not entirely
developed at the moment. Currently we're only providing binaries of E, but
that's largely due to the extremely early alpha state of the work.

In looking at the problem of trust management, I was greatly
influenced by a draft paper by Blaze, Feigenbaum & Lacy, "Distributed
Trust Management." It's not for redistribution, but Matt will
likely cough one up if you ask nicely (mab@research.att.com).

I knew that there were a good number of things we wanted to say
about Java classes, along with a highly flexible way of delegating
the right to say those things in various contexts. I also knew that
we were likely to think of more things to say, and more variations
on these things, so I didn't want to get locked into a rigid
format.  At the same time I wanted to avoid the Byzantine aspects
of X.509. Also, as a company, we are somewhat allergic to rigid
certification hierarchies.

In looking afresh at keys and certificates, I made the observation
that there are basically three parts to a key and three parts to
a certificate.

A key has:
  o An "outside header", which is not used in calculating the key
    hash, and is changeable. It can be used for local tagging and
    indexing of keys for easy retrieval.
  o An "inside header", which is part of the key hash. At minimum
    this needs to include a text field that is used when presenting
    the key to users in lists, etc. I'm also partial to a date header
    on the inside as well.
  o The key itself, in some kind of portable ASCII format.

A certificate has:
  o Some form of statement, which is the thing that is signed.
  o A signature.
  o Helpful information, like where to find any keys mentioned
    in the statement that aren't presented in their entirety.

Our bias was strongly towards ASCII wherever possible, because it
is easier to debug, somewhat easier to parse, and because it can
be viewed with a standard text editor. Also, it facilitates
certificate transport, although one hopes that we're past the days
where key resolution will occur primarily in 7-bit channels. (It's
still nice to be able to send a cert in e-mail that is largely
intelligible to the recipient w/o special tools.)

A note: some people seem to think that it's necessary for
certificate statements to be in a rigidly fixed format (i.e.
Ron's comments about defining whitespace rules.) This certainly
needs to be taken into account, but our approach has been to
parse statements in two ways: as a block of ASCII and as a parse
tree. The text block is used for hashing and signature checking,
the parse tree is used to determine semantics. By keeping these
two aspects together and doing the Right Thing at various stages
of certificate processing, we are able to use a fairly free-form
statement language. Worst case: line separator mismatch has to
be resolved for viewing purposes.

For our certificate statements we cooked up a small, (hopefully!)
clear predicate language strongly influenced by Blaze, et. al,
although much more tightly constrained in our initial implementation
than what they suggest. (I'm going to stop doing the compare and
contrast bit; the curious should read their paper.)

First of all, our system depends on the security of some form of
local storage where a "trust boot file" (TBF) is stored. We are explicitly
_not_ addressing issues arising from the compromise of local storage;
if someone can feed you a bad TBF, bad Java binaries, or, for that
matter, a bad OS, you're hosed.

In the TBF there are two kinds of certificate that are used to
initialize the TrustManager. There are normal certificates and
"policy" certificates, which are unsigned and whose statements are
accepted a priori. Policy statements form the root of a local
certificate tree; starting with these, the TrustManager "chains
forward" through certificates mentioned in "Forward:"
fields until no more remain. At this point a number of well-known
roots have (hopefully) been deputized to approve various classes
of subsidiary certificates.

When a low-level claim needs to be verified, such as "these
classes belong to this package", the TrustManager goes through
a "backwards chaining" process, attempting to get back to a
root that has been deputized by the user's local policy.

Here is a somewhat idealized set of certificates. (They have
lots of comments, were generated by hand instead of by our
GUI certificate tool, and ASCII-encoded binary is shown as
________ for clairty.)

Note that "%%" is used to separate one certificate from another,
"##" is used to separate one section of a certificate from another.
This is one of the more plastic aspects of this format, although
as mentioned before, our primary goal was to clearly and quickly
capture the semantics we wanted, and then worry more intensively
about formats.
Version: "alpha 1.0"
// Comments, by the way, are perfectly fine in these statements
// There are other predicates and predicate variables (e.g.
// "expydate") that are omitted for this short example.
// A hypothetical corporate MIS key, referred to by key hash
// ECR is the type of key/signature
FudcoKey = KeyFP(ECR, "____");

// Our development key that we use for signing work in progress
// for use internally
FudcoDevelop = KeyFP(ECR, "____");

// only certificates in the Trust Boot File can have "POLICY" as a source
POLICY states {
  // We're saying here that as a matter of policy (probably corp.
  // policy) we blindly believe everyting our MIS dept. says about
  // other keys. At present only terminal * characters are supported
  // in claim matching.
  FudcoKey CanMakeClaim where (
    delegate == "yes" and claim == "*"

  // The FudcoDevelop key can be used to say what classes belong in
  // packages beginning with "fudco." or to designate other keys
  // that can validly make this claim as far as I'm concerned
  FudcoDevelop CanMakeClaim where (
    delegate == "yes" and claim == "PkgBelongCert where (pkg == \"fudco.*\")"
  // The FudcoDevelop key can also be used to say what classes can load
  // other classes, without restriction.
  FudcoDevelop CanMakeClaim where (
    delegate == "yes" and claim == "LoadOkayCert where ()"
// there's no sig since this is policy
// more keys to verify and add to root group if possible
Forward: "http://fudco.com/keys/mis-boot-keys"
// where to look for keys mentioned here
Resolve: "http://keys1.fudco.com/keys/keyserve/"
Resolve: "http://keys2.fudco.com/keys/keyserve/"
// Here we introduce a hypothetical Sun "master key" that can
// delegate to other keys with respect to whether or not a class
// belongs in a sun.* or java.* pacakge.
SunMasterKey = KeyFP(ECR, "____");
FudcoKey = KeyFP(ECR, "____");

FudcoKey states {
  SunMasterKey CanMakeClaim
    where (delegate == "yes" and
      claim == "PkgBelongCert where (pkg == \"sun.*\" or pkg == \"java.*\")"
// a hash of the text from %% to ## is signed in the next section
// hints go here... a hypothetical sun key server
Resolve: "http://keys.javasoft.com/keyserve/"
SunMiscKey = KeyFP(ECR, "____");
SunMasterKey = KeyFP(ECR, "____");

SunMasterKey states {
  SunMiscKey CanMakeClaim where (delegate == "no" and
    claim == "PkgBelongCert where (pkg == \"sun.misc.*\")"
// hints go here... a hypothetical sun key server
Resolve: "http://keys.javasoft.com/keyserve/"
// this is a cert that would be attached to or associated with
// a java class or classes
SunMiscKey = KeyFP(ECR, "____");

SunMiscKey states {
  PkgBelongCert where (class == "sun.misc.foo" and class_hash == "____");
  PkgBelongCert where (class == "sun.misc.bar" and class_hash == "____");
Resolve: "http://keys.javasoft.com/keyserve/"
etc. etc.

------                                                             ------
Douglas Barnes         "The tighter you close your fist, Governor Tarkin,
cman@communities.com    the more systems will slip through your fingers."
cman@best.com                                             --Princess Leia