1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h"
6
7 #include <string>
8
9 #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
10 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
11 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
12
13 namespace quic {
14 namespace test {
15
16 class CryptoSecretBoxerTest : public QuicTest {};
17
TEST_F(CryptoSecretBoxerTest,BoxAndUnbox)18 TEST_F(CryptoSecretBoxerTest, BoxAndUnbox) {
19 quiche::QuicheStringPiece message("hello world");
20
21 CryptoSecretBoxer boxer;
22 boxer.SetKeys({std::string(CryptoSecretBoxer::GetKeySize(), 0x11)});
23
24 const std::string box = boxer.Box(QuicRandom::GetInstance(), message);
25
26 std::string storage;
27 quiche::QuicheStringPiece result;
28 EXPECT_TRUE(boxer.Unbox(box, &storage, &result));
29 EXPECT_EQ(result, message);
30
31 EXPECT_FALSE(boxer.Unbox(std::string(1, 'X') + box, &storage, &result));
32 EXPECT_FALSE(
33 boxer.Unbox(box.substr(1, std::string::npos), &storage, &result));
34 EXPECT_FALSE(boxer.Unbox(std::string(), &storage, &result));
35 EXPECT_FALSE(boxer.Unbox(
36 std::string(1, box[0] ^ 0x80) + box.substr(1, std::string::npos),
37 &storage, &result));
38 }
39
40 // Helper function to test whether one boxer can decode the output of another.
CanDecode(const CryptoSecretBoxer & decoder,const CryptoSecretBoxer & encoder)41 static bool CanDecode(const CryptoSecretBoxer& decoder,
42 const CryptoSecretBoxer& encoder) {
43 quiche::QuicheStringPiece message("hello world");
44 const std::string boxed = encoder.Box(QuicRandom::GetInstance(), message);
45 std::string storage;
46 quiche::QuicheStringPiece result;
47 bool ok = decoder.Unbox(boxed, &storage, &result);
48 if (ok) {
49 EXPECT_EQ(result, message);
50 }
51 return ok;
52 }
53
TEST_F(CryptoSecretBoxerTest,MultipleKeys)54 TEST_F(CryptoSecretBoxerTest, MultipleKeys) {
55 std::string key_11(CryptoSecretBoxer::GetKeySize(), 0x11);
56 std::string key_12(CryptoSecretBoxer::GetKeySize(), 0x12);
57
58 CryptoSecretBoxer boxer_11, boxer_12, boxer;
59 boxer_11.SetKeys({key_11});
60 boxer_12.SetKeys({key_12});
61 boxer.SetKeys({key_12, key_11});
62
63 // Neither single-key boxer can decode the other's tokens.
64 EXPECT_FALSE(CanDecode(boxer_11, boxer_12));
65 EXPECT_FALSE(CanDecode(boxer_12, boxer_11));
66
67 // |boxer| encodes with the first key, which is key_12.
68 EXPECT_TRUE(CanDecode(boxer_12, boxer));
69 EXPECT_FALSE(CanDecode(boxer_11, boxer));
70
71 // The boxer with both keys can decode tokens from either single-key boxer.
72 EXPECT_TRUE(CanDecode(boxer, boxer_11));
73 EXPECT_TRUE(CanDecode(boxer, boxer_12));
74
75 // After we flush key_11 from |boxer|, it can no longer decode tokens from
76 // |boxer_11|.
77 boxer.SetKeys({key_12});
78 EXPECT_FALSE(CanDecode(boxer, boxer_11));
79 }
80
81 } // namespace test
82 } // namespace quic
83