171 lines
5.5 KiB
Diff
171 lines
5.5 KiB
Diff
|
diff --git a/lib/softoken/legacydb/pcertdb.c b/lib/softoken/legacydb/pcertdb.c
|
||
|
--- a/lib/softoken/legacydb/pcertdb.c
|
||
|
+++ b/lib/softoken/legacydb/pcertdb.c
|
||
|
@@ -4272,16 +4272,17 @@ CreateTrust(void)
|
||
|
{
|
||
|
NSSLOWCERTTrust *trust = NULL;
|
||
|
|
||
|
nsslowcert_LockFreeList();
|
||
|
trust = trustListHead;
|
||
|
if (trust) {
|
||
|
trustListCount--;
|
||
|
trustListHead = trust->next;
|
||
|
+ trust->next = NULL;
|
||
|
}
|
||
|
PORT_Assert(trustListCount >= 0);
|
||
|
nsslowcert_UnlockFreeList();
|
||
|
if (trust) {
|
||
|
return trust;
|
||
|
}
|
||
|
|
||
|
return PORT_ZNew(NSSLOWCERTTrust);
|
||
|
@@ -5155,19 +5156,21 @@ done:
|
||
|
}
|
||
|
|
||
|
PRBool
|
||
|
nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust)
|
||
|
{
|
||
|
if (trust == NULL) {
|
||
|
return PR_FALSE;
|
||
|
}
|
||
|
- return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
|
||
|
- (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
|
||
|
- (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
|
||
|
+ /* if we only have CERTDB__USER and CERTDB_TRUSTED_UNKNOWN bits, then
|
||
|
+ * we don't have a trust record. */
|
||
|
+ return !(((trust->sslFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0) &&
|
||
|
+ ((trust->emailFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0) &&
|
||
|
+ ((trust->objectSigningFlags & ~(CERTDB_USER|CERTDB_TRUSTED_UNKNOWN)) == 0));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This function has the logic that decides if another person's cert and
|
||
|
* email profile from an S/MIME message should be saved. It can deal with
|
||
|
* the case when there is no profile.
|
||
|
*/
|
||
|
static SECStatus
|
||
|
diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c
|
||
|
--- a/lib/softoken/sftkdb.c
|
||
|
+++ b/lib/softoken/sftkdb.c
|
||
|
@@ -119,47 +119,79 @@ sftkdb_isAuthenticatedAttribute(CK_ATTRI
|
||
|
case CKA_TRUST_STEP_UP_APPROVED:
|
||
|
case CKA_NSS_OVERRIDE_EXTENSIONS:
|
||
|
return PR_TRUE;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return PR_FALSE;
|
||
|
}
|
||
|
-
|
||
|
/*
|
||
|
* convert a native ULONG to a database ulong. Database ulong's
|
||
|
* are all 4 byte big endian values.
|
||
|
*/
|
||
|
void
|
||
|
sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < SDB_ULONG_SIZE; i++) {
|
||
|
data[i] = (value >> (SDB_ULONG_SIZE - 1 - i) * BBP) & 0xff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* convert a database ulong back to a native ULONG. (reverse of the above
|
||
|
- * function.
|
||
|
+ * function).
|
||
|
*/
|
||
|
static CK_ULONG
|
||
|
sftk_SDBULong2ULong(unsigned char *data)
|
||
|
{
|
||
|
int i;
|
||
|
CK_ULONG value = 0;
|
||
|
|
||
|
for (i = 0; i < SDB_ULONG_SIZE; i++) {
|
||
|
value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE - 1 - i) * BBP);
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
+/* certain trust records are default values, which are the values
|
||
|
+ * returned if the signature check fails anyway.
|
||
|
+ * In those cases, we can skip the signature check. */
|
||
|
+PRBool
|
||
|
+sftkdb_isNullTrust(const CK_ATTRIBUTE *template)
|
||
|
+{
|
||
|
+ switch (template->type) {
|
||
|
+ case CKA_TRUST_SERVER_AUTH:
|
||
|
+ case CKA_TRUST_CLIENT_AUTH:
|
||
|
+ case CKA_TRUST_EMAIL_PROTECTION:
|
||
|
+ case CKA_TRUST_CODE_SIGNING:
|
||
|
+ if (template->ulValueLen != SDB_ULONG_SIZE) {
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (sftk_SDBULong2ULong(template->pValue) ==
|
||
|
+ CKT_NSS_TRUST_UNKNOWN) {
|
||
|
+ return PR_TRUE;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case CKA_TRUST_STEP_UP_APPROVED:
|
||
|
+ if (template->ulValueLen != 1) {
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (*((unsigned char *)(template->pValue)) == 0) {
|
||
|
+ return PR_TRUE;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ return PR_FALSE;
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* fix up the input templates. Our fixed up ints are stored in data and must
|
||
|
* be freed by the caller. The new template must also be freed. If there are no
|
||
|
* CK_ULONG attributes, the orignal template is passed in as is.
|
||
|
*/
|
||
|
static CK_ATTRIBUTE *
|
||
|
sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
|
||
|
unsigned char **dataOut, int *dataOutSize)
|
||
|
@@ -410,17 +442,18 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *te
|
||
|
}
|
||
|
|
||
|
/* copy the plain text back into the template */
|
||
|
PORT_Memcpy(template[i].pValue, plainText->data, plainText->len);
|
||
|
template[i].ulValueLen = plainText->len;
|
||
|
SECITEM_ZfreeItem(plainText, PR_TRUE);
|
||
|
}
|
||
|
/* make sure signed attributes are valid */
|
||
|
- if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) {
|
||
|
+ if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)
|
||
|
+ && !sftkdb_isNullTrust(&ntemplate[i])) {
|
||
|
SECStatus rv;
|
||
|
CK_RV local_crv;
|
||
|
SECItem signText;
|
||
|
SECItem plainText;
|
||
|
unsigned char signData[SDB_MAX_META_DATA_LEN];
|
||
|
|
||
|
signText.data = signData;
|
||
|
signText.len = sizeof(signData);
|
||
|
@@ -2387,16 +2420,18 @@ sftkdb_mergeObject(SFTKDBHandle *handle,
|
||
|
crv = (*source->sdb_GetAttributeValue)(source, id,
|
||
|
ptemplate, max_attributes);
|
||
|
if (crv != CKR_OK) {
|
||
|
goto loser;
|
||
|
}
|
||
|
|
||
|
objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate,
|
||
|
max_attributes);
|
||
|
+/*printf(" - merging object Type 0x%08lx id=0x%08lx updateID=%s\n", objectType, id,
|
||
|
+ handle->updateID?handle->updateID: "<NULL>");*/
|
||
|
|
||
|
/*
|
||
|
* Update Object updates the object template if necessary then returns
|
||
|
* whether or not we need to actually write the object out to our target
|
||
|
* database.
|
||
|
*/
|
||
|
if (!handle->updateID) {
|
||
|
crv = sftkdb_CreateObject(arena, handle, target, &newID,
|