1 /*
2  **
3  ** Copyright 2020, The Android Open Source Project
4  **
5  ** Licensed under the Apache License, Version 2.0 (the "License");
6  ** you may not use this file except in compliance with the License.
7  ** You may obtain a copy of the License at
8  **
9  **     http://www.apache.org/licenses/LICENSE-2.0
10  **
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  */
17 #pragma once
18 
19 #include <iostream>
20 #include <memory>
21 #include <numeric>
22 #include <vector>
23 
24 #include <cppbor.h>
25 #include <cppbor_parse.h>
26 
27 #include <aidl/android/hardware/security/keymint/Certificate.h>
28 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
29 #include <aidl/android/hardware/security/secureclock/TimeStampToken.h>
30 #include <aidl/android/hardware/security/sharedsecret/ISharedSecret.h>
31 
32 #include <keymaster/android_keymaster_messages.h>
33 
34 namespace keymint::javacard {
35 using aidl::android::hardware::security::keymint::AttestationKey;
36 using aidl::android::hardware::security::keymint::Certificate;
37 using aidl::android::hardware::security::keymint::HardwareAuthToken;
38 using aidl::android::hardware::security::keymint::KeyCharacteristics;
39 using aidl::android::hardware::security::keymint::KeyParameter;
40 using aidl::android::hardware::security::secureclock::TimeStampToken;
41 using aidl::android::hardware::security::sharedsecret::SharedSecretParameters;
42 using cppbor::Array;
43 using cppbor::Bstr;
44 using cppbor::EncodedItem;
45 using cppbor::Item;
46 using cppbor::MajorType;
47 using cppbor::Map;
48 using cppbor::Nint;
49 using cppbor::Tstr;
50 using cppbor::Uint;
51 using std::string;
52 using std::unique_ptr;
53 using std::vector;
54 
55 class CborConverter {
56   public:
57     CborConverter() = default;
58 
59     ~CborConverter() = default;
60 
61     std::tuple<std::unique_ptr<Item>, keymaster_error_t>
62     decodeData(const std::vector<uint8_t>& response);
63 
64     std::optional<uint64_t> getUint64(const unique_ptr<Item>& item);
65 
66     std::optional<uint64_t> getUint64(const unique_ptr<Item>& item, const uint32_t pos);
67 
68     std::optional<SharedSecretParameters>
69     getSharedSecretParameters(const std::unique_ptr<Item>& item, const uint32_t pos);
70 
71     std::optional<string> getByteArrayStr(const unique_ptr<Item>& item, const uint32_t pos);
72 
73     std::optional<string> getTextStr(const unique_ptr<Item>& item, const uint32_t pos);
74 
75     std::optional<std::vector<uint8_t>> getByteArrayVec(const unique_ptr<Item>& item,
76                                                         const uint32_t pos);
77 
78     std::optional<vector<KeyParameter>> getKeyParameters(const unique_ptr<Item>& item,
79                                                          const uint32_t pos);
80 
81     bool addKeyparameters(Array& array, const vector<KeyParameter>& keyParams);
82 
83     bool addAttestationKey(Array& array, const std::optional<AttestationKey>& attestationKey);
84 
85     bool addHardwareAuthToken(Array& array, const HardwareAuthToken& authToken);
86 
87     bool addSharedSecretParameters(Array& array, const vector<SharedSecretParameters>& params);
88 
89     std::optional<TimeStampToken> getTimeStampToken(const std::unique_ptr<Item>& item,
90                                                     const uint32_t pos);
91 
92     std::optional<vector<KeyCharacteristics>>
93     getKeyCharacteristics(const std::unique_ptr<Item>& item, const uint32_t pos);
94 
95     std::optional<vector<Certificate>> getCertificateChain(const std::unique_ptr<Item>& item,
96                                                            const uint32_t pos);
97 
98      std::optional<vector<vector<uint8_t>>> getMultiByteArray(const unique_ptr<Item>& item,
99                                                               const uint32_t pos);
100 
101     bool addTimeStampToken(Array& array, const TimeStampToken& token);
102 
103     std::optional<Map> getMapItem(const std::unique_ptr<Item>& item, const uint32_t pos);
104 
105     std::optional<Array> getArrayItem(const std::unique_ptr<Item>& item, const uint32_t pos);
106 
107     std::optional<keymaster_error_t> getErrorCode(const std::unique_ptr<Item>& item,
108                                                   const uint32_t pos);
109 
110   private:
111     /**
112      * Get the type of the Item pointer.
113      */
getType(const unique_ptr<Item> & item)114     inline MajorType getType(const unique_ptr<Item>& item) { return item.get()->type(); }
115 
116     /**
117      * Construct Keyparameter structure from the pair of key and value. If TagType is  ENUM_REP the
118      * value contains binary string. If TagType is UINT_REP or ULONG_REP the value contains Array of
119      * unsigned integers.
120      */
121     std::optional<std::vector<KeyParameter>> getKeyParameter(
122         const std::pair<const std::unique_ptr<Item>&, const std::unique_ptr<Item>&> pair);
123 
124     /**
125      * Get the sub item pointer from the root item pointer at the given position.
126      */
getItemAtPos(const unique_ptr<Item> & item,const uint32_t pos)127     inline std::optional<unique_ptr<Item>> getItemAtPos(const unique_ptr<Item>& item,
128                                                         const uint32_t pos) {
129         Array* arr = nullptr;
130 
131         if (MajorType::ARRAY != getType(item)) {
132             return std::nullopt;
133         }
134         arr = const_cast<Array*>(item.get()->asArray());
135         if (arr->size() < (pos + 1)) {
136             return std::nullopt;
137         }
138         return std::move((*arr)[pos]);
139     }
140 };
141 
142 }  // namespace keymint::javacard
143