1 /*
2  * Copyright 2021, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <android/hardware/keymaster/4.0/types.h>
25 
26 #include <cn-cbor/cn-cbor.h>
27 
28 namespace cuttlefish {
29 namespace confui {
30 
31 /** take prompt_text_, extra_data
32  * returns CBOR map, created with the two
33  *
34  * Usage:
35  *  if (IsOk()) GetMessage()
36  *
37  * The CBOR map is used to create signed confirmation
38  */
39 class Cbor {
40   enum class Error : uint32_t {
41     OK = 0,
42     OUT_OF_DATA = 1,
43     MALFORMED = 2,
44     MALFORMED_UTF8 = 3,
45   };
46 
47   enum class MessageSize : uint32_t { MAX = 6144u };
48 
49   enum class Type : uint8_t {
50     NUMBER = 0,
51     NEGATIVE = 1,
52     BYTE_STRING = 2,
53     TEXT_STRING = 3,
54     ARRAY = 4,
55     MAP = 5,
56     TAG = 6,
57     FLOAT = 7,
58   };
59 
60  public:
Cbor(const std::string & prompt_text,const std::vector<std::uint8_t> & extra_data)61   Cbor(const std::string& prompt_text,
62        const std::vector<std::uint8_t>& extra_data)
63       : prompt_text_(prompt_text),
64         extra_data_(extra_data),
65         buffer_status_{Error::OK},
66         buffer_(kMax + 1) {
67     Init();
68   }
69 
IsOk()70   bool IsOk() const { return buffer_status_ == Error::OK; }
GetErrorCode()71   Error GetErrorCode() const { return buffer_status_; }
IsMessageTooLong()72   bool IsMessageTooLong() const { return buffer_status_ == Error::OUT_OF_DATA; }
IsMalformedUtf8()73   bool IsMalformedUtf8() const {
74     return buffer_status_ == Error::MALFORMED_UTF8;
75   }
76   // call this only when IsOk() returns true
77   std::vector<std::uint8_t>&& GetMessage();
78 
79   /** When encoded, the Cbor object should not exceed this limit in terms of
80    * size in bytes
81    */
82   const std::uint32_t kMax = static_cast<std::uint32_t>(MessageSize::MAX);
83 
84  private:
85   class CborDeleter {
86    public:
operator()87     void operator()(cn_cbor* ptr) { cn_cbor_free(ptr); }
88   };
89 
90   std::unique_ptr<cn_cbor, CborDeleter> cb_map_;
91   std::string prompt_text_;
92   std::vector<std::uint8_t> extra_data_;
93   Error buffer_status_;
94   std::vector<std::uint8_t> buffer_;
95 
96   void Init();
97   Error CheckUTF8Copy(const std::string& text);
98 };
99 
100 }  // namespace confui
101 }  // end of namespace cuttlefish
102