• Travis Cross's avatar
    add enhanced zrtp passthrough (zrtp passthru) mode · 23f8967c
    Travis Cross 提交于
    ZRTP passthrough mode allows two ZRTP-capable clients to negotiate an
    end-to-end security association through FreeSWITCH.  The clients are
    therefore able to be certain that the FreeSWITCH instance mediating
    the call cannot eavesdrop on their conversation.
    
    Importantly, this capability is maintained across multiple FreeSWITCH
    hops.  If widely deployed, this enables a global network architecture
    where two people can speak securely with strong cryptographically
    protected authentication and confidentiality.
    
    With this commit we implement a zrtp-passthru mode that handles all
    the details of the negotiation intelligently.  This mode can be
    selected by setting the boolean parameter inbound-zrtp-passthru in the
    sofia profile.  This will also force late-negotiation as it is
    essential for correctly negotiating an end-to-end ZRTP security
    association.
    
    When an incoming call with a zrtp-hash is received and this mode is
    enabled, we find the first audio and the first video zrtp-hash in the
    SDP and store them as remote values on this channel.  Once a b-leg is
    available, we set the local zrtp-hash values on that channel to the
    remote zrtp-hash values collected from the a-leg.
    
    Because zrtp-passthru absolutely requires that the channels negotiate
    the same codec, we offer to the b-leg only codecs that the a-leg can
    speak.  Once the b-leg accepts a codec, we will force that choice onto
    the a-leg.
    
    If the b-leg sends us zrtp-hash values in the signaling, we store
    those as remote values on the b-leg and copy them to the local values
    on the a-leg.
    
    At this point, each leg has the zrtp-hash values from the other, and
    we know we can do ZRTP passthrough mode on the call.  We send the
    b-leg's zrtp-hash back to the a-leg in the 200 OK.
    
    We then enable UDPTL mode on the rtp streams for both the audio and
    the video so that we don't interfere in the ZRTP negotiation.
    
    If the b-leg fails to return a zrtp-hash in the signaling, we set up a
    ZRTP security association with the a-leg ourselves, if we are so
    equipped.  Likewise, if the a-leg fails to send a zrtp-hash in the
    signaling, we attempt to set up a ZRTP security association ourselves
    with the b-leg.
    
    The zrtp-passthru mode can also be enabled in the dialplan by setting
    the boolean channel variable zrtp_passthru.  If enabled in this
    manner, we can't force late-negotiation, so the user would need to be
    sure this is configured.
    
    If ZRTP passthrough mode is not enabled in either manner, this change
    should have no effect.
    
    Channel variables for each of the various zrtp-hash values are set,
    though it is anticipated that there is no good reason to use them, so
    they may be removed without warning.  For checking whether zrtp
    passthrough mode was successful, we provide the channel variable
    zrtp_passthru_active which is set on both legs.
    
    Though not implemented by this commit, the changes here should make it
    more straightforward to add correct zrtp-hash values to the signaling
    and verify that correct hello hash values are received when FreeSWITCH
    is acting as a terminating leg of the ZRTP security association.
    
    A historical note...
    
    This commit replaces the recently-added sdp_zrtp_hash_string method,
    commit 2ab1605a.
    
    This prior method sets a channel variable from the a-leg's zrtp-hash,
    then relies on the dialplan to export this channel variable to the
    b-leg, where it is put into the SDP.
    
    While it was a great start and wonderful for testing, this approach
    has some drawbacks that motivated the present work:
    
     * There's no good way to pass the zrtp-hash from the b-leg back to
       the a-leg.  In fact, the implementation seems to send the a-leg's
       zrtp-hash back to the originating client in the 200 OK.  This is
       not correct.
    
     * To support video, we'd need to have a separate dialplan variable,
       and the dialplan author would need to deal with that explicitly.
    
     * The API is problematic as it requires the dialplan author to
       understand intricate details of how ZRTP works to implement a
       correct dialplan.  Further, by providing too fine-grained control
       (but at the same time, not enough control) it would limit our
       ability to make the behavior smarter once people started relying on
       this.
    23f8967c
switch_channel.c 127.7 KB