blob: e2848a10902a101830275ea1c4608745293f64ad [file] [log] [blame]
Harald Alvestrand0d018412021-11-04 13:52:311/*
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"
Harald Alvestrand0d018412021-11-04 13:52:3130#include "rtc_base/ssl_stream_adapter.h"
31
32// Forward declaration to avoid pulling in libsrtp headers here
33struct srtp_event_data_t;
34struct srtp_ctx_t_;
35
36namespace cricket {
37
38// A helper class used to negotiate SDES crypto params.
39// TODO(zhihuang): Find a better name for this class, like "SdesNegotiator".
40class 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
86 absl::optional<int> send_cipher_suite() { return send_cipher_suite_; }
87 absl::optional<int> recv_cipher_suite() { return recv_cipher_suite_; }
88
89 rtc::ArrayView<const uint8_t> send_key() { return send_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_