Package 

Class MessageIntegrityAttribute

  • All Implemented Interfaces:
    org.ice4j.attribute.ContentDependentAttribute

    
    public class MessageIntegrityAttribute
    extends Attribute implements ContentDependentAttribute
                        

    The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message. The MESSAGE-INTEGRITY attribute can be present in any STUN message type. Since it uses the SHA1 hash, the HMAC will be 20 bytes. The text used as input to HMAC is the STUN message, including the header, up to and including the attribute preceding the MESSAGE-INTEGRITY attribute. With the exception of the FINGERPRINT attribute, which appears after MESSAGE-INTEGRITY, agents MUST ignore all other attributes that follow MESSAGE-INTEGRITY. The key for the HMAC depends on whether long-term or short-term credentials are in use. For long-term credentials, the key is 16 bytes:

             key = MD5(username ":" realm ":" SASLprep(password))
    
    That is, the 16-byte key is formed by taking the MD5 hash of the result of concatenating the following five fields: (1) the username, with any quotes and trailing nulls removed, as taken from the USERNAME attribute (in which case SASLprep has already been applied); (2) a single colon; (3) the realm, with any quotes and trailing nulls removed; (4) a single colon; and (5) the password, with any trailing nulls removed and after processing using SASLprep. For example, if the username was 'user', the realm was 'realm', and the password was 'pass', then the 16-byte HMAC key would be the result of performing an MD5 hash on the string 'user:realm:pass', the resulting hash being 0x8493fbc53ba582fb4c044c456bdc40eb.

    For short-term credentials:

                           key = SASLprep(password)
    
    where MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined in RFC 4013 [RFC4013].

    The structure of the key when used with long-term credentials facilitates deployment in systems that also utilize SIP. Typically, SIP systems utilizing SIP's digest authentication mechanism do not actually store the password in the database. Rather, they store a value called H(A1), which is equal to the key defined above.

    Based on the rules above, the hash used to construct MESSAGE- INTEGRITY includes the length field from the STUN message header. Prior to performing the hash, the MESSAGE-INTEGRITY attribute MUST be inserted into the message (with dummy content). The length MUST then be set to point to the length of the message up to, and including, the MESSAGE-INTEGRITY attribute itself, but excluding any attributes after it. Once the computation is performed, the value of the MESSAGE-INTEGRITY attribute can be filled in, and the value of the length in the STUN header can be set to its correct value -- the length of the entire message. Similarly, when validating the MESSAGE-INTEGRITY, the length field should be adjusted to point to the end of the MESSAGE-INTEGRITY attribute prior to calculating the HMAC. Such adjustment is necessary when attributes, such as FINGERPRINT, appear after MESSAGE-INTEGRITY.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
    • Constructor Summary

      Constructors 
      Constructor Description
    • Enum Constant Summary

      Enum Constants 
      Enum Constant Description
    • Method Summary

      Modifier and Type Method Description
      Array<byte> getHmacSha1Content() Returns the HMAC-SHA1 value stored in this attribute.
      void setUsername(String username) Sets the username that we should use to obtain an encryption key (password) that the encode method should use when creating the content of this message.
      void setMedia(String media) Sets the media name that we should use to get the corresponding remote key (short-term authentication only).
      static Array<byte> calculateHmacSha1(Array<byte> message, int offset, int length, Array<byte> key) Encodes message using key and the HMAC-SHA1 algorithm as per RFC 2104 and returns the resulting byte array.
      void decodeAttributeBody(Array<byte> attributeValue, char offset, char length) Sets this attribute's fields according to the message and attributeValue arrays.
      Array<byte> encode() Returns a binary representation of this attribute.
      Array<byte> encode(StunStack stunStack, Array<byte> content, int offset, int length) Returns a binary representation of this attribute.
      char getDataLength() Returns the length of this attribute's body.
      String getName() Returns the human readable name of this attribute.
      boolean equals(Object obj) Compares two MessageIntegrityAttributes.
      • Methods inherited from class org.ice4j.attribute.Attribute

        getAttributeType, getLocationInMessage, setLocationInMessage
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

    • Method Detail

      • setUsername

         void setUsername(String username)

        Sets the username that we should use to obtain an encryption key (password) that the encode method should use when creating the content of this message.

        Parameters:
        username - the username that we should use to obtain an encryption key (password) that the encode method should use when creating the content of this message.
      • setMedia

         void setMedia(String media)

        Sets the media name that we should use to get the corresponding remote key (short-term authentication only).

        Parameters:
        media - name
      • calculateHmacSha1

         static Array<byte> calculateHmacSha1(Array<byte> message, int offset, int length, Array<byte> key)

        Encodes message using key and the HMAC-SHA1 algorithm as per RFC 2104 and returns the resulting byte array. This is a utility method that generates content for the MessageIntegrityAttribute regardless of the credentials being used (short or long term).

        Parameters:
        message - the STUN message that the resulting content will need to travel in.
        offset - the index where data starts in message.
        length - the length of the data in message that the method should consider.
        key - the key that we should be using for the encoding (which depends on whether we are using short or long term credentials).
      • decodeAttributeBody

         void decodeAttributeBody(Array<byte> attributeValue, char offset, char length)

        Sets this attribute's fields according to the message and attributeValue arrays.

        Parameters:
        attributeValue - a binary array containing this attribute's field values and NOT containing the attribute header.
        offset - the position where attribute values begin (most often offset is equal to the index of the first byte after length)
        length - the length of the binary array.
      • encode

         Array<byte> encode()

        Returns a binary representation of this attribute.

      • encode

         Array<byte> encode(StunStack stunStack, Array<byte> content, int offset, int length)

        Returns a binary representation of this attribute.

        Parameters:
        stunStack - the StunStack in the context of which the request to encode this ContentDependentAttribute is being made
        content - the content of the message that this attribute will be transported in
        offset - the content-related offset where the actual content starts.
        length - the length of the content in the content array.
      • getDataLength

         char getDataLength()

        Returns the length of this attribute's body.

      • getName

         String getName()

        Returns the human readable name of this attribute.

      • equals

         boolean equals(Object obj)

        Compares two MessageIntegrityAttributes. Two attributes are considered equal when they have the same type length and value.

        Parameters:
        obj - the object to compare this attribute with.