Changeset 90316 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Jul 23, 2021 3:49:47 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/tools/RTEfiSigDb.cpp
r90297 r90316 41 41 #include <iprt/stream.h> 42 42 #include <iprt/string.h> 43 #include <iprt/uuid.h> 43 44 #include <iprt/vfs.h> 44 45 … … 52 53 * Global Variables * 53 54 *********************************************************************************************************************************/ 55 /** Signature type identifier to internal type mapping. */ 56 struct 57 { 58 const char *pszId; 59 RTEFISIGTYPE enmType; 60 } g_aId2SigType[] = 61 { 62 { "sha256", RTEFISIGTYPE_SHA256 }, 63 { "rsa2048", RTEFISIGTYPE_RSA2048 }, 64 { "x509", RTEFISIGTYPE_X509 } 65 }; 54 66 55 67 … … 83 95 , RTPathFilename(pszArg0)); 84 96 97 if (!pszCommand || !strcmp(pszCommand, "add")) 98 RTPrintf("Usage: %s add <signature database path> <x509|sha256|rsa2048> <owner uuid> <signature path> ...\n" 99 , RTPathFilename(pszArg0)); 100 85 101 return RTEXITCODE_SUCCESS; 102 } 103 104 105 static RTEFISIGTYPE rtEfiSigDbGetTypeById(const char *pszId) 106 { 107 for (uint32_t i = 0; i < RT_ELEMENTS(g_aId2SigType); i++) 108 if (!strcmp(pszId, g_aId2SigType[i].pszId)) 109 return g_aId2SigType[i].enmType; 110 111 return RTEFISIGTYPE_INVALID; 112 } 113 114 115 /** 116 * Opens the specified signature database, returning an VFS file handle on success. 117 * 118 * @returns IPRT status code. 119 * @param pszPath Path to the signature database. 120 * @param phVfsFile Where to return the VFS file handle on success. 121 */ 122 static int rtEfiSigDbOpen(const char *pszPath, PRTVFSFILE phVfsFile) 123 { 124 int rc; 125 126 if (RTVfsChainIsSpec(pszPath)) 127 { 128 RTVFSOBJ hVfsObj; 129 rc = RTVfsChainOpenObj(pszPath, RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 130 RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_ON_LINK, 131 &hVfsObj, NULL, NULL); 132 if ( RT_SUCCESS(rc) 133 && RTVfsObjGetType(hVfsObj) == RTVFSOBJTYPE_FILE) 134 { 135 *phVfsFile = RTVfsObjToFile(hVfsObj); 136 RTVfsObjRelease(hVfsObj); 137 } 138 else 139 { 140 RTPrintf("'%s' doesn't point to a file\n", pszPath); 141 rc = VERR_INVALID_PARAMETER; 142 } 143 } 144 else 145 rc = RTVfsFileOpenNormal(pszPath, RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 146 phVfsFile); 147 148 return rc; 86 149 } 87 150 … … 117 180 RT_NOREF(pszArg0); 118 181 119 /* 120 * Parse arguments. 121 */ 122 static const RTGETOPTDEF s_aOptions[] = 123 { 124 { "--input", 'i', RTGETOPT_REQ_STRING } 125 }; 126 127 int rc = VINF_SUCCESS; 128 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 129 const char *pszInput = NULL; 130 131 RTGETOPTUNION ValueUnion; 132 RTGETOPTSTATE GetState; 133 RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 134 while ((rc = RTGetOpt(&GetState, &ValueUnion))) 135 { 136 switch (rc) 137 { 138 case 'i': 139 pszInput = ValueUnion.psz; 140 break; 141 default: 142 return RTGetOptPrintError(rc, &ValueUnion); 143 } 144 } 145 146 if (!pszInput) 182 if (!cArgs) 147 183 { 148 184 RTPrintf("An input path must be given\n"); … … 150 186 } 151 187 188 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 152 189 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 153 if (RTVfsChainIsSpec(pszInput)) 154 { 155 RTVFSOBJ hVfsObj; 156 rc = RTVfsChainOpenObj(pszInput, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 157 RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_ON_LINK, 158 &hVfsObj, NULL, NULL); 159 if ( RT_SUCCESS(rc) 160 && RTVfsObjGetType(hVfsObj) == RTVFSOBJTYPE_FILE) 161 { 162 hVfsFile = RTVfsObjToFile(hVfsObj); 163 RTVfsObjRelease(hVfsObj); 190 int rc = rtEfiSigDbOpen(papszArgs[0], &hVfsFile); 191 if (RT_SUCCESS(rc)) 192 { 193 RTEFISIGDB hEfiSigDb; 194 rc = RTEfiSigDbCreate(&hEfiSigDb); 195 if (RT_SUCCESS(rc)) 196 { 197 uint32_t idxSig = 0; 198 199 rc = RTEfiSigDbAddFromExistingDb(hEfiSigDb, hVfsFile); 200 if (RT_SUCCESS(rc)) 201 RTEfiSigDbEnum(hEfiSigDb, rtEfiSgDbEnum, &idxSig); 202 else 203 { 204 RTPrintf("Loading the signature database failed with %Rrc\n", rc); 205 rcExit = RTEXITCODE_FAILURE; 206 } 207 208 RTEfiSigDbDestroy(hEfiSigDb); 164 209 } 165 210 else 166 211 { 167 RTPrintf("'%s' doesn't point to a file\n", pszInput); 168 return RTEXITCODE_FAILURE; 169 } 212 RTPrintf("Creating the signature database failed with %Rrc\n", rc); 213 rcExit = RTEXITCODE_FAILURE; 214 } 215 216 RTVfsFileRelease(hVfsFile); 170 217 } 171 218 else 172 rc = RTVfsFileOpenNormal(pszInput, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 173 &hVfsFile); 174 175 RTEFISIGDB hEfiSigDb; 176 rc = RTEfiSigDbCreate(&hEfiSigDb); 219 rcExit = RTEXITCODE_FAILURE; 220 221 return rcExit; 222 } 223 224 225 /** 226 * Handles the 'add' command. 227 * 228 * @returns Program exit code. 229 * @param pszArg0 The program name. 230 * @param cArgs The number of arguments to the 'add' command. 231 * @param papszArgs The argument vector, starting after 'add'. 232 */ 233 static RTEXITCODE rtEfiSgDbCmdAdd(const char *pszArg0, int cArgs, char **papszArgs) 234 { 235 RT_NOREF(pszArg0); 236 237 if (!cArgs) 238 { 239 RTPrintf("The signature database path is missing\n"); 240 return RTEXITCODE_FAILURE; 241 } 242 243 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 244 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 245 int rc = rtEfiSigDbOpen(papszArgs[0], &hVfsFile); 177 246 if (RT_SUCCESS(rc)) 178 247 { 179 uint32_t idxSig = 0; 180 181 rc = RTEfiSigDbAddFromExistingDb(hEfiSigDb, hVfsFile); 248 RTEFISIGDB hEfiSigDb; 249 rc = RTEfiSigDbCreate(&hEfiSigDb); 182 250 if (RT_SUCCESS(rc)) 183 RTEfiSigDbEnum(hEfiSigDb, rtEfiSgDbEnum, &idxSig); 184 185 RTEfiSigDbDestroy(hEfiSigDb); 186 } 187 188 RTVfsFileRelease(hVfsFile); 251 { 252 uint64_t cbSigDb = 0; 253 rc = RTVfsFileQuerySize(hVfsFile, &cbSigDb); 254 if ( RT_SUCCESS(rc) 255 && cbSigDb) 256 rc = RTEfiSigDbAddFromExistingDb(hEfiSigDb, hVfsFile); 257 if (RT_SUCCESS(rc)) 258 { 259 cArgs--; 260 papszArgs++; 261 262 while (cArgs >= 3) 263 { 264 RTEFISIGTYPE enmSigType = rtEfiSigDbGetTypeById(papszArgs[0]); 265 const char *pszUuidOwner = papszArgs[1]; 266 const char *pszSigDataPath = papszArgs[2]; 267 268 if (enmSigType == RTEFISIGTYPE_INVALID) 269 { 270 RTPrintf("Signature type '%s' is not known\n", papszArgs[0]); 271 break; 272 } 273 274 RTUUID UuidOwner; 275 rc = RTUuidFromStr(&UuidOwner, pszUuidOwner); 276 if (RT_FAILURE(rc)) 277 { 278 RTPrintf("UUID '%s' is malformed\n", pszUuidOwner); 279 break; 280 } 281 282 RTVFSFILE hVfsFileSigData = NIL_RTVFSFILE; 283 rc = rtEfiSigDbOpen(pszSigDataPath, &hVfsFileSigData); 284 if (RT_FAILURE(rc)) 285 { 286 RTPrintf("Opening '%s' failed with %Rrc\n", pszSigDataPath); 287 break; 288 } 289 290 rc = RTEfiSigDbAddSignatureFromFile(hEfiSigDb, enmSigType, &UuidOwner, hVfsFileSigData); 291 RTVfsFileRelease(hVfsFileSigData); 292 if (RT_FAILURE(rc)) 293 { 294 RTPrintf("Adding signature data from '%s' failed with %Rrc\n", pszSigDataPath, rc); 295 break; 296 } 297 papszArgs += 3; 298 cArgs -= 3; 299 } 300 301 if (RT_SUCCESS(rc)) 302 { 303 if (!cArgs) 304 { 305 rc = RTVfsFileSeek(hVfsFile, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 306 AssertRC(rc); 307 308 rc = RTEfiSigDbWriteToFile(hEfiSigDb, hVfsFile); 309 if (RT_FAILURE(rc)) 310 { 311 RTPrintf("Writing the updated signature database failed with %Rrc\n", rc); 312 rcExit = RTEXITCODE_FAILURE; 313 } 314 } 315 else 316 { 317 RTPrintf("Incomplete list of entries to add given\n"); 318 rcExit = RTEXITCODE_FAILURE; 319 } 320 } 321 } 322 else 323 { 324 RTPrintf("Loading the signature database failed with %Rrc\n", rc); 325 rcExit = RTEXITCODE_FAILURE; 326 } 327 328 RTEfiSigDbDestroy(hEfiSigDb); 329 } 330 else 331 { 332 RTPrintf("Creating the signature database failed with %Rrc\n", rc); 333 rcExit = RTEXITCODE_FAILURE; 334 } 335 336 RTVfsFileRelease(hVfsFile); 337 } 338 else 339 rcExit = RTEXITCODE_FAILURE; 340 189 341 return rcExit; 190 342 } … … 205 357 else if (!strcmp(argv[1], "list")) 206 358 rcExit = rtEfiSgDbCmdList(argv[0], argc - 2, argv + 2); 359 else if (!strcmp(argv[1], "add")) 360 rcExit = rtEfiSgDbCmdAdd(argv[0], argc - 2, argv + 2); 207 361 else if ( !strcmp(argv[1], "-h") 208 362 || !strcmp(argv[1], "-?")
Note:
See TracChangeset
for help on using the changeset viewer.