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 #include "ckdbm.h"
6 
7 static CK_RV
nss_dbm_mdToken_Setup(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance)8 nss_dbm_mdToken_Setup(
9     NSSCKMDToken *mdToken,
10     NSSCKFWToken *fwToken,
11     NSSCKMDInstance *mdInstance,
12     NSSCKFWInstance *fwInstance)
13 {
14     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
15     CK_RV rv = CKR_OK;
16 
17     token->arena = NSSCKFWToken_GetArena(fwToken, &rv);
18     token->session_db = nss_dbm_db_open(token->arena, fwInstance, (char *)NULL,
19                                         O_RDWR | O_CREAT, &rv);
20     if ((nss_dbm_db_t *)NULL == token->session_db) {
21         return rv;
22     }
23 
24     /* Add a label record if there isn't one? */
25 
26     return CKR_OK;
27 }
28 
29 static void
nss_dbm_mdToken_Invalidate(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance)30 nss_dbm_mdToken_Invalidate(
31     NSSCKMDToken *mdToken,
32     NSSCKFWToken *fwToken,
33     NSSCKMDInstance *mdInstance,
34     NSSCKFWInstance *fwInstance)
35 {
36     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
37 
38     if ((nss_dbm_db_t *)NULL != token->session_db) {
39         nss_dbm_db_close(token->session_db);
40         token->session_db = (nss_dbm_db_t *)NULL;
41     }
42 }
43 
44 static CK_RV
nss_dbm_mdToken_InitToken(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance,NSSItem * pin,NSSUTF8 * label)45 nss_dbm_mdToken_InitToken(
46     NSSCKMDToken *mdToken,
47     NSSCKFWToken *fwToken,
48     NSSCKMDInstance *mdInstance,
49     NSSCKFWInstance *fwInstance,
50     NSSItem *pin,
51     NSSUTF8 *label)
52 {
53     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
54     nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
55     CK_RV rv;
56 
57     /* Wipe the session object data */
58 
59     if ((nss_dbm_db_t *)NULL != token->session_db) {
60         nss_dbm_db_close(token->session_db);
61     }
62 
63     token->session_db = nss_dbm_db_open(token->arena, fwInstance, (char *)NULL,
64                                         O_RDWR | O_CREAT, &rv);
65     if ((nss_dbm_db_t *)NULL == token->session_db) {
66         return rv;
67     }
68 
69     /* Wipe the token object data */
70 
71     if (token->slot->flags & O_RDWR) {
72         if ((nss_dbm_db_t *)NULL != token->slot->token_db) {
73             nss_dbm_db_close(token->slot->token_db);
74         }
75 
76         token->slot->token_db = nss_dbm_db_open(instance->arena, fwInstance,
77                                                 token->slot->filename,
78                                                 token->slot->flags | O_CREAT | O_TRUNC,
79                                                 &rv);
80         if ((nss_dbm_db_t *)NULL == token->slot->token_db) {
81             return rv;
82         }
83 
84         /* PIN is irrelevant */
85 
86         rv = nss_dbm_db_set_label(token->slot->token_db, label);
87         if (CKR_OK != rv) {
88             return rv;
89         }
90     }
91 
92     return CKR_OK;
93 }
94 
95 static NSSUTF8 *
nss_dbm_mdToken_GetLabel(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance,CK_RV * pError)96 nss_dbm_mdToken_GetLabel(
97     NSSCKMDToken *mdToken,
98     NSSCKFWToken *fwToken,
99     NSSCKMDInstance *mdInstance,
100     NSSCKFWInstance *fwInstance,
101     CK_RV *pError)
102 {
103     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
104 
105     if ((NSSUTF8 *)NULL == token->label) {
106         token->label = nss_dbm_db_get_label(token->slot->token_db, token->arena, pError);
107     }
108 
109     /* If no label has been set, return *something* */
110     if ((NSSUTF8 *)NULL == token->label) {
111         return token->slot->filename;
112     }
113 
114     return token->label;
115 }
116 
117 static NSSUTF8 *
nss_dbm_mdToken_GetManufacturerID(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance,CK_RV * pError)118 nss_dbm_mdToken_GetManufacturerID(
119     NSSCKMDToken *mdToken,
120     NSSCKFWToken *fwToken,
121     NSSCKMDInstance *mdInstance,
122     NSSCKFWInstance *fwInstance,
123     CK_RV *pError)
124 {
125     return "mozilla.org NSS";
126 }
127 
128 static NSSUTF8 *
nss_dbm_mdToken_GetModel(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance,CK_RV * pError)129 nss_dbm_mdToken_GetModel(
130     NSSCKMDToken *mdToken,
131     NSSCKFWToken *fwToken,
132     NSSCKMDInstance *mdInstance,
133     NSSCKFWInstance *fwInstance,
134     CK_RV *pError)
135 {
136     return "dbm";
137 }
138 
139 /* GetSerialNumber is irrelevant */
140 /* GetHasRNG defaults to CK_FALSE */
141 
142 static CK_BBOOL
nss_dbm_mdToken_GetIsWriteProtected(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance)143 nss_dbm_mdToken_GetIsWriteProtected(
144     NSSCKMDToken *mdToken,
145     NSSCKFWToken *fwToken,
146     NSSCKMDInstance *mdInstance,
147     NSSCKFWInstance *fwInstance)
148 {
149     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
150 
151     if (token->slot->flags & O_RDWR) {
152         return CK_FALSE;
153     } else {
154         return CK_TRUE;
155     }
156 }
157 
158 /* GetLoginRequired defaults to CK_FALSE */
159 /* GetUserPinInitialized defaults to CK_FALSE */
160 /* GetRestoreKeyNotNeeded is irrelevant */
161 /* GetHasClockOnToken defaults to CK_FALSE */
162 /* GetHasProtectedAuthenticationPath defaults to CK_FALSE */
163 /* GetSupportsDualCryptoOperations is irrelevant */
164 
165 static CK_ULONG
nss_dbm_mdToken_effectively_infinite(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance)166 nss_dbm_mdToken_effectively_infinite(
167     NSSCKMDToken *mdToken,
168     NSSCKFWToken *fwToken,
169     NSSCKMDInstance *mdInstance,
170     NSSCKFWInstance *fwInstance)
171 {
172     return CK_EFFECTIVELY_INFINITE;
173 }
174 
175 static CK_VERSION
nss_dbm_mdToken_GetHardwareVersion(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance)176 nss_dbm_mdToken_GetHardwareVersion(
177     NSSCKMDToken *mdToken,
178     NSSCKFWToken *fwToken,
179     NSSCKMDInstance *mdInstance,
180     NSSCKFWInstance *fwInstance)
181 {
182     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
183     return nss_dbm_db_get_format_version(token->slot->token_db);
184 }
185 
186 /* GetFirmwareVersion is irrelevant */
187 /* GetUTCTime is irrelevant */
188 
189 static NSSCKMDSession *
nss_dbm_mdToken_OpenSession(NSSCKMDToken * mdToken,NSSCKFWToken * fwToken,NSSCKMDInstance * mdInstance,NSSCKFWInstance * fwInstance,NSSCKFWSession * fwSession,CK_BBOOL rw,CK_RV * pError)190 nss_dbm_mdToken_OpenSession(
191     NSSCKMDToken *mdToken,
192     NSSCKFWToken *fwToken,
193     NSSCKMDInstance *mdInstance,
194     NSSCKFWInstance *fwInstance,
195     NSSCKFWSession *fwSession,
196     CK_BBOOL rw,
197     CK_RV *pError)
198 {
199     nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
200     return nss_dbm_mdSession_factory(token, fwSession, fwInstance, rw, pError);
201 }
202 
203 /* GetMechanismCount defaults to zero */
204 /* GetMechanismTypes is irrelevant */
205 /* GetMechanism is irrelevant */
206 
207 NSS_IMPLEMENT NSSCKMDToken *
nss_dbm_mdToken_factory(nss_dbm_slot_t * slot,CK_RV * pError)208 nss_dbm_mdToken_factory(
209     nss_dbm_slot_t *slot,
210     CK_RV *pError)
211 {
212     nss_dbm_token_t *token;
213     NSSCKMDToken *rv;
214 
215     token = nss_ZNEW(slot->instance->arena, nss_dbm_token_t);
216     if ((nss_dbm_token_t *)NULL == token) {
217         *pError = CKR_HOST_MEMORY;
218         return (NSSCKMDToken *)NULL;
219     }
220 
221     rv = nss_ZNEW(slot->instance->arena, NSSCKMDToken);
222     if ((NSSCKMDToken *)NULL == rv) {
223         *pError = CKR_HOST_MEMORY;
224         return (NSSCKMDToken *)NULL;
225     }
226 
227     token->slot = slot;
228 
229     rv->etc = (void *)token;
230     rv->Setup = nss_dbm_mdToken_Setup;
231     rv->Invalidate = nss_dbm_mdToken_Invalidate;
232     rv->InitToken = nss_dbm_mdToken_InitToken;
233     rv->GetLabel = nss_dbm_mdToken_GetLabel;
234     rv->GetManufacturerID = nss_dbm_mdToken_GetManufacturerID;
235     rv->GetModel = nss_dbm_mdToken_GetModel;
236     /*  GetSerialNumber is irrelevant */
237     /*  GetHasRNG defaults to CK_FALSE */
238     rv->GetIsWriteProtected = nss_dbm_mdToken_GetIsWriteProtected;
239     /*  GetLoginRequired defaults to CK_FALSE */
240     /*  GetUserPinInitialized defaults to CK_FALSE */
241     /*  GetRestoreKeyNotNeeded is irrelevant */
242     /*  GetHasClockOnToken defaults to CK_FALSE */
243     /*  GetHasProtectedAuthenticationPath defaults to CK_FALSE */
244     /*  GetSupportsDualCryptoOperations is irrelevant */
245     rv->GetMaxSessionCount = nss_dbm_mdToken_effectively_infinite;
246     rv->GetMaxRwSessionCount = nss_dbm_mdToken_effectively_infinite;
247     /*  GetMaxPinLen is irrelevant */
248     /*  GetMinPinLen is irrelevant */
249     /*  GetTotalPublicMemory defaults to CK_UNAVAILABLE_INFORMATION */
250     /*  GetFreePublicMemory defaults to CK_UNAVAILABLE_INFORMATION */
251     /*  GetTotalPrivateMemory defaults to CK_UNAVAILABLE_INFORMATION */
252     /*  GetFreePrivateMemory defaults to CK_UNAVAILABLE_INFORMATION */
253     rv->GetHardwareVersion = nss_dbm_mdToken_GetHardwareVersion;
254     /*  GetFirmwareVersion is irrelevant */
255     /*  GetUTCTime is irrelevant */
256     rv->OpenSession = nss_dbm_mdToken_OpenSession;
257     rv->null = NULL;
258 
259     return rv;
260 }
261