aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/channel.php99
-rw-r--r--include/crypto.php10
-rw-r--r--include/xchan.php229
-rw-r--r--include/zot.php47
4 files changed, 384 insertions, 1 deletions
diff --git a/include/channel.php b/include/channel.php
index 49da57fd6..23ceb1414 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -454,6 +454,105 @@ function create_identity($arr) {
return $ret;
}
+
+function change_channel_keys($channel) {
+
+ $ret = array('success' => false);
+
+ $stored = [];
+
+ $key = new_keypair(4096);
+
+ $sig = base64url_encode(rsa_sign($channel['channel_guid'],$key['prvkey']));
+ $hash = make_xchan_hash($channel['channel_guid'],$sig);
+
+ $stored['old_guid'] = $channel['channel_guid'];
+ $stored['old_guid_sig'] = $channel['channel_guid_sig'];
+ $stored['old_key'] = $channel['channel_pubkey'];
+ $stored['old_hash'] = $channel['channel_hash'];
+
+ $stored['new_key'] = $key['pubkey'];
+ $stored['new_sig'] = base64url_encode(rsa_sign($key['pubkey'],$channel['channel_prvkey']));
+
+ // Save this info for the notifier to collect
+
+ set_pconfig($channel['channel_id'],'system','keychange',$stored);
+
+ $r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', channel_hash = '%s' where channel_id = %d",
+ dbesc($key['prvkey']),
+ dbesc($key['pubkey']),
+ dbesc($sig),
+ dbesc($hash),
+ intval($channel['channel_id'])
+ );
+ if(! $r) {
+ return $ret;
+ }
+ $r = q("select * from channel where channel_id = %d",
+ intval($channel['channel_id'])
+ );
+
+ if(! $r) {
+ $ret['message'] = t('Unable to retrieve modified identity');
+ return $ret;
+ }
+
+ $modified = $r[0];
+
+ $h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ",
+ dbesc($stored['old_hash']),
+ dbesc(z_root())
+ );
+
+ if($h) {
+ foreach($h as $hv) {
+ $hv['hubloc_guid_sig'] = $sig;
+ $hv['hubloc_hash'] = $hash;
+ $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modifed['channel_prvkey']));
+ hubloc_store_lowlevel($hv);
+ }
+ }
+
+ $x = q("select * from xchan where xchan_hash = '%s' ",
+ dbesc($stored['old_hash'])
+ );
+
+ $check = q("select * from xchan where xchan_hash = '%s'",
+ dbesc($hash)
+ );
+
+ if(($x) && (! $check)) {
+ $oldxchan = $x[0];
+ foreach($x as $xv) {
+ $xv['xchan_guid_sig'] = $sig;
+ $xv['xchan_hash'] = $hash;
+ $xv['xchan_pubkey'] = $key['pubkey'];
+ xchan_store_lowlevel($xv);
+ $newxchan = $xv;
+ }
+ }
+
+ $a = q("select * from abook where abook_xchan = '%s' and abook_self = 1",
+ dbesc($stored['old_hash'])
+ );
+
+ if($a) {
+ q("update abook set abook_xchan = '%s' where abook_id = %d",
+ dbesc($hash),
+ intval($a[0]['abook_id'])
+ );
+ }
+
+ xchan_change_key($oldxchan,$newxchan,$stored);
+
+ Zotlabs\Daemon\Master::Summon(array('Notifier', 'keychange', $channel['channel_id']));
+
+ $ret['success'] = true;
+ return $ret;
+}
+
+
+
/**
* @brief Set default channel to be used on login.
*
diff --git a/include/crypto.php b/include/crypto.php
index 2c5545e9b..6ac3fd732 100644
--- a/include/crypto.php
+++ b/include/crypto.php
@@ -185,6 +185,16 @@ function crypto_methods() {
}
+function signing_methods() {
+
+
+ $r = [ 'sha256' ];
+ call_hooks('signing_methods',$r);
+ return $r;
+
+}
+
+
function aes_encapsulate($data,$pubkey) {
if(! $pubkey)
logger('aes_encapsulate: no key. data: ' . $data);
diff --git a/include/xchan.php b/include/xchan.php
index 12eb674fa..dba0b8b88 100644
--- a/include/xchan.php
+++ b/include/xchan.php
@@ -137,3 +137,232 @@ function xchan_fetch($arr) {
}
+function xchan_change_key($oldx,$newx,$data) {
+
+ $r = q("update abook set abook_xchan = '%s' where abook_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update abconfig set xchan = '%s' where xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update group_member set xchan = '%s' where xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update chat set chat_xchan = '%s' where chat_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update chatpresence set cp_xchan = '%s' where cp_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update event set event_xchan = '%s' where event_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update item set owner_xchan = '%s' where owner_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update item set author_xchan = '%s' where author_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update item set source_xchan = '%s' where source_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update mail set from_xchan = '%s' where from_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update mail set to_xchan = '%s' where to_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update shares set share_xchan = '%s' where share_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update source set src_channel_xchan = '%s' where src_channel_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update source set src_xchan = '%s' where src_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xchat set xchat_xchan = '%s' where xchat_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xconfig set xchan = '%s' where xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xign set xchan = '%s' where xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xlink set xlink_xchan = '%s' where xlink_xchan = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xprof set xprof_hash = '%s' where xprof_hash = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("update xtag set xtag_hash = '%s' where xtag_hash = '%s'",
+ dbsec($newx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ $r = q("select channel_id, channel_allow_cid, channel_deny_cid from channel where (channel_allow_cid like '%s' or channel_deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update channel set channel_allow_cid = '%s', channel_deny_cid = '%s' where channel_id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['channel_allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['channel_deny_cid'])),
+ intval($rv['channel_id'])
+ );
+ }
+ }
+
+ $r = q("select id, allow_cid, deny_cid from attach where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update attach set allow_cid = '%s', deny_cid = '%s' where id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['id'])
+ );
+ }
+ }
+
+ $r = q("select cr_id, allow_cid, deny_cid from chatroom where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update chatroom set allow_cid = '%s', deny_cid = '%s' where cr_id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['cr_id'])
+ );
+ }
+ }
+
+
+ $r = q("select id, allow_cid, deny_cid from event where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update event set allow_cid = '%s', deny_cid = '%s' where id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['id'])
+ );
+ }
+ }
+
+
+ $r = q("select id, allow_cid, deny_cid from item where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update item set allow_cid = '%s', deny_cid = '%s' where id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['id'])
+ );
+ }
+ }
+
+
+ $r = q("select mitem_id, allow_cid, deny_cid from menu_item where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update menu_item set allow_cid = '%s', deny_cid = '%s' where mitem_id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['mitem_id'])
+ );
+ }
+ }
+
+
+
+ $r = q("select obj_id, allow_cid, deny_cid from obj where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update obj set allow_cid = '%s', deny_cid = '%s' where obj_id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['obj_id'])
+ );
+ }
+ }
+
+ $r = q("select id, allow_cid, deny_cid from photo where (allow_cid like '%s' or deny_cid like '%s') ",
+ dbesc($oldx['xchan_hash']),
+ dbesc($oldx['xchan_hash'])
+ );
+
+ if($r) {
+ foreach($r as $rv) {
+ $z = q("update photo set allow_cid = '%s', deny_cid = '%s' where id = %d",
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['allow_cid'])),
+ dbesc(str_replace('<' . $oldx['xchan_hash'] . '>', '<' . $newx['xchan_hash'] . '>', $rv['deny_cid'])),
+ intval($rv['id'])
+ );
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/include/zot.php b/include/zot.php
index 8bbc4a969..f9682237e 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -122,7 +122,8 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
],
'callback' => '/post',
'version' => ZOT_REVISION,
- 'encryption' => crypto_methods()
+ 'encryption' => crypto_methods(),
+ 'signing' => signing_methods()
];
if ($recipients) {
@@ -3757,6 +3758,50 @@ function zot_reply_message_request($data) {
json_return_and_die($ret);
}
+function zot_rekey_request($sender,$data) {
+
+ $ret = array('success' => false);
+
+ // newsig is newkey signed with oldkey
+
+ // The original xchan will remain. In Zot/Receiver we will have imported the new xchan and hubloc to verify
+ // the packet authenticity. What we will do now is verify that the keychange operation was signed by the
+ // oldkey, and if so change all the abook, abconfig, group, and permission elements which reference the
+ // old xchan_hash.
+
+ if((! $data['old_key']) && (! $data['new_key']) && (! $data['new_sig']))
+ json_return_and_die($ret);
+
+ $oldhash = make_xchan_hash($data['old_guid'],$data['old_guid_sig']);
+
+ $r = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($oldhash)
+ );
+
+ if(! $r) {
+ json_return_and_die($ret);
+ }
+
+ $xchan = $r[0];
+
+ if(! rsa_verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) {
+ json_return_and_die($ret);
+ }
+
+ $newhash = make_xchan_hash($sender['guid'],$sender['guid_sig']);
+
+ $r = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($newhash)
+ );
+
+ $newxchan = $r[0];
+
+ xchan_change_key($xchan,$newxchan,$data);
+
+ $ret['success'] = true;
+ json_return_and_die($ret);
+}
+
function zotinfo($arr) {