]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_apple_x509_cl/lib/clNameUtils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_apple_x509_cl / lib / clNameUtils.cpp
diff --git a/libsecurity_apple_x509_cl/lib/clNameUtils.cpp b/libsecurity_apple_x509_cl/lib/clNameUtils.cpp
deleted file mode 100644 (file)
index 0c88a1e..0000000
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
- * 
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
- * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
- * specific language governing rights and limitations under the License.
- */
-
-/*
- * clNameUtils.cpp - support for Name, GeneralizedName, all sorts of names
- */
-#include "clNameUtils.h"
-#include "clNssUtils.h"
-#include "cldebugging.h"
-#include <security_utilities/utilities.h>
-
-#pragma mark ----- NSS_Name <--> CSSM_X509_NAME -----
-
-/* 
- * NSS_ATV --> CSSM_X509_TYPE_VALUE_PAIR
- */
-static
-void CL_nssAtvToCssm(
-       const NSS_ATV                           &nssObj,
-       CSSM_X509_TYPE_VALUE_PAIR       &cssmObj,
-       Allocator                               &alloc)
-{
-       /* tag and decoded data */
-       cssmObj.valueType = nssObj.value.tag;
-       clAllocCopyData(alloc, nssObj.value.item, cssmObj.value);
-       /* the OID */
-       clAllocCopyData(alloc, nssObj.type, cssmObj.type);
-}
-
-/* NSS_RDN --> CSSM_X509_RDN */
-void CL_nssRdnToCssm(
-       const NSS_RDN   &nssObj,
-       CSSM_X509_RDN   &cssmObj,
-       Allocator       &alloc,
-       SecNssCoder             &coder)         // conversion requires further decoding
-{
-       memset(&cssmObj, 0, sizeof(cssmObj));
-       unsigned numAtvs = clNssArraySize((const void **)nssObj.atvs);
-       if(numAtvs == 0) {
-               return;
-       }
-       
-       size_t len = numAtvs * sizeof(CSSM_X509_TYPE_VALUE_PAIR);
-       cssmObj.AttributeTypeAndValue = 
-                       (CSSM_X509_TYPE_VALUE_PAIR_PTR)alloc.malloc(len);
-       cssmObj.numberOfPairs = numAtvs;
-       CSSM_X509_TYPE_VALUE_PAIR_PTR cssmAtvs = cssmObj.AttributeTypeAndValue;
-       memset(cssmAtvs, 0, len);
-       
-       for(unsigned dex=0; dex<numAtvs; dex++) {
-               CL_nssAtvToCssm(*(nssObj.atvs[dex]), cssmAtvs[dex], alloc);
-       }
-       return;
-}
-
-/* NSS_Name --> CSSM_X509_NAME */
-void CL_nssNameToCssm(
-       const NSS_Name  &nssObj,
-       CSSM_X509_NAME  &cssmObj,
-       Allocator       &alloc)
-{
-       memset(&cssmObj, 0, sizeof(cssmObj));
-       unsigned numRdns = clNssArraySize((const void **)nssObj.rdns);
-       if(numRdns == 0) {
-               /* not technically an error */
-               return;
-       }
-       
-       size_t len = numRdns * sizeof(CSSM_X509_RDN);
-       cssmObj.RelativeDistinguishedName = (CSSM_X509_RDN_PTR)alloc.malloc(len);
-       cssmObj.numberOfRDNs = numRdns;
-       CSSM_X509_RDN_PTR cssmRdns = cssmObj.RelativeDistinguishedName;
-       memset(cssmRdns, 0, len);
-       
-       SecNssCoder     coder;          // conversion requires further decoding
-       
-       for(unsigned dex=0; dex<numRdns; dex++) {
-               CL_nssRdnToCssm(*(nssObj.rdns[dex]), cssmRdns[dex], alloc, coder);
-       }
-       return;
-}
-
-/* 
- * CSSM_X509_TYPE_VALUE_PAIR --> NSS_ATV 
- */
-void CL_cssmAtvToNss(
-       const CSSM_X509_TYPE_VALUE_PAIR &cssmObj,
-       NSS_ATV                                                 &nssObj,
-       SecNssCoder                                             &coder)
-{
-       memset(&nssObj, 0, sizeof(nssObj));
-       
-       /* copy the OID */
-       coder.allocCopyItem(cssmObj.type, nssObj.type);
-       
-       /* tag and value */
-       nssObj.value.tag = cssmObj.valueType;
-       coder.allocCopyItem(cssmObj.value, nssObj.value.item);
-}
-
-/* CSSM_X509_RDN --> NSS_RDN */
-void CL_cssmRdnToNss(
-       const CSSM_X509_RDN     &cssmObj,
-       NSS_RDN                         &nssObj,
-       SecNssCoder                     &coder)
-{
-       memset(&nssObj, 0, sizeof(nssObj));
-       
-       /* alloc NULL-terminated array of ATV pointers */
-       unsigned numAtvs = cssmObj.numberOfPairs;
-       unsigned size = (numAtvs + 1) * sizeof(void *);
-       nssObj.atvs = (NSS_ATV **)coder.malloc(size);
-       memset(nssObj.atvs, 0, size);
-       
-       /* grind thru the elements */
-       for(unsigned atvDex=0; atvDex<numAtvs; atvDex++) {
-               nssObj.atvs[atvDex] = (NSS_ATV *)coder.malloc(sizeof(NSS_ATV));
-               CL_cssmAtvToNss(cssmObj.AttributeTypeAndValue[atvDex],
-                       *nssObj.atvs[atvDex], coder);
-       }
-}
-
-/* CSSM_X509_NAME --> NSS_Name */
-void CL_cssmNameToNss(
-       const CSSM_X509_NAME    &cssmObj,
-       NSS_Name                                &nssObj,
-       SecNssCoder                             &coder)
-{
-       memset(&nssObj, 0, sizeof(nssObj));
-       
-       /* alloc NULL-terminated array of RDN pointers */
-       unsigned numRdns = cssmObj.numberOfRDNs;
-       nssObj.rdns = (NSS_RDN **)clNssNullArray(numRdns, coder);
-       
-       /* grind thru the elements */
-       for(unsigned rdnDex=0; rdnDex<numRdns; rdnDex++) {
-               nssObj.rdns[rdnDex] = (NSS_RDN *)coder.malloc(sizeof(NSS_RDN));
-               CL_cssmRdnToNss(cssmObj.RelativeDistinguishedName[rdnDex],
-                       *nssObj.rdns[rdnDex], coder);
-       }
-}
-
-#pragma mark ----- Name Normalization -----
-
-void CL_normalizeString(
-       char *strPtr,
-       int &strLen)                                    // IN/OUT
-{
-       char *pCh = strPtr;                             // working ptr
-       char *pD = pCh;                                 // start of good string chars
-       char *pEos = pCh + strLen - 1;
-       
-       if(strLen == 0) {
-               return;
-       }
-
-       /* adjust if Length included NULL terminator */
-       while(*pEos == 0) {
-               pEos--;
-       }
-       
-       /* Remove trailing spaces */
-       while(isspace(*pEos)) {
-               pEos--;
-       }
-       
-       /* Point to one past last non-space character */
-       pEos++;
-
-       /* upper case */
-       while(pCh < pEos) {
-               *pCh = toupper(*pCh);
-               pCh++;
-       }
-       
-       /* clean out whitespace */
-       /* 
-        * 1. skip all leading whitespace 
-        */
-       pCh = pD;
-       while(isspace(*pCh) && (pCh < pEos)) {
-               pCh++;
-       }
-       
-       /*
-        * 2. eliminate multiple whitespace.
-        *    pCh points to first non-white char.
-        *        pD still points to start of string
-        */
-       char ch;
-       while(pCh < pEos) {
-               ch = *pCh++;
-               *pD++ = ch;             // normal case
-               if( isspace(ch) ){
-                       /* skip 'til next nonwhite */
-                       while(isspace(*pCh) && (pCh < pEos)) {
-                               pCh++;
-                       }
-               }
-       };
-
-       strLen = (int)(pD - strPtr);
-}
-
-/* 
- * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case 
- * insensitive and we're supposed to ignore leading and trailing 
- * whitespace, and collapse multiple whitespace characters into one. 
- *
- * Incoming NSS_Name is assumed to be entirely within specifed coder's
- * address space; we'll be munging some of that and possibly replacing
- * some pointers with others allocated from the same space. 
- */
-void CL_normalizeX509NameNSS(
-       NSS_Name &nssName,
-       SecNssCoder &coder)
-{
-       unsigned numRdns = clNssArraySize((const void **)nssName.rdns);
-       if(numRdns == 0) {
-               /* not technically an error */
-               return;
-       }
-       
-       for(unsigned rdnDex=0; rdnDex<numRdns; rdnDex++) {
-               NSS_RDN *rdn = nssName.rdns[rdnDex];
-               assert(rdn != NULL);
-               unsigned numAttrs = clNssArraySize((const void **)rdn->atvs);
-               if(numAttrs == 0) {
-                       clFieldLog("clNormalizeX509Name: zero numAttrs at index %d", rdnDex);
-                       continue;
-               }
-               
-               /* descend into array of attribute/values */
-               for(unsigned attrDex=0; attrDex<numAttrs; attrDex++) {
-                       NSS_ATV *attr = rdn->atvs[attrDex];
-                       assert(attr != NULL);
-                       
-                       /* 
-                        * attr->value is an ASN_ANY containing an encoded
-                        * string. We only normalize Prinatable String types. 
-                        * If we find one, decode it, normalize it, encode the
-                        * result, and put the encoding back in attr->value.
-                        * We temporarily "leak" the original string, which only
-                        * has a lifetime of the incoming SecNssCoder. 
-                        */
-                       NSS_TaggedItem &attrVal = attr->value;
-                       if(attrVal.tag != SEC_ASN1_PRINTABLE_STRING) {
-                               /* skip it */
-                               continue;
-                       }
-
-                       /* normalize */
-                       char *strPtr = (char *)attrVal.item.Data;
-                       int newLen = (int)attrVal.item.Length;
-                       CL_normalizeString(strPtr, newLen);
-                       
-                       /* possible length adjustment */
-                       attrVal.item.Length = newLen;
-               }       /* for each attribute/value */
-       }               /* for each RDN */
-}
-
-#pragma mark ----- CE_GeneralNames <--> NSS_GeneralNames -----
-
-void CL_nssGeneralNameToCssm(
-       NSS_GeneralName &nssObj,
-       CE_GeneralName &cdsaObj,
-       SecNssCoder &coder,                             // for temp decoding
-       Allocator &alloc)                       // destination 
-{
-       memset(&cdsaObj, 0, sizeof(cdsaObj));
-       PRErrorCode prtn;
-
-       /* for caller's CE_GeneralName */
-       CSSM_BOOL berEncoded = CSSM_FALSE;
-       CE_GeneralNameType cdsaTag;
-       
-       /*
-        * At this point, depending on the decoded object's tag, we either
-        * have the final bytes to copy out, or we need to decode further.
-        * After this switch, if doCopy is true, give the caller a copy
-        * of nssObj.item.
-        */
-       bool doCopy = true;
-       switch(nssObj.tag) {
-               case NGT_OtherName:             // ASN_ANY -> CE_OtherName
-               {
-                       cdsaTag = GNT_OtherName;
-                       
-                       /* decode to coder memory */
-                       CE_OtherName *nssOther = 
-                               (CE_OtherName *)coder.malloc(sizeof(CE_OtherName));
-                       memset(nssOther, 0, sizeof(CE_OtherName));
-                       prtn = coder.decodeItem(nssObj.item, 
-                               kSecAsn1GenNameOtherNameTemplate, 
-                               nssOther);
-                       if(prtn) {
-                               clErrorLog("CL_nssGeneralNameToCssm: error decoding "
-                                               "OtherName\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }
-                       
-                       /* copy out to caller */
-                       clAllocData(alloc, cdsaObj.name, sizeof(CE_OtherName));
-                       clCopyOtherName(*nssOther, *((CE_OtherName *)cdsaObj.name.Data), 
-                               alloc);
-                       doCopy = false;
-                       break;
-               }
-               case NGT_RFC822Name:    // IA5String, done
-                       cdsaTag = GNT_RFC822Name;
-                       break;
-               case NGT_DNSName:               // IA5String
-                       cdsaTag = GNT_DNSName;
-                       break;
-               case NGT_X400Address:   // ASY_ANY, leave alone
-                       cdsaTag = GNT_X400Address;
-                       berEncoded = CSSM_TRUE;
-                       break;
-               case NGT_DirectoryName: // ASN_ANY --> NSS_Name
-               {
-                       cdsaTag = GNT_DirectoryName;
-                       
-                       /* Decode to coder memory */
-                       NSS_Name *nssName = (NSS_Name *)coder.malloc(sizeof(NSS_Name));
-                       memset(nssName, 0, sizeof(NSS_Name));
-                       prtn = coder.decodeItem(nssObj.item, kSecAsn1NameTemplate, nssName);
-                       if(prtn) {
-                               clErrorLog("CL_nssGeneralNameToCssm: error decoding "
-                                               "NSS_Name\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }
-                       
-                       /* convert & copy out to caller */
-                       clAllocData(alloc, cdsaObj.name, sizeof(CSSM_X509_NAME));
-                       CL_nssNameToCssm(*nssName, 
-                               *((CSSM_X509_NAME *)cdsaObj.name.Data), alloc);
-                       doCopy = false;
-                       break;
-               }
-               case NGT_EdiPartyName:  // ASN_ANY, leave alone
-                       cdsaTag = GNT_EdiPartyName;
-                       berEncoded = CSSM_TRUE;
-                       break;
-               case NGT_URI:                   // IA5String
-                       cdsaTag = GNT_URI;
-                       break;
-               case NGT_IPAddress:             // OCTET_STRING
-                       cdsaTag = GNT_IPAddress;
-                       break;
-               case NGT_RegisteredID:  // OID
-                       cdsaTag = GNT_RegisteredID;
-                       break;
-               default:
-                       clErrorLog("CL_nssGeneralNameToCssm: bad name tag\n");
-                       CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-       }       
-       
-       cdsaObj.nameType = cdsaTag;
-       cdsaObj.berEncoded = berEncoded;
-       if(doCopy) {
-               clAllocCopyData(alloc, nssObj.item, cdsaObj.name);
-       }
-}
-
-void CL_nssGeneralNamesToCssm(
-       const NSS_GeneralNames &nssObj,
-       CE_GeneralNames &cdsaObj,
-       SecNssCoder &coder,                             // for temp decoding
-       Allocator &alloc)                       // destination 
-{
-       memset(&cdsaObj, 0, sizeof(cdsaObj));
-       unsigned numNames = clNssArraySize((const void **)nssObj.names);
-       if(numNames == 0) {
-               return;
-       }
-       
-       /*
-        * Decode each name element, currently a raw ASN_ANY blob.
-        * Then convert each result into CDSA form.
-        * This array of (NSS_GeneralName)s is temporary, it doesn't
-        * persist outside of this routine other than the fact that it's
-        * mallocd by the coder arena pool. 
-        */
-       NSS_GeneralName *names = 
-               (NSS_GeneralName *)coder.malloc(sizeof(NSS_GeneralName) * numNames);
-       memset(names, 0, sizeof(NSS_GeneralName) * numNames);
-       cdsaObj.generalName = (CE_GeneralName *)alloc.malloc(
-               sizeof(CE_GeneralName) * numNames);
-       cdsaObj.numNames = numNames;
-       
-       for(unsigned dex=0; dex<numNames; dex++) {
-               if(coder.decodeItem(*nssObj.names[dex], kSecAsn1GeneralNameTemplate,
-                               &names[dex])) {
-                       clErrorLog("***CL_nssGeneralNamesToCssm: Error decoding "
-                               "General.name\n");
-                       CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-               }
-               
-               CL_nssGeneralNameToCssm(names[dex],
-                       cdsaObj.generalName[dex],
-                       coder, alloc);
-       }
-}
-
-void CL_cssmGeneralNameToNss(
-       CE_GeneralName &cdsaObj,
-       NSS_GeneralName &nssObj,                // actually an NSSTaggedItem
-       SecNssCoder &coder)                             // for temp decoding
-{
-       memset(&nssObj, 0, sizeof(nssObj));
-       
-       /*
-        * The default here is just to use the app-supplied data as is...
-        */
-       nssObj.item = cdsaObj.name;
-       unsigned char itemTag;                  // for nssObj.tag
-       bool doCopy = false;                    // unless we have to modify tag byte
-       unsigned char overrideTag;              // to force context-specific tag for
-                                                                       //   an ASN_ANY
-       PRErrorCode prtn;
-                                                                       
-       switch(cdsaObj.nameType) {
-               case GNT_OtherName:     
-                       /*
-                        * Caller supplies an CE_OtherName. Encode it.
-                        */
-                       if((cdsaObj.name.Length != sizeof(CE_OtherName)) ||
-                          (cdsaObj.name.Data == NULL)) {
-                               clErrorLog("CL_cssmGeneralNameToNss: OtherName.Length"
-                                       " error\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }
-                       prtn = coder.encodeItem(cdsaObj.name.Data,
-                               kSecAsn1OtherNameTemplate, nssObj.item);
-                       if(prtn) {
-                               clErrorLog("CL_cssmGeneralNameToNss: OtherName encode"
-                                       " error\n");
-                               CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
-                       }
-                       itemTag = NGT_OtherName;
-                       break;
-               case GNT_RFC822Name:            // IA5String
-                       itemTag = NGT_RFC822Name;
-                       break;
-               case GNT_DNSName:                       // IA5String
-                       itemTag = NGT_DNSName;
-                       break;
-               case GNT_X400Address:           // caller's resposibility
-                       /*
-                        * Encoded as ASN_ANY, the only thing we do is to 
-                        * force the correct context-specific tag
-                        */
-                       itemTag = GNT_X400Address;
-                       if(!cdsaObj.berEncoded) {
-                               clErrorLog("CL_cssmGeneralNameToNss: X400Address must"
-                                       " be BER-encoded\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }                       
-                       overrideTag = SEC_ASN1_CONTEXT_SPECIFIC | 
-                               SEC_ASN1_CONSTRUCTED | NGT_X400Address;
-                       doCopy = true;
-                       break;
-               case GNT_DirectoryName: 
-               {
-                       /*
-                        * Caller supplies an CSSM_X509_NAME. Convert to NSS
-                        * format and encode it.
-                        */
-                       if((cdsaObj.name.Length != sizeof(CSSM_X509_NAME)) || 
-                          (cdsaObj.name.Data == NULL)) {
-                               clErrorLog("CL_cssmGeneralNameToNss: DirectoryName.Length"
-                                       " error\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }
-                       NSS_Name nssName;
-                       CSSM_X509_NAME_PTR cdsaName = 
-                               (CSSM_X509_NAME_PTR)cdsaObj.name.Data;
-                       CL_cssmNameToNss(*cdsaName, nssName, coder);
-                       prtn = coder.encodeItem(&nssName,
-                               kSecAsn1NameTemplate, nssObj.item);
-                       if(prtn) {
-                               clErrorLog("CL_cssmGeneralNameToNss: X509Name encode"
-                                       " error\n");
-                               CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
-                       }
-                       itemTag = GNT_DirectoryName;
-                       
-                       /*
-                        * AND, munge the tag to make it a context-specific
-                        * sequence
-                        * no, not needed, this is wrapped in an explicit...
-                        */
-                       //nssObj.item.Data[0] = SEC_ASN1_CONTEXT_SPECIFIC | 
-                       //      SEC_ASN1_CONSTRUCTED | GNT_DirectoryName;
-
-                       break;
-               }
-               case GNT_EdiPartyName:          // caller's resposibility
-                       /*
-                        * Encoded as ASN_ANY, the only thing we do is to 
-                        * force the correct context-specific tag
-                        */
-                       itemTag = GNT_EdiPartyName;
-                       if(!cdsaObj.berEncoded) {
-                               clErrorLog("CL_cssmGeneralNameToNss: EdiPartyName must"
-                                       " be BER-encoded\n");
-                               CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT);
-                       }
-                       overrideTag = SEC_ASN1_CONTEXT_SPECIFIC |  NGT_X400Address;
-                       doCopy = true;
-                       break;
-               case GNT_URI:                           // IA5String
-                       itemTag = GNT_URI;
-                       break;
-               case GNT_IPAddress:                     // OCTET_STRING
-                       itemTag = NGT_IPAddress;
-                       break;
-               case GNT_RegisteredID:          // OID
-                       itemTag = NGT_RegisteredID;
-                       break;
-               default:
-                       clErrorLog("CL_cssmGeneralNameToNss: bad name tag\n");
-                       CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG);
-       }
-       if(doCopy) {
-               coder.allocCopyItem(cdsaObj.name, nssObj.item);
-               nssObj.item.Data[0] = overrideTag;
-       }
-       nssObj.tag = itemTag;
-}
-
-void CL_cssmGeneralNamesToNss(
-       const CE_GeneralNames &cdsaObj, 
-       NSS_GeneralNames &nssObj,
-       SecNssCoder &coder)
-{
-       uint32 numNames = cdsaObj.numNames;
-       nssObj.names = (CSSM_DATA **)clNssNullArray(numNames, coder);
-       
-       /* 
-        * Convert each element in cdsaObj to NSS form, encode, drop into
-        * the ASN_ANY array.
-        *
-        * This array of (NSS_GeneralName)s is temporary, it doesn't
-        * persist outside of this routine other than the fact that it's
-        * mallocd by the coder arena pool. 
-        */
-       NSS_GeneralName *names = 
-               (NSS_GeneralName *)coder.malloc(sizeof(NSS_GeneralName) * numNames);
-       memset(names, 0, sizeof(NSS_GeneralName) * numNames);
-       for(unsigned dex=0; dex<cdsaObj.numNames; dex++) {
-               nssObj.names[dex] = (CSSM_DATA_PTR)coder.malloc(sizeof(CSSM_DATA));
-               memset(nssObj.names[dex], 0, sizeof(CSSM_DATA));
-               CL_cssmGeneralNameToNss(cdsaObj.generalName[dex],
-                       names[dex], coder);
-               if(coder.encodeItem(&names[dex], kSecAsn1GeneralNameTemplate,
-                               *nssObj.names[dex])) {
-                       clErrorLog("***Error encoding General.name\n");
-                       CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
-               }
-       }
-}
-
-/* Copy a CE_OtherName */
-void clCopyOtherName(
-       const CE_OtherName &src,
-       CE_OtherName &dst,
-       Allocator &alloc)
-{
-       clAllocCopyData(alloc, src.typeId, dst.typeId);
-       clAllocCopyData(alloc, src.value, dst.value);
-}
-
-#pragma mark ----- Name-related Free -----
-
-void CL_freeAuthorityKeyId(
-       CE_AuthorityKeyID                               &cdsaObj,
-       Allocator                                       &alloc)
-{
-       alloc.free(cdsaObj.keyIdentifier.Data);
-       CL_freeCssmGeneralNames(cdsaObj.generalNames, alloc);
-       alloc.free(cdsaObj.generalNames);
-       alloc.free(cdsaObj.serialNumber.Data);
-       memset(&cdsaObj, 0, sizeof(CE_AuthorityKeyID));
-}
-
-void CL_freeCssmGeneralName(
-       CE_GeneralName          &genName,
-       Allocator                       &alloc)
-{
-       switch(genName.nameType) {
-               /* 
-                * Two special cases here.
-                */
-               case GNT_DirectoryName:
-                       if((!genName.berEncoded) &&                                     // we're flexible
-                                       (genName.name.Length == 
-                                               sizeof(CSSM_X509_NAME))) {              // paranoia
-                               CL_freeX509Name((CSSM_X509_NAME_PTR)genName.name.Data, alloc);
-                       }
-                       break;
-                       
-               case GNT_OtherName:
-                       if((!genName.berEncoded) &&                                     // we're flexible
-                                       (genName.name.Length == 
-                                               sizeof(CE_OtherName))) {                // paranoia
-                               CE_OtherName *con = (CE_OtherName *)genName.name.Data;
-                               CL_freeOtherName(con, alloc);
-                       }
-                       break;
-               default:
-                       break;
-       }
-       /* and always free this */
-       alloc.free(genName.name.Data);
-}
-
-void CL_freeCssmGeneralNames(
-       CE_GeneralNames                 *cdsaObj,
-       Allocator                               &alloc)
-{
-       if(cdsaObj == NULL) {
-               return;
-       }
-       for(unsigned i=0; i<cdsaObj->numNames; i++) {
-               CL_freeCssmGeneralName(cdsaObj->generalName[i], alloc);
-       }
-       if(cdsaObj->numNames) {
-               memset(cdsaObj->generalName, 0, cdsaObj->numNames * sizeof(CE_GeneralName));
-               alloc.free(cdsaObj->generalName);
-       }
-       memset(cdsaObj, 0, sizeof(CE_GeneralNames));
-}
-
-void CL_freeCssmDistPointName(
-       CE_DistributionPointName        *cssmDpn,
-       Allocator                               &alloc)
-{
-       if(cssmDpn == NULL) {
-               return;
-       }
-       switch(cssmDpn->nameType) {
-               case CE_CDNT_FullName:
-                       CL_freeCssmGeneralNames(cssmDpn->dpn.fullName, alloc);
-                       alloc.free(cssmDpn->dpn.fullName);
-                       break;
-               case CE_CDNT_NameRelativeToCrlIssuer:
-                       CL_freeX509Rdn(cssmDpn->dpn.rdn, alloc);
-                       alloc.free(cssmDpn->dpn.rdn);
-                       break;
-       }
-       memset(cssmDpn, 0, sizeof(*cssmDpn));
-}
-
-void CL_freeCssmDistPoints(
-       CE_CRLDistPointsSyntax  *cssmDps,
-       Allocator                       &alloc)
-{
-       if(cssmDps == NULL) {
-               return;
-       }
-       for(unsigned dex=0; dex<cssmDps->numDistPoints; dex++) {
-               CE_CRLDistributionPoint *cssmDp = &cssmDps->distPoints[dex];
-               if(cssmDp->distPointName) {
-                       CL_freeCssmDistPointName(cssmDp->distPointName, alloc);
-                       alloc.free(cssmDp->distPointName);
-               }
-               if(cssmDp->crlIssuer) {
-                       CL_freeCssmGeneralNames(cssmDp->crlIssuer, alloc);
-                       alloc.free(cssmDp->crlIssuer);
-               }
-       }
-       memset(cssmDps->distPoints, 0, 
-               cssmDps->numDistPoints * sizeof(CE_CRLDistributionPoint));
-       alloc.free(cssmDps->distPoints);
-       memset(cssmDps, 0, sizeof(*cssmDps));
-}
-
-/* free contents of an CSSM_X509_NAME */
-void CL_freeX509Name(
-       CSSM_X509_NAME_PTR      x509Name,
-       Allocator               &alloc)
-{
-       if(x509Name == NULL) {
-               return;
-       }
-       for(unsigned rdnDex=0; rdnDex<x509Name->numberOfRDNs; rdnDex++) {
-               CSSM_X509_RDN_PTR rdn = &x509Name->RelativeDistinguishedName[rdnDex];
-               CL_freeX509Rdn(rdn, alloc);
-       }
-       alloc.free(x509Name->RelativeDistinguishedName);
-       memset(x509Name, 0, sizeof(CSSM_X509_NAME));
-}
-
-void CL_freeX509Rdn(
-       CSSM_X509_RDN_PTR       rdn,
-       Allocator               &alloc)
-{
-       if(rdn == NULL) {
-               return;
-       }
-       for(unsigned atvDex=0; atvDex<rdn->numberOfPairs; atvDex++) {
-               CSSM_X509_TYPE_VALUE_PAIR_PTR atv = 
-                       &rdn->AttributeTypeAndValue[atvDex];
-               alloc.free(atv->type.Data);
-               alloc.free(atv->value.Data);
-               memset(atv, 0, sizeof(CSSM_X509_TYPE_VALUE_PAIR));
-       }
-       alloc.free(rdn->AttributeTypeAndValue);
-       memset(rdn, 0, sizeof(CSSM_X509_RDN));
-}
-
-void CL_freeOtherName(
-       CE_OtherName            *cssmOther,
-       Allocator               &alloc)
-{
-       if(cssmOther == NULL) {
-               return;
-       }
-       alloc.free(cssmOther->typeId.Data);
-       alloc.free(cssmOther->value.Data);
-       memset(cssmOther, 0, sizeof(*cssmOther));
-}
-
-void CL_freeCssmIssuingDistPoint(
-       CE_IssuingDistributionPoint     *cssmIdp,
-       Allocator                               &alloc)
-{
-       CL_freeCssmDistPointName(cssmIdp->distPointName, alloc);
-}
-