2 * Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 * clNameUtils.cpp - support for Name, GeneralizedName, all sorts of names
22 #include "clNameUtils.h"
23 #include "clNssUtils.h"
24 #include "cldebugging.h"
25 #include <Security/utilities.h>
27 #pragma mark ----- NSS_Name <--> CSSM_X509_NAME -----
30 * NSS_ATV --> CSSM_X509_TYPE_VALUE_PAIR
34 const NSS_ATV
&nssObj
,
35 CSSM_X509_TYPE_VALUE_PAIR
&cssmObj
,
38 /* tag and decoded data */
39 cssmObj
.valueType
= nssObj
.value
.tag
;
40 clAllocCopyData(alloc
, nssObj
.value
.item
, cssmObj
.value
);
42 clAllocCopyData(alloc
, nssObj
.type
, cssmObj
.type
);
45 /* NSS_RDN --> CSSM_X509_RDN */
47 const NSS_RDN
&nssObj
,
48 CSSM_X509_RDN
&cssmObj
,
50 SecNssCoder
&coder
) // conversion requires further decoding
52 memset(&cssmObj
, 0, sizeof(cssmObj
));
53 unsigned numAtvs
= clNssArraySize((const void **)nssObj
.atvs
);
58 size_t len
= numAtvs
* sizeof(CSSM_X509_TYPE_VALUE_PAIR
);
59 cssmObj
.AttributeTypeAndValue
=
60 (CSSM_X509_TYPE_VALUE_PAIR_PTR
)alloc
.malloc(len
);
61 cssmObj
.numberOfPairs
= numAtvs
;
62 CSSM_X509_TYPE_VALUE_PAIR_PTR cssmAtvs
= cssmObj
.AttributeTypeAndValue
;
63 memset(cssmAtvs
, 0, len
);
65 for(unsigned dex
=0; dex
<numAtvs
; dex
++) {
66 CL_nssAtvToCssm(*(nssObj
.atvs
[dex
]), cssmAtvs
[dex
], alloc
);
71 /* NSS_Name --> CSSM_X509_NAME */
72 void CL_nssNameToCssm(
73 const NSS_Name
&nssObj
,
74 CSSM_X509_NAME
&cssmObj
,
77 memset(&cssmObj
, 0, sizeof(cssmObj
));
78 unsigned numRdns
= clNssArraySize((const void **)nssObj
.rdns
);
80 /* not technically an error */
84 size_t len
= numRdns
* sizeof(CSSM_X509_RDN
);
85 cssmObj
.RelativeDistinguishedName
= (CSSM_X509_RDN_PTR
)alloc
.malloc(len
);
86 cssmObj
.numberOfRDNs
= numRdns
;
87 CSSM_X509_RDN_PTR cssmRdns
= cssmObj
.RelativeDistinguishedName
;
88 memset(cssmRdns
, 0, len
);
90 SecNssCoder coder
; // conversion requires further decoding
92 for(unsigned dex
=0; dex
<numRdns
; dex
++) {
93 CL_nssRdnToCssm(*(nssObj
.rdns
[dex
]), cssmRdns
[dex
], alloc
, coder
);
99 * CSSM_X509_TYPE_VALUE_PAIR --> NSS_ATV
101 void CL_cssmAtvToNss(
102 const CSSM_X509_TYPE_VALUE_PAIR
&cssmObj
,
106 memset(&nssObj
, 0, sizeof(nssObj
));
109 coder
.allocCopyItem(cssmObj
.type
, nssObj
.type
);
112 nssObj
.value
.tag
= cssmObj
.valueType
;
113 coder
.allocCopyItem(cssmObj
.value
, nssObj
.value
.item
);
116 /* CSSM_X509_RDN --> NSS_RDN */
117 void CL_cssmRdnToNss(
118 const CSSM_X509_RDN
&cssmObj
,
122 memset(&nssObj
, 0, sizeof(nssObj
));
124 /* alloc NULL-terminated array of ATV pointers */
125 unsigned numAtvs
= cssmObj
.numberOfPairs
;
126 unsigned size
= (numAtvs
+ 1) * sizeof(void *);
127 nssObj
.atvs
= (NSS_ATV
**)coder
.malloc(size
);
128 memset(nssObj
.atvs
, 0, size
);
130 /* grind thru the elements */
131 for(unsigned atvDex
=0; atvDex
<numAtvs
; atvDex
++) {
132 nssObj
.atvs
[atvDex
] = (NSS_ATV
*)coder
.malloc(sizeof(NSS_ATV
));
133 CL_cssmAtvToNss(cssmObj
.AttributeTypeAndValue
[atvDex
],
134 *nssObj
.atvs
[atvDex
], coder
);
138 /* CSSM_X509_NAME --> NSS_Name */
139 void CL_cssmNameToNss(
140 const CSSM_X509_NAME
&cssmObj
,
144 memset(&nssObj
, 0, sizeof(nssObj
));
146 /* alloc NULL-terminated array of RDN pointers */
147 unsigned numRdns
= cssmObj
.numberOfRDNs
;
148 nssObj
.rdns
= (NSS_RDN
**)clNssNullArray(numRdns
, coder
);
150 /* grind thru the elements */
151 for(unsigned rdnDex
=0; rdnDex
<numRdns
; rdnDex
++) {
152 nssObj
.rdns
[rdnDex
] = (NSS_RDN
*)coder
.malloc(sizeof(NSS_RDN
));
153 CL_cssmRdnToNss(cssmObj
.RelativeDistinguishedName
[rdnDex
],
154 *nssObj
.rdns
[rdnDex
], coder
);
158 #pragma mark ----- Name Normalization -----
160 void CL_normalizeString(
162 int &strLen
) // IN/OUT
164 char *pCh
= strPtr
; // working ptr
165 char *pD
= pCh
; // start of good string chars
166 char *pEos
= pCh
+ strLen
- 1;
172 /* adjust if Length included NULL terminator */
177 /* Remove trailing spaces */
178 while(isspace(*pEos
)) {
182 /* Point to one past last non-space character */
187 *pCh
= toupper(*pCh
);
191 /* clean out whitespace */
193 * 1. skip all leading whitespace
196 while(isspace(*pCh
) && (pCh
< pEos
)) {
201 * 2. eliminate multiple whitespace.
202 * pCh points to first non-white char.
203 * pD still points to start of string
208 *pD
++ = ch
; // normal case
210 /* skip 'til next nonwhite */
211 while(isspace(*pCh
) && (pCh
< pEos
)) {
217 strLen
= pD
- strPtr
;
221 * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case
222 * insensitive and we're supposed to ignore leading and trailing
223 * whitespace, and collapse multiple whitespace characters into one.
225 * Incoming NSS_Name is assumed to be entirely within specifed coder's
226 * address space; we'll be munging some of that and possibly replacing
227 * some pointers with others allocated from the same space.
229 void CL_normalizeX509NameNSS(
233 unsigned numRdns
= clNssArraySize((const void **)nssName
.rdns
);
235 /* not technically an error */
239 for(unsigned rdnDex
=0; rdnDex
<numRdns
; rdnDex
++) {
240 NSS_RDN
*rdn
= nssName
.rdns
[rdnDex
];
242 unsigned numAttrs
= clNssArraySize((const void **)rdn
->atvs
);
244 clFieldLog("clNormalizeX509Name: zero numAttrs at index %d", rdnDex
);
248 /* descend into array of attribute/values */
249 for(unsigned attrDex
=0; attrDex
<numAttrs
; attrDex
++) {
250 NSS_ATV
*attr
= rdn
->atvs
[attrDex
];
251 assert(attr
!= NULL
);
254 * attr->value is an ASN_ANY containing an encoded
255 * string. We only normalize Prinatable String types.
256 * If we find one, decode it, normalize it, encode the
257 * result, and put the encoding back in attr->value.
258 * We temporarily "leak" the original string, which only
259 * has a lifetime of the incoming SecNssCoder.
261 NSS_TaggedItem
&attrVal
= attr
->value
;
262 if(attrVal
.tag
!= SEC_ASN1_PRINTABLE_STRING
) {
268 char *strPtr
= (char *)attrVal
.item
.Data
;
269 int newLen
= attrVal
.item
.Length
;
270 CL_normalizeString(strPtr
, newLen
);
272 /* possible length adjustment */
273 attrVal
.item
.Length
= newLen
;
274 } /* for each attribute/value */
278 #pragma mark ----- CE_GeneralNames <--> NSS_GeneralNames -----
280 void CL_nssGeneralNameToCssm(
281 NSS_GeneralName
&nssObj
,
282 CE_GeneralName
&cdsaObj
,
283 SecNssCoder
&coder
, // for temp decoding
284 CssmAllocator
&alloc
) // destination
286 memset(&cdsaObj
, 0, sizeof(cdsaObj
));
289 /* for caller's CE_GeneralName */
290 CSSM_BOOL berEncoded
= CSSM_FALSE
;
291 CE_GeneralNameType cdsaTag
;
294 * At this point, depending on the decoded object's tag, we either
295 * have the final bytes to copy out, or we need to decode further.
296 * After this switch, if doCopy is true, give the caller a copy
301 case NGT_OtherName
: // ASN_ANY -> CE_OtherName
303 cdsaTag
= GNT_OtherName
;
305 /* decode to coder memory */
306 CE_OtherName
*nssOther
=
307 (CE_OtherName
*)coder
.malloc(sizeof(CE_OtherName
));
308 memset(nssOther
, 0, sizeof(CE_OtherName
));
309 prtn
= coder
.decodeItem(nssObj
.item
,
310 NSS_GenNameOtherNameTemplate
,
313 clErrorLog("CL_nssGeneralNameToCssm: error decoding "
315 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
318 /* copy out to caller */
319 clAllocData(alloc
, cdsaObj
.name
, sizeof(CE_OtherName
));
320 clCopyOtherName(*nssOther
, *((CE_OtherName
*)cdsaObj
.name
.Data
),
325 case NGT_RFC822Name
: // IA5String, done
326 cdsaTag
= GNT_RFC822Name
;
328 case NGT_DNSName
: // IA5String
329 cdsaTag
= GNT_DNSName
;
331 case NGT_X400Address
: // ASY_ANY, leave alone
332 cdsaTag
= GNT_X400Address
;
333 berEncoded
= CSSM_TRUE
;
335 case NGT_DirectoryName
: // ASN_ANY --> NSS_Name
337 cdsaTag
= GNT_DirectoryName
;
339 /* Decode to coder memory */
340 NSS_Name
*nssName
= (NSS_Name
*)coder
.malloc(sizeof(NSS_Name
));
341 memset(nssName
, 0, sizeof(NSS_Name
));
342 prtn
= coder
.decodeItem(nssObj
.item
, NSS_NameTemplate
, nssName
);
344 clErrorLog("CL_nssGeneralNameToCssm: error decoding "
346 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
349 /* convert & copy out to caller */
350 clAllocData(alloc
, cdsaObj
.name
, sizeof(CSSM_X509_NAME
));
351 CL_nssNameToCssm(*nssName
,
352 *((CSSM_X509_NAME
*)cdsaObj
.name
.Data
), alloc
);
356 case NGT_EdiPartyName
: // ASN_ANY, leave alone
357 cdsaTag
= GNT_EdiPartyName
;
358 berEncoded
= CSSM_TRUE
;
360 case NGT_URI
: // IA5String
363 case NGT_IPAddress
: // OCTET_STRING
364 cdsaTag
= GNT_IPAddress
;
366 case NGT_RegisteredID
: // OID
367 cdsaTag
= GNT_RegisteredID
;
370 clErrorLog("CL_nssGeneralNameToCssm: bad name tag\n");
371 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
374 cdsaObj
.nameType
= cdsaTag
;
375 cdsaObj
.berEncoded
= berEncoded
;
377 clAllocCopyData(alloc
, nssObj
.item
, cdsaObj
.name
);
381 void CL_nssGeneralNamesToCssm(
382 const NSS_GeneralNames
&nssObj
,
383 CE_GeneralNames
&cdsaObj
,
384 SecNssCoder
&coder
, // for temp decoding
385 CssmAllocator
&alloc
) // destination
387 memset(&cdsaObj
, 0, sizeof(cdsaObj
));
388 unsigned numNames
= clNssArraySize((const void **)nssObj
.names
);
394 * Decode each name element, currently a raw ASN_ANY blob.
395 * Then convert each result into CDSA form.
396 * This array of (NSS_GeneralName)s is temporary, it doesn't
397 * persist outside of this routine other than the fact that it's
398 * mallocd by the coder arena pool.
400 NSS_GeneralName
*names
=
401 (NSS_GeneralName
*)coder
.malloc(sizeof(NSS_GeneralName
) * numNames
);
402 memset(names
, 0, sizeof(NSS_GeneralName
) * numNames
);
403 cdsaObj
.generalName
= (CE_GeneralName
*)alloc
.malloc(
404 sizeof(CE_GeneralName
) * numNames
);
405 cdsaObj
.numNames
= numNames
;
407 for(unsigned dex
=0; dex
<numNames
; dex
++) {
408 if(coder
.decodeItem(*nssObj
.names
[dex
], NSS_GeneralNameTemplate
,
410 clErrorLog("***CL_nssGeneralNamesToCssm: Error decoding "
412 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
415 CL_nssGeneralNameToCssm(names
[dex
],
416 cdsaObj
.generalName
[dex
],
421 void CL_cssmGeneralNameToNss(
422 CE_GeneralName
&cdsaObj
,
423 NSS_GeneralName
&nssObj
, // actually an NSSTaggedItem
424 SecNssCoder
&coder
) // for temp decoding
426 memset(&nssObj
, 0, sizeof(nssObj
));
429 * The default here is just to use the app-supplied data as is...
431 nssObj
.item
= cdsaObj
.name
;
432 unsigned char itemTag
; // for nssObj.tag
433 bool doCopy
= false; // unless we have to modify tag byte
434 unsigned char overrideTag
; // to force context-specific tag for
438 switch(cdsaObj
.nameType
) {
441 * Caller supplies an CE_OtherName. Encode it.
443 if((cdsaObj
.name
.Length
!= sizeof(CE_OtherName
)) ||
444 (cdsaObj
.name
.Data
== NULL
)) {
445 clErrorLog("CL_cssmGeneralNameToNss: OtherName.Length"
447 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
449 prtn
= coder
.encodeItem(cdsaObj
.name
.Data
,
450 NSS_OtherNameTemplate
, nssObj
.item
);
452 clErrorLog("CL_cssmGeneralNameToNss: OtherName encode"
454 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR
);
456 itemTag
= NGT_OtherName
;
458 case GNT_RFC822Name
: // IA5String
459 itemTag
= NGT_RFC822Name
;
461 case GNT_DNSName
: // IA5String
462 itemTag
= NGT_DNSName
;
464 case GNT_X400Address
: // caller's resposibility
466 * Encoded as ASN_ANY, the only thing we do is to
467 * force the correct context-specific tag
469 itemTag
= GNT_X400Address
;
470 if(!cdsaObj
.berEncoded
) {
471 clErrorLog("CL_cssmGeneralNameToNss: X400Address must"
472 " be BER-encoded\n");
473 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
475 overrideTag
= SEC_ASN1_CONTEXT_SPECIFIC
|
476 SEC_ASN1_CONSTRUCTED
| NGT_X400Address
;
479 case GNT_DirectoryName
:
482 * Caller supplies an CSSM_X509_NAME. Convert to NSS
483 * format and encode it.
485 if((cdsaObj
.name
.Length
!= sizeof(CSSM_X509_NAME
)) ||
486 (cdsaObj
.name
.Data
== NULL
)) {
487 clErrorLog("CL_cssmGeneralNameToNss: DirectoryName.Length"
489 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
492 CSSM_X509_NAME_PTR cdsaName
=
493 (CSSM_X509_NAME_PTR
)cdsaObj
.name
.Data
;
494 CL_cssmNameToNss(*cdsaName
, nssName
, coder
);
495 prtn
= coder
.encodeItem(&nssName
,
496 NSS_NameTemplate
, nssObj
.item
);
498 clErrorLog("CL_cssmGeneralNameToNss: X509Name encode"
500 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR
);
502 itemTag
= GNT_DirectoryName
;
505 * AND, munge the tag to make it a context-specific
507 * no, not needed, this is wrapped in an explicit...
509 //nssObj.item.Data[0] = SEC_ASN1_CONTEXT_SPECIFIC |
510 // SEC_ASN1_CONSTRUCTED | GNT_DirectoryName;
514 case GNT_EdiPartyName
: // caller's resposibility
516 * Encoded as ASN_ANY, the only thing we do is to
517 * force the correct context-specific tag
519 itemTag
= GNT_EdiPartyName
;
520 if(!cdsaObj
.berEncoded
) {
521 clErrorLog("CL_cssmGeneralNameToNss: EdiPartyName must"
522 " be BER-encoded\n");
523 CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT
);
525 overrideTag
= SEC_ASN1_CONTEXT_SPECIFIC
| NGT_X400Address
;
528 case GNT_URI
: // IA5String
531 case GNT_IPAddress
: // OCTET_STRING
532 itemTag
= NGT_IPAddress
;
534 case GNT_RegisteredID
: // OID
535 itemTag
= NGT_RegisteredID
;
538 clErrorLog("CL_cssmGeneralNameToNss: bad name tag\n");
539 CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG
);
542 coder
.allocCopyItem(cdsaObj
.name
, nssObj
.item
);
543 nssObj
.item
.Data
[0] = overrideTag
;
545 nssObj
.tag
= itemTag
;
548 void CL_cssmGeneralNamesToNss(
549 const CE_GeneralNames
&cdsaObj
,
550 NSS_GeneralNames
&nssObj
,
553 uint32 numNames
= cdsaObj
.numNames
;
554 nssObj
.names
= (CSSM_DATA
**)clNssNullArray(numNames
, coder
);
557 * Convert each element in cdsaObj to NSS form, encode, drop into
560 * This array of (NSS_GeneralName)s is temporary, it doesn't
561 * persist outside of this routine other than the fact that it's
562 * mallocd by the coder arena pool.
564 NSS_GeneralName
*names
=
565 (NSS_GeneralName
*)coder
.malloc(sizeof(NSS_GeneralName
) * numNames
);
566 memset(names
, 0, sizeof(NSS_GeneralName
) * numNames
);
567 for(unsigned dex
=0; dex
<cdsaObj
.numNames
; dex
++) {
568 nssObj
.names
[dex
] = (CSSM_DATA_PTR
)coder
.malloc(sizeof(CSSM_DATA
));
569 memset(nssObj
.names
[dex
], 0, sizeof(CSSM_DATA
));
570 CL_cssmGeneralNameToNss(cdsaObj
.generalName
[dex
],
572 if(coder
.encodeItem(&names
[dex
], NSS_GeneralNameTemplate
,
573 *nssObj
.names
[dex
])) {
574 clErrorLog("***Error encoding General.name\n");
575 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR
);
580 /* Copy a CE_OtherName */
581 void clCopyOtherName(
582 const CE_OtherName
&src
,
584 CssmAllocator
&alloc
)
586 clAllocCopyData(alloc
, src
.typeId
, dst
.typeId
);
587 clAllocCopyData(alloc
, src
.value
, dst
.value
);
590 #pragma mark ----- Name-related Free -----
592 void CL_freeAuthorityKeyId(
593 CE_AuthorityKeyID
&cdsaObj
,
594 CssmAllocator
&alloc
)
596 alloc
.free(cdsaObj
.keyIdentifier
.Data
);
597 CL_freeCssmGeneralNames(cdsaObj
.generalNames
, alloc
);
598 alloc
.free(cdsaObj
.generalNames
);
599 alloc
.free(cdsaObj
.serialNumber
.Data
);
600 memset(&cdsaObj
, 0, sizeof(CE_AuthorityKeyID
));
603 void CL_freeCssmGeneralNames(
604 CE_GeneralNames
*cdsaObj
,
605 CssmAllocator
&alloc
)
607 if(cdsaObj
== NULL
) {
610 for(unsigned i
=0; i
<cdsaObj
->numNames
; i
++) {
612 * Two special cases here.
614 CE_GeneralName
*genName
= &cdsaObj
->generalName
[i
];
615 switch(genName
->nameType
) {
616 case GNT_DirectoryName
:
617 if((!genName
->berEncoded
) && // we're flexible
618 (genName
->name
.Length
==
619 sizeof(CSSM_X509_NAME
))) { // paranoia
620 CL_freeX509Name((CSSM_X509_NAME_PTR
)genName
->name
.Data
, alloc
);
625 if((!genName
->berEncoded
) && // we're flexible
626 (genName
->name
.Length
==
627 sizeof(CE_OtherName
))) { // paranoia
628 CE_OtherName
*con
= (CE_OtherName
*)genName
->name
.Data
;
629 CL_freeOtherName(con
, alloc
);
635 /* and always free this */
636 alloc
.free(cdsaObj
->generalName
[i
].name
.Data
);
638 if(cdsaObj
->numNames
) {
639 memset(cdsaObj
->generalName
, 0, cdsaObj
->numNames
* sizeof(CE_GeneralName
));
640 alloc
.free(cdsaObj
->generalName
);
642 memset(cdsaObj
, 0, sizeof(CE_GeneralNames
));
645 void CL_freeCssmDistPoints(
646 CE_CRLDistPointsSyntax
*cssmDps
,
647 CssmAllocator
&alloc
)
649 if(cssmDps
== NULL
) {
652 for(unsigned dex
=0; dex
<cssmDps
->numDistPoints
; dex
++) {
653 CE_CRLDistributionPoint
*cssmDp
= &cssmDps
->distPoints
[dex
];
654 if(cssmDp
->distPointName
) {
655 CL_freeCssmDistPointName(cssmDp
->distPointName
, alloc
);
656 alloc
.free(cssmDp
->distPointName
);
658 if(cssmDp
->crlIssuer
) {
659 CL_freeCssmGeneralNames(cssmDp
->crlIssuer
, alloc
);
660 alloc
.free(cssmDp
->crlIssuer
);
663 memset(cssmDps
->distPoints
, 0,
664 cssmDps
->numDistPoints
* sizeof(CE_CRLDistributionPoint
));
665 alloc
.free(cssmDps
->distPoints
);
666 memset(cssmDps
, 0, sizeof(*cssmDps
));
669 void CL_freeCssmDistPointName(
670 CE_DistributionPointName
*cssmDpn
,
671 CssmAllocator
&alloc
)
673 if(cssmDpn
== NULL
) {
676 switch(cssmDpn
->nameType
) {
677 case CE_CDNT_FullName
:
678 CL_freeCssmGeneralNames(cssmDpn
->fullName
, alloc
);
679 alloc
.free(cssmDpn
->fullName
);
681 case CE_CDNT_NameRelativeToCrlIssuer
:
682 CL_freeX509Rdn(cssmDpn
->rdn
, alloc
);
683 alloc
.free(cssmDpn
->rdn
);
686 memset(cssmDpn
, 0, sizeof(*cssmDpn
));
689 /* free contents of an CSSM_X509_NAME */
690 void CL_freeX509Name(
691 CSSM_X509_NAME_PTR x509Name
,
692 CssmAllocator
&alloc
)
694 if(x509Name
== NULL
) {
697 for(unsigned rdnDex
=0; rdnDex
<x509Name
->numberOfRDNs
; rdnDex
++) {
698 CSSM_X509_RDN_PTR rdn
= &x509Name
->RelativeDistinguishedName
[rdnDex
];
699 CL_freeX509Rdn(rdn
, alloc
);
701 alloc
.free(x509Name
->RelativeDistinguishedName
);
702 memset(x509Name
, 0, sizeof(CSSM_X509_NAME
));
706 CSSM_X509_RDN_PTR rdn
,
707 CssmAllocator
&alloc
)
712 for(unsigned atvDex
=0; atvDex
<rdn
->numberOfPairs
; atvDex
++) {
713 CSSM_X509_TYPE_VALUE_PAIR_PTR atv
=
714 &rdn
->AttributeTypeAndValue
[atvDex
];
715 alloc
.free(atv
->type
.Data
);
716 alloc
.free(atv
->value
.Data
);
717 memset(atv
, 0, sizeof(CSSM_X509_TYPE_VALUE_PAIR
));
719 alloc
.free(rdn
->AttributeTypeAndValue
);
720 memset(rdn
, 0, sizeof(CSSM_X509_RDN
));
723 void CL_freeOtherName(
724 CE_OtherName
*cssmOther
,
725 CssmAllocator
&alloc
)
727 if(cssmOther
== NULL
) {
730 alloc
.free(cssmOther
->typeId
.Data
);
731 alloc
.free(cssmOther
->value
.Data
);
732 memset(cssmOther
, 0, sizeof(*cssmOther
));
735 void CL_freeCssmIssuingDistPoint(
736 CE_IssuingDistributionPoint
*cssmIdp
,
737 CssmAllocator
&alloc
)
739 CL_freeCssmDistPointName(cssmIdp
->distPointName
, alloc
);