Skip to content

Commit

Permalink
Update module
Browse files Browse the repository at this point in the history
  • Loading branch information
fanatid committed Apr 17, 2016
1 parent f7dd8dd commit f6c8fef
Showing 1 changed file with 163 additions and 63 deletions.
226 changes: 163 additions & 63 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,190 @@
'use strict'
var Transform = require('stream').Transform
var inherits = require('inherits')
var StringDecoder = require('string_decoder').StringDecoder
module.exports = CipherBase
inherits(CipherBase, Transform)
function CipherBase (hashMode) {

exports.CipherBase = CipherBase
exports.CipherivBase = CipherivBase
exports.DecipherBase = DecipherBase
exports.DecipherivBase = DecipherivBase

var K_CIPHER = 0
var K_DECIPHER = 1

function throwIfNotStringOrBuffer (val, prefix) {
if (!Buffer.isBuffer(val) && typeof val !== 'string') throw new TypeError(prefx + ' must be a string or a buffer')
}

function throwIfNotBuffer (val, prefix) {
if (!Buffer.isBuffer(val)) throw new TypeError(prefix + ' must be a buffer')
}

function getDecoder (decoder, encoding) {
if (encoding === 'utf-8') encoding = 'utf8'
decoder = decoder || new StringDecoder(encoding)
if (decoder.encoding !== encoding) throw new Error('Cannot change encoding')
return decoder
}

function toBuf (str, prefix) {
throwIfNotStringOrBuffer(str, prefix)
if (typeof str === 'string') return new Buffer(str, 'utf8')
else return str
}

function CipherBase (cipher, password) {
Transform.call(this)
this.hashMode = typeof hashMode === 'string'
if (this.hashMode) {
this[hashMode] = this._finalOrDigest
} else {
this.final = this._finalOrDigest
}

this._kind = K_CIPHER
this._authTag = null
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
this._finalized = false

this._init(toBuf(cipher, 'Cipher type'), toBuf(password, 'Password'))
}

CipherBase.prototype.setAutoPadding = function () {}
inherits(CipherBase, Transform)

CipherBase.prototype.getAuthTag = function () {
throw new Error('trying to get auth tag in unsupported state')
CipherBase.prototype._init = function () {
throw new Error('_init is not implemented')
}

CipherBase.prototype.setAuthTag = function () {
throw new Error('trying to set auth tag in unsupported state')
CipherBase.prototype._initiv = function () {
throw new Error('_initiv is not implemented')
}

CipherBase.prototype.setAAD = function () {
throw new Error('trying to set aad in unsupported state')
CipherBase.prototype._isAuthenticatedMode = function () {
throw new Error('_isAuthenticatedMode is not implemented')
}

CipherBase.prototype._transform = function (data, _, next) {
var err
CipherBase.prototype._transform = function (chunk, encoding, callback) {
var error = null
try {
if (this.hashMode) {
this._update(data)
} else {
this.push(this._update(data))
}
} catch (e) {
err = e
} finally {
next(err)
if (encoding !== 'buffer') chunk = new Buffer(chunk, encoding)
this.push(this.update(chunk))
} catch (err) {
error = err
}

callback(error)
}
CipherBase.prototype._flush = function (done) {
var err

CipherBase.prototype._flush = function (callback) {
var error = null
try {
this.push(this._final())
} catch (e) {
err = e
} finally {
done(err)
} catch (err) {
error = err
}

callback(error)
}
CipherBase.prototype._finalOrDigest = function (outputEnc) {
var outData = this._final() || new Buffer('')
if (outputEnc) {
outData = this._toString(outData, outputEnc, true)

CipherBase.prototype.update = function (data, inputEncoding, outputEncoding) {
throwIfNotStringOrBuffer(data, 'Cipher data')
if (this._finalized) throw new Error('Trying to add data in unsupported state')

if (!Buffer.isBuffer(data)) data = new Buffer(data, inputEncoding || 'binary')

data = this._update(data)
if (outputEncoding && outputEncoding !== 'buffer') {
this._decoder = getDecoder(this._decoder, outputEncoding)
data = this._decoder.write(data)
}
return outData
return data
}

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')
CipherBase.prototype._update = function (data) {
throw new Error('_update is not implemented')
}

CipherBase.prototype.final = function (encoding) {
if (this._finalized) {
var msg = this._isAuthenticatedMode()
? 'Unsupported state or unable to authenticate data'
: 'Unsupported state'
throw new Error(msg)
}
var out = this._decoder.write(value)
if (final) {
out += this._decoder.end()
this._finalized = true

var data = this._final()
if (encoding && encoding !== 'buffer') {
this._decoder = getDecoder(this._decoder, encoding)
data = this._decoder.end(data)
}
return out
return data
}

CipherBase.prototype._final = function (data) {
throw new Error('_final is not implemented')
}

CipherBase.prototype.setAAD = function (aadbuf) {
throwIfNotBuffer(aadbuf, 'AAD')
if (!this._isAuthenticatedMode() || this._finalized) throw new Error('Attempting to set AAD in unsupported state')
this._setAAD(aadbuf)
}

CipherBase.prototype._setAAD = function (aadbuf) {
throw new Error('_setAAD is not implemented')
}

CipherBase.prototype.getAuthTag = function () {
// only after final and if encrypting
if (this._kind !== K_CIPHER || this._authTag === null) throw new Error('Attempting to get auth tag in unsupported state')
return new Buffer(this._authTag)
}

CipherBase.prototype.setAuthTag = function (tagbuf) {
if (!Buffer.isBuffer(tagbuf)) throw new TypeError('Not a buffer')
if (!this._isAuthenticatedMode() || this._kind !== K_DECIPHER || this._finalized) throw new Error('Attempting to set auth tag in unsupported state')
this._authTag = new Buffer(tagbuf)
}

CipherBase.prototype.setAutoPadding = function (ap) {
if (this._finalized) throw new Error('Attempting to set auto padding in unsupported state')
this._setAutoPadding(!!ap)
}

CipherBase.prototype._setAutoPadding = function (ap) {
throw new Error('_setAutoPadding is not implemented')
}

function CipherivBase (cipher, password, iv) {
Transform.call(this)

this._kind = K_CIPHER
this._authTag = null
this._decoder = null
this._finalized = false

this._initiv(toBuf(cipher, 'Cipher type'), toBuf(password, 'Password'), toBuf(iv, 'IV'))
}

inherits(CipherivBase, Transform)

function DecipherBase (cipher, password, iv) {
Transform.call(this)

this._kind = K_DECIPHER
this._authTag = null
this._decoder = null
this._finalized = false

this._init(toBuf(cipher, 'Cipher type'), toBuf(password, 'Password'))
}

inherits(DecipherBase, Transform)

function DecipherivBase (cipher, password, iv) {
Transform.call(this)

this._kind = K_DECIPHER
this._authTag = null
this._decoder = null
this._finalized = false

this._initiv(toBuf(cipher, 'Cipher type'), toBuf(password, 'Password'), toBuf(iv, 'IV'))
}

inherits(DecipherivBase, Transform)

0 comments on commit f6c8fef

Please sign in to comment.