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