mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
52 lines
2.0 KiB
JavaScript
52 lines
2.0 KiB
JavaScript
|
|
var SEA = require('./root');
|
|
var shim = require('./shim');
|
|
var S = require('./settings');
|
|
// Derive shared secret from other's pub and my epub/epriv
|
|
SEA.secret = SEA.secret || (async (key, pair, cb, opt) => { try {
|
|
opt = opt || {};
|
|
if(!pair || !pair.epriv || !pair.epub){
|
|
pair = await SEA.I(null, {what: key, how: 'secret', why: opt.why});
|
|
}
|
|
var pub = key.epub || key;
|
|
var epub = pair.epub;
|
|
var epriv = pair.epriv;
|
|
var ecdhSubtle = shim.ossl || shim.subtle;
|
|
var pubKeyData = keysToEcdhJwk(pub);
|
|
var props = Object.assign({ public: await ecdhSubtle.importKey(...pubKeyData, true, []) },{name: 'ECDH', namedCurve: 'P-256'}); // Thanks to @sirpy !
|
|
var privKeyData = keysToEcdhJwk(epub, epriv);
|
|
var derived = await ecdhSubtle.importKey(...privKeyData, false, ['deriveBits']).then(async (privKey) => {
|
|
// privateKey scope doesn't leak out from here!
|
|
var derivedBits = await ecdhSubtle.deriveBits(props, privKey, 256);
|
|
var rawBits = new Uint8Array(derivedBits);
|
|
var derivedKey = await ecdhSubtle.importKey('raw', rawBits,{ name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt' ]);
|
|
return ecdhSubtle.exportKey('jwk', derivedKey).then(({ k }) => k);
|
|
})
|
|
var r = derived;
|
|
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
|
return r;
|
|
} catch(e) {
|
|
console.log(e);
|
|
SEA.err = e;
|
|
if(SEA.throw){ throw e }
|
|
if(cb){ cb() }
|
|
return;
|
|
}});
|
|
|
|
// can this be replaced with settings.jwk?
|
|
var keysToEcdhJwk = (pub, d) => { // d === priv
|
|
//var [ x, y ] = Buffer.from(pub, 'base64').toString('utf8').split(':') // old
|
|
var [ x, y ] = pub.split('.') // new
|
|
var jwk = d ? { d: d } : {}
|
|
return [ // Use with spread returned value...
|
|
'jwk',
|
|
Object.assign(
|
|
jwk,
|
|
{ x: x, y: y, kty: 'EC', crv: 'P-256', ext: true }
|
|
), // ??? refactor
|
|
{name: 'ECDH', namedCurve: 'P-256'}
|
|
]
|
|
}
|
|
|
|
module.exports = SEA.secret;
|
|
|