From 8ab53f2da319ff7cb61d47f5bbe9a20d72eca1bc Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Thu, 4 Jan 2024 00:21:15 +0000 Subject: [PATCH] Some plumbing to export an SSB identity from Tilde Friends. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4732 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- apps/identity.json | 5 +++++ apps/identity/app.js | 37 +++++++++++++++++++++++++++++++++++++ core/core.js | 9 +++++++++ src/ssb.js.c | 17 +++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 apps/identity.json create mode 100644 apps/identity/app.js diff --git a/apps/identity.json b/apps/identity.json new file mode 100644 index 00000000..eaa9d030 --- /dev/null +++ b/apps/identity.json @@ -0,0 +1,5 @@ +{ + "type": "tildefriends-app", + "emoji": "🪪", + "previous": "&XHcSLE9zb9QH0hFGAza/5wuIv8jj2NKARlOvMBpMAzc=.sha256" +} \ No newline at end of file diff --git a/apps/identity/app.js b/apps/identity/app.js new file mode 100644 index 00000000..b1b0c3fc --- /dev/null +++ b/apps/identity/app.js @@ -0,0 +1,37 @@ +import * as tfrpc from '/tfrpc.js'; + +tfrpc.register(async function get_private_key(id) { + return bip39Words(await ssb.getPrivateKey(id)); +}); + +async function main() { + /* + let words = 'body hair useful camp warm into cause riot two bamboo kick educate dinosaur advice seed type crisp where guilt avocado output rely lunch goddess'; + let bytes = base64Decode('GO0Lv5BvcuuJJdHrokHoo0PmCDC/XjO/SZ6H+ddq4UvWd/VPW1RJrjd1aCUIfPIojFXrWMb8R54vVerU2TwjdQ==').slice(0, 32); + let data = { + ids: ids, + words: bip39Words(bytes), + bytes: base64Encode(bip39Bytes(words)), + round: bip39Words((await bip39Bytes(words)).slice(0, 32)), + privates: (await Promise.all(ids.map(id => ssb.getPrivateKey(id)))).map(x => bip39Words(x)), + };*/ + let ids = await ssb.getIdentities(); + await app.setDocument(` + `+ + ids.map(id => `
`).join('\n')+ + ``); +} + +main(); \ No newline at end of file diff --git a/core/core.js b/core/core.js index 54bb9689..45e3d3ad 100644 --- a/core/core.js +++ b/core/core.js @@ -407,6 +407,15 @@ async function getProcessBlob(blobId, key, options) { return ssb.getIdentities(process.credentials.session.name); } }; + imports.ssb.getPrivateKey = function(id) { + if (process.credentials && + process.credentials.session && + process.credentials.session.name) { + return Promise.resolve(imports.core.permissionTest('ssb_id_export')).then(function() { + return ssb.getPrivateKey(process.credentials.session.name, id); + }); + } + }; imports.ssb.appendMessageWithIdentity = function(id, message) { if (process.credentials && process.credentials.session && diff --git a/src/ssb.js.c b/src/ssb.js.c index 3cdc970e..f4977413 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -162,6 +162,22 @@ static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val, return result; } +static JSValue _tf_ssb_getPrivateKey(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + JSValue result = JS_UNDEFINED; + tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); + const char* user = JS_ToCString(context, argv[0]); + const char* id = JS_ToCString(context, argv[1]); + uint8_t private_key[crypto_sign_SECRETKEYBYTES]; + if (tf_ssb_db_identity_get_private_key(ssb, user, id, private_key, sizeof(private_key))) + { + result = tf_util_new_uint8_array(context, private_key, sizeof(private_key) / 2); + } + JS_FreeCString(context, user); + JS_FreeCString(context, id); + return result; +} + static JSValue _tf_ssb_getServerIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { JSValue result = JS_NewArray(context); @@ -1630,6 +1646,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb) JS_SetPropertyStr(context, object, "createIdentity", JS_NewCFunction(context, _tf_ssb_createIdentity, "createIdentity", 1)); JS_SetPropertyStr(context, object, "setServerFollowingMe", JS_NewCFunction(context, _tf_ssb_set_server_following_me, "setServerFollowingMe", 3)); JS_SetPropertyStr(context, object, "getIdentities", JS_NewCFunction(context, _tf_ssb_getIdentities, "getIdentities", 1)); + JS_SetPropertyStr(context, object, "getPrivateKey", JS_NewCFunction(context, _tf_ssb_getPrivateKey, "getPrivateKey", 2)); JS_SetPropertyStr(context, object, "hmacsha256sign", JS_NewCFunction(context, _tf_ssb_hmacsha256_sign, "hmacsha256sign", 3)); JS_SetPropertyStr(context, object, "hmacsha256verify", JS_NewCFunction(context, _tf_ssb_hmacsha256_verify, "hmacsha256verify", 3)); JS_SetPropertyStr(context, object, "privateMessageEncrypt", JS_NewCFunction(context, _tf_ssb_private_message_encrypt, "privateMessageEncrypt", 4));