| 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 |