1 // Copyright 2023 Google LLC
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 //     https://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 #pragma once
15 
16 #include <string>
17 
18 #include "ukey2_bindings.h"
19 
20 namespace rust {
21 struct D2DRestoreConnectionContextV1Result;
22 
23 // The Connection object that can handle encryption/decryption of messages over
24 // the wire. This object should only be constructed via FromSavedSession() or
25 // Ukey2Handshake::ToConnectionContext().
26 class D2DConnectionContextV1 {
27  public:
28   // Encodes a message to the connection peer using the derived key from the
29   // handshake If associated_data is not empty, it will be used to compute the
30   // signature and the same associated_data string must be passed into
31   // DecodeMessageFromPeer() in order for the message to be validated.
32   std::string EncodeMessageToPeer(std::string message,
33                                   std::string associated_data);
34   // Decodes a message from the connection peer. If associated_data was passed
35   // into EncodeMessageToPeer(), that same associated_data must be passed here
36   // in order for this function to succeed.
37   std::string DecodeMessageFromPeer(std::string message,
38                                     std::string associated_data);
39   // Gets a session-specific unique identifier.
40   std::string GetSessionUnique();
41   // Gets the encoding sequence number.
42   int GetSequenceNumberForEncoding();
43   // Gets the decoding sequence number.
44   int GetSequenceNumberForDecoding();
45   // Returns byte data suitable for use with FromSavedSession().
46   std::string SaveSession();
47   // Recreates the state of a previous D2DConnectionContextV1 using the data
48   // from SaveSession(). This function will return an error if the byte pattern
49   // is not as expected. Expected format:
50   // ---------------------------------------------------------------------------
51   // | 1 byte |       4 bytes     |      4 bytes      |  32 bytes |  32 bytes  |
52   // ---------------------------------------------------------------------------
53   //  Version | Encode sequence # | Decode sequence # | Encode key | Decode key
54   static D2DRestoreConnectionContextV1Result FromSavedSession(std::string data);
55 
56  private:
57   friend class Ukey2Handshake;
D2DConnectionContextV1(Ukey2ConnectionContextHandle handle)58   D2DConnectionContextV1(Ukey2ConnectionContextHandle handle)
59       : handle_(handle) {}
60   const Ukey2ConnectionContextHandle handle_;
61 };
62 
63 struct D2DRestoreConnectionContextV1Result {
64   D2DConnectionContextV1 handle;
65   CD2DRestoreConnectionContextV1Status status;
66 };
67 
68 struct ParseResult {
69   bool success;
70   std::string alert_to_send;
71 };
72 
73 // Base handshake. This should be used to start a secure channel represented by
74 // a D2DConnectionContextV1.
75 class Ukey2Handshake {
76  public:
77   // Creates a Ukey2Handshake instance for the responder.
78   static Ukey2Handshake ForResponder();
79   // Creates a Ukey2Handshake instance for the initiator.
80   static Ukey2Handshake ForInitiator();
81   // Returns true if the handshake is complete, false otherwise.
82   bool IsHandshakeComplete();
83   // Returns raw byte data with the message to send over the wire.
84   std::string GetNextHandshakeMessage();
85   // Parses the raw handshake message received over the wire.
86   ParseResult ParseHandshakeMessage(std::string message);
87   // Returns the authentication string of length output_length to be confirmed
88   // on both devices.
89   std::string GetVerificationString(size_t output_length);
90   // Turns this Ukey2Handshake instance into a D2DConnectionContextV1. This
91   // method once called, renders the Ukey2Handshake object unusable.
92   D2DConnectionContextV1 ToConnectionContext();
93 
94  private:
Ukey2Handshake(Ukey2HandshakeContextHandle handle)95   Ukey2Handshake(Ukey2HandshakeContextHandle handle) : handle_(handle) {}
96   const Ukey2HandshakeContextHandle handle_;
97 };
98 }  // namespace rust
99