roughtime.googlesource.com/roughtime.git@v0.0.0-20201210012726-dd529367052d/protocol_test.cc (about) 1 /* Copyright 2016 The Roughtime Authors. 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 #include "protocol.h" 16 #include "gtest/gtest.h" 17 18 #include <openssl/sha.h> 19 20 namespace roughtime { 21 22 constexpr tag_t kTagTAG1 = MakeTag('T', 'A', 'G', '1'); 23 constexpr tag_t kTagTAG2 = MakeTag('T', 'A', 'G', '2'); 24 constexpr tag_t kTagTAG3 = MakeTag('T', 'A', 'G', '3'); 25 constexpr tag_t kTagTAG4 = MakeTag('T', 'A', 'G', '4'); 26 27 TEST(ParserTest, Success) { 28 const uint8_t buffer[] = { 29 0x03, 0x00, 0x00, 0x00, // 3 tags 30 0x04, 0x00, 0x00, 0x00, // tag #2 has offset 4 31 0x08, 0x00, 0x00, 0x00, // tag #3 has offset 8 32 0x54, 0x41, 0x47, 0x31, // TAG1 33 0x54, 0x41, 0x47, 0x32, // TAG2 34 0x54, 0x41, 0x47, 0x33, // TAG3 35 0x11, 0x11, 0x11, 0x11, // data for tag #1 36 0x22, 0x22, 0x22, 0x22, // data for tag #2 37 0x33, 0x33, 0x33, 0x33, // data for tag #3 38 }; 39 40 Parser parser(buffer, sizeof(buffer)); 41 EXPECT_TRUE(parser.is_valid()); 42 const uint8_t* datap; 43 size_t len; 44 45 EXPECT_TRUE(parser.GetTag(&datap, &len, kTagTAG1)); 46 EXPECT_EQ(4, len); 47 EXPECT_TRUE(memcmp("\x11\x11\x11\x11", datap, len) == 0); 48 datap = nullptr; 49 EXPECT_TRUE(parser.GetFixedLen(&datap, kTagTAG1, 4)); 50 EXPECT_TRUE(memcmp("\x11\x11\x11\x11", datap, len) == 0); 51 datap = nullptr; 52 53 EXPECT_TRUE(parser.GetTag(&datap, &len, kTagTAG2)); 54 EXPECT_EQ(4, len); 55 EXPECT_TRUE(memcmp("\x22\x22\x22\x22", datap, len) == 0); 56 datap = nullptr; 57 EXPECT_TRUE(parser.GetFixedLen(&datap, kTagTAG2, 4)); 58 EXPECT_TRUE(memcmp("\x22\x22\x22\x22", datap, len) == 0); 59 datap = nullptr; 60 61 EXPECT_TRUE(parser.GetTag(&datap, &len, kTagTAG3)); 62 EXPECT_EQ(4, len); 63 EXPECT_TRUE(memcmp("\x33\x33\x33\x33", datap, len) == 0); 64 datap = nullptr; 65 EXPECT_TRUE(parser.GetFixedLen(&datap, kTagTAG3, 4)); 66 EXPECT_TRUE(memcmp("\x33\x33\x33\x33", datap, len) == 0); 67 datap = nullptr; 68 69 EXPECT_FALSE(parser.GetTag(&datap, &len, kTagTAG4)); 70 EXPECT_FALSE(parser.GetFixedLen(&datap, kTagTAG4, 1)); 71 } 72 73 TEST(ParserTest, UnalignedInput) { 74 alignas(4) const uint8_t buffer[] = { 75 0x00, // unalign input. 76 0x02, 0x00, 0x00, 0x00, // 2 tags 77 0x04, 0x00, 0x00, 0x00, // tag #2 has offset 4 78 0x54, 0x41, 0x47, 0x31, // TAG1 79 0x54, 0x41, 0x47, 0x32, // TAG2 80 0x11, 0x11, 0x11, 0x11, // data for tag #1 81 0x22, 0x22, 0x22, 0x22, // data for tag #2 82 }; 83 84 Parser parser(buffer + 1, sizeof(buffer) - 1); 85 EXPECT_TRUE(parser.is_valid()); 86 const uint8_t* datap; 87 size_t len; 88 89 EXPECT_TRUE(parser.GetTag(&datap, &len, kTagTAG1)); 90 EXPECT_EQ(4, len); 91 EXPECT_TRUE(memcmp("\x11\x11\x11\x11", datap, len) == 0); 92 datap = nullptr; 93 EXPECT_TRUE(parser.GetFixedLen(&datap, kTagTAG1, 4)); 94 EXPECT_TRUE(memcmp("\x11\x11\x11\x11", datap, len) == 0); 95 datap = nullptr; 96 97 EXPECT_TRUE(parser.GetTag(&datap, &len, kTagTAG2)); 98 EXPECT_EQ(4, len); 99 EXPECT_TRUE(memcmp("\x22\x22\x22\x22", datap, len) == 0); 100 datap = nullptr; 101 EXPECT_TRUE(parser.GetFixedLen(&datap, kTagTAG2, 4)); 102 EXPECT_TRUE(memcmp("\x22\x22\x22\x22", datap, len) == 0); 103 datap = nullptr; 104 105 EXPECT_FALSE(parser.GetTag(&datap, &len, kTagTAG4)); 106 EXPECT_FALSE(parser.GetFixedLen(&datap, kTagTAG4, 1)); 107 } 108 109 TEST(ParserTest, IntegerTypes) { 110 uint8_t buffer[128]; 111 Builder builder(buffer, sizeof(buffer), 2); 112 uint64_t big = 0xdeaddeaddeaddeadULL; 113 uint32_t little = 0xbeefbeef; 114 115 ASSERT_TRUE(builder.AddTagData(kTagTAG1, reinterpret_cast<uint8_t*>(&big), 116 sizeof(big))); 117 ASSERT_TRUE(builder.AddTagData(kTagTAG2, reinterpret_cast<uint8_t*>(&little), 118 sizeof(little))); 119 size_t out_len; 120 ASSERT_TRUE(builder.Finish(&out_len)); 121 122 Parser parser(buffer, out_len); 123 EXPECT_TRUE(parser.is_valid()); 124 big = 0; 125 little = 0; 126 127 EXPECT_FALSE(parser.Get(&big, kTagTAG2)); // Wrong tag. 128 EXPECT_TRUE(parser.Get(&big, kTagTAG1)); 129 EXPECT_EQ(0xdeaddeaddeaddeadULL, big); 130 131 EXPECT_FALSE(parser.Get(&little, kTagTAG1)); // Wrong tag. 132 EXPECT_TRUE(parser.Get(&little, kTagTAG2)); 133 EXPECT_EQ(0xbeefbeef, little); 134 } 135 136 TEST(ParserTest, EmptyMessage) { 137 uint8_t buffer[] = { 138 0x00, 0x00, 0x00, 0x00, // 0 tags. 139 }; 140 Parser parser(buffer, sizeof(buffer)); 141 EXPECT_TRUE(parser.is_valid()); 142 } 143 144 TEST(ParserTest, TooManyTags) { 145 uint8_t buffer[] = { 146 0xff, 0xff, 0xff, 0xff, // hella tags. 147 }; 148 Parser parser(buffer, sizeof(buffer)); 149 EXPECT_FALSE(parser.is_valid()); 150 } 151 152 TEST(ParserTest, TwoEmptyTags) { 153 uint8_t buffer[] = { 154 0x02, 0x00, 0x00, 0x00, // 2 tags. 155 0x00, 0x00, 0x00, 0x00, // tag #2 has offset 0 156 0x01, 0x00, 0x00, 0x00, // tag #1 157 0x02, 0x00, 0x00, 0x00, // tag #2 158 }; 159 Parser parser(buffer, sizeof(buffer)); 160 EXPECT_TRUE(parser.is_valid()); 161 } 162 163 TEST(ParserTest, OffsetNotAMultipleOf4) { 164 uint8_t buffer[] = { 165 0x02, 0x00, 0x00, 0x00, // 2 tags. 166 0x03, 0x00, 0x00, 0x00, // tag #2 has offset 3 167 0x54, 0x41, 0x47, 0x31, // TAG1 168 0x55, 0x41, 0x47, 0x31, // TAG2 169 0x00, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 171 }; 172 Parser parser(buffer, sizeof(buffer)); 173 EXPECT_FALSE(parser.is_valid()); 174 } 175 176 TEST(ParserTest, OffsetsOutOfOrder) { 177 uint8_t buffer[] = { 178 0x03, 0x00, 0x00, 0x00, // 3 tags. 179 0x08, 0x00, 0x00, 0x00, // tag #2 has offset 8 180 0x04, 0x00, 0x00, 0x00, // tag #3 has offset 4 181 }; 182 Parser parser(buffer, sizeof(buffer)); 183 EXPECT_FALSE(parser.is_valid()); 184 } 185 186 TEST(ParserTest, TagsOutOfOrder) { 187 uint8_t buffer[] = { 188 0x02, 0x00, 0x00, 0x00, // 2 tags. 189 0x00, 0x00, 0x00, 0x00, // tag #2 has offset 0 190 0x01, 0x00, 0x00, 0x00, // tag #1 191 0x01, 0x00, 0x00, 0x00, // tag #2, same as #1 (out of order) 192 }; 193 Parser parser(buffer, sizeof(buffer)); 194 EXPECT_FALSE(parser.is_valid()); 195 } 196 197 TEST(ParserTest, InvalidOffset) { 198 uint8_t buffer[] = { 199 0x02, 0x00, 0x00, 0x00, // 2 tags. 200 0x04, 0x00, 0x00, 0x00, // tag #2 has offset 4 (past end of message) 201 0x01, 0x00, 0x00, 0x00, // tag #1 202 0x02, 0x00, 0x00, 0x00, // tag #2 203 }; 204 Parser parser(buffer, sizeof(buffer)); 205 EXPECT_FALSE(parser.is_valid()); 206 } 207 208 TEST(BuilderTest, Success) { 209 uint8_t buffer[128]; 210 Builder builder(buffer, sizeof(buffer), 3); 211 const uint8_t* data = reinterpret_cast<const uint8_t*>("1234"); 212 213 EXPECT_TRUE(builder.AddTagData(kTagTAG1, data, 4)); 214 EXPECT_TRUE(builder.AddTagData(kTagTAG2, data, 4)); 215 EXPECT_TRUE(builder.AddTagData(kTagTAG3, data, 4)); 216 size_t out_len = 0; 217 EXPECT_TRUE(builder.Finish(&out_len)); 218 constexpr uint8_t kExpected[] = { 219 0x03, 0x00, 0x00, 0x00, // 3 tags 220 0x04, 0x00, 0x00, 0x00, // tag #2 has offset 4 221 0x08, 0x00, 0x00, 0x00, // tag #3 has offset 8 222 0x54, 0x41, 0x47, 0x31, // TAG1 223 0x54, 0x41, 0x47, 0x32, // TAG2 224 0x54, 0x41, 0x47, 0x33, // TAG3 225 0x31, 0x32, 0x33, 0x34, 226 0x31, 0x32, 0x33, 0x34, 227 0x31, 0x32, 0x33, 0x34, 228 }; 229 EXPECT_EQ(sizeof(kExpected), out_len); 230 EXPECT_EQ(0, memcmp(kExpected, buffer, sizeof(kExpected))); 231 } 232 233 TEST(BuilderTest, ExtraTag) { 234 uint8_t buffer[128]; 235 Builder builder(buffer, sizeof(buffer), 1); 236 uint32_t data = 42; 237 EXPECT_TRUE(builder.AddTagData( 238 kTagTAG1, reinterpret_cast<const uint8_t*>(&data), sizeof(data))); 239 EXPECT_FALSE(builder.AddTagData( 240 kTagTAG2, reinterpret_cast<const uint8_t*>(&data), sizeof(data))); 241 } 242 243 TEST(BuilderTest, AddAfterFinish) { 244 uint8_t buffer[128]; 245 Builder builder(buffer, sizeof(buffer), 1); 246 uint32_t data = 42; 247 EXPECT_TRUE(builder.AddTagData( 248 kTagTAG1, reinterpret_cast<const uint8_t*>(&data), sizeof(data))); 249 size_t out_len = 0; 250 EXPECT_TRUE(builder.Finish(&out_len)); 251 EXPECT_FALSE(builder.AddTagData( 252 kTagTAG2, reinterpret_cast<const uint8_t*>(&data), sizeof(data))); 253 } 254 255 TEST(BuilderTest, EmptyMessage) { 256 uint8_t buffer[4]; 257 Builder builder(buffer, sizeof(buffer), 0); 258 size_t len; 259 EXPECT_TRUE(builder.Finish(&len)); 260 } 261 262 TEST(BuilderTest, FinishAfterFinish) { 263 uint8_t buffer[4]; 264 Builder builder(buffer, sizeof(buffer), 0); 265 size_t len; 266 EXPECT_TRUE(builder.Finish(&len)); 267 EXPECT_FALSE(builder.Finish(&len)); 268 } 269 270 TEST(BuilderTest, MissingTag) { 271 uint8_t buffer[4]; 272 Builder builder(buffer, sizeof(buffer), 1); 273 size_t len; 274 EXPECT_FALSE(builder.Finish(&len)); 275 } 276 277 TEST(BuilderTest, ShortBuffer) { 278 uint8_t buffer[3]; 279 Builder builder(buffer, sizeof(buffer), 0); 280 size_t len; 281 EXPECT_FALSE(builder.Finish(&len)); 282 } 283 284 TEST(HashTest, SimpleTree) { 285 uint8_t zeros[kNonceLength]; 286 memset(zeros, 0, sizeof(zeros)); 287 uint8_t left[SHA512_DIGEST_LENGTH]; 288 HashLeaf(left, zeros); 289 constexpr uint8_t kExpectedLeftHash[SHA512_DIGEST_LENGTH] = { 290 0x19, 0xdc, 0x6a, 0xe1, 0x2d, 0xe0, 0x8b, 0x21, 0xb3, 0x6c, 0x1e, 291 0xc7, 0xf3, 0x53, 0xce, 0x9e, 0x7c, 0xef, 0x73, 0xfa, 0x4d, 0x13, 292 0x54, 0xc4, 0x36, 0x23, 0x41, 0x67, 0xf0, 0x84, 0x7b, 0xc9, 0xe2, 293 0xb8, 0x5e, 0x2f, 0x36, 0x20, 0x8f, 0x77, 0x3e, 0xf3, 0x24, 0xe2, 294 0xd7, 0x9e, 0x6a, 0xf1, 0xbe, 0xca, 0x44, 0x70, 0xe4, 0x4b, 0x86, 295 0x72, 0xb4, 0x7d, 0x07, 0x7e, 0xfe, 0x33, 0xa1, 0xf8}; 296 EXPECT_EQ(0, memcmp(kExpectedLeftHash, left, SHA512_DIGEST_LENGTH)); 297 298 uint8_t nonzeros[kNonceLength]; 299 memset(nonzeros, 'a', sizeof(nonzeros)); 300 uint8_t right[SHA512_DIGEST_LENGTH]; 301 HashLeaf(right, nonzeros); 302 constexpr uint8_t kExpectedRightHash[SHA512_DIGEST_LENGTH] = { 303 0x3d, 0x3a, 0xb5, 0x8a, 0x53, 0xc4, 0x57, 0x2a, 0x2a, 0x47, 0xeb, 304 0x04, 0xd3, 0x22, 0x18, 0x5a, 0x7b, 0x47, 0xe6, 0x85, 0xd2, 0xa6, 305 0x8f, 0x3b, 0xb8, 0xee, 0x4d, 0x34, 0x78, 0xa3, 0x34, 0x2a, 0xa7, 306 0xe1, 0x06, 0xb7, 0x28, 0xb6, 0x06, 0xbd, 0x73, 0x17, 0xf0, 0x8f, 307 0x37, 0xd9, 0xb0, 0xb5, 0x46, 0x90, 0x0b, 0x6e, 0x02, 0xa4, 0x01, 308 0x7e, 0x77, 0xce, 0xbc, 0x63, 0xc4, 0x77, 0xb6, 0x7f, 309 }; 310 EXPECT_EQ(0, memcmp(kExpectedRightHash, right, SHA512_DIGEST_LENGTH)); 311 312 uint8_t root[SHA512_DIGEST_LENGTH]; 313 HashNode(root, left, right); 314 constexpr uint8_t kExpectedRootHash[SHA512_DIGEST_LENGTH] = { 315 0x6a, 0xcd, 0xdd, 0x50, 0x32, 0x56, 0xc3, 0x53, 0x6c, 0x19, 0xe5, 316 0x79, 0x20, 0xf3, 0xeb, 0xa9, 0x81, 0xb8, 0x8a, 0x1b, 0x25, 0x10, 317 0x88, 0x97, 0xb4, 0x4a, 0x9a, 0x39, 0xc7, 0x58, 0x0d, 0x33, 0x87, 318 0xab, 0x4f, 0x1e, 0x91, 0x49, 0x7d, 0xd7, 0xb7, 0xc3, 0xa9, 0xf5, 319 0xa2, 0x24, 0xe1, 0x77, 0x50, 0x50, 0xa4, 0x69, 0xf1, 0x68, 0xcf, 320 0x51, 0x0a, 0xac, 0xd2, 0x04, 0x39, 0x1a, 0x48, 0x7e}; 321 EXPECT_EQ(0, memcmp(kExpectedRootHash, root, SHA512_DIGEST_LENGTH)); 322 } 323 324 } // namespace roughtime