werift 0.22.9 → 0.24.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 (173) hide show
  1. package/README.md +46 -0
  2. package/lib/common/src/transport.d.ts +22 -9
  3. package/lib/common/src/transport.js +152 -25
  4. package/lib/common/src/transport.js.map +1 -1
  5. package/lib/dtls/src/flight/server/flight6.js +12 -2
  6. package/lib/dtls/src/flight/server/flight6.js.map +1 -1
  7. package/lib/dtls/src/server.js +6 -1
  8. package/lib/dtls/src/server.js.map +1 -1
  9. package/lib/dtls/src/socket.d.ts +1 -0
  10. package/lib/dtls/src/socket.js +3 -0
  11. package/lib/dtls/src/socket.js.map +1 -1
  12. package/lib/ice/src/candidate.d.ts +16 -1
  13. package/lib/ice/src/candidate.js +99 -15
  14. package/lib/ice/src/candidate.js.map +1 -1
  15. package/lib/ice/src/ice.d.ts +2 -0
  16. package/lib/ice/src/ice.js +171 -41
  17. package/lib/ice/src/ice.js.map +1 -1
  18. package/lib/ice/src/iceBase.d.ts +23 -2
  19. package/lib/ice/src/iceBase.js +63 -1
  20. package/lib/ice/src/iceBase.js.map +1 -1
  21. package/lib/ice/src/index.d.ts +2 -0
  22. package/lib/ice/src/index.js +2 -0
  23. package/lib/ice/src/index.js.map +1 -1
  24. package/lib/ice/src/stun/const.d.ts +1 -26
  25. package/lib/ice/src/stun/const.js +15 -54
  26. package/lib/ice/src/stun/const.js.map +1 -1
  27. package/lib/ice/src/stun/message.d.ts +1 -25
  28. package/lib/ice/src/stun/message.js +15 -149
  29. package/lib/ice/src/stun/message.js.map +1 -1
  30. package/lib/ice/src/stun/protocol.d.ts +1 -1
  31. package/lib/ice/src/stun/protocol.js +2 -2
  32. package/lib/ice/src/stun/protocol.js.map +1 -1
  33. package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
  34. package/lib/ice/src/stun/tcpFrame.js +26 -0
  35. package/lib/ice/src/stun/tcpFrame.js.map +1 -0
  36. package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
  37. package/lib/ice/src/stun/tcpProtocol.js +326 -0
  38. package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
  39. package/lib/ice/src/stun/transaction.d.ts +2 -1
  40. package/lib/ice/src/stun/transaction.js +9 -3
  41. package/lib/ice/src/stun/transaction.js.map +1 -1
  42. package/lib/ice/src/turn/frame.d.ts +1 -0
  43. package/lib/ice/src/turn/frame.js +18 -0
  44. package/lib/ice/src/turn/frame.js.map +1 -0
  45. package/lib/ice/src/turn/protocol.d.ts +9 -7
  46. package/lib/ice/src/turn/protocol.js +32 -44
  47. package/lib/ice/src/turn/protocol.js.map +1 -1
  48. package/lib/ice/src/types/model.d.ts +1 -1
  49. package/lib/ice/src/types/model.js.map +1 -1
  50. package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
  51. package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
  52. package/lib/ice-server/src/stun/attributes.js.map +1 -0
  53. package/lib/ice-server/src/stun/const.d.ts +28 -0
  54. package/lib/ice-server/src/stun/const.js +88 -0
  55. package/lib/ice-server/src/stun/const.js.map +1 -0
  56. package/lib/ice-server/src/stun/message.d.ts +37 -0
  57. package/lib/ice-server/src/stun/message.js +190 -0
  58. package/lib/ice-server/src/stun/message.js.map +1 -0
  59. package/lib/ice-server/src/turn/auth.d.ts +1 -0
  60. package/lib/ice-server/src/turn/auth.js +10 -0
  61. package/lib/ice-server/src/turn/auth.js.map +1 -0
  62. package/lib/ice-server/src/turn/frame.d.ts +13 -0
  63. package/lib/ice-server/src/turn/frame.js +69 -0
  64. package/lib/ice-server/src/turn/frame.js.map +1 -0
  65. package/lib/index.mjs +3075 -883
  66. package/lib/nonstandard/index.mjs +1964 -447
  67. package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
  68. package/lib/rtp/src/extra/container/mp4/container.js +258 -173
  69. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  70. package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
  71. package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
  72. package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
  73. package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
  74. package/lib/rtp/src/extra/processor/mp4.js +115 -60
  75. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  76. package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
  77. package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
  78. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  79. package/lib/rtp/src/index.d.ts +1 -0
  80. package/lib/rtp/src/index.js +1 -0
  81. package/lib/rtp/src/index.js.map +1 -1
  82. package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
  83. package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
  84. package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
  85. package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
  86. package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
  87. package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
  88. package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
  89. package/lib/rtp/src/srtp/cipher/index.js +1 -1
  90. package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
  91. package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
  92. package/lib/rtp/src/srtp/context/srtp.js +22 -5
  93. package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
  94. package/lib/rtp/src/srtp/error.d.ts +3 -0
  95. package/lib/rtp/src/srtp/error.js +11 -0
  96. package/lib/rtp/src/srtp/error.js.map +1 -0
  97. package/lib/rtp/src/srtp/packet.d.ts +5 -0
  98. package/lib/rtp/src/srtp/packet.js +48 -0
  99. package/lib/rtp/src/srtp/packet.js.map +1 -0
  100. package/lib/webrtc/src/dataChannel.d.ts +4 -2
  101. package/lib/webrtc/src/dataChannel.js +14 -4
  102. package/lib/webrtc/src/dataChannel.js.map +1 -1
  103. package/lib/webrtc/src/errors.d.ts +3 -0
  104. package/lib/webrtc/src/errors.js +11 -0
  105. package/lib/webrtc/src/errors.js.map +1 -0
  106. package/lib/webrtc/src/helper.d.ts +5 -1
  107. package/lib/webrtc/src/helper.js +33 -1
  108. package/lib/webrtc/src/helper.js.map +1 -1
  109. package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
  110. package/lib/webrtc/src/media/receiver/statistics.js +22 -0
  111. package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
  112. package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
  113. package/lib/webrtc/src/media/rtpReceiver.js +135 -20
  114. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  115. package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
  116. package/lib/webrtc/src/media/rtpSender.js +177 -28
  117. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  118. package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
  119. package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
  120. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  121. package/lib/webrtc/src/media/stats.d.ts +15 -1
  122. package/lib/webrtc/src/media/stats.js +55 -1
  123. package/lib/webrtc/src/media/stats.js.map +1 -1
  124. package/lib/webrtc/src/media/track.d.ts +2 -1
  125. package/lib/webrtc/src/media/track.js +7 -1
  126. package/lib/webrtc/src/media/track.js.map +1 -1
  127. package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
  128. package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
  129. package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
  130. package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
  131. package/lib/webrtc/src/nonstandard/navigator.js +96 -32
  132. package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
  133. package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
  134. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
  135. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
  136. package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
  137. package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
  138. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  139. package/lib/webrtc/src/peerConnection.d.ts +185 -49
  140. package/lib/webrtc/src/peerConnection.js +477 -107
  141. package/lib/webrtc/src/peerConnection.js.map +1 -1
  142. package/lib/webrtc/src/sctpManager.d.ts +2 -2
  143. package/lib/webrtc/src/sctpManager.js +30 -9
  144. package/lib/webrtc/src/sctpManager.js.map +1 -1
  145. package/lib/webrtc/src/sdp.d.ts +10 -7
  146. package/lib/webrtc/src/sdp.js +39 -9
  147. package/lib/webrtc/src/sdp.js.map +1 -1
  148. package/lib/webrtc/src/sdpManager.d.ts +5 -4
  149. package/lib/webrtc/src/sdpManager.js +53 -31
  150. package/lib/webrtc/src/sdpManager.js.map +1 -1
  151. package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
  152. package/lib/webrtc/src/secureTransportManager.js +101 -23
  153. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  154. package/lib/webrtc/src/transceiverManager.d.ts +5 -4
  155. package/lib/webrtc/src/transceiverManager.js +64 -64
  156. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  157. package/lib/webrtc/src/transport/dtls.d.ts +16 -4
  158. package/lib/webrtc/src/transport/dtls.js +208 -35
  159. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  160. package/lib/webrtc/src/transport/ice.d.ts +21 -3
  161. package/lib/webrtc/src/transport/ice.js +159 -30
  162. package/lib/webrtc/src/transport/ice.js.map +1 -1
  163. package/lib/webrtc/src/transport/sctp.d.ts +10 -3
  164. package/lib/webrtc/src/transport/sctp.js +44 -13
  165. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  166. package/lib/webrtc/src/utils.d.ts +14 -4
  167. package/lib/webrtc/src/utils.js +138 -16
  168. package/lib/webrtc/src/utils.js.map +1 -1
  169. package/package.json +7 -4
  170. package/lib/ice/src/stun/attributes.js.map +0 -1
  171. package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
  172. package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
  173. package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
@@ -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 header_1 = require("../../rtcp/header");
7
- const rtp_1 = require("../../rtp/rtp");
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 header = rtp_1.RtpHeader.deSerialize(cipherText);
40
- const size = cipherText.length - this.authTagLength;
41
- cipherText = cipherText.subarray(0, cipherText.length - this.authTagLength);
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 = cipherText.subarray(header.payloadOffset);
46
+ const payload = encryptedPacket.subarray(header.payloadOffset);
45
47
  const buf = cipher.update(payload);
46
48
  const dst = Buffer.concat([
47
- cipherText.subarray(0, header.payloadOffset),
49
+ encryptedPacket.subarray(0, header.payloadOffset),
48
50
  buf,
49
- Buffer.alloc(size - header.payloadOffset - buf.length),
50
51
  ]);
51
- return [dst, header];
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 = header_1.RtcpHeader.deSerialize(encrypted);
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] >> 7;
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;
@@ -5,8 +5,8 @@ const crypto_1 = require("crypto");
5
5
  const _1 = require(".");
6
6
  const src_1 = require("../../../../common/src");
7
7
  const helper_1 = require("../../helper");
8
- const header_1 = require("../../rtcp/header");
9
- const rtp_1 = require("../../rtp/rtp");
8
+ const error_1 = require("../error");
9
+ const packet_1 = require("../packet");
10
10
  class CipherAesGcm extends _1.CipherAesBase {
11
11
  constructor(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt) {
12
12
  super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);
@@ -46,17 +46,25 @@ class CipherAesGcm extends _1.CipherAesBase {
46
46
  const dst = Buffer.concat([hdr, enc, authTag]);
47
47
  return dst;
48
48
  }
49
- decryptRtp(cipherText, rolloverCounter) {
50
- const header = rtp_1.RtpHeader.deSerialize(cipherText);
49
+ decryptRtp(cipherText, rolloverCounter, header = (0, packet_1.parseSrtpRtpHeader)(cipherText, this.aeadAuthTagLen)) {
50
+ const headerBuffer = cipherText.subarray(0, header.payloadOffset);
51
+ const authTagOffset = cipherText.length - this.aeadAuthTagLen;
52
+ const authTag = cipherText.subarray(authTagOffset);
51
53
  let dst = Buffer.from([]);
52
54
  dst = (0, helper_1.growBufferSize)(dst, cipherText.length - this.aeadAuthTagLen);
53
- cipherText.slice(0, header.payloadOffset).copy(dst);
55
+ headerBuffer.copy(dst);
54
56
  const iv = this.rtpInitializationVector(header, rolloverCounter);
55
- const enc = cipherText.slice(header.payloadOffset, cipherText.length - this.aeadAuthTagLen);
56
- const cipher = (0, crypto_1.createDecipheriv)("aes-128-gcm", this.srtpSessionKey, iv);
57
- const dec = cipher.update(enc);
57
+ const enc = cipherText.slice(header.payloadOffset, authTagOffset);
58
+ const decipher = (0, crypto_1.createDecipheriv)("aes-128-gcm", this.srtpSessionKey, iv);
59
+ decipher.setAAD(headerBuffer);
60
+ decipher.setAuthTag(authTag);
61
+ const dec = decipher.update(enc);
62
+ finalizeAuthenticatedDecryption(decipher, "SRTP");
58
63
  dec.copy(dst, header.payloadOffset);
59
- return [dst, header];
64
+ return [
65
+ dst,
66
+ (0, packet_1.finalizeSrtpRtpHeader)(header, dst, "Failed to authenticate SRTP packet"),
67
+ ];
60
68
  }
61
69
  encryptRTCP(rtcpPacket, srtcpIndex) {
62
70
  const ssrc = rtcpPacket.readUInt32BE(4);
@@ -77,19 +85,40 @@ class CipherAesGcm extends _1.CipherAesBase {
77
85
  return dst;
78
86
  }
79
87
  decryptRTCP(encrypted) {
80
- const header = header_1.RtcpHeader.deSerialize(encrypted);
81
- const aadPos = encrypted.length - srtcpIndexSize;
82
- const dst = Buffer.alloc(aadPos - this.aeadAuthTagLen);
83
- encrypted.slice(0, 8).copy(dst);
88
+ const header = (0, packet_1.parseSrtcpHeader)(encrypted, this.aeadAuthTagLen, srtcpIndexSize);
89
+ const srtcpIndexOffset = encrypted.length - srtcpIndexSize;
90
+ const authTagOffset = srtcpIndexOffset - this.aeadAuthTagLen;
84
91
  const ssrc = encrypted.readUInt32BE(4);
85
- let srtcpIndex = encrypted.readUInt32BE(encrypted.length - 4);
86
- srtcpIndex &= ~(rtcpEncryptionFlag << 24);
92
+ const encodedSrtcpIndex = encrypted.readUInt32BE(srtcpIndexOffset);
93
+ const isEncrypted = encodedSrtcpIndex >>> 31 === 1;
94
+ const srtcpIndex = encodedSrtcpIndex & ~(rtcpEncryptionFlag << 24);
87
95
  const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);
88
- const aad = this.rtcpAdditionalAuthenticatedData(encrypted, srtcpIndex);
89
- const cipher = (0, crypto_1.createDecipheriv)("aes-128-gcm", this.srtcpSessionKey, iv);
90
- cipher.setAAD(aad);
91
- const dec = cipher.update(encrypted.slice(8, aadPos));
92
- dec.copy(dst, 8);
96
+ const aad = isEncrypted
97
+ ? Buffer.concat([
98
+ encrypted.subarray(0, 8),
99
+ encrypted.subarray(srtcpIndexOffset),
100
+ ])
101
+ : Buffer.concat([
102
+ encrypted.subarray(0, authTagOffset),
103
+ encrypted.subarray(srtcpIndexOffset),
104
+ ]);
105
+ const cipherText = isEncrypted
106
+ ? encrypted.slice(8, authTagOffset)
107
+ : Buffer.alloc(0);
108
+ const dst = isEncrypted
109
+ ? Buffer.alloc(authTagOffset)
110
+ : Buffer.from(encrypted.subarray(0, authTagOffset));
111
+ if (isEncrypted) {
112
+ encrypted.slice(0, 8).copy(dst);
113
+ }
114
+ const decipher = (0, crypto_1.createDecipheriv)("aes-128-gcm", this.srtcpSessionKey, iv);
115
+ decipher.setAAD(aad);
116
+ decipher.setAuthTag(encrypted.subarray(authTagOffset, srtcpIndexOffset));
117
+ const dec = decipher.update(cipherText);
118
+ finalizeAuthenticatedDecryption(decipher, "SRTCP");
119
+ if (isEncrypted) {
120
+ dec.copy(dst, 8);
121
+ }
93
122
  return [dst, header];
94
123
  }
95
124
  // https://tools.ietf.org/html/rfc7714#section-8.1
@@ -126,4 +155,12 @@ class CipherAesGcm extends _1.CipherAesBase {
126
155
  exports.CipherAesGcm = CipherAesGcm;
127
156
  const srtcpIndexSize = 4;
128
157
  const rtcpEncryptionFlag = 0x80;
158
+ function finalizeAuthenticatedDecryption(decipher, packetType) {
159
+ try {
160
+ decipher.final();
161
+ }
162
+ catch {
163
+ throw new error_1.SrtpAuthenticationError(`Failed to authenticate ${packetType} packet`);
164
+ }
165
+ }
129
166
  //# sourceMappingURL=gcm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gcm.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/gcm.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv } from \"crypto\";\n\nimport { CipherAesBase } from \".\";\nimport { createBufferWriter } from \"../../../../common/src\";\nimport { growBufferSize } from \"../../helper\";\nimport { RtcpHeader } from \"../../rtcp/header\";\nimport { RtpHeader } from \"../../rtp/rtp\";\n\nexport class CipherAesGcm extends CipherAesBase {\n readonly aeadAuthTagLen = 16;\n readonly rtpIvWriter = createBufferWriter([2, 4, 4, 2], true);\n readonly rtcpIvWriter = createBufferWriter([2, 4, 2, 4], true);\n readonly aadWriter = createBufferWriter([4], true);\n\n constructor(\n srtpSessionKey: Buffer,\n srtpSessionSalt: Buffer,\n srtcpSessionKey: Buffer,\n srtcpSessionSalt: Buffer,\n ) {\n super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);\n }\n\n encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number) {\n const hdr = header.serialize(header.serializeSize);\n\n const iv = this.rtpInitializationVector(header, rolloverCounter);\n\n const cipher = createCipheriv(\"aes-128-gcm\", this.srtpSessionKey, iv);\n cipher.setAAD(hdr);\n const enc = cipher.update(payload);\n cipher.final();\n\n const authTag = cipher.getAuthTag();\n\n const dst = Buffer.concat([hdr, enc, authTag]);\n return dst;\n }\n\n decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader] {\n const header = RtpHeader.deSerialize(cipherText);\n\n let dst = Buffer.from([]);\n dst = growBufferSize(dst, cipherText.length - this.aeadAuthTagLen);\n cipherText.slice(0, header.payloadOffset).copy(dst);\n\n const iv = this.rtpInitializationVector(header, rolloverCounter);\n\n const enc = cipherText.slice(\n header.payloadOffset,\n cipherText.length - this.aeadAuthTagLen,\n );\n\n const cipher = createDecipheriv(\"aes-128-gcm\", this.srtpSessionKey, iv);\n const dec = cipher.update(enc);\n\n dec.copy(dst, header.payloadOffset);\n\n return [dst, header];\n }\n\n encryptRTCP(rtcpPacket: Buffer, srtcpIndex: number): Buffer {\n const ssrc = rtcpPacket.readUInt32BE(4);\n\n const addPos = rtcpPacket.length + this.aeadAuthTagLen;\n let dst = Buffer.from([]);\n dst = growBufferSize(dst, addPos + srtcpIndexSize);\n rtcpPacket.slice(0, 8).copy(dst);\n\n const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);\n const aad = this.rtcpAdditionalAuthenticatedData(rtcpPacket, srtcpIndex);\n\n const cipher = createCipheriv(\"aes-128-gcm\", this.srtcpSessionKey, iv);\n cipher.setAAD(aad);\n const enc = cipher.update(rtcpPacket.slice(8));\n cipher.final();\n enc.copy(dst, 8);\n\n const authTag = cipher.getAuthTag();\n authTag.copy(dst, 8 + enc.length);\n aad.slice(8, 12).copy(dst, addPos);\n\n return dst;\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n const header = RtcpHeader.deSerialize(encrypted);\n const aadPos = encrypted.length - srtcpIndexSize;\n\n const dst = Buffer.alloc(aadPos - this.aeadAuthTagLen);\n encrypted.slice(0, 8).copy(dst);\n\n const ssrc = encrypted.readUInt32BE(4);\n\n let srtcpIndex = encrypted.readUInt32BE(encrypted.length - 4);\n srtcpIndex &= ~(rtcpEncryptionFlag << 24);\n\n const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);\n const aad = this.rtcpAdditionalAuthenticatedData(encrypted, srtcpIndex);\n\n const cipher = createDecipheriv(\"aes-128-gcm\", this.srtcpSessionKey, iv);\n cipher.setAAD(aad);\n const dec = cipher.update(encrypted.slice(8, aadPos));\n\n dec.copy(dst, 8);\n\n return [dst, header];\n }\n\n // https://tools.ietf.org/html/rfc7714#section-8.1\n private rtpInitializationVector(header: RtpHeader, rolloverCounter: number) {\n const iv = this.rtpIvWriter([\n 0,\n header.ssrc,\n rolloverCounter,\n header.sequenceNumber,\n ]);\n for (let i = 0; i < iv.length; i++) {\n iv[i] ^= this.srtpSessionSalt[i];\n }\n return iv;\n }\n\n // https://tools.ietf.org/html/rfc7714#section-9.1\n private rtcpInitializationVector(ssrc: number, srtcpIndex: number) {\n const iv = this.rtcpIvWriter([0, ssrc, 0, srtcpIndex]);\n for (let i = 0; i < iv.length; i++) {\n iv[i] ^= this.srtcpSessionSalt[i];\n }\n return iv;\n }\n\n // https://datatracker.ietf.org/doc/html/rfc7714#section-17\n private rtcpAdditionalAuthenticatedData(\n rtcpPacket: Buffer,\n srtcpIndex: number,\n ) {\n const aad = Buffer.concat([\n rtcpPacket.subarray(0, 8),\n this.aadWriter([srtcpIndex]),\n ]);\n aad[8] |= rtcpEncryptionFlag;\n return aad;\n }\n}\n\nconst srtcpIndexSize = 4;\nconst rtcpEncryptionFlag = 0x80;\n"]}
1
+ {"version":3,"file":"gcm.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/gcm.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv } from \"crypto\";\n\nimport { CipherAesBase } from \".\";\nimport { createBufferWriter } from \"../../../../common/src\";\nimport { growBufferSize } from \"../../helper\";\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 CipherAesGcm extends CipherAesBase {\n readonly aeadAuthTagLen = 16;\n readonly rtpIvWriter = createBufferWriter([2, 4, 4, 2], true);\n readonly rtcpIvWriter = createBufferWriter([2, 4, 2, 4], true);\n readonly aadWriter = createBufferWriter([4], true);\n\n constructor(\n srtpSessionKey: Buffer,\n srtpSessionSalt: Buffer,\n srtcpSessionKey: Buffer,\n srtcpSessionSalt: Buffer,\n ) {\n super(srtpSessionKey, srtpSessionSalt, srtcpSessionKey, srtcpSessionSalt);\n }\n\n encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number) {\n const hdr = header.serialize(header.serializeSize);\n\n const iv = this.rtpInitializationVector(header, rolloverCounter);\n\n const cipher = createCipheriv(\"aes-128-gcm\", this.srtpSessionKey, iv);\n cipher.setAAD(hdr);\n const enc = cipher.update(payload);\n cipher.final();\n\n const authTag = cipher.getAuthTag();\n\n const dst = Buffer.concat([hdr, enc, authTag]);\n return dst;\n }\n\n decryptRtp(\n cipherText: Buffer,\n rolloverCounter: number,\n header = parseSrtpRtpHeader(cipherText, this.aeadAuthTagLen),\n ): [Buffer, RtpHeader] {\n const headerBuffer = cipherText.subarray(0, header.payloadOffset);\n const authTagOffset = cipherText.length - this.aeadAuthTagLen;\n const authTag = cipherText.subarray(authTagOffset);\n\n let dst = Buffer.from([]);\n dst = growBufferSize(dst, cipherText.length - this.aeadAuthTagLen);\n headerBuffer.copy(dst);\n\n const iv = this.rtpInitializationVector(header, rolloverCounter);\n\n const enc = cipherText.slice(header.payloadOffset, authTagOffset);\n\n const decipher = createDecipheriv(\"aes-128-gcm\", this.srtpSessionKey, iv);\n decipher.setAAD(headerBuffer);\n decipher.setAuthTag(authTag);\n const dec = decipher.update(enc);\n finalizeAuthenticatedDecryption(decipher, \"SRTP\");\n\n dec.copy(dst, header.payloadOffset);\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 const ssrc = rtcpPacket.readUInt32BE(4);\n\n const addPos = rtcpPacket.length + this.aeadAuthTagLen;\n let dst = Buffer.from([]);\n dst = growBufferSize(dst, addPos + srtcpIndexSize);\n rtcpPacket.slice(0, 8).copy(dst);\n\n const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);\n const aad = this.rtcpAdditionalAuthenticatedData(rtcpPacket, srtcpIndex);\n\n const cipher = createCipheriv(\"aes-128-gcm\", this.srtcpSessionKey, iv);\n cipher.setAAD(aad);\n const enc = cipher.update(rtcpPacket.slice(8));\n cipher.final();\n enc.copy(dst, 8);\n\n const authTag = cipher.getAuthTag();\n authTag.copy(dst, 8 + enc.length);\n aad.slice(8, 12).copy(dst, addPos);\n\n return dst;\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n const header = parseSrtcpHeader(\n encrypted,\n this.aeadAuthTagLen,\n srtcpIndexSize,\n );\n const srtcpIndexOffset = encrypted.length - srtcpIndexSize;\n const authTagOffset = srtcpIndexOffset - this.aeadAuthTagLen;\n\n const ssrc = encrypted.readUInt32BE(4);\n const encodedSrtcpIndex = encrypted.readUInt32BE(srtcpIndexOffset);\n const isEncrypted = encodedSrtcpIndex >>> 31 === 1;\n const srtcpIndex = encodedSrtcpIndex & ~(rtcpEncryptionFlag << 24);\n\n const iv = this.rtcpInitializationVector(ssrc, srtcpIndex);\n const aad = isEncrypted\n ? Buffer.concat([\n encrypted.subarray(0, 8),\n encrypted.subarray(srtcpIndexOffset),\n ])\n : Buffer.concat([\n encrypted.subarray(0, authTagOffset),\n encrypted.subarray(srtcpIndexOffset),\n ]);\n const cipherText = isEncrypted\n ? encrypted.slice(8, authTagOffset)\n : Buffer.alloc(0);\n const dst = isEncrypted\n ? Buffer.alloc(authTagOffset)\n : Buffer.from(encrypted.subarray(0, authTagOffset));\n if (isEncrypted) {\n encrypted.slice(0, 8).copy(dst);\n }\n\n const decipher = createDecipheriv(\"aes-128-gcm\", this.srtcpSessionKey, iv);\n decipher.setAAD(aad);\n decipher.setAuthTag(encrypted.subarray(authTagOffset, srtcpIndexOffset));\n const dec = decipher.update(cipherText);\n finalizeAuthenticatedDecryption(decipher, \"SRTCP\");\n\n if (isEncrypted) {\n dec.copy(dst, 8);\n }\n\n return [dst, header];\n }\n\n // https://tools.ietf.org/html/rfc7714#section-8.1\n private rtpInitializationVector(header: RtpHeader, rolloverCounter: number) {\n const iv = this.rtpIvWriter([\n 0,\n header.ssrc,\n rolloverCounter,\n header.sequenceNumber,\n ]);\n for (let i = 0; i < iv.length; i++) {\n iv[i] ^= this.srtpSessionSalt[i];\n }\n return iv;\n }\n\n // https://tools.ietf.org/html/rfc7714#section-9.1\n private rtcpInitializationVector(ssrc: number, srtcpIndex: number) {\n const iv = this.rtcpIvWriter([0, ssrc, 0, srtcpIndex]);\n for (let i = 0; i < iv.length; i++) {\n iv[i] ^= this.srtcpSessionSalt[i];\n }\n return iv;\n }\n\n // https://datatracker.ietf.org/doc/html/rfc7714#section-17\n private rtcpAdditionalAuthenticatedData(\n rtcpPacket: Buffer,\n srtcpIndex: number,\n ) {\n const aad = Buffer.concat([\n rtcpPacket.subarray(0, 8),\n this.aadWriter([srtcpIndex]),\n ]);\n aad[8] |= rtcpEncryptionFlag;\n return aad;\n }\n}\n\nconst srtcpIndexSize = 4;\nconst rtcpEncryptionFlag = 0x80;\n\nfunction finalizeAuthenticatedDecryption(\n decipher: ReturnType<typeof createDecipheriv>,\n packetType: \"SRTP\" | \"SRTCP\",\n) {\n try {\n decipher.final();\n } catch {\n throw new SrtpAuthenticationError(\n `Failed to authenticate ${packetType} packet`,\n );\n }\n}\n"]}
@@ -7,7 +7,7 @@ export declare abstract class CipherAesBase {
7
7
  srtcpSessionSalt: Buffer;
8
8
  constructor(srtpSessionKey: Buffer, srtpSessionSalt: Buffer, srtcpSessionKey: Buffer, srtcpSessionSalt: Buffer);
9
9
  encryptRtp(header: RtpHeader, payload: Buffer, rolloverCounter: number): Buffer;
10
- decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader];
10
+ decryptRtp(cipherText: Buffer, rolloverCounter: number, header?: RtpHeader): [Buffer, RtpHeader];
11
11
  encryptRTCP(rawRtcp: Buffer, srtcpIndex: number): Buffer;
12
12
  decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader];
13
13
  }
@@ -31,7 +31,7 @@ class CipherAesBase {
31
31
  encryptRtp(header, payload, rolloverCounter) {
32
32
  return Buffer.from([]);
33
33
  }
34
- decryptRtp(cipherText, rolloverCounter) {
34
+ decryptRtp(cipherText, rolloverCounter, header) {
35
35
  return [];
36
36
  }
37
37
  encryptRTCP(rawRtcp, srtcpIndex) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/index.ts"],"names":[],"mappings":";;;AAGA,MAAsB,aAAa;IACjC,YACS,cAAsB,EACtB,eAAuB,EACvB,eAAuB,EACvB,gBAAwB;QAH/B;;;;mBAAO,cAAc;WAAQ;QAC7B;;;;mBAAO,eAAe;WAAQ;QAC9B;;;;mBAAO,eAAe;WAAQ;QAC9B;;;;mBAAO,gBAAgB;WAAQ;IAC9B,CAAC;IAEJ,UAAU,CACR,MAAiB,EACjB,OAAe,EACf,eAAuB;QAEvB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,UAAkB,EAAE,eAAuB;QACpD,OAAO,EAAS,CAAC;IACnB,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,UAAkB;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,OAAO,EAAS,CAAC;IACnB,CAAC;CACF;AA3BD,sCA2BC","sourcesContent":["import type { RtcpHeader } from \"../../rtcp/header\";\nimport type { RtpHeader } from \"../../rtp/rtp\";\n\nexport abstract class CipherAesBase {\n constructor(\n public srtpSessionKey: Buffer,\n public srtpSessionSalt: Buffer,\n public srtcpSessionKey: Buffer,\n public srtcpSessionSalt: Buffer,\n ) {}\n\n encryptRtp(\n header: RtpHeader,\n payload: Buffer,\n rolloverCounter: number,\n ): Buffer {\n return Buffer.from([]);\n }\n\n decryptRtp(cipherText: Buffer, rolloverCounter: number): [Buffer, RtpHeader] {\n return [] as any;\n }\n\n encryptRTCP(rawRtcp: Buffer, srtcpIndex: number): Buffer {\n return Buffer.from([]);\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n return [] as any;\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/cipher/index.ts"],"names":[],"mappings":";;;AAGA,MAAsB,aAAa;IACjC,YACS,cAAsB,EACtB,eAAuB,EACvB,eAAuB,EACvB,gBAAwB;QAH/B;;;;mBAAO,cAAc;WAAQ;QAC7B;;;;mBAAO,eAAe;WAAQ;QAC9B;;;;mBAAO,eAAe;WAAQ;QAC9B;;;;mBAAO,gBAAgB;WAAQ;IAC9B,CAAC;IAEJ,UAAU,CACR,MAAiB,EACjB,OAAe,EACf,eAAuB;QAEvB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,UAAU,CACR,UAAkB,EAClB,eAAuB,EACvB,MAAkB;QAElB,OAAO,EAAS,CAAC;IACnB,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,UAAkB;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,OAAO,EAAS,CAAC;IACnB,CAAC;CACF;AA/BD,sCA+BC","sourcesContent":["import type { RtcpHeader } from \"../../rtcp/header\";\nimport type { RtpHeader } from \"../../rtp/rtp\";\n\nexport abstract class CipherAesBase {\n constructor(\n public srtpSessionKey: Buffer,\n public srtpSessionSalt: Buffer,\n public srtcpSessionKey: Buffer,\n public srtcpSessionSalt: Buffer,\n ) {}\n\n encryptRtp(\n header: RtpHeader,\n payload: Buffer,\n rolloverCounter: number,\n ): Buffer {\n return Buffer.from([]);\n }\n\n decryptRtp(\n cipherText: Buffer,\n rolloverCounter: number,\n header?: RtpHeader,\n ): [Buffer, RtpHeader] {\n return [] as any;\n }\n\n encryptRTCP(rawRtcp: Buffer, srtcpIndex: number): Buffer {\n return Buffer.from([]);\n }\n\n decryptRTCP(encrypted: Buffer): [Buffer, RtcpHeader] {\n return [] as any;\n }\n}\n"]}
@@ -1,8 +1,9 @@
1
- import { RtpHeader } from "../../rtp/rtp";
1
+ import type { RtpHeader } from "../../rtp/rtp";
2
2
  import type { SrtpProfile } from "../const";
3
3
  import { Context } from "./context";
4
4
  export declare class SrtpContext extends Context {
5
5
  constructor(masterKey: Buffer, masterSalt: Buffer, profile: SrtpProfile);
6
6
  encryptRtp(payload: Buffer, header: RtpHeader): Buffer<ArrayBufferLike>;
7
7
  decryptRtp(cipherText: Buffer): [Buffer, RtpHeader];
8
+ private get rtpAuthTagLength();
8
9
  }
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SrtpContext = void 0;
4
- const rtp_1 = require("../../rtp/rtp");
4
+ const const_1 = require("../const");
5
+ const packet_1 = require("../packet");
5
6
  const context_1 = require("./context");
6
7
  class SrtpContext extends context_1.Context {
7
8
  constructor(masterKey, masterSalt, profile) {
@@ -14,12 +15,28 @@ class SrtpContext extends context_1.Context {
14
15
  return enc;
15
16
  }
16
17
  decryptRtp(cipherText) {
17
- const header = rtp_1.RtpHeader.deSerialize(cipherText);
18
- const s = this.getSrtpSsrcState(header.ssrc);
19
- this.updateRolloverCount(header.sequenceNumber, s);
20
- const dec = this.cipher.decryptRtp(cipherText, s.rolloverCounter);
18
+ const header = (0, packet_1.parseSrtpRtpHeader)(cipherText, this.rtpAuthTagLength);
19
+ const existingState = this.srtpSSRCStates[header.ssrc];
20
+ const nextState = existingState
21
+ ? { ...existingState }
22
+ : {
23
+ ssrc: header.ssrc,
24
+ rolloverCounter: 0,
25
+ lastSequenceNumber: 0,
26
+ };
27
+ this.updateRolloverCount(header.sequenceNumber, nextState);
28
+ const dec = this.cipher.decryptRtp(cipherText, nextState.rolloverCounter, header);
29
+ if (existingState) {
30
+ Object.assign(existingState, nextState);
31
+ }
32
+ else {
33
+ this.srtpSSRCStates[header.ssrc] = nextState;
34
+ }
21
35
  return dec;
22
36
  }
37
+ get rtpAuthTagLength() {
38
+ return this.profile === const_1.ProtectionProfileAeadAes128Gcm ? 16 : 10;
39
+ }
23
40
  }
24
41
  exports.SrtpContext = SrtpContext;
25
42
  //# sourceMappingURL=srtp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"srtp.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/context/srtp.ts"],"names":[],"mappings":";;;AAAA,uCAA0C;AAE1C,uCAAoC;AAEpC,MAAa,WAAY,SAAQ,iBAAO;IACtC,YAAY,SAAiB,EAAE,UAAkB,EAAE,OAAoB;QACrE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,OAAe,EAAE,MAAiB;QAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QACvE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,UAAU,CAAC,UAAkB;QAC3B,MAAM,MAAM,GAAG,eAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAEjD,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QAClE,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAtBD,kCAsBC","sourcesContent":["import { RtpHeader } from \"../../rtp/rtp\";\nimport type { SrtpProfile } from \"../const\";\nimport { Context } from \"./context\";\n\nexport class SrtpContext extends Context {\n constructor(masterKey: Buffer, masterSalt: Buffer, profile: SrtpProfile) {\n super(masterKey, masterSalt, profile);\n }\n\n encryptRtp(payload: Buffer, header: RtpHeader) {\n const s = this.getSrtpSsrcState(header.ssrc);\n this.updateRolloverCount(header.sequenceNumber, s);\n\n const enc = this.cipher.encryptRtp(header, payload, s.rolloverCounter);\n return enc;\n }\n\n decryptRtp(cipherText: Buffer): [Buffer, RtpHeader] {\n const header = RtpHeader.deSerialize(cipherText);\n\n const s = this.getSrtpSsrcState(header.ssrc);\n this.updateRolloverCount(header.sequenceNumber, s);\n\n const dec = this.cipher.decryptRtp(cipherText, s.rolloverCounter);\n return dec;\n }\n}\n"]}
1
+ {"version":3,"file":"srtp.js","sourceRoot":"","sources":["../../../../../../rtp/src/srtp/context/srtp.ts"],"names":[],"mappings":";;;AACA,oCAA0D;AAE1D,sCAA+C;AAC/C,uCAAoC;AAEpC,MAAa,WAAY,SAAQ,iBAAO;IACtC,YAAY,SAAiB,EAAE,UAAkB,EAAE,OAAoB;QACrE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,OAAe,EAAE,MAAiB;QAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QACvE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,UAAU,CAAC,UAAkB;QAC3B,MAAM,MAAM,GAAG,IAAA,2BAAkB,EAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAErE,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,aAAa;YAC7B,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE;YACtB,CAAC,CAAC;gBACE,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,eAAe,EAAE,CAAC;gBAClB,kBAAkB,EAAE,CAAC;aACtB,CAAC;QACN,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QAE3D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAChC,UAAU,EACV,SAAS,CAAC,eAAe,EACzB,MAAM,CACP,CAAC;QACF,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAY,gBAAgB;QAC1B,OAAO,IAAI,CAAC,OAAO,KAAK,sCAA8B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC;CACF;AA1CD,kCA0CC","sourcesContent":["import type { RtpHeader } from \"../../rtp/rtp\";\nimport { ProtectionProfileAeadAes128Gcm } from \"../const\";\nimport type { SrtpProfile } from \"../const\";\nimport { parseSrtpRtpHeader } from \"../packet\";\nimport { Context } from \"./context\";\n\nexport class SrtpContext extends Context {\n constructor(masterKey: Buffer, masterSalt: Buffer, profile: SrtpProfile) {\n super(masterKey, masterSalt, profile);\n }\n\n encryptRtp(payload: Buffer, header: RtpHeader) {\n const s = this.getSrtpSsrcState(header.ssrc);\n this.updateRolloverCount(header.sequenceNumber, s);\n\n const enc = this.cipher.encryptRtp(header, payload, s.rolloverCounter);\n return enc;\n }\n\n decryptRtp(cipherText: Buffer): [Buffer, RtpHeader] {\n const header = parseSrtpRtpHeader(cipherText, this.rtpAuthTagLength);\n\n const existingState = this.srtpSSRCStates[header.ssrc];\n const nextState = existingState\n ? { ...existingState }\n : {\n ssrc: header.ssrc,\n rolloverCounter: 0,\n lastSequenceNumber: 0,\n };\n this.updateRolloverCount(header.sequenceNumber, nextState);\n\n const dec = this.cipher.decryptRtp(\n cipherText,\n nextState.rolloverCounter,\n header,\n );\n if (existingState) {\n Object.assign(existingState, nextState);\n } else {\n this.srtpSSRCStates[header.ssrc] = nextState;\n }\n return dec;\n }\n\n private get rtpAuthTagLength() {\n return this.profile === ProtectionProfileAeadAes128Gcm ? 16 : 10;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare class SrtpAuthenticationError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SrtpAuthenticationError = void 0;
4
+ class SrtpAuthenticationError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "SrtpAuthenticationError";
8
+ }
9
+ }
10
+ exports.SrtpAuthenticationError = SrtpAuthenticationError;
11
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../../../rtp/src/srtp/error.ts"],"names":[],"mappings":";;;AAAA,MAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AALD,0DAKC","sourcesContent":["export class SrtpAuthenticationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SrtpAuthenticationError\";\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { RtcpHeader } from "../rtcp/header";
2
+ import { RtpHeader } from "../rtp/rtp";
3
+ export declare function parseSrtpRtpHeader(packet: Buffer, authTagLength: number, message?: string): RtpHeader;
4
+ export declare function parseSrtcpHeader(packet: Buffer, authTagLength: number, srtcpIndexSize: number, message?: string): RtcpHeader;
5
+ export declare function finalizeSrtpRtpHeader(header: RtpHeader, packet: Buffer, message?: string): RtpHeader;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSrtpRtpHeader = parseSrtpRtpHeader;
4
+ exports.parseSrtcpHeader = parseSrtcpHeader;
5
+ exports.finalizeSrtpRtpHeader = finalizeSrtpRtpHeader;
6
+ const header_1 = require("../rtcp/header");
7
+ const rtp_1 = require("../rtp/rtp");
8
+ const error_1 = require("./error");
9
+ const minRtpHeaderSize = 12;
10
+ const minRtcpPacketSize = 8;
11
+ function parseSrtpRtpHeader(packet, authTagLength, message = "Failed to authenticate SRTP packet") {
12
+ const authTagOffset = packet.length - authTagLength;
13
+ assertAuthenticatedPacketLength(packet.length >= minRtpHeaderSize + authTagLength, message);
14
+ const header = wrapAuthenticationError(() => rtp_1.RtpHeader.deSerialize(packet.subarray(0, authTagOffset)), message);
15
+ header.paddingSize = 0;
16
+ assertAuthenticatedPacketLength(header.payloadOffset >= minRtpHeaderSize &&
17
+ header.payloadOffset <= authTagOffset, message);
18
+ return header;
19
+ }
20
+ function parseSrtcpHeader(packet, authTagLength, srtcpIndexSize, message = "Failed to authenticate SRTCP packet") {
21
+ assertAuthenticatedPacketLength(packet.length >= minRtcpPacketSize + authTagLength + srtcpIndexSize, message);
22
+ return wrapAuthenticationError(() => header_1.RtcpHeader.deSerialize(packet.subarray(0, header_1.RTCP_HEADER_SIZE)), message);
23
+ }
24
+ function assertAuthenticatedPacketLength(condition, message) {
25
+ if (!condition) {
26
+ throw new error_1.SrtpAuthenticationError(message);
27
+ }
28
+ }
29
+ function wrapAuthenticationError(parse, message) {
30
+ try {
31
+ return parse();
32
+ }
33
+ catch {
34
+ throw new error_1.SrtpAuthenticationError(message);
35
+ }
36
+ }
37
+ function finalizeSrtpRtpHeader(header, packet, message = "Failed to authenticate SRTP packet") {
38
+ if (!header.padding) {
39
+ header.paddingSize = 0;
40
+ return header;
41
+ }
42
+ assertAuthenticatedPacketLength(packet.length > header.payloadOffset, message);
43
+ const paddingSize = packet[packet.length - 1];
44
+ assertAuthenticatedPacketLength(paddingSize > 0 && paddingSize <= packet.length - header.payloadOffset, message);
45
+ header.paddingSize = paddingSize;
46
+ return header;
47
+ }
48
+ //# sourceMappingURL=packet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packet.js","sourceRoot":"","sources":["../../../../../rtp/src/srtp/packet.ts"],"names":[],"mappings":";;AAOA,gDAwBC;AAED,4CAeC;AAgBD,sDAuBC;AAvFD,2CAA8D;AAC9D,oCAAuC;AACvC,mCAAkD;AAElD,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,SAAgB,kBAAkB,CAChC,MAAc,EACd,aAAqB,EACrB,OAAO,GAAG,oCAAoC;IAE9C,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC;IACpD,+BAA+B,CAC7B,MAAM,CAAC,MAAM,IAAI,gBAAgB,GAAG,aAAa,EACjD,OAAO,CACR,CAAC;IAEF,MAAM,MAAM,GAAG,uBAAuB,CACpC,GAAG,EAAE,CAAC,eAAS,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAC9D,OAAO,CACR,CAAC;IACF,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;IAEvB,+BAA+B,CAC7B,MAAM,CAAC,aAAa,IAAI,gBAAgB;QACtC,MAAM,CAAC,aAAa,IAAI,aAAa,EACvC,OAAO,CACR,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,gBAAgB,CAC9B,MAAc,EACd,aAAqB,EACrB,cAAsB,EACtB,OAAO,GAAG,qCAAqC;IAE/C,+BAA+B,CAC7B,MAAM,CAAC,MAAM,IAAI,iBAAiB,GAAG,aAAa,GAAG,cAAc,EACnE,OAAO,CACR,CAAC;IAEF,OAAO,uBAAuB,CAC5B,GAAG,EAAE,CAAC,mBAAU,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,yBAAgB,CAAC,CAAC,EAClE,OAAO,CACR,CAAC;AACJ,CAAC;AAED,SAAS,+BAA+B,CAAC,SAAkB,EAAE,OAAe;IAC1E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,+BAAuB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAI,KAAc,EAAE,OAAe;IACjE,IAAI,CAAC;QACH,OAAO,KAAK,EAAE,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,+BAAuB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAgB,qBAAqB,CACnC,MAAiB,EACjB,MAAc,EACd,OAAO,GAAG,oCAAoC;IAE9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+BAA+B,CAC7B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa,EACpC,OAAO,CACR,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9C,+BAA+B,CAC7B,WAAW,GAAG,CAAC,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa,EACtE,OAAO,CACR,CAAC;IAEF,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { RTCP_HEADER_SIZE, RtcpHeader } from \"../rtcp/header\";\nimport { RtpHeader } from \"../rtp/rtp\";\nimport { SrtpAuthenticationError } from \"./error\";\n\nconst minRtpHeaderSize = 12;\nconst minRtcpPacketSize = 8;\n\nexport function parseSrtpRtpHeader(\n packet: Buffer,\n authTagLength: number,\n message = \"Failed to authenticate SRTP packet\",\n) {\n const authTagOffset = packet.length - authTagLength;\n assertAuthenticatedPacketLength(\n packet.length >= minRtpHeaderSize + authTagLength,\n message,\n );\n\n const header = wrapAuthenticationError(\n () => RtpHeader.deSerialize(packet.subarray(0, authTagOffset)),\n message,\n );\n header.paddingSize = 0;\n\n assertAuthenticatedPacketLength(\n header.payloadOffset >= minRtpHeaderSize &&\n header.payloadOffset <= authTagOffset,\n message,\n );\n\n return header;\n}\n\nexport function parseSrtcpHeader(\n packet: Buffer,\n authTagLength: number,\n srtcpIndexSize: number,\n message = \"Failed to authenticate SRTCP packet\",\n) {\n assertAuthenticatedPacketLength(\n packet.length >= minRtcpPacketSize + authTagLength + srtcpIndexSize,\n message,\n );\n\n return wrapAuthenticationError(\n () => RtcpHeader.deSerialize(packet.subarray(0, RTCP_HEADER_SIZE)),\n message,\n );\n}\n\nfunction assertAuthenticatedPacketLength(condition: boolean, message: string) {\n if (!condition) {\n throw new SrtpAuthenticationError(message);\n }\n}\n\nfunction wrapAuthenticationError<T>(parse: () => T, message: string) {\n try {\n return parse();\n } catch {\n throw new SrtpAuthenticationError(message);\n }\n}\n\nexport function finalizeSrtpRtpHeader(\n header: RtpHeader,\n packet: Buffer,\n message = \"Failed to authenticate SRTP packet\",\n) {\n if (!header.padding) {\n header.paddingSize = 0;\n return header;\n }\n\n assertAuthenticatedPacketLength(\n packet.length > header.payloadOffset,\n message,\n );\n\n const paddingSize = packet[packet.length - 1];\n assertAuthenticatedPacketLength(\n paddingSize > 0 && paddingSize <= packet.length - header.payloadOffset,\n message,\n );\n\n header.paddingSize = paddingSize;\n return header;\n}\n"]}
@@ -8,10 +8,12 @@ export interface DataChannelStats {
8
8
  messagesReceived: number;
9
9
  bytesReceived: number;
10
10
  }
11
+ export declare function getDataChannelMessageSize(data: Buffer | string): number;
11
12
  export declare class RTCDataChannel extends EventTarget implements DataChannelStats {
12
13
  readonly sctp: RTCSctpTransport;
13
14
  private readonly parameters;
14
15
  readonly sendOpen: boolean;
16
+ readonly statsId: string;
15
17
  readonly stateChange: Event<[DCState]>;
16
18
  readonly stateChanged: Event<[DCState]>;
17
19
  readonly onMessage: Event<[string | Buffer<ArrayBufferLike>]>;
@@ -33,8 +35,8 @@ export declare class RTCDataChannel extends EventTarget implements DataChannelSt
33
35
  bytesReceived: number;
34
36
  constructor(sctp: RTCSctpTransport, parameters: RTCDataChannelParameters, sendOpen?: boolean);
35
37
  get ordered(): boolean;
36
- get maxRetransmits(): number | undefined;
37
- get maxPacketLifeTime(): number | undefined;
38
+ get maxRetransmits(): number | null;
39
+ get maxPacketLifeTime(): number | null;
38
40
  get label(): string;
39
41
  get protocol(): string;
40
42
  get negotiated(): boolean;
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RTCDataChannelParameters = exports.RTCDataChannel = void 0;
4
+ exports.getDataChannelMessageSize = getDataChannelMessageSize;
5
+ const crypto_1 = require("crypto");
4
6
  const common_1 = require("./imports/common");
5
7
  const helper_1 = require("./helper");
6
8
  const log = (0, common_1.debug)("werift:packages/webrtc/src/dataChannel.ts");
9
+ function getDataChannelMessageSize(data) {
10
+ return Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
11
+ }
7
12
  class RTCDataChannel extends helper_1.EventTarget {
8
13
  constructor(sctp, parameters, sendOpen = true) {
9
14
  super();
@@ -25,6 +30,12 @@ class RTCDataChannel extends helper_1.EventTarget {
25
30
  writable: true,
26
31
  value: sendOpen
27
32
  });
33
+ Object.defineProperty(this, "statsId", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: (0, crypto_1.randomUUID)().toString()
38
+ });
28
39
  Object.defineProperty(this, "stateChange", {
29
40
  enumerable: true,
30
41
  configurable: true,
@@ -160,10 +171,10 @@ class RTCDataChannel extends helper_1.EventTarget {
160
171
  return this.parameters.ordered;
161
172
  }
162
173
  get maxRetransmits() {
163
- return this.parameters.maxRetransmits;
174
+ return this.parameters.maxRetransmits ?? null;
164
175
  }
165
176
  get maxPacketLifeTime() {
166
- return this.parameters.maxPacketLifeTime;
177
+ return this.parameters.maxPacketLifeTime ?? null;
167
178
  }
168
179
  get label() {
169
180
  return this.parameters.label;
@@ -220,10 +231,9 @@ class RTCDataChannel extends helper_1.EventTarget {
220
231
  }
221
232
  }
222
233
  send(data) {
223
- const size = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
234
+ const size = this.sctp.datachannelSend(this, data);
224
235
  this.messagesSent++;
225
236
  this.bytesSent += size;
226
- this.sctp.datachannelSend(this, data);
227
237
  }
228
238
  close() {
229
239
  this.sctp.dataChannelClose(this);