/************************************************************************* * * F i p s M o d e * If arg=="true", enable FIPS mode on the internal module. If arg=="false", * disable FIPS mode on the internal module. */ Error FipsMode(char *arg) { char *internal_name; if (!PORT_Strcasecmp(arg, "true")) { if (!PK11_IsFIPS()) { internal_name = PR_smprintf("%s", SECMOD_GetInternalModule()->commonName); if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError())); PR_smprintf_free(internal_name); PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); return FIPS_SWITCH_FAILED_ERR; } PR_smprintf_free(internal_name); if (!PK11_IsFIPS()) { PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); return FIPS_SWITCH_FAILED_ERR; } PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]); } else { PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_ON_ERR]); return FIPS_ALREADY_ON_ERR; } } else if (!PORT_Strcasecmp(arg, "false")) { if (PK11_IsFIPS()) { internal_name = PR_smprintf("%s", SECMOD_GetInternalModule()->commonName); if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError())); PR_smprintf_free(internal_name); PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); return FIPS_SWITCH_FAILED_ERR; } PR_smprintf_free(internal_name); if (PK11_IsFIPS()) { PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); return FIPS_SWITCH_FAILED_ERR; } PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]); } else { PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_OFF_ERR]); return FIPS_ALREADY_OFF_ERR; } } else { PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]); return INVALID_FIPS_ARG; } return SUCCESS; }
/* Determine if we have the FIP's module loaded as the default * module to trigger other bogus FIPS requirements in PKCS #12 and * SSL */ PRBool PK11_IsFIPS(void) { SECMODModule *mod = SECMOD_GetInternalModule(); if (mod && mod->internal) { return mod->isFIPS; } return PR_FALSE; }
/* void toggleFIPSMode (); */ NS_IMETHODIMP nsPKCS11ModuleDB::ToggleFIPSMode() { nsNSSShutDownPreventionLock locker; // The way to toggle FIPS mode in NSS is extremely obscure. // Basically, we delete the internal module, and voila it // gets replaced with the opposite module, ie if it was // FIPS before, then it becomes non-FIPS next. SECMODModule *internal; // This function returns us a pointer to a local copy of // the internal module stashed in NSS. We don't want to // delete it since it will cause much pain in NSS. internal = SECMOD_GetInternalModule(); if (!internal) return NS_ERROR_FAILURE; SECStatus srv = SECMOD_DeleteInternalModule(internal->commonName); if (srv != SECSuccess) return NS_ERROR_FAILURE; return NS_OK; }
VCardEmulError vcard_emul_init(const VCardEmulOptions *options) { SECStatus rv; PRBool ret, has_readers = PR_FALSE; VReader *vreader; VReaderEmul *vreader_emul; SECMODListLock *module_lock; SECMODModuleList *module_list; SECMODModuleList *mlp; int i; if (vcard_emul_init_called) { return VCARD_EMUL_INIT_ALREADY_INITED; } vcard_emul_init_called = 1; vreader_init(); vevent_queue_init(); if (options == NULL) { options = &default_options; } /* first initialize NSS */ if (options->nss_db) { rv = NSS_Init(options->nss_db); } else { gchar *path; #ifndef _WIN32 path = g_strdup("/etc/pki/nssdb"); #else if (g_get_system_config_dirs() == NULL || g_get_system_config_dirs()[0] == NULL) { return VCARD_EMUL_FAIL; } path = g_build_filename( g_get_system_config_dirs()[0], "pki", "nssdb", NULL); #endif rv = NSS_Init(path); g_free(path); } if (rv != SECSuccess) { return VCARD_EMUL_FAIL; } /* Set password callback function */ PK11_SetPasswordFunc(vcard_emul_get_password); /* set up soft cards emulated by software certs rather than physical cards * */ for (i = 0; i < options->vreader_count; i++) { int j; int cert_count; unsigned char **certs; int *cert_len; VCardKey **keys; PK11SlotInfo *slot; slot = PK11_FindSlotByName(options->vreader[i].name); if (slot == NULL) { continue; } vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type, options->vreader[i].type_params); vreader = vreader_new(options->vreader[i].vname, vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); cert_count = options->vreader[i].cert_count; ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, options->vreader[i].cert_count); if (ret == PR_FALSE) { continue; } cert_count = 0; for (j = 0; j < options->vreader[i].cert_count; j++) { /* we should have a better way of identifying certs than by * nickname here */ CERTCertificate *cert = PK11_FindCertFromNickname( options->vreader[i].cert_name[j], NULL); if (cert == NULL) { continue; } certs[cert_count] = cert->derCert.data; cert_len[cert_count] = cert->derCert.len; keys[cert_count] = vcard_emul_make_key(slot, cert); /* this is safe because the key is still holding a cert reference */ CERT_DestroyCertificate(cert); cert_count++; } if (cert_count) { VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); /* allow insertion and removal of soft cards */ vreader_emul->saved_vcard = vcard_reference(vcard); vcard_free(vcard); vreader_free(vreader); has_readers = PR_TRUE; } g_free(certs); g_free(cert_len); g_free(keys); } /* if we aren't suppose to use hw, skip looking up hardware tokens */ if (!options->use_hw) { nss_emul_init = has_readers; return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL; } /* make sure we have some PKCS #11 module loaded */ module_lock = SECMOD_GetDefaultModuleListLock(); module_list = SECMOD_GetDefaultModuleList(); SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; if (module_has_removable_hw_slots(module)) { break; } } SECMOD_ReleaseReadLock(module_lock); /* now examine all the slots, finding which should be readers */ /* We should control this with options. For now we mirror out any * removable hardware slot */ default_card_type = options->hw_card_type; default_type_params = g_strdup(options->hw_type_params); SECMOD_GetReadLock(module_lock); for (mlp = module_list; mlp; mlp = mlp->next) { SECMODModule *module = mlp->module; /* Ignore the internal module */ if (module == NULL || module == SECMOD_GetInternalModule()) { continue; } for (i = 0; i < module->slotCount; i++) { PK11SlotInfo *slot = module->slots[i]; /* only map removable HW slots */ if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) { continue; } if (strcmp("E-Gate 0 0", PK11_GetSlotName(slot)) == 0) { /* * coolkey <= 1.1.0-20 emulates this reader if it can't find * any hardware readers. This causes problems, warn user of * problems. */ fprintf(stderr, "known bad coolkey version - see " "https://bugzilla.redhat.com/show_bug.cgi?id=802435\n"); continue; } vreader_emul = vreader_emul_new(slot, options->hw_card_type, options->hw_type_params); vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul, vreader_emul_delete); vreader_add_reader(vreader); if (PK11_IsPresent(slot)) { VCard *vcard; vcard = vcard_emul_mirror_card(vreader); vreader_insert_card(vreader, vcard); vcard_emul_init_series(vreader, vcard); vcard_free(vcard); } } vcard_emul_new_event_thread(module); } SECMOD_ReleaseReadLock(module_lock); nss_emul_init = PR_TRUE; return VCARD_EMUL_OK; }
int main(int argc, char ** argv) { SECStatus rv; PRFileDesc *in; PRFileDesc *out; PRPollDesc pd; PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT; char buf[1024]; PRInt32 nBytes; char * command; char * tokenName; char * tokenpw; int fipsmode = 0; int semid = 0; union semun semarg; if (argc < 4 || argc > 5) { fprintf(stderr, "Usage: nss_pcache <semid> <fips on/off> <directory> [prefix]\n"); exit(1); } signal(SIGHUP, SIG_IGN); semid = strtol(argv[1], NULL, 10); if (!strcasecmp(argv[2], "on")) fipsmode = 1; /* Initialize NSPR */ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256); /* Set the PKCS #11 strings for the internal token. */ PK11_ConfigurePKCS11(NULL,NULL,NULL, INTERNAL_TOKEN_NAME, NULL, NULL,NULL,NULL,8,1); /* Initialize NSS and open the certificate database read-only. */ rv = NSS_Initialize(argv[3], argc == 5 ? argv[4] : NULL, argc == 5 ? argv[4] : NULL, "secmod.db", NSS_INIT_READONLY); if (rv != SECSuccess) { fprintf(stderr, "Unable to initialize NSS database: %d\n", rv); exit(1); } if (fipsmode) { if (!PK11_IsFIPS()) { char * internal_name = PR_smprintf("%s", SECMOD_GetInternalModule()->commonName); if ((SECMOD_DeleteInternalModule(internal_name) != SECSuccess) || !PK11_IsFIPS()) { NSS_Shutdown(); fprintf(stderr, "Unable to enable FIPS mode"); exit(1); } PR_smprintf_free(internal_name); } } in = PR_GetSpecialFD(PR_StandardInput); out = PR_GetSpecialFD(PR_StandardOutput); if (in == NULL || out == NULL) { fprintf(stderr, "PR_GetInheritedFD failed\n"); exit(1); } pd.fd = in; pd.in_flags = PR_POLL_READ | PR_POLL_EXCEPT; while (1) { rv = PR_Poll(&pd, 1, timeout); if (rv == -1) { /* PR_Poll failed */ break; } if (pd.out_flags & (PR_POLL_HUP | PR_POLL_ERR | PR_POLL_NVAL | PR_POLL_EXCEPT)) { break; } if (pd.out_flags & PR_POLL_READ) { memset(buf, 0, sizeof(buf)); nBytes = PR_Read(in, buf, sizeof(buf)); if (nBytes == -1 || nBytes == 0) { break; } command = getstr(buf, 0); tokenName = getstr(buf, 1); tokenpw = getstr(buf, 2); if (command && !strcmp(command, "QUIT")) { break; } else if (command && !strcmp(command, "STOR")) { PRInt32 err = PIN_SUCCESS; Node *node = NULL; if (tokenName && tokenpw) { node = (Node*)malloc(sizeof (Node)); if (!node) { err = PIN_NOMEMORY; } node->tokenName = strdup(tokenName); node->store = 0; node->next = 0; if (err == PIN_SUCCESS) err = CreatePk11PinStore(&node->store, tokenName, tokenpw); memset(tokenpw, 0, strlen(tokenpw)); } else err = PIN_SYSTEMERROR; sprintf(buf, "%d", err); PR_Write(out, buf, 1); if (err == PIN_SUCCESS) { if (pinList) node->next = pinList; pinList = node; } /* Now clean things up */ if (command) free(command); if (tokenName) free(tokenName); if (tokenpw) free(tokenpw); } else if (command && !strcmp(command, "RETR")) { Node *node; char *pin = 0; PRBool found = PR_FALSE; for (node = pinList; node != NULL; node = node->next) { if (!strcmp(node->tokenName, tokenName)) { if (Pk11StoreGetPin(&pin, node->store) == SECSuccess) { if (strlen(pin) == 0) PR_Write(out, "", 1); else PR_Write(out, pin, strlen(pin)); memset(pin, 0, strlen(pin)); free(pin); found = PR_TRUE; break; } } } if (found != PR_TRUE) PR_Write(out, "", 1); free(command); free(tokenName); } else { ; /* ack, unknown command */ } } } freeList(pinList); PR_Close(in); /* Remove the semaphore used for locking here. This is because this * program only goes away when Apache shuts down so we don't have to * worry about reloads. */ semctl(semid, 0, IPC_RMID, semarg); return 0; }