werift 0.22.9 → 0.23.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/lib/dtls/src/flight/server/flight6.js +12 -2
- package/lib/dtls/src/flight/server/flight6.js.map +1 -1
- package/lib/dtls/src/server.js +6 -1
- package/lib/dtls/src/server.js.map +1 -1
- package/lib/dtls/src/socket.d.ts +1 -0
- package/lib/dtls/src/socket.js +3 -0
- package/lib/dtls/src/socket.js.map +1 -1
- package/lib/index.mjs +434 -75
- package/lib/nonstandard/index.mjs +207 -40
- package/lib/rtp/src/index.d.ts +1 -0
- package/lib/rtp/src/index.js +1 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
- package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
- package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
- package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
- package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
- package/lib/rtp/src/srtp/cipher/index.js +1 -1
- package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
- package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
- package/lib/rtp/src/srtp/context/srtp.js +22 -5
- package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
- package/lib/rtp/src/srtp/error.d.ts +3 -0
- package/lib/rtp/src/srtp/error.js +11 -0
- package/lib/rtp/src/srtp/error.js.map +1 -0
- package/lib/rtp/src/srtp/packet.d.ts +5 -0
- package/lib/rtp/src/srtp/packet.js +48 -0
- package/lib/rtp/src/srtp/packet.js.map +1 -0
- package/lib/webrtc/src/dataChannel.d.ts +1 -0
- package/lib/webrtc/src/dataChannel.js +5 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +4 -1
- package/lib/webrtc/src/peerConnection.js +26 -5
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +3 -2
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +1 -1
- package/lib/webrtc/src/sdpManager.js +3 -4
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.js +1 -1
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.js +3 -2
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +1 -0
- package/lib/webrtc/src/transport/dtls.js +117 -12
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +9 -3
- package/lib/webrtc/src/transport/sctp.js +35 -7
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +2 -0
- package/lib/webrtc/src/utils.js +20 -0
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -4477,7 +4477,12 @@ import { createHmac as createHmac2 } from "crypto";
|
|
|
4477
4477
|
import AES from "aes-js";
|
|
4478
4478
|
|
|
4479
4479
|
// ../rtp/src/srtp/cipher/ctr.ts
|
|
4480
|
-
import {
|
|
4480
|
+
import {
|
|
4481
|
+
createCipheriv as createCipheriv2,
|
|
4482
|
+
createDecipheriv,
|
|
4483
|
+
createHmac,
|
|
4484
|
+
timingSafeEqual
|
|
4485
|
+
} from "crypto";
|
|
4481
4486
|
|
|
4482
4487
|
// ../rtp/src/srtp/cipher/index.ts
|
|
4483
4488
|
var CipherAesBase = class {
|
|
@@ -4490,7 +4495,7 @@ var CipherAesBase = class {
|
|
|
4490
4495
|
encryptRtp(header, payload, rolloverCounter) {
|
|
4491
4496
|
return Buffer.from([]);
|
|
4492
4497
|
}
|
|
4493
|
-
decryptRtp(cipherText, rolloverCounter) {
|
|
4498
|
+
decryptRtp(cipherText, rolloverCounter, header) {
|
|
4494
4499
|
return [];
|
|
4495
4500
|
}
|
|
4496
4501
|
encryptRTCP(rawRtcp, srtcpIndex) {
|
|
@@ -4501,6 +4506,74 @@ var CipherAesBase = class {
|
|
|
4501
4506
|
}
|
|
4502
4507
|
};
|
|
4503
4508
|
|
|
4509
|
+
// ../rtp/src/srtp/error.ts
|
|
4510
|
+
var SrtpAuthenticationError = class extends Error {
|
|
4511
|
+
constructor(message) {
|
|
4512
|
+
super(message);
|
|
4513
|
+
this.name = "SrtpAuthenticationError";
|
|
4514
|
+
}
|
|
4515
|
+
};
|
|
4516
|
+
|
|
4517
|
+
// ../rtp/src/srtp/packet.ts
|
|
4518
|
+
var minRtpHeaderSize = 12;
|
|
4519
|
+
var minRtcpPacketSize = 8;
|
|
4520
|
+
function parseSrtpRtpHeader(packet, authTagLength, message = "Failed to authenticate SRTP packet") {
|
|
4521
|
+
const authTagOffset = packet.length - authTagLength;
|
|
4522
|
+
assertAuthenticatedPacketLength(
|
|
4523
|
+
packet.length >= minRtpHeaderSize + authTagLength,
|
|
4524
|
+
message
|
|
4525
|
+
);
|
|
4526
|
+
const header = wrapAuthenticationError(
|
|
4527
|
+
() => RtpHeader.deSerialize(packet.subarray(0, authTagOffset)),
|
|
4528
|
+
message
|
|
4529
|
+
);
|
|
4530
|
+
header.paddingSize = 0;
|
|
4531
|
+
assertAuthenticatedPacketLength(
|
|
4532
|
+
header.payloadOffset >= minRtpHeaderSize && header.payloadOffset <= authTagOffset,
|
|
4533
|
+
message
|
|
4534
|
+
);
|
|
4535
|
+
return header;
|
|
4536
|
+
}
|
|
4537
|
+
function parseSrtcpHeader(packet, authTagLength, srtcpIndexSize3, message = "Failed to authenticate SRTCP packet") {
|
|
4538
|
+
assertAuthenticatedPacketLength(
|
|
4539
|
+
packet.length >= minRtcpPacketSize + authTagLength + srtcpIndexSize3,
|
|
4540
|
+
message
|
|
4541
|
+
);
|
|
4542
|
+
return wrapAuthenticationError(
|
|
4543
|
+
() => RtcpHeader.deSerialize(packet.subarray(0, RTCP_HEADER_SIZE)),
|
|
4544
|
+
message
|
|
4545
|
+
);
|
|
4546
|
+
}
|
|
4547
|
+
function assertAuthenticatedPacketLength(condition, message) {
|
|
4548
|
+
if (!condition) {
|
|
4549
|
+
throw new SrtpAuthenticationError(message);
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
function wrapAuthenticationError(parse, message) {
|
|
4553
|
+
try {
|
|
4554
|
+
return parse();
|
|
4555
|
+
} catch {
|
|
4556
|
+
throw new SrtpAuthenticationError(message);
|
|
4557
|
+
}
|
|
4558
|
+
}
|
|
4559
|
+
function finalizeSrtpRtpHeader(header, packet, message = "Failed to authenticate SRTP packet") {
|
|
4560
|
+
if (!header.padding) {
|
|
4561
|
+
header.paddingSize = 0;
|
|
4562
|
+
return header;
|
|
4563
|
+
}
|
|
4564
|
+
assertAuthenticatedPacketLength(
|
|
4565
|
+
packet.length > header.payloadOffset,
|
|
4566
|
+
message
|
|
4567
|
+
);
|
|
4568
|
+
const paddingSize = packet[packet.length - 1];
|
|
4569
|
+
assertAuthenticatedPacketLength(
|
|
4570
|
+
paddingSize > 0 && paddingSize <= packet.length - header.payloadOffset,
|
|
4571
|
+
message
|
|
4572
|
+
);
|
|
4573
|
+
header.paddingSize = paddingSize;
|
|
4574
|
+
return header;
|
|
4575
|
+
}
|
|
4576
|
+
|
|
4504
4577
|
// ../rtp/src/srtp/cipher/ctr.ts
|
|
4505
4578
|
var CipherAesCtr = class extends CipherAesBase {
|
|
4506
4579
|
constructor(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt, srtpSessionAuthTag, srtcpSessionAuthTag) {
|
|
@@ -4526,10 +4599,20 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
|
4526
4599
|
);
|
|
4527
4600
|
return Buffer.concat([headerBuffer, enc, authTag]);
|
|
4528
4601
|
}
|
|
4529
|
-
decryptRtp(cipherText, rolloverCounter) {
|
|
4530
|
-
const
|
|
4531
|
-
const
|
|
4532
|
-
|
|
4602
|
+
decryptRtp(cipherText, rolloverCounter, header = parseSrtpRtpHeader(cipherText, this.authTagLength)) {
|
|
4603
|
+
const authTagOffset = cipherText.length - this.authTagLength;
|
|
4604
|
+
const encryptedPacket = cipherText.subarray(0, authTagOffset);
|
|
4605
|
+
const actualAuthTag = cipherText.subarray(authTagOffset);
|
|
4606
|
+
const expectedAuthTag = this.generateSrtpAuthTag(
|
|
4607
|
+
rolloverCounter,
|
|
4608
|
+
encryptedPacket.subarray(0, header.payloadOffset),
|
|
4609
|
+
encryptedPacket.subarray(header.payloadOffset)
|
|
4610
|
+
);
|
|
4611
|
+
assertAuthTag(
|
|
4612
|
+
actualAuthTag,
|
|
4613
|
+
expectedAuthTag,
|
|
4614
|
+
"Failed to authenticate SRTP packet"
|
|
4615
|
+
);
|
|
4533
4616
|
const counter = this.generateCounter(
|
|
4534
4617
|
header.sequenceNumber,
|
|
4535
4618
|
rolloverCounter,
|
|
@@ -4541,14 +4624,16 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
|
4541
4624
|
this.srtpSessionKey,
|
|
4542
4625
|
counter
|
|
4543
4626
|
);
|
|
4544
|
-
const payload =
|
|
4627
|
+
const payload = encryptedPacket.subarray(header.payloadOffset);
|
|
4545
4628
|
const buf = cipher.update(payload);
|
|
4546
4629
|
const dst = Buffer.concat([
|
|
4547
|
-
|
|
4548
|
-
buf
|
|
4549
|
-
Buffer.alloc(size - header.payloadOffset - buf.length)
|
|
4630
|
+
encryptedPacket.subarray(0, header.payloadOffset),
|
|
4631
|
+
buf
|
|
4550
4632
|
]);
|
|
4551
|
-
return [
|
|
4633
|
+
return [
|
|
4634
|
+
dst,
|
|
4635
|
+
finalizeSrtpRtpHeader(header, dst, "Failed to authenticate SRTP packet")
|
|
4636
|
+
];
|
|
4552
4637
|
}
|
|
4553
4638
|
encryptRTCP(rtcpPacket, srtcpIndex) {
|
|
4554
4639
|
let out = Buffer.from(rtcpPacket);
|
|
@@ -4570,15 +4655,29 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
|
4570
4655
|
return out;
|
|
4571
4656
|
}
|
|
4572
4657
|
decryptRTCP(encrypted) {
|
|
4573
|
-
const header =
|
|
4658
|
+
const header = parseSrtcpHeader(
|
|
4659
|
+
encrypted,
|
|
4660
|
+
this.authTagLength,
|
|
4661
|
+
srtcpIndexSize
|
|
4662
|
+
);
|
|
4574
4663
|
const tailOffset = encrypted.length - (this.authTagLength + srtcpIndexSize);
|
|
4664
|
+
const authenticatedPortion = encrypted.subarray(
|
|
4665
|
+
0,
|
|
4666
|
+
encrypted.length - this.authTagLength
|
|
4667
|
+
);
|
|
4668
|
+
const actualTag = encrypted.subarray(encrypted.length - this.authTagLength);
|
|
4669
|
+
const expectedTag = this.generateSrtcpAuthTag(authenticatedPortion);
|
|
4670
|
+
assertAuthTag(
|
|
4671
|
+
actualTag,
|
|
4672
|
+
expectedTag,
|
|
4673
|
+
"Failed to authenticate SRTCP packet"
|
|
4674
|
+
);
|
|
4575
4675
|
const out = Buffer.from(encrypted).slice(0, tailOffset);
|
|
4576
|
-
const isEncrypted = encrypted[tailOffset]
|
|
4676
|
+
const isEncrypted = encrypted[tailOffset] >>> 7;
|
|
4577
4677
|
if (isEncrypted === 0) return [out, header];
|
|
4578
4678
|
let srtcpIndex = encrypted.readUInt32BE(tailOffset);
|
|
4579
4679
|
srtcpIndex &= ~(1 << 31);
|
|
4580
4680
|
const ssrc = encrypted.readUInt32BE(4);
|
|
4581
|
-
const actualTag = encrypted.subarray(encrypted.length - 10);
|
|
4582
4681
|
const counter = this.generateCounter(
|
|
4583
4682
|
srtcpIndex & 65535,
|
|
4584
4683
|
srtcpIndex >> 16,
|
|
@@ -4619,6 +4718,11 @@ var CipherAesCtr = class extends CipherAesBase {
|
|
|
4619
4718
|
}
|
|
4620
4719
|
};
|
|
4621
4720
|
var srtcpIndexSize = 4;
|
|
4721
|
+
function assertAuthTag(actual, expected, message) {
|
|
4722
|
+
if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {
|
|
4723
|
+
throw new SrtpAuthenticationError(message);
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4622
4726
|
|
|
4623
4727
|
// ../rtp/src/srtp/cipher/gcm.ts
|
|
4624
4728
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv2 } from "crypto";
|
|
@@ -4641,20 +4745,25 @@ var CipherAesGcm = class extends CipherAesBase {
|
|
|
4641
4745
|
const dst = Buffer.concat([hdr, enc, authTag]);
|
|
4642
4746
|
return dst;
|
|
4643
4747
|
}
|
|
4644
|
-
decryptRtp(cipherText, rolloverCounter) {
|
|
4645
|
-
const
|
|
4748
|
+
decryptRtp(cipherText, rolloverCounter, header = parseSrtpRtpHeader(cipherText, this.aeadAuthTagLen)) {
|
|
4749
|
+
const headerBuffer = cipherText.subarray(0, header.payloadOffset);
|
|
4750
|
+
const authTagOffset = cipherText.length - this.aeadAuthTagLen;
|
|
4751
|
+
const authTag = cipherText.subarray(authTagOffset);
|
|
4646
4752
|
let dst = Buffer.from([]);
|
|
4647
4753
|
dst = growBufferSize(dst, cipherText.length - this.aeadAuthTagLen);
|
|
4648
|
-
|
|
4754
|
+
headerBuffer.copy(dst);
|
|
4649
4755
|
const iv = this.rtpInitializationVector(header, rolloverCounter);
|
|
4650
|
-
const enc = cipherText.slice(
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
);
|
|
4654
|
-
const
|
|
4655
|
-
|
|
4756
|
+
const enc = cipherText.slice(header.payloadOffset, authTagOffset);
|
|
4757
|
+
const decipher = createDecipheriv2("aes-128-gcm", this.srtpSessionKey, iv);
|
|
4758
|
+
decipher.setAAD(headerBuffer);
|
|
4759
|
+
decipher.setAuthTag(authTag);
|
|
4760
|
+
const dec = decipher.update(enc);
|
|
4761
|
+
finalizeAuthenticatedDecryption(decipher, "SRTP");
|
|
4656
4762
|
dec.copy(dst, header.payloadOffset);
|
|
4657
|
-
return [
|
|
4763
|
+
return [
|
|
4764
|
+
dst,
|
|
4765
|
+
finalizeSrtpRtpHeader(header, dst, "Failed to authenticate SRTP packet")
|
|
4766
|
+
];
|
|
4658
4767
|
}
|
|
4659
4768
|
encryptRTCP(rtcpPacket, srtcpIndex) {
|
|
4660
4769
|
const ssrc = rtcpPacket.readUInt32BE(4);
|
|
@@ -4675,19 +4784,38 @@ var CipherAesGcm = class extends CipherAesBase {
|
|
|
4675
4784
|
return dst;
|
|
4676
4785
|
}
|
|
4677
4786
|
decryptRTCP(encrypted) {
|
|
4678
|
-
const header =
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4787
|
+
const header = parseSrtcpHeader(
|
|
4788
|
+
encrypted,
|
|
4789
|
+
this.aeadAuthTagLen,
|
|
4790
|
+
srtcpIndexSize2
|
|
4791
|
+
);
|
|
4792
|
+
const srtcpIndexOffset = encrypted.length - srtcpIndexSize2;
|
|
4793
|
+
const authTagOffset = srtcpIndexOffset - this.aeadAuthTagLen;
|
|
4682
4794
|
const ssrc = encrypted.readUInt32BE(4);
|
|
4683
|
-
|
|
4684
|
-
|
|
4795
|
+
const encodedSrtcpIndex = encrypted.readUInt32BE(srtcpIndexOffset);
|
|
4796
|
+
const isEncrypted = encodedSrtcpIndex >>> 31 === 1;
|
|
4797
|
+
const srtcpIndex = encodedSrtcpIndex & ~(rtcpEncryptionFlag << 24);
|
|
4685
4798
|
const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);
|
|
4686
|
-
const aad =
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4799
|
+
const aad = isEncrypted ? Buffer.concat([
|
|
4800
|
+
encrypted.subarray(0, 8),
|
|
4801
|
+
encrypted.subarray(srtcpIndexOffset)
|
|
4802
|
+
]) : Buffer.concat([
|
|
4803
|
+
encrypted.subarray(0, authTagOffset),
|
|
4804
|
+
encrypted.subarray(srtcpIndexOffset)
|
|
4805
|
+
]);
|
|
4806
|
+
const cipherText = isEncrypted ? encrypted.slice(8, authTagOffset) : Buffer.alloc(0);
|
|
4807
|
+
const dst = isEncrypted ? Buffer.alloc(authTagOffset) : Buffer.from(encrypted.subarray(0, authTagOffset));
|
|
4808
|
+
if (isEncrypted) {
|
|
4809
|
+
encrypted.slice(0, 8).copy(dst);
|
|
4810
|
+
}
|
|
4811
|
+
const decipher = createDecipheriv2("aes-128-gcm", this.srtcpSessionKey, iv);
|
|
4812
|
+
decipher.setAAD(aad);
|
|
4813
|
+
decipher.setAuthTag(encrypted.subarray(authTagOffset, srtcpIndexOffset));
|
|
4814
|
+
const dec = decipher.update(cipherText);
|
|
4815
|
+
finalizeAuthenticatedDecryption(decipher, "SRTCP");
|
|
4816
|
+
if (isEncrypted) {
|
|
4817
|
+
dec.copy(dst, 8);
|
|
4818
|
+
}
|
|
4691
4819
|
return [dst, header];
|
|
4692
4820
|
}
|
|
4693
4821
|
// https://tools.ietf.org/html/rfc7714#section-8.1
|
|
@@ -4723,6 +4851,15 @@ var CipherAesGcm = class extends CipherAesBase {
|
|
|
4723
4851
|
};
|
|
4724
4852
|
var srtcpIndexSize2 = 4;
|
|
4725
4853
|
var rtcpEncryptionFlag = 128;
|
|
4854
|
+
function finalizeAuthenticatedDecryption(decipher, packetType) {
|
|
4855
|
+
try {
|
|
4856
|
+
decipher.final();
|
|
4857
|
+
} catch {
|
|
4858
|
+
throw new SrtpAuthenticationError(
|
|
4859
|
+
`Failed to authenticate ${packetType} packet`
|
|
4860
|
+
);
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4726
4863
|
|
|
4727
4864
|
// ../rtp/src/srtp/context/context.ts
|
|
4728
4865
|
var Context = class {
|
|
@@ -4980,12 +5117,29 @@ var SrtpContext = class extends Context {
|
|
|
4980
5117
|
return enc;
|
|
4981
5118
|
}
|
|
4982
5119
|
decryptRtp(cipherText) {
|
|
4983
|
-
const header =
|
|
4984
|
-
const
|
|
4985
|
-
|
|
4986
|
-
|
|
5120
|
+
const header = parseSrtpRtpHeader(cipherText, this.rtpAuthTagLength);
|
|
5121
|
+
const existingState = this.srtpSSRCStates[header.ssrc];
|
|
5122
|
+
const nextState = existingState ? { ...existingState } : {
|
|
5123
|
+
ssrc: header.ssrc,
|
|
5124
|
+
rolloverCounter: 0,
|
|
5125
|
+
lastSequenceNumber: 0
|
|
5126
|
+
};
|
|
5127
|
+
this.updateRolloverCount(header.sequenceNumber, nextState);
|
|
5128
|
+
const dec = this.cipher.decryptRtp(
|
|
5129
|
+
cipherText,
|
|
5130
|
+
nextState.rolloverCounter,
|
|
5131
|
+
header
|
|
5132
|
+
);
|
|
5133
|
+
if (existingState) {
|
|
5134
|
+
Object.assign(existingState, nextState);
|
|
5135
|
+
} else {
|
|
5136
|
+
this.srtpSSRCStates[header.ssrc] = nextState;
|
|
5137
|
+
}
|
|
4987
5138
|
return dec;
|
|
4988
5139
|
}
|
|
5140
|
+
get rtpAuthTagLength() {
|
|
5141
|
+
return this.profile === ProtectionProfileAeadAes128Gcm ? 16 : 10;
|
|
5142
|
+
}
|
|
4989
5143
|
};
|
|
4990
5144
|
|
|
4991
5145
|
// ../rtp/src/srtp/srtp.ts
|
|
@@ -8508,6 +8662,16 @@ handlers2[16 /* client_key_exchange_16 */] = ({ cipher, dtls }) => (message) =>
|
|
|
8508
8662
|
);
|
|
8509
8663
|
log18(dtls.sessionId, "setup cipher", cipher.cipher.summary);
|
|
8510
8664
|
};
|
|
8665
|
+
handlers2[11 /* certificate_11 */] = ({ cipher, dtls }) => (message) => {
|
|
8666
|
+
log18(dtls.sessionId, "handshake certificate", message);
|
|
8667
|
+
cipher.remoteCertificate = message.certificateList[0];
|
|
8668
|
+
};
|
|
8669
|
+
handlers2[15 /* certificate_verify_15 */] = ({ cipher, dtls }) => (message) => {
|
|
8670
|
+
if (!cipher.remoteCertificate) {
|
|
8671
|
+
throw new Error("client certificate missing before certificate verify");
|
|
8672
|
+
}
|
|
8673
|
+
log18(dtls.sessionId, "certificate_verify", message.algorithm);
|
|
8674
|
+
};
|
|
8511
8675
|
handlers2[20 /* finished_20 */] = ({ dtls }) => (message) => {
|
|
8512
8676
|
log18(dtls.sessionId, "finished", message);
|
|
8513
8677
|
};
|
|
@@ -9301,6 +9465,7 @@ var SCTP_TSN_MODULO = 2 ** 32;
|
|
|
9301
9465
|
|
|
9302
9466
|
// src/transport/sctp.ts
|
|
9303
9467
|
var log32 = debug("werift:packages/webrtc/src/transport/sctp.ts");
|
|
9468
|
+
var DEFAULT_MAX_MESSAGE_SIZE = 65536;
|
|
9304
9469
|
|
|
9305
9470
|
// src/media/rtpReceiver.ts
|
|
9306
9471
|
var log33 = debug("werift:packages/webrtc/src/media/rtpReceiver.ts");
|
|
@@ -9352,7 +9517,8 @@ function generateDefaultPeerConfig() {
|
|
|
9352
9517
|
bundlePolicy: "max-compat",
|
|
9353
9518
|
debug: {},
|
|
9354
9519
|
midSuffix: false,
|
|
9355
|
-
forceTurnTCP: false
|
|
9520
|
+
forceTurnTCP: false,
|
|
9521
|
+
maxMessageSize: DEFAULT_MAX_MESSAGE_SIZE
|
|
9356
9522
|
};
|
|
9357
9523
|
}
|
|
9358
9524
|
var defaultPeerConfig = generateDefaultPeerConfig();
|
|
@@ -9818,6 +9984,7 @@ export {
|
|
|
9818
9984
|
SourceDescriptionChunk,
|
|
9819
9985
|
SourceDescriptionItem,
|
|
9820
9986
|
SrtcpSession,
|
|
9987
|
+
SrtpAuthenticationError,
|
|
9821
9988
|
SrtpSession,
|
|
9822
9989
|
StatusVectorChunk,
|
|
9823
9990
|
TcpTransport,
|
package/lib/rtp/src/index.d.ts
CHANGED
package/lib/rtp/src/index.js
CHANGED
|
@@ -38,5 +38,6 @@ __exportStar(require("./rtp/rtp"), exports);
|
|
|
38
38
|
__exportStar(require("./rtp/rtx"), exports);
|
|
39
39
|
__exportStar(require("./srtp/srtcp"), exports);
|
|
40
40
|
__exportStar(require("./srtp/srtp"), exports);
|
|
41
|
+
__exportStar(require("./srtp/error"), exports);
|
|
41
42
|
__exportStar(require("./util"), exports);
|
|
42
43
|
//# sourceMappingURL=index.js.map
|
package/lib/rtp/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../rtp/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kBAAgB;AAChB,+CAA6B;AAC7B,mDAAiC;AACjC,0CAAwB;AACxB,2CAAyB;AACzB,gDAA8B;AAC9B,8CAA4B;AAC5B,oEAAkD;AAClD,mDAAiC;AACjC,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,oDAAkC;AAClC,oDAAkC;AAClC,8CAA4B;AAC5B,4CAA0B;AAC1B,wDAAsC;AACtC,oDAAkC;AAClC,oDAAkC;AAClC,mDAAiC;AACjC,4CAA0B;AAC1B,4CAA0B;AAC1B,+CAA6B;AAC7B,8CAA4B;AAC5B,yCAAuB","sourcesContent":["import \"buffer\";\nexport * from \"./srtp/const\";\nexport * from \"../../common/src\";\nexport * from \"./codec\";\nexport * from \"./helper\";\nexport * from \"./rtcp/header\";\nexport * from \"./rtcp/psfb\";\nexport * from \"./rtcp/psfb/pictureLossIndication\";\nexport * from \"./rtcp/psfb/remb\";\nexport * from \"./rtcp/rr\";\nexport * from \"./rtcp/rtcp\";\nexport * from \"./rtcp/rtpfb\";\nexport * from \"./rtcp/rtpfb/nack\";\nexport * from \"./rtcp/rtpfb/twcc\";\nexport * from \"./rtcp/sdes\";\nexport * from \"./rtcp/sr\";\nexport * from \"./rtp/headerExtension\";\nexport * from \"./rtp/red/encoder\";\nexport * from \"./rtp/red/handler\";\nexport * from \"./rtp/red/packet\";\nexport * from \"./rtp/rtp\";\nexport * from \"./rtp/rtx\";\nexport * from \"./srtp/srtcp\";\nexport * from \"./srtp/srtp\";\nexport * from \"./util\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../rtp/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kBAAgB;AAChB,+CAA6B;AAC7B,mDAAiC;AACjC,0CAAwB;AACxB,2CAAyB;AACzB,gDAA8B;AAC9B,8CAA4B;AAC5B,oEAAkD;AAClD,mDAAiC;AACjC,4CAA0B;AAC1B,8CAA4B;AAC5B,+CAA6B;AAC7B,oDAAkC;AAClC,oDAAkC;AAClC,8CAA4B;AAC5B,4CAA0B;AAC1B,wDAAsC;AACtC,oDAAkC;AAClC,oDAAkC;AAClC,mDAAiC;AACjC,4CAA0B;AAC1B,4CAA0B;AAC1B,+CAA6B;AAC7B,8CAA4B;AAC5B,+CAA6B;AAC7B,yCAAuB","sourcesContent":["import \"buffer\";\nexport * from \"./srtp/const\";\nexport * from \"../../common/src\";\nexport * from \"./codec\";\nexport * from \"./helper\";\nexport * from \"./rtcp/header\";\nexport * from \"./rtcp/psfb\";\nexport * from \"./rtcp/psfb/pictureLossIndication\";\nexport * from \"./rtcp/psfb/remb\";\nexport * from \"./rtcp/rr\";\nexport * from \"./rtcp/rtcp\";\nexport * from \"./rtcp/rtpfb\";\nexport * from \"./rtcp/rtpfb/nack\";\nexport * from \"./rtcp/rtpfb/twcc\";\nexport * from \"./rtcp/sdes\";\nexport * from \"./rtcp/sr\";\nexport * from \"./rtp/headerExtension\";\nexport * from \"./rtp/red/encoder\";\nexport * from \"./rtp/red/handler\";\nexport * from \"./rtp/red/packet\";\nexport * from \"./rtp/rtp\";\nexport * from \"./rtp/rtx\";\nexport * from \"./srtp/srtcp\";\nexport * from \"./srtp/srtp\";\nexport * from \"./srtp/error\";\nexport * from \"./util\";\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { CipherAesBase } from ".";
|
|
2
|
-
import { RtcpHeader } from "../../rtcp/header";
|
|
3
|
-
import { RtpHeader } from "../../rtp/rtp";
|
|
2
|
+
import type { RtcpHeader } from "../../rtcp/header";
|
|
3
|
+
import type { RtpHeader } from "../../rtp/rtp";
|
|
4
4
|
export declare class CipherAesCtr extends CipherAesBase {
|
|
5
5
|
private srtpSessionAuthTag;
|
|
6
6
|
private srtcpSessionAuthTag;
|
|
7
7
|
readonly authTagLength = 10;
|
|
8
8
|
constructor(srtpSessionKey: Buffer, srtpSessionSalt: Buffer, srtcpSessionKey: Buffer, srtcpSessionSalt: Buffer, srtpSessionAuthTag: Buffer, srtcpSessionAuthTag: Buffer);
|
|
9
9
|
encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number): Buffer<ArrayBuffer>;
|
|
10
|
-
decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader];
|
|
10
|
+
decryptRtp(cipherText: Buffer, rolloverCounter: number, header?: RtpHeader): [Buffer, RtpHeader];
|
|
11
11
|
encryptRTCP(rtcpPacket: Buffer, srtcpIndex: number): Buffer;
|
|
12
12
|
decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader];
|
|
13
13
|
generateSrtcpAuthTag(buf: Buffer): Buffer<ArrayBuffer>;
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CipherAesCtr = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const error_1 = require("../error");
|
|
7
|
+
const packet_1 = require("../packet");
|
|
8
8
|
class CipherAesCtr extends _1.CipherAesBase {
|
|
9
9
|
constructor(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt, srtpSessionAuthTag, srtcpSessionAuthTag) {
|
|
10
10
|
super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);
|
|
@@ -35,20 +35,24 @@ class CipherAesCtr extends _1.CipherAesBase {
|
|
|
35
35
|
const authTag = this.generateSrtpAuthTag(rolloverCounter, headerBuffer, enc);
|
|
36
36
|
return Buffer.concat([headerBuffer, enc, authTag]);
|
|
37
37
|
}
|
|
38
|
-
decryptRtp(cipherText, rolloverCounter) {
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
38
|
+
decryptRtp(cipherText, rolloverCounter, header = (0, packet_1.parseSrtpRtpHeader)(cipherText, this.authTagLength)) {
|
|
39
|
+
const authTagOffset = cipherText.length - this.authTagLength;
|
|
40
|
+
const encryptedPacket = cipherText.subarray(0, authTagOffset);
|
|
41
|
+
const actualAuthTag = cipherText.subarray(authTagOffset);
|
|
42
|
+
const expectedAuthTag = this.generateSrtpAuthTag(rolloverCounter, encryptedPacket.subarray(0, header.payloadOffset), encryptedPacket.subarray(header.payloadOffset));
|
|
43
|
+
assertAuthTag(actualAuthTag, expectedAuthTag, "Failed to authenticate SRTP packet");
|
|
42
44
|
const counter = this.generateCounter(header.sequenceNumber, rolloverCounter, header.ssrc, this.srtpSessionSalt);
|
|
43
45
|
const cipher = (0, crypto_1.createDecipheriv)("aes-128-ctr", this.srtpSessionKey, counter);
|
|
44
|
-
const payload =
|
|
46
|
+
const payload = encryptedPacket.subarray(header.payloadOffset);
|
|
45
47
|
const buf = cipher.update(payload);
|
|
46
48
|
const dst = Buffer.concat([
|
|
47
|
-
|
|
49
|
+
encryptedPacket.subarray(0, header.payloadOffset),
|
|
48
50
|
buf,
|
|
49
|
-
Buffer.alloc(size - header.payloadOffset - buf.length),
|
|
50
51
|
]);
|
|
51
|
-
return [
|
|
52
|
+
return [
|
|
53
|
+
dst,
|
|
54
|
+
(0, packet_1.finalizeSrtpRtpHeader)(header, dst, "Failed to authenticate SRTP packet"),
|
|
55
|
+
];
|
|
52
56
|
}
|
|
53
57
|
encryptRTCP(rtcpPacket, srtcpIndex) {
|
|
54
58
|
let out = Buffer.from(rtcpPacket);
|
|
@@ -66,17 +70,19 @@ class CipherAesCtr extends _1.CipherAesBase {
|
|
|
66
70
|
return out;
|
|
67
71
|
}
|
|
68
72
|
decryptRTCP(encrypted) {
|
|
69
|
-
const header =
|
|
73
|
+
const header = (0, packet_1.parseSrtcpHeader)(encrypted, this.authTagLength, srtcpIndexSize);
|
|
70
74
|
const tailOffset = encrypted.length - (this.authTagLength + srtcpIndexSize);
|
|
75
|
+
const authenticatedPortion = encrypted.subarray(0, encrypted.length - this.authTagLength);
|
|
76
|
+
const actualTag = encrypted.subarray(encrypted.length - this.authTagLength);
|
|
77
|
+
const expectedTag = this.generateSrtcpAuthTag(authenticatedPortion);
|
|
78
|
+
assertAuthTag(actualTag, expectedTag, "Failed to authenticate SRTCP packet");
|
|
71
79
|
const out = Buffer.from(encrypted).slice(0, tailOffset);
|
|
72
|
-
const isEncrypted = encrypted[tailOffset]
|
|
80
|
+
const isEncrypted = encrypted[tailOffset] >>> 7;
|
|
73
81
|
if (isEncrypted === 0)
|
|
74
82
|
return [out, header];
|
|
75
83
|
let srtcpIndex = encrypted.readUInt32BE(tailOffset);
|
|
76
84
|
srtcpIndex &= ~(1 << 31);
|
|
77
85
|
const ssrc = encrypted.readUInt32BE(4);
|
|
78
|
-
// todo impl compare
|
|
79
|
-
const actualTag = encrypted.subarray(encrypted.length - 10);
|
|
80
86
|
const counter = this.generateCounter(srtcpIndex & 0xffff, srtcpIndex >> 16, ssrc, this.srtcpSessionSalt);
|
|
81
87
|
const cipher = (0, crypto_1.createDecipheriv)("aes-128-ctr", this.srtcpSessionKey, counter);
|
|
82
88
|
const buf = cipher.update(out.subarray(8));
|
|
@@ -109,4 +115,9 @@ class CipherAesCtr extends _1.CipherAesBase {
|
|
|
109
115
|
}
|
|
110
116
|
exports.CipherAesCtr = CipherAesCtr;
|
|
111
117
|
const srtcpIndexSize = 4;
|
|
118
|
+
function assertAuthTag(actual, expected, message) {
|
|
119
|
+
if (actual.length !== expected.length || !(0, crypto_1.timingSafeEqual)(actual, expected)) {
|
|
120
|
+
throw new error_1.SrtpAuthenticationError(message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
112
123
|
//# sourceMappingURL=ctr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ctr.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/ctr.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv, createHmac } from \"crypto\";\n\nimport { CipherAesBase } from \".\";\nimport { RtcpHeader } from \"../../rtcp/header\";\nimport { RtpHeader } from \"../../rtp/rtp\";\n\nexport class CipherAesCtr extends CipherAesBase {\n readonly authTagLength = 10;\n\n constructor(\n srtpSessionKey: Buffer,\n srtpSessionSalt: Buffer,\n srtcpSessionKey: Buffer,\n srtcpSessionSalt: Buffer,\n private srtpSessionAuthTag: Buffer,\n private srtcpSessionAuthTag: Buffer,\n ) {\n super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);\n }\n\n encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number) {\n const headerBuffer = header.serialize(header.serializeSize);\n\n const counter = this.generateCounter(\n header.sequenceNumber,\n rolloverCounter,\n header.ssrc,\n this.srtpSessionSalt,\n );\n\n const cipher = createCipheriv(\"aes-128-ctr\", this.srtpSessionKey, counter);\n const enc = cipher.update(payload);\n\n const authTag = this.generateSrtpAuthTag(\n rolloverCounter,\n headerBuffer,\n enc,\n );\n return Buffer.concat([headerBuffer, enc, authTag]);\n }\n\n decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader] {\n const header = RtpHeader.deSerialize(cipherText);\n\n const size = cipherText.length - this.authTagLength;\n\n cipherText = cipherText.subarray(0, cipherText.length - this.authTagLength);\n\n const counter = this.generateCounter(\n header.sequenceNumber,\n rolloverCounter,\n header.ssrc,\n this.srtpSessionSalt,\n );\n const cipher = createDecipheriv(\n \"aes-128-ctr\",\n this.srtpSessionKey,\n counter,\n );\n const payload = cipherText.subarray(header.payloadOffset);\n const buf = cipher.update(payload);\n\n const dst = Buffer.concat([\n cipherText.subarray(0, header.payloadOffset),\n buf,\n Buffer.alloc(size - header.payloadOffset - buf.length),\n ]);\n\n return [dst, header];\n }\n\n encryptRTCP(rtcpPacket: Buffer, srtcpIndex: number): Buffer {\n let out = Buffer.from(rtcpPacket);\n const ssrc = out.readUInt32BE(4);\n\n const counter = this.generateCounter(\n srtcpIndex & 0xffff,\n srtcpIndex >> 16,\n ssrc,\n this.srtcpSessionSalt,\n );\n const cipher = createCipheriv(\"aes-128-ctr\", this.srtcpSessionKey, counter);\n // Encrypt everything after header\n const buf = cipher.update(out.slice(8));\n buf.copy(out, 8);\n out = Buffer.concat([out, Buffer.alloc(4)]);\n out.writeUInt32BE(srtcpIndex, out.length - 4);\n out[out.length - 4] |= 0x80;\n const authTag = this.generateSrtcpAuthTag(out);\n out = Buffer.concat([out, authTag]);\n\n return out;\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n const header = RtcpHeader.deSerialize(encrypted);\n\n const tailOffset = encrypted.length - (this.authTagLength + srtcpIndexSize);\n const out = Buffer.from(encrypted).slice(0, tailOffset);\n\n const isEncrypted = encrypted[tailOffset] >> 7;\n if (isEncrypted === 0) return [out, header];\n\n let srtcpIndex = encrypted.readUInt32BE(tailOffset);\n srtcpIndex &= ~(1 << 31);\n\n const ssrc = encrypted.readUInt32BE(4);\n\n // todo impl compare\n const actualTag = encrypted.subarray(encrypted.length - 10);\n\n const counter = this.generateCounter(\n srtcpIndex & 0xffff,\n srtcpIndex >> 16,\n ssrc,\n this.srtcpSessionSalt,\n );\n const cipher = createDecipheriv(\n \"aes-128-ctr\",\n this.srtcpSessionKey,\n counter,\n );\n const buf = cipher.update(out.subarray(8));\n buf.copy(out, 8);\n return [out, header];\n }\n\n generateSrtcpAuthTag(buf: Buffer) {\n const srtcpSessionAuth = createHmac(\"sha1\", this.srtcpSessionAuthTag);\n return srtcpSessionAuth.update(buf).digest().slice(0, 10);\n }\n\n generateCounter(\n sequenceNumber: number,\n rolloverCounter: number,\n ssrc: number,\n sessionSalt: Buffer,\n ) {\n const counter = Buffer.alloc(16);\n counter.writeUInt32BE(ssrc, 4);\n counter.writeUInt32BE(rolloverCounter, 8);\n counter.writeUInt32BE(Number(BigInt(sequenceNumber) << 16n), 12);\n\n for (let i = 0; i < sessionSalt.length; i++) {\n counter[i] ^= sessionSalt[i];\n }\n return counter;\n }\n\n generateSrtpAuthTag(roc: number, ...buffers: Buffer[]) {\n const srtpSessionAuth = createHmac(\"sha1\", this.srtpSessionAuthTag);\n const rocRaw = Buffer.alloc(4);\n rocRaw.writeUInt32BE(roc);\n\n for (const buf of buffers) {\n srtpSessionAuth.update(buf);\n }\n return srtpSessionAuth.update(rocRaw).digest().subarray(0, 10);\n }\n}\n\nconst srtcpIndexSize = 4;\n"]}
|
|
1
|
+
{"version":3,"file":"ctr.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/ctr.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createCipheriv,\n createDecipheriv,\n createHmac,\n timingSafeEqual,\n} from \"crypto\";\n\nimport { CipherAesBase } from \".\";\nimport type { RtcpHeader } from \"../../rtcp/header\";\nimport type { RtpHeader } from \"../../rtp/rtp\";\nimport { SrtpAuthenticationError } from \"../error\";\nimport {\n finalizeSrtpRtpHeader,\n parseSrtcpHeader,\n parseSrtpRtpHeader,\n} from \"../packet\";\n\nexport class CipherAesCtr extends CipherAesBase {\n readonly authTagLength = 10;\n\n constructor(\n srtpSessionKey: Buffer,\n srtpSessionSalt: Buffer,\n srtcpSessionKey: Buffer,\n srtcpSessionSalt: Buffer,\n private srtpSessionAuthTag: Buffer,\n private srtcpSessionAuthTag: Buffer,\n ) {\n super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);\n }\n\n encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number) {\n const headerBuffer = header.serialize(header.serializeSize);\n\n const counter = this.generateCounter(\n header.sequenceNumber,\n rolloverCounter,\n header.ssrc,\n this.srtpSessionSalt,\n );\n\n const cipher = createCipheriv(\"aes-128-ctr\", this.srtpSessionKey, counter);\n const enc = cipher.update(payload);\n\n const authTag = this.generateSrtpAuthTag(\n rolloverCounter,\n headerBuffer,\n enc,\n );\n return Buffer.concat([headerBuffer, enc, authTag]);\n }\n\n decryptRtp(\n cipherText: Buffer,\n rolloverCounter: number,\n header = parseSrtpRtpHeader(cipherText, this.authTagLength),\n ): [Buffer, RtpHeader] {\n const authTagOffset = cipherText.length - this.authTagLength;\n const encryptedPacket = cipherText.subarray(0, authTagOffset);\n const actualAuthTag = cipherText.subarray(authTagOffset);\n\n const expectedAuthTag = this.generateSrtpAuthTag(\n rolloverCounter,\n encryptedPacket.subarray(0, header.payloadOffset),\n encryptedPacket.subarray(header.payloadOffset),\n );\n assertAuthTag(\n actualAuthTag,\n expectedAuthTag,\n \"Failed to authenticate SRTP packet\",\n );\n\n const counter = this.generateCounter(\n header.sequenceNumber,\n rolloverCounter,\n header.ssrc,\n this.srtpSessionSalt,\n );\n const cipher = createDecipheriv(\n \"aes-128-ctr\",\n this.srtpSessionKey,\n counter,\n );\n const payload = encryptedPacket.subarray(header.payloadOffset);\n const buf = cipher.update(payload);\n\n const dst = Buffer.concat([\n encryptedPacket.subarray(0, header.payloadOffset),\n buf,\n ]);\n\n return [\n dst,\n finalizeSrtpRtpHeader(header, dst, \"Failed to authenticate SRTP packet\"),\n ];\n }\n\n encryptRTCP(rtcpPacket: Buffer, srtcpIndex: number): Buffer {\n let out = Buffer.from(rtcpPacket);\n const ssrc = out.readUInt32BE(4);\n\n const counter = this.generateCounter(\n srtcpIndex & 0xffff,\n srtcpIndex >> 16,\n ssrc,\n this.srtcpSessionSalt,\n );\n const cipher = createCipheriv(\"aes-128-ctr\", this.srtcpSessionKey, counter);\n // Encrypt everything after header\n const buf = cipher.update(out.slice(8));\n buf.copy(out, 8);\n out = Buffer.concat([out, Buffer.alloc(4)]);\n out.writeUInt32BE(srtcpIndex, out.length - 4);\n out[out.length - 4] |= 0x80;\n const authTag = this.generateSrtcpAuthTag(out);\n out = Buffer.concat([out, authTag]);\n\n return out;\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n const header = parseSrtcpHeader(\n encrypted,\n this.authTagLength,\n srtcpIndexSize,\n );\n\n const tailOffset = encrypted.length - (this.authTagLength + srtcpIndexSize);\n const authenticatedPortion = encrypted.subarray(\n 0,\n encrypted.length - this.authTagLength,\n );\n const actualTag = encrypted.subarray(encrypted.length - this.authTagLength);\n const expectedTag = this.generateSrtcpAuthTag(authenticatedPortion);\n assertAuthTag(\n actualTag,\n expectedTag,\n \"Failed to authenticate SRTCP packet\",\n );\n\n const out = Buffer.from(encrypted).slice(0, tailOffset);\n\n const isEncrypted = encrypted[tailOffset] >>> 7;\n if (isEncrypted === 0) return [out, header];\n\n let srtcpIndex = encrypted.readUInt32BE(tailOffset);\n srtcpIndex &= ~(1 << 31);\n\n const ssrc = encrypted.readUInt32BE(4);\n\n const counter = this.generateCounter(\n srtcpIndex & 0xffff,\n srtcpIndex >> 16,\n ssrc,\n this.srtcpSessionSalt,\n );\n const cipher = createDecipheriv(\n \"aes-128-ctr\",\n this.srtcpSessionKey,\n counter,\n );\n const buf = cipher.update(out.subarray(8));\n buf.copy(out, 8);\n return [out, header];\n }\n\n generateSrtcpAuthTag(buf: Buffer) {\n const srtcpSessionAuth = createHmac(\"sha1\", this.srtcpSessionAuthTag);\n return srtcpSessionAuth.update(buf).digest().slice(0, 10);\n }\n\n generateCounter(\n sequenceNumber: number,\n rolloverCounter: number,\n ssrc: number,\n sessionSalt: Buffer,\n ) {\n const counter = Buffer.alloc(16);\n counter.writeUInt32BE(ssrc, 4);\n counter.writeUInt32BE(rolloverCounter, 8);\n counter.writeUInt32BE(Number(BigInt(sequenceNumber) << 16n), 12);\n\n for (let i = 0; i < sessionSalt.length; i++) {\n counter[i] ^= sessionSalt[i];\n }\n return counter;\n }\n\n generateSrtpAuthTag(roc: number, ...buffers: Buffer[]) {\n const srtpSessionAuth = createHmac(\"sha1\", this.srtpSessionAuthTag);\n const rocRaw = Buffer.alloc(4);\n rocRaw.writeUInt32BE(roc);\n\n for (const buf of buffers) {\n srtpSessionAuth.update(buf);\n }\n return srtpSessionAuth.update(rocRaw).digest().subarray(0, 10);\n }\n}\n\nconst srtcpIndexSize = 4;\n\nfunction assertAuthTag(actual: Buffer, expected: Buffer, message: string) {\n if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) {\n throw new SrtpAuthenticationError(message);\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CipherAesBase } from ".";
|
|
2
|
-
import { RtcpHeader } from "../../rtcp/header";
|
|
3
|
-
import { RtpHeader } from "../../rtp/rtp";
|
|
2
|
+
import type { RtcpHeader } from "../../rtcp/header";
|
|
3
|
+
import type { RtpHeader } from "../../rtp/rtp";
|
|
4
4
|
export declare class CipherAesGcm extends CipherAesBase {
|
|
5
5
|
readonly aeadAuthTagLen = 16;
|
|
6
6
|
readonly rtpIvWriter: (values: (number | bigint)[]) => Buffer<ArrayBuffer>;
|
|
@@ -8,7 +8,7 @@ export declare class CipherAesGcm extends CipherAesBase {
|
|
|
8
8
|
readonly aadWriter: (values: (number | bigint)[]) => Buffer<ArrayBuffer>;
|
|
9
9
|
constructor(srtpSessionKey: Buffer, srtpSessionSalt: Buffer, srtcpSessionKey: Buffer, srtcpSessionSalt: Buffer);
|
|
10
10
|
encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number): Buffer<ArrayBuffer>;
|
|
11
|
-
decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader];
|
|
11
|
+
decryptRtp(cipherText: Buffer, rolloverCounter: number, header?: RtpHeader): [Buffer, RtpHeader];
|
|
12
12
|
encryptRTCP(rtcpPacket: Buffer, srtcpIndex: number): Buffer;
|
|
13
13
|
decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader];
|
|
14
14
|
private rtpInitializationVector;
|