Hi Jens,

Agreed - however our use case wouldn't work well with solution you propose.  
Our documents are signed before they are inserted into CouchDB 
http://goo.gl/vlJwO (and actually before certain metadata fields are attached 
to the object).  That's one area where I think your proposal is lacking is that 
there's not really a method to exclude fields from the signature except via 
underscore fields. The key thing to note is we had a document model before 
object signing requirement; so we had to design a signature solution that was 
additive in order to not change object model field names for risk of blowing 
backwards compatibility.  If there was way with your solution, similar to the 
security object, store an model to XOR against to compute/validate the 
signature that might be fine.

On Jul 3, 2012, at 6:07 PM, Jens Alfke wrote:


On Jul 3, 2012, at 10:01 AM, Jim Klo wrote:

Yes, and as a matter of fact, i just got digital signature validation using 
OpenPGP within a map function working a few minutes ago!
Here's a link to the relevant code: 
https://github.com/jimklo/TheCollector/blob/master/dataservices/thecollector-resources/views/lib/sig_utils.js

As far as I can tell, this code uses a data schema where the signed contents 
are wrapped in some kind of OpenPGP encoding:

       var msg_list = openpgp.read_message(doc.digital_signature.signature);
       for (var i=0; i<msg_list.length; i++) {
           isValid |= msg_list[i].verifySignature();
       }

It looks like msg_list is the actual document payload, which has to be decoded 
using openpgp.read_message.


Correct - and yes agreed not exactly the most efficient.  Possibly using a 
detached signature would be better, however because we also identified that a 
canonical JSON serialization has not been widely defined or accepted we went 
for a translation of selected signed fields to bencoding then using OpenPGP, 
clearsign a SHA256 hash of the bencoded JSON.

This is IMHO not a very good solution because it hides the document contents 
away — for example, all the map functions and any app logic that uses documents 
will have to know to call read_message, which will also make them slower.

Presumably the performance hit is only a once per view hit, which I can live 
with in our UC. I'm not sure I'm following though - we don't hide the document 
contents at all, as we use clearsign, unless you were assuming we were 
encrypting too.  I'd agree that I don't necessarily like that each map must 
apply the check; however for our UC, that's acceptable, since not all documents 
are signed.  Additionally, moving this code from a map function into a validate 
document update function would solve the need of having to validate within each 
map function; potentially marking each document with a _isvalidsignature field 
upon insert/update.


The schema I implemented (see my previous message) doesn't alter the basic 
document format. The signature is in a nested object but applies to the entire 
document contents (minus the signature itself of course). There's no need to 
change any code that reads documents; the only time you have to know about the 
signature scheme is while verifying the signature. It's even possible to have 
multiple signatures on a document.


Essentially we've both aligned to more or less the same solution, and 
identified similar challenges. The one issue both of us face is the encoding of 
floating point values. Our rule is to convert FPV to a base 10 string 
representation, before bencoding. Otherwise things like ratings or other 
numerically scaled values get lost in the serialization process and non-unique 
hashes become pointless to sign.

If you haven't been following IETF's JOSE, you should take a look at it 
http://datatracker.ietf.org/doc/draft-ietf-jose-json-web-signature/?include_text=1
  It's not very CouchDB friendly, however I wonder if there would be a way to 
make couch use it; Say you can insert and update docs using a JOSE payload 
instead of a JSON payload, CouchDB could deserialize the b64 encoding back into 
JSON for users who don't care to validate signatures, but then optionally could 
GET the documents back as a list of JOSE payloads..  The nice thing about their 
solution is there's no need for a canonical representation, the bad thing is 
there's no way to deal with 'unsigned fields'.

I'm certainly open to some collaboration here, as I'm not too happy with 
bencoding and FWIW canonical JSON is very difficult to make portable (ordered 
maps aren't supported across many languages) I've been considering replacing 
bencoding with Tagged Netstrings http://tnetstrings.org/ which provides a good 
translation that is more portable and include floating point, and boolean 
values.

—Jens

Jim Klo
Senior Software Engineer
Center for Software Engineering
SRI International

Reply via email to