OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 /* | 4 /* |
5 * The following handles the loading, unloading and management of | 5 * The following handles the loading, unloading and management of |
6 * various PCKS #11 modules | 6 * various PCKS #11 modules |
7 */ | 7 */ |
8 | 8 |
9 #include <ctype.h> | 9 #include <ctype.h> |
10 #include "pkcs11.h" | 10 #include "pkcs11.h" |
11 #include "seccomon.h" | 11 #include "seccomon.h" |
12 #include "secmod.h" | 12 #include "secmod.h" |
13 #include "secmodi.h" | 13 #include "secmodi.h" |
14 #include "secmodti.h" | 14 #include "secmodti.h" |
15 #include "pki3hack.h" | 15 #include "pki3hack.h" |
16 #include "secerr.h" | 16 #include "secerr.h" |
17 | 17 |
18 #include "utilpars.h" | 18 #include "utilpars.h" |
19 | 19 |
20 /* create a new module */ | 20 /* create a new module */ |
21 static SECMODModule * | 21 static SECMODModule *secmod_NewModule(void) { |
22 secmod_NewModule(void) | 22 SECMODModule *newMod; |
23 { | 23 PLArenaPool *arena; |
24 SECMODModule *newMod; | 24 |
25 PLArenaPool *arena; | 25 /* create an arena in which dllName and commonName can be |
26 | 26 * allocated. |
27 | 27 */ |
28 /* create an arena in which dllName and commonName can be | 28 arena = PORT_NewArena(512); |
29 * allocated. | 29 if (arena == NULL) { |
30 */ | 30 return NULL; |
31 arena = PORT_NewArena(512); | 31 } |
32 if (arena == NULL) { | 32 |
33 » return NULL; | 33 newMod = (SECMODModule *)PORT_ArenaAlloc(arena, sizeof(SECMODModule)); |
34 } | 34 if (newMod == NULL) { |
35 | 35 PORT_FreeArena(arena, PR_FALSE); |
36 newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule)); | 36 return NULL; |
37 if (newMod == NULL) { | 37 } |
38 » PORT_FreeArena(arena,PR_FALSE); | 38 |
39 » return NULL; | 39 /* |
40 } | 40 * initialize of the fields of the module |
41 | 41 */ |
42 /* | 42 newMod->arena = arena; |
43 * initialize of the fields of the module | 43 newMod->internal = PR_FALSE; |
44 */ | 44 newMod->loaded = PR_FALSE; |
45 newMod->arena = arena; | 45 newMod->isFIPS = PR_FALSE; |
46 newMod->internal = PR_FALSE; | 46 newMod->dllName = NULL; |
47 newMod->loaded = PR_FALSE; | 47 newMod->commonName = NULL; |
48 newMod->isFIPS = PR_FALSE; | 48 newMod->library = NULL; |
49 newMod->dllName = NULL; | 49 newMod->functionList = NULL; |
50 newMod->commonName = NULL; | 50 newMod->slotCount = 0; |
51 newMod->library = NULL; | 51 newMod->slots = NULL; |
52 newMod->functionList = NULL; | 52 newMod->slotInfo = NULL; |
53 newMod->slotCount = 0; | 53 newMod->slotInfoCount = 0; |
54 newMod->slots = NULL; | 54 newMod->refCount = 1; |
55 newMod->slotInfo = NULL; | 55 newMod->ssl[0] = 0; |
56 newMod->slotInfoCount = 0; | 56 newMod->ssl[1] = 0; |
57 newMod->refCount = 1; | 57 newMod->libraryParams = NULL; |
58 newMod->ssl[0] = 0; | 58 newMod->moduleDBFunc = NULL; |
59 newMod->ssl[1] = 0; | 59 newMod->parent = NULL; |
60 newMod->libraryParams = NULL; | 60 newMod->isCritical = PR_FALSE; |
61 newMod->moduleDBFunc = NULL; | 61 newMod->isModuleDB = PR_FALSE; |
62 newMod->parent = NULL; | 62 newMod->moduleDBOnly = PR_FALSE; |
63 newMod->isCritical = PR_FALSE; | 63 newMod->trustOrder = 0; |
64 newMod->isModuleDB = PR_FALSE; | 64 newMod->cipherOrder = 0; |
65 newMod->moduleDBOnly = PR_FALSE; | 65 newMod->evControlMask = 0; |
66 newMod->trustOrder = 0; | 66 newMod->refLock = PZ_NewLock(nssILockRefLock); |
67 newMod->cipherOrder = 0; | 67 if (newMod->refLock == NULL) { |
68 newMod->evControlMask = 0; | 68 PORT_FreeArena(arena, PR_FALSE); |
69 newMod->refLock = PZ_NewLock(nssILockRefLock); | 69 return NULL; |
70 if (newMod->refLock == NULL) { | 70 } |
71 » PORT_FreeArena(arena,PR_FALSE); | 71 return newMod; |
72 » return NULL; | |
73 } | |
74 return newMod; | |
75 ···· | |
76 } | 72 } |
77 | 73 |
78 /* private flags for isModuleDB (field in SECMODModule). */ | 74 /* private flags for isModuleDB (field in SECMODModule). */ |
79 /* The meaing of these flags is as follows: | 75 /* The meaing of these flags is as follows: |
80 * | 76 * |
81 * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the | 77 * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the |
82 * database of other modules to load. Module DBs are loadable modules that | 78 * database of other modules to load. Module DBs are loadable modules that |
83 * tells NSS which PKCS #11 modules to load and when. These module DBs are | 79 * tells NSS which PKCS #11 modules to load and when. These module DBs are |
84 * chainable. That is, one module DB can load another one. NSS system init | 80 * chainable. That is, one module DB can load another one. NSS system init |
85 * design takes advantage of this feature. In system NSS, a fixed system | 81 * design takes advantage of this feature. In system NSS, a fixed system |
86 * module DB loads the system defined libraries, then chains out to the | 82 * module DB loads the system defined libraries, then chains out to the |
87 * traditional module DBs to load any system or user configured modules | 83 * traditional module DBs to load any system or user configured modules |
88 * (like smart cards). This bit is the same as the already existing meaning | 84 * (like smart cards). This bit is the same as the already existing meaning |
89 * of isModuleDB = PR_TRUE. None of the other module db flags should be set· | 85 * of isModuleDB = PR_TRUE. None of the other module db flags should be set |
90 * if this flag isn't on. | 86 * if this flag isn't on. |
91 * | 87 * |
92 * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first | 88 * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first |
93 * PKCS #11 module presented by a module DB. This allows the OS to load a | 89 * PKCS #11 module presented by a module DB. This allows the OS to load a |
94 * softoken from the system module, then ask the existing module DB code to | 90 * softoken from the system module, then ask the existing module DB code to |
95 * load the other PKCS #11 modules in that module DB (skipping it's request | 91 * load the other PKCS #11 modules in that module DB (skipping it's request |
96 * to load softoken). This gives the system init finer control over the | 92 * to load softoken). This gives the system init finer control over the |
97 * configuration of that softoken module. | 93 * configuration of that softoken module. |
98 * | 94 * |
99 * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a | 95 * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a |
100 * different module DB as the 'default' module DB (the one in which | 96 * different module DB as the 'default' module DB (the one in which |
101 * 'Add module' changes will go). Without this flag NSS takes the first | 97 * 'Add module' changes will go). Without this flag NSS takes the first |
102 * module as the default Module DB, but in system NSS, that first module | 98 * module as the default Module DB, but in system NSS, that first module |
103 * is the system module, which is likely read only (at least to the user). | 99 * is the system module, which is likely read only (at least to the user). |
104 * This allows system NSS to delegate those changes to the user's module DB, | 100 * This allows system NSS to delegate those changes to the user's module DB, |
105 * preserving the user's ability to load new PKCS #11 modules (which only | 101 * preserving the user's ability to load new PKCS #11 modules (which only |
106 * affect him), from existing applications like Firefox. | 102 * affect him), from existing applications like Firefox. |
107 */ | 103 */ |
108 #define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB 0x01 /* must be set if any of the· | 104 #define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB \ |
109 » » » » » » *other flags are set */ | 105 0x01 /* must be set if any of the \ |
110 #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02 | 106 *other flags are set */ |
| 107 #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02 |
111 #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04 | 108 #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04 |
112 | 109 |
113 | |
114 /* private flags for internal (field in SECMODModule). */ | 110 /* private flags for internal (field in SECMODModule). */ |
115 /* The meaing of these flags is as follows: | 111 /* The meaing of these flags is as follows: |
116 * | 112 * |
117 * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is | 113 * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is |
118 * the internal module (that is, softoken). This bit is the same as the | 114 * the internal module (that is, softoken). This bit is the same as the |
119 * already existing meaning of internal = PR_TRUE. None of the other | 115 * already existing meaning of internal = PR_TRUE. None of the other |
120 * internal flags should be set if this flag isn't on. | 116 * internal flags should be set if this flag isn't on. |
121 * | 117 * |
122 * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark | 118 * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark |
123 * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary' | 119 * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary' |
124 * slot defined by this module will be the new internal key slot. | 120 * slot defined by this module will be the new internal key slot. |
125 */ | 121 */ |
126 #define SECMOD_FLAG_INTERNAL_IS_INTERNAL 0x01 /* must be set if any of· | 122 #define SECMOD_FLAG_INTERNAL_IS_INTERNAL \ |
127 » » » » » » *the other flags are set */ | 123 0x01 /* must be set if any of \ |
128 #define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02 | 124 *the other flags are set */ |
| 125 #define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02 |
129 | 126 |
130 /* | 127 /* |
131 * for 3.4 we continue to use the old SECMODModule structure | 128 * for 3.4 we continue to use the old SECMODModule structure |
132 */ | 129 */ |
133 SECMODModule * | 130 SECMODModule *SECMOD_CreateModule(const char *library, const char *moduleName, |
134 SECMOD_CreateModule(const char *library, const char *moduleName,· | 131 const char *parameters, const char *nss) { |
135 » » » » const char *parameters, const char *nss) | 132 SECMODModule *mod = secmod_NewModule(); |
136 { | 133 char *slotParams, *ciphers; |
137 SECMODModule *mod = secmod_NewModule(); | 134 /* pk11pars.h still does not have const char * interfaces */ |
138 char *slotParams,*ciphers; | 135 char *nssc = (char *)nss; |
139 /* pk11pars.h still does not have const char * interfaces */ | 136 if (mod == NULL) return NULL; |
140 char *nssc = (char *)nss; | 137 |
141 if (mod == NULL) return NULL; | 138 mod->commonName = PORT_ArenaStrdup(mod->arena, moduleName ? moduleName : ""); |
142 | 139 if (library) { |
143 mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : ""); | 140 mod->dllName = PORT_ArenaStrdup(mod->arena, library); |
144 if (library) { | 141 } |
145 » mod->dllName = PORT_ArenaStrdup(mod->arena,library); | 142 /* new field */ |
146 } | 143 if (parameters) { |
147 /* new field */ | 144 mod->libraryParams = PORT_ArenaStrdup(mod->arena, parameters); |
148 if (parameters) { | 145 } |
149 » mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters); | 146 mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nssc); |
150 } | 147 mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nssc); |
151 mod->internal = NSSUTIL_ArgHasFlag("flags","internal",nssc); | 148 mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nssc); |
152 mod->isFIPS = NSSUTIL_ArgHasFlag("flags","FIPS",nssc); | 149 slotParams = NSSUTIL_ArgGetParamValue("slotParams", nssc); |
153 mod->isCritical = NSSUTIL_ArgHasFlag("flags","critical",nssc); | 150 mod->slotInfo = |
154 slotParams = NSSUTIL_ArgGetParamValue("slotParams",nssc); | 151 NSSUTIL_ArgParseSlotInfo(mod->arena, slotParams, &mod->slotInfoCount); |
155 mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena,slotParams, | 152 if (slotParams) PORT_Free(slotParams); |
156 » » » » » » » &mod->slotInfoCount); | 153 /* new field */ |
157 if (slotParams) PORT_Free(slotParams); | 154 mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nssc, |
158 /* new field */ | 155 NSSUTIL_DEFAULT_TRUST_ORDER, NULL); |
159 mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder",nssc, | 156 /* new field */ |
160 » » » » » NSSUTIL_DEFAULT_TRUST_ORDER,NULL); | 157 mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nssc, |
161 /* new field */ | 158 NSSUTIL_DEFAULT_CIPHER_ORDER, NULL); |
162 mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder",nssc, | 159 /* new field */ |
163 » » » » » NSSUTIL_DEFAULT_CIPHER_ORDER,NULL); | 160 mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nssc); |
164 /* new field */ | 161 mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nssc); |
165 mod->isModuleDB = NSSUTIL_ArgHasFlag("flags","moduleDB",nssc); | 162 if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE; |
166 mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags","moduleDBOnly",nssc); | 163 |
167 if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE; | 164 /* we need more bits, but we also want to preserve binary compatibility |
168 | 165 * so we overload the isModuleDB PRBool with additional flags. |
169 /* we need more bits, but we also want to preserve binary compatibility· | 166 * These flags are only valid if mod->isModuleDB is already set. |
170 * so we overload the isModuleDB PRBool with additional flags.· | 167 * NOTE: this depends on the fact that PRBool is at least a char on |
171 * These flags are only valid if mod->isModuleDB is already set. | 168 * all platforms. These flags are only valid if moduleDB is set, so |
172 * NOTE: this depends on the fact that PRBool is at least a char on· | 169 * code checking if (mod->isModuleDB) will continue to work correctly. */ |
173 * all platforms. These flags are only valid if moduleDB is set, so· | 170 if (mod->isModuleDB) { |
174 * code checking if (mod->isModuleDB) will continue to work correctly. */ | 171 char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB; |
175 if (mod->isModuleDB) { | 172 if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nssc)) { |
176 » char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB; | 173 flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST; |
177 » if (NSSUTIL_ArgHasFlag("flags","skipFirst",nssc)) { | 174 } |
178 » flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST; | 175 if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nssc)) { |
179 » } | 176 flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB; |
180 » if (NSSUTIL_ArgHasFlag("flags","defaultModDB",nssc)) { | 177 } |
181 » flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB; | 178 /* additional moduleDB flags could be added here in the future */ |
182 » } | 179 mod->isModuleDB = (PRBool)flags; |
183 » /* additional moduleDB flags could be added here in the future */ | 180 } |
184 » mod->isModuleDB = (PRBool) flags; | 181 |
185 } | 182 if (mod->internal) { |
186 | 183 char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL; |
187 if (mod->internal) { | 184 |
188 » char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL; | 185 if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) { |
189 | 186 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; |
190 » if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) { | 187 } |
191 » flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; | 188 mod->internal = (PRBool)flags; |
192 » } | 189 } |
193 » mod->internal = (PRBool) flags; | 190 |
194 } | 191 ciphers = NSSUTIL_ArgGetParamValue("ciphers", nssc); |
195 | 192 NSSUTIL_ArgParseCipherFlags(&mod->ssl[0], ciphers); |
196 ciphers = NSSUTIL_ArgGetParamValue("ciphers",nssc); | 193 if (ciphers) PORT_Free(ciphers); |
197 NSSUTIL_ArgParseCipherFlags(&mod->ssl[0],ciphers); | 194 |
198 if (ciphers) PORT_Free(ciphers); | 195 secmod_PrivateModuleCount++; |
199 | 196 |
200 secmod_PrivateModuleCount++; | 197 return mod; |
201 | 198 } |
202 return mod; | 199 |
203 } | 200 PRBool SECMOD_GetSkipFirstFlag(SECMODModule *mod) { |
204 | 201 char flags = (char)mod->isModuleDB; |
205 PRBool | 202 |
206 SECMOD_GetSkipFirstFlag(SECMODModule *mod) | 203 return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE; |
207 { | 204 } |
208 char flags = (char) mod->isModuleDB; | 205 |
209 | 206 PRBool SECMOD_GetDefaultModDBFlag(SECMODModule *mod) { |
210 return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE; | 207 char flags = (char)mod->isModuleDB; |
211 } | 208 |
212 | 209 return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE; |
213 PRBool | 210 } |
214 SECMOD_GetDefaultModDBFlag(SECMODModule *mod) | 211 |
215 { | 212 PRBool secmod_IsInternalKeySlot(SECMODModule *mod) { |
216 char flags = (char) mod->isModuleDB; | 213 char flags = (char)mod->internal; |
217 | 214 |
218 return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE; | 215 return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE; |
219 } | 216 } |
220 | 217 |
221 PRBool | 218 void secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val) { |
222 secmod_IsInternalKeySlot(SECMODModule *mod) | 219 char flags = (char)mod->internal; |
223 { | 220 |
224 char flags = (char) mod->internal; | 221 if (val) { |
225 | 222 flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; |
226 return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE; | 223 } else { |
227 } | 224 flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT; |
228 | 225 } |
229 void | 226 mod->internal = flags; |
230 secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val) | |
231 { | |
232 char flags = (char) mod->internal; | |
233 | |
234 if (val) { | |
235 » flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; | |
236 } else { | |
237 » flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT; | |
238 } | |
239 mod->internal = flags; | |
240 } | 227 } |
241 | 228 |
242 /* | 229 /* |
243 * copy desc and value into target. Target is known to be big enough to | 230 * copy desc and value into target. Target is known to be big enough to |
244 * hold desc +2 +value, which is good because the result of this will be | 231 * hold desc +2 +value, which is good because the result of this will be |
245 * *desc"*value". We may, however, have to add some escapes for special | 232 * *desc"*value". We may, however, have to add some escapes for special |
246 * characters imbedded into value (rare). This string potentially comes from | 233 * characters imbedded into value (rare). This string potentially comes from |
247 * a user, so we don't want the user overflowing the target buffer by using | 234 * a user, so we don't want the user overflowing the target buffer by using |
248 * excessive escapes. To prevent this we count the escapes we need to add and | 235 * excessive escapes. To prevent this we count the escapes we need to add and |
249 * try to expand the buffer with Realloc. | 236 * try to expand the buffer with Realloc. |
250 */ | 237 */ |
251 static char * | 238 static char *secmod_doDescCopy(char *target, int *targetLen, const char *desc, |
252 secmod_doDescCopy(char *target, int *targetLen, const char *desc, | 239 int descLen, char *value) { |
253 » » » int descLen, char *value) | 240 int diff, esc_len; |
254 { | 241 |
255 int diff, esc_len; | 242 esc_len = NSSUTIL_EscapeSize(value, '\"') - 1; |
256 | 243 diff = esc_len - strlen(value); |
257 esc_len = NSSUTIL_EscapeSize(value, '\"') - 1; | 244 if (diff > 0) { |
258 diff = esc_len - strlen(value); | 245 /* we need to escape... expand newSpecPtr as well to make sure |
259 if (diff > 0) { | 246 * we don't overflow it */ |
260 » /* we need to escape... expand newSpecPtr as well to make sure | 247 char *newPtr = PORT_Realloc(target, *targetLen * diff); |
261 » * we don't overflow it */ | 248 if (!newPtr) { |
262 » char *newPtr = PORT_Realloc(target, *targetLen * diff); | 249 return target; /* not enough space, just drop the whole copy */ |
263 » if (!newPtr) { | 250 } |
264 » return target; /* not enough space, just drop the whole copy */ | 251 *targetLen += diff; |
265 » } | 252 target = newPtr; |
266 » *targetLen += diff; | 253 value = NSSUTIL_Escape(value, '\"'); |
267 » target = newPtr; | 254 if (value == NULL) { |
268 » value = NSSUTIL_Escape(value, '\"'); | 255 return target; /* couldn't escape value, just drop the copy */ |
269 » if (value == NULL) { | 256 } |
270 » return target; /* couldn't escape value, just drop the copy */ | 257 } |
271 » } | 258 PORT_Memcpy(target, desc, descLen); |
272 } | 259 target += descLen; |
273 PORT_Memcpy(target, desc, descLen); | 260 *target++ = '\"'; |
274 target += descLen; | 261 PORT_Memcpy(target, value, esc_len); |
275 *target++='\"'; | 262 target += esc_len; |
276 PORT_Memcpy(target, value, esc_len); | 263 *target++ = '\"'; |
277 target += esc_len; | 264 if (diff > 0) { |
278 *target++='\"'; | 265 PORT_Free(value); |
279 if (diff > 0) { | 266 } |
280 » PORT_Free(value); | 267 return target; |
281 } | 268 } |
282 return target; | 269 |
283 } | 270 #define SECMOD_SPEC_COPY(new, start, end) \ |
284 | 271 if (end > start) { \ |
285 #define SECMOD_SPEC_COPY(new, start, end) \ | 272 int _cnt = end - start; \ |
286 if (end > start) { \ | 273 PORT_Memcpy(new, start, _cnt); \ |
287 » int _cnt = end - start;» \ | 274 new += _cnt; \ |
288 » PORT_Memcpy(new, start, _cnt); \ | |
289 » new += _cnt; \ | |
290 } | 275 } |
291 #define SECMOD_TOKEN_DESCRIPTION "tokenDescription=" | 276 #define SECMOD_TOKEN_DESCRIPTION "tokenDescription=" |
292 #define SECMOD_SLOT_DESCRIPTION "slotDescription=" | 277 #define SECMOD_SLOT_DESCRIPTION "slotDescription=" |
293 | 278 |
294 | 279 /* |
295 /* | 280 * Find any tokens= values in the module spec. |
296 * Find any tokens= values in the module spec. | |
297 * Always return a new spec which does not have any tokens= arguments. | 281 * Always return a new spec which does not have any tokens= arguments. |
298 * If tokens= arguments are found, Split the the various tokens defined into | 282 * If tokens= arguments are found, Split the the various tokens defined into |
299 * an array of child specs to return. | 283 * an array of child specs to return. |
300 * | 284 * |
301 * Caller is responsible for freeing the child spec and the new token | 285 * Caller is responsible for freeing the child spec and the new token |
302 * spec. | 286 * spec. |
303 */ | 287 */ |
304 char * | 288 char *secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS, |
305 secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,· | 289 char *moduleSpec, char ***children, |
306 » » » » char *moduleSpec, char ***children,· | 290 CK_SLOT_ID **ids) { |
307 » » » » CK_SLOT_ID **ids) | 291 int newSpecLen = PORT_Strlen(moduleSpec) + 2; |
308 { | 292 char *newSpec = PORT_Alloc(newSpecLen); |
309 int newSpecLen = PORT_Strlen(moduleSpec)+2; | 293 char *newSpecPtr = newSpec; |
310 char *newSpec = PORT_Alloc(newSpecLen); | 294 char *modulePrev = moduleSpec; |
311 char *newSpecPtr = newSpec; | 295 char *target = NULL; |
312 char *modulePrev = moduleSpec; | 296 char *tmp = NULL; |
313 char *target = NULL; | 297 char **childArray = NULL; |
314 char *tmp = NULL; | 298 char *tokenIndex; |
315 char **childArray = NULL; | 299 CK_SLOT_ID *idArray = NULL; |
316 char *tokenIndex; | 300 int tokenCount = 0; |
317 CK_SLOT_ID *idArray = NULL; | 301 int i; |
318 int tokenCount = 0; | 302 |
319 int i; | 303 if (newSpec == NULL) { |
320 | 304 return NULL; |
321 if (newSpec == NULL) { | 305 } |
322 » return NULL; | 306 |
323 } | 307 *children = NULL; |
324 | 308 if (ids) { |
325 *children = NULL; | 309 *ids = NULL; |
326 if (ids) { | 310 } |
327 » *ids = NULL; | 311 moduleSpec = NSSUTIL_ArgStrip(moduleSpec); |
328 } | 312 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); |
329 moduleSpec = NSSUTIL_ArgStrip(moduleSpec); | 313 |
| 314 /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening |
| 315 * a new softoken module takes the following parameters to name the |
| 316 * various tokens: |
| 317 * |
| 318 * cryptoTokenDescription: name of the non-fips crypto token. |
| 319 * cryptoSlotDescription: name of the non-fips crypto slot. |
| 320 * dbTokenDescription: name of the non-fips db token. |
| 321 * dbSlotDescription: name of the non-fips db slot. |
| 322 * FIPSTokenDescription: name of the fips db/crypto token. |
| 323 * FIPSSlotDescription: name of the fips db/crypto slot. |
| 324 * |
| 325 * if we are opening a new slot, we need to have the following |
| 326 * parameters: |
| 327 * tokenDescription: name of the token. |
| 328 * slotDescription: name of the slot. |
| 329 * |
| 330 * |
| 331 * The convert flag tells us to drop the unnecessary *TokenDescription |
| 332 * and *SlotDescription arguments and convert the appropriate pair |
| 333 * (either db or FIPS based on the isFIPS flag) to tokenDescription and |
| 334 * slotDescription). |
| 335 */ |
| 336 /* |
| 337 * walk down the list. if we find a tokens= argument, save it, |
| 338 * otherise copy the argument. |
| 339 */ |
| 340 while (*moduleSpec) { |
| 341 int next; |
| 342 modulePrev = moduleSpec; |
| 343 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=", |
| 344 modulePrev = moduleSpec; |
| 345 /* skip copying */) |
| 346 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=", |
| 347 if (convert) { modulePrev = moduleSpec; }); |
| 348 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=", |
| 349 if (convert) { modulePrev = moduleSpec; }); |
| 350 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=", |
| 351 if (convert) { |
| 352 modulePrev = moduleSpec; |
| 353 if (!isFIPS) { |
| 354 newSpecPtr = |
| 355 secmod_doDescCopy(newSpecPtr, &newSpecLen, SECMOD_TOKEN_DESCRIPTION, |
| 356 sizeof(SECMOD_TOKEN_DESCRIPTION) - 1, tmp); |
| 357 } |
| 358 }); |
| 359 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=", |
| 360 if (convert) { |
| 361 modulePrev = moduleSpec; /* skip copying */ |
| 362 if (!isFIPS) { |
| 363 newSpecPtr = |
| 364 secmod_doDescCopy(newSpecPtr, &newSpecLen, SECMOD_SLOT_DESCRIPTION, |
| 365 sizeof(SECMOD_SLOT_DESCRIPTION) - 1, tmp); |
| 366 } |
| 367 }); |
| 368 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=", |
| 369 if (convert) { |
| 370 modulePrev = moduleSpec; /* skip copying */ |
| 371 if (isFIPS) { |
| 372 newSpecPtr = |
| 373 secmod_doDescCopy(newSpecPtr, &newSpecLen, SECMOD_TOKEN_DESCRIPTION, |
| 374 sizeof(SECMOD_TOKEN_DESCRIPTION) - 1, tmp); |
| 375 } |
| 376 }); |
| 377 NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=", |
| 378 if (convert) { |
| 379 modulePrev = moduleSpec; /* skip copying */ |
| 380 if (isFIPS) { |
| 381 newSpecPtr = |
| 382 secmod_doDescCopy(newSpecPtr, &newSpecLen, SECMOD_SLOT_DESCRIPTION, |
| 383 sizeof(SECMOD_SLOT_DESCRIPTION) - 1, tmp); |
| 384 } |
| 385 }); |
| 386 NSSUTIL_HANDLE_FINAL_ARG(moduleSpec) |
330 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); | 387 SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); |
331 | 388 } |
332 /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening· | 389 if (tmp) { |
333 * a new softoken module takes the following parameters to name the· | 390 PORT_Free(tmp); |
334 * various tokens: | 391 tmp = NULL; |
335 *·· | 392 } |
336 * cryptoTokenDescription: name of the non-fips crypto token. | 393 *newSpecPtr = 0; |
337 * cryptoSlotDescription: name of the non-fips crypto slot. | 394 |
338 * dbTokenDescription: name of the non-fips db token. | 395 /* no target found, return the newSpec */ |
339 * dbSlotDescription: name of the non-fips db slot. | 396 if (target == NULL) { |
340 * FIPSTokenDescription: name of the fips db/crypto token. | 397 return newSpec; |
341 * FIPSSlotDescription: name of the fips db/crypto slot. | 398 } |
342 * | 399 |
343 * if we are opening a new slot, we need to have the following | 400 /* now build the child array from target */ |
344 * parameters: | 401 /*first count them */ |
345 * tokenDescription: name of the token. | 402 for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex; |
346 * slotDescription: name of the slot. | 403 tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) { |
347 * | 404 tokenCount++; |
348 * | 405 } |
349 * The convert flag tells us to drop the unnecessary *TokenDescription· | 406 |
350 * and *SlotDescription arguments and convert the appropriate pair· | 407 childArray = PORT_NewArray(char *, tokenCount + 1); |
351 * (either db or FIPS based on the isFIPS flag) to tokenDescription and· | 408 if (childArray == NULL) { |
352 * slotDescription). | 409 /* just return the spec as is then */ |
353 */ | |
354 /* | |
355 * walk down the list. if we find a tokens= argument, save it, | |
356 * otherise copy the argument. | |
357 */ | |
358 while (*moduleSpec) { | |
359 » int next; | |
360 » modulePrev = moduleSpec; | |
361 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=", | |
362 » » » modulePrev = moduleSpec; /* skip copying */ ) | |
363 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=", | |
364 » » » if (convert) { modulePrev = moduleSpec; } ); | |
365 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=", | |
366 » » » if (convert) { modulePrev = moduleSpec; } ); | |
367 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=", | |
368 » » » if (convert) { | |
369 » » » modulePrev = moduleSpec;· | |
370 » » » if (!isFIPS) { | |
371 » » » » newSpecPtr = secmod_doDescCopy(newSpecPtr,· | |
372 » » » » &newSpecLen, SECMOD_TOKEN_DESCRIPTION,· | |
373 » » » » sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp); | |
374 » » » } | |
375 » » » }); | |
376 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=", | |
377 » » » if (convert) { | |
378 » » » modulePrev = moduleSpec; /* skip copying */· | |
379 » » » if (!isFIPS) { | |
380 » » » » newSpecPtr = secmod_doDescCopy(newSpecPtr,· | |
381 » » » » &newSpecLen, SECMOD_SLOT_DESCRIPTION,· | |
382 » » » » sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp); | |
383 » » » } | |
384 » » » } ); | |
385 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=", | |
386 » » » if (convert) { | |
387 » » » modulePrev = moduleSpec; /* skip copying */· | |
388 » » » if (isFIPS) { | |
389 » » » » newSpecPtr = secmod_doDescCopy(newSpecPtr,· | |
390 » » » » &newSpecLen, SECMOD_TOKEN_DESCRIPTION,· | |
391 » » » » sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp); | |
392 » » » } | |
393 » » » } ); | |
394 » NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=", | |
395 » » » if (convert) { | |
396 » » » modulePrev = moduleSpec; /* skip copying */· | |
397 » » » if (isFIPS) { | |
398 » » » » newSpecPtr = secmod_doDescCopy(newSpecPtr,· | |
399 » » » » &newSpecLen, SECMOD_SLOT_DESCRIPTION,· | |
400 » » » » sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp); | |
401 » » » } | |
402 » » » } ); | |
403 » NSSUTIL_HANDLE_FINAL_ARG(moduleSpec) | |
404 » SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); | |
405 } | |
406 if (tmp) { | |
407 » PORT_Free(tmp); | |
408 » tmp = NULL; | |
409 } | |
410 *newSpecPtr = 0; | |
411 | |
412 /* no target found, return the newSpec */ | |
413 if (target == NULL) { | |
414 » return newSpec; | |
415 } | |
416 | |
417 /* now build the child array from target */ | |
418 /*first count them */ | |
419 for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex; | |
420 » tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) { | |
421 » tokenCount++; | |
422 } | |
423 | |
424 childArray = PORT_NewArray(char *, tokenCount+1); | |
425 if (childArray == NULL) { | |
426 » /* just return the spec as is then */ | |
427 » PORT_Free(target); | |
428 » return newSpec; | |
429 } | |
430 if (ids) { | |
431 » idArray = PORT_NewArray(CK_SLOT_ID, tokenCount+1); | |
432 » if (idArray == NULL) { | |
433 » PORT_Free(childArray); | |
434 » PORT_Free(target); | |
435 » return newSpec; | |
436 » } | |
437 } | |
438 | |
439 /* now fill them in */ | |
440 for (tokenIndex = NSSUTIL_ArgStrip(target), i=0 ;· | |
441 » » » *tokenIndex && (i < tokenCount);· | |
442 » » » tokenIndex=NSSUTIL_ArgStrip(tokenIndex)) { | |
443 » int next; | |
444 » char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next); | |
445 » tokenIndex += next; | |
446 | |
447 » if (idArray) { | |
448 » idArray[i] = NSSUTIL_ArgDecodeNumber(name); | |
449 » } | |
450 | |
451 » PORT_Free(name); /* drop the explicit number */ | |
452 | |
453 » /* if anything is left, copy the args to the child array */ | |
454 » if (!NSSUTIL_ArgIsBlank(*tokenIndex)) { | |
455 » childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next); | |
456 » tokenIndex += next; | |
457 » } | |
458 } | |
459 | |
460 PORT_Free(target); | 410 PORT_Free(target); |
461 childArray[i] = 0; | 411 return newSpec; |
| 412 } |
| 413 if (ids) { |
| 414 idArray = PORT_NewArray(CK_SLOT_ID, tokenCount + 1); |
| 415 if (idArray == NULL) { |
| 416 PORT_Free(childArray); |
| 417 PORT_Free(target); |
| 418 return newSpec; |
| 419 } |
| 420 } |
| 421 |
| 422 /* now fill them in */ |
| 423 for (tokenIndex = NSSUTIL_ArgStrip(target), i = 0; |
| 424 *tokenIndex && (i < tokenCount); |
| 425 tokenIndex = NSSUTIL_ArgStrip(tokenIndex)) { |
| 426 int next; |
| 427 char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next); |
| 428 tokenIndex += next; |
| 429 |
462 if (idArray) { | 430 if (idArray) { |
463 » idArray[i] = 0; | 431 idArray[i] = NSSUTIL_ArgDecodeNumber(name); |
464 } | 432 } |
465 | 433 |
466 /* return it */ | 434 PORT_Free(name); /* drop the explicit number */ |
467 *children = childArray; | 435 |
468 if (ids) { | 436 /* if anything is left, copy the args to the child array */ |
469 » *ids = idArray; | 437 if (!NSSUTIL_ArgIsBlank(*tokenIndex)) { |
470 } | 438 childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next); |
471 return newSpec; | 439 tokenIndex += next; |
| 440 } |
| 441 } |
| 442 |
| 443 PORT_Free(target); |
| 444 childArray[i] = 0; |
| 445 if (idArray) { |
| 446 idArray[i] = 0; |
| 447 } |
| 448 |
| 449 /* return it */ |
| 450 *children = childArray; |
| 451 if (ids) { |
| 452 *ids = idArray; |
| 453 } |
| 454 return newSpec; |
472 } | 455 } |
473 | 456 |
474 /* get the database and flags from the spec */ | 457 /* get the database and flags from the spec */ |
475 static char * | 458 static char *secmod_getConfigDir(char *spec, char **certPrefix, |
476 secmod_getConfigDir(char *spec, char **certPrefix, char **keyPrefix, | 459 char **keyPrefix, PRBool *readOnly) { |
477 » » » PRBool *readOnly) | 460 char *config = NULL; |
478 { | 461 |
479 char * config = NULL; | 462 *certPrefix = NULL; |
480 | 463 *keyPrefix = NULL; |
481 *certPrefix = NULL; | 464 *readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", spec); |
482 *keyPrefix = NULL; | 465 |
483 *readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",spec); | 466 spec = NSSUTIL_ArgStrip(spec); |
484 | 467 while (*spec) { |
485 spec = NSSUTIL_ArgStrip(spec); | 468 int next; |
486 while (*spec) { | 469 NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;) |
487 » int next; | 470 NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;) |
488 » NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;) | 471 NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;) |
489 » NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;) | 472 NSSUTIL_HANDLE_FINAL_ARG(spec) |
490 » NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;) | 473 } |
491 » NSSUTIL_HANDLE_FINAL_ARG(spec) | 474 return config; |
492 } | |
493 return config; | |
494 } | 475 } |
495 | 476 |
496 struct SECMODConfigListStr { | 477 struct SECMODConfigListStr { |
497 char *config; | 478 char *config; |
498 char *certPrefix; | 479 char *certPrefix; |
499 char *keyPrefix; | 480 char *keyPrefix; |
500 PRBool isReadOnly; | 481 PRBool isReadOnly; |
501 }; | 482 }; |
502 | 483 |
503 /* | 484 /* |
504 * return an array of already openned databases from a spec list. | 485 * return an array of already openned databases from a spec list. |
505 */ | 486 */ |
506 SECMODConfigList * | 487 SECMODConfigList *secmod_GetConfigList(PRBool isFIPS, char *spec, int *count) { |
507 secmod_GetConfigList(PRBool isFIPS, char *spec, int *count) | 488 char **children; |
508 { | 489 CK_SLOT_ID *ids; |
509 char **children; | 490 char *strippedSpec; |
510 CK_SLOT_ID *ids; | 491 int childCount; |
511 char *strippedSpec; | 492 SECMODConfigList *conflist = NULL; |
512 int childCount; | 493 int i; |
513 SECMODConfigList *conflist = NULL; | 494 |
514 int i; | 495 strippedSpec = |
515 | 496 secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS, spec, &children, &ids); |
516 strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS, | 497 if (strippedSpec == NULL) { |
517 » » » » » » spec,&children,&ids); | 498 return NULL; |
518 if (strippedSpec == NULL) { | 499 } |
519 » return NULL; | 500 |
520 } | 501 for (childCount = 0; children && children[childCount]; childCount++) |
521 | 502 ; |
522 for (childCount=0; children && children[childCount]; childCount++) ; | 503 *count = childCount + 1; /* include strippedSpec */ |
523 *count = childCount+1; /* include strippedSpec */ | 504 conflist = PORT_NewArray(SECMODConfigList, *count); |
524 conflist = PORT_NewArray(SECMODConfigList,*count); | 505 if (conflist == NULL) { |
525 if (conflist == NULL) { | 506 *count = 0; |
526 » *count = 0; | 507 goto loser; |
527 » goto loser; | 508 } |
528 } | 509 |
529 | 510 conflist[0].config = |
530 conflist[0].config = secmod_getConfigDir(strippedSpec, | 511 secmod_getConfigDir(strippedSpec, &conflist[0].certPrefix, |
531 » » » » » &conflist[0].certPrefix,· | 512 &conflist[0].keyPrefix, &conflist[0].isReadOnly); |
532 » » » » » &conflist[0].keyPrefix, | 513 for (i = 0; i < childCount; i++) { |
533 » » » » » &conflist[0].isReadOnly); | 514 conflist[i + 1].config = secmod_getConfigDir( |
534 for (i=0; i < childCount; i++) { | 515 children[i], &conflist[i + 1].certPrefix, &conflist[i + 1].keyPrefix, |
535 » conflist[i+1].config = secmod_getConfigDir(children[i], | 516 &conflist[i + 1].isReadOnly); |
536 » » » » » &conflist[i+1].certPrefix, | 517 } |
537 » » » » » &conflist[i+1].keyPrefix, | |
538 » » » » » &conflist[i+1].isReadOnly); | |
539 } | |
540 | 518 |
541 loser: | 519 loser: |
542 secmod_FreeChildren(children, ids); | 520 secmod_FreeChildren(children, ids); |
543 PORT_Free(strippedSpec); | 521 PORT_Free(strippedSpec); |
544 return conflist; | 522 return conflist; |
545 } | 523 } |
546 | 524 |
547 /* | 525 /* |
548 * determine if we are trying to open an old dbm database. For this test | 526 * determine if we are trying to open an old dbm database. For this test |
549 * RDB databases should return PR_FALSE. | 527 * RDB databases should return PR_FALSE. |
550 */ | 528 */ |
551 static PRBool | 529 static PRBool secmod_configIsDBM(char *configDir) { |
552 secmod_configIsDBM(char *configDir) | 530 char *env; |
553 { | 531 |
554 char *env; | 532 /* explicit dbm open */ |
555 | 533 if (strncmp(configDir, "dbm:", 4) == 0) { |
556 /* explicit dbm open */ | 534 return PR_TRUE; |
557 if (strncmp(configDir, "dbm:", 4) == 0) { | 535 } |
558 » return PR_TRUE; | 536 /* explicit open of a non-dbm database */ |
559 } | 537 if ((strncmp(configDir, "sql:", 4) == 0) || |
560 /* explicit open of a non-dbm database */ | 538 (strncmp(configDir, "rdb:", 4) == 0) || |
561 if ((strncmp(configDir, "sql:",4) == 0) | 539 (strncmp(configDir, "extern:", 7) == 0)) { |
562 » || (strncmp(configDir, "rdb:", 4) == 0) | |
563 » || (strncmp(configDir, "extern:", 7) == 0)) { | |
564 » return PR_FALSE; | |
565 } | |
566 env = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); | |
567 /* implicit dbm open */ | |
568 if ((env == NULL) || (strcmp(env,"dbm") == 0)) { | |
569 » return PR_TRUE; | |
570 } | |
571 /* implicit non-dbm open */ | |
572 return PR_FALSE; | 540 return PR_FALSE; |
| 541 } |
| 542 env = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); |
| 543 /* implicit dbm open */ |
| 544 if ((env == NULL) || (strcmp(env, "dbm") == 0)) { |
| 545 return PR_TRUE; |
| 546 } |
| 547 /* implicit non-dbm open */ |
| 548 return PR_FALSE; |
573 } | 549 } |
574 | 550 |
575 /* | 551 /* |
576 * match two prefixes. prefix may be NULL. NULL patches '\0' | 552 * match two prefixes. prefix may be NULL. NULL patches '\0' |
577 */ | 553 */ |
578 static PRBool | 554 static PRBool secmod_matchPrefix(char *prefix1, char *prefix2) { |
579 secmod_matchPrefix(char *prefix1, char *prefix2) | 555 if ((prefix1 == NULL) || (*prefix1 == 0)) { |
580 { | 556 if ((prefix2 == NULL) || (*prefix2 == 0)) { |
581 if ((prefix1 == NULL) || (*prefix1 == 0)) { | 557 return PR_TRUE; |
582 » if ((prefix2 == NULL) || (*prefix2 == 0)) { | |
583 » return PR_TRUE; | |
584 » } | |
585 » return PR_FALSE; | |
586 } | |
587 if (strcmp(prefix1, prefix2) == 0) { | |
588 » return PR_TRUE; | |
589 } | 558 } |
590 return PR_FALSE; | 559 return PR_FALSE; |
| 560 } |
| 561 if (strcmp(prefix1, prefix2) == 0) { |
| 562 return PR_TRUE; |
| 563 } |
| 564 return PR_FALSE; |
591 } | 565 } |
592 | 566 |
593 /* | 567 /* |
594 * return true if we are requesting a database that is already openned. | 568 * return true if we are requesting a database that is already openned. |
595 */ | 569 */ |
596 PRBool | 570 PRBool secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, |
597 secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count) | 571 int count) { |
598 { | 572 char *config; |
599 char *config; | 573 char *certPrefix; |
600 char *certPrefix; | 574 char *keyPrefix; |
601 char *keyPrefix; | 575 PRBool isReadOnly; |
602 PRBool isReadOnly; | 576 PRBool ret = PR_FALSE; |
603 PRBool ret=PR_FALSE; | 577 int i; |
604 int i; | 578 |
605 | 579 config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly); |
606 config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly); | 580 if (!config) { |
607 if (!config) { | 581 ret = PR_TRUE; |
608 » ret=PR_TRUE; | 582 goto done; |
609 » goto done; | 583 } |
610 } | 584 |
611 | 585 /* NOTE: we dbm isn't multiple open safe. If we open the same database |
612 /* NOTE: we dbm isn't multiple open safe. If we open the same database· | 586 * twice from two different locations, then we can corrupt our database |
613 * twice from two different locations, then we can corrupt our database | 587 * (the cache will be inconsistent). Protect against this by claiming |
614 * (the cache will be inconsistent). Protect against this by claiming | 588 * for comparison only that we are always openning dbm databases read only. |
615 * for comparison only that we are always openning dbm databases read only. | 589 */ |
616 */ | 590 if (secmod_configIsDBM(config)) { |
617 if (secmod_configIsDBM(config)) { | 591 isReadOnly = 1; |
618 » isReadOnly = 1; | 592 } |
619 } | 593 for (i = 0; i < count; i++) { |
620 for (i=0; i < count; i++) { | 594 if ((strcmp(config, conflist[i].config) == 0) && |
621 » if ((strcmp(config,conflist[i].config) == 0) && | 595 secmod_matchPrefix(certPrefix, conflist[i].certPrefix) && |
622 » secmod_matchPrefix(certPrefix, conflist[i].certPrefix) && | 596 secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) && |
623 » secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) && | 597 /* this last test -- if we just need the DB open read only, |
624 » /* this last test -- if we just need the DB open read only, | 598 * than any open will suffice, but if we requested it read/write |
625 » * than any open will suffice, but if we requested it read/write | 599 * and it's only open read only, we need to open it again */ |
626 » * and it's only open read only, we need to open it again */ | 600 (isReadOnly || !conflist[i].isReadOnly)) { |
627 » (isReadOnly || !conflist[i].isReadOnly)) { | 601 ret = PR_TRUE; |
628 » ret = PR_TRUE; | 602 goto done; |
629 » goto done; | 603 } |
630 » } | 604 } |
631 } | 605 |
632 | 606 ret = PR_FALSE; |
633 ret = PR_FALSE; | |
634 done: | 607 done: |
635 PORT_Free(config); | 608 PORT_Free(config); |
636 PORT_Free(certPrefix); | 609 PORT_Free(certPrefix); |
637 PORT_Free(keyPrefix); | 610 PORT_Free(keyPrefix); |
638 return ret; | 611 return ret; |
639 } | 612 } |
640 | 613 |
641 void | 614 void secmod_FreeConfigList(SECMODConfigList *conflist, int count) { |
642 secmod_FreeConfigList(SECMODConfigList *conflist, int count) | 615 int i; |
643 { | 616 for (i = 0; i < count; i++) { |
644 int i; | 617 PORT_Free(conflist[i].config); |
645 for (i=0; i < count; i++) { | 618 PORT_Free(conflist[i].certPrefix); |
646 » PORT_Free(conflist[i].config); | 619 PORT_Free(conflist[i].keyPrefix); |
647 » PORT_Free(conflist[i].certPrefix); | 620 } |
648 » PORT_Free(conflist[i].keyPrefix); | 621 PORT_Free(conflist); |
649 } | 622 } |
650 PORT_Free(conflist); | 623 |
651 } | 624 void secmod_FreeChildren(char **children, CK_SLOT_ID *ids) { |
652 | 625 char **thisChild; |
653 void | 626 |
654 secmod_FreeChildren(char **children, CK_SLOT_ID *ids) | 627 if (!children) { |
655 { | |
656 char **thisChild; | |
657 | |
658 if (!children) { | |
659 » return; | |
660 } | |
661 | |
662 for (thisChild = children; thisChild && *thisChild; thisChild++ ) { | |
663 » PORT_Free(*thisChild); | |
664 } | |
665 PORT_Free(children); | |
666 if (ids) { | |
667 » PORT_Free(ids); | |
668 } | |
669 return; | 628 return; |
| 629 } |
| 630 |
| 631 for (thisChild = children; thisChild && *thisChild; thisChild++) { |
| 632 PORT_Free(*thisChild); |
| 633 } |
| 634 PORT_Free(children); |
| 635 if (ids) { |
| 636 PORT_Free(ids); |
| 637 } |
| 638 return; |
670 } | 639 } |
671 | 640 |
672 /* | 641 /* |
673 * caclulate the length of each child record: | 642 * caclulate the length of each child record: |
674 * " 0x{id}=<{escaped_child}>" | 643 * " 0x{id}=<{escaped_child}>" |
675 */ | 644 */ |
676 static int | 645 static int secmod_getChildLength(char *child, CK_SLOT_ID id) { |
677 secmod_getChildLength(char *child, CK_SLOT_ID id) | 646 int length = NSSUTIL_DoubleEscapeSize(child, '>', ']'); |
678 { | 647 if (id == 0) { |
679 int length = NSSUTIL_DoubleEscapeSize(child, '>', ']'); | 648 length++; |
680 if (id == 0) { | 649 } |
681 » length++; | 650 while (id) { |
682 } | 651 length++; |
683 while (id) { | 652 id = id >> 4; |
684 » length++; | 653 } |
685 » id = id >> 4; | 654 length += 6; /* {sp}0x[id]=<{child}> */ |
686 } | 655 return length; |
687 length += 6; /* {sp}0x[id]=<{child}> */ | |
688 return length; | |
689 } | 656 } |
690 | 657 |
691 /* | 658 /* |
692 * Build a child record: | 659 * Build a child record: |
693 * " 0x{id}=<{escaped_child}>" | 660 * " 0x{id}=<{escaped_child}>" |
694 */ | 661 */ |
695 static SECStatus | 662 static SECStatus secmod_mkTokenChild(char **next, int *length, char *child, |
696 secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id) | 663 CK_SLOT_ID id) { |
697 { | 664 int len; |
698 int len; | 665 char *escSpec; |
699 char *escSpec; | 666 |
700 | 667 len = PR_snprintf(*next, *length, " 0x%x=<", id); |
701 len = PR_snprintf(*next, *length, " 0x%x=<",id); | 668 if (len < 0) { |
702 if (len < 0) { | 669 return SECFailure; |
703 » return SECFailure; | 670 } |
704 } | 671 *next += len; |
705 *next += len; | 672 *length -= len; |
706 *length -= len; | 673 escSpec = NSSUTIL_DoubleEscape(child, '>', ']'); |
707 escSpec = NSSUTIL_DoubleEscape(child, '>', ']'); | 674 if (escSpec == NULL) { |
708 if (escSpec == NULL) { | 675 return SECFailure; |
709 » return SECFailure; | 676 } |
710 } | 677 if (*child && (*escSpec == 0)) { |
711 if (*child && (*escSpec == 0)) { | |
712 » PORT_Free(escSpec); | |
713 » return SECFailure; | |
714 } | |
715 len = strlen(escSpec); | |
716 if (len+1 > *length) { | |
717 » PORT_Free(escSpec); | |
718 » return SECFailure; | |
719 } | |
720 PORT_Memcpy(*next,escSpec, len); | |
721 *next += len; | |
722 *length -= len; | |
723 PORT_Free(escSpec); | 678 PORT_Free(escSpec); |
724 **next = '>'; | 679 return SECFailure; |
725 (*next)++; | 680 } |
726 (*length)--; | 681 len = strlen(escSpec); |
727 return SECSuccess; | 682 if (len + 1 > *length) { |
| 683 PORT_Free(escSpec); |
| 684 return SECFailure; |
| 685 } |
| 686 PORT_Memcpy(*next, escSpec, len); |
| 687 *next += len; |
| 688 *length -= len; |
| 689 PORT_Free(escSpec); |
| 690 **next = '>'; |
| 691 (*next)++; |
| 692 (*length)--; |
| 693 return SECSuccess; |
728 } | 694 } |
729 | 695 |
730 #define TOKEN_STRING " tokens=[" | 696 #define TOKEN_STRING " tokens=[" |
731 | 697 |
732 char * | 698 char *secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, |
733 secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken, | 699 char *newToken, CK_SLOT_ID newID, |
734 » » » CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids) | 700 char **children, CK_SLOT_ID *ids) { |
735 { | 701 char *rawParam = NULL; /* oldParam with tokens stripped off */ |
736 char *rawParam = NULL;» /* oldParam with tokens stripped off */ | 702 char *newParam = NULL; /* space for the return parameter */ |
737 char *newParam = NULL;» /* space for the return parameter */ | 703 char *nextParam = NULL; /* current end of the new parameter */ |
738 char *nextParam = NULL;» /* current end of the new parameter */ | 704 char **oldChildren = NULL; |
739 char **oldChildren = NULL; | 705 CK_SLOT_ID *oldIds = NULL; |
740 CK_SLOT_ID *oldIds = NULL; | 706 void *mark = NULL; /* mark the arena pool in case we need |
741 void *mark = NULL; /* mark the arena pool in case we need· | 707 * to release it */ |
742 » » » » * to release it */ | 708 int length, i, tmpLen; |
743 int length, i, tmpLen; | 709 SECStatus rv; |
744 SECStatus rv; | 710 |
745 | 711 /* first strip out and save the old tokenlist */ |
746 /* first strip out and save the old tokenlist */ | 712 rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE, PR_FALSE, oldParam, |
747 rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE,PR_FALSE, | 713 &oldChildren, &oldIds); |
748 » » » » » oldParam,&oldChildren,&oldIds); | 714 if (!rawParam) { |
749 if (!rawParam) { | 715 goto loser; |
750 » goto loser; | 716 } |
751 } | 717 |
752 | 718 /* now calculate the total length of the new buffer */ |
753 /* now calculate the total length of the new buffer */ | 719 /* First the 'fixed stuff', length of rawparam (does not include a NULL), |
754 /* First the 'fixed stuff', length of rawparam (does not include a NULL), | 720 * length of the token string (does include the NULL), closing bracket */ |
755 * length of the token string (does include the NULL), closing bracket */ | 721 length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1; |
756 length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1; | 722 /* now add then length of all the old children */ |
757 /* now add then length of all the old children */ | 723 for (i = 0; oldChildren && oldChildren[i]; i++) { |
758 for (i=0; oldChildren && oldChildren[i]; i++) { | 724 length += secmod_getChildLength(oldChildren[i], oldIds[i]); |
759 » length += secmod_getChildLength(oldChildren[i], oldIds[i]); | 725 } |
760 } | 726 |
761 | 727 /* add the new token */ |
762 /* add the new token */ | 728 length += secmod_getChildLength(newToken, newID); |
763 length += secmod_getChildLength(newToken, newID); | 729 |
764 | 730 /* and it's new children */ |
765 /* and it's new children */ | 731 for (i = 0; children && children[i]; i++) { |
766 for (i=0; children && children[i]; i++) { | 732 if (ids[i] == -1) { |
767 » if (ids[i] == -1) { | 733 continue; |
768 » continue; | 734 } |
769 » } | 735 length += secmod_getChildLength(children[i], ids[i]); |
770 » length += secmod_getChildLength(children[i], ids[i]); | 736 } |
771 } | 737 |
772 | 738 /* now allocate and build the string */ |
773 /* now allocate and build the string */ | 739 mark = PORT_ArenaMark(arena); |
774 mark = PORT_ArenaMark(arena); | 740 if (!mark) { |
775 if (!mark) { | 741 goto loser; |
776 » goto loser; | 742 } |
777 } | 743 newParam = PORT_ArenaAlloc(arena, length); |
778 newParam = PORT_ArenaAlloc(arena,length); | 744 if (!newParam) { |
779 if (!newParam) { | 745 goto loser; |
780 » goto loser; | 746 } |
781 } | 747 |
782 | 748 PORT_Strcpy(newParam, oldParam); |
783 PORT_Strcpy(newParam, oldParam); | 749 tmpLen = strlen(oldParam); |
784 tmpLen = strlen(oldParam); | 750 nextParam = newParam + tmpLen; |
785 nextParam = newParam + tmpLen; | 751 length -= tmpLen; |
786 length -= tmpLen; | 752 PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING) - 1); |
787 PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING)-1); | 753 nextParam += sizeof(TOKEN_STRING) - 1; |
788 nextParam += sizeof(TOKEN_STRING)-1; | 754 length -= sizeof(TOKEN_STRING) - 1; |
789 length -= sizeof(TOKEN_STRING)-1; | 755 |
790 | 756 for (i = 0; oldChildren && oldChildren[i]; i++) { |
791 for (i=0; oldChildren && oldChildren[i]; i++) { | 757 rv = secmod_mkTokenChild(&nextParam, &length, oldChildren[i], oldIds[i]); |
792 » rv = secmod_mkTokenChild(&nextParam,&length,oldChildren[i],oldIds[i]); | |
793 » if (rv != SECSuccess) { | |
794 » goto loser; | |
795 » } | |
796 } | |
797 | |
798 rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID); | |
799 if (rv != SECSuccess) { | 758 if (rv != SECSuccess) { |
800 » goto loser; | 759 goto loser; |
801 } | 760 } |
802 | 761 } |
803 for (i=0; children && children[i]; i++) { | 762 |
804 » if (ids[i] == -1) { | 763 rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID); |
805 » continue; | 764 if (rv != SECSuccess) { |
806 » } | 765 goto loser; |
807 » rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]); | 766 } |
808 » if (rv != SECSuccess) { | 767 |
809 » goto loser; | 768 for (i = 0; children && children[i]; i++) { |
810 » } | 769 if (ids[i] == -1) { |
811 } | 770 continue; |
812 | 771 } |
813 if (length < 2) { | 772 rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]); |
814 » goto loser; | 773 if (rv != SECSuccess) { |
815 } | 774 goto loser; |
816 | 775 } |
817 *nextParam++ = ']'; | 776 } |
818 *nextParam++ = 0; | 777 |
819 | 778 if (length < 2) { |
820 /* we are going to return newParam now, don't release the mark */ | 779 goto loser; |
821 PORT_ArenaUnmark(arena, mark); | 780 } |
822 mark = NULL; | 781 |
| 782 *nextParam++ = ']'; |
| 783 *nextParam++ = 0; |
| 784 |
| 785 /* we are going to return newParam now, don't release the mark */ |
| 786 PORT_ArenaUnmark(arena, mark); |
| 787 mark = NULL; |
823 | 788 |
824 loser: | 789 loser: |
825 if (mark) { | 790 if (mark) { |
826 » PORT_ArenaRelease(arena, mark); | 791 PORT_ArenaRelease(arena, mark); |
827 » newParam = NULL; /* if the mark is still active,· | 792 newParam = NULL; /* if the mark is still active, |
828 » » » * don't return the param */ | 793 * don't return the param */ |
829 } | 794 } |
830 if (rawParam) { | 795 if (rawParam) { |
831 » PORT_Free(rawParam); | 796 PORT_Free(rawParam); |
832 } | 797 } |
833 if (oldChildren) { | 798 if (oldChildren) { |
834 » secmod_FreeChildren(oldChildren, oldIds); | 799 secmod_FreeChildren(oldChildren, oldIds); |
835 } | 800 } |
836 return newParam; | 801 return newParam; |
837 } | 802 } |
838 ···· | 803 |
839 static char * | 804 static char *secmod_mkModuleSpec(SECMODModule *module) { |
840 secmod_mkModuleSpec(SECMODModule * module) | 805 char *nss = NULL, *modSpec = NULL, **slotStrings = NULL; |
841 { | 806 int slotCount, i, si; |
842 char *nss = NULL, *modSpec = NULL, **slotStrings = NULL; | 807 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); |
843 int slotCount, i, si; | 808 |
844 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); | 809 /* allocate target slot info strings */ |
845 | 810 slotCount = 0; |
846 /* allocate target slot info strings */ | 811 |
847 slotCount = 0; | 812 SECMOD_GetReadLock(moduleLock); |
848 | 813 if (module->slotCount) { |
| 814 for (i = 0; i < module->slotCount; i++) { |
| 815 if (module->slots[i]->defaultFlags != 0) { |
| 816 slotCount++; |
| 817 } |
| 818 } |
| 819 } else { |
| 820 slotCount = module->slotInfoCount; |
| 821 } |
| 822 |
| 823 slotStrings = (char **)PORT_ZAlloc(slotCount * sizeof(char *)); |
| 824 if (slotStrings == NULL) { |
| 825 SECMOD_ReleaseReadLock(moduleLock); |
| 826 goto loser; |
| 827 } |
| 828 |
| 829 /* build the slot info strings */ |
| 830 if (module->slotCount) { |
| 831 for (i = 0, si = 0; i < module->slotCount; i++) { |
| 832 if (module->slots[i]->defaultFlags) { |
| 833 PORT_Assert(si < slotCount); |
| 834 if (si >= slotCount) break; |
| 835 slotStrings[si] = NSSUTIL_MkSlotString( |
| 836 module->slots[i]->slotID, module->slots[i]->defaultFlags, |
| 837 module->slots[i]->timeout, module->slots[i]->askpw, |
| 838 module->slots[i]->hasRootCerts, module->slots[i]->hasRootTrust); |
| 839 si++; |
| 840 } |
| 841 } |
| 842 } else { |
| 843 for (i = 0; i < slotCount; i++) { |
| 844 slotStrings[i] = NSSUTIL_MkSlotString( |
| 845 module->slotInfo[i].slotID, module->slotInfo[i].defaultFlags, |
| 846 module->slotInfo[i].timeout, module->slotInfo[i].askpw, |
| 847 module->slotInfo[i].hasRootCerts, module->slotInfo[i].hasRootTrust); |
| 848 } |
| 849 } |
| 850 |
| 851 SECMOD_ReleaseReadLock(moduleLock); |
| 852 nss = NSSUTIL_MkNSSString( |
| 853 slotStrings, slotCount, module->internal, module->isFIPS, |
| 854 module->isModuleDB, module->moduleDBOnly, module->isCritical, |
| 855 module->trustOrder, module->cipherOrder, module->ssl[0], module->ssl[1]); |
| 856 modSpec = NSSUTIL_MkModuleSpec(module->dllName, module->commonName, |
| 857 module->libraryParams, nss); |
| 858 PORT_Free(slotStrings); |
| 859 PR_smprintf_free(nss); |
| 860 loser: |
| 861 return (modSpec); |
| 862 } |
| 863 |
| 864 char **SECMOD_GetModuleSpecList(SECMODModule *module) { |
| 865 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc; |
| 866 if (func) { |
| 867 return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND, module->libraryParams, NULL); |
| 868 } |
| 869 return NULL; |
| 870 } |
| 871 |
| 872 SECStatus SECMOD_AddPermDB(SECMODModule *module) { |
| 873 SECMODModuleDBFunc func; |
| 874 char *moduleSpec; |
| 875 char **retString; |
| 876 |
| 877 if (module->parent == NULL) return SECFailure; |
| 878 |
| 879 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc; |
| 880 if (func) { |
| 881 moduleSpec = secmod_mkModuleSpec(module); |
| 882 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD, |
| 883 module->parent->libraryParams, moduleSpec); |
| 884 PORT_Free(moduleSpec); |
| 885 if (retString != NULL) return SECSuccess; |
| 886 } |
| 887 return SECFailure; |
| 888 } |
| 889 |
| 890 SECStatus SECMOD_DeletePermDB(SECMODModule *module) { |
| 891 SECMODModuleDBFunc func; |
| 892 char *moduleSpec; |
| 893 char **retString; |
| 894 |
| 895 if (module->parent == NULL) return SECFailure; |
| 896 |
| 897 func = (SECMODModuleDBFunc)module->parent->moduleDBFunc; |
| 898 if (func) { |
| 899 moduleSpec = secmod_mkModuleSpec(module); |
| 900 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL, |
| 901 module->parent->libraryParams, moduleSpec); |
| 902 PORT_Free(moduleSpec); |
| 903 if (retString != NULL) return SECSuccess; |
| 904 } |
| 905 return SECFailure; |
| 906 } |
| 907 |
| 908 SECStatus SECMOD_FreeModuleSpecList(SECMODModule *module, |
| 909 char **moduleSpecList) { |
| 910 SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc; |
| 911 char **retString; |
| 912 if (func) { |
| 913 retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE, |
| 914 module->libraryParams, moduleSpecList); |
| 915 if (retString != NULL) return SECSuccess; |
| 916 } |
| 917 return SECFailure; |
| 918 } |
| 919 |
| 920 /* |
| 921 * load a PKCS#11 module but do not add it to the default NSS trust domain |
| 922 */ |
| 923 SECMODModule *SECMOD_LoadModule(char *modulespec, SECMODModule *parent, |
| 924 PRBool recurse) { |
| 925 char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss = NULL; |
| 926 SECStatus status; |
| 927 SECMODModule *module = NULL; |
| 928 SECMODModule *oldModule = NULL; |
| 929 SECStatus rv; |
| 930 |
| 931 /* initialize the underlying module structures */ |
| 932 SECMOD_Init(); |
| 933 |
| 934 status = NSSUTIL_ArgParseModuleSpec(modulespec, &library, &moduleName, |
| 935 ¶meters, &nss); |
| 936 if (status != SECSuccess) { |
| 937 goto loser; |
| 938 } |
| 939 |
| 940 module = SECMOD_CreateModule(library, moduleName, parameters, nss); |
| 941 if (library) PORT_Free(library); |
| 942 if (moduleName) PORT_Free(moduleName); |
| 943 if (parameters) PORT_Free(parameters); |
| 944 if (nss) PORT_Free(nss); |
| 945 if (!module) { |
| 946 goto loser; |
| 947 } |
| 948 if (parent) { |
| 949 module->parent = SECMOD_ReferenceModule(parent); |
| 950 if (module->internal && secmod_IsInternalKeySlot(parent)) { |
| 951 module->internal = parent->internal; |
| 952 } |
| 953 } |
| 954 |
| 955 /* load it */ |
| 956 rv = secmod_LoadPKCS11Module(module, &oldModule); |
| 957 if (rv != SECSuccess) { |
| 958 goto loser; |
| 959 } |
| 960 |
| 961 /* if we just reload an old module, no need to add it to any lists. |
| 962 * we simple release all our references */ |
| 963 if (oldModule) { |
| 964 /* This module already exists, don't link it anywhere. This |
| 965 * will probably destroy this module */ |
| 966 SECMOD_DestroyModule(module); |
| 967 return oldModule; |
| 968 } |
| 969 |
| 970 if (recurse && module->isModuleDB) { |
| 971 char **moduleSpecList; |
| 972 PORT_SetError(0); |
| 973 |
| 974 moduleSpecList = SECMOD_GetModuleSpecList(module); |
| 975 if (moduleSpecList) { |
| 976 char **index; |
| 977 |
| 978 index = moduleSpecList; |
| 979 if (*index && SECMOD_GetSkipFirstFlag(module)) { |
| 980 index++; |
| 981 } |
| 982 |
| 983 for (; *index; index++) { |
| 984 SECMODModule *child; |
| 985 if (0 == PORT_Strcmp(*index, modulespec)) { |
| 986 /* avoid trivial infinite recursion */ |
| 987 PORT_SetError(SEC_ERROR_NO_MODULE); |
| 988 rv = SECFailure; |
| 989 break; |
| 990 } |
| 991 child = SECMOD_LoadModule(*index, module, PR_TRUE); |
| 992 if (!child) break; |
| 993 if (child->isCritical && !child->loaded) { |
| 994 int err = PORT_GetError(); |
| 995 if (!err) err = SEC_ERROR_NO_MODULE; |
| 996 SECMOD_DestroyModule(child); |
| 997 PORT_SetError(err); |
| 998 rv = SECFailure; |
| 999 break; |
| 1000 } |
| 1001 SECMOD_DestroyModule(child); |
| 1002 } |
| 1003 SECMOD_FreeModuleSpecList(module, moduleSpecList); |
| 1004 } else { |
| 1005 if (!PORT_GetError()) PORT_SetError(SEC_ERROR_NO_MODULE); |
| 1006 rv = SECFailure; |
| 1007 } |
| 1008 } |
| 1009 |
| 1010 if (rv != SECSuccess) { |
| 1011 goto loser; |
| 1012 } |
| 1013 |
| 1014 /* inherit the reference */ |
| 1015 if (!module->moduleDBOnly) { |
| 1016 SECMOD_AddModuleToList(module); |
| 1017 } else { |
| 1018 SECMOD_AddModuleToDBOnlyList(module); |
| 1019 } |
| 1020 |
| 1021 /* handle any additional work here */ |
| 1022 return module; |
| 1023 |
| 1024 loser: |
| 1025 if (module) { |
| 1026 if (module->loaded) { |
| 1027 SECMOD_UnloadModule(module); |
| 1028 } |
| 1029 SECMOD_AddModuleToUnloadList(module); |
| 1030 } |
| 1031 return module; |
| 1032 } |
| 1033 |
| 1034 /* |
| 1035 * load a PKCS#11 module and add it to the default NSS trust domain |
| 1036 */ |
| 1037 SECMODModule *SECMOD_LoadUserModule(char *modulespec, SECMODModule *parent, |
| 1038 PRBool recurse) { |
| 1039 SECStatus rv = SECSuccess; |
| 1040 SECMODModule *newmod = SECMOD_LoadModule(modulespec, parent, recurse); |
| 1041 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); |
| 1042 |
| 1043 if (newmod) { |
849 SECMOD_GetReadLock(moduleLock); | 1044 SECMOD_GetReadLock(moduleLock); |
850 if (module->slotCount) { | 1045 rv = STAN_AddModuleToDefaultTrustDomain(newmod); |
851 » for (i=0; i < module->slotCount; i++) { | |
852 » if (module->slots[i]->defaultFlags !=0) { | |
853 » » slotCount++; | |
854 » } | |
855 » } | |
856 } else { | |
857 » slotCount = module->slotInfoCount; | |
858 } | |
859 | |
860 slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *)); | |
861 if (slotStrings == NULL) { | |
862 SECMOD_ReleaseReadLock(moduleLock); | |
863 » goto loser; | |
864 } | |
865 | |
866 | |
867 /* build the slot info strings */ | |
868 if (module->slotCount) { | |
869 » for (i=0, si= 0; i < module->slotCount; i++) { | |
870 » if (module->slots[i]->defaultFlags) { | |
871 » » PORT_Assert(si < slotCount); | |
872 » » if (si >= slotCount) break; | |
873 » » slotStrings[si] = NSSUTIL_MkSlotString(module->slots[i]->slotID, | |
874 » » » module->slots[i]->defaultFlags, | |
875 » » » module->slots[i]->timeout, | |
876 » » » module->slots[i]->askpw, | |
877 » » » module->slots[i]->hasRootCerts, | |
878 » » » module->slots[i]->hasRootTrust); | |
879 » » si++; | |
880 » } | |
881 » } | |
882 } else { | |
883 » for (i=0; i < slotCount; i++) { | |
884 » » slotStrings[i] = NSSUTIL_MkSlotString( | |
885 » » » module->slotInfo[i].slotID, | |
886 » » » module->slotInfo[i].defaultFlags, | |
887 » » » module->slotInfo[i].timeout, | |
888 » » » module->slotInfo[i].askpw, | |
889 » » » module->slotInfo[i].hasRootCerts, | |
890 » » » module->slotInfo[i].hasRootTrust); | |
891 » } | |
892 } | |
893 | |
894 SECMOD_ReleaseReadLock(moduleLock); | 1046 SECMOD_ReleaseReadLock(moduleLock); |
895 nss = NSSUTIL_MkNSSString(slotStrings,slotCount,module->internal,· | 1047 if (SECSuccess != rv) { |
896 » » module->isFIPS, module->isModuleDB, | 1048 SECMOD_DestroyModule(newmod); |
897 » » module->moduleDBOnly, module->isCritical, | 1049 return NULL; |
898 » » module->trustOrder, module->cipherOrder, | 1050 } |
899 » » module->ssl[0],module->ssl[1]); | 1051 } |
900 modSpec= NSSUTIL_MkModuleSpec(module->dllName,module->commonName, | 1052 return newmod; |
901 » » » » » » module->libraryParams,nss); | |
902 PORT_Free(slotStrings); | |
903 PR_smprintf_free(nss); | |
904 loser: | |
905 return (modSpec); | |
906 } | |
907 ···· | |
908 | |
909 char ** | |
910 SECMOD_GetModuleSpecList(SECMODModule *module) | |
911 { | |
912 SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc; | |
913 if (func) { | |
914 » return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND, | |
915 » » module->libraryParams,NULL); | |
916 } | |
917 return NULL; | |
918 } | |
919 | |
920 SECStatus | |
921 SECMOD_AddPermDB(SECMODModule *module) | |
922 { | |
923 SECMODModuleDBFunc func; | |
924 char *moduleSpec; | |
925 char **retString; | |
926 | |
927 if (module->parent == NULL) return SECFailure; | |
928 | |
929 func = (SECMODModuleDBFunc) module->parent->moduleDBFunc; | |
930 if (func) { | |
931 » moduleSpec = secmod_mkModuleSpec(module); | |
932 » retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD, | |
933 » » module->parent->libraryParams,moduleSpec); | |
934 » PORT_Free(moduleSpec); | |
935 » if (retString != NULL) return SECSuccess; | |
936 } | |
937 return SECFailure; | |
938 } | |
939 | |
940 SECStatus | |
941 SECMOD_DeletePermDB(SECMODModule *module) | |
942 { | |
943 SECMODModuleDBFunc func; | |
944 char *moduleSpec; | |
945 char **retString; | |
946 | |
947 if (module->parent == NULL) return SECFailure; | |
948 | |
949 func = (SECMODModuleDBFunc) module->parent->moduleDBFunc; | |
950 if (func) { | |
951 » moduleSpec = secmod_mkModuleSpec(module); | |
952 » retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL, | |
953 » » module->parent->libraryParams,moduleSpec); | |
954 » PORT_Free(moduleSpec); | |
955 » if (retString != NULL) return SECSuccess; | |
956 } | |
957 return SECFailure; | |
958 } | |
959 | |
960 SECStatus | |
961 SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList) | |
962 { | |
963 SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc; | |
964 char **retString; | |
965 if (func) { | |
966 » retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE, | |
967 » » module->libraryParams,moduleSpecList); | |
968 » if (retString != NULL) return SECSuccess; | |
969 } | |
970 return SECFailure; | |
971 } | |
972 | |
973 /* | |
974 * load a PKCS#11 module but do not add it to the default NSS trust domain | |
975 */ | |
976 SECMODModule * | |
977 SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse) | |
978 { | |
979 char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL; | |
980 SECStatus status; | |
981 SECMODModule *module = NULL; | |
982 SECMODModule *oldModule = NULL; | |
983 SECStatus rv; | |
984 | |
985 /* initialize the underlying module structures */ | |
986 SECMOD_Init(); | |
987 | |
988 status = NSSUTIL_ArgParseModuleSpec(modulespec, &library, &moduleName,· | |
989 » » » » » » » ¶meters, &nss); | |
990 if (status != SECSuccess) { | |
991 » goto loser; | |
992 } | |
993 | |
994 module = SECMOD_CreateModule(library, moduleName, parameters, nss); | |
995 if (library) PORT_Free(library); | |
996 if (moduleName) PORT_Free(moduleName); | |
997 if (parameters) PORT_Free(parameters); | |
998 if (nss) PORT_Free(nss); | |
999 if (!module) { | |
1000 » goto loser; | |
1001 } | |
1002 if (parent) { | |
1003 » module->parent = SECMOD_ReferenceModule(parent); | |
1004 » if (module->internal && secmod_IsInternalKeySlot(parent)) { | |
1005 » module->internal = parent->internal; | |
1006 » } | |
1007 } | |
1008 | |
1009 /* load it */ | |
1010 rv = secmod_LoadPKCS11Module(module, &oldModule); | |
1011 if (rv != SECSuccess) { | |
1012 » goto loser; | |
1013 } | |
1014 | |
1015 /* if we just reload an old module, no need to add it to any lists. | |
1016 * we simple release all our references */ | |
1017 if (oldModule) { | |
1018 » /* This module already exists, don't link it anywhere. This | |
1019 » * will probably destroy this module */ | |
1020 » SECMOD_DestroyModule(module); | |
1021 » return oldModule; | |
1022 } | |
1023 | |
1024 if (recurse && module->isModuleDB) { | |
1025 » char ** moduleSpecList; | |
1026 » PORT_SetError(0); | |
1027 | |
1028 » moduleSpecList = SECMOD_GetModuleSpecList(module); | |
1029 » if (moduleSpecList) { | |
1030 » char **index; | |
1031 | |
1032 » index = moduleSpecList; | |
1033 » if (*index && SECMOD_GetSkipFirstFlag(module)) { | |
1034 » » index++; | |
1035 » } | |
1036 | |
1037 » for (; *index; index++) { | |
1038 » » SECMODModule *child; | |
1039 » » if (0 == PORT_Strcmp(*index, modulespec)) { | |
1040 » » /* avoid trivial infinite recursion */ | |
1041 » » PORT_SetError(SEC_ERROR_NO_MODULE); | |
1042 » » rv = SECFailure; | |
1043 » » break; | |
1044 » » } | |
1045 » » child = SECMOD_LoadModule(*index,module,PR_TRUE); | |
1046 » » if (!child) break; | |
1047 » » if (child->isCritical && !child->loaded) { | |
1048 » » int err = PORT_GetError(); | |
1049 » » if (!err)·· | |
1050 » » » err = SEC_ERROR_NO_MODULE; | |
1051 » » SECMOD_DestroyModule(child); | |
1052 » » PORT_SetError(err); | |
1053 » » rv = SECFailure; | |
1054 » » break; | |
1055 » » } | |
1056 » » SECMOD_DestroyModule(child); | |
1057 » } | |
1058 » SECMOD_FreeModuleSpecList(module,moduleSpecList); | |
1059 » } else { | |
1060 » if (!PORT_GetError()) | |
1061 » » PORT_SetError(SEC_ERROR_NO_MODULE); | |
1062 » rv = SECFailure; | |
1063 » } | |
1064 } | |
1065 | |
1066 if (rv != SECSuccess) { | |
1067 » goto loser; | |
1068 } | |
1069 | |
1070 | |
1071 /* inherit the reference */ | |
1072 if (!module->moduleDBOnly) { | |
1073 » SECMOD_AddModuleToList(module); | |
1074 } else { | |
1075 » SECMOD_AddModuleToDBOnlyList(module); | |
1076 } | |
1077 ··· | |
1078 /* handle any additional work here */ | |
1079 return module; | |
1080 | |
1081 loser: | |
1082 if (module) { | |
1083 » if (module->loaded) { | |
1084 » SECMOD_UnloadModule(module); | |
1085 » } | |
1086 » SECMOD_AddModuleToUnloadList(module); | |
1087 } | |
1088 return module; | |
1089 } | |
1090 | |
1091 /* | |
1092 * load a PKCS#11 module and add it to the default NSS trust domain | |
1093 */ | |
1094 SECMODModule * | |
1095 SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse) | |
1096 { | |
1097 SECStatus rv = SECSuccess; | |
1098 SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse); | |
1099 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); | |
1100 | |
1101 if (newmod) { | |
1102 » SECMOD_GetReadLock(moduleLock); | |
1103 rv = STAN_AddModuleToDefaultTrustDomain(newmod); | |
1104 » SECMOD_ReleaseReadLock(moduleLock); | |
1105 if (SECSuccess != rv) { | |
1106 SECMOD_DestroyModule(newmod); | |
1107 return NULL; | |
1108 } | |
1109 } | |
1110 return newmod; | |
1111 } | 1053 } |
1112 | 1054 |
1113 /* | 1055 /* |
1114 * remove the PKCS#11 module from the default NSS trust domain, call | 1056 * remove the PKCS#11 module from the default NSS trust domain, call |
1115 * C_Finalize, and destroy the module structure | 1057 * C_Finalize, and destroy the module structure |
1116 */ | 1058 */ |
1117 SECStatus SECMOD_UnloadUserModule(SECMODModule *mod) | 1059 SECStatus SECMOD_UnloadUserModule(SECMODModule *mod) { |
1118 { | 1060 SECStatus rv = SECSuccess; |
1119 SECStatus rv = SECSuccess; | 1061 int atype = 0; |
1120 int atype = 0; | 1062 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); |
1121 SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); | 1063 if (!mod) { |
1122 if (!mod) { | 1064 return SECFailure; |
1123 return SECFailure; | 1065 } |
1124 } | 1066 |
1125 | 1067 SECMOD_GetReadLock(moduleLock); |
1126 SECMOD_GetReadLock(moduleLock); | 1068 rv = STAN_RemoveModuleFromDefaultTrustDomain(mod); |
1127 rv = STAN_RemoveModuleFromDefaultTrustDomain(mod); | 1069 SECMOD_ReleaseReadLock(moduleLock); |
1128 SECMOD_ReleaseReadLock(moduleLock); | 1070 if (SECSuccess != rv) { |
1129 if (SECSuccess != rv) { | 1071 return SECFailure; |
1130 return SECFailure; | 1072 } |
1131 } | 1073 return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE); |
1132 return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE); | 1074 } |
1133 } | |
1134 | |
OLD | NEW |