public class MessageIntegrityAttribute extends Attribute implements ContentDependentAttribute
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.
Modifier and Type | Field and Description |
---|---|
static char |
DATA_LENGTH
The HMAC-SHA1 algorithm.
|
static String |
HMAC_SHA1_ALGORITHM
The HMAC-SHA1 algorithm.
|
private byte[] |
hmacSha1Content
The actual content of the message
|
private static Logger |
logger
The Logger used by the Message class and its instances
for logging output.
|
private String |
media
The media name if we use short-term authentication.
|
static String |
NAME
Attribute name.
|
private String |
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. |
ALTERNATE_SERVER, attributeType, CHANGE_REQUEST, CHANGED_ADDRESS, CHANNEL_NUMBER, CONNECTION_ID, DATA, DESTINATION_ADDRESS, DONT_FRAGMENT, ERROR_CODE, EVEN_PORT, FINGERPRINT, HEADER_LENGTH, ICE_CONTROLLED, ICE_CONTROLLING, LIFETIME, MAGIC_COOKIE, MAPPED_ADDRESS, MESSAGE_INTEGRITY, NONCE, PASSWORD, PRIORITY, REALM, REFLECTED_FROM, REMOTE_ADDRESS, REQUESTED_ADDRESS_FAMILY, REQUESTED_TRANSPORT, RESERVATION_TOKEN, RESPONSE_ADDRESS, SOFTWARE, SOURCE_ADDRESS, UNKNOWN_ATTRIBUTES, UNKNOWN_OPTIONAL_ATTRIBUTE, USE_CANDIDATE, USERNAME, XOR_MAPPED_ADDRESS, XOR_ONLY, XOR_PEER_ADDRESS, XOR_RELAYED_ADDRESS
Modifier | Constructor and Description |
---|---|
protected |
MessageIntegrityAttribute()
Creates a MessageIntegrityAttribute.
|
Modifier and Type | Method and Description |
---|---|
static byte[] |
calculateHmacSha1(byte[] message,
int offset,
int length,
byte[] key)
Encodes message using key and the HMAC-SHA1 algorithm
as per RFC 2104 and returns the resulting byte array.
|
void |
decodeAttributeBody(byte[] attributeValue,
char offset,
char length)
Sets this attribute's fields according to the message and attributeValue
arrays.
|
byte[] |
encode()
Returns a binary representation of this attribute.
|
byte[] |
encode(StunStack stunStack,
byte[] content,
int offset,
int length)
Returns a binary representation of this attribute.
|
boolean |
equals(Object obj)
Compares two MessageIntegrityAttributes.
|
char |
getDataLength()
Returns the length of this attribute's body.
|
byte[] |
getHmacSha1Content()
Returns the HMAC-SHA1 value stored in this attribute.
|
String |
getName()
Returns the human readable name of this attribute.
|
void |
setMedia(String media)
Sets the media name that we should use to get the corresponding remote
key (short-term authentication only).
|
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. |
getAttributeType, getLocationInMessage, setAttributeType, setLocationInMessage
private static final Logger logger
public static final String NAME
public static final String HMAC_SHA1_ALGORITHM
public static final char DATA_LENGTH
private byte[] hmacSha1Content
private String username
encode()
method should use when
creating the content of this message.private String media
protected MessageIntegrityAttribute()
public void setUsername(String username)
encode()
method should use when
creating the content of this message.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.public void setMedia(String media)
media
- namepublic byte[] getHmacSha1Content()
public static byte[] calculateHmacSha1(byte[] message, int offset, int length, byte[] key) throws IllegalArgumentException
MessageIntegrityAttribute
regardless of the credentials being used (short or long term).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).IllegalArgumentException
- if the encoding fails for some reason.public void decodeAttributeBody(byte[] attributeValue, char offset, char length)
decodeAttributeBody
in class Attribute
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.
the start of this attribute.public byte[] encode() throws UnsupportedOperationException
encode
in class Attribute
UnsupportedOperationException
- since ContentDependentAttribute
s should be encoded through the content
dependent encode method.public byte[] encode(StunStack stunStack, byte[] content, int offset, int length)
encode
in interface ContentDependentAttribute
stunStack
- the StunStack in the context of which the
request to encode this ContentDependentAttribute is being madecontent
- the content of the message that this attribute will be
transported inoffset
- the content-related offset where the actual
content starts.length
- the length of the content in the content array.public char getDataLength()
getDataLength
in class Attribute
public String getName()
public boolean equals(Object obj)
Copyright © 2018. All rights reserved.