react / wstein / node_modules / browserify / node_modules / crypto-browserify / node_modules / public-encrypt / node_modules / parse-asn1 / node_modules / asn1.js / lib / asn1 / encoders / der.js
80647 viewsvar inherits = require('inherits');1var Buffer = require('buffer').Buffer;23var asn1 = require('../../asn1');4var base = asn1.base;5var bignum = asn1.bignum;67// Import DER constants8var der = asn1.constants.der;910function DEREncoder(entity) {11this.enc = 'der';12this.name = entity.name;13this.entity = entity;1415// Construct base tree16this.tree = new DERNode();17this.tree._init(entity.body);18};19module.exports = DEREncoder;2021DEREncoder.prototype.encode = function encode(data, reporter) {22return this.tree._encode(data, reporter).join();23};2425// Tree methods2627function DERNode(parent) {28base.Node.call(this, 'der', parent);29}30inherits(DERNode, base.Node);3132DERNode.prototype._encodeComposite = function encodeComposite(tag,33primitive,34cls,35content) {36var encodedTag = encodeTag(tag, primitive, cls, this.reporter);3738// Short form39if (content.length < 0x80) {40var header = new Buffer(2);41header[0] = encodedTag;42header[1] = content.length;43return this._createEncoderBuffer([ header, content ]);44}4546// Long form47// Count octets required to store length48var lenOctets = 1;49for (var i = content.length; i >= 0x100; i >>= 8)50lenOctets++;5152var header = new Buffer(1 + 1 + lenOctets);53header[0] = encodedTag;54header[1] = 0x80 | lenOctets;5556for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)57header[i] = j & 0xff;5859return this._createEncoderBuffer([ header, content ]);60};6162DERNode.prototype._encodeStr = function encodeStr(str, tag) {63if (tag === 'octstr')64return this._createEncoderBuffer(str);65else if (tag === 'bitstr')66return this._createEncoderBuffer([ str.unused | 0, str.data ]);67else if (tag === 'ia5str')68return this._createEncoderBuffer(str);69return this.reporter.error('Encoding of string type: ' + tag +70' unsupported');71};7273DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {74if (typeof id === 'string') {75if (!values)76return this.reporter.error('string objid given, but no values map found');77if (!values.hasOwnProperty(id))78return this.reporter.error('objid not found in values map');79id = values[id].split(/\s+/g);80for (var i = 0; i < id.length; i++)81id[i] |= 0;82} else if (Array.isArray(id)) {83id = id.slice();84}8586if (!Array.isArray(id)) {87return this.reporter.error('objid() should be either array or string, ' +88'got: ' + JSON.stringify(id));89}9091if (!relative) {92if (id[1] >= 40)93return this.reporter.error('Second objid identifier OOB');94id.splice(0, 2, id[0] * 40 + id[1]);95}9697// Count number of octets98var size = 0;99for (var i = 0; i < id.length; i++) {100var ident = id[i];101for (size++; ident >= 0x80; ident >>= 7)102size++;103}104105var objid = new Buffer(size);106var offset = objid.length - 1;107for (var i = id.length - 1; i >= 0; i--) {108var ident = id[i];109objid[offset--] = ident & 0x7f;110while ((ident >>= 7) > 0)111objid[offset--] = 0x80 | (ident & 0x7f);112}113114return this._createEncoderBuffer(objid);115};116117function two(num) {118if (num < 10)119return '0' + num;120else121return num;122}123124DERNode.prototype._encodeTime = function encodeTime(time, tag) {125var str;126var date = new Date(time);127128if (tag === 'gentime') {129str = [130two(date.getFullYear()),131two(date.getUTCMonth() + 1),132two(date.getUTCDate()),133two(date.getUTCHours()),134two(date.getUTCMinutes()),135two(date.getUTCSeconds()),136'Z'137].join('');138} else if (tag === 'utctime') {139str = [140two(date.getFullYear() % 100),141two(date.getUTCMonth() + 1),142two(date.getUTCDate()),143two(date.getUTCHours()),144two(date.getUTCMinutes()),145two(date.getUTCSeconds()),146'Z'147].join('');148} else {149this.reporter.error('Encoding ' + tag + ' time is not supported yet');150}151152return this._encodeStr(str, 'octstr');153};154155DERNode.prototype._encodeNull = function encodeNull() {156return this._createEncoderBuffer('');157};158159DERNode.prototype._encodeInt = function encodeInt(num, values) {160if (typeof num === 'string') {161if (!values)162return this.reporter.error('String int or enum given, but no values map');163if (!values.hasOwnProperty(num)) {164return this.reporter.error('Values map doesn\'t contain: ' +165JSON.stringify(num));166}167num = values[num];168}169170// Bignum, assume big endian171if (typeof num !== 'number' && !Buffer.isBuffer(num)) {172var numArray = num.toArray();173if (num.sign === false && numArray[0] & 0x80) {174numArray.unshift(0);175}176num = new Buffer(numArray);177}178179if (Buffer.isBuffer(num)) {180var size = num.length;181if (num.length === 0)182size++;183184var out = new Buffer(size);185num.copy(out);186if (num.length === 0)187out[0] = 0188return this._createEncoderBuffer(out);189}190191if (num < 0x80)192return this._createEncoderBuffer(num);193194if (num < 0x100)195return this._createEncoderBuffer([0, num]);196197var size = 1;198for (var i = num; i >= 0x100; i >>= 8)199size++;200201var out = new Array(size);202for (var i = out.length - 1; i >= 0; i--) {203out[i] = num & 0xff;204num >>= 8;205}206if(out[0] & 0x80) {207out.unshift(0);208}209210return this._createEncoderBuffer(new Buffer(out));211};212213DERNode.prototype._encodeBool = function encodeBool(value) {214return this._createEncoderBuffer(value ? 0xff : 0);215};216217DERNode.prototype._use = function use(entity, obj) {218if (typeof entity === 'function')219entity = entity(obj);220return entity._getEncoder('der').tree;221};222223DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {224var state = this._baseState;225var i;226if (state['default'] === null)227return false;228229var data = dataBuffer.join();230if (state.defaultBuffer === undefined)231state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();232233if (data.length !== state.defaultBuffer.length)234return false;235236for (i=0; i < data.length; i++)237if (data[i] !== state.defaultBuffer[i])238return false;239240return true;241};242243// Utility methods244245function encodeTag(tag, primitive, cls, reporter) {246var res;247248if (tag === 'seqof')249tag = 'seq';250else if (tag === 'setof')251tag = 'set';252253if (der.tagByName.hasOwnProperty(tag))254res = der.tagByName[tag];255else if (typeof tag === 'number' && (tag | 0) === tag)256res = tag;257else258return reporter.error('Unknown tag: ' + tag);259260if (res >= 0x1f)261return reporter.error('Multi-octet tag encoding unsupported');262263if (!primitive)264res |= 0x20;265266res |= (der.tagClassByName[cls || 'universal'] << 6);267268return res;269}270271272