-
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8fbd9e7
Showing
5 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": ["standard"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
var Transform = require('stream').Transform | ||
var inherits = require('inherits') | ||
var StringDecoder = require('string_decoder').StringDecoder | ||
module.exports = CipherBase | ||
inherits(CipherBase, Transform) | ||
function CipherBase (hashMode) { | ||
Transform.call(this) | ||
this.hashMode = typeof hashMode === 'string'; | ||
if (this.hashMode) { | ||
this[hashMode] = this._finalOrDigest | ||
} else { | ||
this.final = this._finalOrDigest | ||
} | ||
this._decoder = null | ||
this._encoding = null | ||
} | ||
CipherBase.prototype.update = function (data, inputEnc, outputEnc) { | ||
if (typeof data === 'string') { | ||
data = new Buffer(data, inputEnc) | ||
} | ||
var outData = this._update(data) | ||
if (this.hashMode) { | ||
return this | ||
} | ||
if (outputEnc) { | ||
outData = this._toString(outData, outputEnc) | ||
} | ||
return outData | ||
} | ||
CipherBase.prototype._transform = function (data, _, next) { | ||
var err | ||
try { | ||
this.push(this._update(data)) | ||
} catch (e) { | ||
err = e | ||
} finally { | ||
next(err) | ||
} | ||
} | ||
CipherBase.prototype._flush = function (done) { | ||
var err | ||
try { | ||
this.push(this._final()) | ||
} catch (e) { | ||
err = e | ||
} finally { | ||
done(err) | ||
} | ||
} | ||
CipherBase.prototype._finalOrDigest = function (outputEnc) { | ||
var outData = this._final() || new Buffer('') | ||
if (outputEnc) { | ||
outData = this._toString(outData, outputEnc, true) | ||
} | ||
return outData | ||
} | ||
|
||
CipherBase.prototype._toString = function (value, enc, final) { | ||
if (!this._decoder) { | ||
this._decoder = new StringDecoder(enc) | ||
this._encoding = enc | ||
} | ||
if (this._encoding !== enc) { | ||
throw new Error('can\'t switch encodings') | ||
} | ||
var out = this._decoder.write(value) | ||
if (final) { | ||
out += this._decoder.end() | ||
} | ||
return out | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "cipher-base", | ||
"version": "1.0.0", | ||
"description": "abstract base class for crypto-streams", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node test.js | tspec" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/crypto-browserify/cipher-base.git" | ||
}, | ||
"keywords": [ | ||
"cipher", | ||
"stream" | ||
], | ||
"author": "Calvin Metcalf <[email protected]>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/crypto-browserify/cipher-base/issues" | ||
}, | ||
"homepage": "https://github.com/crypto-browserify/cipher-base#readme", | ||
"dependencies": { | ||
"inherits": "^2.0.1" | ||
}, | ||
"devDependencies": { | ||
"tap-spec": "^4.1.0", | ||
"tape": "^4.2.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
cipher-base | ||
=== | ||
|
||
Abstract base class to inherit from if you want to create streams implementing | ||
the same api as node crypto streams. | ||
|
||
Requires you to implement 2 methods `_final` and `_update`. `_final` takes a | ||
buffer and should return a buffer, `_final` takes no arguments and should return | ||
a buffer. | ||
|
||
|
||
The constructor takes one argument and that is a string which if present switches | ||
it into hash mode, i.e. the object you get from crypto.createHash or | ||
crypto.createSign, this switches the name of the final method to be the string | ||
you passed instead of `final` and returns `this` from update. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
var test = require('tape') | ||
var CipherBase = require('./') | ||
var inherits = require('inherits') | ||
|
||
test('basic version', function (t) { | ||
inherits(Cipher, CipherBase) | ||
function Cipher () { | ||
CipherBase.call(this) | ||
} | ||
Cipher.prototype._update = function (input) { | ||
t.ok(Buffer.isBuffer(input)) | ||
return input | ||
} | ||
Cipher.prototype._final = function () { | ||
// noop | ||
} | ||
var cipher = new Cipher() | ||
var utf8 = 'abc123abcd' | ||
var update = cipher.update(utf8, 'utf8', 'base64') + cipher.final('base64') | ||
var string = (new Buffer(update, 'base64')).toString() | ||
t.equals(utf8, string) | ||
t.end() | ||
}) | ||
test('hash mode', function (t) { | ||
inherits(Cipher, CipherBase) | ||
function Cipher () { | ||
CipherBase.call(this, 'finalName') | ||
this._cache = [] | ||
} | ||
Cipher.prototype._update = function (input) { | ||
t.ok(Buffer.isBuffer(input)) | ||
this._cache.push(input) | ||
} | ||
Cipher.prototype._final = function () { | ||
return Buffer.concat(this._cache) | ||
} | ||
var cipher = new Cipher() | ||
var utf8 = 'abc123abcd' | ||
var update = cipher.update(utf8, 'utf8').finalName('base64') | ||
var string = (new Buffer(update, 'base64')).toString() | ||
|
||
t.equals(utf8, string) | ||
t.end() | ||
}) | ||
test('encodings', function (t) { | ||
inherits(Cipher, CipherBase) | ||
function Cipher () { | ||
CipherBase.call(this) | ||
} | ||
Cipher.prototype._update = function (input) { | ||
return input | ||
} | ||
Cipher.prototype._final = function () { | ||
// noop | ||
} | ||
t.test('mix and match encoding', function (t) { | ||
t.plan(2) | ||
|
||
var cipher = new Cipher() | ||
cipher.update('foo', 'utf8', 'utf8') | ||
t.throws(function () { | ||
cipher.update('foo', 'utf8', 'base64') | ||
}) | ||
cipher = new Cipher() | ||
cipher.update('foo', 'utf8', 'base64') | ||
t.doesNotThrow(function () { | ||
cipher.update('foo', 'utf8') | ||
cipher.final('base64') | ||
}) | ||
}) | ||
t.test('handle long uft8 plaintexts', function (t) { | ||
t.plan(1) | ||
var txt = 'ふっかつ あきる すぶり はやい つける まゆげ たんさん みんぞく ねほりはほり せまい たいまつばな ひはん' | ||
|
||
var cipher = new Cipher() | ||
var decipher = new Cipher() | ||
var enc = decipher.update(cipher.update(txt, 'utf8', 'base64'), 'base64', 'utf8') | ||
enc += decipher.update(cipher.final('base64'), 'base64', 'utf8') | ||
enc += decipher.final('utf8') | ||
|
||
t.equals(txt, enc) | ||
}) | ||
}) |