1 /*
2  *  Copyright (c) 2018-present, Facebook, Inc.
3  *  All rights reserved.
4  *
5  *  This source code is licensed under the BSD-style license found in the
6  *  LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <folly/portability/GTest.h>
10 
11 #include <fizz/crypto/test/TestUtil.h>
12 #include <fizz/protocol/clock/test/Mocks.h>
13 #include <fizz/server/TicketTypes.h>
14 #include <fizz/util/FizzUtil.h>
15 #include <folly/FileUtil.h>
16 #include <folly/experimental/TestUtil.h>
17 
18 namespace fizz {
19 namespace test {
20 
TEST(UtilTest,GetAlpnFromNpn)21 TEST(UtilTest, GetAlpnFromNpn) {
22   std::list<folly::SSLContext::NextProtocolsItem> npList;
23   std::list<std::string> protocolList1{"test", "test2"};
24   std::list<std::string> protocolList2{"test3", "test4"};
25 
26   npList.push_back(folly::SSLContext::NextProtocolsItem(1, protocolList1));
27   {
28     std::vector<std::string> expectedList{
29         std::begin(protocolList1), std::end(protocolList1)};
30     EXPECT_EQ(FizzUtil::getAlpnsFromNpnList(npList), expectedList);
31   }
32 
33   npList.push_back(folly::SSLContext::NextProtocolsItem(2, protocolList2));
34   {
35     std::vector<std::string> expectedList{
36         std::begin(protocolList2), std::end(protocolList2)};
37     EXPECT_EQ(FizzUtil::getAlpnsFromNpnList(npList), expectedList);
38   }
39 }
40 
TEST(UtilTest,CreateTicketCipher)41 TEST(UtilTest, CreateTicketCipher) {
42   auto cipher = FizzUtil::createTicketCipher<server::AES128TicketCipher>(
43       std::vector<std::string>(),
44       "fakeSecretttttttttttttttttttttttttt",
45       std::vector<std::string>(),
46       std::chrono::seconds(100),
47       std::chrono::minutes(100),
48       std::make_shared<OpenSSLFactory>(),
49       std::make_shared<server::CertManager>(),
50       folly::Optional<std::string>("fakeContext"));
51   auto clock = std::make_shared<MockClock>();
52   server::TicketPolicy policy;
53   policy.setClock(clock);
54   cipher->setPolicy(policy);
55   {
56     server::ResumptionState state;
57     auto blob = cipher->encrypt(std::move(state)).get();
58     EXPECT_EQ(
59         std::get<0>(cipher->decrypt(std::move(std::get<0>(*blob))).get()),
60         PskType::Resumption);
61   }
62   {
63     auto newCipher = FizzUtil::createTicketCipher<server::AES128TicketCipher>(
64         std::vector<std::string>(),
65         "fakeSecrettttttttttttttttttttttttt2",
66         std::vector<std::string>(),
67         std::chrono::seconds(100),
68         std::chrono::minutes(100),
69         std::make_shared<OpenSSLFactory>(),
70         std::make_shared<server::CertManager>(),
71         folly::Optional<std::string>("fakeContext"));
72     newCipher->setPolicy(std::move(policy));
73     server::ResumptionState state;
74     auto blob = cipher->encrypt(std::move(state)).get();
75     EXPECT_EQ(
76         std::get<0>(newCipher->decrypt(std::move(std::get<0>(*blob))).get()),
77         PskType::Rejected);
78   }
79 }
80 
TEST(UtilTest,CreateTokenCipher)81 TEST(UtilTest, CreateTokenCipher) {
82   auto cipher = FizzUtil::createTokenCipher<server::AES128TokenCipher>(
83       std::vector<std::string>(),
84       "fakeSecrettttttttttttttttttttttttt3",
85       std::vector<std::string>(),
86       folly::Optional<std::string>("fakePskContext"),
87       std::string("fakeCodecContext"));
88   {
89     auto inMessage = "Secret message";
90     auto inPlaintextBuf = folly::IOBuf::copyBuffer(inMessage);
91     auto cipherTextBuf = cipher->encrypt(std::move(inPlaintextBuf)).value();
92     auto outPlaintextBuf = cipher->decrypt(std::move(cipherTextBuf)).value();
93     auto outMessage = outPlaintextBuf->moveToFbString().toStdString();
94     EXPECT_EQ(inMessage, outMessage);
95   }
96   {
97     auto newCipher = FizzUtil::createTokenCipher<server::AES128TokenCipher>(
98         std::vector<std::string>(),
99         "fakeSecrettttttttttttttttttttttttt4",
100         std::vector<std::string>(),
101         folly::Optional<std::string>("fakePskContext"),
102         std::string("fakeCodecContext"));
103     auto inMessage = "Brand new secret message";
104     auto inPlaintextBuf = folly::IOBuf::copyBuffer(inMessage);
105     auto cipherTextBuf = newCipher->encrypt(std::move(inPlaintextBuf)).value();
106     auto outPlaintextBuf = newCipher->decrypt(std::move(cipherTextBuf)).value();
107     auto outMessage = outPlaintextBuf->moveToFbString().toStdString();
108     EXPECT_EQ(inMessage, outMessage);
109   }
110 }
111 
TEST(UtilTest,ReadPKey)112 TEST(UtilTest, ReadPKey) {
113   {
114     folly::test::TemporaryFile testFile("test");
115     folly::writeFileAtomic(testFile.path().string(), kP256Key);
116     FizzUtil::readPrivateKey(testFile.path().string(), "");
117   }
118   {
119     folly::test::TemporaryFile testFile("test");
120     folly::writeFileAtomic(
121         testFile.path().string(), folly::StringPiece("test"));
122     EXPECT_THROW(
123         FizzUtil::readPrivateKey(testFile.path().string(), ""),
124         std::runtime_error);
125   }
126 }
127 
TEST(UtilTest,ReadChainFile)128 TEST(UtilTest, ReadChainFile) {
129   {
130     folly::test::TemporaryFile testFile("test");
131     folly::writeFileAtomic(testFile.path().string(), kP256Certificate);
132     EXPECT_EQ(FizzUtil::readChainFile(testFile.path().string()).size(), 1);
133   }
134   {
135     folly::test::TemporaryFile testFile("test");
136     folly::writeFileAtomic(testFile.path().string(), kP384Key);
137     EXPECT_THROW(
138         FizzUtil::readChainFile(testFile.path().string()), std::runtime_error);
139   }
140   {
141     EXPECT_THROW(
142         FizzUtil::readChainFile("test_file_does_not_exist"),
143         std::runtime_error);
144   }
145 }
146 
147 } // namespace test
148 } // namespace fizz
149