Example #1
0
        /// <summary>
        /// Add the MESSAGE-INTEGRITY attribute to the message.
        /// This should be fired just before a call to StunClient.SendMessage as it needs existing
        /// attribute to be computed. But these attributes MUST be added before the MESSAGE-ATTRIBUTE
        /// except for FINGERPRINT attribute which MUST be added at the end of the StunMessage
        /// and also used in the MESSAGE-INTEGRITY computation
        /// </summary>
        /// <param name="password">The password used to authenticate the StunMessage</param>
        /// <param name="useLongTermCredentials">True if this StunMessage should authenticate using longterm credentials</param>
        public void AddMessageIntegrity(String password, Boolean useLongTermCredentials)
        {
            password = new SASLprep().Prepare(password);

            byte[] hmacSha1Key;

            if (useLongTermCredentials)
            {
                if (this.Stun.Username == null)
                    throw new ArgumentException("USERNAME attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Username");

                if (this.Stun.Realm == null)
                    throw new ArgumentException("REALM attribute is mandatory for long-term credentials MESSAGE-INTEGRITY creation", "this.Realm");

                using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                {
                    String valueToHashMD5 = String.Format(CultureInfo.CurrentCulture,
                                                          "{0}:{1}:{2}",
                                                          this.Stun.Username.ValueString,
                                                          this.Stun.Realm.ValueString,
                                                          password);

                    hmacSha1Key = md5.ComputeHash(StunMessage.Encoder.GetBytes(valueToHashMD5));
                }
            }
            else
            {
                hmacSha1Key = StunMessage.Encoder.GetBytes(password);
            }

            StunAttribute messageIntegrity = new StunAttribute(StunAttributeType.MessageIntegrity,
                                                               this.ComputeHMAC(hmacSha1Key));
            this.SetAttribute(messageIntegrity);
        }
Example #2
0
        /// <summary>
        /// Constructs a new StunAttribute
        /// </summary>
        /// <param name="type">The type of this StunAttribute</param>
        /// <param name="typeBytes">The value of the type of this StunAttribute in bytes</param>
        /// <param name="value">The value of this StunAttribute</param>
        public StunAttribute(StunAttributeType type, byte[] typeBytes, byte[] value)
        {
            if (typeBytes == null)
                throw new ArgumentNullException("value", "Cannot be null");

            if (value == null)
                throw new ArgumentNullException("value", "Cannot be null");

            switch (type)
            {
                case StunAttributeType.Software:
                case StunAttributeType.Realm:
                case StunAttributeType.Nonce:
                case StunAttributeType.ErrorCode:
                    if (value.Length > 763)
                        throw new ArgumentOutOfRangeException("value", "Cannot be greater than 763 bytes for the given type as described in RFC 5389");
                    break;

                case StunAttributeType.Username:
                    if (value.Length > 513)
                        throw new ArgumentOutOfRangeException("value", "Cannot be greater than 513 bytes for the given type as described in RFC 5389");
                    break;
            }

            switch (type)
            {
                case StunAttributeType.Realm:
                case StunAttributeType.Username:
                    String saslPrepValue = new SASLprep().Prepare(StunMessage.Encoder.GetString(value));

                    value = StunMessage.Encoder.GetBytes(saslPrepValue);
                    break;
            }

            this.TypeBytes = typeBytes;
            this.Type = type;
            this.Value = value;
        }