summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/_crypto/crypto_browserify/asn1.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/node/polyfills/_crypto/crypto_browserify/asn1.js')
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js167
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js734
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js138
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js60
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js386
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/pem.js63
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js348
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/pem.js30
-rw-r--r--ext/node/polyfills/_crypto/crypto_browserify/asn1.js/mod.js96
9 files changed, 2022 insertions, 0 deletions
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js
new file mode 100644
index 000000000..cb01476cd
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js
@@ -0,0 +1,167 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import { Reporter } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js";
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+export 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);
+DecoderBuffer.prototype = Object.create(Reporter.prototype, {
+ constructor: {
+ value: DecoderBuffer,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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);
+};
+
+export 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);
+ }
+}
+
+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;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js
new file mode 100644
index 000000000..027778155
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js
@@ -0,0 +1,734 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import { Reporter } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js";
+import {
+ DecoderBuffer,
+ EncoderBuffer,
+} from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js";
+import { assert } from "internal:deno_node/polyfills/_util/asserts.ts";
+
+// 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",
+];
+
+export 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();
+ }
+}
+
+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(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);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js
new file mode 100644
index 000000000..509f6c5b3
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js
@@ -0,0 +1,138 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+export function Reporter(options) {
+ this._reporterState = {
+ obj: null,
+ path: [],
+ options: options || {},
+ errors: [],
+ };
+}
+
+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 = Object.create(Error.prototype, {
+ constructor: {
+ value: ReporterError,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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;
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js
new file mode 100644
index 000000000..807a97864
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js
@@ -0,0 +1,60 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+// 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;
+}
+
+export const tagClass = {
+ 0: "universal",
+ 1: "application",
+ 2: "context",
+ 3: "private",
+};
+export const tagClassByName = reverse(tagClass);
+
+export const 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",
+};
+export const tagByName = reverse(tag);
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js
new file mode 100644
index 000000000..9ab811507
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js
@@ -0,0 +1,386 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import bignum from "internal:deno_node/polyfills/_crypto/crypto_browserify/bn.js/bn.js";
+import { DecoderBuffer } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js";
+import { Node } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js";
+import * as der from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js";
+
+export 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);
+}
+
+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 = Object.create(Node.prototype, {
+ constructor: {
+ value: DERNode,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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;
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/pem.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/pem.js
new file mode 100644
index 000000000..3dedfb293
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/pem.js
@@ -0,0 +1,63 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+
+import { DERDecoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js";
+
+export function PEMDecoder(entity) {
+ DERDecoder.call(this, entity);
+ this.enc = "pem";
+}
+// inherits(PEMDecoder, DERDecoder);
+PEMDecoder.prototype = Object.create(DERDecoder.prototype, {
+ constructor: {
+ value: PEMDecoder,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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);
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js
new file mode 100644
index 000000000..3f03ef347
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js
@@ -0,0 +1,348 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import { Buffer } from "internal:deno_node/polyfills/buffer.ts";
+import { Node } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js";
+
+// Import DER constants
+import * as der from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js";
+
+export 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);
+}
+
+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 = Object.create(Node.prototype, {
+ constructor: {
+ value: DERNode,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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");
+ }
+ // deno-lint-ignore no-prototype-builtins
+ 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");
+ }
+ // deno-lint-ignore no-prototype-builtins
+ 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";
+ }
+
+ // deno-lint-ignore no-prototype-builtins
+ 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;
+}
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/pem.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/pem.js
new file mode 100644
index 000000000..d2487e1ce
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/pem.js
@@ -0,0 +1,30 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import { DEREncoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js";
+
+export function PEMEncoder(entity) {
+ DEREncoder.call(this, entity);
+ this.enc = "pem";
+}
+// inherits(PEMEncoder, DEREncoder);
+PEMEncoder.prototype = Object.create(DEREncoder.prototype, {
+ constructor: {
+ value: PEMEncoder,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+});
+
+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");
+};
diff --git a/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/mod.js b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/mod.js
new file mode 100644
index 000000000..23cf79ca0
--- /dev/null
+++ b/ext/node/polyfills/_crypto/crypto_browserify/asn1.js/mod.js
@@ -0,0 +1,96 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright 2017 Fedor Indutny. All rights reserved. MIT license.
+
+import bignum from "internal:deno_node/polyfills/_crypto/crypto_browserify/bn.js/bn.js";
+import { Node } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/node.js";
+import {
+ DecoderBuffer,
+ EncoderBuffer,
+} from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/buffer.js";
+import { Reporter } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/base/reporter.js";
+import { DEREncoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/der.js";
+import { PEMEncoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/encoders/pem.js";
+import { DERDecoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/der.js";
+import { PEMDecoder } from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/decoders/pem.js";
+import * as der from "internal:deno_node/polyfills/_crypto/crypto_browserify/asn1.js/constants/der.js";
+
+export const base = {
+ DecoderBuffer,
+ EncoderBuffer,
+ Node,
+ Reporter,
+};
+export const encoders = { der: DEREncoder, pem: PEMEncoder };
+export const decoders = { der: DERDecoder, pem: PEMDecoder };
+export const constants = { der };
+export { bignum };
+
+export 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 = Object.create(Base.prototype, {
+ constructor: {
+ value: Generated,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+ });
+ 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
+ // deno-lint-ignore no-prototype-builtins
+ 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
+ // deno-lint-ignore no-prototype-builtins
+ 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);
+};
+
+export default {
+ base,
+ bignum,
+ constants,
+ decoders,
+ define,
+ encoders,
+};