UNPKG

2.72 kBJavaScriptView Raw
1var fs = require('fs')
2 , libEphemeral = require('./ephemeral')
3 , constants = require('./constants')
4 , libHeader = require('./header')
5 , through = require('through')
6 , assert = require('assert')
7 , bs58 = require('bs58')
8
9function decrypt (inStream, wallet, encryptedSize, noTranslate) {
10 var self = this
11 var outStream = through()
12 var decryptor, hashStream, ephSlice, eph
13 var chunks = []
14 function parseEphemeral (chunk) {
15 chunks.push(chunk)
16 var buf = Buffer.concat(chunks)
17 if (buf.length >= constants.EPH_LENGTH) {
18 ephSlice = buf.slice(0, constants.EPH_LENGTH)
19 chunks = [buf.slice(constants.EPH_LENGTH)]
20 withEphSlice(ephSlice)
21 }
22 }
23 inStream.on('data', parseEphemeral)
24 inStream.once('end', function () {
25 if (!ephSlice) {
26 return outStream.emit('error', new Error('not a salty file'))
27 }
28 })
29 function withEphSlice (buf) {
30 var header
31 var headerStr = ''
32 var ended = false
33 inStream.removeListener('data', parseEphemeral)
34 try {
35 var eph = libEphemeral.parse(buf, wallet)
36 var decryptor = eph.createDecryptor(encryptedSize)
37 var hashStream = eph.createHmac('sha256')
38 }
39 catch (e) {
40 return outStream.emit('error', e)
41 }
42 var tail
43 hashStream.once('data', withHash)
44 outStream.pipe(hashStream)
45 function withHash (hash) {
46 try {
47 assert(tail)
48 header = libHeader.parse(headerStr, noTranslate).validate(hash).toObject()
49 if (header['to-salty-id'] === 'self') {
50 if (header['from-salty-id'] !== wallet.pubkey.pubkey) {
51 return outStream.emit('error', new Error('to-salty-id is self, not addressed to you'))
52 }
53 }
54 else if (header['to-salty-id'] && header['to-salty-id'] !== wallet.pubkey.pubkey) {
55 return outStream.emit('error', new Error('to-salty-id is not addressed to you'))
56 }
57 outStream.emit('header', header)
58 }
59 catch (e) {
60 return outStream.emit('error', e)
61 }
62 }
63 var bytesDecrypted = 0
64 var parserStream = through(function write (chunk) {
65 if (bytesDecrypted + chunk.length < eph.totalSize) {
66 this.queue(chunk)
67 bytesDecrypted += chunk.length
68 }
69 else if (headerStr) {
70 headerStr += chunk.toString()
71 }
72 else {
73 tail = chunk.slice(0, eph.totalSize - bytesDecrypted)
74 if (tail.length) this.queue(tail)
75 bytesDecrypted += tail.length
76 headerStr = chunk.slice(tail.length).toString()
77 }
78 })
79 decryptor.pipe(parserStream).pipe(outStream)
80 var head = Buffer.concat(chunks)
81 decryptor.write(head)
82 inStream.pipe(decryptor)
83 }
84 return outStream
85}
86module.exports = decrypt
\No newline at end of file