@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.
Files changed (54) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +323 -199
  3. package/dist/dns-rr.min.js +26 -0
  4. package/dist/dns-rr.min.js.map +7 -0
  5. package/index.js +12 -11
  6. package/lib/binary.js +108 -0
  7. package/lib/bind.js +94 -0
  8. package/lib/dns-query.js +67 -0
  9. package/lib/tinydns.js +128 -44
  10. package/lib/wire.js +519 -0
  11. package/package.json +23 -6
  12. package/rr/TEMPLATE.js +124 -0
  13. package/rr/a.js +8 -48
  14. package/rr/aaaa.js +13 -80
  15. package/rr/apl.js +123 -27
  16. package/rr/caa.js +27 -50
  17. package/rr/cert.js +58 -87
  18. package/rr/cname.js +7 -63
  19. package/rr/dhcid.js +20 -30
  20. package/rr/dname.js +9 -36
  21. package/rr/dnskey.js +38 -32
  22. package/rr/ds.js +43 -57
  23. package/rr/hinfo.js +21 -40
  24. package/rr/hip.js +88 -26
  25. package/rr/https.js +28 -40
  26. package/rr/ipseckey.js +97 -18
  27. package/rr/key.js +39 -29
  28. package/rr/kx.js +16 -27
  29. package/rr/loc.js +42 -12
  30. package/rr/mx.js +16 -51
  31. package/rr/naptr.js +58 -33
  32. package/rr/ns.js +8 -36
  33. package/rr/nsec.js +89 -18
  34. package/rr/nsec3.js +62 -26
  35. package/rr/nsec3param.js +56 -53
  36. package/rr/nxt.js +57 -18
  37. package/rr/openpgpkey.js +24 -30
  38. package/rr/ptr.js +7 -47
  39. package/rr/rp.js +17 -32
  40. package/rr/rrsig.js +80 -85
  41. package/rr/sig.js +70 -45
  42. package/rr/smimea.js +33 -33
  43. package/rr/soa.js +31 -49
  44. package/rr/spf.js +10 -17
  45. package/rr/srv.js +22 -62
  46. package/rr/sshfp.js +25 -53
  47. package/rr/svcb.js +27 -40
  48. package/rr/tlsa.js +34 -34
  49. package/rr/tsig.js +87 -24
  50. package/rr/txt.js +40 -59
  51. package/rr/uri.js +19 -29
  52. package/rr/wks.js +154 -22
  53. package/rr.js +290 -109
  54. package/lib/readme.js +0 -84
package/rr/soa.js CHANGED
@@ -1,6 +1,21 @@
1
1
  import RR from '../rr.js'
2
2
 
3
3
  export default class SOA extends RR {
4
+ static typeName = 'SOA'
5
+ static typeId = 6
6
+ static RFCs = [1035, 2308]
7
+ static tinydnsType = 'Z'
8
+ static rdataFields = [
9
+ ['mname', 'fqdn'],
10
+ ['rname', 'fqdn'],
11
+ ['serial', 'u32'],
12
+ ['refresh', 'u32'],
13
+ ['retry', 'u32'],
14
+ ['expire', 'u32'],
15
+ ['minimum', 'u32'],
16
+ ]
17
+ static tags = ['common']
18
+
4
19
  constructor(opts) {
5
20
  super(opts)
6
21
  }
@@ -71,18 +86,6 @@ export default class SOA extends RR {
71
86
  return 'Start Of Authority'
72
87
  }
73
88
 
74
- getRdataFields(arg) {
75
- return ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 'minimum']
76
- }
77
-
78
- getRFCs() {
79
- return [1035, 2308]
80
- }
81
-
82
- getTypeId() {
83
- return 6
84
- }
85
-
86
89
  getCanonical() {
87
90
  return {
88
91
  owner: 'example.com.',
@@ -100,26 +103,6 @@ export default class SOA extends RR {
100
103
  }
101
104
 
102
105
  /****** IMPORTERS *******/
103
- fromBind({ bindline }) {
104
- // example.com TTL IN SOA mname rname serial refresh retry expire minimum
105
- const [owner, ttl, c, type, mname, rname, serial, refresh, retry, expire, minimum] =
106
- bindline.split(/[\s+]/)
107
-
108
- return new SOA({
109
- owner,
110
- ttl: parseInt(ttl) || parseInt(minimum),
111
- class: c,
112
- type,
113
- mname,
114
- rname,
115
- serial: parseInt(serial, 10),
116
- refresh: parseInt(refresh, 10),
117
- retry: parseInt(retry, 10),
118
- expire: parseInt(expire, 10),
119
- minimum: parseInt(minimum, 10),
120
- })
121
- }
122
-
123
106
  fromTinydns({ tinyline }) {
124
107
  // Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:time:lo
125
108
  const [fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc] = tinyline.slice(1).split(':')
@@ -141,29 +124,28 @@ export default class SOA extends RR {
141
124
  }
142
125
 
143
126
  /****** EXPORTERS *******/
144
- toBind(zone_opts) {
145
- const numFields = ['serial', 'refresh', 'retry', 'expire', 'minimum']
146
- return `${this.getFQDN('owner', zone_opts)}\t${this.get('ttl')}\t${this.get('class')}\tSOA\t${this.getFQDN('mname', zone_opts)}\t${this.getFQDN('rname', zone_opts)}${numFields.map((f) => '\t' + this.get(f)).join('')}\n`
147
- }
148
-
149
127
  toMaraDNS() {
150
- return `${this.get('owner')}\t SOA\t${this.getRdataFields()
128
+ return `${this.get('owner')}\t SOA\t${this.getFields('rdata')
151
129
  .map((f) => this.getQuoted(f))
152
130
  .join('\t')} ~\n`
153
131
  }
154
132
 
155
133
  getWireRdata() {
156
- const nums = Buffer.alloc(20)
157
- nums.writeUInt32BE(this.get('serial'), 0)
158
- nums.writeUInt32BE(this.get('refresh'), 4)
159
- nums.writeUInt32BE(this.get('retry'), 8)
160
- nums.writeUInt32BE(this.get('expire'), 12)
161
- nums.writeUInt32BE(this.get('minimum'), 16)
162
- return Buffer.concat([
163
- this.wirePackDomain(this.get('mname')),
164
- this.wirePackDomain(this.get('rname')),
165
- nums,
166
- ])
134
+ const mname = this.wirePackDomain(this.get('mname'))
135
+ const rname = this.wirePackDomain(this.get('rname'))
136
+ const result = new Uint8Array(mname.length + rname.length + 20)
137
+ let offset = 0
138
+ result.set(mname, offset)
139
+ offset += mname.length
140
+ result.set(rname, offset)
141
+ offset += rname.length
142
+ const view = new DataView(result.buffer, offset)
143
+ view.setUint32(0, this.get('serial'))
144
+ view.setUint32(4, this.get('refresh'))
145
+ view.setUint32(8, this.get('retry'))
146
+ view.setUint32(12, this.get('expire'))
147
+ view.setUint32(16, this.get('minimum'))
148
+ return result
167
149
  }
168
150
 
169
151
  toTinydns() {
package/rr/spf.js CHANGED
@@ -5,6 +5,12 @@ import TXT from './txt.js'
5
5
  import * as TINYDNS from '../lib/tinydns.js'
6
6
 
7
7
  export default class SPF extends TXT {
8
+ static typeName = 'SPF'
9
+ static typeId = 99
10
+ static RFCs = [4408, 7208]
11
+ static rdataFields = [['data', 'charstrs']]
12
+ static tags = ['obsolete']
13
+
8
14
  constructor(opts) {
9
15
  super(opts)
10
16
  }
@@ -17,23 +23,6 @@ export default class SPF extends TXT {
17
23
  getDescription() {
18
24
  return 'Sender Policy Framework'
19
25
  }
20
-
21
- getTags() {
22
- return ['deprecated']
23
- }
24
-
25
- getRdataFields(arg) {
26
- return ['data']
27
- }
28
-
29
- getRFCs() {
30
- return [4408, 7208]
31
- }
32
-
33
- getTypeId() {
34
- return 99
35
- }
36
-
37
26
  getCanonical() {
38
27
  return {
39
28
  owner: 'example.com.',
@@ -61,6 +50,10 @@ export default class SPF extends TXT {
61
50
  }
62
51
 
63
52
  /****** EXPORTERS *******/
53
+ getWireRdata() {
54
+ return super.getWireRdata()
55
+ }
56
+
64
57
  toTinydns() {
65
58
  const rdata = TINYDNS.escapeOctal(new RegExp(/[\r\n\t:\\/]/, 'g'), this.get('data'))
66
59
  return this.getTinydnsGeneric(rdata)
package/rr/srv.js CHANGED
@@ -2,61 +2,25 @@ import RR from '../rr.js'
2
2
  import * as TINYDNS from '../lib/tinydns.js'
3
3
 
4
4
  export default class SRV extends RR {
5
+ static typeName = 'SRV'
6
+ static typeId = 33
7
+ static RFCs = [2782]
8
+ static rdataFields = [
9
+ ['priority', 'u16'],
10
+ ['weight', 'u16'],
11
+ ['port', 'u16'],
12
+ ['target', 'fqdn'],
13
+ ]
14
+ static tags = ['common']
15
+
5
16
  constructor(opts) {
6
17
  super(opts)
7
18
  }
8
19
 
9
- /****** Resource record specific setters *******/
10
- setPriority(val) {
11
- this.is16bitInt('SRV', 'priority', val)
12
-
13
- this.set('priority', val)
14
- }
15
-
16
- setPort(val) {
17
- this.is16bitInt('SRV', 'port', val)
18
-
19
- this.set('port', val)
20
- }
21
-
22
- setWeight(val) {
23
- this.is16bitInt('SRV', 'weight', val)
24
-
25
- this.set('weight', val)
26
- }
27
-
28
- setTarget(val) {
29
- if (!val) this.throwHelp(`SRV: target is required`)
30
-
31
- if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`SRV: target must be a FQDN`)
32
-
33
- this.isFullyQualified('SRV', 'target', val)
34
- this.isValidHostname('SRV', 'target', val)
35
-
36
- // RFC 4034: letters in the DNS names are lower cased
37
- this.set('target', val.toLowerCase())
38
- }
39
-
40
20
  getDescription() {
41
21
  return 'Service'
42
22
  }
43
23
 
44
- getTags() {
45
- return ['common']
46
- }
47
-
48
- getRdataFields(arg) {
49
- return ['priority', 'weight', 'port', 'target']
50
- }
51
-
52
- getRFCs() {
53
- return [2782]
54
- }
55
-
56
- getTypeId() {
57
- return 33
58
- }
59
-
60
24
  getCanonical() {
61
25
  return {
62
26
  owner: '_imaps._tcp.example.com.',
@@ -102,23 +66,19 @@ export default class SRV extends RR {
102
66
  })
103
67
  }
104
68
 
105
- fromBind({ bindline }) {
106
- // test.example.com 3600 IN SRV Priority Weight Port Target
107
- const [owner, ttl, c, type, pri, weight, port, target] = bindline.split(/\s+/)
108
- return new SRV({
109
- owner: owner,
110
- ttl: parseInt(ttl, 10),
111
- class: c,
112
- type: type,
113
- priority: parseInt(pri, 10),
114
- weight: parseInt(weight, 10),
115
- port: parseInt(port, 10),
116
- target: target,
117
- })
118
- }
119
-
120
69
  /****** EXPORTERS *******/
121
70
 
71
+ getWireRdata() {
72
+ const target = this.wirePackDomain(this.get('target'))
73
+ const result = new Uint8Array(6 + target.length)
74
+ const dv = new DataView(result.buffer)
75
+ dv.setUint16(0, this.get('priority'))
76
+ dv.setUint16(2, this.get('weight'))
77
+ dv.setUint16(4, this.get('port'))
78
+ result.set(target, 6)
79
+ return result
80
+ }
81
+
122
82
  toTinydns() {
123
83
  let rdata = ''
124
84
 
package/rr/sshfp.js CHANGED
@@ -1,18 +1,22 @@
1
1
  import RR from '../rr.js'
2
2
  import * as TINYDNS from '../lib/tinydns.js'
3
+ import * as BINARY from '../lib/binary.js'
3
4
 
4
5
  export default class SSHFP extends RR {
6
+ static typeName = 'SSHFP'
7
+ static typeId = 44
8
+ static RFCs = [4255, 7479, 8709]
9
+ static rdataFields = [
10
+ ['algorithm', 'u8'],
11
+ ['fptype', 'u8'],
12
+ ['fingerprint', 'hex'],
13
+ ]
14
+ static tags = ['security']
15
+
5
16
  constructor(opts) {
6
17
  super(opts)
7
18
  }
8
19
 
9
- /****** Resource record specific setters *******/
10
- setAlgorithm(val) {
11
- this.is8bitInt('SSHFP', 'algorithm', val)
12
-
13
- this.set('algorithm', val)
14
- }
15
-
16
20
  getAlgorithmOptions() {
17
21
  return new Map([
18
22
  [0, 'reserved'],
@@ -24,12 +28,6 @@ export default class SSHFP extends RR {
24
28
  ])
25
29
  }
26
30
 
27
- setFptype(val) {
28
- this.is8bitInt('SSHFP', 'fptype', val)
29
-
30
- this.set('fptype', val)
31
- }
32
-
33
31
  getFptypeOptions() {
34
32
  return new Map([
35
33
  [0, 'reserved'],
@@ -38,30 +36,10 @@ export default class SSHFP extends RR {
38
36
  ])
39
37
  }
40
38
 
41
- setFingerprint(val) {
42
- this.set('fingerprint', val)
43
- }
44
-
45
39
  getDescription() {
46
40
  return 'Secure Shell Key Fingerprints'
47
41
  }
48
42
 
49
- getTags() {
50
- return ['security']
51
- }
52
-
53
- getRdataFields() {
54
- return ['algorithm', 'fptype', 'fingerprint']
55
- }
56
-
57
- getRFCs() {
58
- return [4255, 7479, 8709]
59
- }
60
-
61
- getTypeId() {
62
- return 44
63
- }
64
-
65
43
  getCanonical() {
66
44
  return {
67
45
  owner: 'mail.example.com.',
@@ -77,32 +55,18 @@ export default class SSHFP extends RR {
77
55
  /****** IMPORTERS *******/
78
56
  fromTinydns({ tinyline }) {
79
57
  // SSHFP via generic, :fqdn:n:rdata:ttl:timestamp:lo
80
- const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
81
- if (n != 44) this.throwHelp('SSHFP fromTinydns, invalid n')
58
+ const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
59
+ if (typeId != this.getTypeId()) this.throwHelp('SSHFP fromTinydns, invalid n')
82
60
 
83
61
  return new SSHFP({
84
- owner: this.fullyQualify(fqdn),
85
- ttl: parseInt(ttl, 10),
62
+ owner,
63
+ ttl,
86
64
  type: 'SSHFP',
87
65
  algorithm: TINYDNS.octalToUInt8(rdata.slice(0, 4)),
88
66
  fptype: TINYDNS.octalToUInt8(rdata.slice(4, 8)),
89
67
  fingerprint: TINYDNS.octalToHex(rdata.slice(8)),
90
- timestamp: ts,
91
- location: loc?.trim() ?? '',
92
- })
93
- }
94
-
95
- fromBind({ bindline }) {
96
- // test.example.com 3600 IN SSHFP algo fptype fp
97
- const [owner, ttl, c, type, algo, fptype, fp] = bindline.split(/\s+/)
98
- return new SSHFP({
99
- owner,
100
- ttl: parseInt(ttl, 10),
101
- class: c,
102
- type: type,
103
- algorithm: parseInt(algo, 10),
104
- fptype: parseInt(fptype, 10),
105
- fingerprint: fp,
68
+ timestamp,
69
+ location,
106
70
  })
107
71
  }
108
72
 
@@ -115,4 +79,12 @@ export default class SSHFP extends RR {
115
79
  TINYDNS.packHex(this.get('fingerprint')),
116
80
  )
117
81
  }
82
+
83
+ getWireRdata() {
84
+ const bytes = new Uint8Array(2 + BINARY.hexToBytes(this.get('fingerprint')).length)
85
+ bytes[0] = this.get('algorithm')
86
+ bytes[1] = this.get('fptype')
87
+ bytes.set(BINARY.hexToBytes(this.get('fingerprint')), 2)
88
+ return bytes
89
+ }
118
90
  }
package/rr/svcb.js CHANGED
@@ -1,8 +1,18 @@
1
1
  import RR from '../rr.js'
2
2
 
3
3
  import * as TINYDNS from '../lib/tinydns.js'
4
+ import * as WIRE from '../lib/wire.js'
4
5
 
5
6
  export default class SVCB extends RR {
7
+ static typeName = 'SVCB'
8
+ static typeId = 64
9
+ static RFCs = [9460]
10
+ static rdataFields = [
11
+ ['priority', 'u16'],
12
+ ['target name', 'fqdn'],
13
+ ['params', 'svcparams'],
14
+ ]
15
+
6
16
  constructor(opts) {
7
17
  super(opts)
8
18
  }
@@ -32,18 +42,6 @@ export default class SVCB extends RR {
32
42
  return 'Service Binding'
33
43
  }
34
44
 
35
- getRdataFields(arg) {
36
- return ['priority', 'target name', 'params']
37
- }
38
-
39
- getRFCs() {
40
- return [9460]
41
- }
42
-
43
- getTypeId() {
44
- return 64
45
- }
46
-
47
45
  getCanonical() {
48
46
  return {
49
47
  owner: '_8443._foo.api.example.com.',
@@ -75,40 +73,19 @@ export default class SVCB extends RR {
75
73
  }
76
74
 
77
75
  fromTinydns({ tinyline }) {
78
- const [owner, _typeId, rd, ttl, ts, loc] = tinyline.slice(1).split(':')
79
-
80
- if (rd.length < 6) {
81
- this.throwHelp(`SVCB: RDATA too short: ${rd}`)
82
- }
83
-
84
- // Convert escaped octal RDATA into a binary buffer for reliable parsing
85
- const binary = Buffer.from(TINYDNS.octalToChar(rd), 'binary')
86
-
87
- const priority = binary.readUInt16BE(0)
88
-
89
- // parse domain name from binary starting at offset 2
90
- let pos = 2
91
- const labels = []
92
- while (true) {
93
- const len = binary.readUInt8(pos)
94
- pos += 1
95
- if (len === 0) break
96
- labels.push(binary.slice(pos, pos + len).toString())
97
- pos += len
98
- }
99
- const targetName = `${labels.join('.')}.`
100
- // remaining params are ASCII text after the domain
101
- const params = binary.slice(pos).toString()
76
+ const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
77
+ if (typeId != this.getTypeId()) this.throwHelp('SVCB fromTinydns, invalid n')
78
+ const { priority, targetName, params } = TINYDNS.parseSvcbLikeRdata(rdata, 'SVCB')
102
79
 
103
80
  return new SVCB({
104
- owner: this.fullyQualify(owner),
105
- ttl: parseInt(ttl, 10),
81
+ owner,
82
+ ttl,
106
83
  type: 'SVCB',
107
84
  priority: priority,
108
85
  'target name': targetName,
109
86
  params: params,
110
- timestamp: ts,
111
- location: loc?.trim() ?? '',
87
+ timestamp,
88
+ location,
112
89
  })
113
90
  }
114
91
 
@@ -123,4 +100,14 @@ export default class SVCB extends RR {
123
100
  TINYDNS.escapeOctal(dataRe, this.get('params')),
124
101
  )
125
102
  }
103
+
104
+ getWireRdata() {
105
+ const targetBytes = this.wirePackDomain(this.get('target name'))
106
+ const paramsBytes = WIRE.svcParamsToWire(this.get('params'))
107
+ const result = new Uint8Array(2 + targetBytes.length + paramsBytes.length)
108
+ new DataView(result.buffer).setUint16(0, this.get('priority'))
109
+ result.set(targetBytes, 2)
110
+ result.set(paramsBytes, 2 + targetBytes.length)
111
+ return result
112
+ }
126
113
  }
package/rr/tlsa.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 TLSA extends RR {
7
+ static typeName = 'TLSA'
8
+ static typeId = 52
9
+ static RFCs = [6698, 7671]
10
+ static rdataFields = [
11
+ ['certificate usage', 'u8'],
12
+ ['selector', 'u8'],
13
+ ['matching type', 'u8'],
14
+ ['certificate association data', 'hex'],
15
+ ]
16
+ static tags = ['security']
17
+
6
18
  constructor(opts) {
7
19
  super(opts)
8
20
  }
@@ -58,22 +70,6 @@ export default class TLSA extends RR {
58
70
  return 'TLSA certificate association'
59
71
  }
60
72
 
61
- getTags() {
62
- return ['security']
63
- }
64
-
65
- getRdataFields(arg) {
66
- return ['certificate usage', 'selector', 'matching type', 'certificate association data']
67
- }
68
-
69
- getRFCs() {
70
- return [6698, 7671]
71
- }
72
-
73
- getTypeId() {
74
- return 52
75
- }
76
-
77
73
  getCanonical() {
78
74
  return {
79
75
  owner: '_443._tcp.www.example.com.',
@@ -87,10 +83,6 @@ export default class TLSA extends RR {
87
83
  }
88
84
  }
89
85
 
90
- getQuotedFields() {
91
- return []
92
- }
93
-
94
86
  /****** IMPORTERS *******/
95
87
 
96
88
  fromBind({ bindline }) {
@@ -114,33 +106,41 @@ export default class TLSA extends RR {
114
106
  }
115
107
 
116
108
  fromTinydns({ tinyline }) {
117
- const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
118
- if (n != 52) this.throwHelp('TLSA fromTinydns, invalid n')
109
+ const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
110
+ if (typeId != this.getTypeId()) this.throwHelp('TLSA fromTinydns, invalid n')
119
111
 
120
- const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
112
+ const bytes = TINYDNS.octalRdataToBytes(rdata)
121
113
 
122
114
  return new TLSA({
123
- owner: this.fullyQualify(fqdn),
124
- ttl: parseInt(ttl, 10),
115
+ owner,
116
+ ttl,
125
117
  type: 'TLSA',
126
- 'certificate usage': bytes.readUInt8(0),
127
- selector: bytes.readUInt8(1),
128
- 'matching type': bytes.readUInt8(2),
129
- 'certificate association data': bytes.slice(3).toString(),
130
- timestamp: ts,
131
- location: loc?.trim() ?? '',
118
+ 'certificate usage': bytes[0],
119
+ selector: bytes[1],
120
+ 'matching type': bytes[2],
121
+ 'certificate association data': BINARY.bytesToHex(bytes.subarray(3)),
122
+ timestamp,
123
+ location,
132
124
  })
133
125
  }
134
126
 
135
127
  /****** EXPORTERS *******/
136
128
  toTinydns() {
137
- const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
138
-
139
129
  return this.getTinydnsGeneric(
140
130
  TINYDNS.UInt8toOctal(this.get('certificate usage')) +
141
131
  TINYDNS.UInt8toOctal(this.get('selector')) +
142
132
  TINYDNS.UInt8toOctal(this.get('matching type')) +
143
- TINYDNS.escapeOctal(dataRe, this.get('certificate association data')),
133
+ TINYDNS.packHex(this.get('certificate association data').replace(/[\s()]/g, '')),
144
134
  )
145
135
  }
136
+
137
+ getWireRdata() {
138
+ const cadBytes = BINARY.hexToBytes(this.get('certificate association data').replace(/[\s()]/g, ''))
139
+ const bytes = new Uint8Array(3 + cadBytes.length)
140
+ bytes[0] = this.get('certificate usage')
141
+ bytes[1] = this.get('selector')
142
+ bytes[2] = this.get('matching type')
143
+ bytes.set(cadBytes, 3)
144
+ return bytes
145
+ }
146
146
  }