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 | , libSalty = require('../')
|
12 |
|
13 | describe('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 |
|
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 |
|
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 |
|
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 | |
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 |
|
402 | }) |
\ | No newline at end of file |