security/nss/lib/ckfw/capi/cfind.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef CKCAPI_H
michael@0 6 #include "ckcapi.h"
michael@0 7 #endif /* CKCAPI_H */
michael@0 8
michael@0 9 /*
michael@0 10 * ckcapi/cfind.c
michael@0 11 *
michael@0 12 * This file implements the NSSCKMDFindObjects object for the
michael@0 13 * "capi" cryptoki module.
michael@0 14 */
michael@0 15
michael@0 16 struct ckcapiFOStr {
michael@0 17 NSSArena *arena;
michael@0 18 CK_ULONG n;
michael@0 19 CK_ULONG i;
michael@0 20 ckcapiInternalObject **objs;
michael@0 21 };
michael@0 22
michael@0 23 static void
michael@0 24 ckcapi_mdFindObjects_Final
michael@0 25 (
michael@0 26 NSSCKMDFindObjects *mdFindObjects,
michael@0 27 NSSCKFWFindObjects *fwFindObjects,
michael@0 28 NSSCKMDSession *mdSession,
michael@0 29 NSSCKFWSession *fwSession,
michael@0 30 NSSCKMDToken *mdToken,
michael@0 31 NSSCKFWToken *fwToken,
michael@0 32 NSSCKMDInstance *mdInstance,
michael@0 33 NSSCKFWInstance *fwInstance
michael@0 34 )
michael@0 35 {
michael@0 36 struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
michael@0 37 NSSArena *arena = fo->arena;
michael@0 38 PRUint32 i;
michael@0 39
michael@0 40 /* walk down an free the unused 'objs' */
michael@0 41 for (i=fo->i; i < fo->n ; i++) {
michael@0 42 nss_ckcapi_DestroyInternalObject(fo->objs[i]);
michael@0 43 }
michael@0 44
michael@0 45 nss_ZFreeIf(fo->objs);
michael@0 46 nss_ZFreeIf(fo);
michael@0 47 nss_ZFreeIf(mdFindObjects);
michael@0 48 if ((NSSArena *)NULL != arena) {
michael@0 49 NSSArena_Destroy(arena);
michael@0 50 }
michael@0 51
michael@0 52 return;
michael@0 53 }
michael@0 54
michael@0 55 static NSSCKMDObject *
michael@0 56 ckcapi_mdFindObjects_Next
michael@0 57 (
michael@0 58 NSSCKMDFindObjects *mdFindObjects,
michael@0 59 NSSCKFWFindObjects *fwFindObjects,
michael@0 60 NSSCKMDSession *mdSession,
michael@0 61 NSSCKFWSession *fwSession,
michael@0 62 NSSCKMDToken *mdToken,
michael@0 63 NSSCKFWToken *fwToken,
michael@0 64 NSSCKMDInstance *mdInstance,
michael@0 65 NSSCKFWInstance *fwInstance,
michael@0 66 NSSArena *arena,
michael@0 67 CK_RV *pError
michael@0 68 )
michael@0 69 {
michael@0 70 struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
michael@0 71 ckcapiInternalObject *io;
michael@0 72
michael@0 73 if( fo->i == fo->n ) {
michael@0 74 *pError = CKR_OK;
michael@0 75 return (NSSCKMDObject *)NULL;
michael@0 76 }
michael@0 77
michael@0 78 io = fo->objs[ fo->i ];
michael@0 79 fo->i++;
michael@0 80
michael@0 81 return nss_ckcapi_CreateMDObject(arena, io, pError);
michael@0 82 }
michael@0 83
michael@0 84 static CK_BBOOL
michael@0 85 ckcapi_attrmatch
michael@0 86 (
michael@0 87 CK_ATTRIBUTE_PTR a,
michael@0 88 ckcapiInternalObject *o
michael@0 89 )
michael@0 90 {
michael@0 91 PRBool prb;
michael@0 92 const NSSItem *b;
michael@0 93
michael@0 94 b = nss_ckcapi_FetchAttribute(o, a->type);
michael@0 95 if (b == NULL) {
michael@0 96 return CK_FALSE;
michael@0 97 }
michael@0 98
michael@0 99 if( a->ulValueLen != b->size ) {
michael@0 100 /* match a decoded serial number */
michael@0 101 if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
michael@0 102 unsigned int len;
michael@0 103 unsigned char *data;
michael@0 104
michael@0 105 data = nss_ckcapi_DERUnwrap(b->data, b->size, &len, NULL);
michael@0 106 if ((len == a->ulValueLen) &&
michael@0 107 nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
michael@0 108 return CK_TRUE;
michael@0 109 }
michael@0 110 }
michael@0 111 return CK_FALSE;
michael@0 112 }
michael@0 113
michael@0 114 prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
michael@0 115
michael@0 116 if( PR_TRUE == prb ) {
michael@0 117 return CK_TRUE;
michael@0 118 } else {
michael@0 119 return CK_FALSE;
michael@0 120 }
michael@0 121 }
michael@0 122
michael@0 123
michael@0 124 static CK_BBOOL
michael@0 125 ckcapi_match
michael@0 126 (
michael@0 127 CK_ATTRIBUTE_PTR pTemplate,
michael@0 128 CK_ULONG ulAttributeCount,
michael@0 129 ckcapiInternalObject *o
michael@0 130 )
michael@0 131 {
michael@0 132 CK_ULONG i;
michael@0 133
michael@0 134 for( i = 0; i < ulAttributeCount; i++ ) {
michael@0 135 if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
michael@0 136 return CK_FALSE;
michael@0 137 }
michael@0 138 }
michael@0 139
michael@0 140 /* Every attribute passed */
michael@0 141 return CK_TRUE;
michael@0 142 }
michael@0 143
michael@0 144 #define CKAPI_ITEM_CHUNK 20
michael@0 145
michael@0 146 #define PUT_Object(obj,err) \
michael@0 147 { \
michael@0 148 if (count >= size) { \
michael@0 149 *listp = *listp ? \
michael@0 150 nss_ZREALLOCARRAY(*listp, ckcapiInternalObject *, \
michael@0 151 (size+CKAPI_ITEM_CHUNK) ) : \
michael@0 152 nss_ZNEWARRAY(NULL, ckcapiInternalObject *, \
michael@0 153 (size+CKAPI_ITEM_CHUNK) ) ; \
michael@0 154 if ((ckcapiInternalObject **)NULL == *listp) { \
michael@0 155 err = CKR_HOST_MEMORY; \
michael@0 156 goto loser; \
michael@0 157 } \
michael@0 158 size += CKAPI_ITEM_CHUNK; \
michael@0 159 } \
michael@0 160 (*listp)[ count ] = (obj); \
michael@0 161 count++; \
michael@0 162 }
michael@0 163
michael@0 164
michael@0 165 /*
michael@0 166 * pass parameters back through the callback.
michael@0 167 */
michael@0 168 typedef struct BareCollectParamsStr {
michael@0 169 CK_OBJECT_CLASS objClass;
michael@0 170 CK_ATTRIBUTE_PTR pTemplate;
michael@0 171 CK_ULONG ulAttributeCount;
michael@0 172 ckcapiInternalObject ***listp;
michael@0 173 PRUint32 size;
michael@0 174 PRUint32 count;
michael@0 175 } BareCollectParams;
michael@0 176
michael@0 177 /* collect_bare's callback. Called for each object that
michael@0 178 * supposedly has a PROVINDER_INFO property */
michael@0 179 static BOOL WINAPI
michael@0 180 doBareCollect
michael@0 181 (
michael@0 182 const CRYPT_HASH_BLOB *msKeyID,
michael@0 183 DWORD flags,
michael@0 184 void *reserved,
michael@0 185 void *args,
michael@0 186 DWORD cProp,
michael@0 187 DWORD *propID,
michael@0 188 void **propData,
michael@0 189 DWORD *propSize
michael@0 190 )
michael@0 191 {
michael@0 192 BareCollectParams *bcp = (BareCollectParams *) args;
michael@0 193 PRUint32 size = bcp->size;
michael@0 194 PRUint32 count = bcp->count;
michael@0 195 ckcapiInternalObject ***listp = bcp->listp;
michael@0 196 ckcapiInternalObject *io = NULL;
michael@0 197 DWORD i;
michael@0 198 CRYPT_KEY_PROV_INFO *keyProvInfo = NULL;
michael@0 199 void *idData;
michael@0 200 CK_RV error;
michael@0 201
michael@0 202 /* make sure there is a Key Provider Info property */
michael@0 203 for (i=0; i < cProp; i++) {
michael@0 204 if (CERT_KEY_PROV_INFO_PROP_ID == propID[i]) {
michael@0 205 keyProvInfo = (CRYPT_KEY_PROV_INFO *)propData[i];
michael@0 206 break;
michael@0 207 }
michael@0 208 }
michael@0 209 if ((CRYPT_KEY_PROV_INFO *)NULL == keyProvInfo) {
michael@0 210 return 1;
michael@0 211 }
michael@0 212
michael@0 213 /* copy the key ID */
michael@0 214 idData = nss_ZNEWARRAY(NULL, char, msKeyID->cbData);
michael@0 215 if ((void *)NULL == idData) {
michael@0 216 goto loser;
michael@0 217 }
michael@0 218 nsslibc_memcpy(idData, msKeyID->pbData, msKeyID->cbData);
michael@0 219
michael@0 220 /* build a bare internal object */
michael@0 221 io = nss_ZNEW(NULL, ckcapiInternalObject);
michael@0 222 if ((ckcapiInternalObject *)NULL == io) {
michael@0 223 goto loser;
michael@0 224 }
michael@0 225 io->type = ckcapiBareKey;
michael@0 226 io->objClass = bcp->objClass;
michael@0 227 io->u.key.provInfo = *keyProvInfo;
michael@0 228 io->u.key.provInfo.pwszContainerName =
michael@0 229 nss_ckcapi_WideDup(keyProvInfo->pwszContainerName);
michael@0 230 io->u.key.provInfo.pwszProvName =
michael@0 231 nss_ckcapi_WideDup(keyProvInfo->pwszProvName);
michael@0 232 io->u.key.provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
michael@0 233 io->u.key.containerName =
michael@0 234 nss_ckcapi_WideToUTF8(keyProvInfo->pwszContainerName);
michael@0 235 io->u.key.hProv = 0;
michael@0 236 io->idData = idData;
michael@0 237 io->id.data = idData;
michael@0 238 io->id.size = msKeyID->cbData;
michael@0 239 idData = NULL;
michael@0 240
michael@0 241 /* see if it matches */
michael@0 242 if( CK_FALSE == ckcapi_match(bcp->pTemplate, bcp->ulAttributeCount, io) ) {
michael@0 243 goto loser;
michael@0 244 }
michael@0 245 PUT_Object(io, error);
michael@0 246 bcp->size = size;
michael@0 247 bcp->count = count;
michael@0 248 return 1;
michael@0 249
michael@0 250 loser:
michael@0 251 if (io) {
michael@0 252 nss_ckcapi_DestroyInternalObject(io);
michael@0 253 }
michael@0 254 nss_ZFreeIf(idData);
michael@0 255 return 1;
michael@0 256 }
michael@0 257
michael@0 258 /*
michael@0 259 * collect the bare keys running around
michael@0 260 */
michael@0 261 static PRUint32
michael@0 262 collect_bare(
michael@0 263 CK_OBJECT_CLASS objClass,
michael@0 264 CK_ATTRIBUTE_PTR pTemplate,
michael@0 265 CK_ULONG ulAttributeCount,
michael@0 266 ckcapiInternalObject ***listp,
michael@0 267 PRUint32 *sizep,
michael@0 268 PRUint32 count,
michael@0 269 CK_RV *pError
michael@0 270 )
michael@0 271 {
michael@0 272 BOOL rc;
michael@0 273 BareCollectParams bareCollectParams;
michael@0 274
michael@0 275 bareCollectParams.objClass = objClass;
michael@0 276 bareCollectParams.pTemplate = pTemplate;
michael@0 277 bareCollectParams.ulAttributeCount = ulAttributeCount;
michael@0 278 bareCollectParams.listp = listp;
michael@0 279 bareCollectParams.size = *sizep;
michael@0 280 bareCollectParams.count = count;
michael@0 281
michael@0 282 rc = CryptEnumKeyIdentifierProperties(NULL, CERT_KEY_PROV_INFO_PROP_ID, 0,
michael@0 283 NULL, NULL, &bareCollectParams, doBareCollect);
michael@0 284
michael@0 285 *sizep = bareCollectParams.size;
michael@0 286 return bareCollectParams.count;
michael@0 287 }
michael@0 288
michael@0 289 /* find all the certs that represent the appropriate object (cert, priv key, or
michael@0 290 * pub key) in the cert store.
michael@0 291 */
michael@0 292 static PRUint32
michael@0 293 collect_class(
michael@0 294 CK_OBJECT_CLASS objClass,
michael@0 295 LPCSTR storeStr,
michael@0 296 PRBool hasID,
michael@0 297 CK_ATTRIBUTE_PTR pTemplate,
michael@0 298 CK_ULONG ulAttributeCount,
michael@0 299 ckcapiInternalObject ***listp,
michael@0 300 PRUint32 *sizep,
michael@0 301 PRUint32 count,
michael@0 302 CK_RV *pError
michael@0 303 )
michael@0 304 {
michael@0 305 PRUint32 size = *sizep;
michael@0 306 ckcapiInternalObject *next = NULL;
michael@0 307 HCERTSTORE hStore;
michael@0 308 PCCERT_CONTEXT certContext = NULL;
michael@0 309 PRBool isKey =
michael@0 310 (objClass == CKO_PUBLIC_KEY) | (objClass == CKO_PRIVATE_KEY);
michael@0 311
michael@0 312 hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
michael@0 313 if (NULL == hStore) {
michael@0 314 return count; /* none found does not imply an error */
michael@0 315 }
michael@0 316
michael@0 317 /* FUTURE: use CertFindCertificateInStore to filter better -- so we don't
michael@0 318 * have to enumerate all the certificates */
michael@0 319 while ((PCERT_CONTEXT) NULL !=
michael@0 320 (certContext= CertEnumCertificatesInStore(hStore, certContext))) {
michael@0 321 /* first filter out non user certs if we are looking for keys */
michael@0 322 if (isKey) {
michael@0 323 /* make sure there is a Key Provider Info property */
michael@0 324 CRYPT_KEY_PROV_INFO *keyProvInfo;
michael@0 325 DWORD size = 0;
michael@0 326 BOOL rv;
michael@0 327 rv =CertGetCertificateContextProperty(certContext,
michael@0 328 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
michael@0 329 if (!rv) {
michael@0 330 int reason = GetLastError();
michael@0 331 /* we only care if it exists, we don't really need to fetch it yet */
michael@0 332 if (reason == CRYPT_E_NOT_FOUND) {
michael@0 333 continue;
michael@0 334 }
michael@0 335 }
michael@0 336 /* filter out the non-microsoft providers */
michael@0 337 keyProvInfo = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
michael@0 338 if (keyProvInfo) {
michael@0 339 rv =CertGetCertificateContextProperty(certContext,
michael@0 340 CERT_KEY_PROV_INFO_PROP_ID, keyProvInfo, &size);
michael@0 341 if (rv) {
michael@0 342 char *provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
michael@0 343 nss_ZFreeIf(keyProvInfo);
michael@0 344
michael@0 345 if (provName &&
michael@0 346 (strncmp(provName, "Microsoft", sizeof("Microsoft")-1) != 0)) {
michael@0 347 continue;
michael@0 348 }
michael@0 349 } else {
michael@0 350 int reason = GetLastError();
michael@0 351 /* we only care if it exists, we don't really need to fetch it yet */
michael@0 352 nss_ZFreeIf(keyProvInfo);
michael@0 353 if (reason == CRYPT_E_NOT_FOUND) {
michael@0 354 continue;
michael@0 355 }
michael@0 356
michael@0 357 }
michael@0 358 }
michael@0 359 }
michael@0 360
michael@0 361 if ((ckcapiInternalObject *)NULL == next) {
michael@0 362 next = nss_ZNEW(NULL, ckcapiInternalObject);
michael@0 363 if ((ckcapiInternalObject *)NULL == next) {
michael@0 364 *pError = CKR_HOST_MEMORY;
michael@0 365 goto loser;
michael@0 366 }
michael@0 367 }
michael@0 368 next->type = ckcapiCert;
michael@0 369 next->objClass = objClass;
michael@0 370 next->u.cert.certContext = certContext;
michael@0 371 next->u.cert.hasID = hasID;
michael@0 372 next->u.cert.certStore = storeStr;
michael@0 373 if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, next) ) {
michael@0 374 /* clear cached values that may be dependent on our old certContext */
michael@0 375 memset(&next->u.cert, 0, sizeof(next->u.cert));
michael@0 376 /* get a 'permanent' context */
michael@0 377 next->u.cert.certContext = CertDuplicateCertificateContext(certContext);
michael@0 378 next->objClass = objClass;
michael@0 379 next->u.cert.certContext = certContext;
michael@0 380 next->u.cert.hasID = hasID;
michael@0 381 next->u.cert.certStore = storeStr;
michael@0 382 PUT_Object(next, *pError);
michael@0 383 next = NULL; /* need to allocate a new one now */
michael@0 384 } else {
michael@0 385 /* don't cache the values we just loaded */
michael@0 386 memset(&next->u.cert, 0, sizeof(next->u.cert));
michael@0 387 }
michael@0 388 }
michael@0 389 loser:
michael@0 390 CertCloseStore(hStore, 0);
michael@0 391 nss_ZFreeIf(next);
michael@0 392 *sizep = size;
michael@0 393 return count;
michael@0 394 }
michael@0 395
michael@0 396 NSS_IMPLEMENT PRUint32
michael@0 397 nss_ckcapi_collect_all_certs(
michael@0 398 CK_ATTRIBUTE_PTR pTemplate,
michael@0 399 CK_ULONG ulAttributeCount,
michael@0 400 ckcapiInternalObject ***listp,
michael@0 401 PRUint32 *sizep,
michael@0 402 PRUint32 count,
michael@0 403 CK_RV *pError
michael@0 404 )
michael@0 405 {
michael@0 406 count = collect_class(CKO_CERTIFICATE, "My", PR_TRUE, pTemplate,
michael@0 407 ulAttributeCount, listp, sizep, count, pError);
michael@0 408 /*count = collect_class(CKO_CERTIFICATE, "AddressBook", PR_FALSE, pTemplate,
michael@0 409 ulAttributeCount, listp, sizep, count, pError); */
michael@0 410 count = collect_class(CKO_CERTIFICATE, "CA", PR_FALSE, pTemplate,
michael@0 411 ulAttributeCount, listp, sizep, count, pError);
michael@0 412 count = collect_class(CKO_CERTIFICATE, "Root", PR_FALSE, pTemplate,
michael@0 413 ulAttributeCount, listp, sizep, count, pError);
michael@0 414 count = collect_class(CKO_CERTIFICATE, "Trust", PR_FALSE, pTemplate,
michael@0 415 ulAttributeCount, listp, sizep, count, pError);
michael@0 416 count = collect_class(CKO_CERTIFICATE, "TrustedPeople", PR_FALSE, pTemplate,
michael@0 417 ulAttributeCount, listp, sizep, count, pError);
michael@0 418 count = collect_class(CKO_CERTIFICATE, "AuthRoot", PR_FALSE, pTemplate,
michael@0 419 ulAttributeCount, listp, sizep, count, pError);
michael@0 420 return count;
michael@0 421 }
michael@0 422
michael@0 423 CK_OBJECT_CLASS
michael@0 424 ckcapi_GetObjectClass(CK_ATTRIBUTE_PTR pTemplate,
michael@0 425 CK_ULONG ulAttributeCount)
michael@0 426 {
michael@0 427 CK_ULONG i;
michael@0 428
michael@0 429 for (i=0; i < ulAttributeCount; i++)
michael@0 430 {
michael@0 431 if (pTemplate[i].type == CKA_CLASS) {
michael@0 432 return *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
michael@0 433 }
michael@0 434 }
michael@0 435 /* need to return a value that says 'fetch them all' */
michael@0 436 return CK_INVALID_HANDLE;
michael@0 437 }
michael@0 438
michael@0 439 static PRUint32
michael@0 440 collect_objects(
michael@0 441 CK_ATTRIBUTE_PTR pTemplate,
michael@0 442 CK_ULONG ulAttributeCount,
michael@0 443 ckcapiInternalObject ***listp,
michael@0 444 CK_RV *pError
michael@0 445 )
michael@0 446 {
michael@0 447 PRUint32 i;
michael@0 448 PRUint32 count = 0;
michael@0 449 PRUint32 size = 0;
michael@0 450 CK_OBJECT_CLASS objClass;
michael@0 451
michael@0 452 /*
michael@0 453 * first handle the static build in objects (if any)
michael@0 454 */
michael@0 455 for( i = 0; i < nss_ckcapi_nObjects; i++ ) {
michael@0 456 ckcapiInternalObject *o = (ckcapiInternalObject *)&nss_ckcapi_data[i];
michael@0 457
michael@0 458 if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, o) ) {
michael@0 459 PUT_Object(o, *pError);
michael@0 460 }
michael@0 461 }
michael@0 462
michael@0 463 /*
michael@0 464 * now handle the various object types
michael@0 465 */
michael@0 466 objClass = ckcapi_GetObjectClass(pTemplate, ulAttributeCount);
michael@0 467 *pError = CKR_OK;
michael@0 468 switch (objClass) {
michael@0 469 case CKO_CERTIFICATE:
michael@0 470 count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
michael@0 471 &size, count, pError);
michael@0 472 break;
michael@0 473 case CKO_PUBLIC_KEY:
michael@0 474 count = collect_class(objClass, "My", PR_TRUE, pTemplate,
michael@0 475 ulAttributeCount, listp, &size, count, pError);
michael@0 476 count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
michael@0 477 &size, count, pError);
michael@0 478 break;
michael@0 479 case CKO_PRIVATE_KEY:
michael@0 480 count = collect_class(objClass, "My", PR_TRUE, pTemplate,
michael@0 481 ulAttributeCount, listp, &size, count, pError);
michael@0 482 count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
michael@0 483 &size, count, pError);
michael@0 484 break;
michael@0 485 /* all of them */
michael@0 486 case CK_INVALID_HANDLE:
michael@0 487 count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
michael@0 488 &size, count, pError);
michael@0 489 count = collect_class(CKO_PUBLIC_KEY, "My", PR_TRUE, pTemplate,
michael@0 490 ulAttributeCount, listp, &size, count, pError);
michael@0 491 count = collect_bare(CKO_PUBLIC_KEY, pTemplate, ulAttributeCount, listp,
michael@0 492 &size, count, pError);
michael@0 493 count = collect_class(CKO_PRIVATE_KEY, "My", PR_TRUE, pTemplate,
michael@0 494 ulAttributeCount, listp, &size, count, pError);
michael@0 495 count = collect_bare(CKO_PRIVATE_KEY, pTemplate, ulAttributeCount, listp,
michael@0 496 &size, count, pError);
michael@0 497 break;
michael@0 498 default:
michael@0 499 goto done; /* no other object types we understand in this module */
michael@0 500 }
michael@0 501 if (CKR_OK != *pError) {
michael@0 502 goto loser;
michael@0 503 }
michael@0 504
michael@0 505
michael@0 506 done:
michael@0 507 return count;
michael@0 508 loser:
michael@0 509 nss_ZFreeIf(*listp);
michael@0 510 return 0;
michael@0 511 }
michael@0 512
michael@0 513
michael@0 514
michael@0 515 NSS_IMPLEMENT NSSCKMDFindObjects *
michael@0 516 nss_ckcapi_FindObjectsInit
michael@0 517 (
michael@0 518 NSSCKFWSession *fwSession,
michael@0 519 CK_ATTRIBUTE_PTR pTemplate,
michael@0 520 CK_ULONG ulAttributeCount,
michael@0 521 CK_RV *pError
michael@0 522 )
michael@0 523 {
michael@0 524 /* This could be made more efficient. I'm rather rushed. */
michael@0 525 NSSArena *arena;
michael@0 526 NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
michael@0 527 struct ckcapiFOStr *fo = (struct ckcapiFOStr *)NULL;
michael@0 528 ckcapiInternalObject **temp = (ckcapiInternalObject **)NULL;
michael@0 529
michael@0 530 arena = NSSArena_Create();
michael@0 531 if( (NSSArena *)NULL == arena ) {
michael@0 532 goto loser;
michael@0 533 }
michael@0 534
michael@0 535 rv = nss_ZNEW(arena, NSSCKMDFindObjects);
michael@0 536 if( (NSSCKMDFindObjects *)NULL == rv ) {
michael@0 537 *pError = CKR_HOST_MEMORY;
michael@0 538 goto loser;
michael@0 539 }
michael@0 540
michael@0 541 fo = nss_ZNEW(arena, struct ckcapiFOStr);
michael@0 542 if( (struct ckcapiFOStr *)NULL == fo ) {
michael@0 543 *pError = CKR_HOST_MEMORY;
michael@0 544 goto loser;
michael@0 545 }
michael@0 546
michael@0 547 fo->arena = arena;
michael@0 548 /* fo->n and fo->i are already zero */
michael@0 549
michael@0 550 rv->etc = (void *)fo;
michael@0 551 rv->Final = ckcapi_mdFindObjects_Final;
michael@0 552 rv->Next = ckcapi_mdFindObjects_Next;
michael@0 553 rv->null = (void *)NULL;
michael@0 554
michael@0 555 fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
michael@0 556 if (*pError != CKR_OK) {
michael@0 557 goto loser;
michael@0 558 }
michael@0 559
michael@0 560 fo->objs = nss_ZNEWARRAY(arena, ckcapiInternalObject *, fo->n);
michael@0 561 if( (ckcapiInternalObject **)NULL == fo->objs ) {
michael@0 562 *pError = CKR_HOST_MEMORY;
michael@0 563 goto loser;
michael@0 564 }
michael@0 565
michael@0 566 (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckcapiInternalObject *) * fo->n);
michael@0 567 nss_ZFreeIf(temp);
michael@0 568 temp = (ckcapiInternalObject **)NULL;
michael@0 569
michael@0 570 return rv;
michael@0 571
michael@0 572 loser:
michael@0 573 nss_ZFreeIf(temp);
michael@0 574 nss_ZFreeIf(fo);
michael@0 575 nss_ZFreeIf(rv);
michael@0 576 if ((NSSArena *)NULL != arena) {
michael@0 577 NSSArena_Destroy(arena);
michael@0 578 }
michael@0 579 return (NSSCKMDFindObjects *)NULL;
michael@0 580 }
michael@0 581

mercurial