fei.wang
10 天以前 ae7b22322555448d95fd56f505bafa325c167a26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
'use strict';
 
var Buffer = require('safe-buffer').Buffer;
var Transform = require('stream').Transform;
var StringDecoder = require('string_decoder').StringDecoder;
var inherits = require('inherits');
 
function CipherBase(hashMode) {
    Transform.call(this);
    this.hashMode = typeof hashMode === 'string';
    if (this.hashMode) {
        this[hashMode] = this._finalOrDigest;
    } else {
        this['final'] = this._finalOrDigest;
    }
    if (this._final) {
        this.__final = this._final;
        this._final = null;
    }
    this._decoder = null;
    this._encoding = null;
}
inherits(CipherBase, Transform);
 
var useUint8Array = typeof Uint8Array !== 'undefined';
var useArrayBuffer = typeof ArrayBuffer !== 'undefined'
    && typeof Uint8Array !== 'undefined'
    && ArrayBuffer.isView
    && (Buffer.prototype instanceof Uint8Array || Buffer.TYPED_ARRAY_SUPPORT);
 
function toBuffer(data, encoding) {
    /*
     * No need to do anything for exact instance
     * This is only valid when safe-buffer.Buffer === buffer.Buffer, i.e. when Buffer.from/Buffer.alloc existed
     */
    if (data instanceof Buffer) {
        return data;
    }
 
    // Convert strings to Buffer
    if (typeof data === 'string') {
        return Buffer.from(data, encoding);
    }
 
    /*
     * Wrap any TypedArray instances and DataViews
     * Makes sense only on engines with full TypedArray support -- let Buffer detect that
     */
    if (useArrayBuffer && ArrayBuffer.isView(data)) {
        // Bug in Node.js <6.3.1, which treats this as out-of-bounds
        if (data.byteLength === 0) {
            return Buffer.alloc(0);
        }
 
        var res = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
        /*
         * Recheck result size, as offset/length doesn't work on Node.js <5.10
         * We just go to Uint8Array case if this fails
         */
        if (res.byteLength === data.byteLength) {
            return res;
        }
    }
 
    /*
     * Uint8Array in engines where Buffer.from might not work with ArrayBuffer, just copy over
     * Doesn't make sense with other TypedArray instances
     */
    if (useUint8Array && data instanceof Uint8Array) {
        return Buffer.from(data);
    }
 
    /*
     * Old Buffer polyfill on an engine that doesn't have TypedArray support
     * Also, this is from a different Buffer polyfill implementation then we have, as instanceof check failed
     * Convert to our current Buffer implementation
     */
    if (
        Buffer.isBuffer(data)
            && data.constructor
            && typeof data.constructor.isBuffer === 'function'
            && data.constructor.isBuffer(data)
    ) {
        return Buffer.from(data);
    }
 
    throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView.');
}
 
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
    var bufferData = toBuffer(data, inputEnc); // asserts correct input type
    var outData = this._update(bufferData);
    if (this.hashMode) {
        return this;
    }
 
    if (outputEnc) {
        outData = this._toString(outData, outputEnc);
    }
 
    return outData;
};
 
CipherBase.prototype.setAutoPadding = function () {};
CipherBase.prototype.getAuthTag = function () {
    throw new Error('trying to get auth tag in unsupported state');
};
 
CipherBase.prototype.setAuthTag = function () {
    throw new Error('trying to set auth tag in unsupported state');
};
 
CipherBase.prototype.setAAD = function () {
    throw new Error('trying to set aad in unsupported state');
};
 
CipherBase.prototype._transform = function (data, _, next) {
    var err;
    try {
        if (this.hashMode) {
            this._update(data);
        } else {
            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;
    }
 
    done(err);
};
CipherBase.prototype._finalOrDigest = function (outputEnc) {
    var outData = this.__final() || Buffer.alloc(0);
    if (outputEnc) {
        outData = this._toString(outData, outputEnc, true);
    }
    return outData;
};
 
CipherBase.prototype._toString = function (value, enc, fin) {
    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 (fin) {
        out += this._decoder.end();
    }
 
    return out;
};
 
module.exports = CipherBase;