summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/softoken/sdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/softoken/sdb.c')
-rw-r--r--security/nss/lib/softoken/sdb.c106
1 files changed, 62 insertions, 44 deletions
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c
index fb897d68c..c84476100 100644
--- a/security/nss/lib/softoken/sdb.c
+++ b/security/nss/lib/softoken/sdb.c
@@ -159,7 +159,7 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
- CKA_PUBLIC_KEY_INFO
+ CKA_PUBLIC_KEY_INFO, CKA_NSS_SERVER_DISTRUST_AFTER, CKA_NSS_EMAIL_DISTRUST_AFTER
};
static int known_attributes_size = sizeof(known_attributes) /
@@ -858,7 +858,6 @@ sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
return sdb_mapSQLError(sdb_p->type, sqlerr);
}
-static const char GET_ATTRIBUTE_CMD[] = "SELECT ALL %s FROM %s WHERE id=$ID;";
CK_RV
sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
CK_ATTRIBUTE *template, CK_ULONG count)
@@ -866,8 +865,6 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
SDBPrivate *sdb_p = sdb->private;
sqlite3 *sqlDB = NULL;
sqlite3_stmt *stmt = NULL;
- char *getStr = NULL;
- char *newStr = NULL;
const char *table = NULL;
int sqlerr = SQLITE_OK;
CK_RV error = CKR_OK;
@@ -875,59 +872,79 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
int retry = 0;
unsigned int i;
+ if (count == 0) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
/* open a new db if necessary */
error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
if (error != CKR_OK) {
goto loser;
}
+ char *columns = NULL;
for (i = 0; i < count; i++) {
- getStr = sqlite3_mprintf("a%x", template[i].type);
-
- if (getStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
+ char *newColumns;
+ if (columns) {
+ newColumns = sqlite3_mprintf("%s, a%x", columns, template[i].type);
+ sqlite3_free(columns);
+ columns = NULL;
+ } else {
+ newColumns = sqlite3_mprintf("a%x", template[i].type);
}
-
- newStr = sqlite3_mprintf(GET_ATTRIBUTE_CMD, getStr, table);
- sqlite3_free(getStr);
- getStr = NULL;
- if (newStr == NULL) {
+ if (!newColumns) {
error = CKR_HOST_MEMORY;
goto loser;
}
+ columns = newColumns;
+ }
- sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- sqlite3_free(newStr);
- newStr = NULL;
- if (sqlerr == SQLITE_ERROR) {
- template[i].ulValueLen = -1;
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- continue;
- } else if (sqlerr != SQLITE_OK) {
- goto loser;
- }
+ PORT_Assert(columns);
- sqlerr = sqlite3_bind_int(stmt, 1, object_id);
- if (sqlerr != SQLITE_OK) {
- goto loser;
- }
+ char *statement = sqlite3_mprintf("SELECT DISTINCT %s FROM %s where id=$ID LIMIT 1;",
+ columns, table);
+ sqlite3_free(columns);
+ columns = NULL;
+ if (!statement) {
+ error = CKR_HOST_MEMORY;
+ goto loser;
+ }
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- if (sqlerr == SQLITE_ROW) {
+ sqlerr = sqlite3_prepare_v2(sqlDB, statement, -1, &stmt, NULL);
+ sqlite3_free(statement);
+ statement = NULL;
+ if (sqlerr != SQLITE_OK) {
+ goto loser;
+ }
+
+ // NB: indices in sqlite3_bind_int are 1-indexed
+ sqlerr = sqlite3_bind_int(stmt, 1, object_id);
+ if (sqlerr != SQLITE_OK) {
+ goto loser;
+ }
+
+ do {
+ sqlerr = sqlite3_step(stmt);
+ if (sqlerr == SQLITE_BUSY) {
+ PR_Sleep(SDB_BUSY_RETRY_TIME);
+ }
+ if (sqlerr == SQLITE_ROW) {
+ PORT_Assert(!found);
+ for (i = 0; i < count; i++) {
unsigned int blobSize;
const char *blobData;
- blobSize = sqlite3_column_bytes(stmt, 0);
- blobData = sqlite3_column_blob(stmt, 0);
+ // NB: indices in sqlite_column_{bytes,blob} are 0-indexed
+ blobSize = sqlite3_column_bytes(stmt, i);
+ blobData = sqlite3_column_blob(stmt, i);
if (blobData == NULL) {
+ /* PKCS 11 requires that get attributes process all the
+ * attributes in the template, marking the attributes with
+ * issues with -1. Mark the error but continue */
template[i].ulValueLen = -1;
error = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
+ continue;
}
/* If the blob equals our explicit NULL value, then the
* attribute is a NULL. */
@@ -938,20 +955,21 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
}
if (template[i].pValue) {
if (template[i].ulValueLen < blobSize) {
+ /* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */
template[i].ulValueLen = -1;
error = CKR_BUFFER_TOO_SMALL;
- break;
+ continue;
}
PORT_Memcpy(template[i].pValue, blobData, blobSize);
}
template[i].ulValueLen = blobSize;
- found = 1;
}
- } while (!sdb_done(sqlerr, &retry));
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- stmt = NULL;
- }
+ found = 1;
+ }
+ } while (!sdb_done(sqlerr, &retry));
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+ stmt = NULL;
loser:
/* fix up the error if necessary */