|  | // Copyright 2017 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "net/cert/x509_util_nss.h" | 
|  |  | 
|  | #include "base/files/file_path.h" | 
|  | #include "base/files/file_util.h" | 
|  | #include "base/stl_util.h" | 
|  | #include "net/cert/scoped_nss_types.h" | 
|  | #include "net/cert/x509_certificate.h" | 
|  | #include "net/cert/x509_util.h" | 
|  | #include "net/test/cert_test_util.h" | 
|  | #include "net/test/test_certificate_data.h" | 
|  | #include "net/test/test_data_directory.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace net { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | std::string BytesForNSSCert(CERTCertificate* cert) { | 
|  | std::string der_encoded; | 
|  | if (!x509_util::GetDEREncoded(cert, &der_encoded)) | 
|  | ADD_FAILURE(); | 
|  | return der_encoded; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | TEST(X509UtilNSSTest, IsSameCertificate) { | 
|  | ScopedCERTCertificate google_nss_cert( | 
|  | x509_util::CreateCERTCertificateFromBytes(google_der, | 
|  | base::size(google_der))); | 
|  | ASSERT_TRUE(google_nss_cert); | 
|  |  | 
|  | ScopedCERTCertificate google_nss_cert2( | 
|  | x509_util::CreateCERTCertificateFromBytes(google_der, | 
|  | base::size(google_der))); | 
|  | ASSERT_TRUE(google_nss_cert2); | 
|  |  | 
|  | ScopedCERTCertificate webkit_nss_cert( | 
|  | x509_util::CreateCERTCertificateFromBytes(webkit_der, | 
|  | base::size(webkit_der))); | 
|  | ASSERT_TRUE(webkit_nss_cert); | 
|  |  | 
|  | scoped_refptr<X509Certificate> google_x509_cert( | 
|  | X509Certificate::CreateFromBytes( | 
|  | reinterpret_cast<const char*>(google_der), base::size(google_der))); | 
|  | ASSERT_TRUE(google_x509_cert); | 
|  |  | 
|  | scoped_refptr<X509Certificate> webkit_x509_cert( | 
|  | X509Certificate::CreateFromBytes( | 
|  | reinterpret_cast<const char*>(webkit_der), base::size(webkit_der))); | 
|  | ASSERT_TRUE(webkit_x509_cert); | 
|  |  | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(google_nss_cert.get(), | 
|  | google_nss_cert.get())); | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(google_nss_cert.get(), | 
|  | google_nss_cert2.get())); | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(google_nss_cert.get(), | 
|  | google_x509_cert.get())); | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(google_x509_cert.get(), | 
|  | google_nss_cert.get())); | 
|  |  | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(webkit_nss_cert.get(), | 
|  | webkit_nss_cert.get())); | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(webkit_nss_cert.get(), | 
|  | webkit_x509_cert.get())); | 
|  | EXPECT_TRUE(x509_util::IsSameCertificate(webkit_x509_cert.get(), | 
|  | webkit_nss_cert.get())); | 
|  |  | 
|  | EXPECT_FALSE(x509_util::IsSameCertificate(google_nss_cert.get(), | 
|  | webkit_nss_cert.get())); | 
|  | EXPECT_FALSE(x509_util::IsSameCertificate(google_nss_cert.get(), | 
|  | webkit_x509_cert.get())); | 
|  | EXPECT_FALSE(x509_util::IsSameCertificate(google_x509_cert.get(), | 
|  | webkit_nss_cert.get())); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateCERTCertificateFromBytes) { | 
|  | ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(google_cert); | 
|  | EXPECT_STREQ( | 
|  | "CN=www.google.com,O=Google Inc,L=Mountain View,ST=California,C=US", | 
|  | google_cert->subjectName); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateCERTCertificateFromBytesGarbage) { | 
|  | static const uint8_t garbage_data[] = "garbage"; | 
|  | EXPECT_EQ(nullptr, | 
|  | x509_util::CreateCERTCertificateFromBytes(garbage_data, 0)); | 
|  | EXPECT_EQ(nullptr, x509_util::CreateCERTCertificateFromBytes( | 
|  | garbage_data, base::size(garbage_data))); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateCERTCertificateFromX509Certificate) { | 
|  | scoped_refptr<X509Certificate> x509_cert = | 
|  | ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); | 
|  | ASSERT_TRUE(x509_cert); | 
|  | ScopedCERTCertificate nss_cert = | 
|  | x509_util::CreateCERTCertificateFromX509Certificate(x509_cert.get()); | 
|  | ASSERT_TRUE(nss_cert); | 
|  | EXPECT_STREQ("CN=127.0.0.1,O=Test CA,L=Mountain View,ST=California,C=US", | 
|  | nss_cert->subjectName); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateCERTCertificateListFromX509Certificate) { | 
|  | scoped_refptr<X509Certificate> x509_cert = CreateCertificateChainFromFile( | 
|  | GetTestCertsDirectory(), "multi-root-chain1.pem", | 
|  | X509Certificate::FORMAT_PEM_CERT_SEQUENCE); | 
|  | ASSERT_TRUE(x509_cert); | 
|  | EXPECT_EQ(3U, x509_cert->intermediate_buffers().size()); | 
|  |  | 
|  | ScopedCERTCertificateList nss_certs = | 
|  | x509_util::CreateCERTCertificateListFromX509Certificate(x509_cert.get()); | 
|  | ASSERT_EQ(4U, nss_certs.size()); | 
|  | for (int i = 0; i < 4; ++i) | 
|  | ASSERT_TRUE(nss_certs[i]); | 
|  |  | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer()), | 
|  | BytesForNSSCert(nss_certs[0].get())); | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece( | 
|  | x509_cert->intermediate_buffers()[0].get()), | 
|  | BytesForNSSCert(nss_certs[1].get())); | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece( | 
|  | x509_cert->intermediate_buffers()[1].get()), | 
|  | BytesForNSSCert(nss_certs[2].get())); | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece( | 
|  | x509_cert->intermediate_buffers()[2].get()), | 
|  | BytesForNSSCert(nss_certs[3].get())); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilTest, CreateCERTCertificateListFromX509CertificateErrors) { | 
|  | scoped_refptr<X509Certificate> ok_cert( | 
|  | ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); | 
|  | ASSERT_TRUE(ok_cert); | 
|  |  | 
|  | bssl::UniquePtr<CRYPTO_BUFFER> bad_cert = | 
|  | x509_util::CreateCryptoBuffer(base::StringPiece("invalid")); | 
|  | ASSERT_TRUE(bad_cert); | 
|  |  | 
|  | scoped_refptr<X509Certificate> ok_cert2( | 
|  | ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | 
|  | ASSERT_TRUE(ok_cert); | 
|  |  | 
|  | std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates; | 
|  | intermediates.push_back(std::move(bad_cert)); | 
|  | intermediates.push_back(bssl::UpRef(ok_cert2->cert_buffer())); | 
|  | scoped_refptr<X509Certificate> cert_with_intermediates( | 
|  | X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()), | 
|  | std::move(intermediates))); | 
|  | ASSERT_TRUE(cert_with_intermediates); | 
|  | EXPECT_EQ(2U, cert_with_intermediates->intermediate_buffers().size()); | 
|  |  | 
|  | // Normal CreateCERTCertificateListFromX509Certificate fails with invalid | 
|  | // certs in chain. | 
|  | ScopedCERTCertificateList nss_certs = | 
|  | x509_util::CreateCERTCertificateListFromX509Certificate( | 
|  | cert_with_intermediates.get()); | 
|  | EXPECT_TRUE(nss_certs.empty()); | 
|  |  | 
|  | // With InvalidIntermediateBehavior::kIgnore, invalid intermediate certs | 
|  | // should be silently dropped. | 
|  | nss_certs = x509_util::CreateCERTCertificateListFromX509Certificate( | 
|  | cert_with_intermediates.get(), | 
|  | x509_util::InvalidIntermediateBehavior::kIgnore); | 
|  | ASSERT_EQ(2U, nss_certs.size()); | 
|  | for (const auto& nss_cert : nss_certs) | 
|  | ASSERT_TRUE(nss_cert.get()); | 
|  |  | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert->cert_buffer()), | 
|  | BytesForNSSCert(nss_certs[0].get())); | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece(ok_cert2->cert_buffer()), | 
|  | BytesForNSSCert(nss_certs[1].get())); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateCERTCertificateListFromBytes) { | 
|  | base::FilePath cert_path = | 
|  | GetTestCertsDirectory().AppendASCII("multi-root-chain1.pem"); | 
|  | std::string cert_data; | 
|  | ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_data)); | 
|  |  | 
|  | ScopedCERTCertificateList certs = | 
|  | x509_util::CreateCERTCertificateListFromBytes( | 
|  | cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO); | 
|  | ASSERT_EQ(4U, certs.size()); | 
|  | EXPECT_STREQ("CN=127.0.0.1,O=Test CA,L=Mountain View,ST=California,C=US", | 
|  | certs[0]->subjectName); | 
|  | EXPECT_STREQ("CN=B CA - Multi-root", certs[1]->subjectName); | 
|  | EXPECT_STREQ("CN=C CA - Multi-root", certs[2]->subjectName); | 
|  | EXPECT_STREQ("CN=D Root CA - Multi-root", certs[3]->subjectName); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, DupCERTCertificate) { | 
|  | ScopedCERTCertificate cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(cert); | 
|  |  | 
|  | ScopedCERTCertificate cert2 = x509_util::DupCERTCertificate(cert.get()); | 
|  | // Both handles should hold a reference to the same CERTCertificate object. | 
|  | ASSERT_EQ(cert.get(), cert2.get()); | 
|  |  | 
|  | // Release the initial handle. | 
|  | cert.reset(); | 
|  | // The duped handle should still be safe to access. | 
|  | EXPECT_STREQ( | 
|  | "CN=www.google.com,O=Google Inc,L=Mountain View,ST=California,C=US", | 
|  | cert2->subjectName); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, DupCERTCertificateList) { | 
|  | ScopedCERTCertificate cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(cert); | 
|  | ScopedCERTCertificate cert2(x509_util::CreateCERTCertificateFromBytes( | 
|  | webkit_der, base::size(webkit_der))); | 
|  | ASSERT_TRUE(cert2); | 
|  | ScopedCERTCertificateList certs; | 
|  | certs.push_back(std::move(cert)); | 
|  | certs.push_back(std::move(cert2)); | 
|  |  | 
|  | ScopedCERTCertificateList certs_dup = | 
|  | x509_util::DupCERTCertificateList(certs); | 
|  | ASSERT_EQ(2U, certs_dup.size()); | 
|  | ASSERT_EQ(certs[0].get(), certs_dup[0].get()); | 
|  | ASSERT_EQ(certs[1].get(), certs_dup[1].get()); | 
|  |  | 
|  | // Release the initial handles. | 
|  | certs.clear(); | 
|  | // The duped handles should still be safe to access. | 
|  | EXPECT_STREQ( | 
|  | "CN=www.google.com,O=Google Inc,L=Mountain View,ST=California,C=US", | 
|  | certs_dup[0]->subjectName); | 
|  | EXPECT_STREQ( | 
|  | "CN=*.webkit.org,OU=Mac OS Forge,O=Apple " | 
|  | "Inc.,L=Cupertino,ST=California,C=US", | 
|  | certs_dup[1]->subjectName); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, DupCERTCertificateList_EmptyList) { | 
|  | EXPECT_EQ(0U, x509_util::DupCERTCertificateList({}).size()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_NoChain) { | 
|  | ScopedCERTCertificate nss_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(nss_cert); | 
|  | scoped_refptr<X509Certificate> x509_cert = | 
|  | x509_util::CreateX509CertificateFromCERTCertificate(nss_cert.get()); | 
|  | EXPECT_EQ(BytesForNSSCert(nss_cert.get()), | 
|  | x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer())); | 
|  | EXPECT_TRUE(x509_cert->intermediate_buffers().empty()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_EmptyChain) { | 
|  | ScopedCERTCertificate nss_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(nss_cert); | 
|  | scoped_refptr<X509Certificate> x509_cert = | 
|  | x509_util::CreateX509CertificateFromCERTCertificate( | 
|  | nss_cert.get(), std::vector<CERTCertificate*>()); | 
|  | EXPECT_EQ(BytesForNSSCert(nss_cert.get()), | 
|  | x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer())); | 
|  | EXPECT_TRUE(x509_cert->intermediate_buffers().empty()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateX509CertificateFromCERTCertificate_WithChain) { | 
|  | ScopedCERTCertificate nss_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(nss_cert); | 
|  | ScopedCERTCertificate nss_cert2(x509_util::CreateCERTCertificateFromBytes( | 
|  | webkit_der, base::size(webkit_der))); | 
|  | ASSERT_TRUE(nss_cert2); | 
|  |  | 
|  | std::vector<CERTCertificate*> chain; | 
|  | chain.push_back(nss_cert2.get()); | 
|  |  | 
|  | scoped_refptr<X509Certificate> x509_cert = | 
|  | x509_util::CreateX509CertificateFromCERTCertificate(nss_cert.get(), | 
|  | chain); | 
|  | EXPECT_EQ(BytesForNSSCert(nss_cert.get()), | 
|  | x509_util::CryptoBufferAsStringPiece(x509_cert->cert_buffer())); | 
|  | ASSERT_EQ(1U, x509_cert->intermediate_buffers().size()); | 
|  | EXPECT_EQ(x509_util::CryptoBufferAsStringPiece( | 
|  | x509_cert->intermediate_buffers()[0].get()), | 
|  | BytesForNSSCert(nss_cert2.get())); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateX509CertificateListFromCERTCertificates) { | 
|  | ScopedCERTCertificate nss_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(nss_cert); | 
|  | ScopedCERTCertificate nss_cert2(x509_util::CreateCERTCertificateFromBytes( | 
|  | webkit_der, base::size(webkit_der))); | 
|  | ASSERT_TRUE(nss_cert2); | 
|  | ScopedCERTCertificateList nss_certs; | 
|  | nss_certs.push_back(std::move(nss_cert)); | 
|  | nss_certs.push_back(std::move(nss_cert2)); | 
|  |  | 
|  | CertificateList x509_certs = | 
|  | x509_util::CreateX509CertificateListFromCERTCertificates(nss_certs); | 
|  | ASSERT_EQ(2U, x509_certs.size()); | 
|  |  | 
|  | EXPECT_EQ(BytesForNSSCert(nss_certs[0].get()), | 
|  | x509_util::CryptoBufferAsStringPiece(x509_certs[0]->cert_buffer())); | 
|  | EXPECT_EQ(BytesForNSSCert(nss_certs[1].get()), | 
|  | x509_util::CryptoBufferAsStringPiece(x509_certs[1]->cert_buffer())); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CreateX509CertificateListFromCERTCertificates_EmptyList) { | 
|  | ScopedCERTCertificateList nss_certs; | 
|  | CertificateList x509_certs = | 
|  | x509_util::CreateX509CertificateListFromCERTCertificates(nss_certs); | 
|  | ASSERT_EQ(0U, x509_certs.size()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetDEREncoded) { | 
|  | ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(google_cert); | 
|  | std::string der_encoded; | 
|  | ASSERT_TRUE(x509_util::GetDEREncoded(google_cert.get(), &der_encoded)); | 
|  | EXPECT_EQ(std::string(reinterpret_cast<const char*>(google_der), | 
|  | base::size(google_der)), | 
|  | der_encoded); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetDefaultNickname) { | 
|  | base::FilePath certs_dir = GetTestCertsDirectory(); | 
|  |  | 
|  | ScopedCERTCertificate test_cert = ImportCERTCertificateFromFile( | 
|  | certs_dir, "no_subject_common_name_cert.pem"); | 
|  | ASSERT_TRUE(test_cert); | 
|  |  | 
|  | std::string nickname = x509_util::GetDefaultUniqueNickname( | 
|  | test_cert.get(), USER_CERT, nullptr /*slot*/); | 
|  | EXPECT_EQ( | 
|  | "wtc@google.com's COMODO Client Authentication and " | 
|  | "Secure Email CA ID", | 
|  | nickname); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetCERTNameDisplayName_CN) { | 
|  | base::FilePath certs_dir = GetTestCertsDirectory(); | 
|  |  | 
|  | ScopedCERTCertificate test_cert = | 
|  | ImportCERTCertificateFromFile(certs_dir, "ok_cert.pem"); | 
|  | ASSERT_TRUE(test_cert); | 
|  | scoped_refptr<X509Certificate> x509_test_cert = | 
|  | ImportCertFromFile(certs_dir, "ok_cert.pem"); | 
|  | ASSERT_TRUE(x509_test_cert); | 
|  |  | 
|  | std::string name = x509_util::GetCERTNameDisplayName(&test_cert->subject); | 
|  | EXPECT_EQ("127.0.0.1", name); | 
|  | EXPECT_EQ(x509_test_cert->subject().GetDisplayName(), name); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetCERTNameDisplayName_O) { | 
|  | base::FilePath certs_dir = | 
|  | GetTestNetDataDirectory().AppendASCII("parse_certificate_unittest"); | 
|  |  | 
|  | ScopedCERTCertificate test_cert = | 
|  | ImportCERTCertificateFromFile(certs_dir, "subject_t61string.pem"); | 
|  | ASSERT_TRUE(test_cert); | 
|  | scoped_refptr<X509Certificate> x509_test_cert = | 
|  | ImportCertFromFile(certs_dir, "subject_t61string.pem"); | 
|  | ASSERT_TRUE(x509_test_cert); | 
|  |  | 
|  | std::string name = x509_util::GetCERTNameDisplayName(&test_cert->subject); | 
|  | EXPECT_EQ( | 
|  | " !\"#$%&'()*+,-./" | 
|  | "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" | 
|  | "abcdefghijklmnopqrstuvwxyz{|}~" | 
|  | " ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæç" | 
|  | "èéêëìíîïðñòóôõö÷øùúûüýþÿ", | 
|  | name); | 
|  | EXPECT_EQ(x509_test_cert->subject().GetDisplayName(), name); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, ParseClientSubjectAltNames) { | 
|  | base::FilePath certs_dir = GetTestCertsDirectory(); | 
|  |  | 
|  | // This cert contains one rfc822Name field, and one Microsoft UPN | 
|  | // otherName field. | 
|  | ScopedCERTCertificate san_cert = | 
|  | ImportCERTCertificateFromFile(certs_dir, "client_3.pem"); | 
|  | ASSERT_TRUE(san_cert); | 
|  |  | 
|  | std::vector<std::string> rfc822_names; | 
|  | x509_util::GetRFC822SubjectAltNames(san_cert.get(), &rfc822_names); | 
|  | ASSERT_EQ(1U, rfc822_names.size()); | 
|  | EXPECT_EQ("santest@example.com", rfc822_names[0]); | 
|  |  | 
|  | std::vector<std::string> upn_names; | 
|  | x509_util::GetUPNSubjectAltNames(san_cert.get(), &upn_names); | 
|  | ASSERT_EQ(1U, upn_names.size()); | 
|  | EXPECT_EQ("santest@ad.corp.example.com", upn_names[0]); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetValidityTimes) { | 
|  | ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(google_cert); | 
|  |  | 
|  | base::Time not_before, not_after; | 
|  | EXPECT_TRUE( | 
|  | x509_util::GetValidityTimes(google_cert.get(), ¬_before, ¬_after)); | 
|  |  | 
|  | // Constants copied from x509_certificate_unittest.cc. | 
|  | EXPECT_EQ(1238192407,  // Mar 27 22:20:07 2009 GMT | 
|  | not_before.ToDoubleT()); | 
|  | EXPECT_EQ(1269728407,  // Mar 27 22:20:07 2010 GMT | 
|  | not_after.ToDoubleT()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, GetValidityTimesOptionalArgs) { | 
|  | ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(google_cert); | 
|  |  | 
|  | base::Time not_before; | 
|  | EXPECT_TRUE( | 
|  | x509_util::GetValidityTimes(google_cert.get(), ¬_before, nullptr)); | 
|  | // Constants copied from x509_certificate_unittest.cc. | 
|  | EXPECT_EQ(1238192407,  // Mar 27 22:20:07 2009 GMT | 
|  | not_before.ToDoubleT()); | 
|  |  | 
|  | base::Time not_after; | 
|  | EXPECT_TRUE( | 
|  | x509_util::GetValidityTimes(google_cert.get(), nullptr, ¬_after)); | 
|  | EXPECT_EQ(1269728407,  // Mar 27 22:20:07 2010 GMT | 
|  | not_after.ToDoubleT()); | 
|  | } | 
|  |  | 
|  | TEST(X509UtilNSSTest, CalculateFingerprint256) { | 
|  | static const SHA256HashValue google_fingerprint = { | 
|  | {0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1, | 
|  | 0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec, | 
|  | 0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38}}; | 
|  |  | 
|  | ScopedCERTCertificate google_cert(x509_util::CreateCERTCertificateFromBytes( | 
|  | google_der, base::size(google_der))); | 
|  | ASSERT_TRUE(google_cert); | 
|  |  | 
|  | EXPECT_EQ(google_fingerprint, | 
|  | x509_util::CalculateFingerprint256(google_cert.get())); | 
|  | } | 
|  |  | 
|  | }  // namespace net |