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