• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2009 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef PC_SRTP_FILTER_H_
12 #define PC_SRTP_FILTER_H_
13 
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 #include "absl/types/optional.h"
21 #include "api/array_view.h"
22 #include "api/crypto_params.h"
23 #include "api/jsep.h"
24 #include "pc/session_description.h"
25 #include "rtc_base/buffer.h"
26 #include "rtc_base/constructor_magic.h"
27 #include "rtc_base/ssl_stream_adapter.h"
28 #include "rtc_base/thread_checker.h"
29 
30 // Forward declaration to avoid pulling in libsrtp headers here
31 struct srtp_event_data_t;
32 struct srtp_ctx_t_;
33 
34 namespace cricket {
35 
36 // A helper class used to negotiate SDES crypto params.
37 // TODO(zhihuang): Find a better name for this class, like "SdesNegotiator".
38 class SrtpFilter {
39  public:
40   enum Mode { PROTECT, UNPROTECT };
41   enum Error {
42     ERROR_NONE,
43     ERROR_FAIL,
44     ERROR_AUTH,
45     ERROR_REPLAY,
46   };
47 
48   SrtpFilter();
49   ~SrtpFilter();
50 
51   // Whether the filter is active (i.e. crypto has been properly negotiated).
52   bool IsActive() const;
53 
54   // Handle the offer/answer negotiation of the crypto parameters internally.
55   // TODO(zhihuang): Make SetOffer/ProvisionalAnswer/Answer private as helper
56   // methods once start using Process.
57   bool Process(const std::vector<CryptoParams>& cryptos,
58                webrtc::SdpType type,
59                ContentSource source);
60 
61   // Indicates which crypto algorithms and keys were contained in the offer.
62   // offer_params should contain a list of available parameters to use, or none,
63   // if crypto is not desired. This must be called before SetAnswer.
64   bool SetOffer(const std::vector<CryptoParams>& offer_params,
65                 ContentSource source);
66   // Same as SetAnwer. But multiple calls are allowed to SetProvisionalAnswer
67   // after a call to SetOffer.
68   bool SetProvisionalAnswer(const std::vector<CryptoParams>& answer_params,
69                             ContentSource source);
70   // Indicates which crypto algorithms and keys were contained in the answer.
71   // answer_params should contain the negotiated parameters, which may be none,
72   // if crypto was not desired or could not be negotiated (and not required).
73   // This must be called after SetOffer. If crypto negotiation completes
74   // successfully, this will advance the filter to the active state.
75   bool SetAnswer(const std::vector<CryptoParams>& answer_params,
76                  ContentSource source);
77 
78   bool ResetParams();
79 
80   static bool ParseKeyParams(const std::string& params,
81                              uint8_t* key,
82                              size_t len);
83 
send_cipher_suite()84   absl::optional<int> send_cipher_suite() { return send_cipher_suite_; }
recv_cipher_suite()85   absl::optional<int> recv_cipher_suite() { return recv_cipher_suite_; }
86 
send_key()87   rtc::ArrayView<const uint8_t> send_key() { return send_key_; }
recv_key()88   rtc::ArrayView<const uint8_t> recv_key() { return recv_key_; }
89 
90  protected:
91   bool ExpectOffer(ContentSource source);
92 
93   bool StoreParams(const std::vector<CryptoParams>& params,
94                    ContentSource source);
95 
96   bool ExpectAnswer(ContentSource source);
97 
98   bool DoSetAnswer(const std::vector<CryptoParams>& answer_params,
99                    ContentSource source,
100                    bool final);
101 
102   bool NegotiateParams(const std::vector<CryptoParams>& answer_params,
103                        CryptoParams* selected_params);
104 
105  private:
106   bool ApplySendParams(const CryptoParams& send_params);
107 
108   bool ApplyRecvParams(const CryptoParams& recv_params);
109 
110   enum State {
111     ST_INIT,                    // SRTP filter unused.
112     ST_SENTOFFER,               // Offer with SRTP parameters sent.
113     ST_RECEIVEDOFFER,           // Offer with SRTP parameters received.
114     ST_SENTPRANSWER_NO_CRYPTO,  // Sent provisional answer without crypto.
115     // Received provisional answer without crypto.
116     ST_RECEIVEDPRANSWER_NO_CRYPTO,
117     ST_ACTIVE,  // Offer and answer set.
118     // SRTP filter is active but new parameters are offered.
119     // When the answer is set, the state transitions to ST_ACTIVE or ST_INIT.
120     ST_SENTUPDATEDOFFER,
121     // SRTP filter is active but new parameters are received.
122     // When the answer is set, the state transitions back to ST_ACTIVE.
123     ST_RECEIVEDUPDATEDOFFER,
124     // SRTP filter is active but the sent answer is only provisional.
125     // When the final answer is set, the state transitions to ST_ACTIVE or
126     // ST_INIT.
127     ST_SENTPRANSWER,
128     // SRTP filter is active but the received answer is only provisional.
129     // When the final answer is set, the state transitions to ST_ACTIVE or
130     // ST_INIT.
131     ST_RECEIVEDPRANSWER
132   };
133   State state_ = ST_INIT;
134   std::vector<CryptoParams> offer_params_;
135   CryptoParams applied_send_params_;
136   CryptoParams applied_recv_params_;
137   absl::optional<int> send_cipher_suite_;
138   absl::optional<int> recv_cipher_suite_;
139   rtc::ZeroOnFreeBuffer<uint8_t> send_key_;
140   rtc::ZeroOnFreeBuffer<uint8_t> recv_key_;
141 };
142 
143 }  // namespace cricket
144 
145 #endif  // PC_SRTP_FILTER_H_
146