OLD | NEW |
| (Empty) |
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 #ifndef BUILTINS_H | |
6 #include "builtins.h" | |
7 #endif /* BUILTINS_H */ | |
8 | |
9 /* | |
10 * builtins/find.c | |
11 * | |
12 * This file implements the NSSCKMDFindObjects object for the | |
13 * "builtin objects" cryptoki module. | |
14 */ | |
15 | |
16 struct builtinsFOStr { | |
17 NSSArena *arena; | |
18 CK_ULONG n; | |
19 CK_ULONG i; | |
20 builtinsInternalObject **objs; | |
21 }; | |
22 | |
23 static void | |
24 builtins_mdFindObjects_Final( | |
25 NSSCKMDFindObjects *mdFindObjects, | |
26 NSSCKFWFindObjects *fwFindObjects, | |
27 NSSCKMDSession *mdSession, | |
28 NSSCKFWSession *fwSession, | |
29 NSSCKMDToken *mdToken, | |
30 NSSCKFWToken *fwToken, | |
31 NSSCKMDInstance *mdInstance, | |
32 NSSCKFWInstance *fwInstance) | |
33 { | |
34 struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; | |
35 NSSArena *arena = fo->arena; | |
36 | |
37 nss_ZFreeIf(fo->objs); | |
38 nss_ZFreeIf(fo); | |
39 nss_ZFreeIf(mdFindObjects); | |
40 if ((NSSArena *)NULL != arena) { | |
41 NSSArena_Destroy(arena); | |
42 } | |
43 | |
44 return; | |
45 } | |
46 | |
47 static NSSCKMDObject * | |
48 builtins_mdFindObjects_Next( | |
49 NSSCKMDFindObjects *mdFindObjects, | |
50 NSSCKFWFindObjects *fwFindObjects, | |
51 NSSCKMDSession *mdSession, | |
52 NSSCKFWSession *fwSession, | |
53 NSSCKMDToken *mdToken, | |
54 NSSCKFWToken *fwToken, | |
55 NSSCKMDInstance *mdInstance, | |
56 NSSCKFWInstance *fwInstance, | |
57 NSSArena *arena, | |
58 CK_RV *pError) | |
59 { | |
60 struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc; | |
61 builtinsInternalObject *io; | |
62 | |
63 if (fo->i == fo->n) { | |
64 *pError = CKR_OK; | |
65 return (NSSCKMDObject *)NULL; | |
66 } | |
67 | |
68 io = fo->objs[fo->i]; | |
69 fo->i++; | |
70 | |
71 return nss_builtins_CreateMDObject(arena, io, pError); | |
72 } | |
73 | |
74 static int | |
75 builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) | |
76 { | |
77 unsigned char *start = src; | |
78 int len = 0; | |
79 | |
80 if (*src++ != 2) { | |
81 return 0; | |
82 } | |
83 len = *src++; | |
84 if (len & 0x80) { | |
85 int count = len & 0x7f; | |
86 len = 0; | |
87 | |
88 if (count + 2 > size) { | |
89 return 0; | |
90 } | |
91 while (count-- > 0) { | |
92 len = (len << 8) | *src++; | |
93 } | |
94 } | |
95 if (len + (src - start) != size) { | |
96 return 0; | |
97 } | |
98 *dest = src; | |
99 return len; | |
100 } | |
101 | |
102 static CK_BBOOL | |
103 builtins_attrmatch( | |
104 CK_ATTRIBUTE_PTR a, | |
105 const NSSItem *b) | |
106 { | |
107 PRBool prb; | |
108 | |
109 if (a->ulValueLen != b->size) { | |
110 /* match a decoded serial number */ | |
111 if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) { | |
112 int len; | |
113 unsigned char *data = NULL; | |
114 | |
115 len = builtins_derUnwrapInt(b->data, b->size, &data); | |
116 if (data && | |
117 (len == a->ulValueLen) && | |
118 nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) { | |
119 return CK_TRUE; | |
120 } | |
121 } | |
122 return CK_FALSE; | |
123 } | |
124 | |
125 prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL); | |
126 | |
127 if (PR_TRUE == prb) { | |
128 return CK_TRUE; | |
129 } else { | |
130 return CK_FALSE; | |
131 } | |
132 } | |
133 | |
134 static CK_BBOOL | |
135 builtins_match( | |
136 CK_ATTRIBUTE_PTR pTemplate, | |
137 CK_ULONG ulAttributeCount, | |
138 builtinsInternalObject *o) | |
139 { | |
140 CK_ULONG i; | |
141 | |
142 for (i = 0; i < ulAttributeCount; i++) { | |
143 CK_ULONG j; | |
144 | |
145 for (j = 0; j < o->n; j++) { | |
146 if (o->types[j] == pTemplate[i].type) { | |
147 if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]))
{ | |
148 return CK_FALSE; | |
149 } else { | |
150 break; | |
151 } | |
152 } | |
153 } | |
154 | |
155 if (j == o->n) { | |
156 /* Loop ran to the end: no matching attribute */ | |
157 return CK_FALSE; | |
158 } | |
159 } | |
160 | |
161 /* Every attribute passed */ | |
162 return CK_TRUE; | |
163 } | |
164 | |
165 NSS_IMPLEMENT NSSCKMDFindObjects * | |
166 nss_builtins_FindObjectsInit( | |
167 NSSCKFWSession *fwSession, | |
168 CK_ATTRIBUTE_PTR pTemplate, | |
169 CK_ULONG ulAttributeCount, | |
170 CK_RV *pError) | |
171 { | |
172 /* This could be made more efficient. I'm rather rushed. */ | |
173 NSSArena *arena; | |
174 NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; | |
175 struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; | |
176 | |
177 /* | |
178 * 99% of the time we get 0 or 1 matches. So we start with a small | |
179 * stack-allocated array to hold the matches and switch to a heap-allocated | |
180 * array later if the number of matches exceeds STACK_BUF_LENGTH. | |
181 */ | |
182 #define STACK_BUF_LENGTH 1 | |
183 builtinsInternalObject *stackTemp[STACK_BUF_LENGTH]; | |
184 builtinsInternalObject **temp = stackTemp; | |
185 PRBool tempIsHeapAllocated = PR_FALSE; | |
186 PRUint32 i; | |
187 | |
188 arena = NSSArena_Create(); | |
189 if ((NSSArena *)NULL == arena) { | |
190 goto loser; | |
191 } | |
192 | |
193 rv = nss_ZNEW(arena, NSSCKMDFindObjects); | |
194 if ((NSSCKMDFindObjects *)NULL == rv) { | |
195 *pError = CKR_HOST_MEMORY; | |
196 goto loser; | |
197 } | |
198 | |
199 fo = nss_ZNEW(arena, struct builtinsFOStr); | |
200 if ((struct builtinsFOStr *)NULL == fo) { | |
201 *pError = CKR_HOST_MEMORY; | |
202 goto loser; | |
203 } | |
204 | |
205 fo->arena = arena; | |
206 /* fo->n and fo->i are already zero */ | |
207 | |
208 rv->etc = (void *)fo; | |
209 rv->Final = builtins_mdFindObjects_Final; | |
210 rv->Next = builtins_mdFindObjects_Next; | |
211 rv->null = (void *)NULL; | |
212 | |
213 for (i = 0; i < nss_builtins_nObjects; i++) { | |
214 builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data
[i]; | |
215 | |
216 if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) { | |
217 if (fo->n == STACK_BUF_LENGTH) { | |
218 /* Switch from the small stack array to a heap-allocated array l
arge | |
219 * enough to handle matches in all remaining cases. */ | |
220 temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, | |
221 fo->n + nss_builtins_nObjects - i); | |
222 if ((builtinsInternalObject **)NULL == temp) { | |
223 *pError = | |
224 CKR_HOST_MEMORY; | |
225 goto loser; | |
226 } | |
227 tempIsHeapAllocated = PR_TRUE; | |
228 (void)nsslibc_memcpy(temp, stackTemp, | |
229 sizeof(builtinsInternalObject *) * fo->n); | |
230 } | |
231 | |
232 temp[fo->n] = o; | |
233 fo->n++; | |
234 } | |
235 } | |
236 | |
237 fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); | |
238 if ((builtinsInternalObject **)NULL == fo->objs) { | |
239 *pError = CKR_HOST_MEMORY; | |
240 goto loser; | |
241 } | |
242 | |
243 (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->
n); | |
244 if (tempIsHeapAllocated) { | |
245 nss_ZFreeIf(temp); | |
246 temp = (builtinsInternalObject **)NULL; | |
247 } | |
248 | |
249 return rv; | |
250 | |
251 loser: | |
252 if (tempIsHeapAllocated) { | |
253 nss_ZFreeIf(temp); | |
254 } | |
255 nss_ZFreeIf(fo); | |
256 nss_ZFreeIf(rv); | |
257 if ((NSSArena *)NULL != arena) { | |
258 NSSArena_Destroy(arena); | |
259 } | |
260 return (NSSCKMDFindObjects *)NULL; | |
261 } | |
OLD | NEW |