Jitsi: the OpenSource Java VoIP and Instant Messaging client.

net.java.sip.communicator.impl.neomedia.transform.zrtp
Class ZRTPTransformEngine

java.lang.Object
  extended by net.java.sip.communicator.impl.neomedia.transform.zrtp.ZRTPTransformEngine
All Implemented Interfaces:
gnu.java.zrtp.ZrtpCallback, PacketTransformer, TransformEngine

public class ZRTPTransformEngine
extends Object
implements TransformEngine, PacketTransformer, gnu.java.zrtp.ZrtpCallback

JMF extension/connector to support GNU ZRTP4J. ZRTP was developed by Phil Zimmermann and provides functions to negotiate keys and other necessary data (crypto data) to set-up the Secure RTP (SRTP) crypto context. Refer to Phil's ZRTP specification at his Zfone project site to get more detailed information about the capabilities of ZRTP.

Short overview of the ZRTP4J implementation

ZRTP is a specific protocol to negotiate encryption algorithms and the required key material. ZRTP uses a RTP session to exchange its protocol messages. A complete GNU ZRTP4J implementation consists of two parts, the GNU ZRTP4J core and specific code that binds the GNU ZRTP core to the underlying RTP/SRTP stack and the operating system: The GNU ZRTP4J core uses a callback interface class (refer to ZrtpCallback) to access RTP/SRTP or operating specific methods, for example to send data via the RTP/SRTP stack, to access timers, provide mutex handling, and to report events to the application.

The ZRTPTransformEngine

ZRTPTransformEngine implements code that is specific to the JMF implementation. To perform its tasks ZRTPTransformEngine After instantiating a GNU ZRTP4J session (see below for a short example) applications may use the ZRTP specific methods of ZRTPTransformEngine to control and setup GNU ZRTP, for example enable or disable ZRTP processing or getting ZRTP status information. GNU ZRTP4J provides a ZrtpUserCallback class that an application may extend and register with ZRTPTransformEngine. GNU ZRTP4J and ZRTPTransformEngine use the ZrtpUserCallback methods to report ZRTP events to the application. The application may display this information to the user or act otherwise. The following figure depicts the relationships between ZRTPTransformEngine, JMF implementation, the GNU ZRTP4J core, and an application that provides an ZrtpUserCallback class.

                  +---------------------------+
                  |  ZrtpTransformConnector   |
                  | extends TransformConnector|
                  | implements RTPConnector   |
                  +---------------------------+
                                |
                                | uses
                                |
  +----------------+      +-----+---------------+
  |  Application   |      |                     |      +----------------+
  |  instantiates  | uses | ZRTPTransformEngine | uses |                |
  | a ZRTP Session +------+    implements       +------+   GNU ZRTP4J   |
  |  and provides  |      |   ZrtpCallback      |      |      core      |
  |ZrtpUserCallback|      |                     |      | implementation |
  +----------------+      +---------------------+      |  (ZRtp et al)  |
                                                       |                |
                                                       +----------------+
 
The following short code snippets show how an application could instantiate a ZrtpTransformConnector, get the ZRTP4J engine and initialize it. Then the code get a RTP manager instance and initializes it with the ZRTPTransformConnector. Please note: setting the target must be done with the connector, not with the RTP manager.
 ...
   transConnector = (ZrtpTransformConnector)TransformManager
                                                  .createZRTPConnector(sa);
   zrtpEngine = transConnector.getEngine();
   zrtpEngine.setUserCallback(new MyCallback());
   if (!zrtpEngine.initialize("test_t.zid"))
       System.out.println("iniatlize failed");

   // initialize the RTPManager using the ZRTP connector

   mgr = RTPManager.newInstance();
   mgr.initialize(transConnector);

   mgr.addSessionListener(this);
   mgr.addReceiveStreamListener(this);

   transConnector.addTarget(target);
   zrtpEngine.startZrtp();

   ...
 
The demo folder contains a small example that shows how to use GNU ZRTP4J. This ZRTPTransformEngine documentation shows the ZRTP specific extensions and describes overloaded methods and a possible different behaviour.

Author:
Werner Dittmann <Werner.Dittmann@t-online.de>

Nested Class Summary
 
Nested classes/interfaces inherited from interface gnu.java.zrtp.ZrtpCallback
gnu.java.zrtp.ZrtpCallback.EnableSecurity, gnu.java.zrtp.ZrtpCallback.Role
 
Field Summary
protected static int ZRTP_PACKET_HEADER
          Each ZRTP packet has a fixed header of 12 bytes.
 
Constructor Summary
ZRTPTransformEngine()
          Construct a ZRTPTransformEngine.
 
Method Summary
 void acceptEnrollment(boolean accepted)
          Used to accept a PBX enrollment request (The PBX part needs further development)
 int activateTimer(int time)
          Activate timer.
 int cancelTimer()
          Cancel the active timer.
 boolean checkSASSignature(byte[] sasHash)
           
 void cleanup()
          Cleanup function for any remaining timers
 void close()
          Close the transformer and underlying transform engine.
 String getHelloHash()
          Gets the Hello packet Hash
 String[] getHelloHashSep()
          Get the ZRTP Hello Hash data - separate strings.
 byte[] getMultiStrParams()
          Gets the multistream params
 byte[] getPeerZid()
          Get other party's ZID (ZRTP Identifier) data This functions returns the other party's ZID that was receivied during ZRTP processing.
 ZRTCPTransformer getRTCPTransformer()
          Returns an instance of ZRTPCTransformer.
 PacketTransformer getRTPTransformer()
          Returns this RTPTransformer.
 byte[] getSasHash()
          Get the computed SAS hash for this ZRTP session.
 gnu.java.zrtp.ZrtpConstants.SupportedSASTypes getSasType()
          Get the commited SAS rendering algorithm for this ZRTP session.
 boolean getSecureCommunicationStatus()
          Method for getting the default secure status value for communication
 byte[] getSignatureData()
          Gets signature data
 int getSignatureLength()
          Gets signature length
 SecurityEventManager getUserCallback()
          Gets the user callback used to manage the GUI part of ZRTP
 void handleGoClear()
          Method called by the Zrtp class as result of a GoClear request from the other peer.
 void handleTimeout()
          Timeout handling function.
 boolean initialize(String zidFilename)
          Default engine initialization method.
 boolean initialize(String zidFilename, boolean autoEnable)
          Engine initialization method.
 boolean initialize(String zidFilename, boolean autoEnable, gnu.java.zrtp.ZrtpConfigure config)
          Custom engine initialization method.
 boolean initialize(String zidFilename, gnu.java.zrtp.ZrtpConfigure config)
          Engine initialization method.
 boolean isEnableZrtp()
          Returns the enableZrtp flag.
 boolean isEnrollmentMode()
          Check the state of the enrollment mode.
 boolean isMitmMode()
          Check the state of the MitM mode flag.
 boolean isMultiStream()
          Gets the multistream flag (The multistream part needs further development)
 boolean isParanoidMode()
          Check status of paranoid mode.
 boolean isStarted()
          Returns the current status of the ZRTP engine
 void requestGoClear()
          Method called when the user requests through GUI to switch a secured call to unsecure mode.
 void requestGoSecure()
          Method called when the user requests through GUI to switch a previously unsecured call back to secure mode.
 void resetSASVerified()
          Resets the internal engine SAS verified flag
 RawPacket reverseTransform(RawPacket pkt)
          The input data stream calls this method to transform incoming packets.
 void SASVerified()
          Set the SAS as verified internally if the user confirms it
 boolean sendDataZRTP(byte[] data)
          The callback method required by the ZRTP implementation.
 void sendInfo(gnu.java.zrtp.ZrtpCodes.MessageSeverity severity, EnumSet<?> subCode)
          Send information messages to the hosting environment.
 boolean sendSASRelayPacket(byte[] sh, gnu.java.zrtp.ZrtpConstants.SupportedSASTypes render)
          Send the SAS relay packet.
 void setAuxSecret(byte[] data)
          Sets the auxilliary secret data
 void setClientId(String id)
          Sets the client ID
 void setConnector(AbstractRTPConnector connector)
          Sets the RTP connector using this ZRTP engine
 void setEnableZrtp(boolean onOff)
          Sets the enableZrtp flag.
 void setEnrollmentMode(boolean enrollmentMode)
          Set the state of the enrollment mode.
 void setMitmMode(boolean mitmMode)
          Set the state of the MitM mode flag.
 void setMultiStrParams(byte[] parameters)
          Sets the multistream params (The multistream part needs further development)
 void setOwnSSRC(long ssrc)
          Set the SSRC of the RTP transmitter stream.
 void setParanoidMode(boolean yesNo)
          Enables or disables paranoid mode.
 boolean setSignatureData(byte[] data)
          Sets signature data for the Confirm packets
 void setStartMuted(boolean startMuted)
           
 void setUserCallback(SecurityEventManager ub)
          Sets the user callback class used to maintain the GUI ZRTP part
 void signSAS(byte[] sasHash)
           
 void srtpSecretsOff(gnu.java.zrtp.ZrtpCallback.EnableSecurity part)
          This method shall clear the ZRTP secrets.
 void srtpSecretsOn(String c, String s, boolean verified)
           
 boolean srtpSecretsReady(gnu.java.zrtp.ZrtpSrtpSecrets secrets, gnu.java.zrtp.ZrtpCallback.EnableSecurity part)
          Switch on the security for the defined part.
 void startZrtp()
          Start the ZRTP stack immediately, not autosensing mode.
 void stopZrtp()
          Stop ZRTP engine.
 RawPacket transform(RawPacket pkt)
          The data output stream calls this method to transform outgoing packets.
 void zrtpAskEnrollment(gnu.java.zrtp.ZrtpCodes.InfoEnrollment info)
          Zrtp ask for Enrollment.
 void zrtpInformEnrollment(gnu.java.zrtp.ZrtpCodes.InfoEnrollment info)
           
 void zrtpNegotiationFailed(gnu.java.zrtp.ZrtpCodes.MessageSeverity severity, EnumSet<?> subCode)
          Comes a message that zrtp negotiation has failed.
 void zrtpNotSuppOther()
          The other part doesn't support zrtp.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ZRTP_PACKET_HEADER

protected static final int ZRTP_PACKET_HEADER
Each ZRTP packet has a fixed header of 12 bytes.

See Also:
Constant Field Values
Constructor Detail

ZRTPTransformEngine

public ZRTPTransformEngine()
Construct a ZRTPTransformEngine.

Method Detail

getRTCPTransformer

public ZRTCPTransformer getRTCPTransformer()
Returns an instance of ZRTPCTransformer.

Specified by:
getRTCPTransformer in interface TransformEngine
Returns:
the PacketTransformer for RTCP packets
See Also:
TransformEngine.getRTCPTransformer()

getRTPTransformer

public PacketTransformer getRTPTransformer()
Returns this RTPTransformer.

Specified by:
getRTPTransformer in interface TransformEngine
Returns:
the PacketTransformer for RTP packets
See Also:
TransformEngine.getRTPTransformer()

initialize

public boolean initialize(String zidFilename,
                          gnu.java.zrtp.ZrtpConfigure config)
Engine initialization method. Calling this for engine initialization and start it with auto-sensing and a given configuration setting.

Parameters:
zidFilename - The ZID file name
config - The configuration data
Returns:
true if initialization fails, false if succeeds

initialize

public boolean initialize(String zidFilename,
                          boolean autoEnable)
Engine initialization method. Calling this for engine initialization and start it with defined auto-sensing and a default configuration setting.

Parameters:
zidFilename - The ZID file name
autoEnable - If true start with auto-sensing mode.
Returns:
true if initialization fails, false if succeeds

initialize

public boolean initialize(String zidFilename)
Default engine initialization method. Calling this for engine initialization and start it with auto-sensing and default configuration setting.

Parameters:
zidFilename - The ZID file name
Returns:
true if initialization fails, false if succeeds

initialize

public boolean initialize(String zidFilename,
                          boolean autoEnable,
                          gnu.java.zrtp.ZrtpConfigure config)
Custom engine initialization method. This allows to explicit specify if the engine starts with auto-sensing or not.

Parameters:
zidFilename - The ZID file name
autoEnable - Set this true to start with auto-sensing and false to disable it.
config - the zrtp config to use
Returns:
true if initialization fails, false if succeeds

setStartMuted

public void setStartMuted(boolean startMuted)
Parameters:
startMuted - whether to be started as muted if no secure communication is established

getSecureCommunicationStatus

public boolean getSecureCommunicationStatus()
Method for getting the default secure status value for communication

Returns:
the default enabled/disabled status value for secure communication

startZrtp

public void startZrtp()
Start the ZRTP stack immediately, not autosensing mode.


close

public void close()
Close the transformer and underlying transform engine. The close functions closes all stored crypto contexts. This deletes key data and forces a cleanup of the crypto contexts.

Specified by:
close in interface PacketTransformer

stopZrtp

public void stopZrtp()
Stop ZRTP engine.


cleanup

public void cleanup()
Cleanup function for any remaining timers


setOwnSSRC

public void setOwnSSRC(long ssrc)
Set the SSRC of the RTP transmitter stream. ZRTP fills the SSRC in the ZRTP messages.

Parameters:
ssrc - SSRC to set

transform

public RawPacket transform(RawPacket pkt)
The data output stream calls this method to transform outgoing packets.

Specified by:
transform in interface PacketTransformer
Parameters:
pkt - the packet to be transformed
Returns:
the transformed packet
See Also:
PacketTransformer.transform(RawPacket)

reverseTransform

public RawPacket reverseTransform(RawPacket pkt)
The input data stream calls this method to transform incoming packets.

Specified by:
reverseTransform in interface PacketTransformer
Parameters:
pkt - the transformed packet to be restored
Returns:
the restored packet
See Also:
PacketTransformer.reverseTransform(RawPacket)

sendDataZRTP

public boolean sendDataZRTP(byte[] data)
The callback method required by the ZRTP implementation. First allocate space to hold the complete ZRTP packet, copy the message part in its place, the initalize the header, counter, SSRC and crc.

Specified by:
sendDataZRTP in interface gnu.java.zrtp.ZrtpCallback
Parameters:
data - The ZRTP packet data
Returns:
true if sending succeeds, false if it fails

srtpSecretsReady

public boolean srtpSecretsReady(gnu.java.zrtp.ZrtpSrtpSecrets secrets,
                                gnu.java.zrtp.ZrtpCallback.EnableSecurity part)
Switch on the security for the defined part.

Specified by:
srtpSecretsReady in interface gnu.java.zrtp.ZrtpCallback
Parameters:
secrets - The secret keys and salt negotiated by ZRTP
part - An enum that defines sender, receiver, or both.
Returns:
always return true.

srtpSecretsOn

public void srtpSecretsOn(String c,
                          String s,
                          boolean verified)
Specified by:
srtpSecretsOn in interface gnu.java.zrtp.ZrtpCallback
Parameters:
c -
s -
verified -
See Also:
ZrtpCallback.srtpSecretsOn(java.lang.String, java.lang.String, boolean)

srtpSecretsOff

public void srtpSecretsOff(gnu.java.zrtp.ZrtpCallback.EnableSecurity part)
This method shall clear the ZRTP secrets.

Specified by:
srtpSecretsOff in interface gnu.java.zrtp.ZrtpCallback
Parameters:
part - Defines for which part (sender or receiver) to switch on security

activateTimer

public int activateTimer(int time)
Activate timer.

Specified by:
activateTimer in interface gnu.java.zrtp.ZrtpCallback
Parameters:
time - The time in ms for the timer.
Returns:
always return 1.

cancelTimer

public int cancelTimer()
Cancel the active timer.

Specified by:
cancelTimer in interface gnu.java.zrtp.ZrtpCallback
Returns:
always return 1.

handleTimeout

public void handleTimeout()
Timeout handling function. Delegates the handling to the ZRTP engine.


sendInfo

public void sendInfo(gnu.java.zrtp.ZrtpCodes.MessageSeverity severity,
                     EnumSet<?> subCode)
Send information messages to the hosting environment.

Specified by:
sendInfo in interface gnu.java.zrtp.ZrtpCallback
Parameters:
severity - This defines the message's severity
subCode - The message code.

zrtpNegotiationFailed

public void zrtpNegotiationFailed(gnu.java.zrtp.ZrtpCodes.MessageSeverity severity,
                                  EnumSet<?> subCode)
Comes a message that zrtp negotiation has failed.

Specified by:
zrtpNegotiationFailed in interface gnu.java.zrtp.ZrtpCallback
Parameters:
severity - This defines the message's severity
subCode - The message code.

zrtpNotSuppOther

public void zrtpNotSuppOther()
The other part doesn't support zrtp.

Specified by:
zrtpNotSuppOther in interface gnu.java.zrtp.ZrtpCallback

zrtpAskEnrollment

public void zrtpAskEnrollment(gnu.java.zrtp.ZrtpCodes.InfoEnrollment info)
Zrtp ask for Enrollment.

Specified by:
zrtpAskEnrollment in interface gnu.java.zrtp.ZrtpCallback
Parameters:
info - supplied info.

zrtpInformEnrollment

public void zrtpInformEnrollment(gnu.java.zrtp.ZrtpCodes.InfoEnrollment info)
Specified by:
zrtpInformEnrollment in interface gnu.java.zrtp.ZrtpCallback
Parameters:
info -
See Also:
ZrtpCallback.zrtpInformEnrollment( gnu.java.zrtp.ZrtpCodes.InfoEnrollment)

signSAS

public void signSAS(byte[] sasHash)
Specified by:
signSAS in interface gnu.java.zrtp.ZrtpCallback
Parameters:
sas -
See Also:
gnu.java.zrtp.ZrtpCallback#signSAS(java.lang.String)

checkSASSignature

public boolean checkSASSignature(byte[] sasHash)
Specified by:
checkSASSignature in interface gnu.java.zrtp.ZrtpCallback
Parameters:
sas -
Returns:
false if signature check fails, true otherwise
See Also:
gnu.java.zrtp.ZrtpCallback#checkSASSignature(java.lang.String)

setEnableZrtp

public void setEnableZrtp(boolean onOff)
Sets the enableZrtp flag.

Parameters:
onOff - The value for the enableZrtp flag.

isEnableZrtp

public boolean isEnableZrtp()
Returns the enableZrtp flag.

Returns:
the enableZrtp flag.

SASVerified

public void SASVerified()
Set the SAS as verified internally if the user confirms it


resetSASVerified

public void resetSASVerified()
Resets the internal engine SAS verified flag


requestGoClear

public void requestGoClear()
Method called when the user requests through GUI to switch a secured call to unsecure mode. Just forwards the request to the Zrtp class.


requestGoSecure

public void requestGoSecure()
Method called when the user requests through GUI to switch a previously unsecured call back to secure mode. Just forwards the request to the Zrtp class.


setAuxSecret

public void setAuxSecret(byte[] data)
Sets the auxilliary secret data

Parameters:
data - The auxilliary secret data

setClientId

public void setClientId(String id)
Sets the client ID

Parameters:
id - The client ID

getHelloHash

public String getHelloHash()
Gets the Hello packet Hash

Returns:
the Hello packet hash

getHelloHashSep

public String[] getHelloHashSep()
Get the ZRTP Hello Hash data - separate strings.

Returns:
String array containing the version string at offset 0, the Hello hash value as hex-digits at offset 1. Hello hash is available immediately after class instantiation. Returns null if ZRTP is not available.

getMultiStrParams

public byte[] getMultiStrParams()
Gets the multistream params

Returns:
the multistream params

setMultiStrParams

public void setMultiStrParams(byte[] parameters)
Sets the multistream params (The multistream part needs further development)

Parameters:
parameters - the multistream params

isMultiStream

public boolean isMultiStream()
Gets the multistream flag (The multistream part needs further development)

Returns:
the multistream flag

acceptEnrollment

public void acceptEnrollment(boolean accepted)
Used to accept a PBX enrollment request (The PBX part needs further development)

Parameters:
accepted - The boolean value indicating if the request is accepted

getSasType

public gnu.java.zrtp.ZrtpConstants.SupportedSASTypes getSasType()
Get the commited SAS rendering algorithm for this ZRTP session.

Returns:
the commited SAS rendering algorithm

getSasHash

public byte[] getSasHash()
Get the computed SAS hash for this ZRTP session.

Returns:
a refernce to the byte array that contains the full SAS hash.

sendSASRelayPacket

public boolean sendSASRelayPacket(byte[] sh,
                                  gnu.java.zrtp.ZrtpConstants.SupportedSASTypes render)
Send the SAS relay packet. The method creates and sends a SAS relay packet according to the ZRTP specifications. Usually only a MitM capable user agent (PBX) uses this function.

Parameters:
sh - the full SAS hash value
render - the SAS rendering algorithm
Returns:
true if the SASReplay packet has been correctly sent, false otherwise

isMitmMode

public boolean isMitmMode()
Check the state of the MitM mode flag. If true then this ZRTP session acts as MitM, usually enabled by a PBX based client (user agent)

Returns:
state of mitmMode

setMitmMode

public void setMitmMode(boolean mitmMode)
Set the state of the MitM mode flag. If MitM mode is set to true this ZRTP session acts as MitM, usually enabled by a PBX based client (user agent).

Parameters:
mitmMode - defines the new state of the mitmMode flag

setParanoidMode

public void setParanoidMode(boolean yesNo)
Enables or disables paranoid mode. For further explanation of paranoid mode refer to the documentation of ZRtp class.

Parameters:
yesNo - If set to true then paranoid mode is enabled.

isParanoidMode

public boolean isParanoidMode()
Check status of paranoid mode.

Returns:
Returns true if paranoid mode is enabled.

isEnrollmentMode

public boolean isEnrollmentMode()
Check the state of the enrollment mode. If true then we will set the enrollment flag (E) in the confirm packets and performs the enrollment actions. A MitM (PBX) enrollment service sets this flag.

Returns:
status of the enrollmentMode flag.

setEnrollmentMode

public void setEnrollmentMode(boolean enrollmentMode)
Set the state of the enrollment mode. If true then we will set the enrollment flag (E) in the confirm packets and perform the enrollment actions. A MitM (PBX) enrollment service must set this mode to true. Can be set to true only if mitmMode is also true.

Parameters:
enrollmentMode - defines the new state of the enrollmentMode flag

setSignatureData

public boolean setSignatureData(byte[] data)
Sets signature data for the Confirm packets

Parameters:
data - the signature data
Returns:
true if signature data was successfully set

getSignatureData

public byte[] getSignatureData()
Gets signature data

Returns:
the signature data

getSignatureLength

public int getSignatureLength()
Gets signature length

Returns:
the signature length

handleGoClear

public void handleGoClear()
Method called by the Zrtp class as result of a GoClear request from the other peer. An explicit user confirmation is needed before switching to unsecured mode. This is asked through the user callback.

Specified by:
handleGoClear in interface gnu.java.zrtp.ZrtpCallback

setConnector

public void setConnector(AbstractRTPConnector connector)
Sets the RTP connector using this ZRTP engine

Parameters:
connector - the connector to set

setUserCallback

public void setUserCallback(SecurityEventManager ub)
Sets the user callback class used to maintain the GUI ZRTP part

Parameters:
ub - The user callback class

isStarted

public boolean isStarted()
Returns the current status of the ZRTP engine

Returns:
the current status of the ZRTP engine

getUserCallback

public SecurityEventManager getUserCallback()
Gets the user callback used to manage the GUI part of ZRTP

Returns:
the user callback

getPeerZid

public byte[] getPeerZid()
Get other party's ZID (ZRTP Identifier) data This functions returns the other party's ZID that was receivied during ZRTP processing. The ZID data can be retrieved after ZRTP receive the first Hello packet from the other party. The application may call this method for example during SAS processing in showSAS(...) user callback method.

Returns:
the ZID data as byte array.

Jitsi: the OpenSource Java VoIP and Instant Messaging client.

Jitsi, the OpenSource Java VoIP and Instant Messaging client.
Distributable under LGPL license.