Beispiel #1
0
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;
}
Beispiel #2
0
/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createCrlObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                   const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    PRBool isKRL = PR_FALSE;
    SECItem derSubj, derCrl;
    char *url = NULL;
    const CK_ATTRIBUTE *subject, *crl;
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle;

    certHandle = lg_getCertDB(sdb);

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

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

    /* lookup SUBJECT */
    subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
    if (!subject) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    derSubj.data = (unsigned char *)subject->pValue;
    derSubj.len = subject->ulValueLen;

    /* lookup VALUE */
    crl = lg_FindAttribute(CKA_VALUE, templ, count);
    PORT_Assert(crl);
    if (!crl) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    derCrl.data = (unsigned char *)crl->pValue;
    derCrl.len = crl->ulValueLen;

    url = lg_getString(CKA_NSS_URL, templ, count);
    isKRL = lg_isTrue(CKA_NSS_KRL, templ, count);

    /* Store CRL by SUBJECT */
    rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL);

    if (url) {
        PORT_Free(url);
    }
    if (rv != SECSuccess) {
        return CKR_DEVICE_ERROR;
    }

    /* if we overwrote the existing CRL, poison the handle entry so we get
     * a new object handle */
    (void)lg_poisonHandle(sdb, &derSubj,
                          isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
    *handle = lg_mkHandle(sdb, &derSubj,
                          isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);

    return CKR_OK;
}
Beispiel #3
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;
}
Beispiel #4
0
/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createSMimeObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                     const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    SECItem derSubj, rawProfile, rawTime, emailKey;
    SECItem *pRawProfile = NULL;
    SECItem *pRawTime = NULL;
    char *email = NULL;
    const CK_ATTRIBUTE *subject = NULL,
                       *profile = NULL,
                       *time = NULL;
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle;
    CK_RV ck_rv = CKR_OK;

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

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

    /* lookup SUBJECT */
    subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
    PORT_Assert(subject);
    if (!subject) {
        ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }

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

    /* lookup VALUE */
    profile = lg_FindAttribute(CKA_VALUE, templ, count);
    if (profile) {
        rawProfile.data = (unsigned char *)profile->pValue;
        rawProfile.len = profile->ulValueLen;
        rawProfile.type = siBuffer;
        pRawProfile = &rawProfile;
    }

    /* lookup Time */
    time = lg_FindAttribute(CKA_NSS_SMIME_TIMESTAMP, templ, count);
    if (time) {
        rawTime.data = (unsigned char *)time->pValue;
        rawTime.len = time->ulValueLen;
        rawTime.type = siBuffer;
        pRawTime = &rawTime;
    }

    email = lg_getString(CKA_NSS_EMAIL, templ, count);
    if (!email) {
        ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
        goto loser;
    }

    /* Store S/MIME Profile by SUBJECT */
    rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
                                     pRawProfile, pRawTime);
    if (rv != SECSuccess) {
        ck_rv = CKR_DEVICE_ERROR;
        goto loser;
    }
    emailKey.data = (unsigned char *)email;
    emailKey.len = PORT_Strlen(email) + 1;

    *handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME);

loser:
    if (email)
        PORT_Free(email);

    return ck_rv;
}
Beispiel #5
0
/*
 * check the consistancy and initialize a Trust Object
 */
static CK_RV
lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
                     const CK_ATTRIBUTE *templ, CK_ULONG count)
{
    const CK_ATTRIBUTE *issuer = NULL;
    const CK_ATTRIBUTE *serial = NULL;
    NSSLOWCERTCertificate *cert = NULL;
    const CK_ATTRIBUTE *trust;
    CK_TRUST sslTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST clientTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST emailTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_TRUST signTrust = CKT_NSS_TRUST_UNKNOWN;
    CK_BBOOL stepUp;
    NSSLOWCERTCertTrust dbTrust = { 0 };
    SECStatus rv;
    NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
    NSSLOWCERTIssuerAndSN issuerSN;

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

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

    issuer = lg_FindAttribute(CKA_ISSUER, templ, count);
    serial = lg_FindAttribute(CKA_SERIAL_NUMBER, templ, count);

    if (issuer && serial) {
        issuerSN.derIssuer.data = (unsigned char *)issuer->pValue;
        issuerSN.derIssuer.len = issuer->ulValueLen;

        issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
        issuerSN.serialNumber.len = serial->ulValueLen;

        cert = nsslowcert_FindCertByIssuerAndSN(certHandle, &issuerSN);
    }

    if (cert == NULL) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    lg_GetULongAttribute(CKA_TRUST_SERVER_AUTH, templ, count, &sslTrust);
    lg_GetULongAttribute(CKA_TRUST_CLIENT_AUTH, templ, count, &clientTrust);
    lg_GetULongAttribute(CKA_TRUST_EMAIL_PROTECTION, templ, count, &emailTrust);
    lg_GetULongAttribute(CKA_TRUST_CODE_SIGNING, templ, count, &signTrust);
    stepUp = CK_FALSE;
    trust = lg_FindAttribute(CKA_TRUST_STEP_UP_APPROVED, templ, count);
    if (trust) {
        if (trust->ulValueLen == sizeof(CK_BBOOL)) {
            stepUp = *(CK_BBOOL *)trust->pValue;
        }
    }

    /* preserve certain old fields */
    if (cert->trust) {
        dbTrust.sslFlags = cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
        dbTrust.emailFlags =
            cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
        dbTrust.objectSigningFlags =
            cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
    }

    dbTrust.sslFlags |= lg_MapTrust(sslTrust, PR_FALSE);
    dbTrust.sslFlags |= lg_MapTrust(clientTrust, PR_TRUE);
    dbTrust.emailFlags |= lg_MapTrust(emailTrust, PR_FALSE);
    dbTrust.objectSigningFlags |= lg_MapTrust(signTrust, PR_FALSE);
    if (stepUp) {
        dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
    }

    rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
    *handle = lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_TRUST);
    nsslowcert_DestroyCertificate(cert);
    if (rv != SECSuccess) {
        return CKR_DEVICE_ERROR;
    }

    return CKR_OK;
}