gnu.java.zrtp.packets.ZrtpPacketSASRelay Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zrtp4j-light Show documentation
Show all versions of zrtp4j-light Show documentation
ZRTP for Java library, Jitsi fork without embedded ciphers
/*
* Copyright (C) 2006-2011 Werner Dittmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authors: Werner Dittmann
*/
package gnu.java.zrtp.packets;
import gnu.java.zrtp.ZrtpConstants;
import gnu.java.zrtp.utils.ZrtpUtils;
/**
* @author Werner Dittmann <[email protected]>
*
*/
public class ZrtpPacketSASRelay extends ZrtpPacketBase {
/*
* The number of the Confirm specific ZRTP part in words
*/
private static final int ZRTP_SAS_RELAY_FIXED_LENGTH = 16;
private static final int HMAC_OFFSET = ZRTP_HEADER_LENGTH * ZRTP_WORD_SIZE; // [2*ZRTP_WORD_SIZE];
private static final int IV_OFFSET = HMAC_OFFSET + 2*ZRTP_WORD_SIZE; // [4*ZRTP_WORD_SIZE];
private static final int FILLER_OFFSET = IV_OFFSET + 4*ZRTP_WORD_SIZE;
private static final int SIG_LENGTH_OFFSET = FILLER_OFFSET + 2;
private static final int FLAGS_OFFSET = SIG_LENGTH_OFFSET + 1;
private static final int SAS_OFFSET = FLAGS_OFFSET + 1;
private static final int TRUSTED_SAS_OFFSET = SAS_OFFSET + ZRTP_WORD_SIZE;
private static final int SIG_DATA_OFFSET = TRUSTED_SAS_OFFSET + 8*ZRTP_WORD_SIZE;
// required bytes to hold the header, the fix part and the CRC
private static final int CONFIRM_FIXED_LENGTH =
(ZRTP_HEADER_LENGTH + ZRTP_SAS_RELAY_FIXED_LENGTH) * ZRTP_WORD_SIZE + CRC_SIZE;
private int signatureLength;
public ZrtpPacketSASRelay() {
super(null);
setSignatureLength(0);
setMessageType(ZrtpConstants.SASRelayMsg);
}
@SuppressWarnings("unused")
public ZrtpPacketSASRelay(final int sl) {
super(null);
setSignatureLength(sl);
setMessageType(ZrtpConstants.SASRelayMsg);
}
public final void setSignatureLength(final int sl) {
if (sl > 512) {
return; // TODO throw exception here ?
}
signatureLength = sl;
// compute total length inlcuding space for signature and CRC
int length = CONFIRM_FIXED_LENGTH + (sl * ZRTP_WORD_SIZE);
if (packetBuffer == null) {
packetBuffer = new byte[length];
}
else {
// allocate new buffer, maybe shorter
byte[] tmp = new byte[length];
// copy header data to new place
System.arraycopy(packetBuffer, 0, tmp, 0, (ZRTP_HEADER_LENGTH + ZRTP_SAS_RELAY_FIXED_LENGTH) * ZRTP_WORD_SIZE);
packetBuffer = tmp;
}
packetBuffer[SIG_LENGTH_OFFSET] = (byte)sl;
if (sl > 255) {
packetBuffer[FILLER_OFFSET+1] = 1; // set 9th bit if necessary
}
setLength((length-CRC_SIZE) / 4);
setZrtpId();
}
public ZrtpPacketSASRelay(final byte[] data) {
super(data);
signatureLength = packetBuffer[SIG_LENGTH_OFFSET] & 0xff;
if (packetBuffer[FILLER_OFFSET+1] == 1) { // if we have a 9th bit - set it
signatureLength |= 0x100;
}
}
@SuppressWarnings("unused")
public final boolean isSASFlag() {
return ((packetBuffer[FLAGS_OFFSET] & 0x4) == 0x4);
}
public final byte[] getIv() {
return ZrtpUtils.readRegion(packetBuffer, IV_OFFSET, 4*ZRTP_WORD_SIZE);
}
public final byte[] getHmac() {
return ZrtpUtils.readRegion(packetBuffer, HMAC_OFFSET, 2*ZRTP_WORD_SIZE);
}
public ZrtpConstants.SupportedSASTypes getSas() {
for (ZrtpConstants.SupportedSASTypes sh : ZrtpConstants.SupportedSASTypes.values()) {
byte[] s = sh.name;
if (s[0] == packetBuffer[SAS_OFFSET] && s[1] == packetBuffer[SAS_OFFSET + 1]
&& s[2] == packetBuffer[SAS_OFFSET + 2]
&& s[3] == packetBuffer[SAS_OFFSET + 3]) {
return sh;
}
}
return null;
}
public final byte[] getTrustedSas() {
return ZrtpUtils.readRegion(packetBuffer, TRUSTED_SAS_OFFSET, 8*ZRTP_WORD_SIZE);
}
public final byte[] getDataToSecure() {
// 9 is ZRTP_HEADER plus non secure confirm data
int length = (getLength() - 9) * ZRTP_WORD_SIZE;
return ZrtpUtils.readRegion(packetBuffer, FILLER_OFFSET, length);
}
@SuppressWarnings("unused")
public final byte[] getSignatureData() {
return ZrtpUtils.readRegion(packetBuffer, SIG_DATA_OFFSET, signatureLength);
}
@SuppressWarnings("unused")
public final int getSignatureLength() {
return signatureLength;
}
/// Check if packet length makes sense. Smallest SasRelay packet is 19 words, similar to Confirm
public final boolean isLengthOk() {
return getLength() >= 19;
}
/*
* Setter methods
*/
@SuppressWarnings("unused")
public final void setSASFlag() {
packetBuffer[FLAGS_OFFSET] |= 0x4;
}
public final void setHmac(final byte[] data) {
System.arraycopy(data, 0, packetBuffer, HMAC_OFFSET, 2*ZRTP_WORD_SIZE);
}
public final void setIv(final byte[] data) {
System.arraycopy(data, 0, packetBuffer, IV_OFFSET, 4*ZRTP_WORD_SIZE);
}
public final void setSasType(final byte[] data) {
System.arraycopy(data, 0, packetBuffer, SAS_OFFSET, ZRTP_WORD_SIZE);
}
public final void setTrustedSas(final byte[] data) {
System.arraycopy(data, 0, packetBuffer, TRUSTED_SAS_OFFSET, 8*ZRTP_WORD_SIZE);
}
public final void setDataToSecure(final byte[] data) {
// 9 is ZRTP_HEADER plus non secure confirm data
int length = (getLength() - 9) * ZRTP_WORD_SIZE;
System.arraycopy(data, 0, packetBuffer, FILLER_OFFSET, length);
}
@SuppressWarnings("unused")
public final void setSignatureData(final byte[] data) {
if (data.length > signatureLength) {
return; // TODO throw exception here?
}
System.arraycopy(data, 0, packetBuffer, SIG_DATA_OFFSET, data.length);
}
// /* ***
// public static void main(String[] args) {
// ZrtpPacketSASRelay pkt = new ZrtpPacketSASRelay(0);
// System.err.println("SAS relay length: " + pkt.getLength());
// pkt.setSASFlag();
//
// System.err.println("packetBuffer length in bytes: " + pkt.getHeaderBase().length);
// ZrtpUtils.hexdump("SAS relay packet", pkt.getHeaderBase(), pkt.getHeaderBase().length);
//
// pkt = new ZrtpPacketSASRelay();
// pkt.setSignatureLength(150);
// System.err.println("SAS Relay length: " + pkt.getLength());
// pkt.setSASFlag();
//
// System.err.println("packetBuffer length in bytes: " + pkt.getHeaderBase().length);
// System.err.println("Signature length in words: " + pkt.getSignatureLength());
// ZrtpUtils.hexdump("SAS relay packet", pkt.getHeaderBase(), pkt.getHeaderBase().length);
// }
// *** */
}