On Sat, Aug 29, 2009 at 1:06 PM, Matthew
Toseland<toad at amphibian.dyndns.org> wrote:
> On Thursday 27 August 2009 20:01:19 Evan Daniel wrote:
>> On Thu, Aug 27, 2009 at 1:18 PM, Matthew
>> Toseland<toad at amphibian.dyndns.org> wrote:
>> > On Wednesday 26 August 2009 19:01:43 Evan Daniel wrote:
>> >> On Wed, Aug 26, 2009 at 1:13 PM, Matthew
>> >> Toseland<toad at amphibian.dyndns.org> wrote:
>> >> > On Monday 27 July 2009 18:26:27 Evan Daniel wrote:
>> >> >> On Mon, Jul 27, 2009 at 9:18 AM, Matthew
>> >> >> Toseland<toad at amphibian.dyndns.org> wrote:
>> >> >> > - RSKs: Important sites, particularly those distributing 
>> >> >> > executables, need a revocation mechanism. This can be emulated with 
>> >> >> > HTML UI elements, but is clumsy and problematic due to the various 
>> >> >> > different error messages.
>> >> >>
>> >> >> Adding HTML UI elements on SSKs as the exist now has a major problem:
>> >> >> if Mallory obtains Alice's privkey, his first order of business
>> >> >> becomes inserting a new edition of the freesite that points to a
>> >> >> different revoke key than the one Alice gave Bob, thus preventing Bob
>> >> >> from revoking the site in a meaningful manner.
>> >> >
>> >> > Right. Hence post the frame as a CHK site. But it is still not very 
>> >> > good, because some error messages can be quite confusing.
>> >>
>> >> That doesn't work unless the top level site is a CHK, which sucks :/
>> >>
>> >> >>
>> >> >> I suggest something like the following, based on a chat I had with
>> >> >> saces. ?The idea is to retrofit revocation capability onto existing
>> >> >> SSKs without changing how SSKs work or breaking existing client
>> >> >> software. ?There are probably lots of problems with the details :)
>> >> >>
>> >> >> Create a new keytype, RSK at . ?This is treated exactly like an SSK
>> >> >> internally (ie a translation layer similar to USKs), but has several
>> >> >> differences. ?First, the namespace is different (mangled internally
>> >> >> somehow) so that "RSK at crypto/foo" and "SSK at crypto/foo" are 
>> >> >> different
>> >> >> keys. ?Second, the null filename is allowed ("RSK at crypto/" is a 
>> >> >> valid
>> >> >> key). ?Third, redirects are not allowed.
>> >> >
>> >> > Why allow null key? It gets very confusing if you do that, and parsing 
>> >> > can be ambiguous - is this a manifest lookup in the null key or is it a 
>> >> > non-null key?
>> >> >
>> >> > Why no redirects? You can't fit much in a single SSK block! Oh, the RSK 
>> >> > is just the revocation, not the data with revocation protection?
>> >>
>> >> The idea is that RSK at crypto/ holds the revocation for SSK at crypto/ .
>> >> Manifests would be disallowed as well; you only need the one default
>> >> file.
>> >
>> > Hence RSK vs RDK below.
>> >>
>> >> >> The usage is as follows: the RSK@ keyspace represents the revocation
>> >> >> files for the SSKs with the same pubkey / crypto key. ?The null
>> >> >> filename ("RSK at crypto/") represents a revoke for the whole keyspace
>> >> >> (key blown, etc). ?Non-null filenames ("RSK at crypto/foo") represent
>> >> >> finer-grained revokes for things like broken inserts (if you screw up
>> >> >> an edition of a freesite and haven't yet inserted the fixed version,
>> >> >> for example). ?I'm less certain I like the fine-grained revokes, but
>> >> >> I'm mentioning them anyway for completeness; the remainder of the
>> >> >> proposal would work fine with or without support for them.
>> >> >
>> >> > IMHO fine-grained revokes are completely pointless because the question 
>> >> > at issue is whether there is a reasonable possibility that a bad guy 
>> >> > might have the private key for the whole keyspace.
>> >>
>> >> Not completely pointless. ?If a seriously problematic bug made it into
>> >> one of the auto-updates, it might be nice to revoke just that build in
>> >> a way that would prevent nodes from installing that build, but didn't
>> >> represent a compromise of the key. ?Pushing a new update isn't a
>> >> complete substitute, because it's slower (especially if the bug takes
>> >> time to fix).
>> >>
>> >> Similarly, if a large site (like, say, one of the spider indexes) is
>> >> accidentally published with an error, it might be nice to have clients
>> >> keep using the old version until the new one can be published (which
>> >> might take a day or three, given the size of such an index).
>> >
>> > Hmmm, maybe. Inserting a redirect to an older version takes the author 
>> > very little time, whereas having the client check an extra key reduces 
>> > speed for everyone, and the author still has to insert a key.
>>
>> So the idea would be that if you discover version 10 has a problem,
>> you immediately insert version 11 as a redirect to version 9, and then
>> insert version 12 with the fix as soon as is convenient?
>>
>> I think that works, and makes fine-grained revokes superfluous, provided 
>> that:
>> 1) There is a good UI to do this. ?Right now I know of no user-level
>> tool that does this.
>> 2) We need to fix bugs 3415, 3428, and possibly 545.
>
> Yes, yes, and not essential.
>
>> 3) The node auto-update code needs to verify that there is no later
>> version available before installing an update. ?Does it do this
>> already?
>
> No.
>>
>> >> >> If the RSK key is found, then its existence indicates that the site
>> >> >> has been revoked. ?It would contain, at a minimum, a message saying
>> >> >> who revoked it. ?If I'm creating a freesite, and want to distribute
>> >> >> revoke privs, I would generate a set of RSK binary blobs (which say
>> >> >> things like "revoked by Alice" "revoked by Bob" etc), and distribute
>> >> >> those to the relevant people. ?I could even generate several blobs for
>> >> >> Alice, with different pre-defined revoke reasons.
>> >> >
>> >> > Interesting. No customisable revoke message..
>> >> >>
>> >> >> (Optional extension) The RSK key could also include a set of places to
>> >> >> look for further information. ?For example, a set of SSKs owned by the
>> >> >> people with revoke privs, which could be used to implement voting
>> >> >> rules or similar. ?Then, everyone would get a copy of the same blob
>> >> >> that basically says "revoked by someone, see these keys for details".
>> >> >> It could then specify eg four SSKs to check, with a rule that the
>> >> >> revoke is valid if any two of the four are found. ?This could also
>> >> >> implement revoker-definable reasons: I give Alice a revoke blob that
>> >> >> says "revoked by Alice, see this SSK for the reason".
>> >> >
>> >> > Ok, so in the naive implementation each trustee is given a blob that 
>> >> > identifies them and explains the specific pre-set failure mode. In 
>> >> > which case any trustee can insert his error blob, and there would be no 
>> >> > way for the user to know the trustee has gone bad. But the next step is 
>> >> > for all of the blobs to contain the list of extra data locations for 
>> >> > each trustee. So we can query them and determine that the blob was 
>> >> > bogus, because the others said so.
>> >> >
>> >> > HOWEVER, this opens up a more fundamental weakness: If the attacker 
>> >> > obtains the private key he can insert whatever he wants, including a 
>> >> > bogus list of extra data locations. He can ensure that no real 
>> >> > revocation is inserted simply by inserting a bogus revocation with 
>> >> > extra data locations which all say it is bogus. And this is not 
>> >> > solvable with a single-fetch model AFAICS: We need to publish the extra 
>> >> > data locations *in advance*.
>> >> >
>> >> > Clearly we don't want to encode it into the URI, as it would be 
>> >> > ridiculously long. And we don't want it to depend on a single privkey 
>> >> > either. So we need an RSK manifest. This should be in a CHK, or a SSK 
>> >> > with a throwaway key. An SSK is smaller and has better survivability; a 
>> >> > CHK doesn't allow tampering even with the throwaway key. It would 
>> >> > contain:
>> >> > - The target URI. Probably a USK.
>> >> > - The blob URI. This is checked before moving on to the target URI.
>> >> > - SSKs for each of the trustees.
>> >> > - How many trustees are required to endorse a new RSK (0 = not allowed).
>> >> > - How many trustees are required to endorse a new RSK in the case where 
>> >> > a valid blob has been inserted by one of the trustees (0 = not allowed).
>> >> > - How many trustees are required to endorse a new RSK in the case where 
>> >> > an invalid blob has been found (0 = not allowed).
>> >> >
>> >> > When fetching an RSK, we fetch the manifest. If it is not found, we 
>> >> > fail. If it is not formatted as a valid RSK manifest, we fail. We check 
>> >> > the blob URI. If we don't find the blob, we fetch the target URI: 
>> >> > everything is fine, but we fetch the trustees' SSKs in the background 
>> >> > anyway to ensure good propagation. If we do find a blob, and it is not 
>> >> > a valid blob specifying one of the trustees and a recognised failure 
>> >> > mode, we fail. We fetch the trustees' extra data. If the original RSK 
>> >> > allows them to create a new RSK, and there are enough votes given the 
>> >> > conditions, we do a permanent redirect to the new RSK. If not, we 
>> >> > display all their messages.
>> >> >
>> >> > I am uncertain whether the trustees' blobs should contain a nonce 
>> >> > signed by their SSK's privkey to identify themselves; this would 
>> >> > complicate creating them, so maybe not worth it.
>> >> >
>> >> > Thoughts?
>> >>
>> >> Well, I hadn't been trying to design revocable SSKs that can be 
>> >> un-revoked :)
>> >
>> > Okay, you meant extra data purely as a way for an authorised revoker to 
>> > give more information, without identifying the other authorised revokers 
>> > or depending on them.
>>
>> Right. ?Given that the presumed attacker could also insert such a blob
>> and message, I'm no longer certain how wise it is to provide the
>> capability.
>
> Exactly.
>>
>> >> The idea was that the mere presence of the RSK key indicated a revoke.
>> >> ?It didn't matter what the data was, and once the key exists there are
>> >> no error conditions possible that prevent the revoke from being valid.
>> >>
>> >> The idea was that Alice would publish a SSK site. ?Bob would generate
>> >> his own SSK keypair. ?Alice would give Bob a blob that is the revoke
>> >> for her site ( RSK at alice_key/ ). ?It would contain something like
>> >> "revoker: Bob\ndetailed message:
>> >> SSK at bob_key/alice-site-revoke/detailed_message.txt". ?Alice could give
>> >> several (different) such blobs to several trustees. ?Each would insert
>> >> to the same RSK, but with different contents. ?The contents, including
>> >> Bob's SSK for details, are set at blob creation time, so bob's SSK
>> >> needs to be known in advance. ?It doesn't matter who inserts the
>> >> revoke, what the message is, or whether the attacker inserted it with
>> >> their own message; the message is purely informational, and its
>> >> presence, absence, or validity has no impact on the validity of the
>> >> revoke. ?This has the advantage that in normal operation (the site is
>> >> not revoked) there's only one extra key I need to poll for (or, with
>> >> fine-grained revokes, two: one for the whole site, and another for the
>> >> specific file).
>> >
>> > Right.
>> >>
>> >> (I'll give some more thought to the multi-trustee un-revoking idea,
>> >> but I don't have any specific comments right now. ?My proposal assumed
>> >> that once the key was compromised, you would revert back to however
>> >> you originally established the trust chain.)
>> >
>> > In the multi-trustee system, we do have an extra key when we first open 
>> > the site, but after that is cached it's just one extra lookup, not one per 
>> > trustee. (I had originally planned one per trustee).
>>
>> So basically, we would have a single RDK per SSK keypair, and that RDK
>> would specify links to the revocation certificate and the trustee list
>> (with the trustee list ? ?Then any trustee could insert the revoke
>> cert (which they have in blob form), and the client would only go
>> searching the trustee list if it found the revoke cert? ?That means
>> that the first time any site on the SSK is visited, we have to go
>> search for the RDK and then the cert, but on future USK editions the
>> RDK lookup is cached and so we only have to look for the cert, much
>> like my proposal.
>
> Yes.
>>
>> If the trustee list changes, or the trustees decide on a new RDK, or
>> similar, what happens? ?Does the original site SSK keypair need to
>> change as well, or are the RSK manifests versioned, or does something
>> else happen? ?Clearly if the original key is compromised, and the
>> trustees decide to endorse a new keypair, the SSK changes; I suppose
>> it's best to simply use this mechanism for any changes at all?
>
> Yes. The trustees insert data pointing to a new RDK, and then insert a 
> revocation cert saying use the new one. The client fetches the trustees' 
> data, possibly including one malicious trustee, executes the specified voting 
> limits, and gives a permanent redirect to the new RSK/RDK.
>>
>> > Certainly your way could be implemented more easily. But however you 
>> > originally established the trust chain may no longer be accessible - or it 
>> > may have been established over a long period largely by the content 
>> > posted, which is common on pseudonymous freesites, including those 
>> > authoring software. So IMHO there is a need for trustees evolution. What 
>> > we do *not* want is it to become commonplace for a revocable site to say, 
>> > on its RSK, "please use this new RSK" because they need to remove or add 
>> > some trustees!!
>> >
>> > Hence IMHO we need some sort of a parent RSK document.
>>
>> OK, I'm convinced. ?We just need a way to ensure that the trustees can
>> create a new trustee list / revoke cert location etc, while avoiding
>> the versioning problem where a person requesting a revoked key finds
>> some of the original revoke information, but not enough to follow the
>> chain all the way to the currently valid site. ?Thoughts?
>
> Well the new RSK/RDK will be a new URI - a new CHK or a new throwaway SSK 
> keypair. AFAICS all we can do is send a permanent redirect to fproxy so it 
> updates its bookmarks, and update our own bookmarks? This should all be SSKs 
> hopefully, so should be reasonably robust? Is it reasonable to assume that 
> the list of trustees doesn't change very often?
>>
>> >> >> Default settings for how to handle revokes are tricky. ?I propose that
>> >> >> the key-revoke ("RSK at crypto/") always be checked, and an error
>> >> >> returned if found by default. ?There would then be a force-download
>> >> >> option to allow clients to download the data anyway. ?File-specific
>> >> >> revokes ("RSK at crypto/filename") are less important, and offer more
>> >> >> censorship possibilities, so they should not be checked by default.
>> >> >> If a client is prepared to intelligently inform the user about them,
>> >> >> it would turn on the option to check them.
>> >> >>
>> >> >> The logic behind prohibiting redirects is that this is not a
>> >> >> general-purpose key, and we want to make DOS or spam attacks as hard
>> >> >> as possible. ?Furthermore, any revoke message ought to fit in 1k.
>> >> >
>> >> > Right ... but what about the payload? I had thought RSKs would check 
>> >> > for the revocation key, and if not found, then proceed to the target 
>> >> > site, which is most likely a redirect to a top block CHK? And clearly 
>> >> > we don't want this to be just in metadata, unless the CHK is metadata - 
>> >> > we need it to be encoded into the URI, by calling it RSK@ instead of 
>> >> > SSK at .
>> >>
>> >> In my proposal, there is no further payload. ?The RSK corresponds the
>> >> the SSK, and any payload is handled at by the SSK.
>> >>
>> >> Looking at it now, what I've been calling RSKs in the proposal need a
>> >> name change, because really the proposal has three key types involved.
>> >> ?There are old-style, non-revocable SSKs. ?There are new, revocable
>> >> SSKs (called RSKs). ?There are revocation keys (call it RKD@, for
>> >> revocation key data, or something). ?If a user supplies
>> >> "RSK at crypto/foo" it gets converted into a fetch for "SSK at crypto/foo"
>> >> and (in parallel) a second fetch for "RKD at crypto/" (and optionally for
>> >> "RKD at crypto/foo" as well). ?And of course there's a corresponding
>> >> version for USKs ("RUK at crypto/foo/n" -> "USK at crypto/foo/n" +
>> >> "RKD at crypto/").
>> >
>> > Right.
>> >>
>> >> This has a (possibly small) speed advantage as well: if the RSK key
>> >> contains a payload (as in your version), then the first fetch must
>> >> complete before we can start looking for the revocation. ?In my
>> >> proposal, as soon as the user supplies the key, we simultaneously
>> >> start fetching the data (on the assumption that it won't be revoked,
>> >> however we don't display it until we know) and the revocation key.
>> >
>> > Hmmm... we'd want the RSK manifest to be inserted separately, not 
>> > dependant on the main pubkey, so yes you're right here.
>>
>> I'm a little unclear on what you mean here. ?If I request
>> RUK at crypto/sitename/1/foo.txt does that get translated (via a USK)
>> into SSK at crypto/sitename-1/foo.txt for data, plus RDK at crypto/ for the
>> revoke manifest, or are you discussing something different?
>
> IMHO RSKs should include enough to fetch the RDK, and the RDK itself would 
> include the site redirect. Once we have fetched the RDK (RSK manifest), we 
> can start fetching the real redirect and the blob at the same time. We don't 
> display the output of the real redirect until after we have checked the blob.
>
> For RUKs, we just add an edition number. This is the edition number of the 
> USK for the site redirect.
>>
>> >> >> This would need some changes internal to the node, but no network
>> >> >> level changes or datastore changes. ?Because RSKs are just a different
>> >> >> way of turning a pubkey + filename into a block ID, they are treated
>> >> >> exactly the same as SSKs at a network and datastore level; all the
>> >> >> changes would be confined to higher levels, much like USKs. ?Beyond
>> >> >> simple code complexity issues, it is important that rare RSKs be able
>> >> >> to hide amongst normal SSKs for security reasons.
>> >> >
>> >> > Right.
>> >> >>
>> >> >> There is an argument in favor of some lower-level changes, but I think
>> >> >> it is outweighed by the problems such changes cause. ?Basically, if my
>> >> >> node is in possession of a revoke certificate for a key, it should
>> >> >> never drop the revoke cert from its store while keeping the key it
>> >> >> refers to. ?Otherwise, it's possible for the revocation of a site to
>> >> >> be lost while the site itself remains accessible. ?Obviously, doing
>> >> >> this would require some sort of low-level special treatment for
>> >> >> revokes. ?However, I suspect that this is rare enough not to be a real
>> >> >> issue.
>> >> >
>> >> > I don't think a lower level solution would be a good idea. Generally 
>> >> > storage and propagation for SSKs is fairly good anyway.
>> >>
>> >> I'm inclined to agree.
>> >>
>> >> >>
>> >> >> The major other thing this would require is support for binary blobs.
>> >> >> At present, there are no user-level tools to handle them. ?As I see
>> >> >> it, the minimum requirements are:
>> >> >> - The ability to create a binary blob for a key and save it, without
>> >> >> inserting that key. ?There would need to be a simple form wizard that
>> >> >> generated revocation blobs in a correctly-formatted manner.
>> >> >
>> >> > This we have, but not the UI.
>> >> >
>> >> >> - The ability to verify a binary blob and read the data it contains.
>> >> >> This would require also knowing the key it represents (AIUI, the blob
>> >> >> normally contains the routing key but not the decryption key, just
>> >> >> like the datastore). ?If Alice intends to revoke Bob's site, she
>> >> >> probably wants to first check that the blob she is about to insert
>> >> >> will do that (inserting the revoke for the wrong site would be bad).
>> >> >> When she receives the revoke blob from Bob, she probably also wants to
>> >> >> check that the revoke message says what Bob said it did. ?This
>> >> >> verification step needs to not actually insert the blob.
>> >> >
>> >> > This we sort-of have; you can pass a BlockSet on a request.
>> >> >
>> >> >> - And, obviously, the ability to actually insert a blob that the user 
>> >> >> has.
>> >> >
>> >> > This we have.
>> >>
>> >> In the API, but not the UI. ?An easy to use UI for all three steps is
>> >> critical to RSKs actually being useful. ?Are these capabilities
>> >> available through FCP?
>> >
>> > Agreed, we need work on the UI.
>> >
>> > There is some support for binary blobs (non-persistent only) in FCP. I 
>> > don't think fetch-with-a-blob is supported, but fetching to a blob and 
>> > inserting a blob are supported.
>>
>> Conceptually, we want to list the contents of the blob, not simply
>> probe for the presence of something. ?Before I go insert a blob, I
>> want to know not only that it does contain what I think it does, but
>> that it doesn't contain anything else. ?At a low level, these can be
>> equivalent (if everything that is supposed to be there is, and there
>> is no extra data, then I know I have the complete list), so either
>> implementation is fine, but at the UI level it should be "display the
>> complete contents of this blob."
>
> Ugh. Well that is possible with SnoopMetadata etc.
>>
>> Also, verify blob shouldn't actually perform a fetch, even locally:
>> consider the case where I want to examine my copy of the revoke blob
>> on a site that has been revoked. ?I want to know I'm looking at the
>> data in my copy of the blob, not the one in my datastore. ?(I'm not
>> completely sure how I'd use that capability, but roughly speaking, if
>> I'm being trusted to hold some weird binary mess, I should always be
>> able to read it and be certain that what I'm looking at is that data,
>> all of that data, and only that data. ?Anything else requires me to go
>> to extra work and examine it early, and then save the results of that
>> examination alongside it, which is bad UI.)
>>
>> And, of course, we need a UI for creating and managing a trustee list,
>> creating a revoke cert that can be handed out (in encrypted form,
>> ideally without requiring the user to also use a distinct tool like
>> gpg, even if it's done by hooking into gpg), inserting the revoke and
>> voting on new keypair approval, and (as above re: fine-grained
>> revokes) inserting redirects to already-inserted data. ?(jSite can
>> sortof be used for this last part, in that you can specify to insert a
>> redirect to a provided CHK rather than insert a specific component
>> file, but if the original insert was a container file that included
>> splitfile metadata, or even simply had jSite insert the file with
>> default settings, I don't think you can).
>
> Hooking into gpg from java is a PITA. We could however password such blobs. 
> And no, jsite can't do what we'd need.
>>
>> Evan Daniel
>

Just to clarify, since this email thread has gotten a bit confusing
(at least to me).

Toad's current proposal, as I understand it, goes approximately like
this.  To create a RSK website, I first create a SSK keypair where the
site will be stored.  Then I determine a list of trustees and a voting
rule, and get the trustees' SSK pubkeys.  Then, I create a second SSK
keypair for the revoke certificate, generate a binary blob reoke cert
that inserts to it (or possibly one per trustee), and forget the
privkey for the keypair.  I then create a CHK with the following
information: the site SSK pubkey, the revoke cert SSK location, and
the trustee list and voting rule.  I insert this CHK key, and hand out
blobs to my trustees.  My trustees verify the blobs (but obviously
don't insert them).

To use the RSK/RUK, I give out the key
"freenet:RSK at routing_key,decryption_key,extra/sitename/filename.ext".
The viewer then takes that key, converts to
"freenet:CHK at routing_key,decryption_key,extra/", fetches that key, and
recovers from it the revoke cert location and the main site SSK.  They
construct the site URI as
"freenet:SSK at 
ssk_pubkey_hash,ssk_decryption_key,ssk_extra/sitename/filename.ext",
with the ssk_ pieces coming from the fetched CHK.  They then (attempt
to) fetch in parallel the revoke cert and the site data.  Once the
revoke cert fetch has failed and the site fetch has succeeded, the
site is displayed.  Iff the revoke cert is fetched, the client fetches
the data from the trustee's sites and worries about applying the
voting rule.

Possibly the top level CHK block in the above would be an SSK block
using the same throwaway keypair as the revoke cert, assuming there's
enough space.  RUKs would be exactly analogous, except that the site
data would be fetched from a USK instead of an SSK, using the normal
USK rules.  If the trustee list is long enough that it's stored as a
redirect, clients need to fetch that redirect in order to ensure data
longevity.

Toad: Which block in the above are you referring to as the RDK?  The
top CHK or SSK with the links to the real site and the revoke cert?
Did I get that all correct?

Evan Daniel

Reply via email to