Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement the SAS sign methods, add a first short test.

  • Loading branch information...
commit ffe862b01bfc0da7c388f82702ff9de69c8055d1 1 parent 721ed68
@wernerd authored
View
28 src/demo/ReceiverMultiZRTP.java
@@ -71,6 +71,33 @@ public void secureOff() {
public void zrtpNotSuppOther() {
System.err.println(prefix + "Rx ZRTP not supported");
}
+
+ public void signSAS(byte[] sasHash) {
+ System.err.println("Receiver: SAS to sign: ");
+ byte[] sign = new byte[12];
+ sign[0] = sasHash[0];
+ sign[1] = sasHash[1];
+ sign[2] = sasHash[2];
+ sign[3] = sasHash[3];
+ sign[4] = (byte)'R';
+ sign[5] = (byte)'E';
+ sign[6] = (byte)'C';
+ sign[7] = (byte)'E';
+ sign[8] = (byte)'I';
+ sign[9] = (byte)'V';
+ sign[10] = (byte)'E';
+ sign[11] = (byte)'R';
+ System.err.println("Receiver set signature data result: " + zrtpEngine.setSignatureData(sign));
+ }
+
+ public boolean checkSASSignature(byte[] sasHash) {
+ System.err.print("Receiver: check signature: ");
+ byte[] sign = zrtpEngine.getSignatureData();
+ String signStrng = new String(sign);
+ System.err.println(signStrng);
+ return true;
+ }
+
void setPrefix(String pre) {
prefix = pre;
}
@@ -118,6 +145,7 @@ protected void initialize() {
transConnector = (ZrtpTransformConnector) TransformManager
.createZRTPConnector(sa);
zrtpEngine = transConnector.getEngine();
+ zrtpEngine.setSignSas(true);
zrtpEngine.setUserCallback(new MyCallback());
ZrtpConfigure config = new ZrtpConfigure();
config.setStandardConfig();
View
39 src/demo/TransmitterMultiZRTP.java
@@ -90,6 +90,32 @@ public void zrtpNotSuppOther() {
System.err.println(prefix + "Tx ZRTP not supported");
}
+ public void signSAS(byte[] sasHash) {
+ System.err.println("Transmitter: SAS to sign: ");
+ byte[] sign = new byte[12];
+ sign[0] = sasHash[0];
+ sign[1] = sasHash[1];
+ sign[2] = sasHash[2];
+ sign[3] = sasHash[3];
+ sign[4] = (byte)'T';
+ sign[5] = (byte)'R';
+ sign[6] = (byte)'A';
+ sign[7] = (byte)'N';
+ sign[8] = (byte)'S';
+ sign[9] = (byte)'M';
+ sign[10] = (byte)'I';
+ sign[11] = (byte)'T';
+ System.err.println("Transmitter set signature data result: " + zrtpEngine.setSignatureData(sign));
+ }
+
+ public boolean checkSASSignature(byte[] sasHash) {
+ System.err.print("Transmitter: check signature: ");
+ byte[] sign = zrtpEngine.getSignatureData();
+ String signStrng = new String(sign);
+ System.err.println(signStrng);
+ return true;
+ }
+
void setPrefix(String pre) {
prefix = pre;
}
@@ -144,20 +170,23 @@ public void init() {
// config.addHashAlgo(ZrtpConstants.SupportedHashes.S384);
// config.setMandatoryOnly();
// IMPORTANT: crypto provider must be set before initialization
- if (!zrtpEngine.initialize("test_r.zid", config))
- System.err.println("TX: Initialize failed, multi: "
- + multiStream);
-
- System.out.println("Hello hash: " + zrtpEngine.getHelloHash());
// IMPORTANT: set other data only _after_ initialization
if (multiStream) {
MyCallbackMulti mcb = new MyCallbackMulti();
mcb.setPrefix("multi - ");
zrtpEngine.setUserCallback(mcb);
+ if (!zrtpEngine.initialize("test_r.zid", config))
+ System.err.println("TX: Initialize failed, multi: "
+ + multiStream);
zrtpEngine.setMultiStrParams(multiParams);
} else {
+ zrtpEngine.setSignSas(true);
zrtpEngine.setUserCallback(new MyCallback());
+ if (!zrtpEngine.initialize("test_r.zid", config))
+ System.err.println("TX: Initialize failed, multi: "
+ + multiStream);
}
+ System.out.println("Hello hash: " + zrtpEngine.getHelloHash());
// initialize the RTPManager using the SRTP connector
rtpManager.addSendStreamListener(this);
// Add a transmit target, must be done in connector
View
64 src/gnu/java/zrtp/ZRtp.java
@@ -326,6 +326,11 @@
private boolean mitmSeen = false;
/**
+ * Set to true if the Hello packet contained the S-flag (sign SAS flag).
+ */
+ private boolean signSasSeen = false;
+
+ /**
* Temporarily store computed pbxSecret, if user accepts enrollment then
* it will copied to our ZID record of the PBX (MitM)
*/
@@ -388,10 +393,17 @@
private ZrtpConfigure configureAlgos;
+ public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config) {
+ this(myZid, cb, id, config, false, false);
+ }
+ public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config, boolean mitmMode) {
+ this(myZid, cb, id, config, mitmMode, false);
+ }
/**
* Constructor initializes all relevant data but does not start the engine.
*/
- public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config, boolean mitmMode) {
+ public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config,
+ boolean mitmMode, boolean sasSignSupport) {
secRand = ZrtpFortuna.getInstance();
configureAlgos = config;
@@ -401,7 +413,7 @@ public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config, bool
callback = cb;
/*
* Generate H0 as a random number (256 bits, 32 bytes) and then the hash
- * chain, refer to chapter 10
+ * chain, refer to chapter 9
*/
secRand.nextBytes(H0);
// hash H0 and generate H1
@@ -421,6 +433,9 @@ public ZRtp(byte[] myZid, ZrtpCallback cb, String id, ZrtpConfigure config, bool
if (mitmMode) // this session acts for a trusted MitM (PBX)
zrtpHello.setMitmMode();
+ if (sasSignSupport)
+ zrtpHello.setSasSign();
+
zrtpHello.setZid(zid);
setClientId(id); // set id, compute HMAC and final helloHash
@@ -838,10 +853,7 @@ public void acceptEnrollment(boolean accepted) {
*
* This functions stores signature data and transmitts it during ZRTP
* processing to the other party as part of the Confirm packets. Refer to
- * chapters 6.7 and 8.2.
- *
- * The signature data must be set before ZRTP the application calls
- * <code>start()</code>.
+ * chapters 7.2ff.
*
* @param data
* The signature data including the signature type block. The
@@ -851,17 +863,19 @@ public void acceptEnrollment(boolean accepted) {
* @return True if the method stored the data, false otherwise.
*/
public boolean setSignatureData(byte[] data) {
- return false;
+ if ((data.length % 4) != 0)
+ return false;
+ ZrtpPacketConfirm conf = (myRole == ZrtpCallback.Role.Responder) ? zrtpConfirm1 : zrtpConfirm2;
+
+ conf.setSignatureLength(data.length / 4);
+ return conf.setSignatureData(data);
}
/**
* Get signature data
*
* This functions returns signature data that was receivied during ZRTP
- * processing. Refer to chapters 6.7 and 8.2.
- *
- * The signature data can be retrieved after ZRTP enters secure state.
- * <code>start()</code>.
+ * processing. Refer to chapters 7.2ff.
*
* @return Signature data in a byte array.
*/
@@ -879,7 +893,7 @@ public boolean setSignatureData(byte[] data) {
* returns zero if no signature data avilable.
*/
public int getSignatureLength() {
- return signatureLength;
+ return signatureLength * 4;
}
/**
@@ -1076,6 +1090,8 @@ protected ZrtpPacketCommit prepareCommit(ZrtpPacketHello hello,
mitmSeen = true;
trustedMitM = zidRec.isMITMKeyAvailable();
}
+ // Check for sign SAS flag and remember it.
+ signSasSeen = hello.isSasSign();
// Construct a DHPart2 message (Initiator's DH message). This packet
// is required to compute the HVI (Hash Value Initiator), refer to
// chapter 5.4.1.1.
@@ -1460,7 +1476,8 @@ else if (pubKey == ZrtpConstants.SupportedPubKeys.EC25
ZidFile zidf = ZidFile.getInstance();
ZidRecord zidRec = zidf.getRecord(peerZid);
- // Now compute the S0, all dependend keys and the new RS1
+ // Now compute the S0, all dependend keys and the new RS1. The functions
+ // also performs sign SAS callback if it's active.
generateKeysInitiator(dhPart1, zidRec);
zidf.saveRecord(zidRec);
@@ -1581,14 +1598,14 @@ else if (pubKey == ZrtpConstants.SupportedPubKeys.EC25
/*
* The expected shared secret Ids were already computed when we built
* the DHPart1 packet. Generate s0, all depended keys, and the new RS1
- * value for the ZID record.
+ * value for the ZID record. The functions also performs sign SAS callback
+ * if it's active.
*/
generateKeysResponder(dhPart2, zidRec);
zidf.saveRecord(zidRec);
// Fill in Confirm1 packet.
zrtpConfirm1.setMessageType(ZrtpConstants.Confirm1Msg);
- zrtpConfirm1.setSignatureLength(0);
// Check if user verfied the SAS in a previous call and thus verfied
// the retained secret.
@@ -1724,7 +1741,6 @@ protected ZrtpPacketConfirm prepareConfirm1MultiStream(
// Fill in Confirm1 packet.
zrtpConfirm1.setMessageType(ZrtpConstants.Confirm1Msg);
- zrtpConfirm1.setSignatureLength(0);
zrtpConfirm1.setExpTime(0xFFFFFFFF);
zrtpConfirm1.setIv(randomIV);
zrtpConfirm1.setHashH0(H0);
@@ -1796,13 +1812,18 @@ protected ZrtpPacketConfirm prepareConfirm2(ZrtpPacketConfirm confirm1,
// Check HMAC of DHPart1 packet stored in temporary buffer. The
// HMAC key of the DHPart1 packet is peer's H0 that is contained in
- // Confirm1. Refer to chapter 9.1 and chapter 10.
+ // Confirm1. Refer to chapter 9
if (!checkMsgHmac(confirm1.getHashH0())) {
sendInfo(ZrtpCodes.MessageSeverity.Severe,
EnumSet.of(ZrtpCodes.SevereCodes.SevereDH1HMACFailed));
errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
return null;
}
+ signatureLength = confirm1.getSignatureLength();
+ if (signSasSeen && signatureLength > 0) {
+ signatureData = confirm1.getSignatureData();
+ callback.checkSASSignature(sasHash);
+ }
/*
* The Confirm1 is ok, handle the Retained secret stuff and inform GUI
* about state.
@@ -1833,7 +1854,6 @@ protected ZrtpPacketConfirm prepareConfirm2(ZrtpPacketConfirm confirm1,
// now generate my Confirm2 message
zrtpConfirm2.setMessageType(ZrtpConstants.Confirm2Msg);
- zrtpConfirm2.setSignatureLength(0);
zrtpConfirm2.setHashH0(H0);
if (sasFlag) {
@@ -1977,7 +1997,6 @@ protected ZrtpPacketConfirm prepareConfirm2MultiStream(
}
// now generate my Confirm2 message
zrtpConfirm2.setMessageType(ZrtpConstants.Confirm2Msg);
- zrtpConfirm2.setSignatureLength(0);
zrtpConfirm2.setHashH0(H0);
zrtpConfirm2.setExpTime(0xFFFFFFFF);
zrtpConfirm2.setIv(randomIV);
@@ -2057,6 +2076,11 @@ protected ZrtpPacketConf2Ack prepareConf2Ack(ZrtpPacketConfirm confirm2,
errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
return null;
}
+ signatureLength = confirm2.getSignatureLength();
+ if (signSasSeen && signatureLength > 0) {
+ signatureData = confirm2.getSignatureData();
+ callback.checkSASSignature(sasHash);
+ }
/*
* The Confirm2 is ok, handle the Retained secret stuff and inform
* GUI about state.
@@ -2752,6 +2776,8 @@ private void computeSRTPKeys() {
sasBytes[2] = (byte) (sasHash[2] & 0xf0);
sasBytes[3] = 0;
SAS = Base32.binary2ascii(sasBytes, 20);
+ if (signSasSeen)
+ callback.signSAS(sasHash);
}
}
View
12 src/gnu/java/zrtp/ZrtpCallback.java
@@ -242,11 +242,11 @@
* <b>Note:</b> SAS signing is not yet fully supported by GNU
* ZRTP.
*
- * @param sas
- * The SAS string to sign.
+ * @param sasHash
+ * The SAS hash to sign.
*
*/
- public void signSAS(String sas);
+ public void signSAS(byte[] sasHash);
/**
* ZRTPQueue calls this method to request a SAS signature check.
@@ -264,12 +264,12 @@
* <b>Note:</b> SAS signing is not yet fully supported by GNU
* ZRTP.
*
- * @param sas
- * The SAS string that was signed by the other peer.
+ * @param sasHash
+ * The SAS hash that was signed by the other peer.
* @return
* true if the signature was ok, false otherwise.
*
*/
- public boolean checkSASSignature(String sas);
+ public boolean checkSASSignature(byte[] sasHash);
}
View
12 src/gnu/java/zrtp/ZrtpUserCallback.java
@@ -190,12 +190,12 @@ public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info) {
* data an enable signature transmission to the other peer. Refer
* to chapter 8.2 of ZRTP specification.
*
- * @param sas
- * The SAS string to sign.
+ * @param sasHash
+ * The SAS hash to sign.
* @see gnu.java.zrtp.jmf.transform.zrtp.ZRTPTransformEngine#setSignatureData
*
*/
- public void signSAS(String sas) {
+ public void signSAS(byte[] sasHash) {
return;
}
@@ -212,13 +212,13 @@ public void signSAS(String sas) {
* this case ZRTP signals an error to the other peer and terminates
* the ZRTP handshake.
*
- * @param sas
- * The SAS string that was signed by the other peer.
+ * @param sasHash
+ * The sasHash that was signed by the other peer.
* @return
* true if the signature was ok, false otherwise.
*
*/
- public boolean checkSASSignature(String sas) {
+ public boolean checkSASSignature(byte[] sasHash) {
return true;
}
View
20 src/gnu/java/zrtp/jmf/transform/zrtp/ZRTPTransformEngine.java
@@ -276,6 +276,8 @@ public void run() {
private boolean mitmMode = false;
+ private boolean signSas = false;
+
private ZRTCPTransformer zrtcpTransformer = null;
/**
@@ -346,7 +348,7 @@ public synchronized boolean initialize(String zidFilename, boolean autoEnable, Z
}
}
enableZrtp = autoEnable;
- zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString, config, mitmMode);
+ zrtpEngine = new ZRtp(zf.getZid(), this, clientIdString, config, mitmMode, signSas);
return true;
}
@@ -692,14 +694,14 @@ public void zrtpInformEnrollment(ZrtpCodes.InfoEnrollment info) {
}
}
- public void signSAS(String sas) {
+ public void signSAS(byte[] sasHash) {
if (userCallback != null) {
- userCallback.signSAS(sas);
+ userCallback.signSAS(sasHash);
}
}
- public boolean checkSASSignature(String sas) {
- return ((userCallback != null) ? userCallback.checkSASSignature(sas) : false);
+ public boolean checkSASSignature(byte[] sasHash) {
+ return ((userCallback != null) ? userCallback.checkSASSignature(sasHash) : false);
}
public void setEnableZrtp(boolean onOff) {
@@ -873,6 +875,14 @@ public int getSignatureLength() {
return ((zrtpEngine != null) ? zrtpEngine.getSignatureLength() : 0);
}
+ public void setSignSas(boolean signSasMode) {
+ signSas = signSasMode;
+ }
+
+ public boolean isSignSas() {
+ return signSas;
+ }
+
public void handleGoClear() {
System.err.println("Need to process a GoClear message!");
}
View
24 src/gnu/java/zrtp/packets/ZrtpPacketConfirm.java
@@ -59,9 +59,9 @@ public ZrtpPacketConfirm(final int sl) {
setSignatureLength(sl);
}
- public final void setSignatureLength(final int sl) {
+ public final boolean setSignatureLength(final int sl) {
if (sl > 512) {
- return; // TODO throw exception here ?
+ return false;
}
signatureLength = sl;
// compute total length inlcuding space for signature and CRC
@@ -83,14 +83,11 @@ public final void setSignatureLength(final int sl) {
}
setLength((length-CRC_SIZE) / 4);
setZrtpId();
+ return true;
}
public ZrtpPacketConfirm(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;
- }
}
public final boolean isSASFlag() {
@@ -124,10 +121,14 @@ public final int getExpTime() {
}
public final byte[] getSignatureData() {
- return ZrtpUtils.readRegion(packetBuffer, SIG_DATA_OFFSET, signatureLength);
+ return ZrtpUtils.readRegion(packetBuffer, SIG_DATA_OFFSET, signatureLength*4);
}
public final int getSignatureLength() {
+ signatureLength = packetBuffer[SIG_LENGTH_OFFSET] & 0xff;
+ if (packetBuffer[FILLER_OFFSET+1] == 1) { // if we have a 9th bit - set it
+ signatureLength |= 0x100;
+ }
return signatureLength;
}
/*
@@ -163,11 +164,12 @@ public final void setHashH0(final byte[] data) {
System.arraycopy(data, 0, packetBuffer, HASH_H0_OFFSET, 8*ZRTP_WORD_SIZE);
}
- public final void setSignatureData(final byte[] data) {
- if (data.length > signatureLength) {
- return; // TODO throw exception here?
+ public final boolean setSignatureData(final byte[] data) {
+ if ((data.length / 4) > signatureLength) {
+ return false;
}
- System.arraycopy(data, 0, packetBuffer, SIG_DATA_OFFSET, data.length);
+ System.arraycopy(data, 0, packetBuffer, SIG_DATA_OFFSET, data.length);
+ return true;
}
/* ***
View
9 src/gnu/java/zrtp/packets/ZrtpPacketHello.java
@@ -53,6 +53,7 @@
// private static final byte HELLO_PASSIVE = 0x10;
private static final byte HELLO_MITM_FLAG = 0x20;
+ private static final byte SAS_SIGN_FLAG = 0x40;
/*
* The length of the Hello specific ZRTP packet part in words
*/
@@ -233,6 +234,14 @@ public final boolean isMitmMode() {
return ((helloFlags & HELLO_MITM_FLAG) == HELLO_MITM_FLAG);
}
+ public final void setSasSign() {
+ packetBuffer[FLAG_LENGTH_OFFSET] |= SAS_SIGN_FLAG;
+ }
+
+ public final boolean isSasSign() {
+ return ((helloFlags & SAS_SIGN_FLAG) == SAS_SIGN_FLAG);
+ }
+
/**
* Check if version data matches.
*
Please sign in to comment.
Something went wrong with that request. Please try again.