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