示例#1
0
/*
 * check the consistancy and initialize a Private Key Object
 */
static CK_RV
lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                          CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    NSSLOWKEYPrivateKey *privKey;
    char *label;
    SECStatus rv = SECSuccess;
    CK_RV crv = CKR_DEVICE_ERROR;
    SECItem pubKey;
    NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb);

    if (keyHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    privKey = lg_mkPrivKey(sdb, templ, count, key_type, &crv);
    if (privKey == NULL)
        return crv;
    label = lg_getString(CKA_LABEL, templ, count);

    crv = lg_Attribute2SSecItem(NULL, CKA_NETSCAPE_DB, templ, count, &pubKey);
    if (crv != CKR_OK) {
        crv = CKR_TEMPLATE_INCOMPLETE;
        rv = SECFailure;
        goto fail;
    }
#ifdef notdef
    if (keyHandle->version != 3) {
        unsigned char buf[SHA1_LENGTH];
        SHA1_HashBuf(buf, pubKey.data, pubKey.len);
        PORT_Memcpy(pubKey.data, buf, sizeof(buf));
        pubKey.len = sizeof(buf);
    }
#endif
    /* get the key type */
    if (key_type == CKK_RSA) {
        rv = RSA_PrivateKeyCheck(&privKey->u.rsa);
        if (rv == SECFailure) {
            goto fail;
        }
    }
    rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey,
                                       label, sdb /*->password*/);

fail:
    if (label)
        PORT_Free(label);
    *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_PRIV);
    if (pubKey.data)
        PORT_Free(pubKey.data);
    lg_nsslowkey_DestroyPrivateKey(privKey);
    if (rv != SECSuccess)
        return crv;

    return CKR_OK;
}
示例#2
0
文件: lginit.c 项目: Jar-win/Waterfox
static DB *
lg_getRawDB(SDB *sdb)
{
    NSSLOWCERTCertDBHandle *certDB;
    NSSLOWKEYDBHandle *keyDB;

    certDB = lg_getCertDB(sdb);
    if (certDB) {
	return certDB->permCertDB;
    }
    keyDB = lg_getKeyDB(sdb);
    if (keyDB) {
	return keyDB->db;
    }
    return NULL;
}
示例#3
0
/*
 * check the consistancy and initialize a Secret Key Object
 */
static CK_RV
lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                         CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_RV crv;
    NSSLOWKEYPrivateKey *privKey = NULL;
    NSSLOWKEYDBHandle *keyHandle = NULL;
    SECItem pubKey;
    char *label = NULL;
    SECStatus rv = SECSuccess;

    pubKey.data = 0;

    /* If the object is a TOKEN object, store in the database */
    keyHandle = lg_getKeyDB(sdb);

    if (keyHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    label = lg_getString(CKA_LABEL, templ, count);

    crv = lg_Attribute2SecItem(NULL, CKA_ID, templ, count, &pubKey);
    /* Should this be ID? */
    if (crv != CKR_OK)
        goto loser;

    /* if we don't have an ID, generate one */
    if (pubKey.len == 0) {
        if (pubKey.data) {
            PORT_Free(pubKey.data);
            pubKey.data = NULL;
        }
        crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
        if (crv != CKR_OK)
            goto loser;
    }

    privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb);
    if (privKey == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
                                       privKey, &pubKey, label, sdb /*->password*/);
    if (rv != SECSuccess) {
        crv = CKR_DEVICE_ERROR;
        goto loser;
    }

    *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_KEY);

loser:
    if (label)
        PORT_Free(label);
    if (privKey)
        lg_nsslowkey_DestroyPrivateKey(privKey);
    if (pubKey.data)
        PORT_Free(pubKey.data);

    return crv;
}
示例#4
0
/*
 * check the consistancy and initialize a Public Key Object
 */
static CK_RV
lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
                         CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
    CK_RV crv = CKR_OK;
    NSSLOWKEYPrivateKey *priv;
    SECItem pubKeySpace = { siBuffer, NULL, 0 };
    SECItem *pubKey;
#ifndef NSS_DISABLE_ECC
    SECItem pubKey2Space = { siBuffer, NULL, 0 };
    PLArenaPool *arena = NULL;
#endif /* NSS_DISABLE_ECC */
    NSSLOWKEYDBHandle *keyHandle = NULL;

    switch (key_type) {
        case CKK_RSA:
            pubKeyAttr = CKA_MODULUS;
            break;
#ifndef NSS_DISABLE_ECC
        case CKK_EC:
            pubKeyAttr = CKA_EC_POINT;
            break;
#endif /* NSS_DISABLE_ECC */
        case CKK_DSA:
        case CKK_DH:
            break;
        default:
            return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    pubKey = &pubKeySpace;
    crv = lg_Attribute2SSecItem(NULL, pubKeyAttr, templ, count, pubKey);
    if (crv != CKR_OK)
        return crv;

#ifndef NSS_DISABLE_ECC
    if (key_type == CKK_EC) {
        SECStatus rv;
        /*
         * for ECC, use the decoded key first.
         */
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
            crv = CKR_HOST_MEMORY;
            goto done;
        }
        rv = SEC_QuickDERDecodeItem(arena, &pubKey2Space,
                                    SEC_ASN1_GET(SEC_OctetStringTemplate),
                                    pubKey);
        if (rv != SECSuccess) {
            /* decode didn't work, just try the pubKey */
            PORT_FreeArena(arena, PR_FALSE);
            arena = NULL;
        } else {
            /* try the decoded pub key first */
            pubKey = &pubKey2Space;
        }
    }
#endif /* NSS_DISABLE_ECC */

    PORT_Assert(pubKey->data);
    if (pubKey->data == NULL) {
        crv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto done;
    }
    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle == NULL) {
        crv = CKR_TOKEN_WRITE_PROTECTED;
        goto done;
    }
    if (keyHandle->version != 3) {
        unsigned char buf[SHA1_LENGTH];
        SHA1_HashBuf(buf, pubKey->data, pubKey->len);
        PORT_Memcpy(pubKey->data, buf, sizeof(buf));
        pubKey->len = sizeof(buf);
    }
    /* make sure the associated private key already exists */
    /* only works if we are logged in */
    priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/);
#ifndef NSS_DISABLE_ECC
    if (priv == NULL && pubKey == &pubKey2Space) {
        /* no match on the decoded key, match the original pubkey */
        pubKey = &pubKeySpace;
        priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey,
                                            sdb /*password*/);
    }
#endif
    if (priv == NULL) {
        /* the legacy database can only 'store' public keys which already
         * have their corresponding private keys in the database */
        crv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto done;
    }
    lg_nsslowkey_DestroyPrivateKey(priv);
    crv = CKR_OK;

    *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB);

done:
    PORT_Free(pubKeySpace.data);
#ifndef NSS_DISABLE_ECC
    if (arena)
        PORT_FreeArena(arena, PR_FALSE);
#endif

    return crv;
}
示例#5
0
/*
 * check the consistancy and initialize a Certificate Object
 */
static CK_RV
lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                    const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    SECItem derCert;
    NSSLOWCERTCertificate *cert;
    NSSLOWCERTCertTrust *trust = NULL;
    NSSLOWCERTCertTrust userTrust =
        { CERTDB_USER, CERTDB_USER, CERTDB_USER };
    NSSLOWCERTCertTrust defTrust =
        { CERTDB_TRUSTED_UNKNOWN,
          CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
    char *label = NULL;
    char *email = NULL;
    SECStatus rv;
    CK_RV crv;
    PRBool inDB = PR_TRUE;
    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
    NSSLOWKEYDBHandle *keyHandle = NULL;
    CK_CERTIFICATE_TYPE type;
    const CK_ATTRIBUTE *attribute;

    /* we can't store any certs private */
    if (lg_isTrue(CKA_PRIVATE, templ, count)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    /* We only support X.509 Certs for now */
    crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, templ, count, &type);
    if (crv != CKR_OK) {
        return crv;
    }

    if (type != CKC_X_509) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    /* X.509 Certificate */

    if (certHandle == NULL) {
        return CKR_TOKEN_WRITE_PROTECTED;
    }

    /* get the der cert */
    attribute = lg_FindAttribute(CKA_VALUE, templ, count);
    if (!attribute) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    derCert.type = 0;
    derCert.data = (unsigned char *)attribute->pValue;
    derCert.len = attribute->ulValueLen;

    label = lg_getString(CKA_LABEL, templ, count);

    cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
    if (cert == NULL) {
        cert = nsslowcert_DecodeDERCertificate(&derCert, label);
        inDB = PR_FALSE;
    }
    if (cert == NULL) {
        if (label)
            PORT_Free(label);
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle) {
        if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
            trust = &userTrust;
        }
    }

    if (!inDB) {
        if (!trust)
            trust = &defTrust;
        rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
    } else {
        rv = trust ? nsslowcert_ChangeCertTrust(certHandle, cert, trust) : SECSuccess;
    }

    if (label)
        PORT_Free(label);

    if (rv != SECSuccess) {
        nsslowcert_DestroyCertificate(cert);
        return CKR_DEVICE_ERROR;
    }

    /*
     * Add a NULL S/MIME profile if necessary.
     */
    email = lg_getString(CKA_NSS_EMAIL, templ, count);
    if (email) {
        certDBEntrySMime *entry;

        entry = nsslowcert_ReadDBSMimeEntry(certHandle, email);
        if (!entry) {
            nsslowcert_SaveSMimeProfile(certHandle, email,
                                        &cert->derSubject, NULL, NULL);
        } else {
            nsslowcert_DestroyDBEntry((certDBEntry *)entry);
        }
        PORT_Free(email);
    }
    *handle = lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_CERT);
    nsslowcert_DestroyCertificate(cert);

    return CKR_OK;
}