mirror of
https://github.com/crazy-max/ghaction-import-gpg.git
synced 2024-11-05 21:25:50 -05:00
OpenPGP.js v5 (#78)
* Bump path-parse from 1.0.6 to 1.0.7 (#104) Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7. - [Release notes](https://github.com/jbgutierrez/path-parse/releases) - [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7) --- updated-dependencies: - dependency-name: path-parse dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * OpenPGP.js 5.0.0 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
1c6a9e9d35
commit
e8a90f2bec
45 changed files with 2088 additions and 47967 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,13 +1,6 @@
|
||||||
/.dev
|
/.dev
|
||||||
/lib
|
node_modules/
|
||||||
/node_modules/*
|
lib
|
||||||
|
|
||||||
# Fix https://github.com/crazy-max/ghaction-import-gpg/issues/9
|
|
||||||
!/node_modules/asn1.js/
|
|
||||||
!/node_modules/bn.js/
|
|
||||||
!/node_modules/inherits/
|
|
||||||
!/node_modules/safer-buffer/
|
|
||||||
!/node_modules/minimalistic-assert/
|
|
||||||
|
|
||||||
# Jetbrains
|
# Jetbrains
|
||||||
/.idea
|
/.idea
|
||||||
|
|
42948
dist/index.js
generated
vendored
42948
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
27
node_modules/asn1.js/.eslintrc.js
generated
vendored
27
node_modules/asn1.js/.eslintrc.js
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
'env': {
|
|
||||||
'browser': false,
|
|
||||||
'commonjs': true,
|
|
||||||
'es6': true,
|
|
||||||
'node': true
|
|
||||||
},
|
|
||||||
'extends': 'eslint:recommended',
|
|
||||||
'rules': {
|
|
||||||
'indent': [
|
|
||||||
'error',
|
|
||||||
2
|
|
||||||
],
|
|
||||||
'linebreak-style': [
|
|
||||||
'error',
|
|
||||||
'unix'
|
|
||||||
],
|
|
||||||
'quotes': [
|
|
||||||
'error',
|
|
||||||
'single'
|
|
||||||
],
|
|
||||||
'semi': [
|
|
||||||
'error',
|
|
||||||
'always'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
21
node_modules/asn1.js/LICENSE
generated
vendored
21
node_modules/asn1.js/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2017 Fedor Indutny
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
100
node_modules/asn1.js/README.md
generated
vendored
100
node_modules/asn1.js/README.md
generated
vendored
|
@ -1,100 +0,0 @@
|
||||||
# ASN1.js
|
|
||||||
|
|
||||||
ASN.1 DER Encoder/Decoder and DSL.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
Define model:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var asn = require('asn1.js');
|
|
||||||
|
|
||||||
var Human = asn.define('Human', function() {
|
|
||||||
this.seq().obj(
|
|
||||||
this.key('firstName').octstr(),
|
|
||||||
this.key('lastName').octstr(),
|
|
||||||
this.key('age').int(),
|
|
||||||
this.key('gender').enum({ 0: 'male', 1: 'female' }),
|
|
||||||
this.key('bio').seqof(Bio)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
var Bio = asn.define('Bio', function() {
|
|
||||||
this.seq().obj(
|
|
||||||
this.key('time').gentime(),
|
|
||||||
this.key('description').octstr()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Encode data:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var output = Human.encode({
|
|
||||||
firstName: 'Thomas',
|
|
||||||
lastName: 'Anderson',
|
|
||||||
age: 28,
|
|
||||||
gender: 'male',
|
|
||||||
bio: [
|
|
||||||
{
|
|
||||||
time: +new Date('31 March 1999'),
|
|
||||||
description: 'freedom of mind'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, 'der');
|
|
||||||
```
|
|
||||||
|
|
||||||
Decode data:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var human = Human.decode(output, 'der');
|
|
||||||
console.log(human);
|
|
||||||
/*
|
|
||||||
{ firstName: <Buffer 54 68 6f 6d 61 73>,
|
|
||||||
lastName: <Buffer 41 6e 64 65 72 73 6f 6e>,
|
|
||||||
age: 28,
|
|
||||||
gender: 'male',
|
|
||||||
bio:
|
|
||||||
[ { time: 922820400000,
|
|
||||||
description: <Buffer 66 72 65 65 64 6f 6d 20 6f 66 20 6d 69 6e 64> } ] }
|
|
||||||
*/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Partial decode
|
|
||||||
|
|
||||||
Its possible to parse data without stopping on first error. In order to do it,
|
|
||||||
you should call:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var human = Human.decode(output, 'der', { partial: true });
|
|
||||||
console.log(human);
|
|
||||||
/*
|
|
||||||
{ result: { ... },
|
|
||||||
errors: [ ... ] }
|
|
||||||
*/
|
|
||||||
```
|
|
||||||
|
|
||||||
#### LICENSE
|
|
||||||
|
|
||||||
This software is licensed under the MIT License.
|
|
||||||
|
|
||||||
Copyright Fedor Indutny, 2017.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||||
persons to whom the Software is furnished to do so, subject to the
|
|
||||||
following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
|
||||||
in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
11
node_modules/asn1.js/lib/asn1.js
generated
vendored
11
node_modules/asn1.js/lib/asn1.js
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const asn1 = exports;
|
|
||||||
|
|
||||||
asn1.bignum = require('bn.js');
|
|
||||||
|
|
||||||
asn1.define = require('./asn1/api').define;
|
|
||||||
asn1.base = require('./asn1/base');
|
|
||||||
asn1.constants = require('./asn1/constants');
|
|
||||||
asn1.decoders = require('./asn1/decoders');
|
|
||||||
asn1.encoders = require('./asn1/encoders');
|
|
57
node_modules/asn1.js/lib/asn1/api.js
generated
vendored
57
node_modules/asn1.js/lib/asn1/api.js
generated
vendored
|
@ -1,57 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const encoders = require('./encoders');
|
|
||||||
const decoders = require('./decoders');
|
|
||||||
const inherits = require('inherits');
|
|
||||||
|
|
||||||
const api = exports;
|
|
||||||
|
|
||||||
api.define = function define(name, body) {
|
|
||||||
return new Entity(name, body);
|
|
||||||
};
|
|
||||||
|
|
||||||
function Entity(name, body) {
|
|
||||||
this.name = name;
|
|
||||||
this.body = body;
|
|
||||||
|
|
||||||
this.decoders = {};
|
|
||||||
this.encoders = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity.prototype._createNamed = function createNamed(Base) {
|
|
||||||
const name = this.name;
|
|
||||||
|
|
||||||
function Generated(entity) {
|
|
||||||
this._initNamed(entity, name);
|
|
||||||
}
|
|
||||||
inherits(Generated, Base);
|
|
||||||
Generated.prototype._initNamed = function _initNamed(entity, name) {
|
|
||||||
Base.call(this, entity, name);
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Generated(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype._getDecoder = function _getDecoder(enc) {
|
|
||||||
enc = enc || 'der';
|
|
||||||
// Lazily create decoder
|
|
||||||
if (!this.decoders.hasOwnProperty(enc))
|
|
||||||
this.decoders[enc] = this._createNamed(decoders[enc]);
|
|
||||||
return this.decoders[enc];
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype.decode = function decode(data, enc, options) {
|
|
||||||
return this._getDecoder(enc).decode(data, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype._getEncoder = function _getEncoder(enc) {
|
|
||||||
enc = enc || 'der';
|
|
||||||
// Lazily create encoder
|
|
||||||
if (!this.encoders.hasOwnProperty(enc))
|
|
||||||
this.encoders[enc] = this._createNamed(encoders[enc]);
|
|
||||||
return this.encoders[enc];
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
|
|
||||||
return this._getEncoder(enc).encode(data, reporter);
|
|
||||||
};
|
|
153
node_modules/asn1.js/lib/asn1/base/buffer.js
generated
vendored
153
node_modules/asn1.js/lib/asn1/base/buffer.js
generated
vendored
|
@ -1,153 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
const Reporter = require('../base/reporter').Reporter;
|
|
||||||
const Buffer = require('safer-buffer').Buffer;
|
|
||||||
|
|
||||||
function DecoderBuffer(base, options) {
|
|
||||||
Reporter.call(this, options);
|
|
||||||
if (!Buffer.isBuffer(base)) {
|
|
||||||
this.error('Input not Buffer');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.base = base;
|
|
||||||
this.offset = 0;
|
|
||||||
this.length = base.length;
|
|
||||||
}
|
|
||||||
inherits(DecoderBuffer, Reporter);
|
|
||||||
exports.DecoderBuffer = DecoderBuffer;
|
|
||||||
|
|
||||||
DecoderBuffer.isDecoderBuffer = function isDecoderBuffer(data) {
|
|
||||||
if (data instanceof DecoderBuffer) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or accept compatible API
|
|
||||||
const isCompatible = typeof data === 'object' &&
|
|
||||||
Buffer.isBuffer(data.base) &&
|
|
||||||
data.constructor.name === 'DecoderBuffer' &&
|
|
||||||
typeof data.offset === 'number' &&
|
|
||||||
typeof data.length === 'number' &&
|
|
||||||
typeof data.save === 'function' &&
|
|
||||||
typeof data.restore === 'function' &&
|
|
||||||
typeof data.isEmpty === 'function' &&
|
|
||||||
typeof data.readUInt8 === 'function' &&
|
|
||||||
typeof data.skip === 'function' &&
|
|
||||||
typeof data.raw === 'function';
|
|
||||||
|
|
||||||
return isCompatible;
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.save = function save() {
|
|
||||||
return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.restore = function restore(save) {
|
|
||||||
// Return skipped data
|
|
||||||
const res = new DecoderBuffer(this.base);
|
|
||||||
res.offset = save.offset;
|
|
||||||
res.length = this.offset;
|
|
||||||
|
|
||||||
this.offset = save.offset;
|
|
||||||
Reporter.prototype.restore.call(this, save.reporter);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.isEmpty = function isEmpty() {
|
|
||||||
return this.offset === this.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
|
|
||||||
if (this.offset + 1 <= this.length)
|
|
||||||
return this.base.readUInt8(this.offset++, true);
|
|
||||||
else
|
|
||||||
return this.error(fail || 'DecoderBuffer overrun');
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.skip = function skip(bytes, fail) {
|
|
||||||
if (!(this.offset + bytes <= this.length))
|
|
||||||
return this.error(fail || 'DecoderBuffer overrun');
|
|
||||||
|
|
||||||
const res = new DecoderBuffer(this.base);
|
|
||||||
|
|
||||||
// Share reporter state
|
|
||||||
res._reporterState = this._reporterState;
|
|
||||||
|
|
||||||
res.offset = this.offset;
|
|
||||||
res.length = this.offset + bytes;
|
|
||||||
this.offset += bytes;
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
DecoderBuffer.prototype.raw = function raw(save) {
|
|
||||||
return this.base.slice(save ? save.offset : this.offset, this.length);
|
|
||||||
};
|
|
||||||
|
|
||||||
function EncoderBuffer(value, reporter) {
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
this.length = 0;
|
|
||||||
this.value = value.map(function(item) {
|
|
||||||
if (!EncoderBuffer.isEncoderBuffer(item))
|
|
||||||
item = new EncoderBuffer(item, reporter);
|
|
||||||
this.length += item.length;
|
|
||||||
return item;
|
|
||||||
}, this);
|
|
||||||
} else if (typeof value === 'number') {
|
|
||||||
if (!(0 <= value && value <= 0xff))
|
|
||||||
return reporter.error('non-byte EncoderBuffer value');
|
|
||||||
this.value = value;
|
|
||||||
this.length = 1;
|
|
||||||
} else if (typeof value === 'string') {
|
|
||||||
this.value = value;
|
|
||||||
this.length = Buffer.byteLength(value);
|
|
||||||
} else if (Buffer.isBuffer(value)) {
|
|
||||||
this.value = value;
|
|
||||||
this.length = value.length;
|
|
||||||
} else {
|
|
||||||
return reporter.error('Unsupported type: ' + typeof value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.EncoderBuffer = EncoderBuffer;
|
|
||||||
|
|
||||||
EncoderBuffer.isEncoderBuffer = function isEncoderBuffer(data) {
|
|
||||||
if (data instanceof EncoderBuffer) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or accept compatible API
|
|
||||||
const isCompatible = typeof data === 'object' &&
|
|
||||||
data.constructor.name === 'EncoderBuffer' &&
|
|
||||||
typeof data.length === 'number' &&
|
|
||||||
typeof data.join === 'function';
|
|
||||||
|
|
||||||
return isCompatible;
|
|
||||||
};
|
|
||||||
|
|
||||||
EncoderBuffer.prototype.join = function join(out, offset) {
|
|
||||||
if (!out)
|
|
||||||
out = Buffer.alloc(this.length);
|
|
||||||
if (!offset)
|
|
||||||
offset = 0;
|
|
||||||
|
|
||||||
if (this.length === 0)
|
|
||||||
return out;
|
|
||||||
|
|
||||||
if (Array.isArray(this.value)) {
|
|
||||||
this.value.forEach(function(item) {
|
|
||||||
item.join(out, offset);
|
|
||||||
offset += item.length;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (typeof this.value === 'number')
|
|
||||||
out[offset] = this.value;
|
|
||||||
else if (typeof this.value === 'string')
|
|
||||||
out.write(this.value, offset);
|
|
||||||
else if (Buffer.isBuffer(this.value))
|
|
||||||
this.value.copy(out, offset);
|
|
||||||
offset += this.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
};
|
|
8
node_modules/asn1.js/lib/asn1/base/index.js
generated
vendored
8
node_modules/asn1.js/lib/asn1/base/index.js
generated
vendored
|
@ -1,8 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const base = exports;
|
|
||||||
|
|
||||||
base.Reporter = require('./reporter').Reporter;
|
|
||||||
base.DecoderBuffer = require('./buffer').DecoderBuffer;
|
|
||||||
base.EncoderBuffer = require('./buffer').EncoderBuffer;
|
|
||||||
base.Node = require('./node');
|
|
638
node_modules/asn1.js/lib/asn1/base/node.js
generated
vendored
638
node_modules/asn1.js/lib/asn1/base/node.js
generated
vendored
|
@ -1,638 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const Reporter = require('../base/reporter').Reporter;
|
|
||||||
const EncoderBuffer = require('../base/buffer').EncoderBuffer;
|
|
||||||
const DecoderBuffer = require('../base/buffer').DecoderBuffer;
|
|
||||||
const assert = require('minimalistic-assert');
|
|
||||||
|
|
||||||
// Supported tags
|
|
||||||
const tags = [
|
|
||||||
'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
|
|
||||||
'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc',
|
|
||||||
'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
|
|
||||||
'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Public methods list
|
|
||||||
const methods = [
|
|
||||||
'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
|
|
||||||
'any', 'contains'
|
|
||||||
].concat(tags);
|
|
||||||
|
|
||||||
// Overrided methods list
|
|
||||||
const overrided = [
|
|
||||||
'_peekTag', '_decodeTag', '_use',
|
|
||||||
'_decodeStr', '_decodeObjid', '_decodeTime',
|
|
||||||
'_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
|
|
||||||
|
|
||||||
'_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
|
|
||||||
'_encodeNull', '_encodeInt', '_encodeBool'
|
|
||||||
];
|
|
||||||
|
|
||||||
function Node(enc, parent, name) {
|
|
||||||
const state = {};
|
|
||||||
this._baseState = state;
|
|
||||||
|
|
||||||
state.name = name;
|
|
||||||
state.enc = enc;
|
|
||||||
|
|
||||||
state.parent = parent || null;
|
|
||||||
state.children = null;
|
|
||||||
|
|
||||||
// State
|
|
||||||
state.tag = null;
|
|
||||||
state.args = null;
|
|
||||||
state.reverseArgs = null;
|
|
||||||
state.choice = null;
|
|
||||||
state.optional = false;
|
|
||||||
state.any = false;
|
|
||||||
state.obj = false;
|
|
||||||
state.use = null;
|
|
||||||
state.useDecoder = null;
|
|
||||||
state.key = null;
|
|
||||||
state['default'] = null;
|
|
||||||
state.explicit = null;
|
|
||||||
state.implicit = null;
|
|
||||||
state.contains = null;
|
|
||||||
|
|
||||||
// Should create new instance on each method
|
|
||||||
if (!state.parent) {
|
|
||||||
state.children = [];
|
|
||||||
this._wrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = Node;
|
|
||||||
|
|
||||||
const stateProps = [
|
|
||||||
'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
|
|
||||||
'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
|
|
||||||
'implicit', 'contains'
|
|
||||||
];
|
|
||||||
|
|
||||||
Node.prototype.clone = function clone() {
|
|
||||||
const state = this._baseState;
|
|
||||||
const cstate = {};
|
|
||||||
stateProps.forEach(function(prop) {
|
|
||||||
cstate[prop] = state[prop];
|
|
||||||
});
|
|
||||||
const res = new this.constructor(cstate.parent);
|
|
||||||
res._baseState = cstate;
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._wrap = function wrap() {
|
|
||||||
const state = this._baseState;
|
|
||||||
methods.forEach(function(method) {
|
|
||||||
this[method] = function _wrappedMethod() {
|
|
||||||
const clone = new this.constructor(this);
|
|
||||||
state.children.push(clone);
|
|
||||||
return clone[method].apply(clone, arguments);
|
|
||||||
};
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._init = function init(body) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.parent === null);
|
|
||||||
body.call(this);
|
|
||||||
|
|
||||||
// Filter children
|
|
||||||
state.children = state.children.filter(function(child) {
|
|
||||||
return child._baseState.parent === this;
|
|
||||||
}, this);
|
|
||||||
assert.equal(state.children.length, 1, 'Root node can have only one child');
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._useArgs = function useArgs(args) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
// Filter children and args
|
|
||||||
const children = args.filter(function(arg) {
|
|
||||||
return arg instanceof this.constructor;
|
|
||||||
}, this);
|
|
||||||
args = args.filter(function(arg) {
|
|
||||||
return !(arg instanceof this.constructor);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
if (children.length !== 0) {
|
|
||||||
assert(state.children === null);
|
|
||||||
state.children = children;
|
|
||||||
|
|
||||||
// Replace parent to maintain backward link
|
|
||||||
children.forEach(function(child) {
|
|
||||||
child._baseState.parent = this;
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
if (args.length !== 0) {
|
|
||||||
assert(state.args === null);
|
|
||||||
state.args = args;
|
|
||||||
state.reverseArgs = args.map(function(arg) {
|
|
||||||
if (typeof arg !== 'object' || arg.constructor !== Object)
|
|
||||||
return arg;
|
|
||||||
|
|
||||||
const res = {};
|
|
||||||
Object.keys(arg).forEach(function(key) {
|
|
||||||
if (key == (key | 0))
|
|
||||||
key |= 0;
|
|
||||||
const value = arg[key];
|
|
||||||
res[value] = key;
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Overrided methods
|
|
||||||
//
|
|
||||||
|
|
||||||
overrided.forEach(function(method) {
|
|
||||||
Node.prototype[method] = function _overrided() {
|
|
||||||
const state = this._baseState;
|
|
||||||
throw new Error(method + ' not implemented for encoding: ' + state.enc);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
//
|
|
||||||
// Public methods
|
|
||||||
//
|
|
||||||
|
|
||||||
tags.forEach(function(tag) {
|
|
||||||
Node.prototype[tag] = function _tagMethod() {
|
|
||||||
const state = this._baseState;
|
|
||||||
const args = Array.prototype.slice.call(arguments);
|
|
||||||
|
|
||||||
assert(state.tag === null);
|
|
||||||
state.tag = tag;
|
|
||||||
|
|
||||||
this._useArgs(args);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
Node.prototype.use = function use(item) {
|
|
||||||
assert(item);
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.use === null);
|
|
||||||
state.use = item;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.optional = function optional() {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
state.optional = true;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.def = function def(val) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state['default'] === null);
|
|
||||||
state['default'] = val;
|
|
||||||
state.optional = true;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.explicit = function explicit(num) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.explicit === null && state.implicit === null);
|
|
||||||
state.explicit = num;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.implicit = function implicit(num) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.explicit === null && state.implicit === null);
|
|
||||||
state.implicit = num;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.obj = function obj() {
|
|
||||||
const state = this._baseState;
|
|
||||||
const args = Array.prototype.slice.call(arguments);
|
|
||||||
|
|
||||||
state.obj = true;
|
|
||||||
|
|
||||||
if (args.length !== 0)
|
|
||||||
this._useArgs(args);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.key = function key(newKey) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.key === null);
|
|
||||||
state.key = newKey;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.any = function any() {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
state.any = true;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.choice = function choice(obj) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.choice === null);
|
|
||||||
state.choice = obj;
|
|
||||||
this._useArgs(Object.keys(obj).map(function(key) {
|
|
||||||
return obj[key];
|
|
||||||
}));
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype.contains = function contains(item) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
assert(state.use === null);
|
|
||||||
state.contains = item;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decoding
|
|
||||||
//
|
|
||||||
|
|
||||||
Node.prototype._decode = function decode(input, options) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
// Decode root node
|
|
||||||
if (state.parent === null)
|
|
||||||
return input.wrapResult(state.children[0]._decode(input, options));
|
|
||||||
|
|
||||||
let result = state['default'];
|
|
||||||
let present = true;
|
|
||||||
|
|
||||||
let prevKey = null;
|
|
||||||
if (state.key !== null)
|
|
||||||
prevKey = input.enterKey(state.key);
|
|
||||||
|
|
||||||
// Check if tag is there
|
|
||||||
if (state.optional) {
|
|
||||||
let tag = null;
|
|
||||||
if (state.explicit !== null)
|
|
||||||
tag = state.explicit;
|
|
||||||
else if (state.implicit !== null)
|
|
||||||
tag = state.implicit;
|
|
||||||
else if (state.tag !== null)
|
|
||||||
tag = state.tag;
|
|
||||||
|
|
||||||
if (tag === null && !state.any) {
|
|
||||||
// Trial and Error
|
|
||||||
const save = input.save();
|
|
||||||
try {
|
|
||||||
if (state.choice === null)
|
|
||||||
this._decodeGeneric(state.tag, input, options);
|
|
||||||
else
|
|
||||||
this._decodeChoice(input, options);
|
|
||||||
present = true;
|
|
||||||
} catch (e) {
|
|
||||||
present = false;
|
|
||||||
}
|
|
||||||
input.restore(save);
|
|
||||||
} else {
|
|
||||||
present = this._peekTag(input, tag, state.any);
|
|
||||||
|
|
||||||
if (input.isError(present))
|
|
||||||
return present;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push object on stack
|
|
||||||
let prevObj;
|
|
||||||
if (state.obj && present)
|
|
||||||
prevObj = input.enterObject();
|
|
||||||
|
|
||||||
if (present) {
|
|
||||||
// Unwrap explicit values
|
|
||||||
if (state.explicit !== null) {
|
|
||||||
const explicit = this._decodeTag(input, state.explicit);
|
|
||||||
if (input.isError(explicit))
|
|
||||||
return explicit;
|
|
||||||
input = explicit;
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = input.offset;
|
|
||||||
|
|
||||||
// Unwrap implicit and normal values
|
|
||||||
if (state.use === null && state.choice === null) {
|
|
||||||
let save;
|
|
||||||
if (state.any)
|
|
||||||
save = input.save();
|
|
||||||
const body = this._decodeTag(
|
|
||||||
input,
|
|
||||||
state.implicit !== null ? state.implicit : state.tag,
|
|
||||||
state.any
|
|
||||||
);
|
|
||||||
if (input.isError(body))
|
|
||||||
return body;
|
|
||||||
|
|
||||||
if (state.any)
|
|
||||||
result = input.raw(save);
|
|
||||||
else
|
|
||||||
input = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options && options.track && state.tag !== null)
|
|
||||||
options.track(input.path(), start, input.length, 'tagged');
|
|
||||||
|
|
||||||
if (options && options.track && state.tag !== null)
|
|
||||||
options.track(input.path(), input.offset, input.length, 'content');
|
|
||||||
|
|
||||||
// Select proper method for tag
|
|
||||||
if (state.any) {
|
|
||||||
// no-op
|
|
||||||
} else if (state.choice === null) {
|
|
||||||
result = this._decodeGeneric(state.tag, input, options);
|
|
||||||
} else {
|
|
||||||
result = this._decodeChoice(input, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.isError(result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Decode children
|
|
||||||
if (!state.any && state.choice === null && state.children !== null) {
|
|
||||||
state.children.forEach(function decodeChildren(child) {
|
|
||||||
// NOTE: We are ignoring errors here, to let parser continue with other
|
|
||||||
// parts of encoded data
|
|
||||||
child._decode(input, options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode contained/encoded by schema, only in bit or octet strings
|
|
||||||
if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
|
|
||||||
const data = new DecoderBuffer(result);
|
|
||||||
result = this._getUse(state.contains, input._reporterState.obj)
|
|
||||||
._decode(data, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop object
|
|
||||||
if (state.obj && present)
|
|
||||||
result = input.leaveObject(prevObj);
|
|
||||||
|
|
||||||
// Set key
|
|
||||||
if (state.key !== null && (result !== null || present === true))
|
|
||||||
input.leaveKey(prevKey, state.key, result);
|
|
||||||
else if (prevKey !== null)
|
|
||||||
input.exitKey(prevKey);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
if (tag === 'seq' || tag === 'set')
|
|
||||||
return null;
|
|
||||||
if (tag === 'seqof' || tag === 'setof')
|
|
||||||
return this._decodeList(input, tag, state.args[0], options);
|
|
||||||
else if (/str$/.test(tag))
|
|
||||||
return this._decodeStr(input, tag, options);
|
|
||||||
else if (tag === 'objid' && state.args)
|
|
||||||
return this._decodeObjid(input, state.args[0], state.args[1], options);
|
|
||||||
else if (tag === 'objid')
|
|
||||||
return this._decodeObjid(input, null, null, options);
|
|
||||||
else if (tag === 'gentime' || tag === 'utctime')
|
|
||||||
return this._decodeTime(input, tag, options);
|
|
||||||
else if (tag === 'null_')
|
|
||||||
return this._decodeNull(input, options);
|
|
||||||
else if (tag === 'bool')
|
|
||||||
return this._decodeBool(input, options);
|
|
||||||
else if (tag === 'objDesc')
|
|
||||||
return this._decodeStr(input, tag, options);
|
|
||||||
else if (tag === 'int' || tag === 'enum')
|
|
||||||
return this._decodeInt(input, state.args && state.args[0], options);
|
|
||||||
|
|
||||||
if (state.use !== null) {
|
|
||||||
return this._getUse(state.use, input._reporterState.obj)
|
|
||||||
._decode(input, options);
|
|
||||||
} else {
|
|
||||||
return input.error('unknown tag: ' + tag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._getUse = function _getUse(entity, obj) {
|
|
||||||
|
|
||||||
const state = this._baseState;
|
|
||||||
// Create altered use decoder if implicit is set
|
|
||||||
state.useDecoder = this._use(entity, obj);
|
|
||||||
assert(state.useDecoder._baseState.parent === null);
|
|
||||||
state.useDecoder = state.useDecoder._baseState.children[0];
|
|
||||||
if (state.implicit !== state.useDecoder._baseState.implicit) {
|
|
||||||
state.useDecoder = state.useDecoder.clone();
|
|
||||||
state.useDecoder._baseState.implicit = state.implicit;
|
|
||||||
}
|
|
||||||
return state.useDecoder;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._decodeChoice = function decodeChoice(input, options) {
|
|
||||||
const state = this._baseState;
|
|
||||||
let result = null;
|
|
||||||
let match = false;
|
|
||||||
|
|
||||||
Object.keys(state.choice).some(function(key) {
|
|
||||||
const save = input.save();
|
|
||||||
const node = state.choice[key];
|
|
||||||
try {
|
|
||||||
const value = node._decode(input, options);
|
|
||||||
if (input.isError(value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
result = { type: key, value: value };
|
|
||||||
match = true;
|
|
||||||
} catch (e) {
|
|
||||||
input.restore(save);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
if (!match)
|
|
||||||
return input.error('Choice not matched');
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Encoding
|
|
||||||
//
|
|
||||||
|
|
||||||
Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
|
|
||||||
return new EncoderBuffer(data, this.reporter);
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._encode = function encode(data, reporter, parent) {
|
|
||||||
const state = this._baseState;
|
|
||||||
if (state['default'] !== null && state['default'] === data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const result = this._encodeValue(data, reporter, parent);
|
|
||||||
if (result === undefined)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this._skipDefault(result, reporter, parent))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._encodeValue = function encode(data, reporter, parent) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
// Decode root node
|
|
||||||
if (state.parent === null)
|
|
||||||
return state.children[0]._encode(data, reporter || new Reporter());
|
|
||||||
|
|
||||||
let result = null;
|
|
||||||
|
|
||||||
// Set reporter to share it with a child class
|
|
||||||
this.reporter = reporter;
|
|
||||||
|
|
||||||
// Check if data is there
|
|
||||||
if (state.optional && data === undefined) {
|
|
||||||
if (state['default'] !== null)
|
|
||||||
data = state['default'];
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode children first
|
|
||||||
let content = null;
|
|
||||||
let primitive = false;
|
|
||||||
if (state.any) {
|
|
||||||
// Anything that was given is translated to buffer
|
|
||||||
result = this._createEncoderBuffer(data);
|
|
||||||
} else if (state.choice) {
|
|
||||||
result = this._encodeChoice(data, reporter);
|
|
||||||
} else if (state.contains) {
|
|
||||||
content = this._getUse(state.contains, parent)._encode(data, reporter);
|
|
||||||
primitive = true;
|
|
||||||
} else if (state.children) {
|
|
||||||
content = state.children.map(function(child) {
|
|
||||||
if (child._baseState.tag === 'null_')
|
|
||||||
return child._encode(null, reporter, data);
|
|
||||||
|
|
||||||
if (child._baseState.key === null)
|
|
||||||
return reporter.error('Child should have a key');
|
|
||||||
const prevKey = reporter.enterKey(child._baseState.key);
|
|
||||||
|
|
||||||
if (typeof data !== 'object')
|
|
||||||
return reporter.error('Child expected, but input is not object');
|
|
||||||
|
|
||||||
const res = child._encode(data[child._baseState.key], reporter, data);
|
|
||||||
reporter.leaveKey(prevKey);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}, this).filter(function(child) {
|
|
||||||
return child;
|
|
||||||
});
|
|
||||||
content = this._createEncoderBuffer(content);
|
|
||||||
} else {
|
|
||||||
if (state.tag === 'seqof' || state.tag === 'setof') {
|
|
||||||
// TODO(indutny): this should be thrown on DSL level
|
|
||||||
if (!(state.args && state.args.length === 1))
|
|
||||||
return reporter.error('Too many args for : ' + state.tag);
|
|
||||||
|
|
||||||
if (!Array.isArray(data))
|
|
||||||
return reporter.error('seqof/setof, but data is not Array');
|
|
||||||
|
|
||||||
const child = this.clone();
|
|
||||||
child._baseState.implicit = null;
|
|
||||||
content = this._createEncoderBuffer(data.map(function(item) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
return this._getUse(state.args[0], data)._encode(item, reporter);
|
|
||||||
}, child));
|
|
||||||
} else if (state.use !== null) {
|
|
||||||
result = this._getUse(state.use, parent)._encode(data, reporter);
|
|
||||||
} else {
|
|
||||||
content = this._encodePrimitive(state.tag, data);
|
|
||||||
primitive = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode data itself
|
|
||||||
if (!state.any && state.choice === null) {
|
|
||||||
const tag = state.implicit !== null ? state.implicit : state.tag;
|
|
||||||
const cls = state.implicit === null ? 'universal' : 'context';
|
|
||||||
|
|
||||||
if (tag === null) {
|
|
||||||
if (state.use === null)
|
|
||||||
reporter.error('Tag could be omitted only for .use()');
|
|
||||||
} else {
|
|
||||||
if (state.use === null)
|
|
||||||
result = this._encodeComposite(tag, primitive, cls, content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap in explicit
|
|
||||||
if (state.explicit !== null)
|
|
||||||
result = this._encodeComposite(state.explicit, false, 'context', result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
const node = state.choice[data.type];
|
|
||||||
if (!node) {
|
|
||||||
assert(
|
|
||||||
false,
|
|
||||||
data.type + ' not found in ' +
|
|
||||||
JSON.stringify(Object.keys(state.choice)));
|
|
||||||
}
|
|
||||||
return node._encode(data.value, reporter);
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
|
|
||||||
const state = this._baseState;
|
|
||||||
|
|
||||||
if (/str$/.test(tag))
|
|
||||||
return this._encodeStr(data, tag);
|
|
||||||
else if (tag === 'objid' && state.args)
|
|
||||||
return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
|
|
||||||
else if (tag === 'objid')
|
|
||||||
return this._encodeObjid(data, null, null);
|
|
||||||
else if (tag === 'gentime' || tag === 'utctime')
|
|
||||||
return this._encodeTime(data, tag);
|
|
||||||
else if (tag === 'null_')
|
|
||||||
return this._encodeNull();
|
|
||||||
else if (tag === 'int' || tag === 'enum')
|
|
||||||
return this._encodeInt(data, state.args && state.reverseArgs[0]);
|
|
||||||
else if (tag === 'bool')
|
|
||||||
return this._encodeBool(data);
|
|
||||||
else if (tag === 'objDesc')
|
|
||||||
return this._encodeStr(data, tag);
|
|
||||||
else
|
|
||||||
throw new Error('Unsupported tag: ' + tag);
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._isNumstr = function isNumstr(str) {
|
|
||||||
return /^[0-9 ]*$/.test(str);
|
|
||||||
};
|
|
||||||
|
|
||||||
Node.prototype._isPrintstr = function isPrintstr(str) {
|
|
||||||
return /^[A-Za-z0-9 '()+,-./:=?]*$/.test(str);
|
|
||||||
};
|
|
123
node_modules/asn1.js/lib/asn1/base/reporter.js
generated
vendored
123
node_modules/asn1.js/lib/asn1/base/reporter.js
generated
vendored
|
@ -1,123 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
|
|
||||||
function Reporter(options) {
|
|
||||||
this._reporterState = {
|
|
||||||
obj: null,
|
|
||||||
path: [],
|
|
||||||
options: options || {},
|
|
||||||
errors: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
exports.Reporter = Reporter;
|
|
||||||
|
|
||||||
Reporter.prototype.isError = function isError(obj) {
|
|
||||||
return obj instanceof ReporterError;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.save = function save() {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
return { obj: state.obj, pathLen: state.path.length };
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.restore = function restore(data) {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
state.obj = data.obj;
|
|
||||||
state.path = state.path.slice(0, data.pathLen);
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.enterKey = function enterKey(key) {
|
|
||||||
return this._reporterState.path.push(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.exitKey = function exitKey(index) {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
state.path = state.path.slice(0, index - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
this.exitKey(index);
|
|
||||||
if (state.obj !== null)
|
|
||||||
state.obj[key] = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.path = function path() {
|
|
||||||
return this._reporterState.path.join('/');
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.enterObject = function enterObject() {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
const prev = state.obj;
|
|
||||||
state.obj = {};
|
|
||||||
return prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.leaveObject = function leaveObject(prev) {
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
const now = state.obj;
|
|
||||||
state.obj = prev;
|
|
||||||
return now;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.error = function error(msg) {
|
|
||||||
let err;
|
|
||||||
const state = this._reporterState;
|
|
||||||
|
|
||||||
const inherited = msg instanceof ReporterError;
|
|
||||||
if (inherited) {
|
|
||||||
err = msg;
|
|
||||||
} else {
|
|
||||||
err = new ReporterError(state.path.map(function(elem) {
|
|
||||||
return '[' + JSON.stringify(elem) + ']';
|
|
||||||
}).join(''), msg.message || msg, msg.stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state.options.partial)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
if (!inherited)
|
|
||||||
state.errors.push(err);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reporter.prototype.wrapResult = function wrapResult(result) {
|
|
||||||
const state = this._reporterState;
|
|
||||||
if (!state.options.partial)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return {
|
|
||||||
result: this.isError(result) ? null : result,
|
|
||||||
errors: state.errors
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function ReporterError(path, msg) {
|
|
||||||
this.path = path;
|
|
||||||
this.rethrow(msg);
|
|
||||||
}
|
|
||||||
inherits(ReporterError, Error);
|
|
||||||
|
|
||||||
ReporterError.prototype.rethrow = function rethrow(msg) {
|
|
||||||
this.message = msg + ' at: ' + (this.path || '(shallow)');
|
|
||||||
if (Error.captureStackTrace)
|
|
||||||
Error.captureStackTrace(this, ReporterError);
|
|
||||||
|
|
||||||
if (!this.stack) {
|
|
||||||
try {
|
|
||||||
// IE only adds stack when thrown
|
|
||||||
throw new Error(this.message);
|
|
||||||
} catch (e) {
|
|
||||||
this.stack = e.stack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
58
node_modules/asn1.js/lib/asn1/constants/der.js
generated
vendored
58
node_modules/asn1.js/lib/asn1/constants/der.js
generated
vendored
|
@ -1,58 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// Helper
|
|
||||||
function reverse(map) {
|
|
||||||
const res = {};
|
|
||||||
|
|
||||||
Object.keys(map).forEach(function(key) {
|
|
||||||
// Convert key to integer if it is stringified
|
|
||||||
if ((key | 0) == key)
|
|
||||||
key = key | 0;
|
|
||||||
|
|
||||||
const value = map[key];
|
|
||||||
res[value] = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.tagClass = {
|
|
||||||
0: 'universal',
|
|
||||||
1: 'application',
|
|
||||||
2: 'context',
|
|
||||||
3: 'private'
|
|
||||||
};
|
|
||||||
exports.tagClassByName = reverse(exports.tagClass);
|
|
||||||
|
|
||||||
exports.tag = {
|
|
||||||
0x00: 'end',
|
|
||||||
0x01: 'bool',
|
|
||||||
0x02: 'int',
|
|
||||||
0x03: 'bitstr',
|
|
||||||
0x04: 'octstr',
|
|
||||||
0x05: 'null_',
|
|
||||||
0x06: 'objid',
|
|
||||||
0x07: 'objDesc',
|
|
||||||
0x08: 'external',
|
|
||||||
0x09: 'real',
|
|
||||||
0x0a: 'enum',
|
|
||||||
0x0b: 'embed',
|
|
||||||
0x0c: 'utf8str',
|
|
||||||
0x0d: 'relativeOid',
|
|
||||||
0x10: 'seq',
|
|
||||||
0x11: 'set',
|
|
||||||
0x12: 'numstr',
|
|
||||||
0x13: 'printstr',
|
|
||||||
0x14: 't61str',
|
|
||||||
0x15: 'videostr',
|
|
||||||
0x16: 'ia5str',
|
|
||||||
0x17: 'utctime',
|
|
||||||
0x18: 'gentime',
|
|
||||||
0x19: 'graphstr',
|
|
||||||
0x1a: 'iso646str',
|
|
||||||
0x1b: 'genstr',
|
|
||||||
0x1c: 'unistr',
|
|
||||||
0x1d: 'charstr',
|
|
||||||
0x1e: 'bmpstr'
|
|
||||||
};
|
|
||||||
exports.tagByName = reverse(exports.tag);
|
|
21
node_modules/asn1.js/lib/asn1/constants/index.js
generated
vendored
21
node_modules/asn1.js/lib/asn1/constants/index.js
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const constants = exports;
|
|
||||||
|
|
||||||
// Helper
|
|
||||||
constants._reverse = function reverse(map) {
|
|
||||||
const res = {};
|
|
||||||
|
|
||||||
Object.keys(map).forEach(function(key) {
|
|
||||||
// Convert key to integer if it is stringified
|
|
||||||
if ((key | 0) == key)
|
|
||||||
key = key | 0;
|
|
||||||
|
|
||||||
const value = map[key];
|
|
||||||
res[value] = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
constants.der = require('./der');
|
|
335
node_modules/asn1.js/lib/asn1/decoders/der.js
generated
vendored
335
node_modules/asn1.js/lib/asn1/decoders/der.js
generated
vendored
|
@ -1,335 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
|
|
||||||
const bignum = require('bn.js');
|
|
||||||
const DecoderBuffer = require('../base/buffer').DecoderBuffer;
|
|
||||||
const Node = require('../base/node');
|
|
||||||
|
|
||||||
// Import DER constants
|
|
||||||
const der = require('../constants/der');
|
|
||||||
|
|
||||||
function DERDecoder(entity) {
|
|
||||||
this.enc = 'der';
|
|
||||||
this.name = entity.name;
|
|
||||||
this.entity = entity;
|
|
||||||
|
|
||||||
// Construct base tree
|
|
||||||
this.tree = new DERNode();
|
|
||||||
this.tree._init(entity.body);
|
|
||||||
}
|
|
||||||
module.exports = DERDecoder;
|
|
||||||
|
|
||||||
DERDecoder.prototype.decode = function decode(data, options) {
|
|
||||||
if (!DecoderBuffer.isDecoderBuffer(data)) {
|
|
||||||
data = new DecoderBuffer(data, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.tree._decode(data, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tree methods
|
|
||||||
|
|
||||||
function DERNode(parent) {
|
|
||||||
Node.call(this, 'der', parent);
|
|
||||||
}
|
|
||||||
inherits(DERNode, Node);
|
|
||||||
|
|
||||||
DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
|
|
||||||
if (buffer.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const state = buffer.save();
|
|
||||||
const decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
|
|
||||||
if (buffer.isError(decodedTag))
|
|
||||||
return decodedTag;
|
|
||||||
|
|
||||||
buffer.restore(state);
|
|
||||||
|
|
||||||
return decodedTag.tag === tag || decodedTag.tagStr === tag ||
|
|
||||||
(decodedTag.tagStr + 'of') === tag || any;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
|
|
||||||
const decodedTag = derDecodeTag(buffer,
|
|
||||||
'Failed to decode tag of "' + tag + '"');
|
|
||||||
if (buffer.isError(decodedTag))
|
|
||||||
return decodedTag;
|
|
||||||
|
|
||||||
let len = derDecodeLen(buffer,
|
|
||||||
decodedTag.primitive,
|
|
||||||
'Failed to get length of "' + tag + '"');
|
|
||||||
|
|
||||||
// Failure
|
|
||||||
if (buffer.isError(len))
|
|
||||||
return len;
|
|
||||||
|
|
||||||
if (!any &&
|
|
||||||
decodedTag.tag !== tag &&
|
|
||||||
decodedTag.tagStr !== tag &&
|
|
||||||
decodedTag.tagStr + 'of' !== tag) {
|
|
||||||
return buffer.error('Failed to match tag: "' + tag + '"');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decodedTag.primitive || len !== null)
|
|
||||||
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
|
|
||||||
|
|
||||||
// Indefinite length... find END tag
|
|
||||||
const state = buffer.save();
|
|
||||||
const res = this._skipUntilEnd(
|
|
||||||
buffer,
|
|
||||||
'Failed to skip indefinite length body: "' + this.tag + '"');
|
|
||||||
if (buffer.isError(res))
|
|
||||||
return res;
|
|
||||||
|
|
||||||
len = buffer.offset - state.offset;
|
|
||||||
buffer.restore(state);
|
|
||||||
return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
|
|
||||||
for (;;) {
|
|
||||||
const tag = derDecodeTag(buffer, fail);
|
|
||||||
if (buffer.isError(tag))
|
|
||||||
return tag;
|
|
||||||
const len = derDecodeLen(buffer, tag.primitive, fail);
|
|
||||||
if (buffer.isError(len))
|
|
||||||
return len;
|
|
||||||
|
|
||||||
let res;
|
|
||||||
if (tag.primitive || len !== null)
|
|
||||||
res = buffer.skip(len);
|
|
||||||
else
|
|
||||||
res = this._skipUntilEnd(buffer, fail);
|
|
||||||
|
|
||||||
// Failure
|
|
||||||
if (buffer.isError(res))
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if (tag.tagStr === 'end')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,
|
|
||||||
options) {
|
|
||||||
const result = [];
|
|
||||||
while (!buffer.isEmpty()) {
|
|
||||||
const possibleEnd = this._peekTag(buffer, 'end');
|
|
||||||
if (buffer.isError(possibleEnd))
|
|
||||||
return possibleEnd;
|
|
||||||
|
|
||||||
const res = decoder.decode(buffer, 'der', options);
|
|
||||||
if (buffer.isError(res) && possibleEnd)
|
|
||||||
break;
|
|
||||||
result.push(res);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
|
|
||||||
if (tag === 'bitstr') {
|
|
||||||
const unused = buffer.readUInt8();
|
|
||||||
if (buffer.isError(unused))
|
|
||||||
return unused;
|
|
||||||
return { unused: unused, data: buffer.raw() };
|
|
||||||
} else if (tag === 'bmpstr') {
|
|
||||||
const raw = buffer.raw();
|
|
||||||
if (raw.length % 2 === 1)
|
|
||||||
return buffer.error('Decoding of string type: bmpstr length mismatch');
|
|
||||||
|
|
||||||
let str = '';
|
|
||||||
for (let i = 0; i < raw.length / 2; i++) {
|
|
||||||
str += String.fromCharCode(raw.readUInt16BE(i * 2));
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
} else if (tag === 'numstr') {
|
|
||||||
const numstr = buffer.raw().toString('ascii');
|
|
||||||
if (!this._isNumstr(numstr)) {
|
|
||||||
return buffer.error('Decoding of string type: ' +
|
|
||||||
'numstr unsupported characters');
|
|
||||||
}
|
|
||||||
return numstr;
|
|
||||||
} else if (tag === 'octstr') {
|
|
||||||
return buffer.raw();
|
|
||||||
} else if (tag === 'objDesc') {
|
|
||||||
return buffer.raw();
|
|
||||||
} else if (tag === 'printstr') {
|
|
||||||
const printstr = buffer.raw().toString('ascii');
|
|
||||||
if (!this._isPrintstr(printstr)) {
|
|
||||||
return buffer.error('Decoding of string type: ' +
|
|
||||||
'printstr unsupported characters');
|
|
||||||
}
|
|
||||||
return printstr;
|
|
||||||
} else if (/str$/.test(tag)) {
|
|
||||||
return buffer.raw().toString();
|
|
||||||
} else {
|
|
||||||
return buffer.error('Decoding of string type: ' + tag + ' unsupported');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
|
|
||||||
let result;
|
|
||||||
const identifiers = [];
|
|
||||||
let ident = 0;
|
|
||||||
let subident = 0;
|
|
||||||
while (!buffer.isEmpty()) {
|
|
||||||
subident = buffer.readUInt8();
|
|
||||||
ident <<= 7;
|
|
||||||
ident |= subident & 0x7f;
|
|
||||||
if ((subident & 0x80) === 0) {
|
|
||||||
identifiers.push(ident);
|
|
||||||
ident = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (subident & 0x80)
|
|
||||||
identifiers.push(ident);
|
|
||||||
|
|
||||||
const first = (identifiers[0] / 40) | 0;
|
|
||||||
const second = identifiers[0] % 40;
|
|
||||||
|
|
||||||
if (relative)
|
|
||||||
result = identifiers;
|
|
||||||
else
|
|
||||||
result = [first, second].concat(identifiers.slice(1));
|
|
||||||
|
|
||||||
if (values) {
|
|
||||||
let tmp = values[result.join(' ')];
|
|
||||||
if (tmp === undefined)
|
|
||||||
tmp = values[result.join('.')];
|
|
||||||
if (tmp !== undefined)
|
|
||||||
result = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
|
|
||||||
const str = buffer.raw().toString();
|
|
||||||
|
|
||||||
let year;
|
|
||||||
let mon;
|
|
||||||
let day;
|
|
||||||
let hour;
|
|
||||||
let min;
|
|
||||||
let sec;
|
|
||||||
if (tag === 'gentime') {
|
|
||||||
year = str.slice(0, 4) | 0;
|
|
||||||
mon = str.slice(4, 6) | 0;
|
|
||||||
day = str.slice(6, 8) | 0;
|
|
||||||
hour = str.slice(8, 10) | 0;
|
|
||||||
min = str.slice(10, 12) | 0;
|
|
||||||
sec = str.slice(12, 14) | 0;
|
|
||||||
} else if (tag === 'utctime') {
|
|
||||||
year = str.slice(0, 2) | 0;
|
|
||||||
mon = str.slice(2, 4) | 0;
|
|
||||||
day = str.slice(4, 6) | 0;
|
|
||||||
hour = str.slice(6, 8) | 0;
|
|
||||||
min = str.slice(8, 10) | 0;
|
|
||||||
sec = str.slice(10, 12) | 0;
|
|
||||||
if (year < 70)
|
|
||||||
year = 2000 + year;
|
|
||||||
else
|
|
||||||
year = 1900 + year;
|
|
||||||
} else {
|
|
||||||
return buffer.error('Decoding ' + tag + ' time is not supported yet');
|
|
||||||
}
|
|
||||||
|
|
||||||
return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeNull = function decodeNull() {
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeBool = function decodeBool(buffer) {
|
|
||||||
const res = buffer.readUInt8();
|
|
||||||
if (buffer.isError(res))
|
|
||||||
return res;
|
|
||||||
else
|
|
||||||
return res !== 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
|
|
||||||
// Bigint, return as it is (assume big endian)
|
|
||||||
const raw = buffer.raw();
|
|
||||||
let res = new bignum(raw);
|
|
||||||
|
|
||||||
if (values)
|
|
||||||
res = values[res.toString(10)] || res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._use = function use(entity, obj) {
|
|
||||||
if (typeof entity === 'function')
|
|
||||||
entity = entity(obj);
|
|
||||||
return entity._getDecoder('der').tree;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Utility methods
|
|
||||||
|
|
||||||
function derDecodeTag(buf, fail) {
|
|
||||||
let tag = buf.readUInt8(fail);
|
|
||||||
if (buf.isError(tag))
|
|
||||||
return tag;
|
|
||||||
|
|
||||||
const cls = der.tagClass[tag >> 6];
|
|
||||||
const primitive = (tag & 0x20) === 0;
|
|
||||||
|
|
||||||
// Multi-octet tag - load
|
|
||||||
if ((tag & 0x1f) === 0x1f) {
|
|
||||||
let oct = tag;
|
|
||||||
tag = 0;
|
|
||||||
while ((oct & 0x80) === 0x80) {
|
|
||||||
oct = buf.readUInt8(fail);
|
|
||||||
if (buf.isError(oct))
|
|
||||||
return oct;
|
|
||||||
|
|
||||||
tag <<= 7;
|
|
||||||
tag |= oct & 0x7f;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tag &= 0x1f;
|
|
||||||
}
|
|
||||||
const tagStr = der.tag[tag];
|
|
||||||
|
|
||||||
return {
|
|
||||||
cls: cls,
|
|
||||||
primitive: primitive,
|
|
||||||
tag: tag,
|
|
||||||
tagStr: tagStr
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function derDecodeLen(buf, primitive, fail) {
|
|
||||||
let len = buf.readUInt8(fail);
|
|
||||||
if (buf.isError(len))
|
|
||||||
return len;
|
|
||||||
|
|
||||||
// Indefinite form
|
|
||||||
if (!primitive && len === 0x80)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Definite form
|
|
||||||
if ((len & 0x80) === 0) {
|
|
||||||
// Short form
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Long form
|
|
||||||
const num = len & 0x7f;
|
|
||||||
if (num > 4)
|
|
||||||
return buf.error('length octect is too long');
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
for (let i = 0; i < num; i++) {
|
|
||||||
len <<= 8;
|
|
||||||
const j = buf.readUInt8(fail);
|
|
||||||
if (buf.isError(j))
|
|
||||||
return j;
|
|
||||||
len |= j;
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
6
node_modules/asn1.js/lib/asn1/decoders/index.js
generated
vendored
6
node_modules/asn1.js/lib/asn1/decoders/index.js
generated
vendored
|
@ -1,6 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const decoders = exports;
|
|
||||||
|
|
||||||
decoders.der = require('./der');
|
|
||||||
decoders.pem = require('./pem');
|
|
51
node_modules/asn1.js/lib/asn1/decoders/pem.js
generated
vendored
51
node_modules/asn1.js/lib/asn1/decoders/pem.js
generated
vendored
|
@ -1,51 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
const Buffer = require('safer-buffer').Buffer;
|
|
||||||
|
|
||||||
const DERDecoder = require('./der');
|
|
||||||
|
|
||||||
function PEMDecoder(entity) {
|
|
||||||
DERDecoder.call(this, entity);
|
|
||||||
this.enc = 'pem';
|
|
||||||
}
|
|
||||||
inherits(PEMDecoder, DERDecoder);
|
|
||||||
module.exports = PEMDecoder;
|
|
||||||
|
|
||||||
PEMDecoder.prototype.decode = function decode(data, options) {
|
|
||||||
const lines = data.toString().split(/[\r\n]+/g);
|
|
||||||
|
|
||||||
const label = options.label.toUpperCase();
|
|
||||||
|
|
||||||
const re = /^-----(BEGIN|END) ([^-]+)-----$/;
|
|
||||||
let start = -1;
|
|
||||||
let end = -1;
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const match = lines[i].match(re);
|
|
||||||
if (match === null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (match[2] !== label)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (start === -1) {
|
|
||||||
if (match[1] !== 'BEGIN')
|
|
||||||
break;
|
|
||||||
start = i;
|
|
||||||
} else {
|
|
||||||
if (match[1] !== 'END')
|
|
||||||
break;
|
|
||||||
end = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (start === -1 || end === -1)
|
|
||||||
throw new Error('PEM section not found for: ' + label);
|
|
||||||
|
|
||||||
const base64 = lines.slice(start + 1, end).join('');
|
|
||||||
// Remove excessive symbols
|
|
||||||
base64.replace(/[^a-z0-9+/=]+/gi, '');
|
|
||||||
|
|
||||||
const input = Buffer.from(base64, 'base64');
|
|
||||||
return DERDecoder.prototype.decode.call(this, input, options);
|
|
||||||
};
|
|
295
node_modules/asn1.js/lib/asn1/encoders/der.js
generated
vendored
295
node_modules/asn1.js/lib/asn1/encoders/der.js
generated
vendored
|
@ -1,295 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
const Buffer = require('safer-buffer').Buffer;
|
|
||||||
const Node = require('../base/node');
|
|
||||||
|
|
||||||
// Import DER constants
|
|
||||||
const der = require('../constants/der');
|
|
||||||
|
|
||||||
function DEREncoder(entity) {
|
|
||||||
this.enc = 'der';
|
|
||||||
this.name = entity.name;
|
|
||||||
this.entity = entity;
|
|
||||||
|
|
||||||
// Construct base tree
|
|
||||||
this.tree = new DERNode();
|
|
||||||
this.tree._init(entity.body);
|
|
||||||
}
|
|
||||||
module.exports = DEREncoder;
|
|
||||||
|
|
||||||
DEREncoder.prototype.encode = function encode(data, reporter) {
|
|
||||||
return this.tree._encode(data, reporter).join();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tree methods
|
|
||||||
|
|
||||||
function DERNode(parent) {
|
|
||||||
Node.call(this, 'der', parent);
|
|
||||||
}
|
|
||||||
inherits(DERNode, Node);
|
|
||||||
|
|
||||||
DERNode.prototype._encodeComposite = function encodeComposite(tag,
|
|
||||||
primitive,
|
|
||||||
cls,
|
|
||||||
content) {
|
|
||||||
const encodedTag = encodeTag(tag, primitive, cls, this.reporter);
|
|
||||||
|
|
||||||
// Short form
|
|
||||||
if (content.length < 0x80) {
|
|
||||||
const header = Buffer.alloc(2);
|
|
||||||
header[0] = encodedTag;
|
|
||||||
header[1] = content.length;
|
|
||||||
return this._createEncoderBuffer([ header, content ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Long form
|
|
||||||
// Count octets required to store length
|
|
||||||
let lenOctets = 1;
|
|
||||||
for (let i = content.length; i >= 0x100; i >>= 8)
|
|
||||||
lenOctets++;
|
|
||||||
|
|
||||||
const header = Buffer.alloc(1 + 1 + lenOctets);
|
|
||||||
header[0] = encodedTag;
|
|
||||||
header[1] = 0x80 | lenOctets;
|
|
||||||
|
|
||||||
for (let i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)
|
|
||||||
header[i] = j & 0xff;
|
|
||||||
|
|
||||||
return this._createEncoderBuffer([ header, content ]);
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._encodeStr = function encodeStr(str, tag) {
|
|
||||||
if (tag === 'bitstr') {
|
|
||||||
return this._createEncoderBuffer([ str.unused | 0, str.data ]);
|
|
||||||
} else if (tag === 'bmpstr') {
|
|
||||||
const buf = Buffer.alloc(str.length * 2);
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
|
||||||
buf.writeUInt16BE(str.charCodeAt(i), i * 2);
|
|
||||||
}
|
|
||||||
return this._createEncoderBuffer(buf);
|
|
||||||
} else if (tag === 'numstr') {
|
|
||||||
if (!this._isNumstr(str)) {
|
|
||||||
return this.reporter.error('Encoding of string type: numstr supports ' +
|
|
||||||
'only digits and space');
|
|
||||||
}
|
|
||||||
return this._createEncoderBuffer(str);
|
|
||||||
} else if (tag === 'printstr') {
|
|
||||||
if (!this._isPrintstr(str)) {
|
|
||||||
return this.reporter.error('Encoding of string type: printstr supports ' +
|
|
||||||
'only latin upper and lower case letters, ' +
|
|
||||||
'digits, space, apostrophe, left and rigth ' +
|
|
||||||
'parenthesis, plus sign, comma, hyphen, ' +
|
|
||||||
'dot, slash, colon, equal sign, ' +
|
|
||||||
'question mark');
|
|
||||||
}
|
|
||||||
return this._createEncoderBuffer(str);
|
|
||||||
} else if (/str$/.test(tag)) {
|
|
||||||
return this._createEncoderBuffer(str);
|
|
||||||
} else if (tag === 'objDesc') {
|
|
||||||
return this._createEncoderBuffer(str);
|
|
||||||
} else {
|
|
||||||
return this.reporter.error('Encoding of string type: ' + tag +
|
|
||||||
' unsupported');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {
|
|
||||||
if (typeof id === 'string') {
|
|
||||||
if (!values)
|
|
||||||
return this.reporter.error('string objid given, but no values map found');
|
|
||||||
if (!values.hasOwnProperty(id))
|
|
||||||
return this.reporter.error('objid not found in values map');
|
|
||||||
id = values[id].split(/[\s.]+/g);
|
|
||||||
for (let i = 0; i < id.length; i++)
|
|
||||||
id[i] |= 0;
|
|
||||||
} else if (Array.isArray(id)) {
|
|
||||||
id = id.slice();
|
|
||||||
for (let i = 0; i < id.length; i++)
|
|
||||||
id[i] |= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Array.isArray(id)) {
|
|
||||||
return this.reporter.error('objid() should be either array or string, ' +
|
|
||||||
'got: ' + JSON.stringify(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!relative) {
|
|
||||||
if (id[1] >= 40)
|
|
||||||
return this.reporter.error('Second objid identifier OOB');
|
|
||||||
id.splice(0, 2, id[0] * 40 + id[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count number of octets
|
|
||||||
let size = 0;
|
|
||||||
for (let i = 0; i < id.length; i++) {
|
|
||||||
let ident = id[i];
|
|
||||||
for (size++; ident >= 0x80; ident >>= 7)
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
const objid = Buffer.alloc(size);
|
|
||||||
let offset = objid.length - 1;
|
|
||||||
for (let i = id.length - 1; i >= 0; i--) {
|
|
||||||
let ident = id[i];
|
|
||||||
objid[offset--] = ident & 0x7f;
|
|
||||||
while ((ident >>= 7) > 0)
|
|
||||||
objid[offset--] = 0x80 | (ident & 0x7f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._createEncoderBuffer(objid);
|
|
||||||
};
|
|
||||||
|
|
||||||
function two(num) {
|
|
||||||
if (num < 10)
|
|
||||||
return '0' + num;
|
|
||||||
else
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
DERNode.prototype._encodeTime = function encodeTime(time, tag) {
|
|
||||||
let str;
|
|
||||||
const date = new Date(time);
|
|
||||||
|
|
||||||
if (tag === 'gentime') {
|
|
||||||
str = [
|
|
||||||
two(date.getUTCFullYear()),
|
|
||||||
two(date.getUTCMonth() + 1),
|
|
||||||
two(date.getUTCDate()),
|
|
||||||
two(date.getUTCHours()),
|
|
||||||
two(date.getUTCMinutes()),
|
|
||||||
two(date.getUTCSeconds()),
|
|
||||||
'Z'
|
|
||||||
].join('');
|
|
||||||
} else if (tag === 'utctime') {
|
|
||||||
str = [
|
|
||||||
two(date.getUTCFullYear() % 100),
|
|
||||||
two(date.getUTCMonth() + 1),
|
|
||||||
two(date.getUTCDate()),
|
|
||||||
two(date.getUTCHours()),
|
|
||||||
two(date.getUTCMinutes()),
|
|
||||||
two(date.getUTCSeconds()),
|
|
||||||
'Z'
|
|
||||||
].join('');
|
|
||||||
} else {
|
|
||||||
this.reporter.error('Encoding ' + tag + ' time is not supported yet');
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._encodeStr(str, 'octstr');
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._encodeNull = function encodeNull() {
|
|
||||||
return this._createEncoderBuffer('');
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._encodeInt = function encodeInt(num, values) {
|
|
||||||
if (typeof num === 'string') {
|
|
||||||
if (!values)
|
|
||||||
return this.reporter.error('String int or enum given, but no values map');
|
|
||||||
if (!values.hasOwnProperty(num)) {
|
|
||||||
return this.reporter.error('Values map doesn\'t contain: ' +
|
|
||||||
JSON.stringify(num));
|
|
||||||
}
|
|
||||||
num = values[num];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bignum, assume big endian
|
|
||||||
if (typeof num !== 'number' && !Buffer.isBuffer(num)) {
|
|
||||||
const numArray = num.toArray();
|
|
||||||
if (!num.sign && numArray[0] & 0x80) {
|
|
||||||
numArray.unshift(0);
|
|
||||||
}
|
|
||||||
num = Buffer.from(numArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Buffer.isBuffer(num)) {
|
|
||||||
let size = num.length;
|
|
||||||
if (num.length === 0)
|
|
||||||
size++;
|
|
||||||
|
|
||||||
const out = Buffer.alloc(size);
|
|
||||||
num.copy(out);
|
|
||||||
if (num.length === 0)
|
|
||||||
out[0] = 0;
|
|
||||||
return this._createEncoderBuffer(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num < 0x80)
|
|
||||||
return this._createEncoderBuffer(num);
|
|
||||||
|
|
||||||
if (num < 0x100)
|
|
||||||
return this._createEncoderBuffer([0, num]);
|
|
||||||
|
|
||||||
let size = 1;
|
|
||||||
for (let i = num; i >= 0x100; i >>= 8)
|
|
||||||
size++;
|
|
||||||
|
|
||||||
const out = new Array(size);
|
|
||||||
for (let i = out.length - 1; i >= 0; i--) {
|
|
||||||
out[i] = num & 0xff;
|
|
||||||
num >>= 8;
|
|
||||||
}
|
|
||||||
if(out[0] & 0x80) {
|
|
||||||
out.unshift(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._createEncoderBuffer(Buffer.from(out));
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._encodeBool = function encodeBool(value) {
|
|
||||||
return this._createEncoderBuffer(value ? 0xff : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._use = function use(entity, obj) {
|
|
||||||
if (typeof entity === 'function')
|
|
||||||
entity = entity(obj);
|
|
||||||
return entity._getEncoder('der').tree;
|
|
||||||
};
|
|
||||||
|
|
||||||
DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {
|
|
||||||
const state = this._baseState;
|
|
||||||
let i;
|
|
||||||
if (state['default'] === null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const data = dataBuffer.join();
|
|
||||||
if (state.defaultBuffer === undefined)
|
|
||||||
state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();
|
|
||||||
|
|
||||||
if (data.length !== state.defaultBuffer.length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (i=0; i < data.length; i++)
|
|
||||||
if (data[i] !== state.defaultBuffer[i])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Utility methods
|
|
||||||
|
|
||||||
function encodeTag(tag, primitive, cls, reporter) {
|
|
||||||
let res;
|
|
||||||
|
|
||||||
if (tag === 'seqof')
|
|
||||||
tag = 'seq';
|
|
||||||
else if (tag === 'setof')
|
|
||||||
tag = 'set';
|
|
||||||
|
|
||||||
if (der.tagByName.hasOwnProperty(tag))
|
|
||||||
res = der.tagByName[tag];
|
|
||||||
else if (typeof tag === 'number' && (tag | 0) === tag)
|
|
||||||
res = tag;
|
|
||||||
else
|
|
||||||
return reporter.error('Unknown tag: ' + tag);
|
|
||||||
|
|
||||||
if (res >= 0x1f)
|
|
||||||
return reporter.error('Multi-octet tag encoding unsupported');
|
|
||||||
|
|
||||||
if (!primitive)
|
|
||||||
res |= 0x20;
|
|
||||||
|
|
||||||
res |= (der.tagClassByName[cls || 'universal'] << 6);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
6
node_modules/asn1.js/lib/asn1/encoders/index.js
generated
vendored
6
node_modules/asn1.js/lib/asn1/encoders/index.js
generated
vendored
|
@ -1,6 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const encoders = exports;
|
|
||||||
|
|
||||||
encoders.der = require('./der');
|
|
||||||
encoders.pem = require('./pem');
|
|
23
node_modules/asn1.js/lib/asn1/encoders/pem.js
generated
vendored
23
node_modules/asn1.js/lib/asn1/encoders/pem.js
generated
vendored
|
@ -1,23 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const inherits = require('inherits');
|
|
||||||
|
|
||||||
const DEREncoder = require('./der');
|
|
||||||
|
|
||||||
function PEMEncoder(entity) {
|
|
||||||
DEREncoder.call(this, entity);
|
|
||||||
this.enc = 'pem';
|
|
||||||
}
|
|
||||||
inherits(PEMEncoder, DEREncoder);
|
|
||||||
module.exports = PEMEncoder;
|
|
||||||
|
|
||||||
PEMEncoder.prototype.encode = function encode(data, options) {
|
|
||||||
const buf = DEREncoder.prototype.encode.call(this, data);
|
|
||||||
|
|
||||||
const p = buf.toString('base64');
|
|
||||||
const out = [ '-----BEGIN ' + options.label + '-----' ];
|
|
||||||
for (let i = 0; i < p.length; i += 64)
|
|
||||||
out.push(p.slice(i, i + 64));
|
|
||||||
out.push('-----END ' + options.label + '-----');
|
|
||||||
return out.join('\n');
|
|
||||||
};
|
|
36
node_modules/asn1.js/package.json
generated
vendored
36
node_modules/asn1.js/package.json
generated
vendored
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"name": "asn1.js",
|
|
||||||
"version": "5.4.1",
|
|
||||||
"description": "ASN.1 encoder and decoder",
|
|
||||||
"main": "lib/asn1.js",
|
|
||||||
"scripts": {
|
|
||||||
"lint-2560": "eslint --fix rfc/2560/*.js rfc/2560/test/*.js",
|
|
||||||
"lint-5280": "eslint --fix rfc/5280/*.js rfc/5280/test/*.js",
|
|
||||||
"lint": "eslint --fix lib/*.js lib/**/*.js lib/**/**/*.js && npm run lint-2560 && npm run lint-5280",
|
|
||||||
"test": "mocha --reporter spec test/*-test.js && cd rfc/2560 && npm i && npm test && cd ../../rfc/5280 && npm i && npm test && cd ../../ && npm run lint"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@github.com:indutny/asn1.js"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"asn.1",
|
|
||||||
"der"
|
|
||||||
],
|
|
||||||
"author": "Fedor Indutny",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/indutny/asn1.js/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/indutny/asn1.js",
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^4.10.0",
|
|
||||||
"mocha": "^7.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"bn.js": "^4.0.0",
|
|
||||||
"inherits": "^2.0.1",
|
|
||||||
"minimalistic-assert": "^1.0.0",
|
|
||||||
"safer-buffer": "^2.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
221
node_modules/bn.js/README.md
generated
vendored
221
node_modules/bn.js/README.md
generated
vendored
|
@ -1,221 +0,0 @@
|
||||||
# <img src="./logo.png" alt="bn.js" width="160" height="160" />
|
|
||||||
|
|
||||||
> BigNum in pure javascript
|
|
||||||
|
|
||||||
[![Build Status](https://secure.travis-ci.org/indutny/bn.js.png)](http://travis-ci.org/indutny/bn.js)
|
|
||||||
|
|
||||||
## Install
|
|
||||||
`npm install --save bn.js`
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
const BN = require('bn.js');
|
|
||||||
|
|
||||||
var a = new BN('dead', 16);
|
|
||||||
var b = new BN('101010', 2);
|
|
||||||
|
|
||||||
var res = a.add(b);
|
|
||||||
console.log(res.toString(10)); // 57047
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note**: decimals are not supported in this library.
|
|
||||||
|
|
||||||
## Notation
|
|
||||||
|
|
||||||
### Prefixes
|
|
||||||
|
|
||||||
There are several prefixes to instructions that affect the way the work. Here
|
|
||||||
is the list of them in the order of appearance in the function name:
|
|
||||||
|
|
||||||
* `i` - perform operation in-place, storing the result in the host object (on
|
|
||||||
which the method was invoked). Might be used to avoid number allocation costs
|
|
||||||
* `u` - unsigned, ignore the sign of operands when performing operation, or
|
|
||||||
always return positive value. Second case applies to reduction operations
|
|
||||||
like `mod()`. In such cases if the result will be negative - modulo will be
|
|
||||||
added to the result to make it positive
|
|
||||||
|
|
||||||
### Postfixes
|
|
||||||
|
|
||||||
The only available postfix at the moment is:
|
|
||||||
|
|
||||||
* `n` - which means that the argument of the function must be a plain JavaScript
|
|
||||||
Number. Decimals are not supported.
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
* `a.iadd(b)` - perform addition on `a` and `b`, storing the result in `a`
|
|
||||||
* `a.umod(b)` - reduce `a` modulo `b`, returning positive value
|
|
||||||
* `a.iushln(13)` - shift bits of `a` left by 13
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
Prefixes/postfixes are put in parens at the of the line. `endian` - could be
|
|
||||||
either `le` (little-endian) or `be` (big-endian).
|
|
||||||
|
|
||||||
### Utilities
|
|
||||||
|
|
||||||
* `a.clone()` - clone number
|
|
||||||
* `a.toString(base, length)` - convert to base-string and pad with zeroes
|
|
||||||
* `a.toNumber()` - convert to Javascript Number (limited to 53 bits)
|
|
||||||
* `a.toJSON()` - convert to JSON compatible hex string (alias of `toString(16)`)
|
|
||||||
* `a.toArray(endian, length)` - convert to byte `Array`, and optionally zero
|
|
||||||
pad to length, throwing if already exceeding
|
|
||||||
* `a.toArrayLike(type, endian, length)` - convert to an instance of `type`,
|
|
||||||
which must behave like an `Array`
|
|
||||||
* `a.toBuffer(endian, length)` - convert to Node.js Buffer (if available). For
|
|
||||||
compatibility with browserify and similar tools, use this instead:
|
|
||||||
`a.toArrayLike(Buffer, endian, length)`
|
|
||||||
* `a.bitLength()` - get number of bits occupied
|
|
||||||
* `a.zeroBits()` - return number of less-significant consequent zero bits
|
|
||||||
(example: `1010000` has 4 zero bits)
|
|
||||||
* `a.byteLength()` - return number of bytes occupied
|
|
||||||
* `a.isNeg()` - true if the number is negative
|
|
||||||
* `a.isEven()` - no comments
|
|
||||||
* `a.isOdd()` - no comments
|
|
||||||
* `a.isZero()` - no comments
|
|
||||||
* `a.cmp(b)` - compare numbers and return `-1` (a `<` b), `0` (a `==` b), or `1` (a `>` b)
|
|
||||||
depending on the comparison result (`ucmp`, `cmpn`)
|
|
||||||
* `a.lt(b)` - `a` less than `b` (`n`)
|
|
||||||
* `a.lte(b)` - `a` less than or equals `b` (`n`)
|
|
||||||
* `a.gt(b)` - `a` greater than `b` (`n`)
|
|
||||||
* `a.gte(b)` - `a` greater than or equals `b` (`n`)
|
|
||||||
* `a.eq(b)` - `a` equals `b` (`n`)
|
|
||||||
* `a.toTwos(width)` - convert to two's complement representation, where `width` is bit width
|
|
||||||
* `a.fromTwos(width)` - convert from two's complement representation, where `width` is the bit width
|
|
||||||
* `BN.isBN(object)` - returns true if the supplied `object` is a BN.js instance
|
|
||||||
|
|
||||||
### Arithmetics
|
|
||||||
|
|
||||||
* `a.neg()` - negate sign (`i`)
|
|
||||||
* `a.abs()` - absolute value (`i`)
|
|
||||||
* `a.add(b)` - addition (`i`, `n`, `in`)
|
|
||||||
* `a.sub(b)` - subtraction (`i`, `n`, `in`)
|
|
||||||
* `a.mul(b)` - multiply (`i`, `n`, `in`)
|
|
||||||
* `a.sqr()` - square (`i`)
|
|
||||||
* `a.pow(b)` - raise `a` to the power of `b`
|
|
||||||
* `a.div(b)` - divide (`divn`, `idivn`)
|
|
||||||
* `a.mod(b)` - reduct (`u`, `n`) (but no `umodn`)
|
|
||||||
* `a.divRound(b)` - rounded division
|
|
||||||
|
|
||||||
### Bit operations
|
|
||||||
|
|
||||||
* `a.or(b)` - or (`i`, `u`, `iu`)
|
|
||||||
* `a.and(b)` - and (`i`, `u`, `iu`, `andln`) (NOTE: `andln` is going to be replaced
|
|
||||||
with `andn` in future)
|
|
||||||
* `a.xor(b)` - xor (`i`, `u`, `iu`)
|
|
||||||
* `a.setn(b)` - set specified bit to `1`
|
|
||||||
* `a.shln(b)` - shift left (`i`, `u`, `iu`)
|
|
||||||
* `a.shrn(b)` - shift right (`i`, `u`, `iu`)
|
|
||||||
* `a.testn(b)` - test if specified bit is set
|
|
||||||
* `a.maskn(b)` - clear bits with indexes higher or equal to `b` (`i`)
|
|
||||||
* `a.bincn(b)` - add `1 << b` to the number
|
|
||||||
* `a.notn(w)` - not (for the width specified by `w`) (`i`)
|
|
||||||
|
|
||||||
### Reduction
|
|
||||||
|
|
||||||
* `a.gcd(b)` - GCD
|
|
||||||
* `a.egcd(b)` - Extended GCD results (`{ a: ..., b: ..., gcd: ... }`)
|
|
||||||
* `a.invm(b)` - inverse `a` modulo `b`
|
|
||||||
|
|
||||||
## Fast reduction
|
|
||||||
|
|
||||||
When doing lots of reductions using the same modulo, it might be beneficial to
|
|
||||||
use some tricks: like [Montgomery multiplication][0], or using special algorithm
|
|
||||||
for [Mersenne Prime][1].
|
|
||||||
|
|
||||||
### Reduction context
|
|
||||||
|
|
||||||
To enable this tricks one should create a reduction context:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var red = BN.red(num);
|
|
||||||
```
|
|
||||||
where `num` is just a BN instance.
|
|
||||||
|
|
||||||
Or:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var red = BN.red(primeName);
|
|
||||||
```
|
|
||||||
|
|
||||||
Where `primeName` is either of these [Mersenne Primes][1]:
|
|
||||||
|
|
||||||
* `'k256'`
|
|
||||||
* `'p224'`
|
|
||||||
* `'p192'`
|
|
||||||
* `'p25519'`
|
|
||||||
|
|
||||||
Or:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var red = BN.mont(num);
|
|
||||||
```
|
|
||||||
|
|
||||||
To reduce numbers with [Montgomery trick][0]. `.mont()` is generally faster than
|
|
||||||
`.red(num)`, but slower than `BN.red(primeName)`.
|
|
||||||
|
|
||||||
### Converting numbers
|
|
||||||
|
|
||||||
Before performing anything in reduction context - numbers should be converted
|
|
||||||
to it. Usually, this means that one should:
|
|
||||||
|
|
||||||
* Convert inputs to reducted ones
|
|
||||||
* Operate on them in reduction context
|
|
||||||
* Convert outputs back from the reduction context
|
|
||||||
|
|
||||||
Here is how one may convert numbers to `red`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var redA = a.toRed(red);
|
|
||||||
```
|
|
||||||
Where `red` is a reduction context created using instructions above
|
|
||||||
|
|
||||||
Here is how to convert them back:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var a = redA.fromRed();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Red instructions
|
|
||||||
|
|
||||||
Most of the instructions from the very start of this readme have their
|
|
||||||
counterparts in red context:
|
|
||||||
|
|
||||||
* `a.redAdd(b)`, `a.redIAdd(b)`
|
|
||||||
* `a.redSub(b)`, `a.redISub(b)`
|
|
||||||
* `a.redShl(num)`
|
|
||||||
* `a.redMul(b)`, `a.redIMul(b)`
|
|
||||||
* `a.redSqr()`, `a.redISqr()`
|
|
||||||
* `a.redSqrt()` - square root modulo reduction context's prime
|
|
||||||
* `a.redInvm()` - modular inverse of the number
|
|
||||||
* `a.redNeg()`
|
|
||||||
* `a.redPow(b)` - modular exponentiation
|
|
||||||
|
|
||||||
## LICENSE
|
|
||||||
|
|
||||||
This software is licensed under the MIT License.
|
|
||||||
|
|
||||||
Copyright Fedor Indutny, 2015.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||||
persons to whom the Software is furnished to do so, subject to the
|
|
||||||
following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
|
||||||
in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
[0]: https://en.wikipedia.org/wiki/Montgomery_modular_multiplication
|
|
||||||
[1]: https://en.wikipedia.org/wiki/Mersenne_prime
|
|
3433
node_modules/bn.js/lib/bn.js
generated
vendored
3433
node_modules/bn.js/lib/bn.js
generated
vendored
File diff suppressed because it is too large
Load diff
36
node_modules/bn.js/package.json
generated
vendored
36
node_modules/bn.js/package.json
generated
vendored
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"name": "bn.js",
|
|
||||||
"version": "4.11.9",
|
|
||||||
"description": "Big number implementation in pure javascript",
|
|
||||||
"main": "lib/bn.js",
|
|
||||||
"scripts": {
|
|
||||||
"lint": "semistandard",
|
|
||||||
"unit": "mocha --reporter=spec test/*-test.js",
|
|
||||||
"test": "npm run lint && npm run unit"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@github.com:indutny/bn.js"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"BN",
|
|
||||||
"BigNum",
|
|
||||||
"Big number",
|
|
||||||
"Modulo",
|
|
||||||
"Montgomery"
|
|
||||||
],
|
|
||||||
"author": "Fedor Indutny <fedor@indutny.com>",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/indutny/bn.js/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/indutny/bn.js",
|
|
||||||
"browser": {
|
|
||||||
"buffer": false
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"istanbul": "^0.3.5",
|
|
||||||
"mocha": "^2.1.0",
|
|
||||||
"semistandard": "^7.0.4"
|
|
||||||
}
|
|
||||||
}
|
|
65
node_modules/bn.js/util/genCombMulTo.js
generated
vendored
65
node_modules/bn.js/util/genCombMulTo.js
generated
vendored
|
@ -1,65 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// NOTE: This could be potentionally used to generate loop-less multiplications
|
|
||||||
function genCombMulTo (alen, blen) {
|
|
||||||
var len = alen + blen - 1;
|
|
||||||
var src = [
|
|
||||||
'var a = self.words;',
|
|
||||||
'var b = num.words;',
|
|
||||||
'var o = out.words;',
|
|
||||||
'var c = 0;',
|
|
||||||
'var lo;',
|
|
||||||
'var mid;',
|
|
||||||
'var hi;'
|
|
||||||
];
|
|
||||||
for (var i = 0; i < alen; i++) {
|
|
||||||
src.push('var a' + i + ' = a[' + i + '] | 0;');
|
|
||||||
src.push('var al' + i + ' = a' + i + ' & 0x1fff;');
|
|
||||||
src.push('var ah' + i + ' = a' + i + ' >>> 13;');
|
|
||||||
}
|
|
||||||
for (i = 0; i < blen; i++) {
|
|
||||||
src.push('var b' + i + ' = b[' + i + '] | 0;');
|
|
||||||
src.push('var bl' + i + ' = b' + i + ' & 0x1fff;');
|
|
||||||
src.push('var bh' + i + ' = b' + i + ' >>> 13;');
|
|
||||||
}
|
|
||||||
src.push('');
|
|
||||||
src.push('out.negative = self.negative ^ num.negative;');
|
|
||||||
src.push('out.length = ' + len + ';');
|
|
||||||
|
|
||||||
for (var k = 0; k < len; k++) {
|
|
||||||
var minJ = Math.max(0, k - alen + 1);
|
|
||||||
var maxJ = Math.min(k, blen - 1);
|
|
||||||
|
|
||||||
src.push('\/* k = ' + k + ' *\/');
|
|
||||||
src.push('var w' + k + ' = c;');
|
|
||||||
src.push('c = 0;');
|
|
||||||
for (var j = minJ; j <= maxJ; j++) {
|
|
||||||
i = k - j;
|
|
||||||
|
|
||||||
src.push('lo = Math.imul(al' + i + ', bl' + j + ');');
|
|
||||||
src.push('mid = Math.imul(al' + i + ', bh' + j + ');');
|
|
||||||
src.push('mid = (mid + Math.imul(ah' + i + ', bl' + j + ')) | 0;');
|
|
||||||
src.push('hi = Math.imul(ah' + i + ', bh' + j + ');');
|
|
||||||
|
|
||||||
src.push('w' + k + ' = (w' + k + ' + lo) | 0;');
|
|
||||||
src.push('w' + k + ' = (w' + k + ' + ((mid & 0x1fff) << 13)) | 0;');
|
|
||||||
src.push('c = (c + hi) | 0;');
|
|
||||||
src.push('c = (c + (mid >>> 13)) | 0;');
|
|
||||||
src.push('c = (c + (w' + k + ' >>> 26)) | 0;');
|
|
||||||
src.push('w' + k + ' &= 0x3ffffff;');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Store in separate step for better memory access
|
|
||||||
for (k = 0; k < len; k++) {
|
|
||||||
src.push('o[' + k + '] = w' + k + ';');
|
|
||||||
}
|
|
||||||
src.push('if (c !== 0) {',
|
|
||||||
' o[' + k + '] = c;',
|
|
||||||
' out.length++;',
|
|
||||||
'}',
|
|
||||||
'return out;');
|
|
||||||
|
|
||||||
return src.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(genCombMulTo(10, 10));
|
|
65
node_modules/bn.js/util/genCombMulTo10.js
generated
vendored
65
node_modules/bn.js/util/genCombMulTo10.js
generated
vendored
|
@ -1,65 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function genCombMulTo (alen, blen) {
|
|
||||||
var len = alen + blen - 1;
|
|
||||||
var src = [
|
|
||||||
'var a = self.words;',
|
|
||||||
'var b = num.words;',
|
|
||||||
'var o = out.words;',
|
|
||||||
'var c = 0;',
|
|
||||||
'var lo;',
|
|
||||||
'var mid;',
|
|
||||||
'var hi;'
|
|
||||||
];
|
|
||||||
for (var i = 0; i < alen; i++) {
|
|
||||||
src.push('var a' + i + ' = a[' + i + '] | 0;');
|
|
||||||
src.push('var al' + i + ' = a' + i + ' & 0x1fff;');
|
|
||||||
src.push('var ah' + i + ' = a' + i + ' >>> 13;');
|
|
||||||
}
|
|
||||||
for (i = 0; i < blen; i++) {
|
|
||||||
src.push('var b' + i + ' = b[' + i + '] | 0;');
|
|
||||||
src.push('var bl' + i + ' = b' + i + ' & 0x1fff;');
|
|
||||||
src.push('var bh' + i + ' = b' + i + ' >>> 13;');
|
|
||||||
}
|
|
||||||
src.push('');
|
|
||||||
src.push('out.negative = self.negative ^ num.negative;');
|
|
||||||
src.push('out.length = ' + len + ';');
|
|
||||||
|
|
||||||
for (var k = 0; k < len; k++) {
|
|
||||||
var minJ = Math.max(0, k - alen + 1);
|
|
||||||
var maxJ = Math.min(k, blen - 1);
|
|
||||||
|
|
||||||
src.push('\/* k = ' + k + ' *\/');
|
|
||||||
src.push('lo = Math.imul(al' + (k - minJ) + ', bl' + minJ + ');');
|
|
||||||
src.push('mid = Math.imul(al' + (k - minJ) + ', bh' + minJ + ');');
|
|
||||||
src.push(
|
|
||||||
'mid = (mid + Math.imul(ah' + (k - minJ) + ', bl' + minJ + ')) | 0;');
|
|
||||||
src.push('hi = Math.imul(ah' + (k - minJ) + ', bh' + minJ + ');');
|
|
||||||
|
|
||||||
for (var j = minJ + 1; j <= maxJ; j++) {
|
|
||||||
i = k - j;
|
|
||||||
|
|
||||||
src.push('lo = (lo + Math.imul(al' + i + ', bl' + j + ')) | 0;');
|
|
||||||
src.push('mid = (mid + Math.imul(al' + i + ', bh' + j + ')) | 0;');
|
|
||||||
src.push('mid = (mid + Math.imul(ah' + i + ', bl' + j + ')) | 0;');
|
|
||||||
src.push('hi = (hi + Math.imul(ah' + i + ', bh' + j + ')) | 0;');
|
|
||||||
}
|
|
||||||
|
|
||||||
src.push('var w' + k + ' = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;');
|
|
||||||
src.push('c = (((hi + (mid >>> 13)) | 0) + (w' + k + ' >>> 26)) | 0;');
|
|
||||||
src.push('w' + k + ' &= 0x3ffffff;');
|
|
||||||
}
|
|
||||||
// Store in separate step for better memory access
|
|
||||||
for (k = 0; k < len; k++) {
|
|
||||||
src.push('o[' + k + '] = w' + k + ';');
|
|
||||||
}
|
|
||||||
src.push('if (c !== 0) {',
|
|
||||||
' o[' + k + '] = c;',
|
|
||||||
' out.length++;',
|
|
||||||
'}',
|
|
||||||
'return out;');
|
|
||||||
|
|
||||||
return src.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(genCombMulTo(10, 10));
|
|
16
node_modules/inherits/LICENSE
generated
vendored
16
node_modules/inherits/LICENSE
generated
vendored
|
@ -1,16 +0,0 @@
|
||||||
The ISC License
|
|
||||||
|
|
||||||
Copyright (c) Isaac Z. Schlueter
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
42
node_modules/inherits/README.md
generated
vendored
42
node_modules/inherits/README.md
generated
vendored
|
@ -1,42 +0,0 @@
|
||||||
Browser-friendly inheritance fully compatible with standard node.js
|
|
||||||
[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
|
|
||||||
|
|
||||||
This package exports standard `inherits` from node.js `util` module in
|
|
||||||
node environment, but also provides alternative browser-friendly
|
|
||||||
implementation through [browser
|
|
||||||
field](https://gist.github.com/shtylman/4339901). Alternative
|
|
||||||
implementation is a literal copy of standard one located in standalone
|
|
||||||
module to avoid requiring of `util`. It also has a shim for old
|
|
||||||
browsers with no `Object.create` support.
|
|
||||||
|
|
||||||
While keeping you sure you are using standard `inherits`
|
|
||||||
implementation in node.js environment, it allows bundlers such as
|
|
||||||
[browserify](https://github.com/substack/node-browserify) to not
|
|
||||||
include full `util` package to your client code if all you need is
|
|
||||||
just `inherits` function. It worth, because browser shim for `util`
|
|
||||||
package is large and `inherits` is often the single function you need
|
|
||||||
from it.
|
|
||||||
|
|
||||||
It's recommended to use this package instead of
|
|
||||||
`require('util').inherits` for any code that has chances to be used
|
|
||||||
not only in node.js but in browser too.
|
|
||||||
|
|
||||||
## usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
var inherits = require('inherits');
|
|
||||||
// then use exactly as the standard one
|
|
||||||
```
|
|
||||||
|
|
||||||
## note on version ~1.0
|
|
||||||
|
|
||||||
Version ~1.0 had completely different motivation and is not compatible
|
|
||||||
neither with 2.0 nor with standard node.js `inherits`.
|
|
||||||
|
|
||||||
If you are using version ~1.0 and planning to switch to ~2.0, be
|
|
||||||
careful:
|
|
||||||
|
|
||||||
* new version uses `super_` instead of `super` for referencing
|
|
||||||
superclass
|
|
||||||
* new version overwrites current prototype while old one preserves any
|
|
||||||
existing fields on it
|
|
9
node_modules/inherits/inherits.js
generated
vendored
9
node_modules/inherits/inherits.js
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
try {
|
|
||||||
var util = require('util');
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (typeof util.inherits !== 'function') throw '';
|
|
||||||
module.exports = util.inherits;
|
|
||||||
} catch (e) {
|
|
||||||
/* istanbul ignore next */
|
|
||||||
module.exports = require('./inherits_browser.js');
|
|
||||||
}
|
|
27
node_modules/inherits/inherits_browser.js
generated
vendored
27
node_modules/inherits/inherits_browser.js
generated
vendored
|
@ -1,27 +0,0 @@
|
||||||
if (typeof Object.create === 'function') {
|
|
||||||
// implementation from standard node.js 'util' module
|
|
||||||
module.exports = function inherits(ctor, superCtor) {
|
|
||||||
if (superCtor) {
|
|
||||||
ctor.super_ = superCtor
|
|
||||||
ctor.prototype = Object.create(superCtor.prototype, {
|
|
||||||
constructor: {
|
|
||||||
value: ctor,
|
|
||||||
enumerable: false,
|
|
||||||
writable: true,
|
|
||||||
configurable: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// old school shim for old browsers
|
|
||||||
module.exports = function inherits(ctor, superCtor) {
|
|
||||||
if (superCtor) {
|
|
||||||
ctor.super_ = superCtor
|
|
||||||
var TempCtor = function () {}
|
|
||||||
TempCtor.prototype = superCtor.prototype
|
|
||||||
ctor.prototype = new TempCtor()
|
|
||||||
ctor.prototype.constructor = ctor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
29
node_modules/inherits/package.json
generated
vendored
29
node_modules/inherits/package.json
generated
vendored
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"name": "inherits",
|
|
||||||
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
|
|
||||||
"version": "2.0.4",
|
|
||||||
"keywords": [
|
|
||||||
"inheritance",
|
|
||||||
"class",
|
|
||||||
"klass",
|
|
||||||
"oop",
|
|
||||||
"object-oriented",
|
|
||||||
"inherits",
|
|
||||||
"browser",
|
|
||||||
"browserify"
|
|
||||||
],
|
|
||||||
"main": "./inherits.js",
|
|
||||||
"browser": "./inherits_browser.js",
|
|
||||||
"repository": "git://github.com/isaacs/inherits",
|
|
||||||
"license": "ISC",
|
|
||||||
"scripts": {
|
|
||||||
"test": "tap"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"tap": "^14.2.4"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"inherits.js",
|
|
||||||
"inherits_browser.js"
|
|
||||||
]
|
|
||||||
}
|
|
13
node_modules/minimalistic-assert/LICENSE
generated
vendored
13
node_modules/minimalistic-assert/LICENSE
generated
vendored
|
@ -1,13 +0,0 @@
|
||||||
Copyright 2015 Calvin Metcalf
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
||||||
with or without fee is hereby granted, provided that the above copyright notice
|
|
||||||
and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
||||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
|
11
node_modules/minimalistic-assert/index.js
generated
vendored
11
node_modules/minimalistic-assert/index.js
generated
vendored
|
@ -1,11 +0,0 @@
|
||||||
module.exports = assert;
|
|
||||||
|
|
||||||
function assert(val, msg) {
|
|
||||||
if (!val)
|
|
||||||
throw new Error(msg || 'Assertion failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.equal = function assertEqual(l, r, msg) {
|
|
||||||
if (l != r)
|
|
||||||
throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
|
|
||||||
};
|
|
19
node_modules/minimalistic-assert/package.json
generated
vendored
19
node_modules/minimalistic-assert/package.json
generated
vendored
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"name": "minimalistic-assert",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"description": "minimalistic-assert ===",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/calvinmetcalf/minimalistic-assert.git"
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/calvinmetcalf/minimalistic-assert/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/calvinmetcalf/minimalistic-assert"
|
|
||||||
}
|
|
4
node_modules/minimalistic-assert/readme.md
generated
vendored
4
node_modules/minimalistic-assert/readme.md
generated
vendored
|
@ -1,4 +0,0 @@
|
||||||
minimalistic-assert
|
|
||||||
===
|
|
||||||
|
|
||||||
very minimalistic assert module.
|
|
21
node_modules/safer-buffer/LICENSE
generated
vendored
21
node_modules/safer-buffer/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2018 Nikita Skovoroda <chalkerx@gmail.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
268
node_modules/safer-buffer/Porting-Buffer.md
generated
vendored
268
node_modules/safer-buffer/Porting-Buffer.md
generated
vendored
|
@ -1,268 +0,0 @@
|
||||||
# Porting to the Buffer.from/Buffer.alloc API
|
|
||||||
|
|
||||||
<a id="overview"></a>
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
- [Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.](#variant-1) (*recommended*)
|
|
||||||
- [Variant 2: Use a polyfill](#variant-2)
|
|
||||||
- [Variant 3: manual detection, with safeguards](#variant-3)
|
|
||||||
|
|
||||||
### Finding problematic bits of code using grep
|
|
||||||
|
|
||||||
Just run `grep -nrE '[^a-zA-Z](Slow)?Buffer\s*\(' --exclude-dir node_modules`.
|
|
||||||
|
|
||||||
It will find all the potentially unsafe places in your own code (with some considerably unlikely
|
|
||||||
exceptions).
|
|
||||||
|
|
||||||
### Finding problematic bits of code using Node.js 8
|
|
||||||
|
|
||||||
If you’re using Node.js ≥ 8.0.0 (which is recommended), Node.js exposes multiple options that help with finding the relevant pieces of code:
|
|
||||||
|
|
||||||
- `--trace-warnings` will make Node.js show a stack trace for this warning and other warnings that are printed by Node.js.
|
|
||||||
- `--trace-deprecation` does the same thing, but only for deprecation warnings.
|
|
||||||
- `--pending-deprecation` will show more types of deprecation warnings. In particular, it will show the `Buffer()` deprecation warning, even on Node.js 8.
|
|
||||||
|
|
||||||
You can set these flags using an environment variable:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ export NODE_OPTIONS='--trace-warnings --pending-deprecation'
|
|
||||||
$ cat example.js
|
|
||||||
'use strict';
|
|
||||||
const foo = new Buffer('foo');
|
|
||||||
$ node example.js
|
|
||||||
(node:7147) [DEP0005] DeprecationWarning: The Buffer() and new Buffer() constructors are not recommended for use due to security and usability concerns. Please use the new Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() construction methods instead.
|
|
||||||
at showFlaggedDeprecation (buffer.js:127:13)
|
|
||||||
at new Buffer (buffer.js:148:3)
|
|
||||||
at Object.<anonymous> (/path/to/example.js:2:13)
|
|
||||||
[... more stack trace lines ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Finding problematic bits of code using linters
|
|
||||||
|
|
||||||
Eslint rules [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
||||||
or
|
|
||||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
||||||
also find calls to deprecated `Buffer()` API. Those rules are included in some pre-sets.
|
|
||||||
|
|
||||||
There is a drawback, though, that it doesn't always
|
|
||||||
[work correctly](https://github.com/chalker/safer-buffer#why-not-safe-buffer) when `Buffer` is
|
|
||||||
overriden e.g. with a polyfill, so recommended is a combination of this and some other method
|
|
||||||
described above.
|
|
||||||
|
|
||||||
<a id="variant-1"></a>
|
|
||||||
## Variant 1: Drop support for Node.js ≤ 4.4.x and 5.0.0 — 5.9.x.
|
|
||||||
|
|
||||||
This is the recommended solution nowadays that would imply only minimal overhead.
|
|
||||||
|
|
||||||
The Node.js 5.x release line has been unsupported since July 2016, and the Node.js 4.x release line reaches its End of Life in April 2018 (→ [Schedule](https://github.com/nodejs/Release#release-schedule)). This means that these versions of Node.js will *not* receive any updates, even in case of security issues, so using these release lines should be avoided, if at all possible.
|
|
||||||
|
|
||||||
What you would do in this case is to convert all `new Buffer()` or `Buffer()` calls to use `Buffer.alloc()` or `Buffer.from()`, in the following way:
|
|
||||||
|
|
||||||
- For `new Buffer(number)`, replace it with `Buffer.alloc(number)`.
|
|
||||||
- For `new Buffer(string)` (or `new Buffer(string, encoding)`), replace it with `Buffer.from(string)` (or `Buffer.from(string, encoding)`).
|
|
||||||
- For all other combinations of arguments (these are much rarer), also replace `new Buffer(...arguments)` with `Buffer.from(...arguments)`.
|
|
||||||
|
|
||||||
Note that `Buffer.alloc()` is also _faster_ on the current Node.js versions than
|
|
||||||
`new Buffer(size).fill(0)`, which is what you would otherwise need to ensure zero-filling.
|
|
||||||
|
|
||||||
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
||||||
or
|
|
||||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
||||||
is recommended to avoid accidential unsafe Buffer API usage.
|
|
||||||
|
|
||||||
There is also a [JSCodeshift codemod](https://github.com/joyeecheung/node-dep-codemod#dep005)
|
|
||||||
for automatically migrating Buffer constructors to `Buffer.alloc()` or `Buffer.from()`.
|
|
||||||
Note that it currently only works with cases where the arguments are literals or where the
|
|
||||||
constructor is invoked with two arguments.
|
|
||||||
|
|
||||||
_If you currently support those older Node.js versions and dropping them would be a semver-major change
|
|
||||||
for you, or if you support older branches of your packages, consider using [Variant 2](#variant-2)
|
|
||||||
or [Variant 3](#variant-3) on older branches, so people using those older branches will also receive
|
|
||||||
the fix. That way, you will eradicate potential issues caused by unguarded Buffer API usage and
|
|
||||||
your users will not observe a runtime deprecation warning when running your code on Node.js 10._
|
|
||||||
|
|
||||||
<a id="variant-2"></a>
|
|
||||||
## Variant 2: Use a polyfill
|
|
||||||
|
|
||||||
Utilize [safer-buffer](https://www.npmjs.com/package/safer-buffer) as a polyfill to support older
|
|
||||||
Node.js versions.
|
|
||||||
|
|
||||||
You would take exacly the same steps as in [Variant 1](#variant-1), but with a polyfill
|
|
||||||
`const Buffer = require('safer-buffer').Buffer` in all files where you use the new `Buffer` api.
|
|
||||||
|
|
||||||
Make sure that you do not use old `new Buffer` API — in any files where the line above is added,
|
|
||||||
using old `new Buffer()` API will _throw_. It will be easy to notice that in CI, though.
|
|
||||||
|
|
||||||
Alternatively, you could use [buffer-from](https://www.npmjs.com/package/buffer-from) and/or
|
|
||||||
[buffer-alloc](https://www.npmjs.com/package/buffer-alloc) [ponyfills](https://ponyfill.com/) —
|
|
||||||
those are great, the only downsides being 4 deps in the tree and slightly more code changes to
|
|
||||||
migrate off them (as you would be using e.g. `Buffer.from` under a different name). If you need only
|
|
||||||
`Buffer.from` polyfilled — `buffer-from` alone which comes with no extra dependencies.
|
|
||||||
|
|
||||||
_Alternatively, you could use [safe-buffer](https://www.npmjs.com/package/safe-buffer) — it also
|
|
||||||
provides a polyfill, but takes a different approach which has
|
|
||||||
[it's drawbacks](https://github.com/chalker/safer-buffer#why-not-safe-buffer). It will allow you
|
|
||||||
to also use the older `new Buffer()` API in your code, though — but that's arguably a benefit, as
|
|
||||||
it is problematic, can cause issues in your code, and will start emitting runtime deprecation
|
|
||||||
warnings starting with Node.js 10._
|
|
||||||
|
|
||||||
Note that in either case, it is important that you also remove all calls to the old Buffer
|
|
||||||
API manually — just throwing in `safe-buffer` doesn't fix the problem by itself, it just provides
|
|
||||||
a polyfill for the new API. I have seen people doing that mistake.
|
|
||||||
|
|
||||||
Enabling eslint rule [no-buffer-constructor](https://eslint.org/docs/rules/no-buffer-constructor)
|
|
||||||
or
|
|
||||||
[node/no-deprecated-api](https://github.com/mysticatea/eslint-plugin-node/blob/master/docs/rules/no-deprecated-api.md)
|
|
||||||
is recommended.
|
|
||||||
|
|
||||||
_Don't forget to drop the polyfill usage once you drop support for Node.js < 4.5.0._
|
|
||||||
|
|
||||||
<a id="variant-3"></a>
|
|
||||||
## Variant 3 — manual detection, with safeguards
|
|
||||||
|
|
||||||
This is useful if you create Buffer instances in only a few places (e.g. one), or you have your own
|
|
||||||
wrapper around them.
|
|
||||||
|
|
||||||
### Buffer(0)
|
|
||||||
|
|
||||||
This special case for creating empty buffers can be safely replaced with `Buffer.concat([])`, which
|
|
||||||
returns the same result all the way down to Node.js 0.8.x.
|
|
||||||
|
|
||||||
### Buffer(notNumber)
|
|
||||||
|
|
||||||
Before:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var buf = new Buffer(notNumber, encoding);
|
|
||||||
```
|
|
||||||
|
|
||||||
After:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var buf;
|
|
||||||
if (Buffer.from && Buffer.from !== Uint8Array.from) {
|
|
||||||
buf = Buffer.from(notNumber, encoding);
|
|
||||||
} else {
|
|
||||||
if (typeof notNumber === 'number')
|
|
||||||
throw new Error('The "size" argument must be of type number.');
|
|
||||||
buf = new Buffer(notNumber, encoding);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`encoding` is optional.
|
|
||||||
|
|
||||||
Note that the `typeof notNumber` before `new Buffer` is required (for cases when `notNumber` argument is not
|
|
||||||
hard-coded) and _is not caused by the deprecation of Buffer constructor_ — it's exactly _why_ the
|
|
||||||
Buffer constructor is deprecated. Ecosystem packages lacking this type-check caused numereous
|
|
||||||
security issues — situations when unsanitized user input could end up in the `Buffer(arg)` create
|
|
||||||
problems ranging from DoS to leaking sensitive information to the attacker from the process memory.
|
|
||||||
|
|
||||||
When `notNumber` argument is hardcoded (e.g. literal `"abc"` or `[0,1,2]`), the `typeof` check can
|
|
||||||
be omitted.
|
|
||||||
|
|
||||||
Also note that using TypeScript does not fix this problem for you — when libs written in
|
|
||||||
`TypeScript` are used from JS, or when user input ends up there — it behaves exactly as pure JS, as
|
|
||||||
all type checks are translation-time only and are not present in the actual JS code which TS
|
|
||||||
compiles to.
|
|
||||||
|
|
||||||
### Buffer(number)
|
|
||||||
|
|
||||||
For Node.js 0.10.x (and below) support:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var buf;
|
|
||||||
if (Buffer.alloc) {
|
|
||||||
buf = Buffer.alloc(number);
|
|
||||||
} else {
|
|
||||||
buf = new Buffer(number);
|
|
||||||
buf.fill(0);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Otherwise (Node.js ≥ 0.12.x):
|
|
||||||
|
|
||||||
```js
|
|
||||||
const buf = Buffer.alloc ? Buffer.alloc(number) : new Buffer(number).fill(0);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Regarding Buffer.allocUnsafe
|
|
||||||
|
|
||||||
Be extra cautious when using `Buffer.allocUnsafe`:
|
|
||||||
* Don't use it if you don't have a good reason to
|
|
||||||
* e.g. you probably won't ever see a performance difference for small buffers, in fact, those
|
|
||||||
might be even faster with `Buffer.alloc()`,
|
|
||||||
* if your code is not in the hot code path — you also probably won't notice a difference,
|
|
||||||
* keep in mind that zero-filling minimizes the potential risks.
|
|
||||||
* If you use it, make sure that you never return the buffer in a partially-filled state,
|
|
||||||
* if you are writing to it sequentially — always truncate it to the actuall written length
|
|
||||||
|
|
||||||
Errors in handling buffers allocated with `Buffer.allocUnsafe` could result in various issues,
|
|
||||||
ranged from undefined behaviour of your code to sensitive data (user input, passwords, certs)
|
|
||||||
leaking to the remote attacker.
|
|
||||||
|
|
||||||
_Note that the same applies to `new Buffer` usage without zero-filling, depending on the Node.js
|
|
||||||
version (and lacking type checks also adds DoS to the list of potential problems)._
|
|
||||||
|
|
||||||
<a id="faq"></a>
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
<a id="design-flaws"></a>
|
|
||||||
### What is wrong with the `Buffer` constructor?
|
|
||||||
|
|
||||||
The `Buffer` constructor could be used to create a buffer in many different ways:
|
|
||||||
|
|
||||||
- `new Buffer(42)` creates a `Buffer` of 42 bytes. Before Node.js 8, this buffer contained
|
|
||||||
*arbitrary memory* for performance reasons, which could include anything ranging from
|
|
||||||
program source code to passwords and encryption keys.
|
|
||||||
- `new Buffer('abc')` creates a `Buffer` that contains the UTF-8-encoded version of
|
|
||||||
the string `'abc'`. A second argument could specify another encoding: For example,
|
|
||||||
`new Buffer(string, 'base64')` could be used to convert a Base64 string into the original
|
|
||||||
sequence of bytes that it represents.
|
|
||||||
- There are several other combinations of arguments.
|
|
||||||
|
|
||||||
This meant that, in code like `var buffer = new Buffer(foo);`, *it is not possible to tell
|
|
||||||
what exactly the contents of the generated buffer are* without knowing the type of `foo`.
|
|
||||||
|
|
||||||
Sometimes, the value of `foo` comes from an external source. For example, this function
|
|
||||||
could be exposed as a service on a web server, converting a UTF-8 string into its Base64 form:
|
|
||||||
|
|
||||||
```
|
|
||||||
function stringToBase64(req, res) {
|
|
||||||
// The request body should have the format of `{ string: 'foobar' }`
|
|
||||||
const rawBytes = new Buffer(req.body.string)
|
|
||||||
const encoded = rawBytes.toString('base64')
|
|
||||||
res.end({ encoded: encoded })
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that this code does *not* validate the type of `req.body.string`:
|
|
||||||
|
|
||||||
- `req.body.string` is expected to be a string. If this is the case, all goes well.
|
|
||||||
- `req.body.string` is controlled by the client that sends the request.
|
|
||||||
- If `req.body.string` is the *number* `50`, the `rawBytes` would be 50 bytes:
|
|
||||||
- Before Node.js 8, the content would be uninitialized
|
|
||||||
- After Node.js 8, the content would be `50` bytes with the value `0`
|
|
||||||
|
|
||||||
Because of the missing type check, an attacker could intentionally send a number
|
|
||||||
as part of the request. Using this, they can either:
|
|
||||||
|
|
||||||
- Read uninitialized memory. This **will** leak passwords, encryption keys and other
|
|
||||||
kinds of sensitive information. (Information leak)
|
|
||||||
- Force the program to allocate a large amount of memory. For example, when specifying
|
|
||||||
`500000000` as the input value, each request will allocate 500MB of memory.
|
|
||||||
This can be used to either exhaust the memory available of a program completely
|
|
||||||
and make it crash, or slow it down significantly. (Denial of Service)
|
|
||||||
|
|
||||||
Both of these scenarios are considered serious security issues in a real-world
|
|
||||||
web server context.
|
|
||||||
|
|
||||||
when using `Buffer.from(req.body.string)` instead, passing a number will always
|
|
||||||
throw an exception instead, giving a controlled behaviour that can always be
|
|
||||||
handled by the program.
|
|
||||||
|
|
||||||
<a id="ecosystem-usage"></a>
|
|
||||||
### The `Buffer()` constructor has been deprecated for a while. Is this really an issue?
|
|
||||||
|
|
||||||
Surveys of code in the `npm` ecosystem have shown that the `Buffer()` constructor is still
|
|
||||||
widely used. This includes new code, and overall usage of such code has actually been
|
|
||||||
*increasing*.
|
|
156
node_modules/safer-buffer/Readme.md
generated
vendored
156
node_modules/safer-buffer/Readme.md
generated
vendored
|
@ -1,156 +0,0 @@
|
||||||
# safer-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![javascript style guide][standard-image]][standard-url] [![Security Responsible Disclosure][secuirty-image]][secuirty-url]
|
|
||||||
|
|
||||||
[travis-image]: https://travis-ci.org/ChALkeR/safer-buffer.svg?branch=master
|
|
||||||
[travis-url]: https://travis-ci.org/ChALkeR/safer-buffer
|
|
||||||
[npm-image]: https://img.shields.io/npm/v/safer-buffer.svg
|
|
||||||
[npm-url]: https://npmjs.org/package/safer-buffer
|
|
||||||
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
|
|
||||||
[standard-url]: https://standardjs.com
|
|
||||||
[secuirty-image]: https://img.shields.io/badge/Security-Responsible%20Disclosure-green.svg
|
|
||||||
[secuirty-url]: https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md
|
|
||||||
|
|
||||||
Modern Buffer API polyfill without footguns, working on Node.js from 0.8 to current.
|
|
||||||
|
|
||||||
## How to use?
|
|
||||||
|
|
||||||
First, port all `Buffer()` and `new Buffer()` calls to `Buffer.alloc()` and `Buffer.from()` API.
|
|
||||||
|
|
||||||
Then, to achieve compatibility with outdated Node.js versions (`<4.5.0` and 5.x `<5.9.0`), use
|
|
||||||
`const Buffer = require('safer-buffer').Buffer` in all files where you make calls to the new
|
|
||||||
Buffer API. _Use `var` instead of `const` if you need that for your Node.js version range support._
|
|
||||||
|
|
||||||
Also, see the
|
|
||||||
[porting Buffer](https://github.com/ChALkeR/safer-buffer/blob/master/Porting-Buffer.md) guide.
|
|
||||||
|
|
||||||
## Do I need it?
|
|
||||||
|
|
||||||
Hopefully, not — dropping support for outdated Node.js versions should be fine nowdays, and that
|
|
||||||
is the recommended path forward. You _do_ need to port to the `Buffer.alloc()` and `Buffer.from()`
|
|
||||||
though.
|
|
||||||
|
|
||||||
See the [porting guide](https://github.com/ChALkeR/safer-buffer/blob/master/Porting-Buffer.md)
|
|
||||||
for a better description.
|
|
||||||
|
|
||||||
## Why not [safe-buffer](https://npmjs.com/safe-buffer)?
|
|
||||||
|
|
||||||
_In short: while `safe-buffer` serves as a polyfill for the new API, it allows old API usage and
|
|
||||||
itself contains footguns._
|
|
||||||
|
|
||||||
`safe-buffer` could be used safely to get the new API while still keeping support for older
|
|
||||||
Node.js versions (like this module), but while analyzing ecosystem usage of the old Buffer API
|
|
||||||
I found out that `safe-buffer` is itself causing problems in some cases.
|
|
||||||
|
|
||||||
For example, consider the following snippet:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ cat example.unsafe.js
|
|
||||||
console.log(Buffer(20))
|
|
||||||
$ ./node-v6.13.0-linux-x64/bin/node example.unsafe.js
|
|
||||||
<Buffer 0a 00 00 00 00 00 00 00 28 13 de 02 00 00 00 00 05 00 00 00>
|
|
||||||
$ standard example.unsafe.js
|
|
||||||
standard: Use JavaScript Standard Style (https://standardjs.com)
|
|
||||||
/home/chalker/repo/safer-buffer/example.unsafe.js:2:13: 'Buffer()' was deprecated since v6. Use 'Buffer.alloc()' or 'Buffer.from()' (use 'https://www.npmjs.com/package/safe-buffer' for '<4.5.0') instead.
|
|
||||||
```
|
|
||||||
|
|
||||||
This is allocates and writes to console an uninitialized chunk of memory.
|
|
||||||
[standard](https://www.npmjs.com/package/standard) linter (among others) catch that and warn people
|
|
||||||
to avoid using unsafe API.
|
|
||||||
|
|
||||||
Let's now throw in `safe-buffer`!
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ cat example.safe-buffer.js
|
|
||||||
const Buffer = require('safe-buffer').Buffer
|
|
||||||
console.log(Buffer(20))
|
|
||||||
$ standard example.safe-buffer.js
|
|
||||||
$ ./node-v6.13.0-linux-x64/bin/node example.safe-buffer.js
|
|
||||||
<Buffer 08 00 00 00 00 00 00 00 28 58 01 82 fe 7f 00 00 00 00 00 00>
|
|
||||||
```
|
|
||||||
|
|
||||||
See the problem? Adding in `safe-buffer` _magically removes the lint warning_, but the behavior
|
|
||||||
remains identiсal to what we had before, and when launched on Node.js 6.x LTS — this dumps out
|
|
||||||
chunks of uninitialized memory.
|
|
||||||
_And this code will still emit runtime warnings on Node.js 10.x and above._
|
|
||||||
|
|
||||||
That was done by design. I first considered changing `safe-buffer`, prohibiting old API usage or
|
|
||||||
emitting warnings on it, but that significantly diverges from `safe-buffer` design. After some
|
|
||||||
discussion, it was decided to move my approach into a separate package, and _this is that separate
|
|
||||||
package_.
|
|
||||||
|
|
||||||
This footgun is not imaginary — I observed top-downloaded packages doing that kind of thing,
|
|
||||||
«fixing» the lint warning by blindly including `safe-buffer` without any actual changes.
|
|
||||||
|
|
||||||
Also in some cases, even if the API _was_ migrated to use of safe Buffer API — a random pull request
|
|
||||||
can bring unsafe Buffer API usage back to the codebase by adding new calls — and that could go
|
|
||||||
unnoticed even if you have a linter prohibiting that (becase of the reason stated above), and even
|
|
||||||
pass CI. _I also observed that being done in popular packages._
|
|
||||||
|
|
||||||
Some examples:
|
|
||||||
* [webdriverio](https://github.com/webdriverio/webdriverio/commit/05cbd3167c12e4930f09ef7cf93b127ba4effae4#diff-124380949022817b90b622871837d56cR31)
|
|
||||||
(a module with 548 759 downloads/month),
|
|
||||||
* [websocket-stream](https://github.com/maxogden/websocket-stream/commit/c9312bd24d08271687d76da0fe3c83493871cf61)
|
|
||||||
(218 288 d/m, fix in [maxogden/websocket-stream#142](https://github.com/maxogden/websocket-stream/pull/142)),
|
|
||||||
* [node-serialport](https://github.com/node-serialport/node-serialport/commit/e8d9d2b16c664224920ce1c895199b1ce2def48c)
|
|
||||||
(113 138 d/m, fix in [node-serialport/node-serialport#1510](https://github.com/node-serialport/node-serialport/pull/1510)),
|
|
||||||
* [karma](https://github.com/karma-runner/karma/commit/3d94b8cf18c695104ca195334dc75ff054c74eec)
|
|
||||||
(3 973 193 d/m, fix in [karma-runner/karma#2947](https://github.com/karma-runner/karma/pull/2947)),
|
|
||||||
* [spdy-transport](https://github.com/spdy-http2/spdy-transport/commit/5375ac33f4a62a4f65bcfc2827447d42a5dbe8b1)
|
|
||||||
(5 970 727 d/m, fix in [spdy-http2/spdy-transport#53](https://github.com/spdy-http2/spdy-transport/pull/53)).
|
|
||||||
* And there are a lot more over the ecosystem.
|
|
||||||
|
|
||||||
I filed a PR at
|
|
||||||
[mysticatea/eslint-plugin-node#110](https://github.com/mysticatea/eslint-plugin-node/pull/110) to
|
|
||||||
partially fix that (for cases when that lint rule is used), but it is a semver-major change for
|
|
||||||
linter rules and presets, so it would take significant time for that to reach actual setups.
|
|
||||||
_It also hasn't been released yet (2018-03-20)._
|
|
||||||
|
|
||||||
Also, `safer-buffer` discourages the usage of `.allocUnsafe()`, which is often done by a mistake.
|
|
||||||
It still supports it with an explicit concern barier, by placing it under
|
|
||||||
`require('safer-buffer/dangereous')`.
|
|
||||||
|
|
||||||
## But isn't throwing bad?
|
|
||||||
|
|
||||||
Not really. It's an error that could be noticed and fixed early, instead of causing havoc later like
|
|
||||||
unguarded `new Buffer()` calls that end up receiving user input can do.
|
|
||||||
|
|
||||||
This package affects only the files where `var Buffer = require('safer-buffer').Buffer` was done, so
|
|
||||||
it is really simple to keep track of things and make sure that you don't mix old API usage with that.
|
|
||||||
Also, CI should hint anything that you might have missed.
|
|
||||||
|
|
||||||
New commits, if tested, won't land new usage of unsafe Buffer API this way.
|
|
||||||
_Node.js 10.x also deals with that by printing a runtime depecation warning._
|
|
||||||
|
|
||||||
### Would it affect third-party modules?
|
|
||||||
|
|
||||||
No, unless you explicitly do an awful thing like monkey-patching or overriding the built-in `Buffer`.
|
|
||||||
Don't do that.
|
|
||||||
|
|
||||||
### But I don't want throwing…
|
|
||||||
|
|
||||||
That is also fine!
|
|
||||||
|
|
||||||
Also, it could be better in some cases when you don't comprehensive enough test coverage.
|
|
||||||
|
|
||||||
In that case — just don't override `Buffer` and use
|
|
||||||
`var SaferBuffer = require('safer-buffer').Buffer` instead.
|
|
||||||
|
|
||||||
That way, everything using `Buffer` natively would still work, but there would be two drawbacks:
|
|
||||||
|
|
||||||
* `Buffer.from`/`Buffer.alloc` won't be polyfilled — use `SaferBuffer.from` and
|
|
||||||
`SaferBuffer.alloc` instead.
|
|
||||||
* You are still open to accidentally using the insecure deprecated API — use a linter to catch that.
|
|
||||||
|
|
||||||
Note that using a linter to catch accidential `Buffer` constructor usage in this case is strongly
|
|
||||||
recommended. `Buffer` is not overriden in this usecase, so linters won't get confused.
|
|
||||||
|
|
||||||
## «Without footguns»?
|
|
||||||
|
|
||||||
Well, it is still possible to do _some_ things with `Buffer` API, e.g. accessing `.buffer` property
|
|
||||||
on older versions and duping things from there. You shouldn't do that in your code, probabably.
|
|
||||||
|
|
||||||
The intention is to remove the most significant footguns that affect lots of packages in the
|
|
||||||
ecosystem, and to do it in the proper way.
|
|
||||||
|
|
||||||
Also, this package doesn't protect against security issues affecting some Node.js versions, so for
|
|
||||||
usage in your own production code, it is still recommended to update to a Node.js version
|
|
||||||
[supported by upstream](https://github.com/nodejs/release#release-schedule).
|
|
58
node_modules/safer-buffer/dangerous.js
generated
vendored
58
node_modules/safer-buffer/dangerous.js
generated
vendored
|
@ -1,58 +0,0 @@
|
||||||
/* eslint-disable node/no-deprecated-api */
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var buffer = require('buffer')
|
|
||||||
var Buffer = buffer.Buffer
|
|
||||||
var safer = require('./safer.js')
|
|
||||||
var Safer = safer.Buffer
|
|
||||||
|
|
||||||
var dangerous = {}
|
|
||||||
|
|
||||||
var key
|
|
||||||
|
|
||||||
for (key in safer) {
|
|
||||||
if (!safer.hasOwnProperty(key)) continue
|
|
||||||
dangerous[key] = safer[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
var Dangereous = dangerous.Buffer = {}
|
|
||||||
|
|
||||||
// Copy Safer API
|
|
||||||
for (key in Safer) {
|
|
||||||
if (!Safer.hasOwnProperty(key)) continue
|
|
||||||
Dangereous[key] = Safer[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy those missing unsafe methods, if they are present
|
|
||||||
for (key in Buffer) {
|
|
||||||
if (!Buffer.hasOwnProperty(key)) continue
|
|
||||||
if (Dangereous.hasOwnProperty(key)) continue
|
|
||||||
Dangereous[key] = Buffer[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Dangereous.allocUnsafe) {
|
|
||||||
Dangereous.allocUnsafe = function (size) {
|
|
||||||
if (typeof size !== 'number') {
|
|
||||||
throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size)
|
|
||||||
}
|
|
||||||
if (size < 0 || size >= 2 * (1 << 30)) {
|
|
||||||
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
||||||
}
|
|
||||||
return Buffer(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Dangereous.allocUnsafeSlow) {
|
|
||||||
Dangereous.allocUnsafeSlow = function (size) {
|
|
||||||
if (typeof size !== 'number') {
|
|
||||||
throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size)
|
|
||||||
}
|
|
||||||
if (size < 0 || size >= 2 * (1 << 30)) {
|
|
||||||
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
||||||
}
|
|
||||||
return buffer.SlowBuffer(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = dangerous
|
|
34
node_modules/safer-buffer/package.json
generated
vendored
34
node_modules/safer-buffer/package.json
generated
vendored
|
@ -1,34 +0,0 @@
|
||||||
{
|
|
||||||
"name": "safer-buffer",
|
|
||||||
"version": "2.1.2",
|
|
||||||
"description": "Modern Buffer API polyfill without footguns",
|
|
||||||
"main": "safer.js",
|
|
||||||
"scripts": {
|
|
||||||
"browserify-test": "browserify --external tape tests.js > browserify-tests.js && tape browserify-tests.js",
|
|
||||||
"test": "standard && tape tests.js"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Nikita Skovoroda",
|
|
||||||
"email": "chalkerx@gmail.com",
|
|
||||||
"url": "https://github.com/ChALkeR"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/ChALkeR/safer-buffer.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/ChALkeR/safer-buffer/issues"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"standard": "^11.0.1",
|
|
||||||
"tape": "^4.9.0"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"Porting-Buffer.md",
|
|
||||||
"Readme.md",
|
|
||||||
"tests.js",
|
|
||||||
"dangerous.js",
|
|
||||||
"safer.js"
|
|
||||||
]
|
|
||||||
}
|
|
77
node_modules/safer-buffer/safer.js
generated
vendored
77
node_modules/safer-buffer/safer.js
generated
vendored
|
@ -1,77 +0,0 @@
|
||||||
/* eslint-disable node/no-deprecated-api */
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var buffer = require('buffer')
|
|
||||||
var Buffer = buffer.Buffer
|
|
||||||
|
|
||||||
var safer = {}
|
|
||||||
|
|
||||||
var key
|
|
||||||
|
|
||||||
for (key in buffer) {
|
|
||||||
if (!buffer.hasOwnProperty(key)) continue
|
|
||||||
if (key === 'SlowBuffer' || key === 'Buffer') continue
|
|
||||||
safer[key] = buffer[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
var Safer = safer.Buffer = {}
|
|
||||||
for (key in Buffer) {
|
|
||||||
if (!Buffer.hasOwnProperty(key)) continue
|
|
||||||
if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue
|
|
||||||
Safer[key] = Buffer[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
safer.Buffer.prototype = Buffer.prototype
|
|
||||||
|
|
||||||
if (!Safer.from || Safer.from === Uint8Array.from) {
|
|
||||||
Safer.from = function (value, encodingOrOffset, length) {
|
|
||||||
if (typeof value === 'number') {
|
|
||||||
throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value)
|
|
||||||
}
|
|
||||||
if (value && typeof value.length === 'undefined') {
|
|
||||||
throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value)
|
|
||||||
}
|
|
||||||
return Buffer(value, encodingOrOffset, length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Safer.alloc) {
|
|
||||||
Safer.alloc = function (size, fill, encoding) {
|
|
||||||
if (typeof size !== 'number') {
|
|
||||||
throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size)
|
|
||||||
}
|
|
||||||
if (size < 0 || size >= 2 * (1 << 30)) {
|
|
||||||
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
|
||||||
}
|
|
||||||
var buf = Buffer(size)
|
|
||||||
if (!fill || fill.length === 0) {
|
|
||||||
buf.fill(0)
|
|
||||||
} else if (typeof encoding === 'string') {
|
|
||||||
buf.fill(fill, encoding)
|
|
||||||
} else {
|
|
||||||
buf.fill(fill)
|
|
||||||
}
|
|
||||||
return buf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!safer.kStringMaxLength) {
|
|
||||||
try {
|
|
||||||
safer.kStringMaxLength = process.binding('buffer').kStringMaxLength
|
|
||||||
} catch (e) {
|
|
||||||
// we can't determine kStringMaxLength in environments where process.binding
|
|
||||||
// is unsupported, so let's not set it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!safer.constants) {
|
|
||||||
safer.constants = {
|
|
||||||
MAX_LENGTH: safer.kMaxLength
|
|
||||||
}
|
|
||||||
if (safer.kStringMaxLength) {
|
|
||||||
safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = safer
|
|
406
node_modules/safer-buffer/tests.js
generated
vendored
406
node_modules/safer-buffer/tests.js
generated
vendored
|
@ -1,406 +0,0 @@
|
||||||
/* eslint-disable node/no-deprecated-api */
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
var test = require('tape')
|
|
||||||
|
|
||||||
var buffer = require('buffer')
|
|
||||||
|
|
||||||
var index = require('./')
|
|
||||||
var safer = require('./safer')
|
|
||||||
var dangerous = require('./dangerous')
|
|
||||||
|
|
||||||
/* Inheritance tests */
|
|
||||||
|
|
||||||
test('Default is Safer', function (t) {
|
|
||||||
t.equal(index, safer)
|
|
||||||
t.notEqual(safer, dangerous)
|
|
||||||
t.notEqual(index, dangerous)
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Is not a function', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(typeof impl, 'object')
|
|
||||||
t.equal(typeof impl.Buffer, 'object')
|
|
||||||
});
|
|
||||||
[buffer].forEach(function (impl) {
|
|
||||||
t.equal(typeof impl, 'object')
|
|
||||||
t.equal(typeof impl.Buffer, 'function')
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Constructor throws', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.throws(function () { impl.Buffer() })
|
|
||||||
t.throws(function () { impl.Buffer(0) })
|
|
||||||
t.throws(function () { impl.Buffer('a') })
|
|
||||||
t.throws(function () { impl.Buffer('a', 'utf-8') })
|
|
||||||
t.throws(function () { return new impl.Buffer() })
|
|
||||||
t.throws(function () { return new impl.Buffer(0) })
|
|
||||||
t.throws(function () { return new impl.Buffer('a') })
|
|
||||||
t.throws(function () { return new impl.Buffer('a', 'utf-8') })
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Safe methods exist', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(typeof impl.Buffer.alloc, 'function', 'alloc')
|
|
||||||
t.equal(typeof impl.Buffer.from, 'function', 'from')
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Unsafe methods exist only in Dangerous', function (t) {
|
|
||||||
[index, safer].forEach(function (impl) {
|
|
||||||
t.equal(typeof impl.Buffer.allocUnsafe, 'undefined')
|
|
||||||
t.equal(typeof impl.Buffer.allocUnsafeSlow, 'undefined')
|
|
||||||
});
|
|
||||||
[dangerous].forEach(function (impl) {
|
|
||||||
t.equal(typeof impl.Buffer.allocUnsafe, 'function')
|
|
||||||
t.equal(typeof impl.Buffer.allocUnsafeSlow, 'function')
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Generic methods/properties are defined and equal', function (t) {
|
|
||||||
['poolSize', 'isBuffer', 'concat', 'byteLength'].forEach(function (method) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer[method], buffer.Buffer[method], method)
|
|
||||||
t.notEqual(typeof impl.Buffer[method], 'undefined', method)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Built-in buffer static methods/properties are inherited', function (t) {
|
|
||||||
Object.keys(buffer).forEach(function (method) {
|
|
||||||
if (method === 'SlowBuffer' || method === 'Buffer') return;
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl[method], buffer[method], method)
|
|
||||||
t.notEqual(typeof impl[method], 'undefined', method)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Built-in Buffer static methods/properties are inherited', function (t) {
|
|
||||||
Object.keys(buffer.Buffer).forEach(function (method) {
|
|
||||||
if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return;
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer[method], buffer.Buffer[method], method)
|
|
||||||
t.notEqual(typeof impl.Buffer[method], 'undefined', method)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('.prototype property of Buffer is inherited', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer.prototype, buffer.Buffer.prototype, 'prototype')
|
|
||||||
t.notEqual(typeof impl.Buffer.prototype, 'undefined', 'prototype')
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('All Safer methods are present in Dangerous', function (t) {
|
|
||||||
Object.keys(safer).forEach(function (method) {
|
|
||||||
if (method === 'Buffer') return;
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl[method], safer[method], method)
|
|
||||||
if (method !== 'kStringMaxLength') {
|
|
||||||
t.notEqual(typeof impl[method], 'undefined', method)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Object.keys(safer.Buffer).forEach(function (method) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer[method], safer.Buffer[method], method)
|
|
||||||
t.notEqual(typeof impl.Buffer[method], 'undefined', method)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Safe methods from Dangerous methods are present in Safer', function (t) {
|
|
||||||
Object.keys(dangerous).forEach(function (method) {
|
|
||||||
if (method === 'Buffer') return;
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl[method], dangerous[method], method)
|
|
||||||
if (method !== 'kStringMaxLength') {
|
|
||||||
t.notEqual(typeof impl[method], 'undefined', method)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Object.keys(dangerous.Buffer).forEach(function (method) {
|
|
||||||
if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return;
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer[method], dangerous.Buffer[method], method)
|
|
||||||
t.notEqual(typeof impl.Buffer[method], 'undefined', method)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Behaviour tests */
|
|
||||||
|
|
||||||
test('Methods return Buffers', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0)))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 10)))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 'a')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10)))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10, 'x')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(9, 'ab')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string', 'utf-8')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64')))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([0, 42, 3])))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from(new Uint8Array([0, 42, 3]))))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([])))
|
|
||||||
});
|
|
||||||
['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
|
|
||||||
t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](0)))
|
|
||||||
t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](10)))
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Constructor is buffer.Buffer', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer.alloc(0).constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.alloc(0, 10).constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.alloc(0, 'a').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.alloc(10).constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.alloc(10, 'x').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.alloc(9, 'ab').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from('').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from('string').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from('string', 'utf-8').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from([0, 42, 3]).constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).constructor, buffer.Buffer)
|
|
||||||
t.equal(impl.Buffer.from([]).constructor, buffer.Buffer)
|
|
||||||
});
|
|
||||||
[0, 10, 100].forEach(function (arg) {
|
|
||||||
t.equal(dangerous.Buffer.allocUnsafe(arg).constructor, buffer.Buffer)
|
|
||||||
t.equal(dangerous.Buffer.allocUnsafeSlow(arg).constructor, buffer.SlowBuffer(0).constructor)
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Invalid calls throw', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.throws(function () { impl.Buffer.from(0) })
|
|
||||||
t.throws(function () { impl.Buffer.from(10) })
|
|
||||||
t.throws(function () { impl.Buffer.from(10, 'utf-8') })
|
|
||||||
t.throws(function () { impl.Buffer.from('string', 'invalid encoding') })
|
|
||||||
t.throws(function () { impl.Buffer.from(-10) })
|
|
||||||
t.throws(function () { impl.Buffer.from(1e90) })
|
|
||||||
t.throws(function () { impl.Buffer.from(Infinity) })
|
|
||||||
t.throws(function () { impl.Buffer.from(-Infinity) })
|
|
||||||
t.throws(function () { impl.Buffer.from(NaN) })
|
|
||||||
t.throws(function () { impl.Buffer.from(null) })
|
|
||||||
t.throws(function () { impl.Buffer.from(undefined) })
|
|
||||||
t.throws(function () { impl.Buffer.from() })
|
|
||||||
t.throws(function () { impl.Buffer.from({}) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc('') })
|
|
||||||
t.throws(function () { impl.Buffer.alloc('string') })
|
|
||||||
t.throws(function () { impl.Buffer.alloc('string', 'utf-8') })
|
|
||||||
t.throws(function () { impl.Buffer.alloc('b25ldHdvdGhyZWU=', 'base64') })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(-10) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(1e90) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(2 * (1 << 30)) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(Infinity) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(-Infinity) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(null) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc(undefined) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc() })
|
|
||||||
t.throws(function () { impl.Buffer.alloc([]) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc([0, 42, 3]) })
|
|
||||||
t.throws(function () { impl.Buffer.alloc({}) })
|
|
||||||
});
|
|
||||||
['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
|
|
||||||
t.throws(function () { dangerous.Buffer[method]('') })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]('string') })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]('string', 'utf-8') })
|
|
||||||
t.throws(function () { dangerous.Buffer[method](2 * (1 << 30)) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method](Infinity) })
|
|
||||||
if (dangerous.Buffer[method] === buffer.Buffer.allocUnsafe) {
|
|
||||||
t.skip('Skipping, older impl of allocUnsafe coerced negative sizes to 0')
|
|
||||||
} else {
|
|
||||||
t.throws(function () { dangerous.Buffer[method](-10) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method](-1e90) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method](-Infinity) })
|
|
||||||
}
|
|
||||||
t.throws(function () { dangerous.Buffer[method](null) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method](undefined) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]() })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]([]) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]([0, 42, 3]) })
|
|
||||||
t.throws(function () { dangerous.Buffer[method]({}) })
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Buffers have appropriate lengths', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.equal(impl.Buffer.alloc(0).length, 0)
|
|
||||||
t.equal(impl.Buffer.alloc(10).length, 10)
|
|
||||||
t.equal(impl.Buffer.from('').length, 0)
|
|
||||||
t.equal(impl.Buffer.from('string').length, 6)
|
|
||||||
t.equal(impl.Buffer.from('string', 'utf-8').length, 6)
|
|
||||||
t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').length, 11)
|
|
||||||
t.equal(impl.Buffer.from([0, 42, 3]).length, 3)
|
|
||||||
t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).length, 3)
|
|
||||||
t.equal(impl.Buffer.from([]).length, 0)
|
|
||||||
});
|
|
||||||
['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
|
|
||||||
t.equal(dangerous.Buffer[method](0).length, 0)
|
|
||||||
t.equal(dangerous.Buffer[method](10).length, 10)
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('Buffers have appropriate lengths (2)', function (t) {
|
|
||||||
t.equal(index.Buffer.alloc, safer.Buffer.alloc)
|
|
||||||
t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
|
|
||||||
var ok = true;
|
|
||||||
[ safer.Buffer.alloc,
|
|
||||||
dangerous.Buffer.allocUnsafe,
|
|
||||||
dangerous.Buffer.allocUnsafeSlow
|
|
||||||
].forEach(function (method) {
|
|
||||||
for (var i = 0; i < 1e2; i++) {
|
|
||||||
var length = Math.round(Math.random() * 1e5)
|
|
||||||
var buf = method(length)
|
|
||||||
if (!buffer.Buffer.isBuffer(buf)) ok = false
|
|
||||||
if (buf.length !== length) ok = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.ok(ok)
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('.alloc(size) is zero-filled and has correct length', function (t) {
|
|
||||||
t.equal(index.Buffer.alloc, safer.Buffer.alloc)
|
|
||||||
t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
|
|
||||||
var ok = true
|
|
||||||
for (var i = 0; i < 1e2; i++) {
|
|
||||||
var length = Math.round(Math.random() * 2e6)
|
|
||||||
var buf = index.Buffer.alloc(length)
|
|
||||||
if (!buffer.Buffer.isBuffer(buf)) ok = false
|
|
||||||
if (buf.length !== length) ok = false
|
|
||||||
var j
|
|
||||||
for (j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== 0) ok = false
|
|
||||||
}
|
|
||||||
buf.fill(1)
|
|
||||||
for (j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== 1) ok = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.ok(ok)
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('.allocUnsafe / .allocUnsafeSlow are fillable and have correct lengths', function (t) {
|
|
||||||
['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
|
|
||||||
var ok = true
|
|
||||||
for (var i = 0; i < 1e2; i++) {
|
|
||||||
var length = Math.round(Math.random() * 2e6)
|
|
||||||
var buf = dangerous.Buffer[method](length)
|
|
||||||
if (!buffer.Buffer.isBuffer(buf)) ok = false
|
|
||||||
if (buf.length !== length) ok = false
|
|
||||||
buf.fill(0, 0, length)
|
|
||||||
var j
|
|
||||||
for (j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== 0) ok = false
|
|
||||||
}
|
|
||||||
buf.fill(1, 0, length)
|
|
||||||
for (j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== 1) ok = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.ok(ok, method)
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('.alloc(size, fill) is `fill`-filled', function (t) {
|
|
||||||
t.equal(index.Buffer.alloc, safer.Buffer.alloc)
|
|
||||||
t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
|
|
||||||
var ok = true
|
|
||||||
for (var i = 0; i < 1e2; i++) {
|
|
||||||
var length = Math.round(Math.random() * 2e6)
|
|
||||||
var fill = Math.round(Math.random() * 255)
|
|
||||||
var buf = index.Buffer.alloc(length, fill)
|
|
||||||
if (!buffer.Buffer.isBuffer(buf)) ok = false
|
|
||||||
if (buf.length !== length) ok = false
|
|
||||||
for (var j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== fill) ok = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.ok(ok)
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('.alloc(size, fill) is `fill`-filled', function (t) {
|
|
||||||
t.equal(index.Buffer.alloc, safer.Buffer.alloc)
|
|
||||||
t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
|
|
||||||
var ok = true
|
|
||||||
for (var i = 0; i < 1e2; i++) {
|
|
||||||
var length = Math.round(Math.random() * 2e6)
|
|
||||||
var fill = Math.round(Math.random() * 255)
|
|
||||||
var buf = index.Buffer.alloc(length, fill)
|
|
||||||
if (!buffer.Buffer.isBuffer(buf)) ok = false
|
|
||||||
if (buf.length !== length) ok = false
|
|
||||||
for (var j = 0; j < length; j++) {
|
|
||||||
if (buf[j] !== fill) ok = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.ok(ok)
|
|
||||||
t.deepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 97))
|
|
||||||
t.notDeepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 98))
|
|
||||||
|
|
||||||
var tmp = new buffer.Buffer(2)
|
|
||||||
tmp.fill('ok')
|
|
||||||
if (tmp[1] === tmp[0]) {
|
|
||||||
// Outdated Node.js
|
|
||||||
t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('ooooo'))
|
|
||||||
} else {
|
|
||||||
t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('okoko'))
|
|
||||||
}
|
|
||||||
t.notDeepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('kokok'))
|
|
||||||
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('safer.Buffer.from returns results same as Buffer constructor', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.deepEqual(impl.Buffer.from(''), new buffer.Buffer(''))
|
|
||||||
t.deepEqual(impl.Buffer.from('string'), new buffer.Buffer('string'))
|
|
||||||
t.deepEqual(impl.Buffer.from('string', 'utf-8'), new buffer.Buffer('string', 'utf-8'))
|
|
||||||
t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), new buffer.Buffer('b25ldHdvdGhyZWU=', 'base64'))
|
|
||||||
t.deepEqual(impl.Buffer.from([0, 42, 3]), new buffer.Buffer([0, 42, 3]))
|
|
||||||
t.deepEqual(impl.Buffer.from(new Uint8Array([0, 42, 3])), new buffer.Buffer(new Uint8Array([0, 42, 3])))
|
|
||||||
t.deepEqual(impl.Buffer.from([]), new buffer.Buffer([]))
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('safer.Buffer.from returns consistent results', function (t) {
|
|
||||||
[index, safer, dangerous].forEach(function (impl) {
|
|
||||||
t.deepEqual(impl.Buffer.from(''), impl.Buffer.alloc(0))
|
|
||||||
t.deepEqual(impl.Buffer.from([]), impl.Buffer.alloc(0))
|
|
||||||
t.deepEqual(impl.Buffer.from(new Uint8Array([])), impl.Buffer.alloc(0))
|
|
||||||
t.deepEqual(impl.Buffer.from('string', 'utf-8'), impl.Buffer.from('string'))
|
|
||||||
t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from([115, 116, 114, 105, 110, 103]))
|
|
||||||
t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from(impl.Buffer.from('string')))
|
|
||||||
t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), impl.Buffer.from('onetwothree'))
|
|
||||||
t.notDeepEqual(impl.Buffer.from('b25ldHdvdGhyZWU='), impl.Buffer.from('onetwothree'))
|
|
||||||
})
|
|
||||||
t.end()
|
|
||||||
})
|
|
|
@ -25,12 +25,11 @@
|
||||||
"@actions/core": "^1.4.0",
|
"@actions/core": "^1.4.0",
|
||||||
"@actions/exec": "^1.1.0",
|
"@actions/exec": "^1.1.0",
|
||||||
"addressparser": "^1.0.1",
|
"addressparser": "^1.0.1",
|
||||||
"openpgp": "^4.10.10"
|
"openpgp": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^26.0.14",
|
"@types/jest": "^26.0.14",
|
||||||
"@types/node": "^14.11.2",
|
"@types/node": "^14.11.2",
|
||||||
"@types/openpgp": "^4.4.14",
|
|
||||||
"@vercel/ncc": "^0.24.1",
|
"@vercel/ncc": "^0.24.1",
|
||||||
"jest": "^26.0.1",
|
"jest": "^26.0.1",
|
||||||
"jest-circus": "^26.0.1",
|
"jest-circus": "^26.0.1",
|
||||||
|
|
29
src/main.ts
29
src/main.ts
|
@ -17,7 +17,7 @@ async function run(): Promise<void> {
|
||||||
|
|
||||||
const version = await gpg.getVersion();
|
const version = await gpg.getVersion();
|
||||||
const dirs = await gpg.getDirs();
|
const dirs = await gpg.getDirs();
|
||||||
await core.group(`📣 GnuPG info`, async () => {
|
await core.group(`GnuPG info`, async () => {
|
||||||
core.info(`Version : ${version.gnupg} (libgcrypt ${version.libgcrypt})`);
|
core.info(`Version : ${version.gnupg} (libgcrypt ${version.libgcrypt})`);
|
||||||
core.info(`Libdir : ${dirs.libdir}`);
|
core.info(`Libdir : ${dirs.libdir}`);
|
||||||
core.info(`Libexecdir : ${dirs.libexecdir}`);
|
core.info(`Libexecdir : ${dirs.libexecdir}`);
|
||||||
|
@ -26,7 +26,7 @@ async function run(): Promise<void> {
|
||||||
});
|
});
|
||||||
|
|
||||||
const privateKey = await openpgp.readPrivateKey(inputs.gpgPrivateKey);
|
const privateKey = await openpgp.readPrivateKey(inputs.gpgPrivateKey);
|
||||||
await core.group(`🔮 Checking GPG private key`, async () => {
|
await core.group(`GPG private key info`, async () => {
|
||||||
core.info(`Fingerprint : ${privateKey.fingerprint}`);
|
core.info(`Fingerprint : ${privateKey.fingerprint}`);
|
||||||
core.info(`KeyID : ${privateKey.keyID}`);
|
core.info(`KeyID : ${privateKey.keyID}`);
|
||||||
core.info(`Name : ${privateKey.name}`);
|
core.info(`Name : ${privateKey.name}`);
|
||||||
|
@ -34,20 +34,19 @@ async function run(): Promise<void> {
|
||||||
core.info(`CreationTime : ${privateKey.creationTime}`);
|
core.info(`CreationTime : ${privateKey.creationTime}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
await core.group(`🔑 Importing GPG private key`, async () => {
|
await core.group(`Importing GPG private key`, async () => {
|
||||||
await gpg.importKey(inputs.gpgPrivateKey).then(stdout => {
|
await gpg.importKey(inputs.gpgPrivateKey).then(stdout => {
|
||||||
core.info(stdout);
|
core.info(stdout);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inputs.passphrase) {
|
if (inputs.passphrase) {
|
||||||
core.info('⚙️ Configuring GnuPG agent');
|
core.info('Configuring GnuPG agent');
|
||||||
await gpg.configureAgent(gpg.agentConfig);
|
await gpg.configureAgent(gpg.agentConfig);
|
||||||
|
|
||||||
core.info('📌 Getting keygrips');
|
await core.group(`Getting keygrips`, async () => {
|
||||||
await core.group(`📌 Getting keygrips`, async () => {
|
|
||||||
for (let keygrip of await gpg.getKeygrips(privateKey.fingerprint)) {
|
for (let keygrip of await gpg.getKeygrips(privateKey.fingerprint)) {
|
||||||
core.info(`🔓 Presetting passphrase for ${keygrip}`);
|
core.info(`Presetting passphrase for ${keygrip}`);
|
||||||
await gpg.presetPassphrase(keygrip, inputs.passphrase).then(stdout => {
|
await gpg.presetPassphrase(keygrip, inputs.passphrase).then(stdout => {
|
||||||
core.debug(stdout);
|
core.debug(stdout);
|
||||||
});
|
});
|
||||||
|
@ -55,14 +54,14 @@ async function run(): Promise<void> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info('🛒 Setting outputs...');
|
core.info('Setting outputs');
|
||||||
context.setOutput('fingerprint', privateKey.fingerprint);
|
context.setOutput('fingerprint', privateKey.fingerprint);
|
||||||
context.setOutput('keyid', privateKey.keyID);
|
context.setOutput('keyid', privateKey.keyID);
|
||||||
context.setOutput('name', privateKey.name);
|
context.setOutput('name', privateKey.name);
|
||||||
context.setOutput('email', privateKey.email);
|
context.setOutput('email', privateKey.email);
|
||||||
|
|
||||||
if (inputs.gitUserSigningkey) {
|
if (inputs.gitUserSigningkey) {
|
||||||
core.info('🔐 Setting GPG signing keyID for this Git repository');
|
core.info('Setting GPG signing keyID for this Git repository');
|
||||||
await git.setConfig('user.signingkey', privateKey.keyID, inputs.gitConfigGlobal);
|
await git.setConfig('user.signingkey', privateKey.keyID, inputs.gitConfigGlobal);
|
||||||
|
|
||||||
const userEmail = inputs.gitCommitterEmail || privateKey.email;
|
const userEmail = inputs.gitCommitterEmail || privateKey.email;
|
||||||
|
@ -73,20 +72,20 @@ async function run(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info(`🔨 Configuring Git committer (${userName} <${userEmail}>)`);
|
core.info(`Configuring Git committer (${userName} <${userEmail}>)`);
|
||||||
await git.setConfig('user.name', userName, inputs.gitConfigGlobal);
|
await git.setConfig('user.name', userName, inputs.gitConfigGlobal);
|
||||||
await git.setConfig('user.email', userEmail, inputs.gitConfigGlobal);
|
await git.setConfig('user.email', userEmail, inputs.gitConfigGlobal);
|
||||||
|
|
||||||
if (inputs.gitCommitGpgsign) {
|
if (inputs.gitCommitGpgsign) {
|
||||||
core.info('💎 Sign all commits automatically');
|
core.info('Sign all commits automatically');
|
||||||
await git.setConfig('commit.gpgsign', 'true', inputs.gitConfigGlobal);
|
await git.setConfig('commit.gpgsign', 'true', inputs.gitConfigGlobal);
|
||||||
}
|
}
|
||||||
if (inputs.gitTagGpgsign) {
|
if (inputs.gitTagGpgsign) {
|
||||||
core.info('💎 Sign all tags automatically');
|
core.info('Sign all tags automatically');
|
||||||
await git.setConfig('tag.gpgsign', 'true', inputs.gitConfigGlobal);
|
await git.setConfig('tag.gpgsign', 'true', inputs.gitConfigGlobal);
|
||||||
}
|
}
|
||||||
if (inputs.gitPushGpgsign) {
|
if (inputs.gitPushGpgsign) {
|
||||||
core.info('💎 Sign all pushes automatically');
|
core.info('Sign all pushes automatically');
|
||||||
await git.setConfig('push.gpgsign', inputs.gitPushGpgsign, inputs.gitConfigGlobal);
|
await git.setConfig('push.gpgsign', inputs.gitPushGpgsign, inputs.gitConfigGlobal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,11 +100,11 @@ async function cleanup(): Promise<void> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
core.info('🚿 Removing keys');
|
core.info('Removing keys');
|
||||||
const privateKey = await openpgp.readPrivateKey(stateHelper.gpgPrivateKey);
|
const privateKey = await openpgp.readPrivateKey(stateHelper.gpgPrivateKey);
|
||||||
await gpg.deleteKey(privateKey.fingerprint);
|
await gpg.deleteKey(privateKey.fingerprint);
|
||||||
|
|
||||||
core.info('💀 Killing GnuPG agent');
|
core.info('Killing GnuPG agent');
|
||||||
await gpg.killAgent();
|
await gpg.killAgent();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(error.message);
|
core.warning(error.message);
|
||||||
|
|
|
@ -15,24 +15,19 @@ export interface KeyPair {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const readPrivateKey = async (key: string): Promise<PrivateKey> => {
|
export const readPrivateKey = async (key: string): Promise<PrivateKey> => {
|
||||||
const {
|
const privateKey = await openpgp.readKey({
|
||||||
keys: [privateKey],
|
armoredKey: (await isArmored(key)) ? key : Buffer.from(key, 'base64').toString()
|
||||||
err: err
|
});
|
||||||
} = await openpgp.key.readArmored((await isArmored(key)) ? key : Buffer.from(key, 'base64').toString());
|
|
||||||
|
|
||||||
if (err?.length) {
|
|
||||||
throw err[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const address = await privateKey.getPrimaryUser().then(primaryUser => {
|
const address = await privateKey.getPrimaryUser().then(primaryUser => {
|
||||||
return addressparser(primaryUser.user.userId.userid)[0];
|
return addressparser(primaryUser.user.userID?.userID)[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fingerprint: privateKey.getFingerprint().toUpperCase(),
|
fingerprint: privateKey.getFingerprint().toUpperCase(),
|
||||||
keyID: await privateKey.getEncryptionKey().then(encKey => {
|
keyID: await privateKey.getEncryptionKey().then(encKey => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return encKey?.getKeyId().toHex().toUpperCase();
|
return encKey?.getKeyID().toHex().toUpperCase();
|
||||||
}),
|
}),
|
||||||
name: address.name,
|
name: address.name,
|
||||||
email: address.address,
|
email: address.address,
|
||||||
|
@ -40,16 +35,16 @@ export const readPrivateKey = async (key: string): Promise<PrivateKey> => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generateKeyPair = async (name: string, email: string, passphrase: string, numBits: number = 4096): Promise<KeyPair> => {
|
export const generateKeyPair = async (name: string, email: string, passphrase: string, type?: 'ecc' | 'rsa'): Promise<KeyPair> => {
|
||||||
const keyPair = await openpgp.generateKey({
|
const keyPair = await openpgp.generateKey({
|
||||||
userIds: [{name: name, email: email}],
|
userIDs: [{name: name, email: email}],
|
||||||
numBits,
|
passphrase: passphrase,
|
||||||
passphrase
|
type: type
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
publicKey: keyPair.publicKeyArmored.replace(/\r\n/g, '\n').trim(),
|
publicKey: keyPair.publicKey.replace(/\r\n/g, '\n').trim(),
|
||||||
privateKey: keyPair.privateKeyArmored.replace(/\r\n/g, '\n').trim()
|
privateKey: keyPair.privateKey.replace(/\r\n/g, '\n').trim()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
58
yarn.lock
58
yarn.lock
|
@ -532,13 +532,6 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.3.0"
|
"@babel/types" "^7.3.0"
|
||||||
|
|
||||||
"@types/bn.js@*":
|
|
||||||
version "4.11.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
|
|
||||||
integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/color-name@^1.1.1":
|
"@types/color-name@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||||
|
@ -609,13 +602,6 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
||||||
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
|
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
|
||||||
|
|
||||||
"@types/openpgp@^4.4.14":
|
|
||||||
version "4.4.14"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/openpgp/-/openpgp-4.4.14.tgz#6dbeaad05ce2a46b5cb696348bf759b6f887fe0d"
|
|
||||||
integrity sha512-bPTsAmoqABBT5Ow75cgLsPj6AlCWL1HBPCzNOUxQRkxlKHC1DuB7yO+4lRl4xnqubkGkI6VnHYgHxE0XpQQqJg==
|
|
||||||
dependencies:
|
|
||||||
"@types/bn.js" "*"
|
|
||||||
|
|
||||||
"@types/prettier@^2.0.0":
|
"@types/prettier@^2.0.0":
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.0.tgz#5f96562c1075ee715a5b138f0b7f591c1f40f6b8"
|
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.0.tgz#5f96562c1075ee715a5b138f0b7f591c1f40f6b8"
|
||||||
|
@ -1598,7 +1584,7 @@ globals@^11.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||||
|
|
||||||
graceful-fs@^4.1.11, graceful-fs@^4.2.4:
|
graceful-fs@^4.2.4:
|
||||||
version "4.2.4"
|
version "4.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||||
|
@ -2674,23 +2660,11 @@ nice-try@^1.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||||
|
|
||||||
node-fetch@^2.1.2:
|
|
||||||
version "2.6.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
|
||||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
|
||||||
|
|
||||||
node-int64@^0.4.0:
|
node-int64@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
||||||
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
|
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
|
||||||
|
|
||||||
node-localstorage@~1.3.0:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-localstorage/-/node-localstorage-1.3.1.tgz#3177ef42837f398aee5dd75e319b281e40704243"
|
|
||||||
integrity sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==
|
|
||||||
dependencies:
|
|
||||||
write-file-atomic "^1.1.4"
|
|
||||||
|
|
||||||
node-modules-regexp@^1.0.0:
|
node-modules-regexp@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
|
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
|
||||||
|
@ -2791,14 +2765,12 @@ onetime@^5.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^2.1.0"
|
mimic-fn "^2.1.0"
|
||||||
|
|
||||||
openpgp@^4.10.10:
|
openpgp@^5.0.0:
|
||||||
version "4.10.10"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-4.10.10.tgz#65b58d24466c278120c7f2d1ebc88ef9b15d6361"
|
resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-5.0.0.tgz#2da0ee406c8834223ae928a9a214f4811f83f923"
|
||||||
integrity sha512-Ub48OogGPjNsr0G/wnJ/SyAQzt/tfcXZTWVZdjKFpXCQV1Ca+upFdSPPkBlGG3lb9EQGOKZJ2tzYNH6ZyKMkDQ==
|
integrity sha512-H4Jsj9Bp1KFQ/w520M1d2x45iz9V39Lf+IwIXmUaBmJAMagAt0zanqmWeFzIMJUYmrHTcm6fO/rpc6aftFUHbA==
|
||||||
dependencies:
|
dependencies:
|
||||||
asn1.js "^5.0.0"
|
asn1.js "^5.0.0"
|
||||||
node-fetch "^2.1.2"
|
|
||||||
node-localstorage "~1.3.0"
|
|
||||||
|
|
||||||
optionator@^0.8.1:
|
optionator@^0.8.1:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
|
@ -2882,9 +2854,9 @@ path-key@^3.0.0, path-key@^3.1.0:
|
||||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
|
|
||||||
path-parse@^1.0.6:
|
path-parse@^1.0.6:
|
||||||
version "1.0.6"
|
version "1.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
|
||||||
performance-now@^2.1.0:
|
performance-now@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
|
@ -3246,11 +3218,6 @@ slash@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
slide@^1.1.5:
|
|
||||||
version "1.1.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
|
|
||||||
integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
|
|
||||||
|
|
||||||
snapdragon-node@^2.0.1:
|
snapdragon-node@^2.0.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||||
|
@ -3784,15 +3751,6 @@ wrappy@1:
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
|
||||||
write-file-atomic@^1.1.4:
|
|
||||||
version "1.3.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
|
|
||||||
integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=
|
|
||||||
dependencies:
|
|
||||||
graceful-fs "^4.1.11"
|
|
||||||
imurmurhash "^0.1.4"
|
|
||||||
slide "^1.1.5"
|
|
||||||
|
|
||||||
write-file-atomic@^3.0.0:
|
write-file-atomic@^3.0.0:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
|
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
|
||||||
|
|
Loading…
Reference in a new issue