From f14f4838a8a5b86aa362f6fd23076877f721d788 Mon Sep 17 00:00:00 2001 From: Hasan Adams Date: Tue, 18 Apr 2023 03:52:51 -0700 Subject: [PATCH] Add TLSA support (#92) * add tlsa record support * add test for tlsa and update readme --- README.md | 11 +++++++++++ index.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test.js | 10 ++++++++++ 3 files changed, 76 insertions(+) diff --git a/README.md b/README.md index 763e1d5..3c8ccf1 100644 --- a/README.md +++ b/README.md @@ -374,6 +374,17 @@ The options `PADDING`, `CLIENT_SUBNET`, `TCP_KEEPALIVE` and `KEY_TAG` support en } ``` +#### `TLSA` + +``` js +{ + usage: 3, + selector: 1, + matchingType: 1, + certificate: Buffer +} +``` + #### `TXT` ``` js diff --git a/index.js b/index.js index cc45e80..5f14d1c 100644 --- a/index.js +++ b/index.js @@ -1409,6 +1409,60 @@ rnaptr.encodingLength = function (data) { name.encodingLength(data.replacement) + 6 } +const rtlsa = exports.tlsa = {} + +rtlsa.encode = function (cert, buf, offset) { + if (!buf) buf = Buffer.alloc(rtlsa.encodingLength(cert)) + if (!offset) offset = 0 + const oldOffset = offset + + const certdata = cert.certificate + if (!Buffer.isBuffer(certdata)) { + throw new Error('Certificate must be a Buffer') + } + + offset += 2 // Leave space for length + buf.writeUInt8(cert.usage, offset) + offset += 1 + buf.writeUInt8(cert.selector, offset) + offset += 1 + buf.writeUInt8(cert.matchingType, offset) + offset += 1 + certdata.copy(buf, offset, 0, certdata.length) + offset += certdata.length + + rtlsa.encode.bytes = offset - oldOffset + buf.writeUInt16BE(rtlsa.encode.bytes - 2, oldOffset) + return buf +} + +rtlsa.encode.bytes = 0 + +rtlsa.decode = function (buf, offset) { + if (!offset) offset = 0 + const oldOffset = offset + + const cert = {} + const length = buf.readUInt16BE(offset) + offset += 2 + cert.usage = buf.readUInt8(offset) + offset += 1 + cert.selector = buf.readUInt8(offset) + offset += 1 + cert.matchingType = buf.readUInt8(offset) + offset += 1 + cert.certificate = buf.slice(offset, oldOffset + length + 2) + offset += cert.certificate.length + rtlsa.decode.bytes = offset - oldOffset + return cert +} + +rtlsa.decode.bytes = 0 + +rtlsa.encodingLength = function (cert) { + return 5 + Buffer.byteLength(cert.certificate) +} + const renc = exports.record = function (type) { switch (type.toUpperCase()) { case 'A': return ra @@ -1433,6 +1487,7 @@ const renc = exports.record = function (type) { case 'SSHFP': return rsshfp case 'DS': return rds case 'NAPTR': return rnaptr + case 'TLSA': return rtlsa } return runknown } diff --git a/test.js b/test.js index 927b56f..70b3b73 100644 --- a/test.js +++ b/test.js @@ -568,6 +568,16 @@ tape('naptr', function (t) { t.end() }) +tape('tlsa', function (t) { + testEncoder(t, packet.tlsa, { + usage: 3, + selector: 1, + matchingType: 1, + certificate: Buffer.from([0, 1, 2, 3, 4, 5]) + }) + t.end() +}) + tape('unpack', function (t) { const buf = Buffer.from([ 0x00, 0x79,