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 |