VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/vdkeystoremgr.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/* $Id: vdkeystoremgr.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Keystore utility for debugging.
4 */
5
6/*
7 * Copyright (C) 2016-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <VBox/vd.h>
33#include <iprt/errcore.h>
34#include <VBox/version.h>
35#include <iprt/initterm.h>
36#include <iprt/base64.h>
37#include <iprt/buildconfig.h>
38#include <iprt/path.h>
39#include <iprt/string.h>
40#include <iprt/uuid.h>
41#include <iprt/stream.h>
42#include <iprt/message.h>
43#include <iprt/getopt.h>
44#include <iprt/assert.h>
45
46#include "../VDKeyStore.h"
47
48/** command handler argument */
49struct HandlerArg
50{
51 int argc;
52 char **argv;
53};
54
55static const char *g_pszProgName = "";
56static void printUsage(PRTSTREAM pStrm)
57{
58 RTStrmPrintf(pStrm,
59 "Usage: %s\n"
60 " create --password <password>\n"
61 " --cipher <cipher>\n"
62 " --dek <dek in base64>\n"
63 "\n"
64 " dump --keystore <keystore data in base64>\n"
65 " [--password <password to decrypt the DEK inside]\n",
66 g_pszProgName);
67}
68
69static void showLogo(PRTSTREAM pStrm)
70{
71 static bool s_fShown; /* show only once */
72
73 if (!s_fShown)
74 {
75 RTStrmPrintf(pStrm, VBOX_PRODUCT " VD Keystore Mgr " VBOX_VERSION_STRING "\n"
76 "Copyright (C) 2016-" VBOX_C_YEAR " " VBOX_VENDOR "\n\n");
77 s_fShown = true;
78 }
79}
80
81/**
82 * Print a usage synopsis and the syntax error message.
83 */
84static int errorSyntax(const char *pszFormat, ...)
85{
86 va_list args;
87 showLogo(g_pStdErr); // show logo even if suppressed
88 va_start(args, pszFormat);
89 RTStrmPrintf(g_pStdErr, "\nSyntax error: %N\n", pszFormat, &args);
90 va_end(args);
91 printUsage(g_pStdErr);
92 return 1;
93}
94
95static int errorRuntime(const char *pszFormat, ...)
96{
97 va_list args;
98
99 va_start(args, pszFormat);
100 RTMsgErrorV(pszFormat, args);
101 va_end(args);
102 return 1;
103}
104
105static DECLCALLBACK(int) handleCreate(HandlerArg *pArgs)
106{
107 const char *pszPassword = NULL;
108 const char *pszCipher = NULL;
109 const char *pszDek = NULL;
110
111 /* Parse the command line. */
112 static const RTGETOPTDEF s_aOptions[] =
113 {
114 { "--password", 'p', RTGETOPT_REQ_STRING },
115 { "--cipher" , 'c', RTGETOPT_REQ_STRING },
116 { "--dek", 'd', RTGETOPT_REQ_STRING }
117 };
118
119 int ch;
120 RTGETOPTUNION ValueUnion;
121 RTGETOPTSTATE GetState;
122 RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0 /* fFlags */);
123 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
124 {
125 switch (ch)
126 {
127 case 'p': // --password
128 pszPassword = ValueUnion.psz;
129 break;
130 case 'c': // --cipher
131 pszCipher = ValueUnion.psz;
132 break;
133 case 'd': // --dek
134 pszDek = ValueUnion.psz;
135 break;
136 default:
137 ch = RTGetOptPrintError(ch, &ValueUnion);
138 printUsage(g_pStdErr);
139 return ch;
140 }
141 }
142
143 /* Check for mandatory parameters. */
144 if (!pszPassword)
145 return errorSyntax("Mandatory --password option missing\n");
146 if (!pszCipher)
147 return errorSyntax("Mandatory --cipher option missing\n");
148 if (!pszDek)
149 return errorSyntax("Mandatory --dek option missing\n");
150
151 /* Get the size of the decoded DEK. */
152 ssize_t cbDekDec = RTBase64DecodedSize(pszDek, NULL);
153 if (cbDekDec == -1)
154 return errorRuntime("The encoding of the base64 DEK is bad\n");
155
156 uint8_t *pbDek = (uint8_t *)RTMemAllocZ(cbDekDec);
157 size_t cbDek = cbDekDec;
158 if (!pbDek)
159 return errorRuntime("Failed to allocate memory for the DEK\n");
160
161 int rc = RTBase64Decode(pszDek, pbDek, cbDek, &cbDek, NULL);
162 if (RT_SUCCESS(rc))
163 {
164 char *pszKeyStoreEnc = NULL;
165 rc = vdKeyStoreCreate(pszPassword, pbDek, cbDek, pszCipher, &pszKeyStoreEnc);
166 if (RT_SUCCESS(rc))
167 {
168 RTPrintf("Successfully created keystore\n"
169 "Keystore (base64): \n"
170 "%s\n", pszKeyStoreEnc);
171 RTMemFree(pszKeyStoreEnc);
172 }
173 else
174 errorRuntime("Failed to create keystore with %Rrc\n", rc);
175 }
176 else
177 errorRuntime("Failed to decode the DEK with %Rrc\n", rc);
178
179 RTMemFree(pbDek);
180 return VERR_NOT_IMPLEMENTED;
181}
182
183static DECLCALLBACK(int) handleDump(HandlerArg *pArgs)
184{
185 return VERR_NOT_IMPLEMENTED;
186}
187
188int main(int argc, char *argv[])
189{
190 int exitcode = 0;
191
192 int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_STANDALONE_APP);
193 if (RT_FAILURE(rc))
194 return RTMsgInitFailure(rc);
195
196 g_pszProgName = RTPathFilename(argv[0]);
197
198 bool fShowLogo = false;
199 int iCmd = 1;
200 int iCmdArg;
201
202 /* global options */
203 for (int i = 1; i < argc || argc <= iCmd; i++)
204 {
205 if ( argc <= iCmd
206 || !strcmp(argv[i], "help")
207 || !strcmp(argv[i], "-?")
208 || !strcmp(argv[i], "-h")
209 || !strcmp(argv[i], "-help")
210 || !strcmp(argv[i], "--help"))
211 {
212 showLogo(g_pStdOut);
213 printUsage(g_pStdOut);
214 return 0;
215 }
216
217 if ( !strcmp(argv[i], "-v")
218 || !strcmp(argv[i], "-version")
219 || !strcmp(argv[i], "-Version")
220 || !strcmp(argv[i], "--version"))
221 {
222 /* Print version number, and do nothing else. */
223 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision());
224 return 0;
225 }
226
227 if ( !strcmp(argv[i], "--nologo")
228 || !strcmp(argv[i], "-nologo")
229 || !strcmp(argv[i], "-q"))
230 {
231 /* suppress the logo */
232 fShowLogo = false;
233 iCmd++;
234 }
235 else
236 {
237 break;
238 }
239 }
240
241 iCmdArg = iCmd + 1;
242
243 if (fShowLogo)
244 showLogo(g_pStdOut);
245
246 /*
247 * All registered command handlers
248 */
249 static const struct
250 {
251 const char *command;
252 DECLR3CALLBACKMEMBER(int, handler, (HandlerArg *a));
253 } s_commandHandlers[] =
254 {
255 { "create", handleCreate },
256 { "dump", handleDump },
257 { NULL, NULL }
258 };
259
260 HandlerArg handlerArg = { 0, NULL };
261 int commandIndex;
262 for (commandIndex = 0; s_commandHandlers[commandIndex].command != NULL; commandIndex++)
263 {
264 if (!strcmp(s_commandHandlers[commandIndex].command, argv[iCmd]))
265 {
266 handlerArg.argc = argc - iCmdArg;
267 handlerArg.argv = &argv[iCmdArg];
268
269 exitcode = s_commandHandlers[commandIndex].handler(&handlerArg);
270 break;
271 }
272 }
273 if (!s_commandHandlers[commandIndex].command)
274 {
275 errorSyntax("Invalid command '%s'", argv[iCmd]);
276 return 1;
277 }
278
279 return exitcode;
280}
281
282/* dummy stub for RuntimeR3 */
283#ifndef RT_OS_WINDOWS
284RTDECL(bool) RTAssertShouldPanic(void)
285{
286 return true;
287}
288#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use