UNPKG

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