1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
14
* The Original Code is the Netscape security libraries.
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.
23
* Alternatively, the contents of this file may be used under the terms of
24
* either the GNU General Public License Version 2 or later (the "GPL"), or
25
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
* in which case the provisions of the GPL or the LGPL are applicable instead
27
* of those above. If you wish to allow use of your version of this file only
28
* under the terms of either the GPL or the LGPL, and not to allow others to
29
* use your version of this file under the terms of the MPL, indicate your
30
* decision by deleting the provisions above and replace them with the notice
31
* and other provisions required by the GPL or the LGPL. If you do not delete
32
* the provisions above, a recipient may use your version of this file under
33
* the terms of any one of the MPL, the GPL or the LGPL.
35
* ***** END LICENSE BLOCK ***** */
38
static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.25.28.1 $ $Date: 2006/08/23 01:36:31 $";
53
extern const NSSError NSS_ERROR_NOT_FOUND;
56
nssPKIObject_Lock(nssPKIObject * object)
58
switch (object->lockType) {
60
PZ_EnterMonitor(object->sync.mlock);
63
PZ_Lock(object->sync.lock);
71
nssPKIObject_Unlock(nssPKIObject * object)
73
switch (object->lockType) {
75
PZ_ExitMonitor(object->sync.mlock);
78
PZ_Unlock(object->sync.lock);
85
NSS_IMPLEMENT PRStatus
86
nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType)
88
object->lockType = lockType;
91
object->sync.mlock = PZ_NewMonitor(nssILockSSL);
92
return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE);
94
object->sync.lock = PZ_NewLock(nssILockSSL);
95
return (object->sync.lock ? PR_SUCCESS : PR_FAILURE);
103
nssPKIObject_DestroyLock(nssPKIObject * object)
105
switch (object->lockType) {
107
PZ_DestroyMonitor(object->sync.mlock);
108
object->sync.mlock = NULL;
111
PZ_DestroyLock(object->sync.lock);
112
object->sync.lock = NULL;
121
NSS_IMPLEMENT nssPKIObject *
122
nssPKIObject_Create (
124
nssCryptokiObject *instanceOpt,
126
NSSCryptoContext *cc,
127
nssPKILockType lockType
131
nssArenaMark *mark = NULL;
132
nssPKIObject *object;
135
mark = nssArena_Mark(arena);
137
arena = nssArena_Create();
139
return (nssPKIObject *)NULL;
142
object = nss_ZNEW(arena, nssPKIObject);
146
object->arena = arena;
147
object->trustDomain = td; /* XXX */
148
object->cryptoContext = cc;
149
if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) {
153
if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
157
PR_AtomicIncrement(&object->refCount);
159
nssArena_Unmark(arena, mark);
164
nssArena_Release(arena, mark);
166
nssArena_Destroy(arena);
168
return (nssPKIObject *)NULL;
172
nssPKIObject_Destroy (
177
PR_ASSERT(object->refCount > 0);
178
if (PR_AtomicDecrement(&object->refCount) == 0) {
179
for (i=0; i<object->numInstances; i++) {
180
nssCryptokiObject_Destroy(object->instances[i]);
182
nssPKIObject_DestroyLock(object);
183
nssArena_Destroy(object->arena);
189
NSS_IMPLEMENT nssPKIObject *
190
nssPKIObject_AddRef (
194
PR_AtomicIncrement(&object->refCount);
198
NSS_IMPLEMENT PRStatus
199
nssPKIObject_AddInstance (
200
nssPKIObject *object,
201
nssCryptokiObject *instance
204
nssPKIObject_Lock(object);
205
if (object->numInstances == 0) {
206
object->instances = nss_ZNEWARRAY(object->arena,
208
object->numInstances + 1);
211
for (i=0; i<object->numInstances; i++) {
212
if (nssCryptokiObject_Equal(object->instances[i], instance)) {
213
nssPKIObject_Unlock(object);
214
if (instance->label) {
215
if (!object->instances[i]->label ||
216
!nssUTF8_Equal(instance->label,
217
object->instances[i]->label, NULL))
219
/* Either the old instance did not have a label,
220
* or the label has changed.
222
nss_ZFreeIf(object->instances[i]->label);
223
object->instances[i]->label = instance->label;
224
instance->label = NULL;
226
} else if (object->instances[i]->label) {
227
/* The old label was removed */
228
nss_ZFreeIf(object->instances[i]->label);
229
object->instances[i]->label = NULL;
231
nssCryptokiObject_Destroy(instance);
235
object->instances = nss_ZREALLOCARRAY(object->instances,
237
object->numInstances + 1);
239
if (!object->instances) {
240
nssPKIObject_Unlock(object);
243
object->instances[object->numInstances++] = instance;
244
nssPKIObject_Unlock(object);
249
nssPKIObject_HasInstance (
250
nssPKIObject *object,
251
nssCryptokiObject *instance
255
PRBool hasIt = PR_FALSE;;
256
nssPKIObject_Lock(object);
257
for (i=0; i<object->numInstances; i++) {
258
if (nssCryptokiObject_Equal(object->instances[i], instance)) {
263
nssPKIObject_Unlock(object);
267
NSS_IMPLEMENT PRStatus
268
nssPKIObject_RemoveInstanceForToken (
269
nssPKIObject *object,
274
nssCryptokiObject *instanceToRemove = NULL;
275
nssPKIObject_Lock(object);
276
if (object->numInstances == 0) {
277
nssPKIObject_Unlock(object);
280
for (i=0; i<object->numInstances; i++) {
281
if (object->instances[i]->token == token) {
282
instanceToRemove = object->instances[i];
283
object->instances[i] = object->instances[object->numInstances-1];
284
object->instances[object->numInstances-1] = NULL;
288
if (--object->numInstances > 0) {
289
nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances,
291
object->numInstances);
293
object->instances = instances;
296
nss_ZFreeIf(object->instances);
298
nssCryptokiObject_Destroy(instanceToRemove);
299
nssPKIObject_Unlock(object);
303
/* this needs more thought on what will happen when there are multiple
306
NSS_IMPLEMENT PRStatus
307
nssPKIObject_DeleteStoredObject (
308
nssPKIObject *object,
313
PRUint32 i, numNotDestroyed;
314
PRStatus status = PR_SUCCESS;
316
NSSTrustDomain *td = object->trustDomain;
317
NSSCallback *pwcb = uhh ? /* is this optional? */
319
nssTrustDomain_GetDefaultCallback(td, NULL);
322
nssPKIObject_Lock(object);
323
for (i=0; i<object->numInstances; i++) {
324
nssCryptokiObject *instance = object->instances[i];
326
NSSSlot *slot = nssToken_GetSlot(instance->token);
327
/* If both the operation and the slot are friendly, login is
328
* not required. If either or both are not friendly, it is
331
if (!(isFriendly && nssSlot_IsFriendly(slot))) {
332
status = nssSlot_Login(slot, pwcb);
333
nssSlot_Destroy(slot);
334
if (status == PR_SUCCESS) {
335
/* XXX this should be fixed to understand read-only tokens,
336
* for now, to handle the builtins, just make the attempt.
338
status = nssToken_DeleteStoredObject(instance);
342
status = nssToken_DeleteStoredObject(instance);
344
object->instances[i] = NULL;
345
if (status == PR_SUCCESS) {
346
nssCryptokiObject_Destroy(instance);
348
object->instances[numNotDestroyed++] = instance;
351
if (numNotDestroyed == 0) {
352
nss_ZFreeIf(object->instances);
353
object->numInstances = 0;
355
object->numInstances = numNotDestroyed;
357
nssPKIObject_Unlock(object);
361
NSS_IMPLEMENT NSSToken **
362
nssPKIObject_GetTokens (
363
nssPKIObject *object,
367
NSSToken **tokens = NULL;
368
nssPKIObject_Lock(object);
369
if (object->numInstances > 0) {
370
tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1);
373
for (i=0; i<object->numInstances; i++) {
374
tokens[i] = nssToken_AddRef(object->instances[i]->token);
378
nssPKIObject_Unlock(object);
379
if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */
383
NSS_IMPLEMENT NSSUTF8 *
384
nssPKIObject_GetNicknameForToken (
385
nssPKIObject *object,
390
NSSUTF8 *nickname = NULL;
391
nssPKIObject_Lock(object);
392
for (i=0; i<object->numInstances; i++) {
393
if ((!tokenOpt && object->instances[i]->label) ||
394
(object->instances[i]->token == tokenOpt))
396
/* XXX should be copy? safe as long as caller has reference */
397
nickname = object->instances[i]->label;
401
nssPKIObject_Unlock(object);
406
NSS_IMPLEMENT nssCryptokiObject **
407
nssPKIObject_GetInstances (
411
nssCryptokiObject **instances = NULL;
413
if (object->numInstances == 0) {
414
return (nssCryptokiObject **)NULL;
416
nssPKIObject_Lock(object);
417
instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,
418
object->numInstances + 1);
420
for (i=0; i<object->numInstances; i++) {
421
instances[i] = nssCryptokiObject_Clone(object->instances[i]);
424
nssPKIObject_Unlock(object);
430
nssCertificateArray_Destroy (
431
NSSCertificate **certs
435
NSSCertificate **certp;
436
for (certp = certs; *certp; certp++) {
438
if ((*certp)->decoding) {
439
CERTCertificate *cc = STAN_GetCERTCertificate(*certp);
441
CERT_DestroyCertificate(cc);
446
nssCertificate_Destroy(*certp);
453
NSSCertificateArray_Destroy (
454
NSSCertificate **certs
457
nssCertificateArray_Destroy(certs);
460
NSS_IMPLEMENT NSSCertificate **
461
nssCertificateArray_Join (
462
NSSCertificate **certs1,
463
NSSCertificate **certs2
466
if (certs1 && certs2) {
467
NSSCertificate **certs, **cp;
471
while (*cp++) count1++;
474
while (*cp++) count++;
475
certs = nss_ZREALLOCARRAY(certs1, NSSCertificate *, count + 1);
479
return (NSSCertificate **)NULL;
481
for (cp = certs2; *cp; cp++, count1++) {
493
NSS_IMPLEMENT NSSCertificate *
494
nssCertificateArray_FindBestCertificate (
495
NSSCertificate **certs,
497
const NSSUsage *usage,
498
NSSPolicies *policiesOpt
501
NSSCertificate *bestCert = NULL;
502
NSSTime *time, sTime;
503
PRBool haveUsageMatch = PR_FALSE;
504
PRBool thisCertMatches;
513
return (NSSCertificate *)NULL;
515
for (; *certs; certs++) {
516
nssDecodedCert *dc, *bestdc;
517
NSSCertificate *c = *certs;
518
dc = nssCertificate_GetDecoding(c);
520
thisCertMatches = dc->matchUsage(dc, usage);
522
/* always take the first cert, but remember whether or not
525
bestCert = nssCertificate_AddRef(c);
526
haveUsageMatch = thisCertMatches;
529
if (haveUsageMatch && !thisCertMatches) {
530
/* if already have a cert for this usage, and if this cert
531
* doesn't have the correct usage, continue
534
} else if (!haveUsageMatch && thisCertMatches) {
535
/* this one does match usage, replace the other */
536
nssCertificate_Destroy(bestCert);
537
bestCert = nssCertificate_AddRef(c);
538
haveUsageMatch = PR_TRUE;
541
/* this cert match as well as any cert we've found so far,
542
* defer to time/policies
545
bestdc = nssCertificate_GetDecoding(bestCert);
547
if (bestdc->isValidAtTime(bestdc, time)) {
548
/* The current best cert is valid at time */
549
if (!dc->isValidAtTime(dc, time)) {
550
/* If the new cert isn't valid at time, it's not better */
554
/* The current best cert is not valid at time */
555
if (dc->isValidAtTime(dc, time)) {
556
/* If the new cert is valid at time, it's better */
557
nssCertificate_Destroy(bestCert);
558
bestCert = nssCertificate_AddRef(c);
561
/* either they are both valid at time, or neither valid;
564
if (!bestdc->isNewerThan(bestdc, dc)) {
565
nssCertificate_Destroy(bestCert);
566
bestCert = nssCertificate_AddRef(c);
569
/* XXX later -- defer to policies */
574
NSS_IMPLEMENT PRStatus
575
nssCertificateArray_Traverse (
576
NSSCertificate **certs,
577
PRStatus (* callback)(NSSCertificate *c, void *arg),
581
PRStatus status = PR_SUCCESS;
583
NSSCertificate **certp;
584
for (certp = certs; *certp; certp++) {
585
status = (*callback)(*certp, arg);
586
if (status != PR_SUCCESS) {
596
nssCRLArray_Destroy (
602
for (crlp = crls; *crlp; crlp++) {
603
nssCRL_Destroy(*crlp);
615
pkiObjectType_Certificate = 0,
616
pkiObjectType_CRL = 1,
617
pkiObjectType_PrivateKey = 2,
618
pkiObjectType_PublicKey = 3
621
/* Each object is defined by a set of items that uniquely identify it.
622
* Here are the uid sets:
624
* NSSCertificate ==> { issuer, serial }
626
* (RSA) ==> { modulus, public exponent }
629
#define MAX_ITEMS_FOR_UID 2
631
/* pkiObjectCollectionNode
633
* A node in the collection is the set of unique identifiers for a single
634
* object, along with either the actual object or a proto-object.
640
nssPKIObject *object;
641
NSSItem uid[MAX_ITEMS_FOR_UID];
643
pkiObjectCollectionNode;
645
/* nssPKIObjectCollection
647
* The collection is the set of all objects, plus the interfaces needed
648
* to manage the objects.
651
struct nssPKIObjectCollectionStr
655
NSSCryptoContext *cc;
656
PRCList head; /* list of pkiObjectCollectionNode's */
658
pkiObjectType objectType;
659
void (* destroyObject)(nssPKIObject *o);
660
PRStatus (* getUIDFromObject)(nssPKIObject *o, NSSItem *uid);
661
PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid,
663
nssPKIObject * (* createObject)(nssPKIObject *o);
664
nssPKILockType lockType; /* type of lock to use for new proto-objects */
667
static nssPKIObjectCollection *
668
nssPKIObjectCollection_Create (
670
NSSCryptoContext *ccOpt,
671
nssPKILockType lockType
675
nssPKIObjectCollection *rvCollection = NULL;
676
arena = nssArena_Create();
678
return (nssPKIObjectCollection *)NULL;
680
rvCollection = nss_ZNEW(arena, nssPKIObjectCollection);
684
PR_INIT_CLIST(&rvCollection->head);
685
rvCollection->arena = arena;
686
rvCollection->td = td; /* XXX */
687
rvCollection->cc = ccOpt;
688
rvCollection->lockType = lockType;
691
nssArena_Destroy(arena);
692
return (nssPKIObjectCollection *)NULL;
696
nssPKIObjectCollection_Destroy (
697
nssPKIObjectCollection *collection
702
pkiObjectCollectionNode *node;
703
/* first destroy any objects in the collection */
704
link = PR_NEXT_LINK(&collection->head);
705
while (link != &collection->head) {
706
node = (pkiObjectCollectionNode *)link;
707
if (node->haveObject) {
708
(*collection->destroyObject)(node->object);
710
nssPKIObject_Destroy(node->object);
712
link = PR_NEXT_LINK(link);
714
/* then destroy it */
715
nssArena_Destroy(collection->arena);
719
NSS_IMPLEMENT PRUint32
720
nssPKIObjectCollection_Count (
721
nssPKIObjectCollection *collection
724
return collection->size;
727
NSS_IMPLEMENT PRStatus
728
nssPKIObjectCollection_AddObject (
729
nssPKIObjectCollection *collection,
733
pkiObjectCollectionNode *node;
734
node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
738
node->haveObject = PR_TRUE;
739
node->object = nssPKIObject_AddRef(object);
740
(*collection->getUIDFromObject)(object, node->uid);
741
PR_INIT_CLIST(&node->link);
742
PR_INSERT_BEFORE(&node->link, &collection->head);
747
static pkiObjectCollectionNode *
748
find_instance_in_collection (
749
nssPKIObjectCollection *collection,
750
nssCryptokiObject *instance
754
pkiObjectCollectionNode *node;
755
link = PR_NEXT_LINK(&collection->head);
756
while (link != &collection->head) {
757
node = (pkiObjectCollectionNode *)link;
758
if (nssPKIObject_HasInstance(node->object, instance)) {
761
link = PR_NEXT_LINK(link);
763
return (pkiObjectCollectionNode *)NULL;
766
static pkiObjectCollectionNode *
767
find_object_in_collection (
768
nssPKIObjectCollection *collection,
775
pkiObjectCollectionNode *node;
776
link = PR_NEXT_LINK(&collection->head);
777
while (link != &collection->head) {
778
node = (pkiObjectCollectionNode *)link;
779
for (i=0; i<MAX_ITEMS_FOR_UID; i++) {
780
if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) {
784
if (i == MAX_ITEMS_FOR_UID) {
787
link = PR_NEXT_LINK(link);
789
return (pkiObjectCollectionNode *)NULL;
792
static pkiObjectCollectionNode *
793
add_object_instance (
794
nssPKIObjectCollection *collection,
795
nssCryptokiObject *instance,
801
pkiObjectCollectionNode *node;
802
nssArenaMark *mark = NULL;
803
NSSItem uid[MAX_ITEMS_FOR_UID];
804
nsslibc_memset(uid, 0, sizeof uid);
805
/* The list is traversed twice, first (here) looking to match the
806
* { token, handle } tuple, and if that is not found, below a search
807
* for unique identifier is done. Here, a match means this exact object
808
* instance is already in the collection, and we have nothing to do.
811
node = find_instance_in_collection(collection, instance);
813
/* The collection is assumed to take over the instance. Since we
814
* are not using it, it must be destroyed.
816
nssCryptokiObject_Destroy(instance);
820
mark = nssArena_Mark(collection->arena);
824
status = (*collection->getUIDFromInstance)(instance, uid,
826
if (status != PR_SUCCESS) {
829
/* Search for unique identifier. A match here means the object exists
830
* in the collection, but does not have this instance, so the instance
833
node = find_object_in_collection(collection, uid);
835
/* This is an object with multiple instances */
836
status = nssPKIObject_AddInstance(node->object, instance);
838
/* This is a completely new object. Create a node for it. */
839
node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
843
node->object = nssPKIObject_Create(NULL, instance,
844
collection->td, collection->cc,
845
collection->lockType);
849
for (i=0; i<MAX_ITEMS_FOR_UID; i++) {
850
node->uid[i] = uid[i];
852
node->haveObject = PR_FALSE;
853
PR_INIT_CLIST(&node->link);
854
PR_INSERT_BEFORE(&node->link, &collection->head);
858
nssArena_Unmark(collection->arena, mark);
862
nssArena_Release(collection->arena, mark);
864
nssCryptokiObject_Destroy(instance);
865
return (pkiObjectCollectionNode *)NULL;
868
NSS_IMPLEMENT PRStatus
869
nssPKIObjectCollection_AddInstances (
870
nssPKIObjectCollection *collection,
871
nssCryptokiObject **instances,
872
PRUint32 numInstances
875
PRStatus status = PR_SUCCESS;
878
pkiObjectCollectionNode *node;
880
for (; *instances; instances++, i++) {
881
if (numInstances > 0 && i == numInstances) {
884
if (status == PR_SUCCESS) {
885
node = add_object_instance(collection, *instances, &foundIt);
887
/* add_object_instance freed the current instance */
888
/* free the remaining instances */
892
nssCryptokiObject_Destroy(*instances);
900
nssPKIObjectCollection_RemoveNode (
901
nssPKIObjectCollection *collection,
902
pkiObjectCollectionNode *node
905
PR_REMOVE_LINK(&node->link);
910
nssPKIObjectCollection_GetObjects (
911
nssPKIObjectCollection *collection,
912
nssPKIObject **rvObjects,
917
PRCList *link = PR_NEXT_LINK(&collection->head);
918
pkiObjectCollectionNode *node;
920
while ((i < rvSize) && (link != &collection->head)) {
921
node = (pkiObjectCollectionNode *)link;
922
if (!node->haveObject) {
923
/* Convert the proto-object to an object */
924
node->object = (*collection->createObject)(node->object);
926
link = PR_NEXT_LINK(link);
927
/*remove bogus object from list*/
928
nssPKIObjectCollection_RemoveNode(collection,node);
932
node->haveObject = PR_TRUE;
934
rvObjects[i++] = nssPKIObject_AddRef(node->object);
935
link = PR_NEXT_LINK(link);
937
if (!error && *rvObjects == NULL) {
938
nss_SetError(NSS_ERROR_NOT_FOUND);
943
NSS_IMPLEMENT PRStatus
944
nssPKIObjectCollection_Traverse (
945
nssPKIObjectCollection *collection,
946
nssPKIObjectCallback *callback
950
PRCList *link = PR_NEXT_LINK(&collection->head);
951
pkiObjectCollectionNode *node;
952
while (link != &collection->head) {
953
node = (pkiObjectCollectionNode *)link;
954
if (!node->haveObject) {
955
node->object = (*collection->createObject)(node->object);
957
link = PR_NEXT_LINK(link);
958
/*remove bogus object from list*/
959
nssPKIObjectCollection_RemoveNode(collection,node);
962
node->haveObject = PR_TRUE;
964
switch (collection->objectType) {
965
case pkiObjectType_Certificate:
966
status = (*callback->func.cert)((NSSCertificate *)node->object,
969
case pkiObjectType_CRL:
970
status = (*callback->func.crl)((NSSCRL *)node->object,
973
case pkiObjectType_PrivateKey:
974
status = (*callback->func.pvkey)((NSSPrivateKey *)node->object,
977
case pkiObjectType_PublicKey:
978
status = (*callback->func.pbkey)((NSSPublicKey *)node->object,
982
link = PR_NEXT_LINK(link);
987
NSS_IMPLEMENT PRStatus
988
nssPKIObjectCollection_AddInstanceAsObject (
989
nssPKIObjectCollection *collection,
990
nssCryptokiObject *instance
993
pkiObjectCollectionNode *node;
995
node = add_object_instance(collection, instance, &foundIt);
999
if (!node->haveObject) {
1000
node->object = (*collection->createObject)(node->object);
1001
if (!node->object) {
1002
/*remove bogus object from list*/
1003
nssPKIObjectCollection_RemoveNode(collection,node);
1006
node->haveObject = PR_TRUE;
1009
else if (!foundIt) {
1010
/* The instance was added to a pre-existing node. This
1011
* function is *only* being used for certificates, and having
1012
* multiple instances of certs in 3.X requires updating the
1014
* But only do it if it was a new instance!!! If the same instance
1015
* is encountered, we set *foundIt to true. Detect that here and
1018
STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object);
1025
* Certificate collections
1029
cert_destroyObject(nssPKIObject *o)
1031
NSSCertificate *c = (NSSCertificate *)o;
1034
CERTCertificate *cc = STAN_GetCERTCertificate(c);
1036
CERT_DestroyCertificate(cc);
1038
} /* else destroy it as NSSCertificate below */
1041
nssCertificate_Destroy(c);
1045
cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1047
NSSCertificate *c = (NSSCertificate *)o;
1049
/* The builtins are still returning decoded serial numbers. Until
1050
* this compatibility issue is resolved, use the full DER of the
1051
* cert to uniquely identify it.
1054
derCert = nssCertificate_GetEncoding(c);
1055
uid[0].data = NULL; uid[0].size = 0;
1056
uid[1].data = NULL; uid[1].size = 0;
1057
if (derCert != NULL) {
1061
NSSDER *issuer, *serial;
1062
issuer = nssCertificate_GetIssuer(c);
1063
serial = nssCertificate_GetSerialNumber(c);
1066
#endif /* NSS_3_4_CODE */
1071
cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1075
/* The builtins are still returning decoded serial numbers. Until
1076
* this compatibility issue is resolved, use the full DER of the
1077
* cert to uniquely identify it.
1079
uid[1].data = NULL; uid[1].size = 0;
1080
return nssCryptokiCertificate_GetAttributes(instance,
1081
NULL, /* XXX sessionOpt */
1085
&uid[0], /* encoding */
1088
NULL); /* subject */
1090
return nssCryptokiCertificate_GetAttributes(instance,
1091
NULL, /* XXX sessionOpt */
1095
NULL, /* encoding */
1096
&uid[0], /* issuer */
1097
&uid[1], /* serial */
1098
NULL); /* subject */
1099
#endif /* NSS_3_4_CODE */
1102
static nssPKIObject *
1103
cert_createObject(nssPKIObject *o)
1105
NSSCertificate *cert;
1106
cert = nssCertificate_Create(o);
1108
/* if (STAN_GetCERTCertificate(cert) == NULL) {
1109
nssCertificate_Destroy(cert);
1110
return (nssPKIObject *)NULL;
1112
/* In 3.4, have to maintain uniqueness of cert pointers by caching all
1113
* certs. Cache the cert here, before returning. If it is already
1114
* cached, take the cached entry.
1117
NSSTrustDomain *td = o->trustDomain;
1118
nssTrustDomain_AddCertsToCache(td, &cert, 1);
1121
return (nssPKIObject *)cert;
1124
NSS_IMPLEMENT nssPKIObjectCollection *
1125
nssCertificateCollection_Create (
1127
NSSCertificate **certsOpt
1131
nssPKIObjectCollection *collection;
1132
collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor);
1133
collection->objectType = pkiObjectType_Certificate;
1134
collection->destroyObject = cert_destroyObject;
1135
collection->getUIDFromObject = cert_getUIDFromObject;
1136
collection->getUIDFromInstance = cert_getUIDFromInstance;
1137
collection->createObject = cert_createObject;
1139
for (; *certsOpt; certsOpt++) {
1140
nssPKIObject *object = (nssPKIObject *)(*certsOpt);
1141
status = nssPKIObjectCollection_AddObject(collection, object);
1147
NSS_IMPLEMENT NSSCertificate **
1148
nssPKIObjectCollection_GetCertificates (
1149
nssPKIObjectCollection *collection,
1150
NSSCertificate **rvOpt,
1151
PRUint32 maximumOpt,
1157
PRBool allocated = PR_FALSE;
1158
if (collection->size == 0) {
1159
return (NSSCertificate **)NULL;
1161
if (maximumOpt == 0) {
1162
rvSize = collection->size;
1164
rvSize = PR_MIN(collection->size, maximumOpt);
1167
rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvSize + 1);
1169
return (NSSCertificate **)NULL;
1171
allocated = PR_TRUE;
1173
status = nssPKIObjectCollection_GetObjects(collection,
1174
(nssPKIObject **)rvOpt,
1176
if (status != PR_SUCCESS) {
1180
return (NSSCertificate **)NULL;
1186
* CRL/KRL collections
1190
crl_destroyObject(nssPKIObject *o)
1192
NSSCRL *crl = (NSSCRL *)o;
1193
nssCRL_Destroy(crl);
1197
crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1199
NSSCRL *crl = (NSSCRL *)o;
1201
encoding = nssCRL_GetEncoding(crl);
1203
uid[1].data = NULL; uid[1].size = 0;
1208
crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1211
return nssCryptokiCRL_GetAttributes(instance,
1212
NULL, /* XXX sessionOpt */
1214
&uid[0], /* encoding */
1221
static nssPKIObject *
1222
crl_createObject(nssPKIObject *o)
1224
return (nssPKIObject *)nssCRL_Create(o);
1227
NSS_IMPLEMENT nssPKIObjectCollection *
1228
nssCRLCollection_Create (
1234
nssPKIObjectCollection *collection;
1235
collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock);
1236
collection->objectType = pkiObjectType_CRL;
1237
collection->destroyObject = crl_destroyObject;
1238
collection->getUIDFromObject = crl_getUIDFromObject;
1239
collection->getUIDFromInstance = crl_getUIDFromInstance;
1240
collection->createObject = crl_createObject;
1242
for (; *crlsOpt; crlsOpt++) {
1243
nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
1244
status = nssPKIObjectCollection_AddObject(collection, object);
1250
NSS_IMPLEMENT NSSCRL **
1251
nssPKIObjectCollection_GetCRLs (
1252
nssPKIObjectCollection *collection,
1254
PRUint32 maximumOpt,
1260
PRBool allocated = PR_FALSE;
1261
if (collection->size == 0) {
1262
return (NSSCRL **)NULL;
1264
if (maximumOpt == 0) {
1265
rvSize = collection->size;
1267
rvSize = PR_MIN(collection->size, maximumOpt);
1270
rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1);
1272
return (NSSCRL **)NULL;
1274
allocated = PR_TRUE;
1276
status = nssPKIObjectCollection_GetObjects(collection,
1277
(nssPKIObject **)rvOpt,
1279
if (status != PR_SUCCESS) {
1283
return (NSSCRL **)NULL;
1288
#ifdef PURE_STAN_BUILD
1290
* PrivateKey collections
1294
privkey_destroyObject(nssPKIObject *o)
1296
NSSPrivateKey *pvk = (NSSPrivateKey *)o;
1297
nssPrivateKey_Destroy(pvk);
1301
privkey_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1303
NSSPrivateKey *pvk = (NSSPrivateKey *)o;
1305
id = nssPrivateKey_GetID(pvk);
1311
privkey_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1314
return nssCryptokiPrivateKey_GetAttributes(instance,
1315
NULL, /* XXX sessionOpt */
1321
static nssPKIObject *
1322
privkey_createObject(nssPKIObject *o)
1325
pvk = nssPrivateKey_Create(o);
1326
return (nssPKIObject *)pvk;
1329
NSS_IMPLEMENT nssPKIObjectCollection *
1330
nssPrivateKeyCollection_Create (
1332
NSSPrivateKey **pvkOpt
1336
nssPKIObjectCollection *collection;
1337
collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock);
1338
collection->objectType = pkiObjectType_PrivateKey;
1339
collection->destroyObject = privkey_destroyObject;
1340
collection->getUIDFromObject = privkey_getUIDFromObject;
1341
collection->getUIDFromInstance = privkey_getUIDFromInstance;
1342
collection->createObject = privkey_createObject;
1344
for (; *pvkOpt; pvkOpt++) {
1345
nssPKIObject *o = (nssPKIObject *)(*pvkOpt);
1346
status = nssPKIObjectCollection_AddObject(collection, o);
1352
NSS_IMPLEMENT NSSPrivateKey **
1353
nssPKIObjectCollection_GetPrivateKeys (
1354
nssPKIObjectCollection *collection,
1355
NSSPrivateKey **rvOpt,
1356
PRUint32 maximumOpt,
1362
PRBool allocated = PR_FALSE;
1363
if (collection->size == 0) {
1364
return (NSSPrivateKey **)NULL;
1366
if (maximumOpt == 0) {
1367
rvSize = collection->size;
1369
rvSize = PR_MIN(collection->size, maximumOpt);
1372
rvOpt = nss_ZNEWARRAY(arenaOpt, NSSPrivateKey *, rvSize + 1);
1374
return (NSSPrivateKey **)NULL;
1376
allocated = PR_TRUE;
1378
status = nssPKIObjectCollection_GetObjects(collection,
1379
(nssPKIObject **)rvOpt,
1381
if (status != PR_SUCCESS) {
1385
return (NSSPrivateKey **)NULL;
1391
* PublicKey collections
1395
pubkey_destroyObject(nssPKIObject *o)
1397
NSSPublicKey *pubk = (NSSPublicKey *)o;
1398
nssPublicKey_Destroy(pubk);
1402
pubkey_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
1404
NSSPublicKey *pubk = (NSSPublicKey *)o;
1406
id = nssPublicKey_GetID(pubk);
1412
pubkey_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
1415
return nssCryptokiPublicKey_GetAttributes(instance,
1416
NULL, /* XXX sessionOpt */
1422
static nssPKIObject *
1423
pubkey_createObject(nssPKIObject *o)
1426
pubk = nssPublicKey_Create(o);
1427
return (nssPKIObject *)pubk;
1430
NSS_IMPLEMENT nssPKIObjectCollection *
1431
nssPublicKeyCollection_Create (
1433
NSSPublicKey **pubkOpt
1437
nssPKIObjectCollection *collection;
1438
collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock);
1439
collection->objectType = pkiObjectType_PublicKey;
1440
collection->destroyObject = pubkey_destroyObject;
1441
collection->getUIDFromObject = pubkey_getUIDFromObject;
1442
collection->getUIDFromInstance = pubkey_getUIDFromInstance;
1443
collection->createObject = pubkey_createObject;
1445
for (; *pubkOpt; pubkOpt++) {
1446
nssPKIObject *o = (nssPKIObject *)(*pubkOpt);
1447
status = nssPKIObjectCollection_AddObject(collection, o);
1453
NSS_IMPLEMENT NSSPublicKey **
1454
nssPKIObjectCollection_GetPublicKeys (
1455
nssPKIObjectCollection *collection,
1456
NSSPublicKey **rvOpt,
1457
PRUint32 maximumOpt,
1463
PRBool allocated = PR_FALSE;
1464
if (collection->size == 0) {
1465
return (NSSPublicKey **)NULL;
1467
if (maximumOpt == 0) {
1468
rvSize = collection->size;
1470
rvSize = PR_MIN(collection->size, maximumOpt);
1473
rvOpt = nss_ZNEWARRAY(arenaOpt, NSSPublicKey *, rvSize + 1);
1475
return (NSSPublicKey **)NULL;
1477
allocated = PR_TRUE;
1479
status = nssPKIObjectCollection_GetObjects(collection,
1480
(nssPKIObject **)rvOpt,
1482
if (status != PR_SUCCESS) {
1486
return (NSSPublicKey **)NULL;
1490
#endif /* PURE_STAN_BUILD */
1492
/* how bad would it be to have a static now sitting around, updated whenever
1493
* this was called? would avoid repeated allocs...
1495
NSS_IMPLEMENT NSSTime *
1500
return NSSTime_SetPRTime(timeOpt, PR_Now());
1503
NSS_IMPLEMENT NSSTime *
1510
rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
1511
rvTime->prTime = prTime;
1515
NSS_IMPLEMENT PRTime
1520
return time->prTime;