~ubuntu-branches/ubuntu/lucid/seamonkey/lucid-security

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/ckfw/capi/cfind.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Tassin
  • Date: 2008-07-29 21:29:02 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080729212902-spm9kpvchp9udwbw
Tags: 1.1.11+nobinonly-0ubuntu1
* New security upstream release: 1.1.11 (LP: #218534)
  Fixes USN-602-1, USN-619-1, USN-623-1 and USN-629-1
* Refresh diverged patch:
  - update debian/patches/80_security_build.patch
* Fix FTBFS with missing -lfontconfig
  - add debian/patches/11_fix_ftbfs_with_fontconfig.patch
  - update debian/patches/series
* Build with default gcc (hardy: 4.2, intrepid: 4.3)
  - update debian/rules
  - update debian/control

Show diffs side-by-side

added added

removed removed

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