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 #pragma once
10 
11 #include <folly/portability/GMock.h>
12 
13 #include <fizz/crypto/aead/test/Mocks.h>
14 #include <fizz/crypto/exchange/test/Mocks.h>
15 #include <fizz/protocol/test/Mocks.h>
16 #include <fizz/record/test/Mocks.h>
17 #include <fizz/server/AsyncFizzServer.h>
18 #include <fizz/server/AsyncSelfCert.h>
19 #include <fizz/server/CookieCipher.h>
20 #include <fizz/server/ReplayCache.h>
21 #include <fizz/server/ServerExtensions.h>
22 #include <fizz/server/ServerProtocol.h>
23 
24 namespace fizz {
25 namespace server {
26 namespace test {
27 
28 /* using override */
29 using namespace testing;
30 /* using override */
31 using namespace fizz::test;
32 
33 class MockServerStateMachine : public ServerStateMachine {
34  public:
35   MOCK_METHOD4(
36       _processAccept,
37       folly::Optional<AsyncActions>(
38           const State&,
39           folly::Executor*,
40           std::shared_ptr<const FizzServerContext> context,
41           const std::shared_ptr<ServerExtensions>& extensions));
processAccept(const State & state,folly::Executor * executor,std::shared_ptr<const FizzServerContext> context,const std::shared_ptr<ServerExtensions> & extensions)42   AsyncActions processAccept(
43       const State& state,
44       folly::Executor* executor,
45       std::shared_ptr<const FizzServerContext> context,
46       const std::shared_ptr<ServerExtensions>& extensions) override {
47     return *_processAccept(state, executor, std::move(context), extensions);
48   }
49 
50   MOCK_METHOD3(
51       _processSocketData,
52       folly::Optional<AsyncActions>(
53           const State&,
54           folly::IOBufQueue&,
55           Aead::AeadOptions));
processSocketData(const State & state,folly::IOBufQueue & queue,Aead::AeadOptions options)56   AsyncActions processSocketData(
57       const State& state,
58       folly::IOBufQueue& queue,
59       Aead::AeadOptions options) override {
60     return *_processSocketData(state, queue, options);
61   }
62 
63   MOCK_METHOD2(
64       _processWriteNewSessionTicket,
65       folly::Optional<AsyncActions>(const State&, WriteNewSessionTicket&));
processWriteNewSessionTicket(const State & state,WriteNewSessionTicket write)66   AsyncActions processWriteNewSessionTicket(
67       const State& state,
68       WriteNewSessionTicket write) override {
69     return *_processWriteNewSessionTicket(state, write);
70   }
71 
72   MOCK_METHOD2(
73       _processAppWrite,
74       folly::Optional<AsyncActions>(const State&, AppWrite&));
processAppWrite(const State & state,AppWrite appWrite)75   AsyncActions processAppWrite(const State& state, AppWrite appWrite) override {
76     return *_processAppWrite(state, appWrite);
77   }
78 
79   MOCK_METHOD2(
80       _processEarlyAppWrite,
81       folly::Optional<AsyncActions>(const State&, EarlyAppWrite&));
processEarlyAppWrite(const State & state,EarlyAppWrite appWrite)82   AsyncActions processEarlyAppWrite(const State& state, EarlyAppWrite appWrite)
83       override {
84     return *_processEarlyAppWrite(state, appWrite);
85   }
86 
87   MOCK_METHOD1(_processAppClose, folly::Optional<Actions>(const State&));
processAppClose(const State & state)88   Actions processAppClose(const State& state) override {
89     return *_processAppClose(state);
90   }
91 
92   MOCK_METHOD1(
93       _processAppCloseImmediate,
94       folly::Optional<Actions>(const State&));
processAppCloseImmediate(const State & state)95   Actions processAppCloseImmediate(const State& state) override {
96     return *_processAppCloseImmediate(state);
97   }
98 };
99 
100 class MockTicketCipher : public TicketCipher {
101  public:
102   MOCK_CONST_METHOD1(
103       _encrypt,
104       folly::Future<folly::Optional<std::pair<Buf, std::chrono::seconds>>>(
105           ResumptionState&));
encrypt(ResumptionState resState)106   folly::Future<folly::Optional<std::pair<Buf, std::chrono::seconds>>> encrypt(
107       ResumptionState resState) const override {
108     return _encrypt(resState);
109   }
110 
111   MOCK_CONST_METHOD1(
112       _decrypt,
113       folly::Future<std::pair<PskType, folly::Optional<ResumptionState>>>(
114           std::unique_ptr<folly::IOBuf>& encryptedTicket));
decrypt(std::unique_ptr<folly::IOBuf> encryptedTicket)115   folly::Future<std::pair<PskType, folly::Optional<ResumptionState>>> decrypt(
116       std::unique_ptr<folly::IOBuf> encryptedTicket) const override {
117     return _decrypt(encryptedTicket);
118   }
119 
120   void setDefaults(
121       std::chrono::system_clock::time_point ticketIssued =
122           std::chrono::system_clock::now()) {
123     ON_CALL(*this, _decrypt(_))
124         .WillByDefault(InvokeWithoutArgs([ticketIssued]() {
125           ResumptionState res;
126           res.version = ProtocolVersion::tls_1_3;
127           res.cipher = CipherSuite::TLS_AES_128_GCM_SHA256;
128           res.resumptionSecret = folly::IOBuf::copyBuffer("resumesecret");
129           res.alpn = "h2";
130           res.ticketAgeAdd = 0;
131           res.ticketIssueTime = ticketIssued;
132           res.handshakeTime = ticketIssued;
133           return std::make_pair(PskType::Resumption, std::move(res));
134         }));
135     ON_CALL(*this, _encrypt(_)).WillByDefault(InvokeWithoutArgs([]() {
136       return std::make_pair(
137           folly::IOBuf::copyBuffer("ticket"), std::chrono::seconds(100));
138     }));
139   }
140 };
141 
142 class MockCookieCipher : public CookieCipher {
143  public:
144   MOCK_CONST_METHOD1(_decrypt, folly::Optional<CookieState>(Buf&));
decrypt(Buf cookie)145   folly::Optional<CookieState> decrypt(Buf cookie) const override {
146     return _decrypt(cookie);
147   }
148 };
149 
150 template <typename SM>
151 class MockHandshakeCallbackT : public AsyncFizzServerT<SM>::HandshakeCallback {
152  public:
153   MOCK_METHOD0(_fizzHandshakeSuccess, void());
fizzHandshakeSuccess(AsyncFizzServerT<SM> *)154   void fizzHandshakeSuccess(AsyncFizzServerT<SM>*) noexcept override {
155     _fizzHandshakeSuccess();
156   }
157 
158   MOCK_METHOD1(_fizzHandshakeError, void(folly::exception_wrapper));
fizzHandshakeError(AsyncFizzServerT<SM> *,folly::exception_wrapper ew)159   void fizzHandshakeError(
160       AsyncFizzServerT<SM>*,
161       folly::exception_wrapper ew) noexcept override {
162     _fizzHandshakeError(std::move(ew));
163   }
164 
165   MOCK_METHOD1(
166       _fizzHandshakeAttemptFallback,
167       void(std::unique_ptr<folly::IOBuf>&));
fizzHandshakeAttemptFallback(std::unique_ptr<folly::IOBuf> clientHello)168   void fizzHandshakeAttemptFallback(
169       std::unique_ptr<folly::IOBuf> clientHello) override {
170     return _fizzHandshakeAttemptFallback(clientHello);
171   }
172 };
173 
174 using MockHandshakeCallback = MockHandshakeCallbackT<ServerStateMachine>;
175 
176 template <typename SM>
177 class MockAsyncFizzServerT : public AsyncFizzServerT<SM> {
178  public:
MockAsyncFizzServerT(folly::AsyncTransportWrapper::UniquePtr socket,const std::shared_ptr<FizzServerContext> & fizzContext)179   MockAsyncFizzServerT(
180       folly::AsyncTransportWrapper::UniquePtr socket,
181       const std::shared_ptr<FizzServerContext>& fizzContext)
182       : AsyncFizzServerT<SM>(std::move(socket), fizzContext) {}
183 
184   using UniquePtr = std::
185       unique_ptr<MockAsyncFizzServerT, folly::DelayedDestruction::Destructor>;
186 
187   MOCK_CONST_METHOD3(getEkm, Buf(folly::StringPiece, const Buf&, uint16_t));
188 };
189 
190 using MockAsyncFizzServer = MockAsyncFizzServerT<ServerStateMachine>;
191 
192 class MockCertManager : public CertManager {
193  public:
194   MOCK_CONST_METHOD4(
195       getCert,
196       CertMatch(
197           const folly::Optional<std::string>& sni,
198           const std::vector<SignatureScheme>& supportedSigSchemes,
199           const std::vector<SignatureScheme>& peerSigSchemes,
200           const std::vector<Extension>& peerExtensions));
201   MOCK_CONST_METHOD1(
202       getCert,
203       std::shared_ptr<SelfCert>(const std::string& identity));
204 };
205 
206 class MockServerExtensions : public ServerExtensions {
207  public:
208   MOCK_METHOD1(getExtensions, std::vector<Extension>(const ClientHello& chlo));
209 };
210 
211 class MockReplayCache : public ReplayCache {
212  public:
213   MOCK_METHOD1(check, folly::Future<ReplayCacheResult>(folly::ByteRange));
214 };
215 
216 class MockAppTokenValidator : public AppTokenValidator {
217  public:
218   MOCK_CONST_METHOD1(validate, bool(const ResumptionState&));
219 };
220 
221 class MockAsyncSelfCert : public AsyncSelfCert {
222  public:
223   MOCK_CONST_METHOD0(getIdentity, std::string());
224   MOCK_CONST_METHOD0(getAltIdentities, std::vector<std::string>());
225   MOCK_CONST_METHOD0(getSigSchemes, std::vector<SignatureScheme>());
226 
227   MOCK_CONST_METHOD1(_getCertMessage, CertificateMsg(Buf&));
getCertMessage(Buf buf)228   CertificateMsg getCertMessage(Buf buf) const override {
229     return _getCertMessage(buf);
230   }
231   MOCK_CONST_METHOD1(
232       getCompressedCert,
233       CompressedCertificate(CertificateCompressionAlgorithm));
234 
235   MOCK_CONST_METHOD3(
236       sign,
237       Buf(SignatureScheme scheme,
238           CertificateVerifyContext context,
239           folly::ByteRange toBeSigned));
240   MOCK_CONST_METHOD0(getX509, folly::ssl::X509UniquePtr());
241   MOCK_CONST_METHOD3(
242       signFuture,
243       folly::Future<folly::Optional<Buf>>(
244           SignatureScheme scheme,
245           CertificateVerifyContext context,
246           folly::ByteRange toBeSigned));
247 };
248 } // namespace test
249 } // namespace server
250 } // namespace fizz
251