roughtime.googlesource.com/roughtime.git@v0.0.0-20201210012726-dd529367052d/server_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 <string.h>
    16  #include <sys/types.h>
    17  #include <unistd.h>
    18  
    19  #include "gtest/gtest.h"
    20  #include <openssl/curve25519.h>
    21  #include <openssl/rand.h>
    22  
    23  #include "open_source_fillins.h"
    24  #include "server.h"
    25  
    26  namespace roughtime {
    27  
    28  TEST(CreateCertificate, Create) {
    29    uint8_t delegated_private_key[ED25519_PRIVATE_KEY_LEN];  // Not used.
    30    uint8_t delegated_public_key[ED25519_PUBLIC_KEY_LEN];
    31    uint8_t root_private_key[ED25519_PRIVATE_KEY_LEN];
    32    uint8_t root_public_key[ED25519_PUBLIC_KEY_LEN];
    33    ED25519_keypair(delegated_public_key, delegated_private_key);
    34    ED25519_keypair(root_public_key, root_private_key);
    35  
    36    uint8_t cert[kCertSize];
    37    EXPECT_TRUE(
    38        CreateCertificate(cert, root_private_key, 0, 1, delegated_public_key));
    39    Parser cert_parser(cert, sizeof(cert));
    40    const uint8_t* delegation;
    41    const uint8_t* signature;
    42    EXPECT_TRUE(
    43        cert_parser.GetFixedLen(&delegation, kTagDELE, kToBeSignedCertSize));
    44    EXPECT_TRUE(
    45        cert_parser.GetFixedLen(&signature, kTagSIG, ED25519_SIGNATURE_LEN));
    46  
    47    Parser delegation_parser(delegation, kToBeSignedCertSize);
    48    uint64_t mint, maxt;
    49    const uint8_t* pubk;
    50    EXPECT_TRUE(delegation_parser.Get(&mint, kTagMINT));
    51    EXPECT_TRUE(delegation_parser.Get(&maxt, kTagMAXT));
    52    EXPECT_TRUE(
    53        delegation_parser.GetFixedLen(&pubk, kTagPUBK, ED25519_PUBLIC_KEY_LEN));
    54    EXPECT_EQ(0, mint);
    55    EXPECT_EQ(1, maxt);
    56    EXPECT_EQ(0,
    57              memcmp(pubk, delegated_public_key, sizeof(delegated_public_key)));
    58  
    59    uint8_t verify[sizeof(kCertContextString) + kToBeSignedCertSize];
    60    memcpy(verify, kCertContextString, sizeof(kCertContextString));
    61    memcpy(verify + sizeof(kCertContextString), delegation, kToBeSignedCertSize);
    62    EXPECT_TRUE(
    63        ED25519_verify(verify, sizeof(verify), signature, root_public_key));
    64  }
    65  
    66  TEST(Tree, OneNode) {
    67    std::unique_ptr<Tree> tree(new Tree);
    68    uint8_t nonce[kNonceLength];
    69    RAND_bytes(nonce, sizeof(nonce));
    70    tree->AddLeaf(0, nonce);
    71    tree->Build(1);
    72  
    73    uint8_t hash[kNonceLength];
    74    HashLeaf(hash, nonce);
    75    EXPECT_EQ(0, memcmp(hash, tree->GetRoot(), kNonceLength));
    76    EXPECT_EQ(0, tree->GetPathLength());
    77  }
    78  
    79  TEST(Tree, ManyNodes) {
    80    std::unique_ptr<Tree> tree(new Tree);
    81    size_t sizes[] = {2, 3, 4, 5, 6, kBatchSize - 1, kBatchSize};
    82    for (size_t i = 0; i < arraysize(sizes); i++) {
    83      size_t size = sizes[i];
    84      uint8_t nonces[kBatchSize][kNonceLength];
    85      for (size_t j = 0; j < size; ++j) {
    86        RAND_bytes(nonces[j], sizeof(nonces[j]));
    87        tree->AddLeaf(j, nonces[j]);
    88      }
    89      tree->Build(size);
    90  
    91      // Verify the inclusion of each nonce.
    92      for (size_t j = 0; j < size; ++j) {
    93        uint8_t hash[kNonceLength];
    94        HashLeaf(hash, nonces[j]);
    95  
    96        uint8_t path[kBatchSize][kNonceLength];
    97        tree->GetPath(reinterpret_cast<uint8_t*>(path), j);
    98        size_t index = j;
    99        for (size_t elem = 0; elem < tree->GetPathLength(); elem++) {
   100          if (index % 2 == 0) {
   101            HashNode(hash, hash, path[elem]);
   102          } else {
   103            HashNode(hash, path[elem], hash);
   104          }
   105          index /= 2;
   106        }
   107        ASSERT_EQ(0, index);
   108        EXPECT_EQ(0, memcmp(hash, tree->GetRoot(), kNonceLength));
   109      }
   110    }
   111  }
   112  
   113  class DummyTimeSource : public TimeSource {
   114   public:
   115    ~DummyTimeSource() override {}
   116    std::pair<uint64_t, uint32_t> Now() override {
   117      return std::make_pair(1000000000, 0);
   118    }
   119  };
   120  
   121  // MakeServer is a helper function to create a new server.  The server's public
   122  // key is written to |*root_public_key|, but its certificate remains hidden.
   123  static std::unique_ptr<Server> MakeServer(uint8_t* root_public_key) {
   124    auto identity = std::unique_ptr<Identity>(new Identity());
   125    uint8_t delegated_private_key[ED25519_PRIVATE_KEY_LEN];  // Not used.
   126    uint8_t delegated_public_key[ED25519_PUBLIC_KEY_LEN];
   127    uint8_t root_private_key[ED25519_PRIVATE_KEY_LEN];
   128    ED25519_keypair(delegated_public_key, delegated_private_key);
   129    ED25519_keypair(root_public_key, root_private_key);
   130    CreateCertificate(identity->certificate, root_private_key, 1000000000,
   131                      2000000000 /* 2033-05-17 */, delegated_public_key);
   132    memcpy(identity->private_key, delegated_private_key,
   133           sizeof(delegated_private_key));
   134    std::unique_ptr<TimeSource> time_source(new DummyTimeSource);
   135    Server* server = new Server(std::move(identity), std::move(time_source));
   136    return std::unique_ptr<Server>(server);
   137  }
   138  
   139  // VerifyResponse is a helper function to verify a that the supplied |response|
   140  // is valid and includes the supplied |nonce|.
   141  static void VerifyResponse(const uint8_t* nonce, const uint8_t* response,
   142                             size_t len) {
   143    // Parse the top-level response.
   144    Parser parser(response, len);
   145    ASSERT_TRUE(parser.is_valid());
   146    uint8_t to_be_verified_with_context[kToBeSignedSize + sizeof(kContextString)];
   147    const uint8_t* to_be_verified;
   148    const uint8_t* signature;
   149    const uint8_t* cert;
   150    const uint8_t* path;
   151    uint32_t index;
   152    size_t path_len;
   153    size_t path_elems;
   154    ASSERT_TRUE(parser.GetFixedLen(&to_be_verified, kTagSREP, kToBeSignedSize));
   155    ASSERT_TRUE(parser.GetFixedLen(&signature, kTagSIG, ED25519_SIGNATURE_LEN));
   156    ASSERT_TRUE(parser.GetFixedLen(&cert, kTagCERT, kCertSize));
   157    ASSERT_TRUE(parser.Get(&index, kTagINDX));
   158    ASSERT_TRUE(parser.GetTag(&path, &path_len, kTagPATH));
   159  
   160    // Parse the signed portion.
   161    Parser srep_parser(to_be_verified, kToBeSignedSize);
   162    ASSERT_TRUE(srep_parser.is_valid());
   163    const uint8_t* root;
   164    uint64_t time;
   165    ASSERT_TRUE(srep_parser.GetFixedLen(&root, kTagROOT, kNonceLength));
   166    ASSERT_TRUE(srep_parser.Get(&time, kTagMIDP));
   167  
   168    // Parse the certificate.
   169    Parser cert_parser(cert, kCertSize);
   170    ASSERT_TRUE(cert_parser.is_valid());
   171    const uint8_t* delegation;
   172    ASSERT_TRUE(
   173        cert_parser.GetFixedLen(&delegation, kTagDELE, kToBeSignedCertSize));
   174  
   175    // Parse the delegation.
   176    Parser delegation_parser(delegation, kToBeSignedCertSize);
   177    ASSERT_TRUE(delegation_parser.is_valid());
   178    const uint8_t* public_key;
   179    uint64_t maxt, mint;
   180    ASSERT_TRUE(delegation_parser.GetFixedLen(&public_key, kTagPUBK,
   181                                              ED25519_PUBLIC_KEY_LEN));
   182    ASSERT_TRUE(delegation_parser.Get(&mint, kTagMINT));
   183    ASSERT_TRUE(delegation_parser.Get(&maxt, kTagMAXT));
   184  
   185    // Verify that delegation is valid for the supplied time.
   186    EXPECT_GE(time, mint);
   187    EXPECT_LE(time, maxt);
   188  
   189    // Verify the signature.
   190    memcpy(to_be_verified_with_context, kContextString, sizeof(kContextString));
   191    memcpy(to_be_verified_with_context + sizeof(kContextString), to_be_verified,
   192           kToBeSignedSize);
   193    EXPECT_TRUE(ED25519_verify(to_be_verified_with_context,
   194                               sizeof(to_be_verified_with_context), signature,
   195                               public_key));
   196  
   197    // Verify the inclusion of |nonce|.
   198    ASSERT_EQ(0, path_len % kNonceLength);
   199    path_elems = path_len / kNonceLength;
   200    uint8_t hash[kNonceLength];
   201    HashLeaf(hash, nonce);
   202    for (size_t i = 0; i < path_elems; i++) {
   203      if (index % 2 == 1) {
   204        HashNode(hash, path, hash);
   205      } else {
   206        HashNode(hash, hash, path);
   207      }
   208      path += kNonceLength;
   209      index /= 2;
   210    }
   211    EXPECT_EQ(0, memcmp(hash, root, kNonceLength));
   212  }
   213  
   214  // MakeRequest, a helper function, writes a new client request with the given
   215  // |nonce| to |*request|.
   216  void MakeRequest(uint8_t* request, uint8_t* nonce) {
   217    Builder builder(request, kMinRequestSize, 2);
   218    RAND_bytes(nonce, sizeof(nonce));
   219    ASSERT_TRUE(builder.AddTagData(kTagNONC, nonce, kNonceLength));
   220    uint8_t* padding;
   221    ASSERT_TRUE(builder.AddTag(&padding, kTagPAD, kPaddingLen));
   222    size_t len;
   223    ASSERT_TRUE(builder.Finish(&len));
   224    ASSERT_EQ(kMinRequestSize, len);
   225  }
   226  
   227  TEST(Server, BadRequest) {
   228    uint8_t root_public_key[ED25519_PUBLIC_KEY_LEN];
   229    auto server = MakeServer(root_public_key);
   230    uint8_t garbage[kMinRequestSize];
   231    memset(garbage, 'a', sizeof(garbage));
   232    EXPECT_FALSE(server->AddRequest(garbage, sizeof(garbage)));
   233  }
   234  
   235  TEST(Server, GoodRequests) {
   236    uint8_t root_public_key[ED25519_PUBLIC_KEY_LEN];
   237    auto server = MakeServer(root_public_key);
   238  
   239    size_t batch_sizes[] = {1, 2, 3, 4, 5, 6, kBatchSize - 1, kBatchSize};
   240    for (size_t i = 0; i < arraysize(batch_sizes); ++i) {
   241      std::unique_ptr<uint8_t[]> requests(
   242          new uint8_t[kBatchSize * kMinRequestSize]);
   243      std::unique_ptr<uint8_t[]> nonces(new uint8_t[kBatchSize * kNonceLength]);
   244      memset(nonces.get(), 0, kBatchSize * kNonceLength);
   245      for (size_t j = 0; j < batch_sizes[i]; ++j) {
   246        MakeRequest(&requests[j * kMinRequestSize], &nonces[j * kNonceLength]);
   247        EXPECT_TRUE(
   248            server->AddRequest(&requests[j * kMinRequestSize], kMinRequestSize));
   249      }
   250      EXPECT_TRUE(server->Sign());
   251  
   252      for (size_t j = 0; j < batch_sizes[i]; ++j) {
   253        uint8_t response[kMaxResponseSize];
   254        size_t response_len;
   255        EXPECT_TRUE(server->MakeResponse(response, &response_len, j));
   256        VerifyResponse(&nonces[j * kNonceLength], response, response_len);
   257      }
   258      server->Reset();
   259    }
   260  }
   261  
   262  TEST(Server, MixedGoodAndBadRequests) {
   263    uint8_t root_public_key[ED25519_PUBLIC_KEY_LEN];
   264    auto server = MakeServer(root_public_key);
   265  
   266    std::unique_ptr<uint8_t[]> requests(
   267        new uint8_t[kBatchSize * kMinRequestSize]);
   268    std::unique_ptr<uint8_t[]> nonces(new uint8_t[kBatchSize * kNonceLength]);
   269    memset(nonces.get(), 0, kBatchSize * kNonceLength);
   270  
   271    MakeRequest(&requests[0 * kMinRequestSize], &nonces[0 * kNonceLength]);
   272    MakeRequest(&requests[1 * kMinRequestSize], &nonces[1 * kNonceLength]);
   273    MakeRequest(&requests[2 * kMinRequestSize], &nonces[2 * kNonceLength]);
   274    memset(&requests[1 * kMinRequestSize], 'a', kMinRequestSize);
   275  
   276    EXPECT_TRUE(
   277        server->AddRequest(&requests[0 * kMinRequestSize], kMinRequestSize));
   278    EXPECT_FALSE(
   279        server->AddRequest(&requests[1 * kMinRequestSize], kMinRequestSize));
   280    EXPECT_TRUE(
   281        server->AddRequest(&requests[2 * kMinRequestSize], kMinRequestSize));
   282    server->Sign();
   283  
   284    uint8_t response[kMaxResponseSize];
   285    size_t response_len;
   286  
   287    EXPECT_TRUE(server->MakeResponse(response, &response_len, 0));
   288    VerifyResponse(&nonces[0 * kNonceLength], response, response_len);
   289    EXPECT_TRUE(server->MakeResponse(response, &response_len, 1));
   290    // index #1 -> nonce #2
   291    VerifyResponse(&nonces[2 * kNonceLength], response, response_len);
   292  }
   293  
   294  }  // namespace roughtime