1 /* 2 * Copyright 2015 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 #include <utility> 12 13 #include "webrtc/base/checks.h" 14 #include "webrtc/base/fakesslidentity.h" 15 #include "webrtc/base/gunit.h" 16 #include "webrtc/base/logging.h" 17 #include "webrtc/base/rtccertificate.h" 18 #include "webrtc/base/safe_conversions.h" 19 #include "webrtc/base/scoped_ptr.h" 20 #include "webrtc/base/sslidentity.h" 21 #include "webrtc/base/thread.h" 22 #include "webrtc/base/timeutils.h" 23 24 namespace rtc { 25 26 namespace { 27 28 static const char* kTestCertCommonName = "RTCCertificateTest's certificate"; 29 30 } // namespace 31 32 class RTCCertificateTest : public testing::Test { 33 public: 34 RTCCertificateTest() {} 35 ~RTCCertificateTest() {} 36 37 protected: 38 // Timestamp note: 39 // All timestamps in this unittest are expressed in number of seconds since 40 // epoch, 1970-01-01T00:00:00Z (UTC). The RTCCertificate interface uses ms, 41 // but only seconds-precision is supported by SSLCertificate. To make the 42 // tests clearer we convert everything to seconds since the precision matters 43 // when generating certificates or comparing timestamps. 44 // As a result, ExpiresSeconds and HasExpiredSeconds are used instead of 45 // RTCCertificate::Expires and ::HasExpired for ms -> s conversion. 46 47 uint64_t NowSeconds() const { 48 return TimeNanos() / kNumNanosecsPerSec; 49 } 50 51 uint64_t ExpiresSeconds(const scoped_refptr<RTCCertificate>& cert) const { 52 uint64_t exp_ms = cert->Expires(); 53 uint64_t exp_s = exp_ms / kNumMillisecsPerSec; 54 // Make sure this did not result in loss of precision. 55 RTC_CHECK_EQ(exp_s * kNumMillisecsPerSec, exp_ms); 56 return exp_s; 57 } 58 59 bool HasExpiredSeconds(const scoped_refptr<RTCCertificate>& cert, 60 uint64_t now_s) const { 61 return cert->HasExpired(now_s * kNumMillisecsPerSec); 62 } 63 64 // An RTC_CHECK ensures that |expires_s| this is in valid range of time_t as 65 // is required by SSLIdentityParams. On some 32-bit systems time_t is limited 66 // to < 2^31. On such systems this will fail for expiration times of year 2038 67 // or later. 68 scoped_refptr<RTCCertificate> GenerateCertificateWithExpires( 69 uint64_t expires_s) const { 70 RTC_CHECK(IsValueInRangeForNumericType<time_t>(expires_s)); 71 72 SSLIdentityParams params; 73 params.common_name = kTestCertCommonName; 74 params.not_before = 0; 75 params.not_after = static_cast<time_t>(expires_s); 76 // Certificate type does not matter for our purposes, using ECDSA because it 77 // is fast to generate. 78 params.key_params = KeyParams::ECDSA(); 79 80 scoped_ptr<SSLIdentity> identity(SSLIdentity::GenerateForTest(params)); 81 return RTCCertificate::Create(std::move(identity)); 82 } 83 }; 84 85 TEST_F(RTCCertificateTest, NewCertificateNotExpired) { 86 // Generate a real certificate without specifying the expiration time. 87 // Certificate type doesn't matter, using ECDSA because it's fast to generate. 88 scoped_ptr<SSLIdentity> identity( 89 SSLIdentity::Generate(kTestCertCommonName, KeyParams::ECDSA())); 90 scoped_refptr<RTCCertificate> certificate = 91 RTCCertificate::Create(std::move(identity)); 92 93 uint64_t now = NowSeconds(); 94 EXPECT_FALSE(HasExpiredSeconds(certificate, now)); 95 // Even without specifying the expiration time we would expect it to be valid 96 // for at least half an hour. 97 EXPECT_FALSE(HasExpiredSeconds(certificate, now + 30*60)); 98 } 99 100 TEST_F(RTCCertificateTest, UsesExpiresAskedFor) { 101 uint64_t now = NowSeconds(); 102 scoped_refptr<RTCCertificate> certificate = 103 GenerateCertificateWithExpires(now); 104 EXPECT_EQ(now, ExpiresSeconds(certificate)); 105 } 106 107 TEST_F(RTCCertificateTest, ExpiresInOneSecond) { 108 // Generate a certificate that expires in 1s. 109 uint64_t now = NowSeconds(); 110 scoped_refptr<RTCCertificate> certificate = 111 GenerateCertificateWithExpires(now + 1); 112 // Now it should not have expired. 113 EXPECT_FALSE(HasExpiredSeconds(certificate, now)); 114 // In 2s it should have expired. 115 EXPECT_TRUE(HasExpiredSeconds(certificate, now + 2)); 116 } 117 118 } // namespace rtc 119