From 43aa1b15a16fe6bc91d824b1a6a576f55dddde86 Mon Sep 17 00:00:00 2001
From: Vincent Lucas <chenzo@jitsi.org>
Date: Thu, 2 Aug 2012 08:53:41 +0000
Subject: [PATCH] Adds SDES for XMPP. Works with Jingle and GTalk (only for
 gmail web app, doesn not work on "talk" for android).

---
 .../transform/sdes/SDesControlImpl.java       | 78 +++++++++++++------
 .../transform/srtp/SRTCPTransformer.java      | 16 +++-
 .../jitsi/service/neomedia/SDesControl.java   | 20 +++--
 3 files changed, 80 insertions(+), 34 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java b/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
index c9b9c36e..28355df1 100644
--- a/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
+++ b/src/org/jitsi/impl/neomedia/transform/sdes/SDesControlImpl.java
@@ -150,63 +150,97 @@ public void setMultistream(SrtpControl master)
     public TransformEngine getTransformEngine()
     {
         if(engine == null)
+        {
             engine = new SDesTransformEngine(this);
+        }
         return engine;
     }
 
-    public String[] getInitiatorCryptoAttributes()
+    /**
+     * Initializes the available SRTP crypto attributes containing: he
+     * crypto-suite, the key-param and the session-param.
+     */
+    private void initAttributes()
     {
         if(attributes == null)
         {
             attributes = new SrtpCryptoAttribute[enabledCryptoSuites.size()];
             for (int i = 0; i < attributes.length; i++)
             {
-                attributes[i] =
-                    sdesFactory.createCryptoAttribute(i + 1,
+                attributes[i] = sdesFactory.createCryptoAttribute(
+                        i + 1,
                         enabledCryptoSuites.get(i));
             }
         }
-        String[] result = new String[attributes.length];
-        for(int i = 0; i < attributes.length; i++)
-            result[i] = attributes[i].encode();
-        return result;
     }
 
-    public String responderSelectAttribute(Iterable<String> peerAttributes)
+    /**
+     * Returns the crypto attributes enabled on this computer.
+     *
+     * @return The crypto attributes enabled on this computer.
+     */
+    public SrtpCryptoAttribute[] getInitiatorCryptoAttributes()
     {
-        for (String suite : enabledCryptoSuites)
+        initAttributes();
+
+        return attributes;
+    }
+
+    /**
+     * Chooses a supported crypto attribute from the peer's list of supplied
+     * attributes and creates the local crypto attribute. Used when the control
+     * is running in the role as responder.
+     * 
+     * @param peerAttributes The peer's crypto attribute offering.
+     *
+     * @return The local crypto attribute for the answer of the offer or null if
+     *         no matching cipher suite could be found.
+     */
+    public SrtpCryptoAttribute responderSelectAttribute(
+            Iterable<SrtpCryptoAttribute> peerAttributes)
+    {
+        for (SrtpCryptoAttribute ea : peerAttributes)
         {
-            for (String ea : peerAttributes)
+            for (String suite : enabledCryptoSuites)
             {
-                SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea);
-                if (suite.equals(peerCA.getCryptoSuite().encode()))
+                if (suite.equals(ea.getCryptoSuite().encode()))
                 {
-                    selectedInAttribute = peerCA;
-                    selectedOutAttribute =
-                        sdesFactory.createCryptoAttribute(1, suite);
-                    return selectedOutAttribute.encode();
+                    selectedInAttribute = ea;
+                    selectedOutAttribute
+                        = sdesFactory.createCryptoAttribute(1, suite);
+                    return selectedOutAttribute;
                 }
             }
         }
         return null;
     }
 
-    public boolean initiatorSelectAttribute(Iterable<String> peerAttributes)
+    /**
+     * Select the local crypto attribute from the initial offering (@see
+     * {@link #getInitiatorCryptoAttributes()}) based on the peer's first
+     * matching cipher suite.
+     * 
+     * @param peerAttributes The peer's crypto offers.
+     *
+     * @return A SrtpCryptoAttribute when a matching cipher suite was found.
+     * Null otherwise.
+     */
+    public SrtpCryptoAttribute initiatorSelectAttribute(
+            Iterable<SrtpCryptoAttribute> peerAttributes)
     {
-        for (SrtpCryptoAttribute localCA : attributes)
+        for (SrtpCryptoAttribute peerCA : peerAttributes)
         {
-            for (String ea : peerAttributes)
+            for (SrtpCryptoAttribute localCA : attributes)
             {
-                SrtpCryptoAttribute peerCA = SrtpCryptoAttribute.create(ea);
                 if (localCA.getCryptoSuite().equals(peerCA.getCryptoSuite()))
                 {
                     selectedInAttribute = peerCA;
                     selectedOutAttribute = localCA;
-                    return true;
+                    return peerCA;
                 }
             }
         }
-        return false;
+        return null;
     }
 
     public SrtpCryptoAttribute getInAttribute()
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java b/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
index 11e63689..20d16d59 100644
--- a/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
+++ b/src/org/jitsi/impl/neomedia/transform/srtp/SRTCPTransformer.java
@@ -90,12 +90,12 @@ private SRTCPCryptoContext getContext(
             SRTPTransformEngine engine)
     {
         long ssrc = pkt.getRTCPSSRC();
-        SRTCPCryptoContext context;
+        SRTCPCryptoContext context = null;
 
         synchronized (contexts)
         {
             context = contexts.get(ssrc);
-            if (context == null)
+            if (context == null && engine != null)
             {
                 context = engine.getDefaultContextControl();
                 if (context != null)
@@ -136,7 +136,15 @@ public RawPacket transform(RawPacket pkt)
     {
         SRTCPCryptoContext context = getContext(pkt, forwardEngine);
 
-        context.transformPacket(pkt);
-        return pkt;
+        if(context != null)
+        {
+            context.transformPacket(pkt);
+            return pkt;
+        }
+        else
+        {
+            // The packet can not be encrypted. Thus, does not send it.
+            return null;
+        }
     }
 }
diff --git a/src/org/jitsi/service/neomedia/SDesControl.java b/src/org/jitsi/service/neomedia/SDesControl.java
index c7875f15..8036d006 100644
--- a/src/org/jitsi/service/neomedia/SDesControl.java
+++ b/src/org/jitsi/service/neomedia/SDesControl.java
@@ -38,12 +38,11 @@ public interface SDesControl
     public Iterable<String> getSupportedCryptoSuites();
 
     /**
-     * Gets the encoded SDES crypto-attributes for all enabled ciphers when the
-     * control is used as the initiator.
-     * 
-     * @return the encoded SDES crypto-attributes for all enabled ciphers.
+     * Returns the crypto attributes enabled on this computer.
+     *
+     * @return The crypto attributes enabled on this computer.
      */
-    public String[] getInitiatorCryptoAttributes();
+    public SrtpCryptoAttribute[] getInitiatorCryptoAttributes();
 
     /**
      * Chooses a supported crypto attribute from the peer's list of supplied
@@ -51,10 +50,12 @@ public interface SDesControl
      * is running in the role as responder.
      * 
      * @param peerAttributes The peer's crypto attribute offering.
+     *
      * @return The local crypto attribute for the answer of the offer or null if
      *         no matching cipher suite could be found.
      */
-    public String responderSelectAttribute(Iterable<String> peerAttributes);
+    public SrtpCryptoAttribute responderSelectAttribute(
+            Iterable<SrtpCryptoAttribute> peerAttributes);
 
     /**
      * Select the local crypto attribute from the initial offering (@see
@@ -62,9 +63,12 @@ public interface SDesControl
      * matching cipher suite.
      * 
      * @param peerAttributes The peer's crypto offers.
-     * @return True when a matching cipher suite was found, false otherwise.
+     *
+     * @return A SrtpCryptoAttribute when a matching cipher suite was found.
+     * Null otherwise.
      */
-    public boolean initiatorSelectAttribute(Iterable<String> peerAttributes);
+    public SrtpCryptoAttribute initiatorSelectAttribute(
+            Iterable<SrtpCryptoAttribute> peerAttributes);
 
     /**
      * Gets the crypto attribute of the incoming MediaStream.
-- 
GitLab