blob: 288d600e3f6cda6c1544eb4a379f40ead21c17bc [file] [log] [blame]
Darren Krahn69a3dbc2015-09-22 16:21:04 -07001// Copyright 2015 The Android Open Source Project
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// http://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
15#include <cstdio>
16#include <memory>
17#include <string>
18#include <vector>
19
20#include "base/command_line.h"
21#include "keymaster/authorization_set.h"
22#include "keystore/keystore_client_impl.h"
23
24using base::CommandLine;
25using keymaster::AuthorizationSet;
26using keymaster::AuthorizationSetBuilder;
27using keystore::KeystoreClient;
28
29namespace {
30
31void PrintUsageAndExit() {
32 printf("Usage: keystore_client_v2 <command> [options]\n");
33 printf("Commands: add-entropy --input=<entropy>\n"
34 " generate --name=<key_name>\n"
35 " get-chars --name=<key_name>\n"
36 " export --name=<key_name>\n"
37 " delete --name=<key_name>\n"
38 " delete-all\n"
39 " exists --name=<key_name>\n"
40 " list [--prefix=<key_name_prefix>]\n"
41 " sign-verify --name=<key_name>\n");
42 exit(1);
43}
44
45std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
46 return std::unique_ptr<KeystoreClient>(new keystore::KeystoreClientImpl);
47}
48
49int AddEntropy(const std::string& input) {
50 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
51 int32_t result = keystore->addRandomNumberGeneratorEntropy(input);
52 printf("AddEntropy: %d\n", result);
53 return result;
54}
55
56int GenerateKey(const std::string& name) {
57 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
58 AuthorizationSetBuilder params;
59 params.RsaSigningKey(2048, 65537)
60 .Digest(KM_DIGEST_SHA_2_224)
61 .Digest(KM_DIGEST_SHA_2_256)
62 .Digest(KM_DIGEST_SHA_2_384)
63 .Digest(KM_DIGEST_SHA_2_512)
64 .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)
65 .Padding(KM_PAD_RSA_PSS)
66 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
67 AuthorizationSet hardware_enforced_characteristics;
68 AuthorizationSet software_enforced_characteristics;
69 int32_t result = keystore->generateKey(name, params.build(), &hardware_enforced_characteristics,
70 &software_enforced_characteristics);
71 printf("GenerateKey: %d (%zu, %zu)\n", result, hardware_enforced_characteristics.size(),
72 software_enforced_characteristics.size());
73 return result;
74}
75
76int GetCharacteristics(const std::string& name) {
77 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
78 AuthorizationSet hardware_enforced_characteristics;
79 AuthorizationSet software_enforced_characteristics;
80 int32_t result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
81 &software_enforced_characteristics);
82 printf("GetCharacteristics: %d (%zu, %zu)\n", result, hardware_enforced_characteristics.size(),
83 software_enforced_characteristics.size());
84 return result;
85}
86
87int ExportKey(const std::string& name) {
88 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
89 std::string data;
90 int32_t result = keystore->exportKey(KM_KEY_FORMAT_X509, name, &data);
91 printf("ExportKey: %d (%zu)\n", result, data.size());
92 return result;
93}
94
95int DeleteKey(const std::string& name) {
96 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
97 int32_t result = keystore->deleteKey(name);
98 printf("DeleteKey: %d\n", result);
99 return result;
100}
101
102int DeleteAllKeys() {
103 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
104 int32_t result = keystore->deleteAllKeys();
105 printf("DeleteAllKeys: %d\n", result);
106 return result;
107}
108
109int DoesKeyExist(const std::string& name) {
110 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
111 printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no");
112 return 0;
113}
114
115int List(const std::string& prefix) {
116 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
117 std::vector<std::string> key_list;
118 if (!keystore->listKeys(prefix, &key_list)) {
119 printf("ListKeys failed.\n");
120 return 1;
121 }
122 printf("Keys:\n");
123 for (const auto& key_name : key_list) {
124 printf(" %s\n", key_name.c_str());
125 }
126 return 0;
127}
128
129int SignAndVerify(const std::string& name) {
130 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
131 AuthorizationSetBuilder sign_params;
132 sign_params.Padding(KM_PAD_RSA_PKCS1_1_5_SIGN);
133 sign_params.Digest(KM_DIGEST_SHA_2_256);
134 AuthorizationSet output_params;
135 keymaster_operation_handle_t handle;
136 int32_t result = keystore->beginOperation(KM_PURPOSE_SIGN, name, sign_params.build(),
137 &output_params, &handle);
138 if (result != KM_ERROR_OK) {
139 printf("Sign: BeginOperation failed: %d\n", result);
140 return result;
141 }
142 AuthorizationSet empty_params;
143 size_t num_input_bytes_consumed;
144 std::string output_data;
145 result = keystore->updateOperation(handle, empty_params, "data_to_sign",
146 &num_input_bytes_consumed, &output_params, &output_data);
147 if (result != KM_ERROR_OK) {
148 printf("Sign: UpdateOperation failed: %d\n", result);
149 return result;
150 }
151 result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
152 &output_params, &output_data);
153 if (result != KM_ERROR_OK) {
154 printf("Sign: FinishOperation failed: %d\n", result);
155 return result;
156 }
157 printf("Sign: %zu bytes.\n", output_data.size());
158 // We have a signature, now verify it.
159 std::string signature_to_verify = output_data;
160 result = keystore->beginOperation(KM_PURPOSE_VERIFY, name, sign_params.build(), &output_params,
161 &handle);
162 if (result != KM_ERROR_OK) {
163 printf("Verify: BeginOperation failed: %d\n", result);
164 return result;
165 }
166 result = keystore->updateOperation(handle, empty_params, "data_to_sign",
167 &num_input_bytes_consumed, &output_params, &output_data);
168 if (result != KM_ERROR_OK) {
169 printf("Verify: UpdateOperation failed: %d\n", result);
170 return result;
171 }
172 result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
173 &output_data);
174 if (result == KM_ERROR_VERIFICATION_FAILED) {
175 printf("Verify: Failed to verify signature.\n");
176 return result;
177 }
178 if (result != KM_ERROR_OK) {
179 printf("Verify: FinishOperation failed: %d\n", result);
180 return result;
181 }
182 printf("Verify: OK\n");
183 return 0;
184}
185
186} // namespace
187
188int main(int argc, char** argv) {
189 CommandLine::Init(argc, argv);
190 CommandLine* command_line = CommandLine::ForCurrentProcess();
191 CommandLine::StringVector args = command_line->GetArgs();
192 if (args.empty()) {
193 PrintUsageAndExit();
194 }
195 if (args[0] == "add-entropy") {
196 return AddEntropy(command_line->GetSwitchValueASCII("input"));
197 } else if (args[0] == "generate") {
198 return GenerateKey(command_line->GetSwitchValueASCII("name"));
199 } else if (args[0] == "get-chars") {
200 return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
201 } else if (args[0] == "export") {
202 return ExportKey(command_line->GetSwitchValueASCII("name"));
203 } else if (args[0] == "delete") {
204 return DeleteKey(command_line->GetSwitchValueASCII("name"));
205 } else if (args[0] == "delete-all") {
206 return DeleteAllKeys();
207 } else if (args[0] == "exists") {
208 return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
209 } else if (args[0] == "list") {
210 return List(command_line->GetSwitchValueASCII("prefix"));
211 } else if (args[0] == "sign-verify") {
212 return SignAndVerify(command_line->GetSwitchValueASCII("name"));
213 } else {
214 PrintUsageAndExit();
215 }
216 return 0;
217}