/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef PC_SRTP_SESSION_H_
#define PC_SRTP_SESSION_H_

#include <stddef.h>
#include <stdint.h>

#include <vector>

#include "api/field_trials_view.h"
#include "api/sequence_checker.h"
#include "rtc_base/buffer.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"

// Forward declaration to avoid pulling in libsrtp headers here
struct srtp_event_data_t;
struct srtp_ctx_t_;  // Trailing _ is required.

namespace webrtc {

// Prohibits webrtc from initializing libsrtp. This can be used if libsrtp is
// initialized by another library or explicitly. Note that this must be called
// before creating an SRTP session with WebRTC.
void ProhibitLibsrtpInitialization();

// Class that wraps a libSRTP session.
class SrtpSession {
 public:
  SrtpSession();
  explicit SrtpSession(const FieldTrialsView& field_trials);
  ~SrtpSession();

  SrtpSession(const SrtpSession&) = delete;
  SrtpSession& operator=(const SrtpSession&) = delete;

  // Enable or disable cryptex. May update existing session.
  bool UseCryptex(bool enabled, bool require, bool sending_session);

  // Configures the session for sending data using the specified
  // crypto suite and key. Receiving must be done by a separate session.
  bool SetSend(int crypto_suite,
               const ZeroOnFreeBuffer<uint8_t>& key,
               const std::vector<int>& extension_ids);
  bool UpdateSend(int crypto_suite,
                  const ZeroOnFreeBuffer<uint8_t>& key,
                  const std::vector<int>& extension_ids);

  // Configures the session for receiving data using the specified
  // crypto suite and key. Sending must be done by a separate session.
  bool SetReceive(int crypto_suite,
                  const ZeroOnFreeBuffer<uint8_t>& key,
                  const std::vector<int>& extension_ids);
  bool UpdateReceive(int crypto_suite,
                     const ZeroOnFreeBuffer<uint8_t>& key,
                     const std::vector<int>& extension_ids);

  // Encrypts/signs an individual RTP/RTCP packet, in-place.
  // If an HMAC is used, this will increase the packet size.
  bool ProtectRtp(CopyOnWriteBuffer& buffer, int64_t* index);
  bool ProtectRtp(CopyOnWriteBuffer& buffer);

  bool ProtectRtcp(CopyOnWriteBuffer& buffer);
  // Decrypts/verifies an invidiual RTP/RTCP packet.
  // If an HMAC is used, this will decrease the packet size.
  bool UnprotectRtp(CopyOnWriteBuffer& buffer);
  bool UnprotectRtcp(CopyOnWriteBuffer& buffer);

  int GetSrtpOverhead() const;

  // Removes a SSRC from the underlying libSRTP session.
  // Note: this should only be done for SSRCs that are received.
  // Removing SSRCs that were sent and then reusing them leads to
  // cryptographic weaknesses described in
  // https://www.rfc-editor.org/rfc/rfc3711#section-8
  // https://www.rfc-editor.org/rfc/rfc7714#section-8.4
  bool RemoveSsrcFromSession(uint32_t ssrc);

 private:
  bool DoSetKey(int type,
                int crypto_suite,
                const ZeroOnFreeBuffer<uint8_t>& key,
                const std::vector<int>& extension_ids);
  bool SetKey(int type,
              int crypto_suite,
              const ZeroOnFreeBuffer<uint8_t>& key,
              const std::vector<int>& extension_ids);
  bool UpdateKey(int type,
                 int crypto_suite,
                 const ZeroOnFreeBuffer<uint8_t>& key,
                 const std::vector<int>& extension_ids);
  // Returns send stream current packet index from srtp db.
  bool GetSendStreamPacketIndex(CopyOnWriteBuffer& buffer, int64_t* index);

  // Writes unencrypted packets in text2pcap format to the log file
  // for debugging.
  void DumpPacket(const CopyOnWriteBuffer& buffer, bool outbound);

  void HandleEvent(const srtp_event_data_t* ev);
  static void HandleEventThunk(srtp_event_data_t* ev);

  RTC_NO_UNIQUE_ADDRESS SequenceChecker thread_checker_{
      SequenceChecker::kDetached};
  srtp_ctx_t_* session_ RTC_GUARDED_BY(thread_checker_) = nullptr;

  // Overhead of the SRTP auth tag for RTP and RTCP in bytes.
  // Depends on the cipher suite used and is usually the same with the exception
  // of the kCsAesCm128HmacSha1_32 cipher suite. The additional four bytes
  // required for RTCP protection are not included.
  int rtp_auth_tag_len_ RTC_GUARDED_BY(thread_checker_) = 0;
  int rtcp_auth_tag_len_ RTC_GUARDED_BY(thread_checker_) = 0;

  bool inited_ RTC_GUARDED_BY(thread_checker_) = false;
  int last_send_seq_num_ RTC_GUARDED_BY(thread_checker_) = -1;
  int decryption_failure_count_ RTC_GUARDED_BY(thread_checker_) = 0;

  // Supported since libsrtp v2.8.0.
  bool use_cryptex_ RTC_GUARDED_BY(thread_checker_) = false;
  bool require_cryptex_ RTC_GUARDED_BY(thread_checker_) = false;

  const bool dump_plain_rtp_ = false;
};

}  //  namespace webrtc


#endif  // PC_SRTP_SESSION_H_
