Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
#ifdef _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#include "nspr.h"
#include "secutil.h"
#include "pk11func.h"
#include "nss.h"
#include "secport.h"
#include "secpkcs5.h"
#include "sechash.h"
#include "certdb.h"
#include "secmod.h"
static char *progName;
PRBool debug = PR_FALSE;
#define ERR_USAGE 2
#define ERR_PK11GETSLOT 13
static void
Usage()
{
#define FPS PR_fprintf(PR_STDERR,
FPS "Usage: %s [-d certdir] [-P dbprefix] [-h tokenname]\n",
progName);
FPS "\t\t [-k slotpwfile | -K slotpw] [-v]\n");
exit(ERR_USAGE);
}
typedef enum {
tagULong,
tagVersion,
tagUtf8
} tagType;
typedef struct {
const char *attributeName;
tagType attributeStorageType;
} attributeTag;
enum {
opt_CertDir = 0,
opt_TokenName,
opt_SlotPWFile,
opt_SlotPW,
opt_DBPrefix,
opt_Debug
};
static secuCommandFlag validation_options[] = {
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
{ /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
{ /* opt_SlotPWFile */ 'k', PR_TRUE, 0, PR_FALSE },
{ /* opt_SlotPW */ 'K', PR_TRUE, 0, PR_FALSE },
{ /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE },
{ /* opt_Debug */ 'v', PR_FALSE, 0, PR_FALSE }
};
void
dump_Raw(char *label, CK_ATTRIBUTE *attr)
{
int i;
unsigned char *value = (unsigned char *)attr->pValue;
printf("0x");
for (i = 0; i < attr->ulValueLen; i++) {
printf("%02x", value[i]);
}
printf("<%s>\n", label);
}
SECStatus
dump_validations(CK_OBJECT_CLASS objc, CK_ATTRIBUTE *template, int count,
attributeTag *tags, PK11SlotInfo *slot)
{
PK11GenericObject *objs, *obj;
objs = PK11_FindGenericObjects(slot, objc);
for (obj = objs; obj != NULL; obj = PK11_GetNextGenericObject(obj)) {
int i;
printf("Validation Object:\n");
PK11_ReadRawAttributes(NULL, PK11_TypeGeneric, obj, template, count);
for (i = 0; i < count; i++) {
CK_ULONG ulong;
CK_VERSION version;
int len = template[i].ulValueLen;
printf(" %s: ", tags[i].attributeName);
if (len < 0) {
printf("<failed>\n");
} else if (len == 0) {
printf("<empty>\n");
} else
switch (tags[i].attributeStorageType) {
case tagULong:
if (len != sizeof(CK_ULONG)) {
dump_Raw("bad ulong", &template[i]);
break;
}
ulong = *(CK_ULONG *)template[i].pValue;
printf("%ld\n", ulong);
break;
case tagVersion:
if (len != sizeof(CK_VERSION)) {
dump_Raw("bad version", &template[i]);
break;
}
version = *(CK_VERSION *)template[i].pValue;
printf("%d.%d\n", version.major, version.minor);
break;
case tagUtf8:
printf("%.*s\n", len, (char *)template[i].pValue);
break;
default:
dump_Raw("unknown tag", &template[i]);
break;
}
PORT_Free(template[i].pValue);
template[i].pValue = NULL;
template[i].ulValueLen = 0;
}
}
PK11_DestroyGenericObjects(objs);
return SECSuccess;
}
int
main(int argc, char **argv)
{
secuPWData slotPw = { PW_NONE, NULL };
secuPWData p12FilePw = { PW_NONE, NULL };
PK11SlotInfo *slot = NULL;
char *slotname = NULL;
char *dbprefix = "";
char *nssdir = NULL;
SECStatus rv;
secuCommand validation;
int local_errno = 0;
CK_ATTRIBUTE validation_template[] = {
{ CKA_NSS_VALIDATION_TYPE, NULL, 0 },
{ CKA_NSS_VALIDATION_VERSION, NULL, 0 },
{ CKA_NSS_VALIDATION_LEVEL, NULL, 0 },
{ CKA_NSS_VALIDATION_MODULE_ID, NULL, 0 }
};
attributeTag validation_tags[] = {
{ "Validation Type", tagULong },
{ "Validation Version", tagVersion },
{ "Validation Level", tagULong },
{ "Validation Module ID", tagUtf8 },
};
#ifdef _CRTDBG_MAP_ALLOC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
validation.numCommands = 0;
validation.commands = 0;
validation.numOptions = PR_ARRAY_SIZE(validation_options);
validation.options = validation_options;
progName = strrchr(argv[0], '/');
progName = progName ? progName + 1 : argv[0];
rv = SECU_ParseCommandLine(argc, argv, progName, &validation);
if (rv != SECSuccess)
Usage();
debug = validation.options[opt_Debug].activated;
slotname = SECU_GetOptionArg(&validation, opt_TokenName);
if (validation.options[opt_SlotPWFile].activated) {
slotPw.source = PW_FROMFILE;
slotPw.data = PORT_Strdup(validation.options[opt_SlotPWFile].arg);
}
if (validation.options[opt_SlotPW].activated) {
slotPw.source = PW_PLAINTEXT;
slotPw.data = PORT_Strdup(validation.options[opt_SlotPW].arg);
}
if (validation.options[opt_CertDir].activated) {
nssdir = validation.options[opt_CertDir].arg;
}
if (validation.options[opt_DBPrefix].activated) {
dbprefix = validation.options[opt_DBPrefix].arg;
}
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
if (nssdir == NULL && NSS_NoDB_Init("") == SECSuccess) {
rv = SECSuccess;
/* if the system isn't already in FIPS mode, we need
* to switch to FIPS mode */
if (!PK11_IsFIPS()) {
/* flip to FIPS mode */
SECMODModule *module = SECMOD_GetInternalModule();
rv = SECMOD_DeleteInternalModule(module->commonName);
}
} else if (nssdir != NULL) {
rv = NSS_Initialize(nssdir, dbprefix, dbprefix, "secmod.db", 0);
}
if (rv != SECSuccess) {
SECU_PrintPRandOSError(progName);
local_errno = -1;
goto done;
}
if (!slotname || PL_strcmp(slotname, "internal") == 0)
slot = PK11_GetInternalKeySlot();
else
slot = PK11_FindSlotByName(slotname);
if (!slot) {
SECU_PrintError(progName, "Invalid slot \"%s\"",
slotname ? "internal" : slotname);
local_errno = ERR_PK11GETSLOT;
goto done;
}
rv = dump_validations(CKO_NSS_VALIDATION,
validation_template,
PR_ARRAY_SIZE(validation_template),
validation_tags,
slot);
done:
if (slotPw.data != NULL)
PORT_ZFree(slotPw.data, PL_strlen(slotPw.data));
if (p12FilePw.data != NULL)
PORT_ZFree(p12FilePw.data, PL_strlen(p12FilePw.data));
if (slotname) {
PORT_Free(slotname);
}
if (slot)
PK11_FreeSlot(slot);
if (NSS_Shutdown() != SECSuccess) {
local_errno = 1;
}
PL_ArenaFinish();
PR_Cleanup();
return local_errno;
}