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