@nictool/dns-resource-record 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +323 -199
- package/dist/dns-rr.min.js +26 -0
- package/dist/dns-rr.min.js.map +7 -0
- package/index.js +12 -11
- package/lib/binary.js +108 -0
- package/lib/bind.js +94 -0
- package/lib/dns-query.js +67 -0
- package/lib/tinydns.js +128 -44
- package/lib/wire.js +519 -0
- package/package.json +23 -6
- package/rr/TEMPLATE.js +124 -0
- package/rr/a.js +8 -48
- package/rr/aaaa.js +13 -80
- package/rr/apl.js +123 -27
- package/rr/caa.js +27 -50
- package/rr/cert.js +58 -87
- package/rr/cname.js +7 -63
- package/rr/dhcid.js +20 -30
- package/rr/dname.js +9 -36
- package/rr/dnskey.js +38 -32
- package/rr/ds.js +43 -57
- package/rr/hinfo.js +21 -40
- package/rr/hip.js +88 -26
- package/rr/https.js +28 -40
- package/rr/ipseckey.js +97 -18
- package/rr/key.js +39 -29
- package/rr/kx.js +16 -27
- package/rr/loc.js +42 -12
- package/rr/mx.js +16 -51
- package/rr/naptr.js +58 -33
- package/rr/ns.js +8 -36
- package/rr/nsec.js +89 -18
- package/rr/nsec3.js +62 -26
- package/rr/nsec3param.js +56 -53
- package/rr/nxt.js +57 -18
- package/rr/openpgpkey.js +24 -30
- package/rr/ptr.js +7 -47
- package/rr/rp.js +17 -32
- package/rr/rrsig.js +80 -85
- package/rr/sig.js +70 -45
- package/rr/smimea.js +33 -33
- package/rr/soa.js +31 -49
- package/rr/spf.js +10 -17
- package/rr/srv.js +22 -62
- package/rr/sshfp.js +25 -53
- package/rr/svcb.js +27 -40
- package/rr/tlsa.js +34 -34
- package/rr/tsig.js +87 -24
- package/rr/txt.js +40 -59
- package/rr/uri.js +19 -29
- package/rr/wks.js +154 -22
- package/rr.js +290 -109
- package/lib/readme.js +0 -84
package/rr/cert.js
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as BINARY from '../lib/binary.js'
|
|
4
5
|
|
|
5
6
|
export default class CERT extends RR {
|
|
7
|
+
static typeName = 'CERT'
|
|
8
|
+
static typeId = 37
|
|
9
|
+
static RFCs = [2538, 4398]
|
|
10
|
+
static rdataFields = [
|
|
11
|
+
['cert type', 'certtype'],
|
|
12
|
+
['key tag', 'u16'],
|
|
13
|
+
['algorithm', 'u8'],
|
|
14
|
+
['certificate', 'base64'],
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
static CERT_TYPES = {
|
|
18
|
+
PKIX: 1,
|
|
19
|
+
SPKI: 2,
|
|
20
|
+
PGP: 3,
|
|
21
|
+
IPKIX: 4,
|
|
22
|
+
ISPKI: 5,
|
|
23
|
+
IPGP: 6,
|
|
24
|
+
ACPKIX: 7,
|
|
25
|
+
IACPKIX: 8,
|
|
26
|
+
URI: 253,
|
|
27
|
+
OID: 254,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static CERT_TYPES_REVERSE = Object.fromEntries(Object.entries(CERT.CERT_TYPES).map(([k, v]) => [v, k]))
|
|
31
|
+
|
|
6
32
|
constructor(opts) {
|
|
7
33
|
super(opts)
|
|
8
34
|
}
|
|
@@ -15,20 +41,8 @@ export default class CERT extends RR {
|
|
|
15
41
|
this.throwHelp('cert type is required')
|
|
16
42
|
}
|
|
17
43
|
// Accept both mnemonic and numeric, but validate mnemonic
|
|
18
|
-
if (typeof val === 'string') {
|
|
19
|
-
|
|
20
|
-
PKIX: 1,
|
|
21
|
-
SPKI: 2,
|
|
22
|
-
PGP: 3,
|
|
23
|
-
IPKIX: 4,
|
|
24
|
-
ISPKI: 5,
|
|
25
|
-
IPGP: 6,
|
|
26
|
-
ACPKIX: 7,
|
|
27
|
-
IACPKIX: 8,
|
|
28
|
-
URI: 253,
|
|
29
|
-
OID: 254,
|
|
30
|
-
}
|
|
31
|
-
if (!Object.hasOwn(types, val)) {
|
|
44
|
+
if (typeof val === 'string' && !/^[0-9]+$/.test(val)) {
|
|
45
|
+
if (!Object.hasOwn(CERT.CERT_TYPES, val)) {
|
|
32
46
|
this.throwHelp(`CERT: unknown cert type mnemonic: ${val}`)
|
|
33
47
|
}
|
|
34
48
|
} else {
|
|
@@ -39,45 +53,18 @@ export default class CERT extends RR {
|
|
|
39
53
|
|
|
40
54
|
getCertTypeValue(val) {
|
|
41
55
|
if (typeof val === 'number') return val
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
SPKI: 2,
|
|
45
|
-
PGP: 3,
|
|
46
|
-
IPKIX: 4,
|
|
47
|
-
ISPKI: 5,
|
|
48
|
-
IPGP: 6,
|
|
49
|
-
ACPKIX: 7,
|
|
50
|
-
IACPKIX: 8,
|
|
51
|
-
URI: 253,
|
|
52
|
-
OID: 254,
|
|
53
|
-
}
|
|
54
|
-
if (Object.hasOwn(types, val)) return types[val]
|
|
56
|
+
if (/^[0-9]+$/.test(val)) return parseInt(val, 10)
|
|
57
|
+
if (Object.hasOwn(CERT.CERT_TYPES, val)) return CERT.CERT_TYPES[val]
|
|
55
58
|
this.throwHelp(`CERT: unknown cert type mnemonic: ${val}`)
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
setKeyTag(val) {
|
|
59
|
-
// The key tag field is the 16-bit value
|
|
60
|
-
// The key tag field is represented as an unsigned decimal integer.
|
|
61
|
-
|
|
62
|
-
this.is16bitInt('CERT', 'key tag', val)
|
|
63
|
-
|
|
64
|
-
this.set('key tag', val)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
setAlgorithm(val) {
|
|
68
|
-
// The algorithm field has the same meaning as the algorithm field in DNSKEY
|
|
69
|
-
// The algorithm field is represented as an unsigned decimal integer
|
|
70
|
-
this.is8bitInt('CERT', 'algorithm', val)
|
|
71
|
-
|
|
72
|
-
this.set('algorithm', val)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
61
|
setCertificate(val) {
|
|
76
62
|
// certificate/CRL portion is represented in base 64 [16] and may be
|
|
77
63
|
// divided into any number of white-space-separated substrings
|
|
78
64
|
if (val === undefined || val === null || val === '') {
|
|
79
65
|
this.throwHelp('certificate is required and cannot be empty')
|
|
80
66
|
}
|
|
67
|
+
this.isBase64('CERT', 'certificate', val.replace(/[\s()]/g, ''))
|
|
81
68
|
this.set('certificate', val)
|
|
82
69
|
}
|
|
83
70
|
|
|
@@ -85,18 +72,6 @@ export default class CERT extends RR {
|
|
|
85
72
|
return 'Certificate'
|
|
86
73
|
}
|
|
87
74
|
|
|
88
|
-
getRdataFields() {
|
|
89
|
-
return ['cert type', 'key tag', 'algorithm', 'certificate']
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
getRFCs() {
|
|
93
|
-
return [2538, 4398]
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
getTypeId() {
|
|
97
|
-
return 37
|
|
98
|
-
}
|
|
99
|
-
|
|
100
75
|
getCanonical() {
|
|
101
76
|
return {
|
|
102
77
|
owner: 'mail.example.com.',
|
|
@@ -106,44 +81,31 @@ export default class CERT extends RR {
|
|
|
106
81
|
'cert type': 'PGP',
|
|
107
82
|
'key tag': 0,
|
|
108
83
|
algorithm: 0,
|
|
109
|
-
certificate: '
|
|
84
|
+
certificate: 'AQIDBA==',
|
|
110
85
|
}
|
|
111
86
|
}
|
|
112
87
|
|
|
113
88
|
/****** IMPORTERS *******/
|
|
114
89
|
|
|
115
90
|
fromTinydns({ tinyline }) {
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
const bytes =
|
|
120
|
-
const typeNum = bytes
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const types = {
|
|
124
|
-
1: 'PKIX',
|
|
125
|
-
2: 'SPKI',
|
|
126
|
-
3: 'PGP',
|
|
127
|
-
4: 'IPKIX',
|
|
128
|
-
5: 'ISPKI',
|
|
129
|
-
6: 'IPGP',
|
|
130
|
-
7: 'ACPKIX',
|
|
131
|
-
8: 'IACPKIX',
|
|
132
|
-
253: 'URI',
|
|
133
|
-
254: 'OID',
|
|
134
|
-
}
|
|
135
|
-
if (types[typeNum]) certType = types[typeNum]
|
|
91
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
92
|
+
if (typeId != this.getTypeId()) this.throwHelp('CERT fromTinydns, invalid n')
|
|
93
|
+
|
|
94
|
+
const bytes = TINYDNS.octalRdataToBytes(rdata)
|
|
95
|
+
const typeNum = (bytes[0] << 8) | bytes[1]
|
|
96
|
+
|
|
97
|
+
const certType = CERT.CERT_TYPES_REVERSE[typeNum] ?? typeNum
|
|
136
98
|
|
|
137
99
|
return new CERT({
|
|
138
|
-
owner
|
|
139
|
-
ttl
|
|
100
|
+
owner,
|
|
101
|
+
ttl,
|
|
140
102
|
type: 'CERT',
|
|
141
103
|
'cert type': certType,
|
|
142
|
-
'key tag': bytes
|
|
143
|
-
algorithm: bytes
|
|
144
|
-
certificate: bytes.
|
|
145
|
-
timestamp
|
|
146
|
-
location
|
|
104
|
+
'key tag': (bytes[2] << 8) | bytes[3],
|
|
105
|
+
algorithm: bytes[4],
|
|
106
|
+
certificate: BINARY.bytesToBase64(bytes.subarray(5)),
|
|
107
|
+
timestamp,
|
|
108
|
+
location,
|
|
147
109
|
})
|
|
148
110
|
}
|
|
149
111
|
|
|
@@ -165,13 +127,22 @@ export default class CERT extends RR {
|
|
|
165
127
|
/****** EXPORTERS *******/
|
|
166
128
|
|
|
167
129
|
toTinydns() {
|
|
168
|
-
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
169
|
-
|
|
170
130
|
return this.getTinydnsGeneric(
|
|
171
131
|
TINYDNS.UInt16toOctal(this.getCertTypeValue(this.get('cert type'))) +
|
|
172
132
|
TINYDNS.UInt16toOctal(this.get('key tag')) +
|
|
173
133
|
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
174
|
-
TINYDNS.
|
|
134
|
+
TINYDNS.base64toOctal(this.get('certificate').replace(/[\s()]/g, '')),
|
|
175
135
|
)
|
|
176
136
|
}
|
|
137
|
+
|
|
138
|
+
getWireRdata() {
|
|
139
|
+
const certBytes = BINARY.base64ToBytes(this.get('certificate').replace(/[\s()]/g, ''))
|
|
140
|
+
const bytes = new Uint8Array(5 + certBytes.length)
|
|
141
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset)
|
|
142
|
+
dv.setUint16(0, this.getCertTypeValue(this.get('cert type')))
|
|
143
|
+
dv.setUint16(2, this.get('key tag'))
|
|
144
|
+
bytes[4] = this.get('algorithm')
|
|
145
|
+
bytes.set(certBytes, 5)
|
|
146
|
+
return bytes
|
|
147
|
+
}
|
|
177
148
|
}
|
package/rr/cname.js
CHANGED
|
@@ -1,46 +1,21 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
export default class CNAME extends RR {
|
|
4
|
+
static typeName = 'CNAME'
|
|
5
|
+
static typeId = 5
|
|
6
|
+
static RFCs = [1035, 2181]
|
|
7
|
+
static tinydnsType = 'C'
|
|
8
|
+
static rdataFields = [['cname', 'fqdn']]
|
|
9
|
+
static tags = ['common']
|
|
10
|
+
|
|
4
11
|
constructor(opts) {
|
|
5
12
|
super(opts)
|
|
6
13
|
}
|
|
7
14
|
|
|
8
|
-
/****** Resource record specific setters *******/
|
|
9
|
-
setCname(val) {
|
|
10
|
-
// A <domain-name> which specifies the canonical or primary
|
|
11
|
-
// name for the owner. The owner name is an alias.
|
|
12
|
-
|
|
13
|
-
if (!val) this.throwHelp('CNAME: cname is required')
|
|
14
|
-
|
|
15
|
-
if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
|
|
16
|
-
|
|
17
|
-
if (!this.isFullyQualified('CNAME', 'cname', val)) return
|
|
18
|
-
if (!this.isValidHostname('CNAME', 'cname', val)) return
|
|
19
|
-
|
|
20
|
-
// RFC 4034: letters in the DNS names are lower cased
|
|
21
|
-
this.set('cname', val.toLowerCase())
|
|
22
|
-
}
|
|
23
|
-
|
|
24
15
|
getDescription() {
|
|
25
16
|
return 'Canonical Name'
|
|
26
17
|
}
|
|
27
18
|
|
|
28
|
-
getTags() {
|
|
29
|
-
return ['common']
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
getRdataFields(arg) {
|
|
33
|
-
return ['cname']
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
getRFCs() {
|
|
37
|
-
return [1035, 2181]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
getTypeId() {
|
|
41
|
-
return 5
|
|
42
|
-
}
|
|
43
|
-
|
|
44
19
|
getCanonical() {
|
|
45
20
|
return {
|
|
46
21
|
owner: 'www.example.com.',
|
|
@@ -51,39 +26,8 @@ export default class CNAME extends RR {
|
|
|
51
26
|
}
|
|
52
27
|
}
|
|
53
28
|
|
|
54
|
-
/****** IMPORTERS *******/
|
|
55
|
-
fromTinydns({ tinyline }) {
|
|
56
|
-
// Cfqdn:p:ttl:timestamp:lo
|
|
57
|
-
const [fqdn, p, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
58
|
-
|
|
59
|
-
return new CNAME({
|
|
60
|
-
owner: this.fullyQualify(fqdn),
|
|
61
|
-
ttl: parseInt(ttl, 10),
|
|
62
|
-
type: 'CNAME',
|
|
63
|
-
cname: this.fullyQualify(p),
|
|
64
|
-
timestamp: ts,
|
|
65
|
-
location: loc?.trim() ?? '',
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
fromBind({ bindline }) {
|
|
70
|
-
// test.example.com 3600 IN CNAME ...
|
|
71
|
-
const [owner, ttl, c, type, cname] = bindline.split(/\s+/)
|
|
72
|
-
return new CNAME({
|
|
73
|
-
owner,
|
|
74
|
-
ttl: parseInt(ttl, 10),
|
|
75
|
-
class: c,
|
|
76
|
-
type,
|
|
77
|
-
cname,
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
29
|
/****** EXPORTERS *******/
|
|
82
30
|
getWireRdata() {
|
|
83
31
|
return this.wirePackDomain(this.get('cname'))
|
|
84
32
|
}
|
|
85
|
-
|
|
86
|
-
toTinydns() {
|
|
87
|
-
return `C${this.getTinyFQDN('owner')}:${this.get('cname')}:${this.getTinydnsPostamble()}\n`
|
|
88
|
-
}
|
|
89
33
|
}
|
package/rr/dhcid.js
CHANGED
|
@@ -3,6 +3,11 @@ import RR from '../rr.js'
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
4
|
|
|
5
5
|
export default class DHCID extends RR {
|
|
6
|
+
static typeName = 'DHCID'
|
|
7
|
+
static typeId = 49
|
|
8
|
+
static RFCs = [4701]
|
|
9
|
+
static rdataFields = [['data', 'base64']]
|
|
10
|
+
|
|
6
11
|
constructor(opts) {
|
|
7
12
|
super(opts)
|
|
8
13
|
}
|
|
@@ -10,6 +15,7 @@ export default class DHCID extends RR {
|
|
|
10
15
|
/****** Resource record specific setters *******/
|
|
11
16
|
setData(val) {
|
|
12
17
|
if (!val) this.throwHelp('DHCID: data is required')
|
|
18
|
+
this.isBase64('DHCID', 'data', val)
|
|
13
19
|
this.set('data', val)
|
|
14
20
|
}
|
|
15
21
|
|
|
@@ -17,18 +23,6 @@ export default class DHCID extends RR {
|
|
|
17
23
|
return 'DHCP Identifier'
|
|
18
24
|
}
|
|
19
25
|
|
|
20
|
-
getRdataFields(arg) {
|
|
21
|
-
return ['data']
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getRFCs() {
|
|
25
|
-
return [4701]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getTypeId() {
|
|
29
|
-
return 49
|
|
30
|
-
}
|
|
31
|
-
|
|
32
26
|
getCanonical() {
|
|
33
27
|
return {
|
|
34
28
|
owner: 'host.example.com.',
|
|
@@ -42,33 +36,29 @@ export default class DHCID extends RR {
|
|
|
42
36
|
/****** IMPORTERS *******/
|
|
43
37
|
fromTinydns({ tinyline }) {
|
|
44
38
|
// DHCID via generic, :fqdn:49:rdata:ttl:timestamp:lo
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
39
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
40
|
+
if (typeId != this.getTypeId()) this.throwHelp('DHCID fromTinydns, invalid n')
|
|
47
41
|
|
|
48
42
|
return new DHCID({
|
|
49
|
-
owner
|
|
50
|
-
ttl
|
|
43
|
+
owner,
|
|
44
|
+
ttl,
|
|
51
45
|
type: 'DHCID',
|
|
52
46
|
data: TINYDNS.octalToBase64(rdata),
|
|
53
|
-
timestamp
|
|
54
|
-
location
|
|
47
|
+
timestamp,
|
|
48
|
+
location,
|
|
55
49
|
})
|
|
56
50
|
}
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
type,
|
|
67
|
-
data: parts.slice(4).join(''),
|
|
68
|
-
})
|
|
52
|
+
/****** EXPORTERS *******/
|
|
53
|
+
|
|
54
|
+
getWireRdata() {
|
|
55
|
+
return new Uint8Array(
|
|
56
|
+
atob(this.get('data'))
|
|
57
|
+
.split('')
|
|
58
|
+
.map((c) => c.charCodeAt(0)),
|
|
59
|
+
)
|
|
69
60
|
}
|
|
70
61
|
|
|
71
|
-
/****** EXPORTERS *******/
|
|
72
62
|
toTinydns() {
|
|
73
63
|
return this.getTinydnsGeneric(TINYDNS.base64toOctal(this.get('data')))
|
|
74
64
|
}
|
package/rr/dname.js
CHANGED
|
@@ -2,39 +2,19 @@ import RR from '../rr.js'
|
|
|
2
2
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
3
3
|
|
|
4
4
|
export default class DNAME extends RR {
|
|
5
|
+
static typeName = 'DNAME'
|
|
6
|
+
static typeId = 39
|
|
7
|
+
static RFCs = [2672, 6672]
|
|
8
|
+
static rdataFields = [['target', 'fqdn']]
|
|
9
|
+
|
|
5
10
|
constructor(opts) {
|
|
6
11
|
super(opts)
|
|
7
12
|
}
|
|
8
13
|
|
|
9
|
-
/****** Resource record specific setters *******/
|
|
10
|
-
setTarget(val) {
|
|
11
|
-
if (!val) this.throwHelp('DNAME: target is required')
|
|
12
|
-
|
|
13
|
-
if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`DNAME: target must be a domain name`)
|
|
14
|
-
|
|
15
|
-
this.isFullyQualified('DNAME', 'target', val)
|
|
16
|
-
this.isValidHostname('DNAME', 'target', val)
|
|
17
|
-
|
|
18
|
-
// RFC 4034: letters in the DNS names are lower cased
|
|
19
|
-
this.set('target', val.toLowerCase())
|
|
20
|
-
}
|
|
21
|
-
|
|
22
14
|
getDescription() {
|
|
23
15
|
return 'Delegation Name'
|
|
24
16
|
}
|
|
25
17
|
|
|
26
|
-
getRdataFields(arg) {
|
|
27
|
-
return ['target']
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getRFCs() {
|
|
31
|
-
return [2672, 6672]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getTypeId() {
|
|
35
|
-
return 39
|
|
36
|
-
}
|
|
37
|
-
|
|
38
18
|
getCanonical() {
|
|
39
19
|
return {
|
|
40
20
|
owner: 'example.com.',
|
|
@@ -61,19 +41,12 @@ export default class DNAME extends RR {
|
|
|
61
41
|
})
|
|
62
42
|
}
|
|
63
43
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return
|
|
68
|
-
owner,
|
|
69
|
-
ttl: parseInt(ttl, 10),
|
|
70
|
-
class: c,
|
|
71
|
-
type,
|
|
72
|
-
target,
|
|
73
|
-
})
|
|
44
|
+
/****** EXPORTERS *******/
|
|
45
|
+
|
|
46
|
+
getWireRdata() {
|
|
47
|
+
return this.wirePackDomain(this.get('target'))
|
|
74
48
|
}
|
|
75
49
|
|
|
76
|
-
/****** EXPORTERS *******/
|
|
77
50
|
toTinydns() {
|
|
78
51
|
const rdata = TINYDNS.packDomainName(this.get('target'))
|
|
79
52
|
return this.getTinydnsGeneric(rdata)
|
package/rr/dnskey.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as BINARY from '../lib/binary.js'
|
|
4
5
|
|
|
5
6
|
export default class DNSKEY extends RR {
|
|
7
|
+
static typeName = 'DNSKEY'
|
|
8
|
+
static typeId = 48
|
|
9
|
+
static RFCs = [4034, 6014, 8624, 9619, 9905]
|
|
10
|
+
static rdataFields = [
|
|
11
|
+
['flags', 'u16'],
|
|
12
|
+
['protocol', 'u8'],
|
|
13
|
+
['algorithm', 'u8'],
|
|
14
|
+
['publickey', 'base64'],
|
|
15
|
+
]
|
|
16
|
+
static tags = ['dnssec']
|
|
17
|
+
|
|
6
18
|
constructor(opts) {
|
|
7
19
|
super(opts)
|
|
8
20
|
}
|
|
@@ -71,7 +83,7 @@ export default class DNSKEY extends RR {
|
|
|
71
83
|
|
|
72
84
|
setPublickey(val) {
|
|
73
85
|
if (!val) this.throwHelp(`DNSKEY: publickey is required`)
|
|
74
|
-
|
|
86
|
+
this.isBase64('DNSKEY', 'publickey', val.replace(/[\s()]/g, ''))
|
|
75
87
|
this.set('publickey', val)
|
|
76
88
|
}
|
|
77
89
|
|
|
@@ -79,22 +91,6 @@ export default class DNSKEY extends RR {
|
|
|
79
91
|
return 'DNS Public Key'
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
getTags() {
|
|
83
|
-
return ['dnssec']
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getRdataFields(arg) {
|
|
87
|
-
return ['flags', 'protocol', 'algorithm', 'publickey']
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
getRFCs() {
|
|
91
|
-
return [4034, 6014, 8624]
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
getTypeId() {
|
|
95
|
-
return 48
|
|
96
|
-
}
|
|
97
|
-
|
|
98
94
|
getCanonical() {
|
|
99
95
|
return {
|
|
100
96
|
owner: 'example.com.',
|
|
@@ -104,7 +100,8 @@ export default class DNSKEY extends RR {
|
|
|
104
100
|
flags: 256,
|
|
105
101
|
protocol: 3,
|
|
106
102
|
algorithm: 5,
|
|
107
|
-
publickey:
|
|
103
|
+
publickey:
|
|
104
|
+
'AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwIXAqcOTiW7iHnQt5hwVAAAAA==',
|
|
108
105
|
}
|
|
109
106
|
}
|
|
110
107
|
|
|
@@ -136,34 +133,43 @@ export default class DNSKEY extends RR {
|
|
|
136
133
|
}
|
|
137
134
|
|
|
138
135
|
fromTinydns({ tinyline }) {
|
|
139
|
-
const
|
|
140
|
-
if (
|
|
136
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
137
|
+
if (typeId != this.getTypeId()) this.throwHelp('DNSKEY fromTinydns, invalid n')
|
|
141
138
|
|
|
142
|
-
const bytes =
|
|
139
|
+
const bytes = TINYDNS.octalRdataToBytes(rdata)
|
|
143
140
|
|
|
144
141
|
return new DNSKEY({
|
|
145
|
-
owner
|
|
146
|
-
ttl
|
|
142
|
+
owner,
|
|
143
|
+
ttl,
|
|
147
144
|
type: 'DNSKEY',
|
|
148
|
-
flags: bytes
|
|
149
|
-
protocol: bytes
|
|
150
|
-
algorithm: bytes
|
|
151
|
-
publickey: bytes.
|
|
152
|
-
timestamp
|
|
153
|
-
location
|
|
145
|
+
flags: (bytes[0] << 8) | bytes[1],
|
|
146
|
+
protocol: bytes[2],
|
|
147
|
+
algorithm: bytes[3],
|
|
148
|
+
publickey: BINARY.bytesToBase64(bytes.subarray(4)),
|
|
149
|
+
timestamp,
|
|
150
|
+
location,
|
|
154
151
|
})
|
|
155
152
|
}
|
|
156
153
|
|
|
157
154
|
/****** EXPORTERS *******/
|
|
158
155
|
|
|
159
156
|
toTinydns() {
|
|
160
|
-
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
161
|
-
|
|
162
157
|
return this.getTinydnsGeneric(
|
|
163
158
|
TINYDNS.UInt16toOctal(this.get('flags')) +
|
|
164
159
|
TINYDNS.UInt8toOctal(this.get('protocol')) +
|
|
165
160
|
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
166
|
-
TINYDNS.
|
|
161
|
+
TINYDNS.base64toOctal(this.get('publickey').replace(/[\s()]/g, '')),
|
|
167
162
|
)
|
|
168
163
|
}
|
|
164
|
+
|
|
165
|
+
getWireRdata() {
|
|
166
|
+
const keyBytes = BINARY.base64ToBytes(this.get('publickey').replace(/[\s()]/g, ''))
|
|
167
|
+
const bytes = new Uint8Array(4 + keyBytes.length)
|
|
168
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset)
|
|
169
|
+
dv.setUint16(0, this.get('flags'))
|
|
170
|
+
bytes[2] = this.get('protocol')
|
|
171
|
+
bytes[3] = this.get('algorithm')
|
|
172
|
+
bytes.set(keyBytes, 4)
|
|
173
|
+
return bytes
|
|
174
|
+
}
|
|
169
175
|
}
|