Permalink
Browse files

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

  • Loading branch information...
1 parent 721ed68 commit ffe862b01bfc0da7c388f82702ff9de69c8055d1 @wernerd committed Mar 24, 2012
@@ -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();
@@ -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
@@ -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);
}
}
@@ -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);
}
@@ -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;
}
Oops, something went wrong.

0 comments on commit ffe862b

Please sign in to comment.