1 // 2 // Copyright (C) 2013 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/certificate_file.h" 18 19 #include <string> 20 #include <vector> 21 22 #include <base/files/file_path.h> 23 #include <base/files/file_util.h> 24 #include <base/files/scoped_temp_dir.h> 25 #include <base/strings/stringprintf.h> 26 #include <gmock/gmock.h> 27 #include <gtest/gtest.h> 28 29 using base::FilePath; 30 using base::StringPrintf; 31 using std::string; 32 using std::vector; 33 using testing::_; 34 using testing::Return; 35 using testing::SetArgumentPointee; 36 using testing::StrEq; 37 38 namespace shill { 39 40 class CertificateFileTest : public testing::Test { 41 public: 42 CertificateFileTest() {} 43 44 virtual void SetUp() { 45 CHECK(temp_dir_.CreateUniqueTempDir()); 46 certificate_directory_ = temp_dir_.path().Append("certificates"); 47 certificate_file_.set_root_directory(certificate_directory_); 48 } 49 50 protected: 51 static const char kDERData[]; 52 static const char kPEMData[]; 53 54 string ExtractHexData(const std::string& pem_data) { 55 return CertificateFile::ExtractHexData(pem_data); 56 } 57 const FilePath& GetOutputFile() { return certificate_file_.output_file_; } 58 const FilePath& GetRootDirectory() { 59 return certificate_file_.root_directory_; 60 } 61 const char* GetPEMHeader() { return CertificateFile::kPEMHeader; } 62 const char* GetPEMFooter() { return CertificateFile::kPEMFooter; } 63 64 CertificateFile certificate_file_; 65 base::ScopedTempDir temp_dir_; 66 base::FilePath certificate_directory_; 67 }; 68 69 const char CertificateFileTest::kDERData[] = 70 "This does not have to be a real certificate " 71 "since we are not testing its validity."; 72 const char CertificateFileTest::kPEMData[] = 73 "VGhpcyBkb2VzIG5vdCBoYXZlIHRvIGJlIGEgcmVhbCBjZXJ0aWZpY2F0ZSBzaW5j\n" 74 "ZSB3ZSBhcmUgbm90IHRlc3RpbmcgaXRzIHZhbGlkaXR5Lgo=\n"; 75 76 77 TEST_F(CertificateFileTest, Construction) { 78 EXPECT_TRUE(GetRootDirectory() == certificate_directory_); 79 EXPECT_FALSE(base::PathExists(GetRootDirectory())); 80 EXPECT_TRUE(GetOutputFile().empty()); 81 } 82 83 TEST_F(CertificateFileTest, CreatePEMFromStrings) { 84 // Create a formatted PEM file from the inner HEX data. 85 const vector<string> kPEMVector0{ kPEMData }; 86 FilePath outfile0 = certificate_file_.CreatePEMFromStrings(kPEMVector0); 87 EXPECT_FALSE(outfile0.empty()); 88 EXPECT_TRUE(base::PathExists(outfile0)); 89 EXPECT_TRUE(certificate_directory_.IsParent(outfile0)); 90 string file_string0; 91 EXPECT_TRUE(base::ReadFileToString(outfile0, &file_string0)); 92 string expected_output0 = StringPrintf( 93 "%s\n%s%s\n", GetPEMHeader(), kPEMData, GetPEMFooter()); 94 EXPECT_EQ(expected_output0, file_string0); 95 96 // Create a formatted PEM file from formatted PEM. 97 const vector<string> kPEMVector1{ expected_output0, kPEMData }; 98 FilePath outfile1 = certificate_file_.CreatePEMFromStrings(kPEMVector1); 99 EXPECT_FALSE(outfile1.empty()); 100 EXPECT_TRUE(base::PathExists(outfile1)); 101 EXPECT_FALSE(base::PathExists(outfile0)); // Old file is deleted. 102 string file_string1; 103 EXPECT_TRUE(base::ReadFileToString(outfile1, &file_string1)); 104 string expected_output1 = StringPrintf( 105 "%s%s", expected_output0.c_str(), expected_output0.c_str()); 106 EXPECT_EQ(expected_output1, file_string1); 107 108 // Fail to create a PEM file. Old file should not have been deleted. 109 const vector<string> kPEMVector2{ kPEMData, "" }; 110 FilePath outfile2 = certificate_file_.CreatePEMFromStrings(kPEMVector2); 111 EXPECT_TRUE(outfile2.empty()); 112 EXPECT_TRUE(base::PathExists(outfile1)); 113 } 114 115 TEST_F(CertificateFileTest, ExtractHexData) { 116 EXPECT_EQ("", ExtractHexData("")); 117 EXPECT_EQ("foo\n", ExtractHexData("foo")); 118 EXPECT_EQ("foo\nbar\n", ExtractHexData("foo\r\n\t\n bar\n")); 119 EXPECT_EQ("", ExtractHexData( 120 StringPrintf("%s\nfoo\nbar\n%s\n", GetPEMFooter(), GetPEMHeader()))); 121 EXPECT_EQ("", ExtractHexData( 122 StringPrintf("%s\nfoo\nbar\n%s\n", GetPEMHeader(), GetPEMHeader()))); 123 EXPECT_EQ("", ExtractHexData( 124 StringPrintf("%s\nfoo\nbar\n", GetPEMHeader()))); 125 EXPECT_EQ("", ExtractHexData( 126 StringPrintf("foo\nbar\n%s\n", GetPEMFooter()))); 127 EXPECT_EQ("foo\nbar\n", ExtractHexData( 128 StringPrintf("%s\nfoo\nbar\n%s\n", GetPEMHeader(), GetPEMFooter()))); 129 EXPECT_EQ("bar\n", ExtractHexData( 130 StringPrintf("foo\n%s\nbar\n%s\nbaz\n", GetPEMHeader(), GetPEMFooter()))); 131 } 132 133 TEST_F(CertificateFileTest, Destruction) { 134 FilePath outfile; 135 { 136 CertificateFile certificate_file; 137 certificate_file.set_root_directory(temp_dir_.path()); 138 outfile = certificate_file.CreatePEMFromStrings(vector<string>{ kPEMData }); 139 EXPECT_TRUE(base::PathExists(outfile)); 140 } 141 // The output file should be deleted when certificate_file goes out-of-scope. 142 EXPECT_FALSE(base::PathExists(outfile)); 143 } 144 145 } // namespace shill 146