public void EncodeToBytes() { byte[] digest = new byte[] { 0xfd, 0x49, 0x5a, 0x92, 0xb5, 0x9f, 0x59, 0x67, 0x33, 0xce, 0xcf, 0xf4, 0x45, 0xb7, 0xa5, 0x88, 0x04, 0x8a, 0x39, 0x05, }; var attr = new MessageIntegrity(digest); Assert.Equal( new byte[] { 0x00, 0x08, 0x00, 0x14, 0xfd, 0x49, 0x5a, 0x92, 0xb5, 0x9f, 0x59, 0x67, 0x33, 0xce, 0xcf, 0xf4, 0x45, 0xb7, 0xa5, 0x88, 0x04, 0x8a, 0x39, 0x05, }, attr.ToByteArray()); }
public byte[] Encode(IStunContext ctx) { bool useMessageIntegrity = !string.IsNullOrEmpty(ctx?.Username) && !string.IsNullOrEmpty(ctx?.Password) && !string.IsNullOrEmpty(ctx?.Realm); var c = (ushort)Class; var m = (ushort)Method; int type = (m & 0x0f80) << 2 | (m & 0x0070) << 1 | (m & 0x000f) << 0 | (c & 0x2) << 7 | (c & 0x1) << 4; using (var ms = new MemoryStream()) { List <Attribute> attrs = Attributes.ToList(); if (!string.IsNullOrEmpty(ctx?.Username)) { attrs.Add(new Username(ctx.Username)); } if (ctx?.Nonce != null) { attrs.Add(new Attributes.Nonce(ctx.Nonce)); } if (!string.IsNullOrEmpty(ctx?.Realm)) { attrs.Add(new Realm(ctx.Realm)); } byte[] encodedAttrs; using (var ams = new MemoryStream()) { foreach (Attribute attr in attrs) { byte[] asBytes = attr.ToByteArray(TransactionId); ams.Write(asBytes, 0, asBytes.Length); } encodedAttrs = ams.ToArray(); } // 8 bytes for Fingerprint var messageLength = (ushort)(encodedAttrs.Length + FingerprintBytes); if (useMessageIntegrity) { messageLength += MessageIntegrityBytes; } ms.Write(((ushort)type).ToBytes(), 0, 2); ms.Write(messageLength.ToBytes(), 0, 2); ms.Write(MagicCookie, 0, MagicCookie.Length); ms.Write(TransactionId, 0, TransactionId.Length); ms.Write(encodedAttrs, 0, encodedAttrs.Length); if (useMessageIntegrity) { var lengthWithoutFingerprint = (ushort)(messageLength - FingerprintBytes); byte[] toCalc = ms.ToArray(); lengthWithoutFingerprint.ToBytes().CopyTo(toCalc, 2); MessageIntegrity mi = MessageIntegrity.Calculate( ctx?.Username, ctx?.Password, ctx?.Realm, toCalc); ms.Write(mi.ToByteArray(), 0, MessageIntegrityBytes); } Fingerprint fingerprint = Fingerprint.FromMessage( ms.ToArray() ); ms.Write(fingerprint.ToByteArray(), 0, FingerprintBytes); return(ms.ToArray()); } }