update signature checking for relayables

pull/338/head
Zach Prezkuta 2012-06-09 13:54:21 -06:00
parent 4faf0e609f
commit 09eb52810b
1 changed files with 127 additions and 74 deletions

View File

@ -1060,39 +1060,59 @@ function diaspora_comment($importer,$xml,$msg) {
} }
$parent_item = $r[0]; $parent_item = $r[0];
$author_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle;
$author_signature = base64_decode($author_signature); /* How Diaspora performs comment signature checking:
if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - If an item has been sent by the comment author to the top-level post owner to relay on
$person = $contact; to the rest of the contacts on the top-level post, the top-level post owner should check
$key = $msg['key']; the author_signature, then create a parent_author_signature before relaying the comment on
} - If an item has been relayed on by the top-level post owner, the contacts who receive it
else { check only the parent_author_signature. Basically, they trust that the top-level post
$person = find_diaspora_person_by_handle($diaspora_handle); owner has already verified the authenticity of anything he/she sends out
- In either case, the signature that get checked is the signature created by the person
who sent the salmon
*/
if(is_array($person) && x($person,'pubkey')) $signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle;
$key = $person['pubkey']; $key = $msg['key'];
else {
logger('diaspora_comment: unable to find author details');
return;
}
}
if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) {
logger('diaspora_comment: verification failed.');
return;
}
if($parent_author_signature) { if($parent_author_signature) {
$owner_signed_data = $guid . ';' . $parent_guid . ';' . $text . ';' . $diaspora_handle; // If a parent_author_signature exists, then we've received the comment
// relayed from the top-level post owner. There's no need to check the
// author_signature if the parent_author_signature is valid
$parent_author_signature = base64_decode($parent_author_signature); $parent_author_signature = base64_decode($parent_author_signature);
$key = $msg['key']; if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
logger('diaspora_comment: top-level owner verification failed.');
return;
}
}
else {
// If there's no parent_author_signature, then we've received the comment
// from the comment creator. In that case, the person is commenting on
// our post, so he/she must be a contact of ours and his/her public key
// should be in $msg['key']
if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) { /* if(strcasecmp($diaspora_handle,$msg['author']) == 0) {
logger('diaspora_comment: owner verification failed.'); $person = $contact;
$key = $msg['key'];
}
else {
$person = find_diaspora_person_by_handle($diaspora_handle);
if(is_array($person) && x($person,'pubkey'))
$key = $person['pubkey'];
else {
logger('diaspora_comment: unable to find author details');
return;
}
}*/
$author_signature = base64_decode($author_signature);
if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
logger('diaspora_comment: comment author verification failed.');
return; return;
} }
} }
@ -1613,7 +1633,7 @@ function diaspora_like($importer,$xml,$msg) {
intval($r[0]['id']), intval($r[0]['id']),
intval($importer['uid']) intval($importer['uid'])
);*/ );*/
// FIXME // FIXME--actually don't unless it turns out that Diaspora does indeed send out "false" likes
// send notification via proc_run() // send notification via proc_run()
return; return;
} }
@ -1626,39 +1646,58 @@ function diaspora_like($importer,$xml,$msg) {
return; return;
} }
/* How Diaspora performs "like" signature checking:
- If an item has been sent by the like author to the top-level post owner to relay on
to the rest of the contacts on the top-level post, the top-level post owner should check
the author_signature, then create a parent_author_signature before relaying the like on
- If an item has been relayed on by the top-level post owner, the contacts who receive it
check only the parent_author_signature. Basically, they trust that the top-level post
owner has already verified the authenticity of anything he/she sends out
- In either case, the signature that get checked is the signature created by the person
who sent the salmon
*/
$signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; $signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
$key = $msg['key'];
$author_signature = base64_decode($author_signature);
if(strcasecmp($diaspora_handle,$msg['author']) == 0) {
$person = $contact;
$key = $msg['key'];
}
else {
$person = find_diaspora_person_by_handle($diaspora_handle);
if(is_array($person) && x($person,'pubkey'))
$key = $person['pubkey'];
else {
logger('diaspora_like: unable to find author details');
return;
}
}
if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
logger('diaspora_like: verification failed.');
return;
}
if($parent_author_signature) { if($parent_author_signature) {
// If a parent_author_signature exists, then we've received the like
//$owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; // relayed from the top-level post owner. There's no need to check the
// author_signature if the parent_author_signature is valid
$parent_author_signature = base64_decode($parent_author_signature); $parent_author_signature = base64_decode($parent_author_signature);
$key = $msg['key'];
if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
logger('diaspora_like: owner verification failed.'); logger('diaspora_like: top-level owner verification failed.');
return;
}
}
else {
// If there's no parent_author_signature, then we've received the like
// from the like creator. In that case, the person is "like"ing
// our post, so he/she must be a contact of ours and his/her public key
// should be in $msg['key']
/* if(strcasecmp($diaspora_handle,$msg['author']) == 0) {
$person = $contact;
$key = $msg['key'];
}
else {
$person = find_diaspora_person_by_handle($diaspora_handle);
if(is_array($person) && x($person,'pubkey'))
$key = $person['pubkey'];
else {
logger('diaspora_like: unable to find author details');
return;
}
}*/
$author_signature = base64_decode($author_signature);
if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
logger('diaspora_like: like creator verification failed.');
return; return;
} }
} }
@ -1802,40 +1841,54 @@ function diaspora_signed_retraction($importer,$xml,$msg) {
$signed_data = $guid . ';' . $type ; $signed_data = $guid . ';' . $type ;
$key = $msg['key'];
$sig_decode = base64_decode($sig); /* How Diaspora performs relayable_retraction signature checking:
if(strcasecmp($diaspora_handle,$msg['author']) == 0) { - If an item has been sent by the item author to the top-level post owner to relay on
$person = $contact; to the rest of the contacts on the top-level post, the top-level post owner checks
$key = $msg['key']; the author_signature, then creates a parent_author_signature before relaying the item on
} - If an item has been relayed on by the top-level post owner, the contacts who receive it
else { check only the parent_author_signature. Basically, they trust that the top-level post
$person = find_diaspora_person_by_handle($diaspora_handle); owner has already verified the authenticity of anything he/she sends out
- In either case, the signature that get checked is the signature created by the person
if(is_array($person) && x($person,'pubkey')) who sent the salmon
$key = $person['pubkey']; */
else {
logger('diaspora_signed_retraction: unable to find author details');
return;
}
}
if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) {
logger('diaspora_signed_retraction: retraction-owner verification failed.' . print_r($msg,true));
return;
}
if($parent_author_signature) { if($parent_author_signature) {
$parent_author_signature = base64_decode($parent_author_signature); $parent_author_signature = base64_decode($parent_author_signature);
$key = $msg['key'];
if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) { if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
logger('diaspora_signed_retraction: failed to verify person relaying the retraction (e.g. owner of a post relaying a retracted comment'); logger('diaspora_signed_retraction: top-level post owner verification failed');
return; return;
} }
} }
else {
/* if(strcasecmp($diaspora_handle,$msg['author']) == 0) {
$person = $contact;
$key = $msg['key'];
}
else {
$person = find_diaspora_person_by_handle($diaspora_handle);
if(is_array($person) && x($person,'pubkey'))
$key = $person['pubkey'];
else {
logger('diaspora_signed_retraction: unable to find author details');
return;
}
}*/
$sig_decode = base64_decode($sig);
if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) {
logger('diaspora_signed_retraction: retraction owner verification failed.' . print_r($msg,true));
return;
}
}
if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') { if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') {
$r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1", $r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1",