jose/src/runtime/node/asn1_sequence_decoder.ts
2020-11-22 12:44:27 +01:00

61 lines
1.2 KiB
TypeScript

const tagInteger = 0x02
const tagSequence = 0x30
/**
* The end justifies the means.
*/
export default class Asn1SequenceDecoder {
buffer: Buffer
offset: number
constructor(buffer: Buffer) {
if (buffer[0] !== tagSequence) {
throw new TypeError()
}
this.buffer = buffer
this.offset = 1
const len = this.decodeLength()
if (len !== buffer.length - this.offset) {
throw new TypeError()
}
}
decodeLength() {
let length = this.buffer[this.offset++]
if (length & 0x80) {
// Long form.
const nBytes = length & ~0x80
length = 0
for (let i = 0; i < nBytes; i++) length = (length << 8) | this.buffer[this.offset + i]
this.offset += nBytes
}
return length
}
unsignedInteger() {
if (this.buffer[this.offset++] !== tagInteger) {
throw new TypeError()
}
let length = this.decodeLength()
// There may be exactly one leading zero (if the next byte's MSB is set).
if (this.buffer[this.offset] === 0) {
this.offset++
length--
}
const result = this.buffer.slice(this.offset, this.offset + length)
this.offset += length
return result
}
end() {
if (this.offset !== this.buffer.length) {
throw new TypeError()
}
}
}