mirror of
https://github.com/darkwire/darkwire.io.git
synced 2025-07-18 02:44:01 +00:00
123 lines
3.3 KiB
JavaScript
123 lines
3.3 KiB
JavaScript
import Crypto from './crypto'
|
|
|
|
const crypto = new Crypto()
|
|
|
|
export const process = (payload, state) => new Promise(async (resolve, reject) => {
|
|
const privateKeyJson = state.user.privateKey
|
|
const privateKey = await crypto.importEncryptDecryptKey(privateKeyJson, 'jwk', ['decrypt', 'unwrapKey'])
|
|
|
|
let sessionKey
|
|
let signingKey
|
|
|
|
const iv = await crypto.convertStringToArrayBufferView(payload.iv)
|
|
const signature = await crypto.convertStringToArrayBufferView(payload.signature)
|
|
const payloadBuffer = await crypto.convertStringToArrayBufferView(payload.payload)
|
|
|
|
await new Promise((resolvePayload) => {
|
|
payload.keys.forEach(async (key) => {
|
|
try {
|
|
sessionKey = await crypto.unwrapKey(
|
|
'jwk',
|
|
key.sessionKey,
|
|
privateKey,
|
|
{
|
|
name: 'RSA-OAEP',
|
|
hash: { name: 'SHA-1' },
|
|
},
|
|
{ name: 'AES-CBC' },
|
|
true,
|
|
['decrypt']
|
|
)
|
|
|
|
signingKey = await crypto.unwrapKey(
|
|
'jwk',
|
|
key.signingKey,
|
|
privateKey,
|
|
{
|
|
name: 'RSA-OAEP',
|
|
hash: { name: 'SHA-1' },
|
|
},
|
|
{ name: 'HMAC', hash: { name: 'SHA-256' } },
|
|
true,
|
|
['verify']
|
|
)
|
|
resolvePayload()
|
|
} catch (e) { } // eslint-disable-line
|
|
})
|
|
})
|
|
|
|
const verified = await crypto.verifyPayload(
|
|
signature,
|
|
payloadBuffer,
|
|
signingKey
|
|
)
|
|
|
|
if (!verified) {
|
|
reject()
|
|
return
|
|
}
|
|
|
|
const decryptedPayload = await crypto.decryptMessage(
|
|
payloadBuffer,
|
|
sessionKey,
|
|
iv
|
|
)
|
|
|
|
const payloadJson = JSON.parse(crypto.convertArrayBufferViewToString(new Uint8Array(decryptedPayload)))
|
|
|
|
resolve(payloadJson)
|
|
})
|
|
|
|
export const prepare = (payload, state) => new Promise(async (resolve) => {
|
|
const myUsername = state.user.username
|
|
const myId = state.user.id
|
|
|
|
const sessionKey = await crypto.createSecretKey()
|
|
const signingKey = await crypto.createSigningKey()
|
|
const iv = await crypto.crypto.getRandomValues(new Uint8Array(16))
|
|
|
|
const jsonToSend = {
|
|
...payload,
|
|
payload: {
|
|
...payload.payload,
|
|
sender: myId,
|
|
username: myUsername,
|
|
text: encodeURI(payload.payload.text),
|
|
},
|
|
}
|
|
|
|
const payloadBuffer = crypto.convertStringToArrayBufferView(JSON.stringify(jsonToSend))
|
|
|
|
const encryptedPayload = await crypto.encryptMessage(payloadBuffer, sessionKey, iv)
|
|
const payloadString = await crypto.convertArrayBufferViewToString(new Uint8Array(encryptedPayload))
|
|
|
|
const signature = await crypto.signMessage(encryptedPayload, signingKey)
|
|
|
|
const encryptedKeys = await Promise.all(state.room.members
|
|
.map(async (member) => {
|
|
const key = await crypto.importEncryptDecryptKey(member.publicKey)
|
|
const enc = await Promise.all([
|
|
crypto.wrapKey(sessionKey, key),
|
|
crypto.wrapKey(signingKey, key),
|
|
])
|
|
return {
|
|
sessionKey: enc[0],
|
|
signingKey: enc[1],
|
|
}
|
|
})
|
|
)
|
|
|
|
const ivString = await crypto.convertArrayBufferViewToString(new Uint8Array(iv))
|
|
const signatureString = await crypto.convertArrayBufferViewToString(new Uint8Array(signature))
|
|
|
|
resolve({
|
|
toSend: {
|
|
payload: payloadString,
|
|
signature: signatureString,
|
|
iv: ivString,
|
|
keys: encryptedKeys,
|
|
},
|
|
original: jsonToSend,
|
|
})
|
|
})
|