@camstack/server 1.2.582 → 1.2.584
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.
|
@@ -5373,6 +5373,13 @@ function createCapRouter_localNetwork(getProvider, createRemoteProxy) {
|
|
|
5373
5373
|
const p = resolveProvider('local-network', input?.nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
5374
5374
|
return p.downloadCa();
|
|
5375
5375
|
}),
|
|
5376
|
+
useStoredUploadedCertificate: trpc_middleware_js_1.adminProcedure
|
|
5377
|
+
.input(zod_1.z.object({ nodeId: zod_1.z.string().optional() }).optional())
|
|
5378
|
+
.output(types_70.localNetworkCapability.methods.useStoredUploadedCertificate.output)
|
|
5379
|
+
.mutation(async ({ input, ctx }) => {
|
|
5380
|
+
const p = resolveProvider('local-network', input?.nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
5381
|
+
return p.useStoredUploadedCertificate();
|
|
5382
|
+
}),
|
|
5376
5383
|
revertToGeneratedCertificate: trpc_middleware_js_1.adminProcedure
|
|
5377
5384
|
.input(zod_1.z.object({ nodeId: zod_1.z.string().optional() }).optional())
|
|
5378
5385
|
.output(types_70.localNetworkCapability.methods.revertToGeneratedCertificate.output)
|
package/dist/boot/boot-config.js
CHANGED
|
@@ -245,6 +245,9 @@ async function setupInfra(_configPath, bootstrapConfig) {
|
|
|
245
245
|
if (boot.uploadedMissing) {
|
|
246
246
|
console.warn(`[Phase2c] WARN the uploaded TLS certificate is missing from ${path.join(dataPath, 'tls')} — serving the generated one. Upload it again in Network → Local access.`);
|
|
247
247
|
}
|
|
248
|
+
if (boot.dormantCaReplaced) {
|
|
249
|
+
console.warn(`[Phase2c] WARN the local CA kept beside the uploaded certificate had no name constraints and was replaced by a constrained one (D873). The previous CA stays on disk until the listener is up. Clients that trusted it must download and trust the new CA again.`);
|
|
250
|
+
}
|
|
248
251
|
if (boot.ensured !== undefined) {
|
|
249
252
|
tlsCert = boot.ensured;
|
|
250
253
|
logTlsCert(boot.ensured);
|
|
@@ -277,6 +280,12 @@ function logTlsCert(result) {
|
|
|
277
280
|
console.log(`[Phase2c] TLS CERTIFICATE REISSUED — reason=${result.reason}, caRotated=${result.caRotated}`);
|
|
278
281
|
console.log(`[Phase2c] leaf ${result.previousFingerprintSha256 ?? '(none)'} → ${result.fingerprintSha256}`);
|
|
279
282
|
console.log(`[Phase2c] valid to ${result.validTo}, names: ${result.sans.join(', ')}`);
|
|
283
|
+
if (result.reason === 'ca-unconstrained') {
|
|
284
|
+
console.log(`[Phase2c] The previous local CA had no name constraints (D873); it is kept on disk until the listener serves the new leaf, then removed.`);
|
|
285
|
+
}
|
|
286
|
+
if (result.droppedNames.length > 0) {
|
|
287
|
+
console.log(`[Phase2c] WARN not certified (outside the local CA's name constraints): ${result.droppedNames.join(', ')}`);
|
|
288
|
+
}
|
|
280
289
|
console.log(result.caRotated
|
|
281
290
|
? `[Phase2c] ACTION REQUIRED: the local CA changed. Install ${result.caCertPath} (SHA-256 ${result.caFingerprintSha256}) on every device that trusted the previous certificate.`
|
|
282
291
|
: `[Phase2c] Local CA unchanged (${result.caFingerprintSha256}) — devices that trust ${result.caCertPath} keep working.`);
|
|
@@ -59,6 +59,11 @@ class PostBootService {
|
|
|
59
59
|
// A certificate that changed underneath the operator is an alert, not
|
|
60
60
|
// a boot line they will never scroll back to (D227).
|
|
61
61
|
this.emitTlsCertChangedIfReissued(tlsCert);
|
|
62
|
+
// The listener is up on the replacement CA's leaf: the retired unconstrained CA (and
|
|
63
|
+
// its key) kept on disk for the replacement window can go (D873).
|
|
64
|
+
if ((0, system_1.retirePreviousLocalCa)(dataPath)) {
|
|
65
|
+
this.logger.warn('Retired the previous local CA that had no name constraints (D873)');
|
|
66
|
+
}
|
|
62
67
|
// Re-drive every non-terminal lifecycle job (addon task phases) from its
|
|
63
68
|
// on-disk checkpoint. Framework tasks are no longer applied by the engine
|
|
64
69
|
// (single-copy collapse — framework updates ship via applyServerUpdate);
|
|
@@ -54,8 +54,15 @@
|
|
|
54
54
|
"reach": "closure-postinstall",
|
|
55
55
|
"markers": {
|
|
56
56
|
"lib/ice/src/ice.js": ["camstack: relay-only SDP under forceTurn"],
|
|
57
|
-
"lib/index.mjs": [
|
|
58
|
-
|
|
57
|
+
"lib/index.mjs": [
|
|
58
|
+
"camstack: relay-only SDP under forceTurn",
|
|
59
|
+
"RTP_HISTORY_SIZE = 4096",
|
|
60
|
+
"camstack: D868 — SRTP output arena"
|
|
61
|
+
],
|
|
62
|
+
"lib/webrtc/src/media/rtpSender.js": ["RTP_HISTORY_SIZE = 4096"],
|
|
63
|
+
"lib/rtp/src/rtp/rtp.js": ["camstack: D868 — SRTP output arena"],
|
|
64
|
+
"lib/rtp/src/srtp/cipher/ctr.js": ["camstack: D868 — header, ciphertext and tag in ONE arena slice"],
|
|
65
|
+
"lib/rtp/src/srtp/cipher/gcm.js": ["camstack: D868 — header, ciphertext and tag in ONE arena slice"]
|
|
59
66
|
},
|
|
60
67
|
"declaredBy": [
|
|
61
68
|
"packages/addon-pipeline",
|
|
@@ -25,10 +25,87 @@ index 74cf126..0c5cedf 100644
|
|
|
25
25
|
}
|
|
26
26
|
clearTimeout(timer);
|
|
27
27
|
diff --git a/node_modules/werift/lib/index.mjs b/node_modules/werift/lib/index.mjs
|
|
28
|
-
index 3e8b013..
|
|
28
|
+
index 3e8b013..f481aa5 100644
|
|
29
29
|
--- a/node_modules/werift/lib/index.mjs
|
|
30
30
|
+++ b/node_modules/werift/lib/index.mjs
|
|
31
|
-
@@ -
|
|
31
|
+
@@ -4358,6 +4358,21 @@ var timestampOffset = 4;
|
|
32
|
+
var ssrcOffset = 8;
|
|
33
|
+
var csrcOffset = 12;
|
|
34
|
+
var csrcSize = 4;
|
|
35
|
+
+
|
|
36
|
+
+// camstack: D868 — SRTP output arena (see lib/rtp/src/rtp/rtp.js).
|
|
37
|
+
+var CAMSTACK_SRTP_ARENA_BYTES = 262144;
|
|
38
|
+
+var camstackSrtpArena = Buffer.allocUnsafeSlow(0);
|
|
39
|
+
+var camstackSrtpArenaOffset = 0;
|
|
40
|
+
+function camstackSrtpOut(size) {
|
|
41
|
+
+ if (size > CAMSTACK_SRTP_ARENA_BYTES >> 2) return Buffer.allocUnsafeSlow(size);
|
|
42
|
+
+ if (camstackSrtpArenaOffset + size > camstackSrtpArena.length) {
|
|
43
|
+
+ camstackSrtpArena = Buffer.allocUnsafeSlow(CAMSTACK_SRTP_ARENA_BYTES);
|
|
44
|
+
+ camstackSrtpArenaOffset = 0;
|
|
45
|
+
+ }
|
|
46
|
+
+ const out = camstackSrtpArena.subarray(camstackSrtpArenaOffset, camstackSrtpArenaOffset + size);
|
|
47
|
+
+ camstackSrtpArenaOffset += size;
|
|
48
|
+
+ return out;
|
|
49
|
+
+}
|
|
50
|
+
var RtpHeader = class _RtpHeader {
|
|
51
|
+
version = 2;
|
|
52
|
+
padding = false;
|
|
53
|
+
@@ -4501,8 +4516,8 @@ var RtpHeader = class _RtpHeader {
|
|
54
|
+
}
|
|
55
|
+
return size;
|
|
56
|
+
}
|
|
57
|
+
- serialize(size) {
|
|
58
|
+
- const buf = Buffer.alloc(size);
|
|
59
|
+
+ serialize(size, into) {
|
|
60
|
+
+ const buf = into ? into.fill(0, 0, size) : Buffer.alloc(size);
|
|
61
|
+
let offset = 0;
|
|
62
|
+
const v_p_x_cc = new BitWriter(8);
|
|
63
|
+
v_p_x_cc.set(2, 0, this.version);
|
|
64
|
+
@@ -4679,7 +4694,9 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
65
|
+
}
|
|
66
|
+
authTagLength = 10;
|
|
67
|
+
encryptRtp(header, payload, rolloverCounter) {
|
|
68
|
+
- const headerBuffer = header.serialize(header.serializeSize);
|
|
69
|
+
+ const hdrSize = header.serializeSize;
|
|
70
|
+
+ const out = camstackSrtpOut(hdrSize + payload.length + this.authTagLength);
|
|
71
|
+
+ const headerBuffer = header.serialize(hdrSize, out.subarray(0, hdrSize));
|
|
72
|
+
const counter = this.generateCounter(
|
|
73
|
+
header.sequenceNumber,
|
|
74
|
+
rolloverCounter,
|
|
75
|
+
@@ -4693,7 +4710,9 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
76
|
+
headerBuffer,
|
|
77
|
+
enc
|
|
78
|
+
);
|
|
79
|
+
- return Buffer.concat([headerBuffer, enc, authTag]);
|
|
80
|
+
+ enc.copy(out, hdrSize);
|
|
81
|
+
+ authTag.copy(out, hdrSize + enc.length);
|
|
82
|
+
+ return out.subarray(0, hdrSize + enc.length + authTag.length);
|
|
83
|
+
}
|
|
84
|
+
decryptRtp(cipherText, rolloverCounter) {
|
|
85
|
+
const header = RtpHeader.deSerialize(cipherText);
|
|
86
|
+
@@ -4800,15 +4819,18 @@ var CipherAesGcm = class extends CipherAesBase {
|
|
87
|
+
super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);
|
|
88
|
+
}
|
|
89
|
+
encryptRtp(header, payload, rolloverCounter) {
|
|
90
|
+
- const hdr = header.serialize(header.serializeSize);
|
|
91
|
+
+ const hdrSize = header.serializeSize;
|
|
92
|
+
+ const out = camstackSrtpOut(hdrSize + payload.length + this.aeadAuthTagLen);
|
|
93
|
+
+ const hdr = header.serialize(hdrSize, out.subarray(0, hdrSize));
|
|
94
|
+
const iv = this.rtpInitializationVector(header, rolloverCounter);
|
|
95
|
+
const cipher = createCipheriv3("aes-128-gcm", this.srtpSessionKey, iv);
|
|
96
|
+
cipher.setAAD(hdr);
|
|
97
|
+
const enc = cipher.update(payload);
|
|
98
|
+
cipher.final();
|
|
99
|
+
const authTag = cipher.getAuthTag();
|
|
100
|
+
- const dst = Buffer.concat([hdr, enc, authTag]);
|
|
101
|
+
- return dst;
|
|
102
|
+
+ enc.copy(out, hdrSize);
|
|
103
|
+
+ authTag.copy(out, hdrSize + enc.length);
|
|
104
|
+
+ return out.subarray(0, hdrSize + enc.length + authTag.length);
|
|
105
|
+
}
|
|
106
|
+
decryptRtp(cipherText, rolloverCounter) {
|
|
107
|
+
const header = RtpHeader.deSerialize(cipherText);
|
|
108
|
+
@@ -7940,7 +7962,10 @@ var Connection = class {
|
|
32
109
|
this.localUsername
|
|
33
110
|
);
|
|
34
111
|
this.pairLocalProtocol(protocol);
|
|
@@ -40,7 +117,7 @@ index 3e8b013..48823e7 100644
|
|
|
40
117
|
return protocol;
|
|
41
118
|
} catch (error) {
|
|
42
119
|
log22("error protocol STUN", error);
|
|
43
|
-
@@ -7967,7 +
|
|
120
|
+
@@ -7967,7 +7992,8 @@ var Connection = class {
|
|
44
121
|
).catch((error) => {
|
|
45
122
|
log22("error", error);
|
|
46
123
|
});
|
|
@@ -50,7 +127,7 @@ index 3e8b013..48823e7 100644
|
|
|
50
127
|
this.appendLocalCandidate(candidate);
|
|
51
128
|
}
|
|
52
129
|
clearTimeout(timer2);
|
|
53
|
-
@@ -13565,7 +
|
|
130
|
+
@@ -13565,7 +13591,7 @@ var SenderBandwidthEstimator = class {
|
|
54
131
|
|
|
55
132
|
// src/media/rtpSender.ts
|
|
56
133
|
var log33 = debug("werift:packages/webrtc/src/media/rtpSender.ts");
|
|
@@ -59,6 +136,100 @@ index 3e8b013..48823e7 100644
|
|
|
59
136
|
var RTT_ALPHA = 0.85;
|
|
60
137
|
var RTCRtpSender = class {
|
|
61
138
|
constructor(trackOrKind) {
|
|
139
|
+
diff --git a/node_modules/werift/lib/rtp/src/rtp/rtp.js b/node_modules/werift/lib/rtp/src/rtp/rtp.js
|
|
140
|
+
index 97b2767..b8ee886 100644
|
|
141
|
+
--- a/node_modules/werift/lib/rtp/src/rtp/rtp.js
|
|
142
|
+
+++ b/node_modules/werift/lib/rtp/src/rtp/rtp.js
|
|
143
|
+
@@ -11,6 +11,26 @@ const timestampOffset = 4;
|
|
144
|
+
const ssrcOffset = 8;
|
|
145
|
+
const csrcOffset = 12;
|
|
146
|
+
const csrcSize = 4;
|
|
147
|
+
+
|
|
148
|
+
+// camstack: D868 — SRTP output arena. Every outgoing RTP packet used to cost a
|
|
149
|
+
+// Buffer.alloc for the header and a Buffer.concat for header + ciphertext + tag.
|
|
150
|
+
+// The packet now lands in a dense slice of a 256 KiB arena that is never reused
|
|
151
|
+
+// (a full arena is left to the GC and lives as long as the datagram in flight).
|
|
152
|
+
+const CAMSTACK_SRTP_ARENA_BYTES = 262144;
|
|
153
|
+
+let camstackSrtpArena = Buffer.allocUnsafeSlow(0);
|
|
154
|
+
+let camstackSrtpArenaOffset = 0;
|
|
155
|
+
+function camstackSrtpOut(size) {
|
|
156
|
+
+ if (size > CAMSTACK_SRTP_ARENA_BYTES >> 2)
|
|
157
|
+
+ return Buffer.allocUnsafeSlow(size);
|
|
158
|
+
+ if (camstackSrtpArenaOffset + size > camstackSrtpArena.length) {
|
|
159
|
+
+ camstackSrtpArena = Buffer.allocUnsafeSlow(CAMSTACK_SRTP_ARENA_BYTES);
|
|
160
|
+
+ camstackSrtpArenaOffset = 0;
|
|
161
|
+
+ }
|
|
162
|
+
+ const out = camstackSrtpArena.subarray(camstackSrtpArenaOffset, camstackSrtpArenaOffset + size);
|
|
163
|
+
+ camstackSrtpArenaOffset += size;
|
|
164
|
+
+ return out;
|
|
165
|
+
+}
|
|
166
|
+
+exports.camstackSrtpOut = camstackSrtpOut;
|
|
167
|
+
/*
|
|
168
|
+
* 0 1 2 3
|
|
169
|
+
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
170
|
+
@@ -242,8 +262,9 @@ class RtpHeader {
|
|
171
|
+
}
|
|
172
|
+
return size;
|
|
173
|
+
}
|
|
174
|
+
- serialize(size) {
|
|
175
|
+
- const buf = Buffer.alloc(size);
|
|
176
|
+
+ serialize(size, into) {
|
|
177
|
+
+ // camstack: D868 — SRTP writes the header straight into its output buffer.
|
|
178
|
+
+ const buf = into ? into.fill(0, 0, size) : Buffer.alloc(size);
|
|
179
|
+
let offset = 0;
|
|
180
|
+
const v_p_x_cc = new src_1.BitWriter(8);
|
|
181
|
+
v_p_x_cc.set(2, 0, this.version);
|
|
182
|
+
diff --git a/node_modules/werift/lib/rtp/src/srtp/cipher/ctr.js b/node_modules/werift/lib/rtp/src/srtp/cipher/ctr.js
|
|
183
|
+
index e0c1380..13aa5aa 100644
|
|
184
|
+
--- a/node_modules/werift/lib/rtp/src/srtp/cipher/ctr.js
|
|
185
|
+
+++ b/node_modules/werift/lib/rtp/src/srtp/cipher/ctr.js
|
|
186
|
+
@@ -28,12 +28,17 @@ class CipherAesCtr extends _1.CipherAesBase {
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
encryptRtp(header, payload, rolloverCounter) {
|
|
190
|
+
- const headerBuffer = header.serialize(header.serializeSize);
|
|
191
|
+
+ // camstack: D868 — header, ciphertext and tag in ONE arena slice (no serialize alloc, no concat).
|
|
192
|
+
+ const hdrSize = header.serializeSize;
|
|
193
|
+
+ const out = rtp_1.camstackSrtpOut(hdrSize + payload.length + this.authTagLength);
|
|
194
|
+
+ const headerBuffer = header.serialize(hdrSize, out.subarray(0, hdrSize));
|
|
195
|
+
const counter = this.generateCounter(header.sequenceNumber, rolloverCounter, header.ssrc, this.srtpSessionSalt);
|
|
196
|
+
const cipher = (0, crypto_1.createCipheriv)("aes-128-ctr", this.srtpSessionKey, counter);
|
|
197
|
+
const enc = cipher.update(payload);
|
|
198
|
+
const authTag = this.generateSrtpAuthTag(rolloverCounter, headerBuffer, enc);
|
|
199
|
+
- return Buffer.concat([headerBuffer, enc, authTag]);
|
|
200
|
+
+ enc.copy(out, hdrSize);
|
|
201
|
+
+ authTag.copy(out, hdrSize + enc.length);
|
|
202
|
+
+ return out.subarray(0, hdrSize + enc.length + authTag.length);
|
|
203
|
+
}
|
|
204
|
+
decryptRtp(cipherText, rolloverCounter) {
|
|
205
|
+
const header = rtp_1.RtpHeader.deSerialize(cipherText);
|
|
206
|
+
diff --git a/node_modules/werift/lib/rtp/src/srtp/cipher/gcm.js b/node_modules/werift/lib/rtp/src/srtp/cipher/gcm.js
|
|
207
|
+
index 8d9d498..4cdd15b 100644
|
|
208
|
+
--- a/node_modules/werift/lib/rtp/src/srtp/cipher/gcm.js
|
|
209
|
+
+++ b/node_modules/werift/lib/rtp/src/srtp/cipher/gcm.js
|
|
210
|
+
@@ -36,15 +36,19 @@ class CipherAesGcm extends _1.CipherAesBase {
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
encryptRtp(header, payload, rolloverCounter) {
|
|
214
|
+
- const hdr = header.serialize(header.serializeSize);
|
|
215
|
+
+ // camstack: D868 — header, ciphertext and tag in ONE arena slice (no serialize alloc, no concat).
|
|
216
|
+
+ const hdrSize = header.serializeSize;
|
|
217
|
+
+ const out = rtp_1.camstackSrtpOut(hdrSize + payload.length + this.aeadAuthTagLen);
|
|
218
|
+
+ const hdr = header.serialize(hdrSize, out.subarray(0, hdrSize));
|
|
219
|
+
const iv = this.rtpInitializationVector(header, rolloverCounter);
|
|
220
|
+
const cipher = (0, crypto_1.createCipheriv)("aes-128-gcm", this.srtpSessionKey, iv);
|
|
221
|
+
cipher.setAAD(hdr);
|
|
222
|
+
const enc = cipher.update(payload);
|
|
223
|
+
cipher.final();
|
|
224
|
+
const authTag = cipher.getAuthTag();
|
|
225
|
+
- const dst = Buffer.concat([hdr, enc, authTag]);
|
|
226
|
+
- return dst;
|
|
227
|
+
+ enc.copy(out, hdrSize);
|
|
228
|
+
+ authTag.copy(out, hdrSize + enc.length);
|
|
229
|
+
+ return out.subarray(0, hdrSize + enc.length + authTag.length);
|
|
230
|
+
}
|
|
231
|
+
decryptRtp(cipherText, rolloverCounter) {
|
|
232
|
+
const header = rtp_1.RtpHeader.deSerialize(cipherText);
|
|
62
233
|
diff --git a/node_modules/werift/lib/webrtc/src/media/rtpSender.js b/node_modules/werift/lib/webrtc/src/media/rtpSender.js
|
|
63
234
|
index bc85968..64a5304 100644
|
|
64
235
|
--- a/node_modules/werift/lib/webrtc/src/media/rtpSender.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.584",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@camstack/addon-admin-ui": "1.2.
|
|
42
|
-
"@camstack/addon-agent-ui": "1.2.
|
|
41
|
+
"@camstack/addon-admin-ui": "1.2.430",
|
|
42
|
+
"@camstack/addon-agent-ui": "1.2.237",
|
|
43
43
|
"@camstack/addon-auth": "1.2.148",
|
|
44
44
|
"@camstack/addon-decoder-nodeav": "1.2.123",
|
|
45
45
|
"@camstack/addon-notifiers": "1.2.135",
|
|
46
|
-
"@camstack/addon-pipeline": "1.2.
|
|
47
|
-
"@camstack/addon-pipeline-orchestrator": "1.2.
|
|
48
|
-
"@camstack/addon-post-analysis": "1.2.
|
|
46
|
+
"@camstack/addon-pipeline": "1.2.373",
|
|
47
|
+
"@camstack/addon-pipeline-orchestrator": "1.2.326",
|
|
48
|
+
"@camstack/addon-post-analysis": "1.2.371",
|
|
49
49
|
"@camstack/develop": "0.1.11",
|
|
50
50
|
"@camstack/sdk": "1.2.132",
|
|
51
|
-
"@camstack/system": "1.2.
|
|
52
|
-
"@camstack/types": "1.2.
|
|
53
|
-
"@camstack/ui-library": "1.2.
|
|
51
|
+
"@camstack/system": "1.2.439",
|
|
52
|
+
"@camstack/types": "1.2.375",
|
|
53
|
+
"@camstack/ui-library": "1.2.293",
|
|
54
54
|
"@fastify/compress": "^9.0.0",
|
|
55
55
|
"@fastify/cookie": "^11.0.2",
|
|
56
56
|
"@fastify/cors": "^11.2.0",
|