The basic components of this are to
a) have KeyManagers manage not PrivateKey objects, but Key objects, and to make sure that the things it considers "signing keys" are either PrivateKeys or Keys that are symmetric keys (i.e. not PublicKey objects),
b) to maintain the current model of specifying what signing key to use by specifying a KeyLocator (credential) which points to a signing key,
c) make the sign and verify helpers smart enough to know that if the signing key passed in is a PrivateKey instance they should sign/verify as currently done, and if it's a Key they should MAC, and
d) make the digestAlgorithm argument passed in optionally to sign methods do double duty specifying a digest algorithm for a private key signature and a MAC algorithm for a symmetric key signature (e.g. "SHA256" for the former, "HMAC-SHA256" for the latter)
e) make the default algorithm handling take a null digestAlgorithm to mean SHA256 for a private key signature and a sensible default for a symmetric MAC (start with HMAC-SHA256; there are better, more recently specified options, but they haven't achieved universal distribution in libraries yet; once things are working with HMAC then Gene or I can suggest a better option)
f) this may require a bit of massaging of the OID handling code in OIDLookup to play nice with MAC algorithms and MAC algorithm OIDs.
Not clear why those are in there as opposed to somewhere else, and they are likely
to cause trouble... much simpler versions are currently in CCNAbstractInputStream, and fancier ones Rebecca did which she thinks she pulled are pretty similar to the mysterious
ones in CCNFileInputStream....
Replaced by issue #100172.
Replaces issue #100060.
Basically the most effective way to handle issues #100080 and #100100 is to refactor CCNSegmenter
so that instead of fragmenting content to a fixed size b, it takes the size b as a constraint on the overall packet size, and fragments content to a size b' < b that takes into account headers,
expansion with encryption, signing, and so on. And during that refactor, it should remove any remaining statefulness in the segmenter, and optimize copy steps appropriately. (For example, my previous attempt to remove copy steps had had the clever side effect of making the segmenter alloc enormous buffers that were only partially used...).
The intent is to make sure that the segmenter is prepped for a world where lots of objects from lots of sources get dropped into the same BulkSigner and signed and output together. (So for instance on platforms where latency is ok but signing is expensive, you can build a Merkle tree over not just the segments of a single file, but over the single segments of many otherwise unrelated small objects).
This is a significant research problem, and very hard to do efficiently while preserving the ability to attribute content to individuals. I'd either do a version of it as an academic exercise (to write a paper on), but not expect it to be practical, or wait for a bit more real-world use of stuff to make it clear what a practical solution ought to look like.
We need the ability to specify not just the exact signer of a piece of content (the PublisherPublicKeyDigest matching the publisher field specified in the SignedInfo), but at least one level of indirection from the exact signer. In other words, to say not just "content signed by Bob", but instead, "content signed by anyone whose key is signed by Bob". (And in fact, we'd like to be able to specify the most complicated expressions we can efficiently evaluate, but the "key signed by" expression is the minimum sufficient to express all the others.) We do that by including a PublisherID, which can specify either a key directly, or a signer constraint, in interests, rather than the more narrow PublisherPublicKeyDigest.
The only thing we can actually currently match in ccnd is the exact publisher, but fixing that problem is not this issue. What this issue refers to is the fact that given that we can only currently match exact publishers, the APIs to various bits of code have gotten sloppy, and pass in PublisherPublicKeyDigests to specify signer constraints, when they ought to pass in PublisherIDs. Basically someone just needs to review all the places where publisher constraints are passed around in the read path and make sure that they specify the more general option, as a meet in the middle pattern for when ccnd supports signer constraints.
Note: there are constraints in PublisherID that specify certificates, not just signers (with this certificate, signed by someone with this certificate). If someone feels driven to simplify, the certificate constraints can be removed. However, one should not jump the gun and assume that if we can only do key match publisher constraints now, we should drop the APIs down to PublisherPublicKeyDigests and not allow signer-of constraints for the moment. The problem is that a) once you drop the api down, it's hard to change it, and b) we absolutely need signer-of constraints (represented by passing in PublisherIDs with the appropriate parameters). The requirement that you know exactly who signed a piece of content before you retrieve it is unscalable and unmanageable, and is why large parts of Java code signing fail (Java supports only specific key constraints in policies ("signed by Bob"), not signer-of constraints ("signed by anyone whose key is approved by Organization X"). If you can say "content signed by anyone at PARC is acceptable" you can easily handle large swaths of content signed by an ever-changing set of people all of whose keys were signed by the PARC CA. If you have to know for a particular piece of content ahead of time that this version of this one was signed by Simon Barber, (when the last one was signed by Jim Thornton), you're toast.
So, basically this is just a cleanup issue to make sure the API stabilizes on the PublisherID form of calls so that signer-of constraints don't require deprecating half the universe.
When access control is used to automatically encrypt content, headers are indeed automatically encrypted. The problem this issue refers to is the fact that we haven't settled on an API for passing user-specified encryption keys (which may be static or dynamic, basically ContentKeys subclasses) in to network objects. Given that (issue #100008), the CCNFileOutputStream can just hand any user-specified keys given to it to the object it uses to write the header, and all will be happy.
After make && make clean, there are jar files left behind that should have been removed by the clean.
Ready to merge (verbal)
I've merged the portion that Paul finished.
Do we park the remainder of this for now?
We may want separate key caches for keys that are loaded in but don't need to be stored long-term
in disk (data keys, ephemeral keys for say macing exchanges with ccnd), and those keys that we want to save over time and reload from disk.
It would be good to refactor AccessControlManager, GroupBasedAccessControlManager and their
subclasses if any to only "know" about the particular access control scheme they implement, and not about the "user", their keys, their group memberships, their identities and so on. The keys ought to be known to the KeyManager, the identities (generally CCN names under which keys are stored) potentially as well; the known group memberships might want to be cached by a GroupManager (but maybe not the KeyManager, which shouldn't know much about any specific access control scheme). But the ACM itself and its subclasses, probably shouldn't know these things.
The easy way to do this refactoring:
- remove the _handle from the ACM class, and pass a handle in (presumably always associated with the same identity for operations that should go together) to calls that need one.
- similarly, pull out the GM and identity caches, though it will take some thought to figure out where to put those.
By pulling out the _handle variable, it becomes very easy to see where the _handle member is merely being used to get a CCNHandle to read/write to the network, and where the ACM is "knowing" too much about the user.
Assigning to Nick to make names more consistent.
Currently this is hardwired into LibraryTestBase.
Some timing circumstances can cause pipelining to hang
Reassigning to Paul to investigate some test failures.
updated wrong issue.
Reassigning to Paul to investigate some test failures.