UNPKG

2.69 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
8function decrypt (inStream, wallet, encryptedSize) {
9 var self = this
10 var outStream = through()
11 var decryptor, hashStream, ephSlice, eph
12 var chunks = []
13 function parseEphemeral (chunk) {
14 chunks.push(chunk)
15 var buf = Buffer.concat(chunks)
16 if (buf.length >= constants.EPH_LENGTH) {
17 ephSlice = buf.slice(0, constants.EPH_LENGTH)
18 chunks = [buf.slice(constants.EPH_LENGTH)]
19 withEphSlice(ephSlice)
20 }
21 }
22 inStream.on('data', parseEphemeral)
23 inStream.once('end', function () {
24 if (!ephSlice) {
25 return outStream.emit('error', new Error('not a salty file'))
26 }
27 })
28 function withEphSlice (buf) {
29 var header
30 var headerStr = ''
31 var ended = false
32 inStream.removeListener('data', parseEphemeral)
33 try {
34 var eph = libEphemeral.parse(buf, wallet)
35 var decryptor = eph.createDecryptor(encryptedSize)
36 var hashStream = eph.createHmac()
37 }
38 catch (e) {
39 return outStream.emit('error', e)
40 }
41 var tail
42 hashStream.once('data', withHash)
43 outStream.pipe(hashStream)
44 function withHash (hash) {
45 try {
46 assert(tail)
47 header = libHeader.parse(headerStr).validate(hash).toObject()
48 var me = wallet.pubkey.toBuffer().toString('base64')
49 if (header['to-salty-id'] === 'self') {
50 if (header['from-salty-id'] !== me) {
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'] !== me) {
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