Monday, June 30, 2008

Activity Log : GSoC Week #10 (23.VI - 29.VI)

I'll be short this time. The main issues solved last week:
  • done the part related with toggleing secure communication on during a call; both parties can do that regardless the fact they started the call unsecured
  • noticed a bug in the ZRTP init phase which occurs some times in the DH exchange and makes it hang (still must investigate why this appears)
  • tried to apply an older patch manually in order to be able to make a call without the presence of a registrar; see below for detailed info

The patch is based on splitting the ProtocolProviderServiceSipImpl functionality resulting in a more general AbstractProtocolProviderServiceSipImpl as a base class for ProtocoProviderServiceSipImpl (registrar mode) and ProtocolProviderServiceSipNoRegistrarImpl (no registrar mode). The selection of the implementation used is based on an option set for the specific AccountID which is used for making the subsequent calls. This option should probably be available in the account wizard somewhere as the original patch author Michael Koch wrote. For now I've added directly the option to the account properties map inside the code in the ProtocolProviderFactorySipImpl loadAccount method to see if the patch works - this means that all the accounts will use the no registrar option, but like I said is only to test the patch. The result is that the two new accounts I created for testing (one on my PC and one on my notebook), start as expected looking like normal registered ones (online and being able to make calls). Anyway, when I try to call one of them from the other, the endpoint that is alerted and starts ringing is the same that makes the call. This happens despite the fact that during a debug session the INVITE message seems to be perfectly fine (I'm not a SIP expert, but that's my impression and to be sure I've checked the standard once more). I've ran the debug step by step (except the JAIN SIP jar contained sources) until the ringing starts (which happens in the createOutgoingCall method inside the OperationSetBasicTelephonySipImpl class at inviteTransaction.sendRequest() - line 295), and all seems to be in order as much as I can tell, like I said, regarding the INVITE request. I'll probably should check again the patch and see if I didn't miss something, or to do a deeper check in the sources to see if it's not related with something modified since the patch was issued.

I didn't modify the sources on svn branch yet with the patch. I've applied it on a different local copy on my PC. I'm posting the no-registrar patched sip package and ProtocolProviderFactory source in the form they now are as a zip archive at this address:

http://students.info.uaic.ro/~eonica/sc/no-registrar.zip

Overriding them on the current date svn encryption branch sources should bring you to the no-registrar patched version status of SC I've reached.

Monday, June 23, 2008

Activity Log : GSoC Week #09 (16.VI - 22.VI)

How things went on for the last half of week since the previous blog entry ( some good news this time :) ) :
  • solved the bouncycastle jar issue with some help from Emil and passed the problem explained last time; the jar used right now is the last version 1.39 and is imported "externally" = isn't included any more inside the media.jar

  • got stuck (for quite a while...) with an InvalidKeyException in ZRTP4J (in the preparation of the Confirm1 message at the initialization of the AES cipher - line 1246); eventually I found out that - quote from the Bouncy Castle site: "Note: with JDK 1.4 and later you will need to have installed the unrestricted policy files to take full advantage of the provider. If you do not install the policy files you are likely to get something like the following: java.lang.SecurityException: Unsupported keysize or algorithm parameters" ; the unrestricted policy files do indeed solve the problem, but this probably means the user should install them (installation means overwriting the original jars in the system's Java path; maybe this might be done through SC setup ...) ; anyway, the idea is that these are needed now for a succesful run and can be found at : https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jce_policy-6-oth-JPR@CDS-CDS_Developer (this is for JDK/JRE 1.6 ; for other versions look for JCE unlimited/unrestricted policy files on the version's download page)
  • removed some more bugs (mainly from CallSessionImpl), updated the GUI with the secure status (see below for details) and finally made a successful SC-SC call secured through ZRTP :)

More details about the GUI additions:

I've added a label to display the SAS and actually the current secure or not status for the call. This is only provisional for now as discussed with Romain in the last GUI related mail. Anyway, I've done it using a GUI plugin. One reason is that eventually it should be done through a plugin so I thought it will be ok to try this from now. Another reason is that other way of sending a message from the media service to the GUI label would have been quite "invasive", needing probably some modifications in the current UIService and adding another ExportedWindow from the main interface. So I went on for the current approach, and based on the AboutWindowPluginComponent related source code inside the Branding plugin (due to the fact the GUI plugin tutorials on the SC dev page seem to be a bit outdated), I created a small JLabel based PluginComponent and added it for now, through a GUI Plugin, near the previous made button.

When not during a call this looks like this:


If the user didn't try to activate secure communication on his client through the nearby button - the call will be unsecured (the ZRTP engine starts with autosensing off):



If the user enabled secure communication for his client but the other peer didn't the call starts the same as above unsecured, but another tooltip is displayed regarding the cause:



And finally if both users have secure communication enabled before the call, the SAS string is displayed:


All these - design, behaviour, etc, like stated before, have provisional status for now. The main idea was to know if it works and how can be done. When it's appropriate, I'll try moving them in another GUI location like discussed.

Like I said, I've managed to run the first SC-SC ZRTP secured call. This is however done with autosensing on for both sides, meaning that the both peers activated secure communication before the call. In case one of them didn't the call goes on unsecured. Actually, the possible cases of how the call goes in case of activating/deactivating the secure status could be very well summarized through the presented screenshots. So, in conclusion, all goes well for now in case any modification in the secure comm status for the client is done between the calls. Toggleing on secure communication during a call doesn't work at this moment and I'll try to focus on it this week (I'll probably should go deeper for this in Werner's sources). Toggleing off secure communication during a call should be similar with the sending of the GoClear optional message, so I'll leave it for later.

I uploaded the current sources to the svn encryption branch. I didn't manage yet to comment all the changes/additions (I'll try to do that this week). That should be all for now.

Wednesday, June 18, 2008

Activity Log : GSoC Week #08 (9.VI - 15.VI)

I'll be shorter this time, summarizing in a few lines the activity for last week's final half and the issues appeared at the beginning of this one:

  • removed quite a few bugs from CallSessionImpl and TransformManager
  • passed the problem with the NoClassDef exception through some refactoring adding Werner's ZRTP4J sources inside the SC tree
  • refactored the refactoring to bring back ZRTP4J in the initial structure and solved the NoClassDef exception the right way by adding the ZRTP4J sources inside the media.jar at build time through build.xml; this approach will permit the future modification to integrating ZRTP4J through a jar very easy - the imports will remain in the same form as now, and the lines in the build.xml will be changed to reflect the jar integration, similar to how the bouncycastle jar is handled at the moment
  • modified the used ZRTP4J sources with Werner's last sources version
  • got stuck into a problem, since this week started, related to how JCE (Java Cryptography Extension) works - detailed below
  • added the current sources on the java.net sip-communicator dedicated branch - https://sip-communicator.dev.java.net/svn/sip-communicator/branches/encryption

Now, a few more words about the problem I'm facing. Probably the best way to start explain it is actually pasting the exception I get:


[java] java.lang.SecurityException: JCE cannot authenticate the provider BC
[java] at javax.crypto.SunJCE_b.a(DashoA13*..)
[java] at javax.crypto.Mac.getInstance(DashoA13*..)
[java] at gnu.java.zrtp.ZRtp.(ZRtp.java:325)
[java] at net.java.sip.communicator.impl.media.transform.zrtp.ZRTPTransformEngine.initialize(ZRTPTransformEngine.java:641)
[java] at net.java.sip.communicator.impl.media.CallSessionImpl.initializeRtpManager(CallSessionImpl.java:1578)
[java] at net.java.sip.communicator.impl.media.CallSessionImpl.allocateMediaPorts(CallSessionImpl.java:1519)
[java] at net.java.sip.communicator.impl.media.CallSessionImpl.createSessionDescription(CallSessionImpl.java:989)
[java] at net.java.sip.communicator.impl.media.CallSessionImpl.createSdpOffer(CallSessionImpl.java:573)
[java] at net.java.sip.communicator.impl.protocol.sip.OperationSetBasicTelephonySipImpl.createOutgoingCall(OperationSetBasicTelephonySipImpl.java:257)
[java] at net.java.sip.communicator.impl.protocol.sip.OperationSetBasicTelephonySipImpl.createCall(OperationSetBasicTelephonySipImpl.java:116)
[java] at net.java.sip.communicator.impl.gui.main.call.CallManager$CreateCallThread.run(CallManager.java:833)
[java] Caused by: java.util.jar.JarException: Cannot parse reference:file:sc-bundles/media.jar
[java] at javax.crypto.SunJCE_c.a(DashoA13*..)
[java] at javax.crypto.SunJCE_b.b(DashoA13*..)
[java] at javax.crypto.SunJCE_b.a(DashoA13*..)
[java] ... 11 more

Ok, the main points of interest, to say so, are the two bolded lines. After some "Google research" done, I've reached a conclusion for the moment (but I'm not very sure about it..). The SecurityException is thrown because the Sun provided implementation of the JCE needs to authenticate any Provider used for cryptography services. According to the bouncycastle site their jar is signed, but... the jar I use at the moment isn't actually the original jar from their site. It is a modified version, made by Su Bing last year, for which I don't know exactly the modifications made. Still, I don't know if the problem resides at the used bouncycastle jar because the exception states it is caused by a jar exception of not being able to parse the media jar. Why is the media jar involved in all these ? Because the contents of the bouncycastle jar were integrated by Su Bing last year at build time through build.xml in the media.jar, which represents the media bundle, in order to be possible to use bouncycastle services. This is related to the OSGi bundle architecture, and was, as far as I can tell after some testing done about a month ago, the reason for the modifications done by Su Bing to the bouncycastle jar = using the original one as it is results in the media bundle failing to start (if I recall corectly). But, as I said before, I'm not sure if the SecurityException thrown is related to these modifications (which again I don't know exactly what about they consist in or how significant they are) or if it is based only on the fact the the bouncycastle code is "embedded" inside the media jar.

Ok, this is the description of the problem. Since Monday I was able to think on some solutions, but I'm not sure any of them will work (or how good they are).

One - quite innapropriate - found after another round of "Google research" can be to use a clean-room JCE implementation which won't try to check at runtime if the bouncycastle provider is authenticated. Like I said I find this quite innapropriate regarding the fact that the bouncycastle jar is signed and in theory there shouldn't be a problem related to the authentication. Besides that, I've looked a bit for some clean room JCE implementations and there aren't many of them (though I didn't do exactly an extensive search - BouncyCastle provides one and I found one more provided by Cryptix). Add to this that I don't know if they're compatible with the current sources (the BouncyCastle one is JDK 1.3 compliant and about the Cryptix one I'm not very sure). Anyway, this approach might be a temporarily solution if nothing else works.

The other solutions focus on eliminating the cause of the problem, rather than effect, about which cause I'm not sure what actually is it, as stated above, in the problem description. So, one option, would be to try separate the bouncycastle jar from the media jar and to import it as an external source, which I don't know if it's possible. If I recall correctly there is a Bundle-Classpath parameter available for the OSGi bundle manifest, but at this very moment when I'm writing I'm not sure if it could be of some use for this. I'll do a bit of research to find out, but any feedback from someone experienced with the OSGi architecture for this and actually for a possible solution for the whole matter should be very helpful.

Another solution, which again I don't know it will solve the problem is to try using the original bouncycastle jar. For this I should try using it again, compare the logs and the behavior, and see if I can't figure out what is the problem exactly. If this won't be enough (and according to last time attempt, might not be..) I'll probably should unpack the modified one and look at the differences (there is a small problem here - the modified one is version 1.37 and the bouncycastle provided one reached version 1.39 meanwhile, and I don't see any web archive with older releases on their site, but maybe I didn't look deep enough.. and anyway a comparison should be possible between different versions too).

This is pretty much what I have in mind at this moment as possible solution. Any feedback about any part of the problem - cause or solution is very welcome.

In the next part of this week, I'll try to find a way to solve it and do some more debugging for the current sources in parallel if possible + adding the SAS support as a provisional solution in the main GUI interface until integrating it through a plugin.

Wednesday, June 11, 2008

Activity Log : GSoC Week #07 (2.VI - 8.VI)

First of all, sorry about the delayed posting. Got stuck with a small problem about which I'll detail in the end.

The code modifications since last week can be found here:

These contain also Werner's sources ( that's the reason for their size :) ), about which I'll talk a bit later.

I'll detail now what I've managed to do since last week. I've changed a bit the steps discussed - more exactly, I've started focusing on the GUI part before actual finishing the library integration (where actual finishing = mainly eliminating bugs) because the GUI actions are related to triggering ZRTP startup.

So, I'll start explaining how things work from the point where the user activates the secure communication until the library code is used. I think it will be more clear this way.

I decided to activate the secure communication (and when I tell secure - I mean it in a general way, not directly related to ZRTP) through a button on the main quick menu toolbar. Actually I had an initial idea, which I started to develop to add this button and the additional ZRTP specific features (like a SAS label) through a ZRTP GUI plugin. But it didn't seem right because first of all - like I said - the button isn't actually related only to ZRTP, and above all it has a pretty general/important function by triggering secure communication from the media package. So I've decided to separate it from the ZRTP GUI part (about which I need a feedback on how and more important where it's prefered to be added; I'll detail later). In conclusion, I've added the specific button and it's handler to the QuickMenu class. I've also added the ability to provide the media service on the GUIActivator, the media service being used in the QuickMenu class by the button handler to set a general secure on/off communication parameter. That's about all the modifications I've done inside the GUI part of SC. I hope I wasn't very "invasive" :). You can see how it looks by running SC or in the next screenshot:







(1. I won't mind if you don't agree with my button "design" and somebody repaints it :) and 2. I really don't know why the mouse cursor wasn't caught in the screenshot but I assure you the tooltip appears because it's there :) )

I'l continue now with the way the code "flows" starting from the button and I'll be back to GUI in the end. Like I said, the button sets a general parameter to toggle communication security on and off. This parameter is actually the usingSRTP boolean member of CallSessionImpl for which I've changed a bit the role as it follows.

There are two distinct moments when the user could toggle the secure status on or off.

1. There isn't any call going on

In this case any call that follows the on/off secure setting made by user should use that setting by default to choose what kind of call - secure/unsecured - to start (e.g.: the user starts SC - lets' say usingSRTP is false by default, toggles secure communication on - usingSRTP true, makes a call - the call will be secured). The problem was that usingSRTP was an instance variable so it didn't exist until the call was created and in the above example it should be set before this happens. The solutions were to make it static or to pass it as a parameter at call session creation by moving it in the MediaServiceImpl. I decided for the first solution to keep as much as possible in the call session and to interact less with the media service. Anyway this can be discussed (with respect to section 2. below), because the value setting for usingSRTP at a button click is still done by using a getter and a setter exported by the media service. I didn't see other entry point possible for the Call Session.

2. There is a call going on

This will be the case when the user is involved in a call and decides to change the secure status for the communication (e.g. : GoClear in ZRTP from secure to normal stream or GoSecure from normal stream to secure). The same thing as before happens with the usingSRTP parameter, but this time also an event will be received by the CallSessionImpl instances notifying that a change in the security status is indicated. I've designed a SecureEventListener/SecureEvent mechanism for this. More exactly the CallSessionImpl implements the secure listener and registers itself as it's own listener in the callStateChanged method when CALL_IN_PROGRESS is received - when call starts, and removes itself from the listeners Vector in the same method at CALL_ENDED when the call ends. So, between these two moments the CallSession will handle, in the secureStatusChanged method, any usingSRTP secure/unsecure modification triggered by the user through the GUI.

Now, like I said in the start, usingSRTP is exactly what it sounds like = using SRTP general indication independent of the key management solution, and the behaviour described above respects also this, which keeps open the posibility of future adding other key sharing solutions. For this, a very basic approach (which should be further developed) is the small implementation done in the keyshare package, which was present also in the last patch, but I've modified it a bit by changing the names to keep it more distinct to the cryptography services providers, and also added a priority field. This should be used in a more advanced algorithm in case of more than one key management systems are present, to select which of them should be used. For now ZRTP being the only one considered, it has the highest priority :). The key management type to be used is being held in the selectedKeyProviderAlgorithm. Actually, this is, I might say the point where the implementation gets different, until now being based on general secure on and off. Based on this selectedKeyProviderAlgorithm type (which might be for now ZRTP, Dummy hardcoded SRTP keys or none) the few general actions in CallSessionImpl related with communication securing are performed different. For example the handling of the SecureEvent during a call which announces a change in the secure mode is ignored in case of Dummy hardcoded SRTP or no securing algorithm, and the Go Clear or Go Secure actions are performed only in case of ZRTP. About this, I've used Werner's ZRTPTransformEngine startZrtp and stopZrtp for now to have some handling methods there, but for stopZrtp I know it's not exactly what is needed for GoClear. About startZrtp I'm not sure if it's ok or not for a GoSecure, after a previous GoClear, as I didn't manage to get deeper yet into the code and compare it with the ZRTP standard, but I suppose it's close :). Anyway, I didn't manage to make a succesfully test yet to see how it actually works (I'll tell in the end where I'm stuck now).

Well, I've reached the point where I should talk about how Werner's library is integrated besides the mentions made on GoSecure/GoClear above. It's not very much to tell. Essentially I've followed the steps on Werner's demo package and adapted to the CallSessionImpl class ( it took more figuring how I'll use Werner's modified SRTP packages :) ). So, the integration (as it's now implemented) could be resumed in the next ideas:


  • based on the selectedKeyProviderAlgorithm type in the initializeRtpManager a ZRTP connector is created by calling the specific function from the TransformManager, after which the RTP Manager is initialized with the connector as parameter

  • ZRTP is actually started in the update methods for the ReceiveStream and SendStream events (in case events are new stream events) by getting the engine instance from the connector and calling startZrtp; I've added an isStarted getter to Werner's ZRTPEngine for this in order not to call the startZrtp method in both of the update handlers; I'm new to JMF and to Werner's code also and I'm not sure if all this is actually OK (I still have some bugs before this point and didn't reached it yet) so some feedback after looking into the sources will be welcome

  • The same startZrtp (and for now stopZrtp) is called also as said before, for handling any during-call-security-status-change-events

  • Werner added the option of choosing a custom Java Security Provider for cryptographic services and modified the SRTP packages accordingly, so I've added in the TransformManager class two functions for minimum support of this customization, somehow similar to the way I've dealed with the custom key management system described above; the functions are initializeProviders which should query the current supported security services providers, and selectProvider which should select one of them for usage; of course for now only one option here too - BouncyCastle; any way the mentioned functions should be further developed and also I'm not sure the way I've integrated them now it's the best approach possible; also related to this I've added a cryptoProvider parameter to the createZrtpConnector too

  • The createZrtpConnector function in the TransformManager practically concludes the access to the library instantiating a ZRTPTransformEngine, selecting a cryptography services provider, creating the connector, and making the necessary initializations in the engine (setConnector, setUserCallback, setCryptoProvider)

About the user callback initialization of the ZRTP engine - I've defined a SCCallback class in the keyshare.zrtp package to be used for this, class which resembles pretty much the internal MyCallback class from Werner's demo package. The difference is that I've provided GUI access in it by getting a UIService reference from the BundleContext provided by the MediaActivator. From this reference to UIService we easily can bring up popup messages (as all functions do at the moment in the respective class). The problem is that I don't know how this approach will comply with the requirement stated by Werner that I quote: "All methods of the user callback class and classes that extend this class run in the context of the RTP thread. Thus it is of paramount importance to keep the execution time of the methods as short as possible." I'll need some feedback about this from an SC GUI developer, or we should see at testing how it works. Also, popup messages aren't the proper solution for all the GUI interaction parts in that callback class. The SAS message for example should be displayed for the entire call duration I think (or at least it should be possible to do this, correct me if I'm wrong) so a Label or some other GUI element should be added for this to the interface. The main problem for me at this point is where :). To be more clear for a feedback from a GUI developer the SAS message is an authentication string for the current call which the user should be able to check with his peer by voice (we could force the user to check the SAS when it's established through a popup message but I don't recall this being mentioned by the standard :) so this is the reason why we should keep it on for the entire call duration). The string has 4 digits as I recall, but I think it depends on the rendering algorithm (I need some feedback from Werner on this, or I'll take another look in the standard to see exactly). So, like I said, the main problem was where to display this. An idea was in the toolbar near the GoSecure button only when the call is active and security is on. Anyway I don't recall exactly at this moment if there are other GUI elements beside this and various information and confirmation messages. For the last part, as I've read in the tutorial, the UIService provides Confirm dialog and Input Dialog as easy as the popup messages so it shoudn't be a problem. If there are any other elements (of which I don't recall to be at this moment), I'll ask Werner to give some feedback if possible. About how the SAS part will be implemented there are two options - one to add it as I did with the button, or to make a GUI plugin for this. Again I'll need some feedback from a GUI developer. (I left actually some minimum remains from the initial plugin I've started in the sources to develop it as a plugin for a SAS but it seems a bit innapropriate - it may be not, though - to make a plugin for displaying only a label; if there are some other elements it's another story) . One more idea related to the SAS is that if adding it as a JLabel to the QuickMenu isn't possible (maybe, it's not supported) it could be very well added as another (bigger) inactive button on which we can change the caption string. That will be pretty much about the interface issues I face right now.

I left the bigger problems for last. The first of them was the fact that Werner modified the SRTP implementation and added it as component packages to ZRTP4J. So I didn't know what to do as first - to use them directly from ZRTp4J or to override them on the previous SC code. Finally I chose the last, on the reason because after all SRTP might be used by other key management system also, and seemed more appropriate. For now as it can be seen also from the patch, I've modified the SRTP packages in the SC code to Werner's version and added only:

  • gnu.java.zrtp

  • gnu.java.zrtp.jmf.transform

  • gnu.java.zrtp.packets

  • gnu.java.zrtp.utils

  • gnu.java.zrtp.zidfile

  • demo


I didn't add the rest because there would be duplicates in the ZRTP4J and SC code. I've also modified the references in the ones mentioned to point to the ones in SC. Like I've said these arent the original SC SRTP packages, I've modified them according to Werner's optimized sources. I also was able to take a look at the modifications Werner did while doing this and I might have some questions (but in another post, after I'll look again at what I didn't understand at the first time). I made a small modification also, by changing a ZrtpUtil package function array comparison call to an inline implementation in order to keep SRTP not depending on the rest of ZRTP library. I know that eventually ZRTP probably should be used as a jar, but for now during the development phase it seems better to integrate it as direct sources (still I don't know if the described approach is the best and I'd like some feedback from Werner and Romain also).



Also about this way of integrating the sources for now, and if this is ok or not, might be related the point where I'm stuck now. To be more clear the packages are added as they were sent by Werner in the mail I've got, moved in the src folder of SC. So the imports are made using import gnu.java.zrtp... The build goes well, but at exec time I got a
java.lang.NoClassDefFoundError: gnu/java/zrtp/jmf/transform/zrtp/ZrtpTransformConnector in CallSessionImpl at the TransformManager.createZRTPConnector call (line 1558) . I'm not stuck at this since very long (so I hope I'll probably figure it out eventually) but until now I don't see a reason for it. The class is built and it is there at the respective path in the bin folder of SC. Maybe I should add some imports in a manifest file, but the Felix console doesn't report any problem related with the gnu packages at runtime so I don't know if the problem resides here. Anyway I'm not very experienced with OSGi to know for sure. Also, I don't think this is a classpath problem, the gnu folder being at the same level with the net folder in src, and the imports are made in similar way. If somebody could provide some help until I'll figure it out, I'll appreciate it very much.



This should be all for the last week (and the beginning of this one also). I'll be waiting for some feedback, until which I'm gonna try getting over the mentioned problem and further testing the current implementation form. Also, I'll try getting the sources posted on the SC dedicated svn branch at java.net until next week.

Tuesday, June 3, 2008

Activity Log : GSoC Week #06 (26.V - 1.VI)

Finally got over with my exams last week, so I started writing my first lines of code in the weekend. You can find these here:



I've also received Werner's code (which I might say again is much more advanced than I am into the matter). After I've looked into it, though I didn't finish yet, my opinion is that it will possibly be a solution not very hard to do, to follow his integration approach, which differs a bit from mine, and find a way to bind it to SIP Communicator; or may also be a solution to combine the approaches, like I'll describe in the end.

Until then, a few words about what I have done until receiving Werner's code:



The sources posted consist mostly of a simple skeleton solution for binding the ZRTP services into the current SRTP implementation. I've tried to make detailed comments inside them so I'll be more short here describing only the general idea:



(I'm not sure how clear I'll be, so I'll recommend for everybody who reads forward to look at the same time on the sources also to get the idea)



I have added two packages : keyshare and keyshare.zrtp.



The connection "starts" in this case also, as for SRTP, in the CallSessionImpl class, in the initializeRTPManager method. The keyshare package contains a very small interface KeyProvider which is intended to define the current supported key management/provider types (for now only ZRTP and a DummyProvider) and has a method for retrieving the provider type. The interface is implemented by two classes, ZRTPProvider and DummyProvider as mentioned, which act more like some constants. The createSRTPConnector in the TransportManager class takes as last parameter an object which implements KeyProvider. Based on the provider type retrieved through the method I've mentioned above it acts accordingly to start the associated implementation for key management (takes a branch on an if to be more clear :) ). In case of ZRTP provider type it instantiates a ZRTPConnector (about which I'll talk below). In case of a DummyProvider procedes as it did before instantiating a SRTPConnector with the hardcoded keys. I made all this selection process (which actually should be developed a bit more) with the purpose to offer a possible entry point for other key management solutions.



(Actually, the KeyProvider interface defined also methods for getting and setting the crypto parameters needed to provide for the SRTP transformation, but I removed them yesterday because I found it to be a bit redundant - the SRTPTransformEngine has already the getters for these; so in conclusion the Provider type classe might look a bit strange and probably could be reduced only to the constants - or could be let this way in case of possible additional methods to be added)



This was the description of the "choosing" of the ZRTP key management solution or any other one (which process isn't final, as I said). Now, focusing on the actual ZRTP part. I've left the description at instantiating the ZRTPConnector in the TransformManager. The ZRTP related classes are contained in the keyshare.zrtp package, and of course the ZRTPConnector is also there. Before going forward, I'll insert a scheme which presents the most important points of interconnection in this package, regarding the integration problem.





I know it's not really UML but I hope it's understandable :). I've described also inside the source comments how it works, so I won't get into deep details here. Shortly speaking, it's like I said a skeleton implementation which runs in the next way:

  • ZRTPConnector extends TransformConnector and overrides all the methods concerned with the input and output stream creation
  • ZRTPConnector makes use of two specific ZRTP input and output stream classes, which extend TransformInputStream and TransformOutputStream, overriding the read and write methods.
  • These methodes are the ones directly responsible with receiving and sending the packets. This is the point of actually binding ZRTP to SC by using in these methods the specific ZRTP services provided by the ZRTP4J library which should be accessed through a ZRTPPacketManager class instance (which is empty at this moment).
  • A sole instance of this class is passed both to the input and the output stream by the ZRTPConnector, which fact provides the possibility to "communicate" between the read and write methods if needed or any other type of interaction between the input and output stream.
  • In the read and write methods, based on the information provided by the ZRTPManager about the ZRTP state, the streams may send RTP, SRTP or ZRTP packets (for SRTP is called the base class implementation - which I've tested).
  • The read and write methods have access to the SRTPTransformEngine to set and get the necessary info they need in the ZRTP communication. This is done by accessing the base class SRTPPacketTransformer member which may expose the SRTPTransformEngine through a getter.

This would be in rough lines my idea of integration. It's explained a bit more in detail in the comments inside the sources.

I don't know if it's ok or not. It might bring some limitations at some points, but I'm not so experienced to ZRTP to see exactly where now. I've tried to keep the SRTP-ZRTP coupling as low as possible. As it can be seen, all the idea is like practicaly adding a ZRTP separate layer, the only modifications I've done in the SRTP implementations being adding some getters and some setters for the derived classes.

Werner's approach after a basic look I've taken into the sources, is based on defining a ZRTPTransformEngine for the main part of the integration. This engine, as far as I can tell after a quick analysis, has pretty much the role I've imagined for my ZRTPPacketManager, so one option would be to adapt Werner's ZRTPEngine interaction to fit my approach related to ZRTPPacketManager (if it's a good approach, about which I have some doubts...) and "connect" the way I described, to the ZRTP library.

This is only an idea which might be taken into consideration :), but as said at start it may be also even better to try finding an integration way for ZRTP4J, based directly on Werner's current transform.zrtp package design (which doesn't seem to hard, but I still need to get some more things clear). Like I said, I still have a bit more to look on the sources to understand them better, and I'll try to think on the integration part also while doing that (maybe I'll get some ideas until the chat).

PS:

Sorry for not posting last evening, as I said I'll try in my mail. Have the bad habit of commenting the code after I finish a work phase, and this time the code comments took longer than I thought : ...