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 : ...

Tuesday, May 27, 2008

Activity Log : GSoC Week #04-#05 (12.V - 25.V)

Unfortunately I didn't have more than a weekend free these weeks so this entry will be quite short:
  • Regarding the problem I was talking about in my last post about how JMF (or FMJ) will handle the ZRTP packets, I think I've reached a conclusion, after I read the JMF samples here: http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/solutions/ (the RTP streaming section) and took another quick look into the JMF API Guide (which wasn't of very much help though because it doesn't contain the RTP Manager/Connector additions). As a reminder: the RTPConnector "acts" on the packets passed by the RTPManager before these are sent into network and on the receiver side, before these are passed to the receiver's RTPManager. So, I believe there shouldn't be a problem with the different ZRTP header (as I thought it might be) as long as all ZRTP traffic is being held in the boundary of a ZRTP RTPConnector dedicated implementation, in a similar way like SRTP is. Otherwise, if the packets would "reach" the RTPManager, there will be a problem probably with the unknown Format, resulting in the need of registering a new one, and things might get a bit to complicated. In conclusion, I think the idea of using a ZRTP dedicated Connector and consequently keeping most of the ZRTP management related to it remains the best option.
  • I also managed to make another comparison between the FMJ API and JMF one, on a few RTP related classes (did it once more at the start of GSoC), and as discussed on the dev list I can't find any differences (RTPConnector, RTPManager and few other classes included here). This, anyway, is only in rough API terms = looked at the function signatures provided by one and compared to the other. I decided to do this once more, after the problems Werner reported on the dev list with FMJ. I didn't manage to get deeper (I wanted actually to investigate a bit further about what are the differences related to the way ReceiveStreamEvent is handled - Werner's reported problem - between JMF and FMJ, but it seems that the JMF sources aren't available any longer on the Sun site: http://www.sun.com/software/communitysource/jmf/download.xml - eventually I'll look for them in other place). Anyway, as I said also on the mailing list, if the ZRTP solution will be based on the common API parts used by JMF and FMJ (which will be almost certain according to the comparison made above), it shouldn't be a problem on which of them is run and tested. Just as a fact, I personally did read a bit more about JMF in this first GSoC phase, so many assumptions are based on this knowledge - hope it applies on both of them (I tried to find some FMJ tutorials but there seems there aren't any - or I didn't look for them enough) .
  • The next steps: fortunately this week I'll be over with my exams (one more research project next Tuesday but that won't be a problem), and I'll finally be able to use most of my time for GSoC beginning with the next week, so probably this weekend (or next Monday latest) I'll try writing the starting code for the RTPConnector based ideas mentioned above. I still must talk to Werner about what exactly his library ZRTP4J provides and any integration issues related to this (probably also Monday) and must see how I'll use the UIService to connect the GUI to the Connector part. All these probably in my next activity log entry :).

Thursday, May 15, 2008

Activity Log : GSoC Week #03 (5.V - 11.V)

A bit late with the entry for this week, but better late than never :)

The activity for the third GSoC week was centered, as said in a previous post on reading the ZRTP standard and getting a bit deeper into the SC SRTP implementation.

I'll try in this entry to summarize the most important notes I took while reading the ZRTP standard.

First of all, I'm reproducing the typical establishment of SRTP using ZRTP diagram from the standard, for better understanding of the next comments, in case someone not very familiar with ZRTP will ever take a look on this blog:





There are many points in the standard where the operation of ZRTP is related to the signaling level. Most of them are concentrated in chapter 9 - Signaling Interactions, but are reminded also during the other chapters. Before reading the standard I was pro keeping the ZRTP integration as much as possible at the media level, in order for a possible support by various signaling protocols in the future, not only SIP. Anyway according to section 9 there are some advantages in interacting with the signaling protocol. Some examples are:

- advertising the ZRTP support through SDP (a=zrtp-hash attribute in the SDP offers and answers) which according to the standard permits an easily detection by other possible future implemented key management protocols and ease of implementing cooperation between these and ZRTP
- additional security support like preventing a third party to insert false media packets [section 9.1] but bringing also the drawback of possible DoS by an attacker who controls the signaling layer [also section 9.1]

However, regarding the fact that (quote from section 9): "ZRTP may be implemented without coupling with the SIP signaling", I still remain pro keeping the integration at the media level, at least for an early phase. Anyway, after all runs ok and it's stable, interacting with the signaling level probably should be considered.

Also related to the signaling level interaction is the discovery phase of ZRTP which is based on two options: including the a=zrtp-hash in SDP offers and answers or/and using an RTP extension field as a flag to indicate support. Regarding the above mentioned, I'll be in favor of the second option (for start at least).
About the actual integration in SC, I'm a bit unclear related to the discovery phase about how the ZRTP packets will be treated by JMF. In case of SRTP, the integration in SC, acts like a filter for the outgoing and incoming packets, but SRTP packets have a similar header with RTP, ZRTP ones don't. In conclusion, I don't know for the moment how the ZRTP packets, multiplexed on the same port through another RTPConnector derived class will be handled by JMF, and if a similar filtering like method will be enough (or additional operation like defining a specific format or other stuff related to the RTP/AVP profile is needed). Anyway, this week hopefully I'll have it made clear after I'l look one more time over the JMF API Guide and in the SC sources ( any possible helpful feedback is very much appreciated though :) )
Because I am at this point, regarding the filtering like approach through a Connector and TransformEngine (actually more like a CreateEngine in this case) classes as I was thinking from the GSoC eval phase, and also proposed by Werner Dittmann, in very very rough lines I think on this (from the sender point of view) like :

- the media stream in call starts
- if ZRTP is activated the Connector intercepts it and:



  • in case ZRTP communication is needed, the neccessary packets are created and sent;
  • this will be done through the usage of a Transform(Create)Engine and any additional classes as I thought initially, which after the recent news :) will be probably actually through a dedicated library (Werner's proposal), or through an Engine class which uses this library;
  • the RTP stream that should be sent during this is dumped (the standard states that during Commit-Conf2Ack for the initiator, and during Commit-Confirm2 for the responder no media should be sent; in other cases of ZRTP communication besides SRTP activation this "no sending" rule also applies - should check again the standard anyway to see where doesn't);
  • after the ZRTP communication ends, the media stream is again let to go through by the Communicator (of course if other rule like tearing down the session doesn't apply)

Like I said in my previous post, this is an opinion about integration pretty close to the one had during the GSoC eval phase, and also to the solution expressed by Werner, and I'm thinking to start a basic design for the classes based on it (e.g. the Connector, the Engine, etc) - (good to have some feedback here if possible too = would be a good approach or not).

Going forward with the standard related ideas, there is needed (like Werner said also) a way for the ZRTP implementation to communicate with the GUI. About how this should be done, my first idea relates to a GUI plugin as described in the dev page tutorial on the SC site, but I need to think more about how this should connect with the ZRTP implementation. For now, some parts that should need GUI support are:

  • not related with the standard effectively, (but I'm thinking it would be necessary) an interface element, which should announce the user that some stream securing (ZRTP) activity is in progress, in order to make him aware about the reason for eventual silence periods (like said previously, the standard states that during some points of protocol transmission, no media stream should be sent; in addition to this, there are specified some retransmission timers for the protocol messages, so I think that possible long no-sound breakes might appear ... anyway, I'm far from being experienced with ZRTP exchange, so someone should correct me if I'm wrong)

  • the SAS verification can be done according to the standard through verbal communication (actually reading the rendered string by the user), through exchanging and comparing over the signaling channel using the a=zrtp-sas attribute or validating a digital signature exchanged in the Confirm1 or Confirm2 messages; I'll personally be in favor of the last solution in order to have an automatic way of verification which won't rely on the user who might skip the SAS check, and without using the signaling channel; however, the digital signature exchange through the Confirm messages is supposed to be contained in a Signature Type Block which according to section 6.1.7. is subject of future standardization; anyway a signature algorithm could be selected for use, but due to the fact described above (and not only that) the SAS should be presented through GUI to the user allowing the posibility of verbal verification

  • also related to the SAS and the GUI support, are the features described in section 5.3.3. of the standard -Handling a Secret Cache Mismatch; the user should be alerted in this case and also the standard implies that the possibility for the call to continue is available even in the case of a supposed MitM attack - so probably the user should be asked through a message box if he wants to go on or not (something similar "yes" or "no" option would also be needed through a GUI element triggered by the PBX enrollment procedure - section 8.3.1. which asks the user if he trusts a certain PBX for SAS relaying)

  • the standard states that starting the actual encryption could be done later after sending the Hello messages, when the Commit is sent, and this action might be triggered by the user through a GO SECURE button; also the user could trigger the GoClear message through another GUI button/action in order to switch back to unencrypted media communication; there is a small issue to be taken into consideration here I think, this being related to how the GUI part of this feature is implemented and communicates with the ZRTP part, in order to permit other future key management protocols; these might permit crypted/unencrypted switch also and the user shouldn't be put in front of two or more buttons to choose from; in conclusion, the only one button used to GO SECURE should have the functionality implemented in such a way that it could be extended in the future when it should probably also initiate an automatic choice process from the supported key management protocols

Other ideas/issues/questions related to the standard:

  • the first ZRTP message initiating the key exchange is the Hello (followed by HelloACK) message which will carry the SRTP configuration options and the ZID; the ZID, according to the standard is generated at ZRTP installation time, being unique and used to look up for retained shared secrets from previous ZRTP sessions with the endpoint; if I understand correctly the ZID may be generated once per application (SIP Communicator) run, before any ZRTP communication is done, in order to save time (need someone to correct me if I'm wrong)

  • the standard describes along with the normal and multistream, the preshared mode as a posibility of keying; this does rely on the already shared secret in order to skip the DH exchange; the standard doen't recommend this due to the lack of PFS (Perfect Forward Secrecy), unless the call participant is very limited in resources; I'll personally leave it away for the early phase of ZRTP integration (or more exactly I'll leave it for later; it should be done however in order to keep the full support of the standard)

  • I'm a bit uncertain about how the PBX SAS relaying should be implemented/supported; I'm reffering mostly on the actual mode of development, not on standard defined characteristics; more exactly the PBX should supply an enrollment extension; I'm not experienced at all with Asterisk (as a PBX example) so I really don't know if it (or other PBX) does supply this extension in order to test the implementation; I'll personally let this for a later phase of development because I should find out what PBX to use and how is this feature implemented (possible could use some feedback on this too, still I'd like to focus on some other issues first); anyway, the SAS PBX relay support could be implemented "blindly" according to the standard description, after all being intended to be supported by any PBX, and tested afterwards

In the end, other stuff done last week: checked (not very deep allthough - should go further when I got the time) to see if the SRTP implementation works with the standard BouncyCastle crypto library; for now it doesn't.

Related to BouncyCastle, I should check if all cryptographic related features mentioned by the ZRTP standard are supported through it (part of them are sure because there are also used in the SRTP implementation, but I don't know if all of them are there).

There are other minor notes I took on the ZRTP standard, but I think this is long enough already for a single post :). Anyway, I've read both standards and things are pretty much clear related to them exclusively. I'll start from now on to focus on the actual basic integration design in SC until the end of this month. (Hope I'll have the time... My final semester exam period starts next week )