| OLD | NEW |
| (Empty) |
| 1 // Copyright 2003-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // signatures_unittest.cpp | |
| 17 // | |
| 18 // Unittests for classes and functions related to crypto-hashes of buffers and | |
| 19 // digital signatures of buffers. | |
| 20 // TODO(omaha): There are a number of places inside the signatures code, where | |
| 21 // empty vector iterators were being dereferenced. Ensure that all these are | |
| 22 // being tested. | |
| 23 | |
| 24 #include <cstring> | |
| 25 #include <vector> | |
| 26 #include "omaha/base/app_util.h" | |
| 27 #include "omaha/base/error.h" | |
| 28 #include "omaha/base/module_utils.h" | |
| 29 #include "omaha/base/path.h" | |
| 30 #include "omaha/base/signatures.h" | |
| 31 #include "omaha/base/utils.h" | |
| 32 #include "omaha/testing/unit_test.h" | |
| 33 | |
| 34 namespace omaha { | |
| 35 | |
| 36 namespace { | |
| 37 | |
| 38 struct { | |
| 39 char* binary; | |
| 40 char* base64; | |
| 41 } test_data[] = { | |
| 42 "", "", | |
| 43 "what", "d2hhdA==", | |
| 44 "what will print out", "d2hhdCB3aWxsIHByaW50IG91dA==", | |
| 45 "foobar", "Zm9vYmFy", | |
| 46 "a man, a plan, a canal: panama!", "YSBtYW4sIGEgcGxhbiwgYSBjYW5hbDogcGFuYW1hIQ
==", // NOLINT | |
| 47 }; | |
| 48 | |
| 49 // This test data from http://en.wikipedia.org/wiki/SHA-1: | |
| 50 struct { | |
| 51 char* binary; | |
| 52 byte hash[20]; | |
| 53 } test_hash[] = { | |
| 54 "The quick brown fox jumps over the lazy dog", | |
| 55 0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, | |
| 56 0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12, | |
| 57 "The quick brown fox jumps over the lazy cog", | |
| 58 0xde, 0x9f, 0x2c, 0x7f, 0xd2, 0x5e, 0x1b, 0x3a, 0xfa, 0xd3, | |
| 59 0xe8, 0x5a, 0x0b, 0xd1, 0x7d, 0x9b, 0x10, 0x0d, 0xb4, 0xb3, | |
| 60 }; | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 TEST(SignaturesTest, Base64) { | |
| 65 for (size_t i = 0; i != arraysize(test_data); i++) { | |
| 66 std::vector<byte> buffer(strlen(test_data[i].binary)); | |
| 67 if (strlen(test_data[i].binary) != 0) { | |
| 68 memcpy(&buffer.front(), test_data[i].binary, strlen(test_data[i].binary)); | |
| 69 } | |
| 70 CStringA test_e; | |
| 71 ASSERT_SUCCEEDED(Base64::Encode(buffer, &test_e)); | |
| 72 ASSERT_STREQ(test_e, test_data[i].base64); | |
| 73 std::vector<byte> test_d; | |
| 74 uint32 test_d_written = 0; | |
| 75 ASSERT_SUCCEEDED(Base64::Decode(test_e, &test_d)); | |
| 76 ASSERT_EQ(test_d.size(), strlen(test_data[i].binary)); | |
| 77 if (strlen(test_data[i].binary) != 0) { | |
| 78 ASSERT_EQ(0, memcmp(&test_d.front(), | |
| 79 test_data[i].binary, | |
| 80 strlen(test_data[i].binary))); | |
| 81 } | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 TEST(SignaturesTest, CryptoHash) { | |
| 86 CryptoHash chash; | |
| 87 for (size_t i = 0; i != arraysize(test_hash); i++) { | |
| 88 std::vector<byte> buffer(strlen(test_hash[i].binary)); | |
| 89 memcpy(&buffer.front(), test_hash[i].binary, strlen(test_hash[i].binary)); | |
| 90 std::vector<byte> hash; | |
| 91 ASSERT_SUCCEEDED(chash.Compute(buffer, &hash)); | |
| 92 ASSERT_EQ(hash.size(), CryptoHash::kHashSize); | |
| 93 ASSERT_EQ(0, memcmp(&hash.front(), | |
| 94 test_hash[i].hash, | |
| 95 CryptoHash::kHashSize)); | |
| 96 ASSERT_SUCCEEDED(chash.Validate(buffer, hash)); | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 TEST(SignaturesTest, CreationVerification) { | |
| 101 TCHAR module_directory[MAX_PATH] = {0}; | |
| 102 ASSERT_TRUE(GetModuleDirectory(NULL, module_directory)); | |
| 103 CString directory; | |
| 104 directory.Format(_T("%s\\unittest_support"), module_directory); | |
| 105 | |
| 106 CString encoded_cert_with_private_key_path; | |
| 107 encoded_cert_with_private_key_path.AppendFormat( | |
| 108 _T("%s\\certificate-with-private-key.pfx"), directory); | |
| 109 CString encoded_cert_without_private_key_path; | |
| 110 encoded_cert_without_private_key_path.AppendFormat( | |
| 111 _T("%s\\certificate-without-private-key.cer"), directory); | |
| 112 CString raw_test_data_path; | |
| 113 raw_test_data_path.AppendFormat(_T("%s\\declaration.txt"), directory); | |
| 114 | |
| 115 // Get cert with private key and cert without private key. | |
| 116 std::vector<byte> encoded_cert_with_private_key; | |
| 117 std::vector<byte> encoded_cert_without_private_key; | |
| 118 ASSERT_SUCCEEDED(ReadEntireFile(encoded_cert_with_private_key_path, | |
| 119 0, | |
| 120 &encoded_cert_with_private_key)); | |
| 121 ASSERT_SUCCEEDED(ReadEntireFile(encoded_cert_without_private_key_path, | |
| 122 0, | |
| 123 &encoded_cert_without_private_key)); | |
| 124 CString cert_password = _T("f00bar"); | |
| 125 CString cert_subject_name = _T("Unofficial Google Test"); | |
| 126 | |
| 127 // Get testdata. | |
| 128 std::vector<byte> raw_testdata; | |
| 129 ASSERT_SUCCEEDED(ReadEntireFile(raw_test_data_path, 0, &raw_testdata)); | |
| 130 | |
| 131 // Create a signing certificate. | |
| 132 CryptoSigningCertificate signing_certificate; | |
| 133 ASSERT_SUCCEEDED(signing_certificate.ImportCertificate( | |
| 134 encoded_cert_with_private_key, cert_password, cert_subject_name)); | |
| 135 | |
| 136 // Create a signature object and sign the test data. | |
| 137 std::vector<byte> signature; | |
| 138 CryptoComputeSignature signer(&signing_certificate); | |
| 139 ASSERT_SUCCEEDED(signer.Sign(raw_testdata, &signature)); | |
| 140 | |
| 141 // Create a validating certificate. | |
| 142 CryptoSignatureVerificationCertificate verification_certificate; | |
| 143 ASSERT_SUCCEEDED(verification_certificate.ImportCertificate( | |
| 144 encoded_cert_without_private_key, cert_subject_name)); | |
| 145 | |
| 146 // Create a signature object and verify the test data's signature. | |
| 147 CryptoVerifySignature verifier(verification_certificate); | |
| 148 ASSERT_SUCCEEDED(verifier.Validate(raw_testdata, signature)); | |
| 149 | |
| 150 // Mess up the signature and show it doesn't verify. | |
| 151 size_t mid = signature.size() / 2; | |
| 152 byte mid_byte = signature[mid]; | |
| 153 signature[mid] = ~mid_byte; | |
| 154 ASSERT_FAILED(verifier.Validate(raw_testdata, signature)); | |
| 155 | |
| 156 // Restore the signature, mess up the test data, and show it doesn't verify. | |
| 157 signature[mid] = mid_byte; | |
| 158 mid = raw_testdata.size() / 2; | |
| 159 mid_byte = raw_testdata[mid]; | |
| 160 raw_testdata[mid] = ~mid_byte; | |
| 161 ASSERT_FAILED(verifier.Validate(raw_testdata, signature)); | |
| 162 } | |
| 163 | |
| 164 TEST(SignaturesTest, AuthenticateFiles) { | |
| 165 const CString executable_path(app_util::GetCurrentModuleDirectory()); | |
| 166 | |
| 167 const CString source_file1 = ConcatenatePath( | |
| 168 executable_path, | |
| 169 _T("unittest_support\\download_cache_test\\") | |
| 170 _T("{89640431-FE64-4da8-9860-1A1085A60E13}\\gears-win32-opt.msi")); | |
| 171 | |
| 172 const CString hash_file1 = _T("ImV9skETZqGFMjs32vbZTvzAYJU="); | |
| 173 | |
| 174 const CString source_file2 = ConcatenatePath( | |
| 175 executable_path, | |
| 176 _T("unittest_support\\download_cache_test\\") | |
| 177 _T("{7101D597-3481-4971-AD23-455542964072}\\livelysetup.exe")); | |
| 178 | |
| 179 const CString hash_file2 = _T("Igq6bYaeXFJCjH770knXyJ6V53s="); | |
| 180 | |
| 181 const CString hash_files = _T("e2uzy96jlusKbADl87zie6F5iwE="); | |
| 182 | |
| 183 const CString bad_hash = _T("sFzmoHgCbowEnioqVb8WanTYbhIabcde="); | |
| 184 | |
| 185 std::vector<CString> files; | |
| 186 | |
| 187 // Authenticate one file. | |
| 188 files.push_back(source_file1); | |
| 189 EXPECT_HRESULT_SUCCEEDED(AuthenticateFiles(files, hash_file1)); | |
| 190 | |
| 191 // Incorrect hash. | |
| 192 EXPECT_EQ(SIGS_E_INVALID_SIGNATURE, AuthenticateFiles(files, hash_file2)); | |
| 193 | |
| 194 // Bad hash. | |
| 195 EXPECT_EQ(E_INVALIDARG, AuthenticateFiles(files, bad_hash)); | |
| 196 EXPECT_EQ(E_INVALIDARG, AuthenticateFiles(files, _T(""))); | |
| 197 | |
| 198 // Authenticate two files. | |
| 199 files.push_back(source_file2); | |
| 200 EXPECT_HRESULT_SUCCEEDED(AuthenticateFiles(files, hash_files)); | |
| 201 | |
| 202 // Round trip through CryptoHash::Compute to verify the hash of two files. | |
| 203 CryptoHash crypto; | |
| 204 std::vector<byte> hash_out; | |
| 205 EXPECT_HRESULT_SUCCEEDED(crypto.Compute(files, 0, &hash_out)); | |
| 206 | |
| 207 CStringA actual_hash_files; | |
| 208 EXPECT_HRESULT_SUCCEEDED(Base64::Encode(hash_out, &actual_hash_files)); | |
| 209 EXPECT_STREQ(hash_files, CString(actual_hash_files)); | |
| 210 } | |
| 211 | |
| 212 } // namespace omaha | |
| 213 | |
| OLD | NEW |