2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is the Netscape security libraries.
14
* The Initial Developer of the Original Code is Netscape
15
* Communications Corporation. Portions created by Netscape are
16
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
21
* Alternatively, the contents of this file may be used under the
22
* terms of the GNU General Public License Version 2 or later (the
23
* "GPL"), in which case the provisions of the GPL are applicable
24
* instead of those above. If you wish to allow use of your
25
* version of this file only under the terms of the GPL and not to
26
* allow others to use your version of this file under the MPL,
27
* indicate your decision by deleting the provisions above and
28
* replace them with the notice and other provisions required by
29
* the GPL. If you do not delete the provisions above, a recipient
30
* may use your version of this file under either the MPL or the
54
CERT_MatchNickname(char *name1, char *name2) {
55
char *nickname1= NULL;
56
char *nickname2 = NULL;
62
/* first deal with the straight comparison */
63
if (PORT_Strcmp(name1, name2) == 0) {
66
/* we need to handle the case where one name has an explicit token and the other
68
token1 = PORT_Strchr(name1,':');
69
token2 = PORT_Strchr(name2,':');
70
if ((token1 && token2) || (!token1 && !token2)) {
71
/* either both token names are specified or neither are, not match */
83
len = nickname1-token;
85
if (PORT_Strcmp(nickname1,nickname2) != 0) {
88
/* compare the other token with the internal slot here */
93
* Find all user certificates that match the given criteria.
95
* "handle" - database to search
96
* "usage" - certificate usage to match
97
* "oneCertPerName" - if set then only return the "best" cert per
99
* "validOnly" - only return certs that are curently valid
100
* "proto_win" - window handle passed to pkcs11
103
CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
105
PRBool oneCertPerName,
109
CERTCertNicknames *nicknames = NULL;
112
CERTCertificate *cert = NULL;
113
CERTCertList *certList = NULL;
116
CERTCertListNode *node = NULL;
117
CERTCertListNode *freenode = NULL;
122
nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER,
125
if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) {
129
nnptr = nicknames->nicknames;
130
nn = nicknames->numnicknames;
134
/* use the pk11 call so that we pick up any certs on tokens,
135
* which may require login
137
if ( proto_win != NULL ) {
138
cert = PK11_FindCertFromNickname(*nnptr,proto_win);
141
/* Sigh, It turns out if the cert is already in the temp db, because
142
* it's in the perm db, then the nickname lookup doesn't work.
143
* since we already have the cert here, though, than we can just call
144
* CERT_CreateSubjectCertList directly. For those cases where we didn't
145
* find the cert in pkcs #11 (because we didn't have a password arg,
146
* or because the nickname is for a peer, server, or CA cert, then we
147
* go look the cert up.
150
cert = CERT_FindCertByNickname(handle,*nnptr);
153
if ( cert != NULL ) {
154
/* collect certs for this nickname, sorting them into the list */
155
certList = CERT_CreateSubjectCertList(certList, handle,
156
&cert->derSubject, time, validOnly);
158
CERT_FilterCertListForUserCerts(certList);
160
/* drop the extra reference */
161
CERT_DestroyCertificate(cert);
168
/* remove certs with incorrect usage */
169
rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);
171
if ( rv != SECSuccess ) {
175
/* remove any extra certs for each name */
176
if ( oneCertPerName ) {
179
nn = nicknames->numnicknames;
180
nnptr = nicknames->nicknames;
182
flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn);
183
if ( flags == NULL ) {
187
node = CERT_LIST_HEAD(certList);
189
/* treverse all certs in the list */
190
while ( !CERT_LIST_END(node, certList) ) {
192
/* find matching nickname index */
193
for ( n = 0; n < nn; n++ ) {
194
if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) {
195
/* We found a match. If this is the first one, then
196
* set the flag and move on to the next cert. If this
197
* is not the first one then delete it from the list.
200
/* We have already seen a cert with this nickname,
201
* so delete this one.
204
node = CERT_LIST_NEXT(node);
205
CERT_RemoveCertListNode(freenode);
207
/* keep the first cert for each nickname, but set the
208
* flag so we know to delete any others with the same
212
node = CERT_LIST_NEXT(node);
218
/* if we get here it means that we didn't find a matching
219
* nickname, which should not happen.
222
node = CERT_LIST_NEXT(node);
231
if ( certList != NULL ) {
232
CERT_DestroyCertList(certList);
237
if ( nicknames != NULL ) {
238
CERT_FreeNicknames(nicknames);
245
* Find a user certificate that matchs the given criteria.
247
* "handle" - database to search
248
* "nickname" - nickname to match
249
* "usage" - certificate usage to match
250
* "validOnly" - only return certs that are curently valid
251
* "proto_win" - window handle passed to pkcs11
254
CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
260
CERTCertificate *cert = NULL;
261
CERTCertList *certList = NULL;
267
/* use the pk11 call so that we pick up any certs on tokens,
268
* which may require login
270
/* XXX - why is this restricted? */
271
if ( proto_win != NULL ) {
272
cert = PK11_FindCertFromNickname(nickname,proto_win);
276
/* sigh, There are still problems find smart cards from the temp
277
* db. This will get smart cards working again. The real fix
278
* is to make sure we can search the temp db by their token nickname.
281
cert = CERT_FindCertByNickname(handle,nickname);
284
if ( cert != NULL ) {
285
/* collect certs for this nickname, sorting them into the list */
286
certList = CERT_CreateSubjectCertList(certList, handle,
287
&cert->derSubject, time, validOnly);
289
CERT_FilterCertListForUserCerts(certList);
291
/* drop the extra reference */
292
CERT_DestroyCertificate(cert);
296
if ( certList == NULL ) {
300
/* remove certs with incorrect usage */
301
rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);
303
if ( rv != SECSuccess ) {
307
if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) {
308
cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
312
if ( certList != NULL ) {
313
CERT_DestroyCertList(certList);
320
CERT_MatchUserCert(CERTCertDBHandle *handle,
322
int nCANames, char **caNames,
325
CERTCertList *certList = NULL;
328
certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE,
330
if ( certList == NULL ) {
334
rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage);
335
if ( rv != SECSuccess ) {
342
if ( certList != NULL ) {
343
CERT_DestroyCertList(certList);
353
typedef struct stringNode {
354
struct stringNode *next;
359
CollectNicknames( NSSCertificate *c, void *data)
361
CERTCertNicknames *names;
362
PRBool saveit = PR_FALSE;
370
char *nickname = NULL;
372
names = (CERTCertNicknames *)data;
374
stanNickname = nssCertificate_GetNickname(c,NULL);
376
if ( stanNickname ) {
377
if (names->what == SEC_CERT_NICKNAMES_USER) {
378
saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL);
382
td = NSSCertificate_GetTrustDomain(c);
386
trust = nssTrustDomain_FindTrustForCertificate(td,c);
388
switch(names->what) {
389
case SEC_CERT_NICKNAMES_ALL:
390
if ((trust->sslFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
391
(trust->emailFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
392
(trust->objectSigningFlags &
393
(CERTDB_VALID_CA|CERTDB_VALID_PEER))) {
398
case SEC_CERT_NICKNAMES_SERVER:
399
if ( trust->sslFlags & CERTDB_VALID_PEER ) {
404
case SEC_CERT_NICKNAMES_CA:
405
if (((trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA)||
406
((trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA) ||
407
((trust->objectSigningFlags & CERTDB_VALID_CA )
408
== CERTDB_VALID_CA)) {
417
/* traverse the list of collected nicknames and make sure we don't make
421
nickname = STAN_GetCERTCertificateName(NULL, c);
422
/* nickname can only be NULL here if we are having memory
424
if (nickname == NULL) {
427
node = (stringNode *)names->head;
428
while ( node != NULL ) {
429
if ( PORT_Strcmp(nickname, node->string) == 0 ) {
430
/* if the string matches, then don't save this one */
440
/* allocate the node */
441
node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode));
442
if ( node == NULL ) {
446
/* copy the string */
447
len = PORT_Strlen(nickname) + 1;
448
node->string = (char*)PORT_ArenaAlloc(names->arena, len);
449
if ( node->string == NULL ) {
450
if (nickname) PORT_Free(nickname);
453
PORT_Memcpy(node->string, nickname, len);
455
/* link it into the list */
456
node->next = (stringNode *)names->head;
457
names->head = (void *)node;
460
names->numnicknames++;
463
if (nickname) PORT_Free(nickname);
468
CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
471
CERTCertNicknames *names;
475
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
476
if ( arena == NULL ) {
477
PORT_SetError(SEC_ERROR_NO_MEMORY);
481
names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
482
if ( names == NULL ) {
486
names->arena = arena;
488
names->numnicknames = 0;
489
names->nicknames = NULL;
493
/* make sure we are logged in */
494
(void) pk11_TraverseAllSlots(NULL, NULL, wincx);
496
NSSTrustDomain_TraverseCertificates(handle,
497
CollectNicknames, (void *)names);
498
if ( names->numnicknames ) {
499
names->nicknames = (char**)PORT_ArenaAlloc(arena,
500
names->numnicknames * sizeof(char *));
502
if ( names->nicknames == NULL ) {
506
node = (stringNode *)names->head;
508
for ( i = 0; i < names->numnicknames; i++ ) {
509
PORT_Assert(node != NULL);
511
names->nicknames[i] = node->string;
512
names->totallen += PORT_Strlen(node->string);
516
PORT_Assert(node == NULL);
522
PORT_FreeArena(arena, PR_FALSE);
527
CERT_FreeNicknames(CERTCertNicknames *nicknames)
529
PORT_FreeArena(nicknames->arena, PR_FALSE);
534
/* [ FROM pcertdb.c ] */
536
typedef struct dnameNode {
537
struct dnameNode *next;
542
CERT_FreeDistNames(CERTDistNames *names)
544
PORT_FreeArena(names->arena, PR_FALSE);
550
CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
552
CERTDistNames *names;
553
PRBool saveit = PR_FALSE;
554
CERTCertTrust *trust;
558
names = (CERTDistNames *)data;
563
/* only collect names of CAs trusted for issuing SSL clients */
564
if ( trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ) {
570
/* allocate the node */
571
node = (dnameNode*)PORT_ArenaAlloc(names->arena, sizeof(dnameNode));
572
if ( node == NULL ) {
577
node->name.len = len = cert->derSubject.len;
578
node->name.type = siBuffer;
579
node->name.data = (unsigned char*)PORT_ArenaAlloc(names->arena, len);
580
if ( node->name.data == NULL ) {
583
PORT_Memcpy(node->name.data, cert->derSubject.data, len);
585
/* link it into the list */
586
node->next = (dnameNode *)names->head;
587
names->head = (void *)node;
597
* Return all of the CAs that are "trusted" for SSL.
600
CERT_GetSSLCACerts(CERTCertDBHandle *handle)
603
CERTDistNames *names;
608
/* allocate an arena to use */
609
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
610
if ( arena == NULL ) {
611
PORT_SetError(SEC_ERROR_NO_MEMORY);
615
/* allocate the header structure */
616
names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
617
if ( names == NULL ) {
621
/* initialize the header struct */
622
names->arena = arena;
627
/* collect the names from the database */
628
rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL);
633
/* construct the array from the list */
634
if ( names->nnames ) {
635
names->names = (SECItem*)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem));
637
if ( names->names == NULL ) {
641
node = (dnameNode *)names->head;
643
for ( i = 0; i < names->nnames; i++ ) {
644
PORT_Assert(node != NULL);
646
names->names[i] = node->name;
650
PORT_Assert(node == NULL);
656
PORT_FreeArena(arena, PR_FALSE);
661
CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,
664
CERTDistNames *dnames = NULL;
667
SECItem *names = NULL;
668
CERTCertificate *cert = NULL;
670
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
671
if (arena == NULL) goto loser;
672
dnames = (CERTDistNames*)PORT_Alloc(sizeof(CERTDistNames));
673
if (dnames == NULL) goto loser;
675
dnames->arena = arena;
676
dnames->nnames = nnames;
677
dnames->names = names = (SECItem*)PORT_Alloc(nnames * sizeof(SECItem));
678
if (names == NULL) goto loser;
680
for (i = 0; i < nnames; i++) {
681
cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]);
682
if (cert == NULL) goto loser;
683
rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject);
684
if (rv == SECFailure) goto loser;
685
CERT_DestroyCertificate(cert);
691
CERT_DestroyCertificate(cert);
693
PORT_FreeArena(arena, PR_FALSE);
697
/* [ from pcertdb.c - calls Ascii to Name ] */
699
* Lookup a certificate in the database by name
702
CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr)
706
CERTCertificate *cert = NULL;
707
PRArenaPool *arena = NULL;
709
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
711
if ( arena == NULL ) {
715
name = CERT_AsciiToName(nameStr);
718
nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name,
720
if ( nameItem == NULL ) {
724
cert = CERT_FindCertByName(handle, nameItem);
725
CERT_DestroyName(name);
730
PORT_FreeArena(arena, PR_FALSE);
738
CERTCrlDistributionPoints *
739
CERT_FindCRLDistributionPoints (CERTCertificate *cert)
741
SECItem encodedExtenValue;
744
encodedExtenValue.data = NULL;
745
encodedExtenValue.len = 0;
747
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS,
749
if ( rv != SECSuccess ) {
753
return (CERT_DecodeCRLDistributionPoints (cert->arena,
754
&encodedExtenValue));
758
CERTSignedCrl * CERT_ImportCRL
759
(CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx)
761
CERTSignedCrl* retCrl = NULL;
762
PK11SlotInfo* slot = PK11_GetInternalKeySlot();
763
retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx,
764
CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
772
cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool trusted)
776
CERTCertificate *cert = NULL;
777
CERTCertificate *newcert = NULL;
778
CERTCertDBHandle *handle;
782
unsigned int certtype;
784
handle = CERT_GetDefaultCertDB();
790
/* decode my certificate */
791
/* This use is ok -- only looks at decoded parts, calls NewTemp later */
792
newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
793
if ( newcert == NULL ) {
798
/* make sure that cert is valid */
799
rv = CERT_CertTimesValid(newcert);
800
if ( rv == SECFailure ) {
805
/* does it have the CA extension */
808
* Make sure that if this is an intermediate CA in the chain that
809
* it was given permission by its signer to be a CA.
811
isca = CERT_IsCACert(newcert, &certtype);
817
trust.sslFlags = CERTDB_VALID_CA;
818
trust.emailFlags = CERTDB_VALID_CA;
819
trust.objectSigningFlags = CERTDB_VALID_CA;
821
/* SSL ca's must have the ssl bit set */
822
if ( ( certUsage == certUsageSSLCA ) &&
823
(( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA )) {
827
/* it passed all of the tests, so lets add it to the database */
828
/* mark it as a CA */
829
PORT_Memset((void *)&trust, 0, sizeof(trust));
830
switch ( certUsage ) {
832
trust.sslFlags = CERTDB_VALID_CA;
834
case certUsageUserCertImport:
835
if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
836
trust.sslFlags = CERTDB_VALID_CA;
838
if ((certtype & NS_CERT_TYPE_EMAIL_CA)
839
== NS_CERT_TYPE_EMAIL_CA ) {
840
trust.emailFlags = CERTDB_VALID_CA;
842
if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) ==
843
NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
844
trust.objectSigningFlags = CERTDB_VALID_CA;
853
cert = CERT_NewTempCertificate(handle, derCert, NULL,
855
if ( cert == NULL ) {
859
/* if the cert is temp, make it perm; otherwise we're done */
861
/* get a default nickname for it */
862
nickname = CERT_MakeCANickname(cert);
864
rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
866
/* free the nickname */
874
CERT_DestroyCertificate(cert);
877
if ( rv != SECSuccess ) {
883
CERT_DestroyCertificate(newcert);
896
CERT_DestroyCertificate(newcert);
901
CERT_DestroyCertificate(cert);
909
CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage)
911
return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE);
915
CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage) {
916
return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE);
919
/* Moved from certdb.c */
921
** CERT_CertChainFromCert
923
** Construct a CERTCertificateList consisting of the given certificate and all
924
** of the issuer certs until we either get to a self-signed cert or can't find
925
** an issuer. Since we don't know how many certs are in the chain we have to
926
** build a linked list first as we count them.
929
typedef struct certNode {
930
struct certNode *next;
931
CERTCertificate *cert;
934
CERTCertificateList *
935
CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
939
CERTCertificateList *chain = NULL;
943
PRArenaPool *tmpArena, *arena;
944
certNode *head, *tail, *node;
947
* Initialize stuff so we can goto loser.
952
/* arena for linked list */
953
tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
954
if (tmpArena == NULL) goto no_memory;
956
/* arena for SecCertificateList */
957
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
958
if (arena == NULL) goto no_memory;
960
head = tail = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode));
961
if (head == NULL) goto no_memory;
963
/* put primary cert first in the linked list */
964
head->cert = c = CERT_DupCertificate(cert);
965
if (head->cert == NULL) goto loser;
968
/* add certs until we come to a self-signed one */
969
while(SECITEM_CompareItem(&c->derIssuer, &c->derSubject) != SECEqual) {
970
c = CERT_FindCertIssuer(tail->cert, PR_Now(), usage);
972
/* no root is found, so make sure we don't attempt to delete one
975
includeRoot = PR_TRUE;
979
tail->next = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode));
981
if (tail == NULL) goto no_memory;
987
/* now build the CERTCertificateList */
988
chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
989
if (chain == NULL) goto no_memory;
990
chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
991
if (chain->certs == NULL) goto no_memory;
993
for(node = head, p = chain->certs; node; node = node->next, p++) {
994
rv = SECITEM_CopyItem(arena, p, &node->cert->derCert);
995
CERT_DestroyCertificate(node->cert);
997
if (rv < 0) goto loser;
999
if ( !includeRoot && len > 1) {
1000
chain->len = len - 1;
1005
chain->arena = arena;
1007
PORT_FreeArena(tmpArena, PR_FALSE);
1012
PORT_SetError(SEC_ERROR_NO_MEMORY);
1015
for (node = head; node; node = node->next) {
1016
if (node->cert != NULL)
1017
CERT_DestroyCertificate(node->cert);
1021
if (arena != NULL) {
1022
PORT_FreeArena(arena, PR_FALSE);
1025
if (tmpArena != NULL) {
1026
PORT_FreeArena(tmpArena, PR_FALSE);
1031
CERTCertificateList *chain = NULL;
1032
NSSCertificate **stanChain;
1033
NSSCertificate *stanCert;
1038
stanCert = STAN_GetNSSCertificate(cert);
1039
nssUsage.anyUsage = PR_FALSE;
1040
nssUsage.nss3usage = usage;
1041
nssUsage.nss3lookingForCA = PR_FALSE;
1042
stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL,
1043
NULL, 0, NULL, NULL);
1049
stanCert = stanChain[0];
1051
stanCert = stanChain[++len];
1054
arena = PORT_NewArena(4096);
1055
if (arena == NULL) {
1059
chain = (CERTCertificateList *)PORT_ArenaAlloc(arena,
1060
sizeof(CERTCertificateList));
1061
if (!chain) goto loser;
1062
chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
1063
if (!chain->certs) goto loser;
1065
stanCert = stanChain[i];
1068
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
1072
derCert.len = (unsigned int)stanCert->encoding.size;
1073
derCert.data = (unsigned char *)stanCert->encoding.data;
1074
derCert.type = siBuffer;
1075
SECITEM_CopyItem(arena, &chain->certs[i], &derCert);
1076
stanCert = stanChain[++i];
1077
if (!stanCert && !cCert->isRoot) {
1078
/* reached the end of the chain, but the final cert is
1079
* not a root. Don't discard it.
1081
includeRoot = PR_TRUE;
1083
CERT_DestroyCertificate(cCert);
1085
if ( !includeRoot && len > 1) {
1086
chain->len = len - 1;
1091
chain->arena = arena;
1092
nss_ZFreeIf(stanChain);
1096
stanCert = stanChain[i];
1098
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
1100
CERT_DestroyCertificate(cCert);
1102
stanCert = stanChain[++i];
1104
nss_ZFreeIf(stanChain);
1106
PORT_FreeArena(arena, PR_FALSE);
1112
/* Builds a CERTCertificateList holding just one DER-encoded cert, namely
1113
** the one for the cert passed as an argument.
1115
CERTCertificateList *
1116
CERT_CertListFromCert(CERTCertificate *cert)
1118
CERTCertificateList *chain = NULL;
1122
/* arena for SecCertificateList */
1123
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1124
if (arena == NULL) goto no_memory;
1126
/* build the CERTCertificateList */
1127
chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
1128
if (chain == NULL) goto no_memory;
1129
chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem));
1130
if (chain->certs == NULL) goto no_memory;
1131
rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert));
1132
if (rv < 0) goto loser;
1134
chain->arena = arena;
1139
PORT_SetError(SEC_ERROR_NO_MEMORY);
1141
if (arena != NULL) {
1142
PORT_FreeArena(arena, PR_FALSE);
1147
CERTCertificateList *
1148
CERT_DupCertList(CERTCertificateList * oldList)
1150
CERTCertificateList *newList = NULL;
1151
PRArenaPool *arena = NULL;
1154
int len = oldList->len;
1157
/* arena for SecCertificateList */
1158
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1162
/* now build the CERTCertificateList */
1163
newList = PORT_ArenaNew(arena, CERTCertificateList);
1164
if (newList == NULL)
1166
newList->arena = arena;
1167
newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
1168
if (newItem == NULL)
1170
newList->certs = newItem;
1173
for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {
1174
rv = SECITEM_CopyItem(arena, newItem, oldItem);
1181
PORT_SetError(SEC_ERROR_NO_MEMORY);
1183
if (arena != NULL) {
1184
PORT_FreeArena(arena, PR_FALSE);
1190
CERT_DestroyCertificateList(CERTCertificateList *list)
1192
PORT_FreeArena(list->arena, PR_FALSE);