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 #include "pkcs11i.h"
10 #include "sdb.h"
11 #include "prprf.h"
12 #include "prenv.h"
13 #include "utilpars.h"
14 
15 #define FREE_CLEAR(p) \
16     if (p) {          \
17         PORT_Free(p); \
18         p = NULL;     \
19     }
20 
21 static void
sftk_parseTokenFlags(char * tmp,sftk_token_parameters * parsed)22 sftk_parseTokenFlags(char *tmp, sftk_token_parameters *parsed)
23 {
24     parsed->readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", tmp);
25     parsed->noCertDB = NSSUTIL_ArgHasFlag("flags", "noCertDB", tmp);
26     parsed->noKeyDB = NSSUTIL_ArgHasFlag("flags", "noKeyDB", tmp);
27     parsed->forceOpen = NSSUTIL_ArgHasFlag("flags", "forceOpen", tmp);
28     parsed->pwRequired = NSSUTIL_ArgHasFlag("flags", "passwordRequired", tmp);
29     parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags", "optimizeSpace", tmp);
30     return;
31 }
32 
33 static void
sftk_parseFlags(char * tmp,sftk_parameters * parsed)34 sftk_parseFlags(char *tmp, sftk_parameters *parsed)
35 {
36     parsed->noModDB = NSSUTIL_ArgHasFlag("flags", "noModDB", tmp);
37     parsed->readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", tmp);
38     /* keep legacy interface working */
39     parsed->noCertDB = NSSUTIL_ArgHasFlag("flags", "noCertDB", tmp);
40     parsed->forceOpen = NSSUTIL_ArgHasFlag("flags", "forceOpen", tmp);
41     parsed->pwRequired = NSSUTIL_ArgHasFlag("flags", "passwordRequired", tmp);
42     parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags", "optimizeSpace", tmp);
43     return;
44 }
45 
46 static CK_RV
sftk_parseTokenParameters(char * param,sftk_token_parameters * parsed)47 sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed)
48 {
49     int next;
50     char *tmp = NULL;
51     const char *index;
52     index = NSSUTIL_ArgStrip(param);
53 
54     while (*index) {
55         NSSUTIL_HANDLE_STRING_ARG(index, parsed->configdir, "configDir=", ;)
56         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updatedir, "updateDir=", ;)
57         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updCertPrefix, "updateCertPrefix=", ;)
58         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updKeyPrefix, "updateKeyPrefix=", ;)
59         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updateID, "updateID=", ;)
60         NSSUTIL_HANDLE_STRING_ARG(index, parsed->certPrefix, "certPrefix=", ;)
61         NSSUTIL_HANDLE_STRING_ARG(index, parsed->keyPrefix, "keyPrefix=", ;)
62         NSSUTIL_HANDLE_STRING_ARG(index, parsed->tokdes, "tokenDescription=", ;)
63         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updtokdes, "updateTokenDescription=", ;)
64         NSSUTIL_HANDLE_STRING_ARG(index, parsed->slotdes, "slotDescription=", ;)
65         NSSUTIL_HANDLE_STRING_ARG(index, tmp, "minPWLen=",
66                                   if (tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); tmp = NULL; })
67         NSSUTIL_HANDLE_STRING_ARG(index, tmp, "flags=",
68                                   if (tmp) { sftk_parseTokenFlags(param,parsed); PORT_Free(tmp); tmp = NULL; })
69         NSSUTIL_HANDLE_FINAL_ARG(index)
70     }
71     return CKR_OK;
72 }
73 
74 static void
sftk_parseTokens(char * tokenParams,sftk_parameters * parsed)75 sftk_parseTokens(char *tokenParams, sftk_parameters *parsed)
76 {
77     const char *tokenIndex;
78     sftk_token_parameters *tokens = NULL;
79     int i = 0, count = 0, next;
80 
81     if ((tokenParams == NULL) || (*tokenParams == 0))
82         return;
83 
84     /* first count the number of slots */
85     for (tokenIndex = NSSUTIL_ArgStrip(tokenParams); *tokenIndex;
86          tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
87         count++;
88     }
89 
90     /* get the data structures */
91     tokens = (sftk_token_parameters *)
92         PORT_ZAlloc(count * sizeof(sftk_token_parameters));
93     if (tokens == NULL)
94         return;
95 
96     for (tokenIndex = NSSUTIL_ArgStrip(tokenParams), i = 0;
97          *tokenIndex && i < count; i++) {
98         char *name;
99         name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
100         tokenIndex += next;
101 
102         tokens[i].slotID = NSSUTIL_ArgDecodeNumber(name);
103         tokens[i].readOnly = PR_FALSE;
104         tokens[i].noCertDB = PR_FALSE;
105         tokens[i].noKeyDB = PR_FALSE;
106         if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
107             char *args = NSSUTIL_ArgFetchValue(tokenIndex, &next);
108             tokenIndex += next;
109             if (args) {
110                 sftk_parseTokenParameters(args, &tokens[i]);
111                 PORT_Free(args);
112             }
113         }
114         if (name)
115             PORT_Free(name);
116         tokenIndex = NSSUTIL_ArgStrip(tokenIndex);
117     }
118     parsed->token_count = i;
119     parsed->tokens = tokens;
120     return;
121 }
122 
123 CK_RV
sftk_parseParameters(char * param,sftk_parameters * parsed,PRBool isFIPS)124 sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
125 {
126     int next;
127     char *tmp = NULL;
128     const char *index;
129     char *certPrefix = NULL, *keyPrefix = NULL;
130     char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL;
131     char *slotdes = NULL, *pslotdes = NULL;
132     char *fslotdes = NULL, *ftokdes = NULL;
133     char *minPW = NULL;
134     index = NSSUTIL_ArgStrip(param);
135 
136     PORT_Memset(parsed, 0, sizeof(sftk_parameters));
137 
138     while (*index) {
139         NSSUTIL_HANDLE_STRING_ARG(index, parsed->configdir, "configDir=", ;)
140         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updatedir, "updateDir=", ;)
141         NSSUTIL_HANDLE_STRING_ARG(index, parsed->updateID, "updateID=", ;)
142         NSSUTIL_HANDLE_STRING_ARG(index, parsed->secmodName, "secmod=", ;)
143         NSSUTIL_HANDLE_STRING_ARG(index, parsed->man, "manufacturerID=", ;)
144         NSSUTIL_HANDLE_STRING_ARG(index, parsed->libdes, "libraryDescription=", ;)
145         /* constructed values, used so legacy interfaces still work */
146         NSSUTIL_HANDLE_STRING_ARG(index, certPrefix, "certPrefix=", ;)
147         NSSUTIL_HANDLE_STRING_ARG(index, keyPrefix, "keyPrefix=", ;)
148         NSSUTIL_HANDLE_STRING_ARG(index, tokdes, "cryptoTokenDescription=", ;)
149         NSSUTIL_HANDLE_STRING_ARG(index, ptokdes, "dbTokenDescription=", ;)
150         NSSUTIL_HANDLE_STRING_ARG(index, slotdes, "cryptoSlotDescription=", ;)
151         NSSUTIL_HANDLE_STRING_ARG(index, pslotdes, "dbSlotDescription=", ;)
152         NSSUTIL_HANDLE_STRING_ARG(index, fslotdes, "FIPSSlotDescription=", ;)
153         NSSUTIL_HANDLE_STRING_ARG(index, ftokdes, "FIPSTokenDescription=", ;)
154         NSSUTIL_HANDLE_STRING_ARG(index, pupdtokdes, "updateTokenDescription=", ;)
155         NSSUTIL_HANDLE_STRING_ARG(index, minPW, "minPWLen=", ;)
156 
157         NSSUTIL_HANDLE_STRING_ARG(index, tmp, "flags=",
158                                   if (tmp) { sftk_parseFlags(param,parsed); PORT_Free(tmp); tmp = NULL; })
159         NSSUTIL_HANDLE_STRING_ARG(index, tmp, "tokens=",
160                                   if (tmp) { sftk_parseTokens(tmp,parsed); PORT_Free(tmp); tmp = NULL; })
161         NSSUTIL_HANDLE_FINAL_ARG(index)
162     }
163     if (parsed->tokens == NULL) {
164         int count = isFIPS ? 1 : 2;
165         int i = count - 1;
166         sftk_token_parameters *tokens = NULL;
167 
168         tokens = (sftk_token_parameters *)
169             PORT_ZAlloc(count * sizeof(sftk_token_parameters));
170         if (tokens == NULL) {
171             goto loser;
172         }
173         parsed->tokens = tokens;
174         parsed->token_count = count;
175         tokens[i].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
176         tokens[i].certPrefix = certPrefix;
177         tokens[i].keyPrefix = keyPrefix;
178         tokens[i].minPW = minPW ? atoi(minPW) : 0;
179         tokens[i].readOnly = parsed->readOnly;
180         tokens[i].noCertDB = parsed->noCertDB;
181         tokens[i].noKeyDB = parsed->noCertDB;
182         tokens[i].forceOpen = parsed->forceOpen;
183         tokens[i].pwRequired = parsed->pwRequired;
184         tokens[i].optimizeSpace = parsed->optimizeSpace;
185         tokens[0].optimizeSpace = parsed->optimizeSpace;
186         certPrefix = NULL;
187         keyPrefix = NULL;
188         if (isFIPS) {
189             tokens[i].tokdes = ftokdes;
190             tokens[i].updtokdes = pupdtokdes;
191             tokens[i].slotdes = fslotdes;
192             fslotdes = NULL;
193             ftokdes = NULL;
194             pupdtokdes = NULL;
195         } else {
196             tokens[i].tokdes = ptokdes;
197             tokens[i].updtokdes = pupdtokdes;
198             tokens[i].slotdes = pslotdes;
199             tokens[0].slotID = NETSCAPE_SLOT_ID;
200             tokens[0].tokdes = tokdes;
201             tokens[0].slotdes = slotdes;
202             tokens[0].noCertDB = PR_TRUE;
203             tokens[0].noKeyDB = PR_TRUE;
204             pupdtokdes = NULL;
205             ptokdes = NULL;
206             pslotdes = NULL;
207             tokdes = NULL;
208             slotdes = NULL;
209         }
210     }
211 
212 loser:
213     FREE_CLEAR(certPrefix);
214     FREE_CLEAR(keyPrefix);
215     FREE_CLEAR(tokdes);
216     FREE_CLEAR(ptokdes);
217     FREE_CLEAR(pupdtokdes);
218     FREE_CLEAR(slotdes);
219     FREE_CLEAR(pslotdes);
220     FREE_CLEAR(fslotdes);
221     FREE_CLEAR(ftokdes);
222     FREE_CLEAR(minPW);
223     return CKR_OK;
224 }
225 
226 void
sftk_freeParams(sftk_parameters * params)227 sftk_freeParams(sftk_parameters *params)
228 {
229     int i;
230 
231     for (i = 0; i < params->token_count; i++) {
232         FREE_CLEAR(params->tokens[i].configdir);
233         FREE_CLEAR(params->tokens[i].certPrefix);
234         FREE_CLEAR(params->tokens[i].keyPrefix);
235         FREE_CLEAR(params->tokens[i].tokdes);
236         FREE_CLEAR(params->tokens[i].slotdes);
237         FREE_CLEAR(params->tokens[i].updatedir);
238         FREE_CLEAR(params->tokens[i].updCertPrefix);
239         FREE_CLEAR(params->tokens[i].updKeyPrefix);
240         FREE_CLEAR(params->tokens[i].updateID);
241         FREE_CLEAR(params->tokens[i].updtokdes);
242     }
243 
244     FREE_CLEAR(params->configdir);
245     FREE_CLEAR(params->secmodName);
246     FREE_CLEAR(params->man);
247     FREE_CLEAR(params->libdes);
248     FREE_CLEAR(params->tokens);
249     FREE_CLEAR(params->updatedir);
250     FREE_CLEAR(params->updateID);
251 }
252