/*
 *  Copyright 2015 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.
 */

#include "rtc_base/rtc_certificate.h"

#include <cstdint>
#include <ctime>
#include <memory>
#include <utility>

#include "api/scoped_refptr.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

constexpr char kTestCertCommonName[] = "RTCCertificateTest's certificate";

}  // namespace

class RTCCertificateTest : public ::testing::Test {
 protected:
  scoped_refptr<RTCCertificate> GenerateECDSA() {
    std::unique_ptr<SSLIdentity> identity(
        SSLIdentity::Create(kTestCertCommonName, KeyParams::ECDSA()));
    RTC_CHECK(identity);
    return RTCCertificate::Create(std::move(identity));
  }

  // Timestamp note:
  //   All timestamps in this unittest are expressed in number of seconds since
  // epoch, 1970-01-01T00:00:00Z (UTC). The RTCCertificate interface uses ms,
  // but only seconds-precision is supported by SSLCertificate. To make the
  // tests clearer we convert everything to seconds since the precision matters
  // when generating certificates or comparing timestamps.
  //   As a result, ExpiresSeconds and HasExpiredSeconds are used instead of
  // RTCCertificate::Expires and ::HasExpired for ms -> s conversion.

  uint64_t NowSeconds() const { return TimeNanos() / kNumNanosecsPerSec; }

  uint64_t ExpiresSeconds(const scoped_refptr<RTCCertificate>& cert) const {
    uint64_t exp_ms = cert->Expires();
    uint64_t exp_s = exp_ms / kNumMillisecsPerSec;
    // Make sure this did not result in loss of precision.
    RTC_CHECK_EQ(exp_s * kNumMillisecsPerSec, exp_ms);
    return exp_s;
  }

  bool HasExpiredSeconds(const scoped_refptr<RTCCertificate>& cert,
                         uint64_t now_s) const {
    return cert->HasExpired(now_s * kNumMillisecsPerSec);
  }

  // An RTC_CHECK ensures that `expires_s` this is in valid range of time_t as
  // is required by SSLIdentityParams. On some 32-bit systems time_t is limited
  // to < 2^31. On such systems this will fail for expiration times of year 2038
  // or later.
  scoped_refptr<RTCCertificate> GenerateCertificateWithExpires(
      uint64_t expires_s) const {
    RTC_CHECK(IsValueInRangeForNumericType<time_t>(expires_s));

    SSLIdentityParams params;
    params.common_name = kTestCertCommonName;
    params.not_before = 0;
    params.not_after = static_cast<time_t>(expires_s);
    // Certificate type does not matter for our purposes, using ECDSA because it
    // is fast to generate.
    params.key_params = KeyParams::ECDSA();

    std::unique_ptr<SSLIdentity> identity(SSLIdentity::CreateForTest(params));
    return RTCCertificate::Create(std::move(identity));
  }
};

TEST_F(RTCCertificateTest, NewCertificateNotExpired) {
  // Generate a real certificate without specifying the expiration time.
  // Certificate type doesn't matter, using ECDSA because it's fast to generate.
  scoped_refptr<RTCCertificate> certificate = GenerateECDSA();

  uint64_t now = NowSeconds();
  EXPECT_FALSE(HasExpiredSeconds(certificate, now));
  // Even without specifying the expiration time we would expect it to be valid
  // for at least half an hour.
  EXPECT_FALSE(HasExpiredSeconds(certificate, now + 30 * 60));
}

TEST_F(RTCCertificateTest, UsesExpiresAskedFor) {
  uint64_t now = NowSeconds();
  scoped_refptr<RTCCertificate> certificate =
      GenerateCertificateWithExpires(now);
  EXPECT_EQ(now, ExpiresSeconds(certificate));
}

TEST_F(RTCCertificateTest, ExpiresInOneSecond) {
  // Generate a certificate that expires in 1s.
  uint64_t now = NowSeconds();
  scoped_refptr<RTCCertificate> certificate =
      GenerateCertificateWithExpires(now + 1);
  // Now it should not have expired.
  EXPECT_FALSE(HasExpiredSeconds(certificate, now));
  // In 2s it should have expired.
  EXPECT_TRUE(HasExpiredSeconds(certificate, now + 2));
}

TEST_F(RTCCertificateTest, DifferentCertificatesNotEqual) {
  scoped_refptr<RTCCertificate> a = GenerateECDSA();
  scoped_refptr<RTCCertificate> b = GenerateECDSA();
  EXPECT_TRUE(*a != *b);
}

TEST_F(RTCCertificateTest, CloneWithPEMSerialization) {
  scoped_refptr<RTCCertificate> orig = GenerateECDSA();

  // To PEM.
  RTCCertificatePEM orig_pem = orig->ToPEM();
  // Clone from PEM.
  scoped_refptr<RTCCertificate> clone = RTCCertificate::FromPEM(orig_pem);
  EXPECT_TRUE(clone);
  EXPECT_TRUE(*orig == *clone);
  EXPECT_EQ(orig->Expires(), clone->Expires());
}

TEST_F(RTCCertificateTest, FromPEMWithInvalidPEM) {
  RTCCertificatePEM pem("not a valid PEM", "not a valid PEM");
  scoped_refptr<RTCCertificate> certificate = RTCCertificate::FromPEM(pem);
  EXPECT_FALSE(certificate);
}

}  // namespace webrtc
