@nictool/dns-resource-record 1.6.1 → 1.8.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 +47 -0
- package/README.md +356 -199
- package/dist/dns-rr.cjs +7050 -0
- 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 +96 -0
- package/lib/dns-query.js +67 -0
- package/lib/tinydns.js +128 -44
- package/lib/wire.js +629 -0
- package/package.json +28 -8
- 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 +60 -81
- package/rr/cname.js +8 -59
- package/rr/dhcid.js +20 -30
- package/rr/dname.js +10 -32
- package/rr/dnskey.js +38 -32
- package/rr/ds.js +59 -54
- 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 +17 -48
- 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 +108 -75
- package/rr/sig.js +70 -45
- package/rr/smimea.js +33 -33
- package/rr/soa.js +31 -49
- package/rr/spf.js +15 -18
- package/rr/srv.js +28 -51
- package/rr/sshfp.js +35 -48
- package/rr/svcb.js +27 -40
- package/rr/tlsa.js +34 -34
- package/rr/tsig.js +87 -24
- package/rr/txt.js +77 -68
- 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,37 +53,17 @@ 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
61
|
setKeyTag(val) {
|
|
59
|
-
|
|
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)
|
|
62
|
+
this.setTypedValue('u16', 'key tag', val)
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
setAlgorithm(val) {
|
|
68
|
-
|
|
69
|
-
// The algorithm field is represented as an unsigned decimal integer
|
|
70
|
-
this.is8bitInt('CERT', 'algorithm', val)
|
|
71
|
-
|
|
72
|
-
this.set('algorithm', val)
|
|
66
|
+
this.setTypedValue('u8', 'algorithm', val)
|
|
73
67
|
}
|
|
74
68
|
|
|
75
69
|
setCertificate(val) {
|
|
@@ -78,6 +72,7 @@ export default class CERT extends RR {
|
|
|
78
72
|
if (val === undefined || val === null || val === '') {
|
|
79
73
|
this.throwHelp('certificate is required and cannot be empty')
|
|
80
74
|
}
|
|
75
|
+
this.isBase64('CERT', 'certificate', val.replace(/[\s()]/g, ''))
|
|
81
76
|
this.set('certificate', val)
|
|
82
77
|
}
|
|
83
78
|
|
|
@@ -85,18 +80,6 @@ export default class CERT extends RR {
|
|
|
85
80
|
return 'Certificate'
|
|
86
81
|
}
|
|
87
82
|
|
|
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
83
|
getCanonical() {
|
|
101
84
|
return {
|
|
102
85
|
owner: 'mail.example.com.',
|
|
@@ -106,44 +89,31 @@ export default class CERT extends RR {
|
|
|
106
89
|
'cert type': 'PGP',
|
|
107
90
|
'key tag': 0,
|
|
108
91
|
algorithm: 0,
|
|
109
|
-
certificate: '
|
|
92
|
+
certificate: 'AQIDBA==',
|
|
110
93
|
}
|
|
111
94
|
}
|
|
112
95
|
|
|
113
96
|
/****** IMPORTERS *******/
|
|
114
97
|
|
|
115
98
|
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]
|
|
99
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
100
|
+
if (typeId != this.getTypeId()) this.throwHelp('CERT fromTinydns, invalid n')
|
|
101
|
+
|
|
102
|
+
const bytes = TINYDNS.octalRdataToBytes(rdata)
|
|
103
|
+
const typeNum = (bytes[0] << 8) | bytes[1]
|
|
104
|
+
|
|
105
|
+
const certType = CERT.CERT_TYPES_REVERSE[typeNum] ?? typeNum
|
|
136
106
|
|
|
137
107
|
return new CERT({
|
|
138
|
-
owner
|
|
139
|
-
ttl
|
|
108
|
+
owner,
|
|
109
|
+
ttl,
|
|
140
110
|
type: 'CERT',
|
|
141
111
|
'cert type': certType,
|
|
142
|
-
'key tag': bytes
|
|
143
|
-
algorithm: bytes
|
|
144
|
-
certificate: bytes.
|
|
145
|
-
timestamp
|
|
146
|
-
location
|
|
112
|
+
'key tag': (bytes[2] << 8) | bytes[3],
|
|
113
|
+
algorithm: bytes[4],
|
|
114
|
+
certificate: BINARY.bytesToBase64(bytes.subarray(5)),
|
|
115
|
+
timestamp,
|
|
116
|
+
location,
|
|
147
117
|
})
|
|
148
118
|
}
|
|
149
119
|
|
|
@@ -165,13 +135,22 @@ export default class CERT extends RR {
|
|
|
165
135
|
/****** EXPORTERS *******/
|
|
166
136
|
|
|
167
137
|
toTinydns() {
|
|
168
|
-
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
169
|
-
|
|
170
138
|
return this.getTinydnsGeneric(
|
|
171
139
|
TINYDNS.UInt16toOctal(this.getCertTypeValue(this.get('cert type'))) +
|
|
172
140
|
TINYDNS.UInt16toOctal(this.get('key tag')) +
|
|
173
141
|
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
174
|
-
TINYDNS.
|
|
142
|
+
TINYDNS.base64toOctal(this.get('certificate').replace(/[\s()]/g, '')),
|
|
175
143
|
)
|
|
176
144
|
}
|
|
145
|
+
|
|
146
|
+
getWireRdata() {
|
|
147
|
+
const certBytes = BINARY.base64ToBytes(this.get('certificate').replace(/[\s()]/g, ''))
|
|
148
|
+
const bytes = new Uint8Array(5 + certBytes.length)
|
|
149
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset)
|
|
150
|
+
dv.setUint16(0, this.getCertTypeValue(this.get('cert type')))
|
|
151
|
+
dv.setUint16(2, this.get('key tag'))
|
|
152
|
+
bytes[4] = this.get('algorithm')
|
|
153
|
+
bytes.set(certBytes, 5)
|
|
154
|
+
return bytes
|
|
155
|
+
}
|
|
177
156
|
}
|
package/rr/cname.js
CHANGED
|
@@ -1,46 +1,26 @@
|
|
|
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
15
|
/****** Resource record specific setters *******/
|
|
9
16
|
setCname(val) {
|
|
10
|
-
|
|
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())
|
|
17
|
+
this.setTypedValue('fqdn', 'cname', val)
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
getDescription() {
|
|
25
21
|
return 'Canonical Name'
|
|
26
22
|
}
|
|
27
23
|
|
|
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
24
|
getCanonical() {
|
|
45
25
|
return {
|
|
46
26
|
owner: 'www.example.com.',
|
|
@@ -51,39 +31,8 @@ export default class CNAME extends RR {
|
|
|
51
31
|
}
|
|
52
32
|
}
|
|
53
33
|
|
|
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
34
|
/****** EXPORTERS *******/
|
|
82
35
|
getWireRdata() {
|
|
83
36
|
return this.wirePackDomain(this.get('cname'))
|
|
84
37
|
}
|
|
85
|
-
|
|
86
|
-
toTinydns() {
|
|
87
|
-
return `C${this.getTinyFQDN('owner')}:${this.get('cname')}:${this.getTinydnsPostamble()}\n`
|
|
88
|
-
}
|
|
89
38
|
}
|
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,24 @@ 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
14
|
/****** Resource record specific setters *******/
|
|
10
15
|
setTarget(val) {
|
|
11
|
-
|
|
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())
|
|
16
|
+
this.setTypedValue('fqdn', 'target', val)
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
getDescription() {
|
|
23
20
|
return 'Delegation Name'
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
getRdataFields(arg) {
|
|
27
|
-
return ['target']
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getRFCs() {
|
|
31
|
-
return [2672, 6672]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getTypeId() {
|
|
35
|
-
return 39
|
|
36
|
-
}
|
|
37
|
-
|
|
38
23
|
getCanonical() {
|
|
39
24
|
return {
|
|
40
25
|
owner: 'example.com.',
|
|
@@ -61,19 +46,12 @@ export default class DNAME extends RR {
|
|
|
61
46
|
})
|
|
62
47
|
}
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return
|
|
68
|
-
owner,
|
|
69
|
-
ttl: parseInt(ttl, 10),
|
|
70
|
-
class: c,
|
|
71
|
-
type,
|
|
72
|
-
target,
|
|
73
|
-
})
|
|
49
|
+
/****** EXPORTERS *******/
|
|
50
|
+
|
|
51
|
+
getWireRdata() {
|
|
52
|
+
return this.wirePackDomain(this.get('target'))
|
|
74
53
|
}
|
|
75
54
|
|
|
76
|
-
/****** EXPORTERS *******/
|
|
77
55
|
toTinydns() {
|
|
78
56
|
const rdata = TINYDNS.packDomainName(this.get('target'))
|
|
79
57
|
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
|
}
|