diff options
Diffstat (limited to 'security/nss/lib/softoken/sftkdb.c')
-rw-r--r-- | security/nss/lib/softoken/sftkdb.c | 84 |
1 files changed, 76 insertions, 8 deletions
diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c index 52e5161176..2ae0840682 100644 --- a/security/nss/lib/softoken/sftkdb.c +++ b/security/nss/lib/softoken/sftkdb.c @@ -28,6 +28,9 @@ #include "utilpars.h" #include "secerr.h" #include "softoken.h" +#if defined(_WIN32) +#include <windows.h> +#endif /* * We want all databases to have the same binary representation independent of @@ -40,7 +43,7 @@ */ #define BBP 8 -static PRBool +PRBool sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type) { switch (type) { @@ -1370,7 +1373,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, } /* make sure we don't have attributes that conflict with the existing DB */ - crv = sftkdb_checkConflicts(db, object->objclass, template, count, objectID); + crv = sftkdb_checkConflicts(db, object->objclass, ntemplate, count, + objectID); if (crv != CKR_OK) { goto loser; } @@ -1386,8 +1390,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, goto loser; } inTransaction = PR_TRUE; - crv = sftkdb_setAttributeValue(arena, handle, db, - objectID, template, count); + crv = sftkdb_setAttributeValue(arena, handle, db, objectID, ntemplate, + count); if (crv != CKR_OK) { goto loser; } @@ -2311,6 +2315,13 @@ loser: crv = (*handle->update->sdb_GetMetaData)(handle->update, "password", &item1, &item2); if (crv != CKR_OK) { + /* if we get here, neither the source, nor the target has been initialized + * with a password entry. Create a metadata table now so that we don't + * mistake this for a partially updated database */ + item1.data[0] = 0; + item2.data[0] = 0; + item1.len = item2.len = 1; + crv = (*handle->db->sdb_PutMetaData)(handle->db, "empty", &item1, &item2); goto done; } crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1, @@ -2501,6 +2512,53 @@ sftk_oldVersionExists(const char *dir, int version) return PR_FALSE; } +#if defined(_WIN32) +/* + * Convert an sdb path (encoded in UTF-8) to a legacy path (encoded in the + * current system codepage). Fails if the path contains a character outside + * the current system codepage. + */ +static char * +sftk_legacyPathFromSDBPath(const char *confdir) +{ + wchar_t *confdirWide; + DWORD size; + char *nconfdir; + BOOL unmappable; + + if (!confdir) { + return NULL; + } + confdirWide = _NSSUTIL_UTF8ToWide(confdir); + if (!confdirWide) { + return NULL; + } + + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + NULL, 0, NULL, &unmappable); + if (size == 0 || unmappable) { + PORT_Free(confdirWide); + return NULL; + } + nconfdir = PORT_Alloc(sizeof(char) * size); + if (!nconfdir) { + PORT_Free(confdirWide); + return NULL; + } + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + nconfdir, size, NULL, &unmappable); + PORT_Free(confdirWide); + if (size == 0 || unmappable) { + PORT_Free(nconfdir); + return NULL; + } + + return nconfdir; +} +#else +#define sftk_legacyPathFromSDBPath(confdir) PORT_Strdup((confdir)) +#endif + static PRBool sftk_hasLegacyDB(const char *confdir, const char *certPrefix, const char *keyPrefix, int certVersion, int keyVersion) @@ -2560,6 +2618,7 @@ sftk_DBInit(const char *configdir, const char *certPrefix, int flags = SDB_RDONLY; PRBool newInit = PR_FALSE; PRBool needUpdate = PR_FALSE; + char *nconfdir = NULL; if (!readOnly) { flags = SDB_CREATE; @@ -2598,11 +2657,14 @@ sftk_DBInit(const char *configdir, const char *certPrefix, * the exists. */ if (crv != CKR_OK) { - if (((flags & SDB_RDONLY) == SDB_RDONLY) && - sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + if ((flags & SDB_RDONLY) == SDB_RDONLY) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + } + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { /* we have legacy databases, if we failed to open the new format * DB's read only, just use the legacy ones */ - crv = sftkdbCall_open(confdir, certPrefix, + crv = sftkdbCall_open(nconfdir, certPrefix, keyPrefix, 8, 3, flags, noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB); } @@ -2631,7 +2693,10 @@ sftk_DBInit(const char *configdir, const char *certPrefix, /* if the new format DB was also a newly created DB, and we * succeeded, then need to update that new database with data * from the existing legacy DB */ - if (sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { + confdir = nconfdir; needUpdate = PR_TRUE; } } @@ -2704,6 +2769,9 @@ done: if (appName) { PORT_Free(appName); } + if (nconfdir) { + PORT_Free(nconfdir); + } return forceOpen ? CKR_OK : crv; } |