VirtualBox

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

Last change on this file since 92689 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette