Example #1
0
File: pk11.c Project: emaldona/nss
/*************************************************************************
 *
 * 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;
}
Example #2
0
/* 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;
}
Example #3
0
/* 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;
}
Example #4
0
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;
}
Example #5
0
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;
}