UNPKG

ya-express-ntlm

Version:
117 lines 4.26 kB
import assert from 'assert'; import { Buffer } from 'buffer'; import * as utils from './utils'; export const makeTLV = (derType, payload) => { if (typeof payload === 'string') { payload = Buffer.from(payload); } let tlv; let offset; if (payload.length < 128) { tlv = Buffer.alloc(1 + 1 + payload.length); tlv.writeUInt8(derType, 0); tlv.writeUInt8(payload.length, 1); offset = 2; } else if (payload.length < 256) { tlv = Buffer.alloc(1 + 2 + payload.length); tlv.writeUInt8(derType, 0); tlv.writeUInt8(utils.toBinary('10000001'), 1); // Number of length bytes = 1 tlv.writeUInt8(payload.length, 2); offset = 3; } else { tlv = Buffer.alloc(1 + 3 + payload.length); tlv.writeUInt8(derType, 0); tlv.writeUInt8(utils.toBinary('10000010'), 1); // Number of length bytes = 2 tlv.writeUInt16BE(payload.length, 2); offset = 4; } for (let i = 0; i < payload.length; i++) { tlv.writeUInt8(payload.readUInt8(i), offset++); } return tlv; }; export const makeINT = (num, tag) => { if (!tag) { tag = 0x02; } let payload; if (num <= 0) { payload = Buffer.from('\0'); } else { payload = Buffer.alloc(0); while (num > 0) { const buf = Buffer.alloc(1); buf.writeUInt8(num & 255, 0); // @ts-ignore payload = buf + payload; num >>>= 8; } } return makeTLV(tag, payload); }; export const makeSEQ = (payload) => makeTLV(0x30, payload); export const makeOctStr = (payload) => makeTLV(0x04, payload); export const parseLen = (berObj) => { let length = berObj.readUInt8(1); if (length < 128) { return [length, 2]; } const nLength = length & utils.toBinary('01111111'); length = 0; for (let i = 2; i < 2 + nLength; i++) { length = length * 256 + berObj.readUInt8(i); } return [length, 2 + nLength]; }; export const parseTLV = (derType, derObj) => { if (derObj.readUInt8(0) !== derType) { throw new Error(`BER element ${derObj.toString('hex')} does not start type 0x${derType.toString(16)}`); } const lengths = parseLen(derObj); const length = lengths[0]; const pStart = lengths[1]; if (derObj.length !== length + pStart) { throw new Error(`BER payload ${derObj.toString('hex')} is not ${length} bytes long (type 0x${derType.toString(16)}).`); } return derObj.subarray(pStart); }; export const parseTLV2 = (derType, derObj) => { if (derObj.readUInt8(0) !== derType) { throw new Error(`BER element ${derObj.toString('hex')} does not start type 0x${derType.toString(16)}`); } const lengths = parseLen(derObj); const length = lengths[0]; const pStart = lengths[1]; if (derObj.length < length + pStart) { throw new Error(`BER payload ${derObj.toString('hex')} is shorter than expected (${length} bytes, type 0x${derType.toString(16)}).`); } return [derObj.subarray(pStart, pStart + length), derObj.subarray(pStart + length)]; }; export const parseINT = (payload, tag = 0x02) => { const res = parseTLV(tag, payload); let value = 0; assert.equal(res.readUInt8(0) & utils.toBinary('10000000'), 0x00); for (let i = 0; i < res.length; i++) { value = value * 256 + res.readUInt8(i); } return value; }; export const parseINT2 = (payload, tag = 0x02) => { const [res0, res1] = parseTLV2(tag, payload); let value = 0; assert.equal(res0.readUInt8(0) & utils.toBinary('10000000'), 0x00); for (let i = 0; i < res0.length; i++) { value = value * 256 + res0.readUInt8(i); } return [value, res1]; }; // export const parseENUM = (payload: Buffer): number => parseINT(payload, 0x0A); export const parseENUM2 = (payload) => parseINT2(payload, 0x0A); export const parseSEQ = (payload) => parseTLV(0x30, payload); // export const parseSEQ2 = (payload: Buffer): [Buffer, Buffer] => parseTLV2(0x30, payload); // export const parseOctStr = (payload: Buffer): Buffer => parseTLV(0x04, payload); export const parseOctStr2 = (payload) => parseTLV2(0x04, payload); //# sourceMappingURL=ASN1.js.map