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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }