mirror of
https://github.com/danbulant/jose
synced 2026-05-23 06:18:58 +00:00
61 lines
1.2 KiB
TypeScript
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()
|
|
}
|
|
}
|
|
}
|