• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2009, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_SESSION_PHONE_SRTPFILTER_H_
29 #define TALK_SESSION_PHONE_SRTPFILTER_H_
30 
31 #include <list>
32 #include <string>
33 #include <vector>
34 #include "talk/base/basictypes.h"
35 #include "talk/session/phone/cryptoparams.h"
36 #include "talk/p2p/base/sessiondescription.h"
37 
38 // Forward declaration to avoid pulling in libsrtp headers here
39 struct srtp_event_data_t;
40 struct srtp_ctx_t;
41 typedef srtp_ctx_t* srtp_t;
42 struct srtp_policy_t;
43 
44 namespace cricket {
45 
46 // Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except
47 // in applications (voice) where the additional bandwidth may be significant.
48 // A 80-bit HMAC is always used for SRTCP.
49 extern const std::string& CS_DEFAULT;
50 // 128-bit AES with 80-bit SHA-1 HMAC.
51 extern const std::string CS_AES_CM_128_HMAC_SHA1_80;
52 // 128-bit AES with 32-bit SHA-1 HMAC.
53 extern const std::string CS_AES_CM_128_HMAC_SHA1_32;
54 // Key is 128 bits and salt is 112 bits == 30 bytes. B64 bloat => 40 bytes.
55 extern const int SRTP_MASTER_KEY_BASE64_LEN;
56 
57 // Class that wraps a libSRTP session. Used internally by SrtpFilter, below.
58 class SrtpSession {
59  public:
60   SrtpSession();
61   ~SrtpSession();
62 
63   // Configures the session for sending data using the specified
64   // cipher-suite and key. Receiving must be done by a separate session.
65   bool SetSend(const std::string& cs, const uint8* key, int len);
66   // Configures the session for receiving data using the specified
67   // cipher-suite and key. Sending must be done by a separate session.
68   bool SetRecv(const std::string& cs, const uint8* key, int len);
69 
70   // Encrypts/signs an individual RTP/RTCP packet, in-place.
71   // If an HMAC is used, this will increase the packet size.
72   bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
73   bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
74   // Decrypts/verifies an invidiual RTP/RTCP packet.
75   // If an HMAC is used, this will decrease the packet size.
76   bool UnprotectRtp(void* data, int in_len, int* out_len);
77   bool UnprotectRtcp(void* data, int in_len, int* out_len);
78 
79  private:
80   bool SetKey(int type, const std::string& cs, const uint8* key, int len);
81   static bool Init();
82   void HandleEvent(const srtp_event_data_t* ev);
83   static void HandleEventThunk(srtp_event_data_t* ev);
84 
85   srtp_t session_;
86   int rtp_auth_tag_len_;
87   int rtcp_auth_tag_len_;
88   static bool inited_;
89   static std::list<SrtpSession*> sessions_;
90 };
91 
92 // Class to transform SRTP to/from RTP.
93 // Initialize by calling SetSend with the local security params, then call
94 // SetRecv once the remote security params are received. At that point
95 // Protect/UnprotectRt(c)p can be called to encrypt/decrypt data.
96 // TODO: Figure out concurrency policy for SrtpFilter.
97 class SrtpFilter {
98  public:
99   SrtpFilter();
100   ~SrtpFilter();
101 
102   // Whether the filter is active (i.e. crypto has been properly negotiated).
103   bool IsActive() const;
104 
105   // Indicates which crypto algorithms and keys were contained in the offer.
106   // offer_params should contain a list of available parameters to use, or none,
107   // if crypto is not desired. This must be called before SetAnswer.
108   bool SetOffer(const std::vector<CryptoParams>& offer_params,
109                 ContentSource source);
110   // Indicates which crypto algorithms and keys were contained in the answer.
111   // answer_params should contain the negotiated parameters, which may be none,
112   // if crypto was not desired or could not be negotiated (and not required).
113   // This must be called after SetOffer. If crypto negotiation completes
114   // successfully, this will advance the filter to the active state.
115   bool SetAnswer(const std::vector<CryptoParams>& answer_params,
116                  ContentSource source);
117 
118   // Encrypts/signs an individual RTP/RTCP packet, in-place.
119   // If an HMAC is used, this will increase the packet size.
120   bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
121   bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
122   // Decrypts/verifies an invidiual RTP/RTCP packet.
123   // If an HMAC is used, this will decrease the packet size.
124   bool UnprotectRtp(void* data, int in_len, int* out_len);
125   bool UnprotectRtcp(void* data, int in_len, int* out_len);
126 
127  protected:
128   bool StoreParams(const std::vector<CryptoParams>& offer_params,
129                    ContentSource source);
130   bool NegotiateParams(const std::vector<CryptoParams>& answer_params,
131                        CryptoParams* selected_params);
132   bool ApplyParams(const CryptoParams& send_params,
133                    const CryptoParams& recv_params);
134   bool ResetParams();
135   static bool ParseKeyParams(const std::string& params, uint8* key, int len);
136 
137  private:
138   enum State { ST_INIT, ST_SENTOFFER, ST_RECEIVEDOFFER, ST_ACTIVE };
139   State state_;
140   std::vector<CryptoParams> offer_params_;
141   SrtpSession send_session_;
142   SrtpSession recv_session_;
143 };
144 
145 }  // namespace cricket
146 
147 #endif  // TALK_SESSION_PHONE_SRTPFILTER_H_
148