public ToByteBuffer ( byte buffer, int startIndex ) : int | ||
buffer | byte | |
startIndex | int | |
return | int |
public byte[] ToByteBuffer(byte[] messageIntegrityKey, bool addFingerprint) { UInt16 attributesLength = 0; foreach (STUNv2Attribute attribute in Attributes) { attributesLength += Convert.ToUInt16(STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + attribute.PaddedLength); } if (messageIntegrityKey != null) { attributesLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH; } int messageLength = STUNv2Header.STUN_HEADER_LENGTH + attributesLength; byte[] buffer = new byte[messageLength]; if (BitConverter.IsLittleEndian) { Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian((UInt16)Header.MessageType)), 0, buffer, 0, 2); Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian(attributesLength)), 0, buffer, 2, 2); Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(STUNv2Header.MAGIC_COOKIE)), 0, buffer, 4, 4); } else { Buffer.BlockCopy(BitConverter.GetBytes((UInt16)Header.MessageType), 0, buffer, 0, 2); Buffer.BlockCopy(BitConverter.GetBytes(attributesLength), 0, buffer, 2, 2); Buffer.BlockCopy(BitConverter.GetBytes(STUNv2Header.MAGIC_COOKIE), 0, buffer, 4, 4); } Buffer.BlockCopy(Header.TransactionId, 0, buffer, 8, STUNv2Header.TRANSACTION_ID_LENGTH); int attributeIndex = 20; foreach (STUNv2Attribute attr in Attributes) { attributeIndex += attr.ToByteBuffer(buffer, attributeIndex); } //logger.LogDebug($"Pre HMAC STUN message: {ByteBufferInfo.HexStr(buffer, attributeIndex)}"); if (messageIntegrityKey != null) { var integrityAttibtue = new STUNv2Attribute(STUNv2AttributeTypesEnum.MessageIntegrity, new byte[MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH]); HMACSHA1 hmacSHA = new HMACSHA1(messageIntegrityKey, true); byte[] hmac = hmacSHA.ComputeHash(buffer, 0, attributeIndex); integrityAttibtue.Value = hmac; attributeIndex += integrityAttibtue.ToByteBuffer(buffer, attributeIndex); } if (addFingerprint) { // The fingerprint attribute length has not been included in the length in the STUN header so adjust it now. attributesLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + FINGERPRINT_ATTRIBUTE_CRC32_LENGTH; messageLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + FINGERPRINT_ATTRIBUTE_CRC32_LENGTH; if (BitConverter.IsLittleEndian) { Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian(attributesLength)), 0, buffer, 2, 2); } else { Buffer.BlockCopy(BitConverter.GetBytes(attributesLength), 0, buffer, 2, 2); } var fingerprintAttribute = new STUNv2Attribute(STUNv2AttributeTypesEnum.FingerPrint, new byte[FINGERPRINT_ATTRIBUTE_CRC32_LENGTH]); uint crc = Crc32.Compute(buffer) ^ FINGERPRINT_XOR; byte[] fingerPrint = (BitConverter.IsLittleEndian) ? BitConverter.GetBytes(NetConvert.DoReverseEndian(crc)) : BitConverter.GetBytes(crc); fingerprintAttribute.Value = fingerPrint; Array.Resize(ref buffer, messageLength); fingerprintAttribute.ToByteBuffer(buffer, attributeIndex); } return(buffer); }
public byte[] ToByteBuffer(string messageIntegrityKey, bool addFingerprint) { UInt16 attributesLength = 0; foreach (STUNv2Attribute attribute in Attributes) { attributesLength += Convert.ToUInt16(STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + attribute.PaddedLength); } if(messageIntegrityKey.NotNullOrBlank()) { attributesLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH; } int messageLength = STUNv2Header.STUN_HEADER_LENGTH + attributesLength; byte[] buffer = new byte[messageLength]; if (BitConverter.IsLittleEndian) { Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian((UInt16)Header.MessageType)), 0, buffer, 0, 2); Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian(attributesLength)), 0, buffer, 2, 2); Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(STUNv2Header.MAGIC_COOKIE)), 0, buffer, 4, 4); } else { Buffer.BlockCopy(BitConverter.GetBytes((UInt16)Header.MessageType), 0, buffer, 0, 2); Buffer.BlockCopy(BitConverter.GetBytes(attributesLength), 0, buffer, 2, 2); Buffer.BlockCopy(BitConverter.GetBytes(STUNv2Header.MAGIC_COOKIE), 0, buffer, 4, 4); } Buffer.BlockCopy(Header.TransactionId, 0, buffer, 8, STUNv2Header.TRANSACTION_ID_LENGTH); int attributeIndex = 20; foreach (STUNv2Attribute attr in Attributes) { attributeIndex += attr.ToByteBuffer(buffer, attributeIndex); } if (messageIntegrityKey.NotNullOrBlank()) { var integrityAttibtue = new STUNv2Attribute(STUNv2AttributeTypesEnum.MessageIntegrity, new byte[MESSAGE_INTEGRITY_ATTRIBUTE_HMAC_LENGTH]); HMACSHA1 hmacSHA = new HMACSHA1(System.Text.Encoding.UTF8.GetBytes(messageIntegrityKey), true); byte[] hmac = hmacSHA.ComputeHash(buffer, 0, attributeIndex); integrityAttibtue.Value = hmac; attributeIndex += integrityAttibtue.ToByteBuffer(buffer, attributeIndex); } if (addFingerprint) { // The fingerprint attribute length has not been included in the length in the STUN header so adjust it now. attributesLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + FINGERPRINT_ATTRIBUTE_CRC32_LENGTH; messageLength += STUNv2Attribute.STUNATTRIBUTE_HEADER_LENGTH + FINGERPRINT_ATTRIBUTE_CRC32_LENGTH; if (BitConverter.IsLittleEndian) { Buffer.BlockCopy(BitConverter.GetBytes(Utility.ReverseEndian(attributesLength)), 0, buffer, 2, 2); } else { Buffer.BlockCopy(BitConverter.GetBytes(attributesLength), 0, buffer, 2, 2); } var fingerprintAttribute = new STUNv2Attribute(STUNv2AttributeTypesEnum.FingerPrint, new byte[FINGERPRINT_ATTRIBUTE_CRC32_LENGTH]); uint crc = Crc32.Compute(buffer) ^ FINGERPRINT_XOR; byte[] fingerPrint = (BitConverter.IsLittleEndian) ? BitConverter.GetBytes(NetConvert.DoReverseEndian(crc)) : BitConverter.GetBytes(crc); fingerprintAttribute.Value = fingerPrint; Array.Resize(ref buffer, messageLength); fingerprintAttribute.ToByteBuffer(buffer, attributeIndex); } return buffer; }