1 | var assert = require('assert')
|
2 | , fs = require('fs')
|
3 | , path = require('path')
|
4 | , crypto = require('crypto')
|
5 | , rimraf = require('rimraf')
|
6 | , child_process = require('child_process')
|
7 | , suppose = require('suppose')
|
8 | , tmpDir = path.join(require('os').tmpDir(), Math.random().toString(36).slice(2))
|
9 | , BIN = path.join(__dirname, '..', 'bin', 'salty')
|
10 | , request = require('micro-request')
|
11 |
|
12 | describe('tests', function () {
|
13 | var p = path.join(tmpDir, 'alice.jpg')
|
14 |
|
15 | before(function () {
|
16 | fs.mkdirSync(tmpDir)
|
17 | if (!process.env.DEBUG) {
|
18 | process.once('exit', function () {
|
19 | rimraf.sync(tmpDir)
|
20 | })
|
21 | }
|
22 | else console.log('tmpDir', tmpDir)
|
23 | })
|
24 |
|
25 | it('stream fixture', function (done) {
|
26 | request('https://raw.githubusercontent.com/carlos8f/node-buffet/master/test/files/folder/Alice-white-rabbit.jpg', {stream: true}, function (err, resp, body) {
|
27 | assert.ifError(err)
|
28 | body.pipe(fs.createWriteStream(p))
|
29 | .once('finish', done)
|
30 | })
|
31 | })
|
32 | it('verify stream fixture', function (done) {
|
33 | fs.createReadStream(p)
|
34 | .pipe(crypto.createHash('sha1'))
|
35 | .on('data', function (data) {
|
36 | assert.equal(data.toString('hex'), '2bce2ffc40e0d90afe577a76db5db4290c48ddf4')
|
37 | done()
|
38 | })
|
39 | })
|
40 | it('set up alice', function (done) {
|
41 | suppose(BIN, ['init', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
42 | .when('Creating wallet...\nYour name: ').respond('Alice\n')
|
43 | .when('Your email address: ').respond('alice@s8f.org\n')
|
44 | .when('Create a passphrase: ').respond('disney sucks\n')
|
45 | .when('Verify passphrase: ').respond('disney sucks\n')
|
46 | .end(function (code) {
|
47 | assert(!code)
|
48 | done()
|
49 | })
|
50 | })
|
51 | it('set up bob', function (done) {
|
52 | suppose(BIN, ['init', '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
53 | .when('Creating wallet...\nYour name: ').respond('Bob\n')
|
54 | .when('Your email address: ').respond('bob@s8f.org\n')
|
55 | .when('Create a passphrase: ').respond('i am bob\n')
|
56 | .when('Verify passphrase: ').respond('i am bob\n')
|
57 | .end(function (code) {
|
58 | assert(!code)
|
59 | done()
|
60 | })
|
61 | })
|
62 | var alice_pubkey
|
63 | it('alice pubkey', function (done) {
|
64 | var chunks = []
|
65 | suppose(BIN, ['pubkey', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
66 | .end(function (code) {
|
67 | assert(!code)
|
68 | })
|
69 | .stdout.on('data', function (chunk) {
|
70 | chunks.push(chunk)
|
71 | })
|
72 | .once('end', function () {
|
73 | var stdout = Buffer.concat(chunks).toString('utf8')
|
74 | var match = stdout.match(/salty\-id ([a-zA-Z0-9-\_]+)\s*(?:"([^"]*)")?\s*(?:<([^>]*)>)?/)
|
75 | assert(match)
|
76 | alice_pubkey = match[0]
|
77 | done()
|
78 | })
|
79 | })
|
80 | it('alice change password', function (done) {
|
81 | suppose(BIN, ['init', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
82 | .when('Wallet exists. Update it? (y/n): ').respond('y\n')
|
83 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('disney sucks\n')
|
84 | .when('Your name: (Alice) ').respond('\n')
|
85 | .when('Your email address: (alice@s8f.org) ').respond('\n')
|
86 | .when('Create a passphrase: ').respond('not a blonde\n')
|
87 | .when('Verify passphrase: ').respond('not a blonde\n')
|
88 | .end(function (code) {
|
89 | assert(!code)
|
90 | done()
|
91 | })
|
92 | })
|
93 | var bob_pubkey
|
94 | it('bob pubkey', function (done) {
|
95 | var chunks = []
|
96 | suppose(BIN, ['pubkey', '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
97 | .end(function (code) {
|
98 | assert(!code)
|
99 | })
|
100 | .stdout.on('data', function (chunk) {
|
101 | chunks.push(chunk)
|
102 | })
|
103 | .once('end', function () {
|
104 | var stdout = Buffer.concat(chunks).toString('utf8')
|
105 | var match = stdout.match(/salty\-id ([a-zA-Z0-9-\_]+)\s*(?:"([^"]*)")?\s*(?:<([^>]*)>)?/)
|
106 | assert(match)
|
107 | bob_pubkey = match[0]
|
108 | done()
|
109 | })
|
110 | })
|
111 | it('alice import bob', function (done) {
|
112 | var chunks = []
|
113 | var proc = suppose(BIN, ['import', '--wallet', 'alice', bob_pubkey], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
114 | .when('Enter name: (Bob) ').respond('\n')
|
115 | .when('Enter email: (bob@s8f.org) ').respond('\n')
|
116 | .end(function (code) {
|
117 | assert(!code)
|
118 | done()
|
119 | })
|
120 | })
|
121 | it('alice ls', function (done) {
|
122 | var chunks = []
|
123 | suppose(BIN, ['ls', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
124 | .end(function (code) {
|
125 | assert(!code)
|
126 | })
|
127 | .stdout.on('data', function (chunk) {
|
128 | chunks.push(chunk)
|
129 | })
|
130 | .once('end', function () {
|
131 | var stdout = Buffer.concat(chunks).toString('utf8')
|
132 | var match = stdout.match(/salty\-id ([a-zA-Z0-9-\_]+)\s*(?:"([^"]*)")?\s*(?:<([^>]*)>)?/g)
|
133 | assert.equal(match.length, 1)
|
134 | assert.equal(match[0], bob_pubkey)
|
135 | done()
|
136 | })
|
137 | })
|
138 | it('alice save', function (done) {
|
139 | var chunks = []
|
140 | var proc = suppose(BIN, ['save', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
141 | .when('Create a passphrase: ').respond('blarg\n')
|
142 | .when('Verify passphrase: ').respond('blarg\n')
|
143 | .end(function (code) {
|
144 | assert(!code)
|
145 | done()
|
146 | })
|
147 | })
|
148 | it('alice destroy', function () {
|
149 | rimraf.sync(path.join(tmpDir, 'alice'))
|
150 | })
|
151 | it('alice restore', function (done) {
|
152 | var chunks = []
|
153 | var proc = suppose(BIN, ['restore', 'salty.pem', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
154 | .when('Enter passphrase: ').respond('blarg\n')
|
155 | .end(function (code) {
|
156 | assert(!code)
|
157 | done()
|
158 | })
|
159 | })
|
160 | var outFile
|
161 | it('alice encrypt for bob (no sign)', function (done) {
|
162 | var chunks = []
|
163 | var proc = suppose(BIN, ['encrypt', '--to', 'bob@s8f.org', 'alice.jpg', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
164 | .end(function (code) {
|
165 | assert(!code)
|
166 | })
|
167 | .stdout.on('data', function (chunk) {
|
168 | chunks.push(chunk)
|
169 | })
|
170 | .once('end', function () {
|
171 | var stdout = Buffer.concat(chunks).toString('utf8')
|
172 | var match = stdout.match(/Encrypted to (.*)/)
|
173 | assert(match)
|
174 | outFile = match[1]
|
175 | done()
|
176 | })
|
177 | })
|
178 | it('bob decrypt', function (done) {
|
179 | var proc = suppose(BIN, ['decrypt', outFile, '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
180 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('i am bob\n')
|
181 | .end(function (code) {
|
182 | assert(!code)
|
183 | done()
|
184 | })
|
185 | })
|
186 | it('verify decrypt', function (done) {
|
187 | fs.createReadStream(path.join(tmpDir, outFile.replace('.salty', '')))
|
188 | .pipe(crypto.createHash('sha1'))
|
189 | .on('data', function (data) {
|
190 | assert.equal(data.toString('hex'), '2bce2ffc40e0d90afe577a76db5db4290c48ddf4')
|
191 | done()
|
192 | })
|
193 | })
|
194 | it('alice encrypt for bob (sign)', function (done) {
|
195 | var chunks = []
|
196 | var proc = suppose(BIN, ['encrypt', '--to', 'bob@s8f.org', 'alice.jpg', '--sign', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
197 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('not a blonde\n')
|
198 | .end(function (code) {
|
199 | assert(!code)
|
200 | })
|
201 | .stdout.on('data', function (chunk) {
|
202 | chunks.push(chunk)
|
203 | })
|
204 | .once('end', function () {
|
205 | var stdout = Buffer.concat(chunks).toString('utf8')
|
206 | var match = stdout.match(/Encrypted to (.*)/)
|
207 | assert(match)
|
208 | assert(match[1] !== outFile)
|
209 | outFile = match[1]
|
210 | done()
|
211 | })
|
212 | })
|
213 | it('bob decrypt', function (done) {
|
214 | var proc = suppose(BIN, ['decrypt', outFile, '--sig', '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
215 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('i am bob\n')
|
216 | .end(function (code) {
|
217 | assert(!code)
|
218 | done()
|
219 | })
|
220 | })
|
221 | it('verify decrypt', function (done) {
|
222 | fs.createReadStream(path.join(tmpDir, outFile.replace('.salty', '')))
|
223 | .pipe(crypto.createHash('sha1'))
|
224 | .on('data', function (data) {
|
225 | assert.equal(data.toString('hex'), '2bce2ffc40e0d90afe577a76db5db4290c48ddf4')
|
226 | done()
|
227 | })
|
228 | })
|
229 | it('stream fixture', function (done) {
|
230 | request('https://gist.githubusercontent.com/carlos8f/a3fd03a48341e36bd2d1/raw/bc01eeaf1b664f79bf4de9c917ac87f94a291a76/jabberwocky.txt', {stream: true}, function (err, resp, body) {
|
231 | assert.ifError(err)
|
232 | body.pipe(fs.createWriteStream(path.join(tmpDir, 'jabberwocky.txt')))
|
233 | .once('finish', done)
|
234 | })
|
235 | })
|
236 | it('verify stream fixture', function (done) {
|
237 | fs.createReadStream(path.join(tmpDir, 'jabberwocky.txt'))
|
238 | .pipe(crypto.createHash('sha1'))
|
239 | .on('data', function (data) {
|
240 | assert.equal(data.toString('hex'), '24a80c902db33368958664babde4b019cdaa65f0')
|
241 | done()
|
242 | })
|
243 | })
|
244 | var pem
|
245 | it('alice encrypt for bob (armor)', function (done) {
|
246 | var chunks = []
|
247 | var proc = suppose(BIN, ['encrypt', '--to', 'bob@s8f.org', 'jabberwocky.txt', '--sign', '--armor', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
248 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('not a blonde\n')
|
249 | .end(function (code) {
|
250 | assert(!code)
|
251 | })
|
252 | .stdout.on('data', function (chunk) {
|
253 | chunks.push(chunk)
|
254 | })
|
255 | .once('end', function () {
|
256 | var stdout = Buffer.concat(chunks).toString('utf8')
|
257 | assert(stdout.match(/BEGIN SALTY MESSAGE/))
|
258 | assert(stdout.match(/END SALTY MESSAGE/))
|
259 | pem = stdout
|
260 | done()
|
261 | })
|
262 | })
|
263 | it('write pem to file', function (done) {
|
264 | fs.writeFile(path.join(tmpDir, 'ctxt.pem'), pem, done)
|
265 | })
|
266 | var stdout
|
267 | it('bob decrypt', function (done) {
|
268 | var chunks = [], valid = false
|
269 | var proc = suppose(BIN, ['decrypt', 'ctxt.pem', '--sig', '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
270 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('i am bob\n')
|
271 | .end(function (code) {
|
272 | assert(!code)
|
273 | assert(stdout)
|
274 | assert(valid)
|
275 | done()
|
276 | })
|
277 | .stdout.on('data', function (chunk) {
|
278 | chunks.push(chunk)
|
279 | })
|
280 | .once('end', function () {
|
281 | stdout = Buffer.concat(chunks).toString('utf8')
|
282 | var beginMatch = stdout.match(/^'Twas brillig, and the slithy toves/)
|
283 | assert(beginMatch, stdout)
|
284 | var endMatch = stdout.match(/And the mome raths outgrabe\.$/)
|
285 | assert(endMatch, stdout)
|
286 | valid = true
|
287 | })
|
288 | })
|
289 | var msg
|
290 | it('alice encrypt for bob (compose)', function (done) {
|
291 | var chunks = [], valid = false
|
292 | msg = 'Hi,\n\nThis is my message...\n\nRegards,\Alice\n'
|
293 | var proc = suppose(BIN, ['encrypt', '--to', 'bob@s8f.org', '--sign', '--message', '--wallet', 'alice'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
294 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('not a blonde\n')
|
295 | .when('\nCompose message: (CTL-D when done)\n\n> ').respond(msg + '\4')
|
296 | .end(function (code) {
|
297 | assert(!code)
|
298 | assert(valid)
|
299 | done()
|
300 | })
|
301 | .stdout.on('data', function (chunk) {
|
302 | chunks.push(chunk)
|
303 | })
|
304 | .once('end', function () {
|
305 | var stdout = Buffer.concat(chunks).toString('utf8')
|
306 | assert(stdout.match(/BEGIN SALTY MESSAGE/))
|
307 | assert(stdout.match(/END SALTY MESSAGE/))
|
308 | pem = stdout
|
309 | valid = true
|
310 | })
|
311 | })
|
312 | it('write pem to file', function (done) {
|
313 | fs.writeFile(path.join(tmpDir, 'ctxt.pem'), pem, done)
|
314 | })
|
315 | it('bob decrypt', function (done) {
|
316 | var chunks = [], valid = false
|
317 | var proc = suppose(BIN, ['decrypt', 'ctxt.pem', '--sig', '--wallet', 'bob'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
318 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('i am bob\n')
|
319 | .end(function (code) {
|
320 | assert(!code)
|
321 | assert(stdout)
|
322 | assert(valid)
|
323 | done()
|
324 | })
|
325 | .stdout.on('data', function (chunk) {
|
326 | chunks.push(chunk)
|
327 | })
|
328 | .once('end', function () {
|
329 | stdout = Buffer.concat(chunks).toString('utf8')
|
330 | assert.deepEqual(stdout, msg)
|
331 | valid = true
|
332 | })
|
333 | })
|
334 | it('alice sign', function (done) {
|
335 | var chunks = [], valid = false
|
336 | msg = 'Hi,\n\nThis is my message...\n\nRegards,\Alice\n'
|
337 | var proc = suppose(BIN, ['sign', '--wallet', 'alice', 'alice.jpg'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
338 | .when('Wallet is encrypted.\nEnter passphrase: ').respond('not a blonde\n')
|
339 | .end(function (code) {
|
340 | assert(!code)
|
341 | assert(valid)
|
342 | done()
|
343 | })
|
344 | .stdout.on('data', function (chunk) {
|
345 | chunks.push(chunk)
|
346 | })
|
347 | .once('end', function () {
|
348 | var stdout = Buffer.concat(chunks).toString('utf8')
|
349 | var match = stdout.match(/Wrote signature to alice\.jpg\.salty-sig/)
|
350 | assert(match)
|
351 | valid = true
|
352 | })
|
353 | })
|
354 | var stderr
|
355 | it('bob verify', function (done) {
|
356 | var chunks = [], valid = false
|
357 | var proc = suppose(BIN, ['verify', 'alice.jpg'], {cwd: tmpDir, debug: fs.createWriteStream('/tmp/debug.txt')})
|
358 | .end(function (code) {
|
359 | assert(!code)
|
360 | assert(stdout)
|
361 | assert(valid)
|
362 | done()
|
363 | })
|
364 | .stderr.on('data', function (chunk) {
|
365 | chunks.push(chunk)
|
366 | })
|
367 | .once('end', function () {
|
368 | stderr = Buffer.concat(chunks).toString('utf8')
|
369 | var match = stderr.match(/signature:\s*OK/)
|
370 | assert(match)
|
371 | valid = true
|
372 | })
|
373 | })
|
374 |
|
375 | |
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 | }) |
\ | No newline at end of file |