Пример #1
0
NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
    NSSToken *rvToken;
    NSSArena *arena;

    /* Don't create a token object for a disabled slot */
    if (nss3slot->disabled) {
	PORT_SetError(SEC_ERROR_NO_TOKEN);
	return NULL;
    }
    arena = nssArena_Create();
    if (!arena) {
	return NULL;
    }
    rvToken = nss_ZNEW(arena, NSSToken);
    if (!rvToken) {
	nssArena_Destroy(arena);
	return NULL;
    }
    rvToken->base.refCount = 1;
    rvToken->base.lock = PZ_NewLock(nssILockOther);
    if (!rvToken->base.lock) {
	nssArena_Destroy(arena);
	return NULL;
    }
    rvToken->base.arena = arena;
    rvToken->pk11slot = nss3slot;
    rvToken->epv = nss3slot->functionList;
    rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
                                                       nss3slot->session,
                                                       nss3slot->sessionLock,
                                                       nss3slot->defRWSession);
    /* continue, even if rvToken->defaultSession is NULL */
    if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
	rvToken->cache = nssTokenObjectCache_Create(rvToken, 
	                                            PR_TRUE, PR_TRUE, PR_TRUE);
	if (!rvToken->cache)
	    goto loser;
    }
    rvToken->trustDomain = td;
    /* Grab the token name from the PKCS#11 fixed-length buffer */
    rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
    rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
    if (!rvToken->slot) {
        goto loser;
    }
    rvToken->slot->token = rvToken;
    if (rvToken->defaultSession)
	rvToken->defaultSession->slot = rvToken->slot;
    return rvToken;
loser:
    PZ_DestroyLock(rvToken->base.lock);
    nssArena_Destroy(arena);
    return NULL;
}
Пример #2
0
NS_IMETHODIMP nsPK11Token::IsHardwareToken(bool *_retval)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  nsresult rv = NS_OK;

  *_retval = PK11_IsHW(mSlot);

  return rv;
}
Пример #3
0
static PRBool
module_has_removable_hw_slots(SECMODModule *mod)
{
    int i;
    PRBool ret = PR_FALSE;
    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();

    if (!moduleLock) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return ret;
    }
    SECMOD_GetReadLock(moduleLock);
    for (i = 0; i < mod->slotCount; i++) {
        PK11SlotInfo *slot = mod->slots[i];
        if (PK11_IsRemovable(slot) && PK11_IsHW(slot)) {
            ret = PR_TRUE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(moduleLock);
    return ret;
}
Пример #4
0
/*
 * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption
 * based on the given bulk encryption key and algorithm identifier (which 
 * may include an iv).
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function below (for starting up encryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
NSSCMSCipherContext *
NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
{
    NSSCMSCipherContext *cc;
    void *ciphercx;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECOidTag algtag;
    SECItem *param = NULL;

    algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = PK11_GetSymKeyUserData(key);
	if (!pwitem) 
	    return NULL;

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}

    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_ParamFromAlgid(algid)) == NULL)
	    return NULL;
    }

    cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
    if (cc == NULL) {
	SECITEM_FreeItem(param,PR_TRUE);
	return NULL;
    }

    /* figure out pad and block sizes */
    cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* create PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, 
					  key, param);
    SECITEM_FreeItem(param, PR_TRUE);
    if (ciphercx == NULL) {
	PORT_Free (cc);
	return NULL;
    }

    cc->cx = ciphercx;
    cc->doit =  (nss_cms_cipher_function) PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext;
    cc->encrypt = PR_FALSE;
    cc->pending_count = 0;

    return cc;
}
Пример #5
0
/*
 * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption,
 * based on the given bulk encryption key and algorithm tag.  Fill in the 
 * algorithm identifier (which may include an iv) appropriately.
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function above (for starting up decryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
NSSCMSCipherContext *
NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid)
{
    NSSCMSCipherContext *cc;
    void *ciphercx;
    SECStatus rv;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECItem *param = NULL;
    PRBool needToEncodeAlgid = PR_FALSE;
    SECOidTag algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = PK11_GetSymKeyUserData(key);
	if (!pwitem) 
	    return NULL;

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}
    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL)
	    return NULL;
	needToEncodeAlgid = PR_TRUE;
    }

    cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
    if (cc == NULL) {
	goto loser;
    }

    /* now find pad and block sizes for our mechanism */
    cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* and here we go, creating a PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, 
					  key, param);
    if (ciphercx == NULL) {
	PORT_Free(cc);
	cc = NULL;
	goto loser;
    }

    /*
     * These are placed after the CreateContextBySymKey() because some
     * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
     * Don't move it from here.
     * XXX is that right? the purpose of this is to get the correct algid
     *     containing the IVs etc. for encoding. this means we need to set this up
     *     BEFORE encoding the algid in the contentInfo, right?
     */
    if (needToEncodeAlgid) {
	rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
	if(rv != SECSuccess) {
	    PORT_Free(cc);
	    cc = NULL;
	    goto loser;
	}
    }

    cc->cx = ciphercx;
    cc->doit = (nss_cms_cipher_function)PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext;
    cc->encrypt = PR_TRUE;
    cc->pending_count = 0;

loser:
    SECITEM_FreeItem(param, PR_TRUE);

    return cc;
}
Пример #6
0
/*
 * Create a cipher object to do decryption,  based on the given bulk
 * encryption key and algorithm identifier (which may include an iv).
 *
 * XXX This interface, or one similar, would be really nice available
 * in general...  I tried to keep the pkcs7-specific stuff (mostly
 * having to do with padding) out of here.
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function below (for starting up encryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
sec_PKCS7CipherObject *
sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
{
    sec_PKCS7CipherObject *result;
    SECOidTag algtag;
    void *ciphercx;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECItem *param = NULL;

    result = (struct sec_pkcs7_cipher_object*)
      PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
    if (result == NULL)
	return NULL;

    ciphercx = NULL;
    algtag = SECOID_GetAlgorithmTag (algid);

    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
	if (!pwitem) {
	    PORT_Free(result);
	    return NULL;
	}

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    PORT_Free(result);
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}
    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	param = PK11_ParamFromAlgid(algid);
	if (param == NULL) {
	    PORT_Free(result);
	    return NULL;
	}
    }

    result->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    slot = PK11_GetSlotFromKey(key);
    result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
    PK11_FreeSlot(slot);
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, 
					  key, param);
    SECITEM_FreeItem(param,PR_TRUE);
    if (ciphercx == NULL) {
	PORT_Free (result);
	return NULL;
    }

    result->cx = ciphercx;
    result->doit =  (sec_pkcs7_cipher_function) PK11_CipherOp;
    result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext;
    result->encrypt = PR_FALSE;
    result->pending_count = 0;

    return result;
}
Пример #7
0
/*
 * Create a cipher object to do encryption, based on the given bulk
 * encryption key and algorithm tag.  Fill in the algorithm identifier
 * (which may include an iv) appropriately.
 *
 * XXX This interface, or one similar, would be really nice available
 * in general...  I tried to keep the pkcs7-specific stuff (mostly
 * having to do with padding) out of here.
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function above (for starting up decryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
sec_PKCS7CipherObject *
sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key,
			      SECOidTag algtag, SECAlgorithmID *algid)
{
    sec_PKCS7CipherObject *result;
    void *ciphercx;
    SECStatus rv;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECItem *param = NULL;
    PRBool needToEncodeAlgid = PR_FALSE;

    result = (struct sec_pkcs7_cipher_object*)
	      PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
    if (result == NULL)
	return NULL;

    ciphercx = NULL;
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
	if (!pwitem) {
	    PORT_Free(result);
	    return NULL;
	}

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    PORT_Free(result);
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}
    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	param = PK11_GenerateNewParam(cryptoMechType, key);
	if (param == NULL) {
	    PORT_Free(result);
	    return NULL;
	}
	needToEncodeAlgid = PR_TRUE;
    }

    result->pad_size = PK11_GetBlockSize(cryptoMechType,param);
    slot = PK11_GetSlotFromKey(key);
    result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
    PK11_FreeSlot(slot);
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, 
    					  key, param);
    if (ciphercx == NULL) {
	PORT_Free (result);
        SECITEM_FreeItem(param,PR_TRUE);
	return NULL;
    }

    /*
     * These are placed after the CreateContextBySymKey() because some
     * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
     * Don't move it from here.
     */
    if (needToEncodeAlgid) {
	rv = PK11_ParamToAlgid(algtag,param,poolp,algid);
	if(rv != SECSuccess) {
	    PORT_Free (result);
            SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}
    }
    SECITEM_FreeItem(param,PR_TRUE);

    result->cx = ciphercx;
    result->doit = (sec_pkcs7_cipher_function) PK11_CipherOp;
    result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext;
    result->encrypt = PR_TRUE;
    result->pending_count = 0;

    return result;
}
Пример #8
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;
}
Пример #9
0
VCardEmulError
vcard_emul_init(const VCardEmulOptions *options)
{
    SECStatus rv;
    PRBool ret, has_readers = PR_FALSE, need_coolkey_module;
    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 {
        rv = NSS_Init("sql:/etc/pki/nssdb");
    }
    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();
    need_coolkey_module = !has_readers;
    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        if (module_has_removable_hw_slots(module)) {
            need_coolkey_module = PR_FALSE;
            break;
        }
    }
    SECMOD_ReleaseReadLock(module_lock);

    if (need_coolkey_module) {
        SECMODModule *module;
        module = SECMOD_LoadUserModule(
                    (char *)"library=libcoolkeypk11.so name=Coolkey",
                    NULL, PR_FALSE);
        if (module == NULL) {
            return VCARD_EMUL_FAIL;
        }
        SECMOD_DestroyModule(module); /* free our reference, Module will still
                                       * be on the list.
                                       * until we destroy it */
    }

    /* 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 = strdup(options->hw_type_params);

    SECMOD_GetReadLock(module_lock);
    for (mlp = module_list; mlp; mlp = mlp->next) {
        SECMODModule *module = mlp->module;
        PRBool has_emul_slots = PR_FALSE;

        if (module == NULL) {
                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;
            }
            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);

            has_readers = PR_TRUE;
            has_emul_slots = PR_TRUE;

            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);
            }
        }
        if (has_emul_slots) {
            vcard_emul_new_event_thread(module);
        }
    }
    SECMOD_ReleaseReadLock(module_lock);
    nss_emul_init = has_readers;

    return VCARD_EMUL_OK;
}
Пример #10
0
/*
 * SecCmsCipherContextStartEncrypt - create a cipher object to do encryption,
 * based on the given bulk encryption key and algorithm tag.  Fill in the algorithm
 * identifier (which may include an iv) appropriately.
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function above (for starting up decryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
SecCmsCipherContext *
SecCmsCipherContextStartEncrypt(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid)
{
    return SecCmsCipherContextStart(poolp, key, algid, PR_TRUE);
#if 0
    SecCmsCipherContext *cc;
    void *ciphercx;
    CSSM_DATA *param;
    OSStatus rv;
    CK_MECHANISM_TYPE mechanism;
    PK11SlotInfo *slot;
    PRBool needToEncodeAlgid = PR_FALSE;
    SECOidTag algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	CK_MECHANISM pbeMech, cryptoMech;
	CSSM_DATA *pbeParams;
	SEC_PKCS5KeyAndPassword *keyPwd;

	PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM));
	PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM));

	/* HACK ALERT!
	 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
	 */
	keyPwd = (SEC_PKCS5KeyAndPassword *)key;
	key = keyPwd->key;

	/* find correct PK11 mechanism and parameters to initialize pbeMech */
	pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
	pbeParams = PK11_ParamFromAlgid(algid);
	if (!pbeParams)
	    return NULL;
	pbeMech.pParameter = pbeParams->Data;
	pbeMech.ulParameterLen = pbeParams->Length;

	/* now map pbeMech to cryptoMech */
	if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem,
						  PR_FALSE) != CKR_OK) { 
	    SECITEM_ZfreeItem(pbeParams, PR_TRUE);
	    return NULL;
	}
	SECITEM_ZfreeItem(pbeParams, PR_TRUE);

	/* and use it to initialize param & mechanism */
	if ((param = (CSSM_DATA *)PORT_ZAlloc(sizeof(CSSM_DATA))) == NULL)
	    return NULL;

	param->Data = (unsigned char *)cryptoMech.pParameter;
	param->Length = cryptoMech.ulParameterLen;
	mechanism = cryptoMech.mechanism;
    } else {
	mechanism = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL)
	    return NULL;
	needToEncodeAlgid = PR_TRUE;
    }

    cc = (SecCmsCipherContext *)PORT_ZAlloc(sizeof(SecCmsCipherContext));
    if (cc == NULL)
	return NULL;

    /* now find pad and block sizes for our mechanism */
    cc->pad_size = PK11_GetBlockSize(mechanism,param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* and here we go, creating a PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT, key, param);
    if (ciphercx == NULL) {
	PORT_Free(cc);
	cc = NULL;
	goto loser;
    }

    /*
     * These are placed after the CreateContextBySymKey() because some
     * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
     * Don't move it from here.
     * XXX is that right? the purpose of this is to get the correct algid
     *     containing the IVs etc. for encoding. this means we need to set this up
     *     BEFORE encoding the algid in the contentInfo, right?
     */
    if (needToEncodeAlgid) {
	rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
	if(rv != SECSuccess) {
	    PORT_Free(cc);
	    cc = NULL;
	    goto loser;
	}
    }

    cc->cx = ciphercx;
    cc->doit = (nss_cms_cipher_function)PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext;
    cc->encrypt = PR_TRUE;
    cc->pending_count = 0;

loser:
    SECITEM_FreeItem(param, PR_TRUE);

    return cc;
#endif
}
Пример #11
0
/*
 * SecCmsCipherContextStartDecrypt - create a cipher context to do decryption
 * based on the given bulk * encryption key and algorithm identifier (which may include an iv).
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function below (for starting up encryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
SecCmsCipherContext *
SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key, SECAlgorithmID *algid)
{
    return SecCmsCipherContextStart(NULL, key, algid, PR_FALSE);
#if 0
    SecCmsCipherContext *cc;
    void *ciphercx;
    CK_MECHANISM_TYPE mechanism;
    CSSM_DATA *param;
    PK11SlotInfo *slot;
    SECOidTag algtag;

    algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	CK_MECHANISM pbeMech, cryptoMech;
	CSSM_DATA *pbeParams;
	SEC_PKCS5KeyAndPassword *keyPwd;

	PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM));
	PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM));

	/* HACK ALERT!
	 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword *
	 */
	keyPwd = (SEC_PKCS5KeyAndPassword *)key;
	key = keyPwd->key;

	/* find correct PK11 mechanism and parameters to initialize pbeMech */
	pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
	pbeParams = PK11_ParamFromAlgid(algid);
	if (!pbeParams)
	    return NULL;
	pbeMech.pParameter = pbeParams->Data;
	pbeMech.ulParameterLen = pbeParams->Length;

	/* now map pbeMech to cryptoMech */
	if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem,
						  PR_FALSE) != CKR_OK) { 
	    SECITEM_ZfreeItem(pbeParams, PR_TRUE);
	    return NULL;
	}
	SECITEM_ZfreeItem(pbeParams, PR_TRUE);

	/* and use it to initialize param & mechanism */
	if ((param = (CSSM_DATA *)PORT_ZAlloc(sizeof(CSSM_DATA))) == NULL)
	     return NULL;

	param->Data = (unsigned char *)cryptoMech.pParameter;
	param->Length = cryptoMech.ulParameterLen;
	mechanism = cryptoMech.mechanism;
    } else {
	mechanism = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_ParamFromAlgid(algid)) == NULL)
	    return NULL;
    }

    cc = (SecCmsCipherContext *)PORT_ZAlloc(sizeof(SecCmsCipherContext));
    if (cc == NULL) {
	SECITEM_FreeItem(param,PR_TRUE);
	return NULL;
    }

    /* figure out pad and block sizes */
    cc->pad_size = PK11_GetBlockSize(mechanism, param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* create PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param);
    SECITEM_FreeItem(param, PR_TRUE);
    if (ciphercx == NULL) {
	PORT_Free (cc);
	return NULL;
    }

    cc->cx = ciphercx;
    cc->doit =  (nss_cms_cipher_function) PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext;
    cc->encrypt = PR_FALSE;
    cc->pending_count = 0;

    return cc;
#endif
}
Пример #12
0
/***********************************************************************
 *
 * L i s t M o d u l e
 *
 * Lists detailed information about the named module.
 */
Error
ListModule(char *moduleName)
{
    SECMODModule *module = NULL;
    PK11SlotInfo *slot;
    int slotnum;
    CK_INFO modinfo;
    CK_SLOT_INFO slotinfo;
    CK_TOKEN_INFO tokeninfo;
    char *ciphers, *mechanisms;
    size_t reasonIdx;
    Error rv = SUCCESS;

    if (!moduleName) {
        return SUCCESS;
    }

    module = SECMOD_FindModule(moduleName);
    if (!module) {
        PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
        rv = NO_SUCH_MODULE_ERR;
        goto loser;
    }

    if ((module->loaded) &&
        (PK11_GetModInfo(module, &modinfo) != SECSuccess)) {
        PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName);
        rv = MOD_INFO_ERR;
        goto loser;
    }

    /* Module info */
    PR_fprintf(PR_STDOUT,
               "\n-----------------------------------------------------------\n");
    PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName);
    if (module->internal || !module->dllName) {
        PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n");
    } else {
        PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName);
    }

    if (module->loaded) {
        PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID);
        PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription);
        PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n",
                   modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor);
        PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n",
                   modinfo.libraryVersion.major, modinfo.libraryVersion.minor);
    } else {
        PR_fprintf(PR_STDOUT, "* Module not loaded\n");
    }
    /* Get cipher and mechanism flags */
    ciphers = getStringFromFlags(module->ssl[0], cipherStrings,
                                 numCipherStrings);
    if (ciphers[0] == '\0') {
        ciphers = "None";
    }
    PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers);
    mechanisms = NULL;
    if (module->slotCount > 0) {
        mechanisms = getStringFromFlags(
            PK11_GetDefaultFlags(module->slots[0]),
            mechanismStrings, numMechanismStrings);
    }
    if ((mechanisms == NULL) || (mechanisms[0] == '\0')) {
        mechanisms = "None";
    }
    PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms);

#define PAD "  "

    /* Loop over each slot */
    for (slotnum = 0; slotnum < module->slotCount; slotnum++) {
        slot = module->slots[slotnum];
        if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) {
            PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR],
                       PK11_GetSlotName(slot));
            rv = SLOT_INFO_ERR;
            continue;
        }

        /* Slot Info */
        PR_fprintf(PR_STDOUT, "\n" PAD "Slot: %s\n", PK11_GetSlotName(slot));
        mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot),
                                        mechanismStrings, numMechanismStrings);
        if (mechanisms[0] == '\0') {
            mechanisms = "None";
        }
        PR_fprintf(PR_STDOUT, PAD "Slot Mechanism Flags: %s\n", mechanisms);
        PR_fprintf(PR_STDOUT, PAD "Manufacturer: %.32s\n",
                   slotinfo.manufacturerID);
        if (PK11_IsHW(slot)) {
            PR_fprintf(PR_STDOUT, PAD "Type: Hardware\n");
        } else {
            PR_fprintf(PR_STDOUT, PAD "Type: Software\n");
        }
        PR_fprintf(PR_STDOUT, PAD "Version Number: %d.%d\n",
                   slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor);
        PR_fprintf(PR_STDOUT, PAD "Firmware Version: %d.%d\n",
                   slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor);
        if (PK11_IsDisabled(slot)) {
            reasonIdx = PK11_GetDisabledReason(slot);
            if (reasonIdx < numDisableReasonStr) {
                PR_fprintf(PR_STDOUT, PAD "Status: DISABLED (%s)\n",
                           disableReasonStr[reasonIdx]);
            } else {
                PR_fprintf(PR_STDOUT, PAD "Status: DISABLED\n");
            }
        } else {
            PR_fprintf(PR_STDOUT, PAD "Status: Enabled\n");
        }

        if (PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) {
            PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR],
                       PK11_GetTokenName(slot));
            rv = TOKEN_INFO_ERR;
            continue;
        }

        /* Token Info */
        PR_fprintf(PR_STDOUT, PAD "Token Name: %.32s\n",
                   tokeninfo.label);
        PR_fprintf(PR_STDOUT, PAD "Token Manufacturer: %.32s\n",
                   tokeninfo.manufacturerID);
        PR_fprintf(PR_STDOUT, PAD "Token Model: %.16s\n", tokeninfo.model);
        PR_fprintf(PR_STDOUT, PAD "Token Serial Number: %.16s\n",
                   tokeninfo.serialNumber);
        PR_fprintf(PR_STDOUT, PAD "Token Version: %d.%d\n",
                   tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor);
        PR_fprintf(PR_STDOUT, PAD "Token Firmware Version: %d.%d\n",
                   tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor);
        if (tokeninfo.flags & CKF_WRITE_PROTECTED) {
            PR_fprintf(PR_STDOUT, PAD "Access: Write Protected\n");
        } else {
            PR_fprintf(PR_STDOUT, PAD "Access: NOT Write Protected\n");
        }
        if (tokeninfo.flags & CKF_LOGIN_REQUIRED) {
            PR_fprintf(PR_STDOUT, PAD "Login Type: Login required\n");
        } else {
            PR_fprintf(PR_STDOUT, PAD
                       "Login Type: Public (no login required)\n");
        }
        if (tokeninfo.flags & CKF_USER_PIN_INITIALIZED) {
            PR_fprintf(PR_STDOUT, PAD "User Pin: Initialized\n");
        } else {
            PR_fprintf(PR_STDOUT, PAD "User Pin: NOT Initialized\n");
        }
    }
    PR_fprintf(PR_STDOUT,
               "\n-----------------------------------------------------------\n");
loser:
    if (module) {
        SECMOD_DestroyModule(module);
    }
    return rv;
}