Bug Summary

File:s/lib/softoken/legacydb/pk11db.c
Warning:line 212, column 5
Value stored to 'offsetPtr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pk11db.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken/legacydb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken/legacydb -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D LG_LIB_NAME="libnssdbm3.so" -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../../dist/public/nss -I ../../../../dist/private/nss -I ../../../../dist/public/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c pk11db.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4/*
5 * The following code handles the storage of PKCS 11 modules used by the
6 * NSS. This file is written to abstract away how the modules are
7 * stored so we can deside that later.
8 */
9
10#include "lgdb.h"
11#include "mcom_db.h"
12#include "secerr.h"
13#include "utilpars.h"
14
15#define FREE_CLEAR(p)if (p) { PORT_Free_Util(p); p = ((void*)0); } \
16 if (p) { \
17 PORT_FreePORT_Free_Util(p); \
18 p = NULL((void*)0); \
19 }
20
21/* Construct a database key for a given module */
22static SECStatus
23lgdb_MakeKey(DBT *key, char *module)
24{
25 int len = 0;
26 char *commonName;
27
28 commonName = NSSUTIL_ArgGetParamValue("name", module);
29 if (commonName == NULL((void*)0)) {
30 commonName = NSSUTIL_ArgGetParamValue("library", module);
31 }
32 if (commonName == NULL((void*)0))
33 return SECFailure;
34 len = PORT_Strlen(commonName)strlen(commonName);
35 key->data = commonName;
36 key->size = len;
37 return SECSuccess;
38}
39
40/* free out constructed database key */
41static void
42lgdb_FreeKey(DBT *key)
43{
44 if (key->data) {
45 PORT_FreePORT_Free_Util(key->data);
46 }
47 key->data = NULL((void*)0);
48 key->size = 0;
49}
50
51typedef struct lgdbDataStr lgdbData;
52typedef struct lgdbSlotDataStr lgdbSlotData;
53struct lgdbDataStr {
54 unsigned char major;
55 unsigned char minor;
56 unsigned char nameStart[2];
57 unsigned char slotOffset[2];
58 unsigned char internal;
59 unsigned char fips;
60 unsigned char ssl[8];
61 unsigned char trustOrder[4];
62 unsigned char cipherOrder[4];
63 unsigned char reserved1;
64 unsigned char isModuleDB;
65 unsigned char isModuleDBOnly;
66 unsigned char isCritical;
67 unsigned char reserved[4];
68 unsigned char names[6]; /* enough space for the length fields */
69};
70
71struct lgdbSlotDataStr {
72 unsigned char slotID[4];
73 unsigned char defaultFlags[4];
74 unsigned char timeout[4];
75 unsigned char askpw;
76 unsigned char hasRootCerts;
77 unsigned char reserved[18]; /* this makes it a round 32 bytes */
78};
79
80#define LGDB_DB_VERSION_MAJOR0 0
81#define LGDB_DB_VERSION_MINOR6 6
82#define LGDB_DB_EXT1_VERSION_MAJOR0 0
83#define LGDB_DB_EXT1_VERSION_MINOR6 6
84#define LGDB_DB_NOUI_VERSION_MAJOR0 0
85#define LGDB_DB_NOUI_VERSION_MINOR4 4
86
87#define LGDB_PUTSHORT(dest, src)(dest)[1] = (unsigned char)((src)&0xff); (dest)[0] = (unsigned
char)(((src) >> 8) & 0xff);
\
88 (dest)[1] = (unsigned char)((src)&0xff); \
89 (dest)[0] = (unsigned char)(((src) >> 8) & 0xff);
90#define LGDB_PUTLONG(dest, src)(dest)[3] = (unsigned char)((src)&0xff); (dest)[2] = (unsigned
char)(((src) >> 8) & 0xff); (dest)[1] = (unsigned char
)(((src) >> 16) & 0xff); (dest)[0] = (unsigned char
)(((src) >> 24) & 0xff);
\
91 (dest)[3] = (unsigned char)((src)&0xff); \
92 (dest)[2] = (unsigned char)(((src) >> 8) & 0xff); \
93 (dest)[1] = (unsigned char)(((src) >> 16) & 0xff); \
94 (dest)[0] = (unsigned char)(((src) >> 24) & 0xff);
95#define LGDB_GETSHORT(src)((unsigned short)(((src)[0] << 8) | (src)[1])) \
96 ((unsigned short)(((src)[0] << 8) | (src)[1]))
97#define LGDB_GETLONG(src)((unsigned long)(((unsigned long)(src)[0] << 24) | ((unsigned
long)(src)[1] << 16) | ((unsigned long)(src)[2] <<
8) | (unsigned long)(src)[3]))
\
98 ((unsigned long)(((unsigned long)(src)[0] << 24) | \
99 ((unsigned long)(src)[1] << 16) | \
100 ((unsigned long)(src)[2] << 8) | \
101 (unsigned long)(src)[3]))
102
103/*
104 * build a data base entry from a module
105 */
106static SECStatus
107lgdb_EncodeData(DBT *data, char *module)
108{
109 lgdbData *encoded = NULL((void*)0);
110 lgdbSlotData *slot;
111 unsigned char *dataPtr, *offsetPtr;
112 unsigned short len, len2 = 0, len3 = 0;
113 int count = 0;
114 unsigned short offset;
115 int dataLen, i;
116 unsigned long order;
117 unsigned long ssl[2];
118 char *commonName = NULL((void*)0), *dllName = NULL((void*)0), *param = NULL((void*)0), *nss = NULL((void*)0);
119 char *slotParams, *ciphers;
120 struct NSSUTILPreSlotInfoStr *slotInfo = NULL((void*)0);
121 SECStatus rv = SECFailure;
122
123 rv = NSSUTIL_ArgParseModuleSpec(module, &dllName, &commonName, &param, &nss);
124 if (rv != SECSuccess)
125 return rv;
126 rv = SECFailure;
127
128 if (commonName == NULL((void*)0)) {
129 /* set error */
130 goto loser;
131 }
132
133 len = PORT_Strlen(commonName)strlen(commonName);
134 if (dllName) {
135 len2 = PORT_Strlen(dllName)strlen(dllName);
136 }
137 if (param) {
138 len3 = PORT_Strlen(param)strlen(param);
139 }
140
141 slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
142 slotInfo = NSSUTIL_ArgParseSlotInfo(NULL((void*)0), slotParams, &count);
143 if (slotParams)
144 PORT_FreePORT_Free_Util(slotParams);
145
146 if (count && slotInfo == NULL((void*)0)) {
147 /* set error */
148 goto loser;
149 }
150
151 dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
152 count * sizeof(lgdbSlotData);
153
154 data->data = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(dataLen);
155 encoded = (lgdbData *)data->data;
156 dataPtr = (unsigned char *)data->data;
157 data->size = dataLen;
158
159 if (encoded == NULL((void*)0)) {
160 /* set error */
161 goto loser;
162 }
163
164 encoded->major = LGDB_DB_VERSION_MAJOR0;
165 encoded->minor = LGDB_DB_VERSION_MINOR6;
166 encoded->internal = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "internal", nss) ? 1 : 0);
167 encoded->fips = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "FIPS", nss) ? 1 : 0);
168 encoded->isModuleDB = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "isModuleDB", nss) ? 1 : 0);
169 encoded->isModuleDBOnly = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "isModuleDBOnly", nss) ? 1 : 0);
170 encoded->isCritical = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "critical", nss) ? 1 : 0);
171
172 order = NSSUTIL_ArgReadLong("trustOrder", nss,
173 NSSUTIL_DEFAULT_TRUST_ORDER50, NULL((void*)0));
174 LGDB_PUTLONG(encoded->trustOrder, order)(encoded->trustOrder)[3] = (unsigned char)((order)&0xff
); (encoded->trustOrder)[2] = (unsigned char)(((order) >>
8) & 0xff); (encoded->trustOrder)[1] = (unsigned char
)(((order) >> 16) & 0xff); (encoded->trustOrder)
[0] = (unsigned char)(((order) >> 24) & 0xff);
;
175 order = NSSUTIL_ArgReadLong("cipherOrder", nss,
176 NSSUTIL_DEFAULT_CIPHER_ORDER0, NULL((void*)0));
177 LGDB_PUTLONG(encoded->cipherOrder, order)(encoded->cipherOrder)[3] = (unsigned char)((order)&0xff
); (encoded->cipherOrder)[2] = (unsigned char)(((order) >>
8) & 0xff); (encoded->cipherOrder)[1] = (unsigned char
)(((order) >> 16) & 0xff); (encoded->cipherOrder
)[0] = (unsigned char)(((order) >> 24) & 0xff);
;
178
179 ciphers = NSSUTIL_ArgGetParamValue("ciphers", nss);
180 NSSUTIL_ArgParseCipherFlags(&ssl[0], ciphers);
181 LGDB_PUTLONG(encoded->ssl, ssl[0])(encoded->ssl)[3] = (unsigned char)((ssl[0])&0xff); (encoded
->ssl)[2] = (unsigned char)(((ssl[0]) >> 8) & 0xff
); (encoded->ssl)[1] = (unsigned char)(((ssl[0]) >> 16
) & 0xff); (encoded->ssl)[0] = (unsigned char)(((ssl[0
]) >> 24) & 0xff);
;
182 LGDB_PUTLONG(&encoded->ssl[4], ssl[1])(&encoded->ssl[4])[3] = (unsigned char)((ssl[1])&0xff
); (&encoded->ssl[4])[2] = (unsigned char)(((ssl[1]) >>
8) & 0xff); (&encoded->ssl[4])[1] = (unsigned char
)(((ssl[1]) >> 16) & 0xff); (&encoded->ssl[4
])[0] = (unsigned char)(((ssl[1]) >> 24) & 0xff);
;
183 if (ciphers)
184 PORT_FreePORT_Free_Util(ciphers);
185
186 offset = (unsigned short)offsetof(lgdbData, names)__builtin_offsetof(lgdbData, names);
187 LGDB_PUTSHORT(encoded->nameStart, offset)(encoded->nameStart)[1] = (unsigned char)((offset)&0xff
); (encoded->nameStart)[0] = (unsigned char)(((offset) >>
8) & 0xff);
;
188 offset = offset + len + len2 + len3 + 3 * sizeof(unsigned short);
189 LGDB_PUTSHORT(encoded->slotOffset, offset)(encoded->slotOffset)[1] = (unsigned char)((offset)&0xff
); (encoded->slotOffset)[0] = (unsigned char)(((offset) >>
8) & 0xff);
;
190
191 LGDB_PUTSHORT(&dataPtr[offset], ((unsigned short)count))(&dataPtr[offset])[1] = (unsigned char)((((unsigned short
)count))&0xff); (&dataPtr[offset])[0] = (unsigned char
)(((((unsigned short)count)) >> 8) & 0xff);
;
192 slot = (lgdbSlotData *)(dataPtr + offset + sizeof(unsigned short));
193
194 offsetPtr = encoded->names;
195 LGDB_PUTSHORT(encoded->names, len)(encoded->names)[1] = (unsigned char)((len)&0xff); (encoded
->names)[0] = (unsigned char)(((len) >> 8) & 0xff
);
;
196 offsetPtr += sizeof(unsigned short);
197 PORT_Memcpymemcpy(offsetPtr, commonName, len);
198 offsetPtr += len;
199
200 LGDB_PUTSHORT(offsetPtr, len2)(offsetPtr)[1] = (unsigned char)((len2)&0xff); (offsetPtr
)[0] = (unsigned char)(((len2) >> 8) & 0xff);
;
201 offsetPtr += sizeof(unsigned short);
202 if (len2) {
203 PORT_Memcpymemcpy(offsetPtr, dllName, len2);
204 }
205 offsetPtr += len2;
206
207 LGDB_PUTSHORT(offsetPtr, len3)(offsetPtr)[1] = (unsigned char)((len3)&0xff); (offsetPtr
)[0] = (unsigned char)(((len3) >> 8) & 0xff);
;
208 offsetPtr += sizeof(unsigned short);
209 if (len3) {
210 PORT_Memcpymemcpy(offsetPtr, param, len3);
211 }
212 offsetPtr += len3;
Value stored to 'offsetPtr' is never read
213
214 if (count) {
215 for (i = 0; i < count; i++) {
216 LGDB_PUTLONG(slot[i].slotID, slotInfo[i].slotID)(slot[i].slotID)[3] = (unsigned char)((slotInfo[i].slotID)&
0xff); (slot[i].slotID)[2] = (unsigned char)(((slotInfo[i].slotID
) >> 8) & 0xff); (slot[i].slotID)[1] = (unsigned char
)(((slotInfo[i].slotID) >> 16) & 0xff); (slot[i].slotID
)[0] = (unsigned char)(((slotInfo[i].slotID) >> 24) &
0xff);
;
217 LGDB_PUTLONG(slot[i].defaultFlags,(slot[i].defaultFlags)[3] = (unsigned char)((slotInfo[i].defaultFlags
)&0xff); (slot[i].defaultFlags)[2] = (unsigned char)(((slotInfo
[i].defaultFlags) >> 8) & 0xff); (slot[i].defaultFlags
)[1] = (unsigned char)(((slotInfo[i].defaultFlags) >> 16
) & 0xff); (slot[i].defaultFlags)[0] = (unsigned char)(((
slotInfo[i].defaultFlags) >> 24) & 0xff);
218 slotInfo[i].defaultFlags)(slot[i].defaultFlags)[3] = (unsigned char)((slotInfo[i].defaultFlags
)&0xff); (slot[i].defaultFlags)[2] = (unsigned char)(((slotInfo
[i].defaultFlags) >> 8) & 0xff); (slot[i].defaultFlags
)[1] = (unsigned char)(((slotInfo[i].defaultFlags) >> 16
) & 0xff); (slot[i].defaultFlags)[0] = (unsigned char)(((
slotInfo[i].defaultFlags) >> 24) & 0xff);
;
219 LGDB_PUTLONG(slot[i].timeout, slotInfo[i].timeout)(slot[i].timeout)[3] = (unsigned char)((slotInfo[i].timeout)&
0xff); (slot[i].timeout)[2] = (unsigned char)(((slotInfo[i].timeout
) >> 8) & 0xff); (slot[i].timeout)[1] = (unsigned char
)(((slotInfo[i].timeout) >> 16) & 0xff); (slot[i].timeout
)[0] = (unsigned char)(((slotInfo[i].timeout) >> 24) &
0xff);
;
220 slot[i].askpw = slotInfo[i].askpw;
221 slot[i].hasRootCerts = slotInfo[i].hasRootCerts;
222 PORT_Memsetmemset(slot[i].reserved, 0, sizeof(slot[i].reserved));
223 }
224 }
225 rv = SECSuccess;
226
227loser:
228 if (commonName)
229 PORT_FreePORT_Free_Util(commonName);
230 if (dllName)
231 PORT_FreePORT_Free_Util(dllName);
232 if (param)
233 PORT_FreePORT_Free_Util(param);
234 if (slotInfo)
235 PORT_FreePORT_Free_Util(slotInfo);
236 if (nss)
237 PORT_FreePORT_Free_Util(nss);
238 return rv;
239}
240
241static void
242lgdb_FreeData(DBT *data)
243{
244 if (data->data) {
245 PORT_FreePORT_Free_Util(data->data);
246 }
247}
248
249static void
250lgdb_FreeSlotStrings(char **slotStrings, int count)
251{
252 int i;
253
254 for (i = 0; i < count; i++) {
255 if (slotStrings[i]) {
256 PR_smprintf_free(slotStrings[i]);
257 slotStrings[i] = NULL((void*)0);
258 }
259 }
260}
261
262/*
263 * build a module from the data base entry.
264 */
265static char *
266lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
267{
268 lgdbData *encoded;
269 lgdbSlotData *slots;
270 PLArenaPool *arena;
271 char *commonName = NULL((void*)0);
272 char *dllName = NULL((void*)0);
273 char *parameters = NULL((void*)0);
274 char *nss;
275 char *moduleSpec;
276 char **slotStrings = NULL((void*)0);
277 unsigned char *names;
278 unsigned long slotCount;
279 unsigned long ssl0 = 0;
280 unsigned long ssl1 = 0;
281 unsigned long slotID;
282 unsigned long defaultFlags;
283 unsigned long timeout;
284 unsigned long trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER50;
285 unsigned long cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER0;
286 unsigned short len;
287 unsigned short namesOffset = 0; /* start of the names block */
288 unsigned long namesRunningOffset; /* offset to name we are
289 * currently processing */
290 unsigned short slotOffset;
291 PRBool isOldVersion = PR_FALSE0;
292 PRBool internal;
293 PRBool isFIPS;
294 PRBool isModuleDB = PR_FALSE0;
295 PRBool isModuleDBOnly = PR_FALSE0;
296 PRBool extended = PR_FALSE0;
297 int i;
298
299 arena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048));
300 if (arena == NULL((void*)0))
301 return NULL((void*)0);
302
303#define CHECK_SIZE(x)if ((unsigned int)data->size < (unsigned int)(x)) goto db_loser \
304 if ((unsigned int)data->size < (unsigned int)(x)) \
305 goto db_loser
306
307 /* -------------------------------------------------------------
308 ** Process the buffer header, which is the lgdbData struct.
309 ** It may be an old or new version. Check the length for each.
310 */
311
312 CHECK_SIZE(offsetof(lgdbData, trustOrder[0]))if ((unsigned int)data->size < (unsigned int)(__builtin_offsetof
(lgdbData, trustOrder[0]))) goto db_loser
;
313
314 encoded = (lgdbData *)data->data;
315
316 internal = (encoded->internal != 0) ? PR_TRUE1 : PR_FALSE0;
317 isFIPS = (encoded->fips != 0) ? PR_TRUE1 : PR_FALSE0;
318
319 if (retInternal)
320 *retInternal = internal;
321 if (internal) {
322 parameters = PORT_ArenaStrdupPORT_ArenaStrdup_Util(arena, defParams);
323 if (parameters == NULL((void*)0))
324 goto loser;
325 }
326 if (internal && (encoded->major == LGDB_DB_NOUI_VERSION_MAJOR0) &&
327 (encoded->minor <= LGDB_DB_NOUI_VERSION_MINOR4)) {
328 isOldVersion = PR_TRUE1;
329 }
330 if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR0) &&
331 (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR6)) {
332 CHECK_SIZE(sizeof(lgdbData))if ((unsigned int)data->size < (unsigned int)(sizeof(lgdbData
))) goto db_loser
;
333 trustOrder = LGDB_GETLONG(encoded->trustOrder)((unsigned long)(((unsigned long)(encoded->trustOrder)[0] <<
24) | ((unsigned long)(encoded->trustOrder)[1] << 16
) | ((unsigned long)(encoded->trustOrder)[2] << 8) |
(unsigned long)(encoded->trustOrder)[3]))
;
334 cipherOrder = LGDB_GETLONG(encoded->cipherOrder)((unsigned long)(((unsigned long)(encoded->cipherOrder)[0]
<< 24) | ((unsigned long)(encoded->cipherOrder)[1] <<
16) | ((unsigned long)(encoded->cipherOrder)[2] << 8
) | (unsigned long)(encoded->cipherOrder)[3]))
;
335 isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE1 : PR_FALSE0;
336 isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE1 : PR_FALSE0;
337 extended = PR_TRUE1;
338 }
339 if (internal && !extended) {
340 trustOrder = 0;
341 cipherOrder = 100;
342 }
343 /* decode SSL cipher enable flags */
344 ssl0 = LGDB_GETLONG(encoded->ssl)((unsigned long)(((unsigned long)(encoded->ssl)[0] <<
24) | ((unsigned long)(encoded->ssl)[1] << 16) | ((
unsigned long)(encoded->ssl)[2] << 8) | (unsigned long
)(encoded->ssl)[3]))
;
345 ssl1 = LGDB_GETLONG(encoded->ssl + 4)((unsigned long)(((unsigned long)(encoded->ssl + 4)[0] <<
24) | ((unsigned long)(encoded->ssl + 4)[1] << 16) |
((unsigned long)(encoded->ssl + 4)[2] << 8) | (unsigned
long)(encoded->ssl + 4)[3]))
;
346
347 slotOffset = LGDB_GETSHORT(encoded->slotOffset)((unsigned short)(((encoded->slotOffset)[0] << 8) | (
encoded->slotOffset)[1]))
;
348 namesOffset = LGDB_GETSHORT(encoded->nameStart)((unsigned short)(((encoded->nameStart)[0] << 8) | (
encoded->nameStart)[1]))
;
349
350 /*--------------------------------------------------------------
351 ** Now process the variable length set of names.
352 ** The names have this structure:
353 ** struct {
354 ** BYTE commonNameLen[ 2 ];
355 ** BYTE commonName [ commonNameLen ];
356 ** BTTE libNameLen [ 2 ];
357 ** BYTE libName [ libNameLen ];
358 ** If it is "extended" it also has these members:
359 ** BYTE initStringLen[ 2 ];
360 ** BYTE initString [ initStringLen ];
361 ** }
362 */
363
364 namesRunningOffset = namesOffset;
365 /* copy the module's common name */
366 CHECK_SIZE(namesRunningOffset + 2)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2)) goto db_loser
;
367 names = (unsigned char *)data->data;
368 len = LGDB_GETSHORT(names + namesRunningOffset)((unsigned short)(((names + namesRunningOffset)[0] << 8
) | (names + namesRunningOffset)[1]))
;
369
370 CHECK_SIZE(namesRunningOffset + 2 + len)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2 + len)) goto db_loser
;
371 commonName = (char *)PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, len + 1);
372 if (commonName == NULL((void*)0))
373 goto loser;
374 PORT_Memcpymemcpy(commonName, names + namesRunningOffset + 2, len);
375 commonName[len] = 0;
376 namesRunningOffset += len + 2;
377
378 /* copy the module's shared library file name. */
379 CHECK_SIZE(namesRunningOffset + 2)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2)) goto db_loser
;
380 len = LGDB_GETSHORT(names + namesRunningOffset)((unsigned short)(((names + namesRunningOffset)[0] << 8
) | (names + namesRunningOffset)[1]))
;
381 if (len) {
382 CHECK_SIZE(namesRunningOffset + 2 + len)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2 + len)) goto db_loser
;
383 dllName = (char *)PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, len + 1);
384 if (dllName == NULL((void*)0))
385 goto loser;
386 PORT_Memcpymemcpy(dllName, names + namesRunningOffset + 2, len);
387 dllName[len] = 0;
388 }
389 namesRunningOffset += len + 2;
390
391 /* copy the module's initialization string, if present. */
392 if (!internal && extended) {
393 CHECK_SIZE(namesRunningOffset + 2)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2)) goto db_loser
;
394 len = LGDB_GETSHORT(names + namesRunningOffset)((unsigned short)(((names + namesRunningOffset)[0] << 8
) | (names + namesRunningOffset)[1]))
;
395 if (len) {
396 CHECK_SIZE(namesRunningOffset + 2 + len)if ((unsigned int)data->size < (unsigned int)(namesRunningOffset
+ 2 + len)) goto db_loser
;
397 parameters = (char *)PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, len + 1);
398 if (parameters == NULL((void*)0))
399 goto loser;
400 PORT_Memcpymemcpy(parameters, names + namesRunningOffset + 2, len);
401 parameters[len] = 0;
402 }
403 namesRunningOffset += len + 2;
404 }
405
406 /*
407 * Consistency check: Make sure the slot and names blocks don't
408 * overlap. These blocks can occur in any order, so this check is made
409 * in 2 parts. First we check the case where the slot block starts
410 * after the name block. Later, when we have the slot block length,
411 * we check the case where slot block starts before the name block.
412 * NOTE: in most cases any overlap will likely be detected by invalid
413 * data read from the blocks, but it's better to find out sooner
414 * than later.
415 */
416 if (slotOffset >= namesOffset) { /* slot block starts after name block */
417 if (slotOffset < namesRunningOffset) {
418 goto db_loser;
419 }
420 }
421
422 /* ------------------------------------------------------------------
423 ** Part 3, process the slot table.
424 ** This part has this structure:
425 ** struct {
426 ** BYTE slotCount [ 2 ];
427 ** lgdbSlotData [ slotCount ];
428 ** {
429 */
430
431 CHECK_SIZE(slotOffset + 2)if ((unsigned int)data->size < (unsigned int)(slotOffset
+ 2)) goto db_loser
;
432 slotCount = LGDB_GETSHORT((unsigned char *)data->data + slotOffset)((unsigned short)((((unsigned char *)data->data + slotOffset
)[0] << 8) | ((unsigned char *)data->data + slotOffset
)[1]))
;
433
434 /*
435 * Consistency check: Part 2. We now have the slot block length, we can
436 * check the case where the slotblock procedes the name block.
437 */
438 if (slotOffset < namesOffset) { /* slot block starts before name block */
439 if (namesOffset < slotOffset + 2 + slotCount * sizeof(lgdbSlotData)) {
440 goto db_loser;
441 }
442 }
443
444 CHECK_SIZE((slotOffset + 2 + slotCount * sizeof(lgdbSlotData)))if ((unsigned int)data->size < (unsigned int)((slotOffset
+ 2 + slotCount * sizeof(lgdbSlotData)))) goto db_loser
;
445 slots = (lgdbSlotData *)((unsigned char *)data->data + slotOffset + 2);
446
447 /* slotCount; */
448 slotStrings = (char **)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, slotCount * sizeof(char *));
449 if (slotStrings == NULL((void*)0))
450 goto loser;
451 for (i = 0; i < (int)slotCount; i++, slots++) {
452 PRBool hasRootCerts = PR_FALSE0;
453 PRBool hasRootTrust = PR_FALSE0;
454 slotID = LGDB_GETLONG(slots->slotID)((unsigned long)(((unsigned long)(slots->slotID)[0] <<
24) | ((unsigned long)(slots->slotID)[1] << 16) | (
(unsigned long)(slots->slotID)[2] << 8) | (unsigned long
)(slots->slotID)[3]))
;
455 defaultFlags = LGDB_GETLONG(slots->defaultFlags)((unsigned long)(((unsigned long)(slots->defaultFlags)[0] <<
24) | ((unsigned long)(slots->defaultFlags)[1] << 16
) | ((unsigned long)(slots->defaultFlags)[2] << 8) |
(unsigned long)(slots->defaultFlags)[3]))
;
456 timeout = LGDB_GETLONG(slots->timeout)((unsigned long)(((unsigned long)(slots->timeout)[0] <<
24) | ((unsigned long)(slots->timeout)[1] << 16) | (
(unsigned long)(slots->timeout)[2] << 8) | (unsigned
long)(slots->timeout)[3]))
;
457 hasRootCerts = slots->hasRootCerts;
458 if (isOldVersion && internal && (slotID != 2)) {
459 unsigned long internalFlags =
460 NSSUTIL_ArgParseSlotFlags("slotFlags",
461 NSSUTIL_DEFAULT_SFTKN_FLAGS"slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]");
462 defaultFlags |= internalFlags;
463 }
464 if (hasRootCerts && !extended) {
465 trustOrder = 100;
466 }
467
468 slotStrings[i] = NSSUTIL_MkSlotString(slotID, defaultFlags, timeout,
469 (unsigned char)slots->askpw,
470 hasRootCerts, hasRootTrust);
471 if (slotStrings[i] == NULL((void*)0)) {
472 lgdb_FreeSlotStrings(slotStrings, i);
473 goto loser;
474 }
475 }
476
477 nss = NSSUTIL_MkNSSString(slotStrings, slotCount, internal, isFIPS,
478 isModuleDB, isModuleDBOnly, internal, trustOrder,
479 cipherOrder, ssl0, ssl1);
480 lgdb_FreeSlotStrings(slotStrings, slotCount);
481 /* it's permissible (and normal) for nss to be NULL. it simply means
482 * there are no NSS specific parameters in the database */
483 moduleSpec = NSSUTIL_MkModuleSpec(dllName, commonName, parameters, nss);
484 PR_smprintf_free(nss);
485 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
486 return moduleSpec;
487
488db_loser:
489 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_DATABASE);
490loser:
491 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
492 return NULL((void*)0);
493}
494
495static DB *
496lgdb_OpenDB(const char *appName, const char *filename, const char *dbName,
497 PRBool readOnly, PRBool update)
498{
499 DB *pkcs11db = NULL((void*)0);
500
501 if (appName) {
502 char *secname = PORT_StrdupPORT_Strdup_Util(filename);
503 int len = strlen(secname);
504 int status = RDB_FAIL1;
505
506 if (len >= 3 && PORT_Strcmpstrcmp(&secname[len - 3], ".db") == 0) {
507 secname[len - 3] = 0;
508 }
509 pkcs11db =
510 rdbopen(appName, "", secname, readOnly ? NO_RDONLY00 : NO_RDWR02, NULL((void*)0));
511 if (update && !pkcs11db) {
512 DB *updatedb;
513
514 pkcs11db = rdbopen(appName, "", secname, NO_CREATE(02 | 0100 | 01000), &status);
515 if (!pkcs11db) {
516 if (status == RDB_RETRY2) {
517 pkcs11db = rdbopen(appName, "", secname,
518 readOnly ? NO_RDONLY00 : NO_RDWR02, NULL((void*)0));
519 }
520 PORT_FreePORT_Free_Util(secname);
521 return pkcs11db;
522 }
523 updatedb = dbopen(dbName, NO_RDONLY00, 0600, DB_HASH, 0);
524 if (updatedb) {
525 db_Copy(pkcs11db, updatedb);
526 (*updatedb->close)(updatedb);
527 } else {
528 (*pkcs11db->close)(pkcs11db);
529 PORT_FreePORT_Free_Util(secname);
530 return NULL((void*)0);
531 }
532 }
533 PORT_FreePORT_Free_Util(secname);
534 return pkcs11db;
535 }
536
537 /* I'm sure we should do more checks here sometime... */
538 pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY00 : NO_RDWR02, 0600, DB_HASH, 0);
539
540 /* didn't exist? create it */
541 if (pkcs11db == NULL((void*)0)) {
542 if (readOnly)
543 return NULL((void*)0);
544
545 pkcs11db = dbopen(dbName, NO_CREATE(02 | 0100 | 01000), 0600, DB_HASH, 0);
546 if (pkcs11db)
547 (*pkcs11db->sync)(pkcs11db, 0);
548 }
549 return pkcs11db;
550}
551
552static void
553lgdb_CloseDB(DB *pkcs11db)
554{
555 (*pkcs11db->close)(pkcs11db);
556}
557
558SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
559 const char *dbname, char *module, PRBool rw);
560
561#define LGDB_STEP10 10
562/*
563 * Read all the existing modules in
564 */
565char **
566legacy_ReadSecmodDB(const char *appName, const char *filename,
567 const char *dbname, char *params, PRBool rw)
568{
569 DBT key, data;
570 int ret;
571 DB *pkcs11db = NULL((void*)0);
572 char **moduleList = NULL((void*)0), **newModuleList = NULL((void*)0);
573 int moduleCount = 1;
574 int useCount = LGDB_STEP10;
575
576 moduleList = (char **)PORT_ZAllocPORT_ZAlloc_Util(useCount * sizeof(char **));
577 if (moduleList == NULL((void*)0))
578 return NULL((void*)0);
579
580 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_TRUE1, rw);
581 if (pkcs11db == NULL((void*)0))
582 goto done;
583
584 /* read and parse the file or data base */
585 ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST3);
586 if (ret)
587 goto done;
588
589 do {
590 char *moduleString;
591 PRBool internal = PR_FALSE0;
592 if ((moduleCount + 1) >= useCount) {
593 useCount += LGDB_STEP10;
594 newModuleList =
595 (char **)PORT_ReallocPORT_Realloc_Util(moduleList, useCount * sizeof(char *));
596 if (newModuleList == NULL((void*)0))
597 goto done;
598 moduleList = newModuleList;
599 PORT_Memsetmemset(&moduleList[moduleCount + 1], 0,
600 sizeof(char *) * LGDB_STEP10);
601 }
602 moduleString = lgdb_DecodeData(params, &data, &internal);
603 if (internal) {
604 moduleList[0] = moduleString;
605 } else {
606 moduleList[moduleCount] = moduleString;
607 moduleCount++;
608 }
609 } while ((*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT7) == 0);
610
611done:
612 if (!moduleList[0]) {
613 char *newparams = NSSUTIL_Quote(params, '"');
614 if (newparams) {
615 moduleList[0] = PR_smprintf(
616 NSSUTIL_DEFAULT_INTERNAL_INIT1"library= name=\"NSS Internal PKCS #11 Module\" parameters=" "%s" NSSUTIL_DEFAULT_INTERNAL_INIT2" NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={" "%s" NSSUTIL_DEFAULT_INTERNAL_INIT3" askpw=any timeout=30})\"",
617 newparams, NSSUTIL_DEFAULT_SFTKN_FLAGS"slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]");
618 PORT_FreePORT_Free_Util(newparams);
619 }
620 }
621 /* deal with trust cert db here */
622
623 if (pkcs11db) {
624 lgdb_CloseDB(pkcs11db);
625 } else if (moduleList[0] && rw) {
626 legacy_AddSecmodDB(appName, filename, dbname, moduleList[0], rw);
627 }
628 if (!moduleList[0]) {
629 PORT_FreePORT_Free_Util(moduleList);
630 moduleList = NULL((void*)0);
631 }
632 return moduleList;
633}
634
635SECStatus
636legacy_ReleaseSecmodDBData(const char *appName, const char *filename,
637 const char *dbname, char **moduleSpecList, PRBool rw)
638{
639 if (moduleSpecList) {
640 char **index;
641 for (index = moduleSpecList; *index; index++) {
642 PR_smprintf_free(*index);
643 }
644 PORT_FreePORT_Free_Util(moduleSpecList);
645 }
646 return SECSuccess;
647}
648
649/*
650 * Delete a module from the Data Base
651 */
652SECStatus
653legacy_DeleteSecmodDB(const char *appName, const char *filename,
654 const char *dbname, char *args, PRBool rw)
655{
656 DBT key;
657 SECStatus rv = SECFailure;
658 DB *pkcs11db = NULL((void*)0);
659 int ret;
660
661 if (!rw)
662 return SECFailure;
663
664 /* make sure we have a db handle */
665 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE0, PR_FALSE0);
666 if (pkcs11db == NULL((void*)0)) {
667 return SECFailure;
668 }
669
670 rv = lgdb_MakeKey(&key, args);
671 if (rv != SECSuccess)
672 goto done;
673 rv = SECFailure;
674 ret = (*pkcs11db->del)(pkcs11db, &key, 0);
675 lgdb_FreeKey(&key);
676 if (ret != 0)
677 goto done;
678
679 ret = (*pkcs11db->sync)(pkcs11db, 0);
680 if (ret == 0)
681 rv = SECSuccess;
682
683done:
684 lgdb_CloseDB(pkcs11db);
685 return rv;
686}
687
688/*
689 * Add a module to the Data base
690 */
691SECStatus
692legacy_AddSecmodDB(const char *appName, const char *filename,
693 const char *dbname, char *module, PRBool rw)
694{
695 DBT key, data;
696 SECStatus rv = SECFailure;
697 DB *pkcs11db = NULL((void*)0);
698 int ret;
699
700 if (!rw)
701 return SECFailure;
702
703 /* make sure we have a db handle */
704 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE0, PR_FALSE0);
705 if (pkcs11db == NULL((void*)0)) {
706 return SECFailure;
707 }
708
709 rv = lgdb_MakeKey(&key, module);
710 if (rv != SECSuccess)
711 goto done;
712 rv = lgdb_EncodeData(&data, module);
713 if (rv != SECSuccess) {
714 lgdb_FreeKey(&key);
715 goto done;
716 }
717 rv = SECFailure;
718 ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0);
719 lgdb_FreeKey(&key);
720 lgdb_FreeData(&data);
721 if (ret != 0)
722 goto done;
723
724 ret = (*pkcs11db->sync)(pkcs11db, 0);
725 if (ret == 0)
726 rv = SECSuccess;
727
728done:
729 lgdb_CloseDB(pkcs11db);
730 return rv;
731}