2 * Copyright (c) 2000-2001 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.
20 * CrlFields.cpp - convert between NSS-based NSS_Crl components and CDSA-style
21 * fields. A major component of DecodedCrl.
23 * Created 8/29/2002 by Doug Mitchell.
24 * Copyright (c) 2002 by Apple Computer.
27 #include "DecodedCrl.h"
28 #include <Security/debugging.h>
29 #include "cldebugging.h"
30 #include "CLCrlExtensions.h"
31 #include "CLCertExtensions.h"
32 #include "CLFieldsCommon.h"
33 #include "clNssUtils.h"
34 #include "clNameUtils.h"
35 #include <Security/utilities.h>
36 #include <Security/oidscrl.h>
37 #include <Security/oidscert.h>
38 #include <Security/cssmerr.h>
39 #include <Security/x509defs.h>
41 static void CL_freeCssmExtensions(
42 CSSM_X509_EXTENSIONS
&extens
,
43 CssmAllocator
&alloc
);
47 *** Format = DER-encoded int (max of four bytes in this case)
49 static bool getField_Version (
51 unsigned index
, // which occurrence (0 = first)
52 uint32
&numFields
, // RETURNED
53 CssmOwnedData
&fieldValue
) // RETURNED
55 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
56 const CSSM_DATA
&vers
= crl
.mCrl
.tbs
.version
;
57 if(!tbsGetCheck(vers
.Data
, index
)) {
58 /* not present, optional */
61 fieldValue
.copy(vers
.Data
, vers
.Length
);
66 static void setField_Version (
68 const CssmData
&fieldValue
)
70 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
71 CSSM_DATA
&vers
= crl
.mCrl
.tbs
.version
;
72 tbsSetCheck(vers
.Data
, fieldValue
, 0, "version");
73 crl
.coder().allocCopyItem(fieldValue
, vers
);
77 *** Format = CSSM_X509_NAME
78 *** class Name from sm_x501if
80 static bool getField_Issuer (
82 unsigned index
, // which occurrence (0 = first)
83 uint32
&numFields
, // RETURNED
84 CssmOwnedData
&fieldValue
) // RETURNED
92 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
94 brtn
= getField_RDN_NSS(crl
.mCrl
.tbs
.issuer
, fieldValue
);
100 freeField_RDN(fieldValue
);
106 static void setField_Issuer (
108 const CssmData
&fieldValue
)
110 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
111 const CSSM_X509_NAME
*cssmName
= (const CSSM_X509_NAME
*)fieldValue
.Data
;
112 NSS_Name
&nssName
= crl
.mCrl
.tbs
.issuer
;
113 tbsSetCheck(nssName
.rdns
, fieldValue
, sizeof(CSSM_X509_NAME
),
115 CL_cssmNameToNss(*cssmName
, nssName
, crl
.coder());
120 *** Format: CSSM_X509_TIME
122 static bool getField_ThisUpdate (
124 unsigned index
, // which occurrence (0 = first)
125 uint32
&numFields
, // RETURNED
126 CssmOwnedData
&fieldValue
) // RETURNED
128 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
129 const NSS_Time
&srcTime
= crl
.mCrl
.tbs
.thisUpdate
;
130 return getField_TimeNSS(srcTime
, index
, numFields
, fieldValue
);
133 static void setField_ThisUpdate (
135 const CssmData
&fieldValue
)
137 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
138 NSS_Time
&dstTime
= crl
.mCrl
.tbs
.thisUpdate
;
139 tbsSetCheck(dstTime
.item
.Data
, fieldValue
,
140 sizeof(CSSM_X509_TIME
), "NotBefore");
141 setField_TimeNSS(fieldValue
, dstTime
, crl
.coder());
144 static bool getField_NextUpdate (
146 unsigned index
, // which occurrence (0 = first)
147 uint32
&numFields
, // RETURNED
148 CssmOwnedData
&fieldValue
) // RETURNED
150 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
151 const NSS_Time
&srcTime
= crl
.mCrl
.tbs
.nextUpdate
;
152 return getField_TimeNSS(srcTime
, index
, numFields
, fieldValue
);
155 static void setField_NextUpdate (
157 const CssmData
&fieldValue
)
159 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
160 NSS_Time
&dstTime
= crl
.mCrl
.tbs
.nextUpdate
;
161 tbsSetCheck(dstTime
.item
.Data
, fieldValue
,
162 sizeof(CSSM_X509_TIME
), "NotBefore");
163 setField_TimeNSS(fieldValue
, dstTime
, crl
.coder());
167 *** Issuer Name (normalized and encoded version)
168 *** Format = CSSM_DATA containing the DER encoding of the normalized name
170 static bool getFieldIssuerNorm(
172 unsigned index
, // which occurrence (0 = first)
173 uint32
&numFields
, // RETURNED
174 CssmOwnedData
&fieldValue
) // RETURNED
179 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
180 return getField_normRDN_NSS(crl
.mCrl
.tbs
.derIssuer
, numFields
,
186 *** Format = CSSM_X509_ALGORITHM_IDENTIFIER
188 static bool getField_CrlTbsAlgId (
190 unsigned index
, // which occurrence (0 = first)
191 uint32
&numFields
, // RETURNED
192 CssmOwnedData
&fieldValue
) // RETURNED
194 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
195 const CSSM_X509_ALGORITHM_IDENTIFIER
&srcAlgId
=
196 crl
.mCrl
.signatureAlgorithm
;
197 if(!tbsGetCheck(srcAlgId
.algorithm
.Data
, index
)) {
200 getField_AlgIdNSS(srcAlgId
, fieldValue
);
206 * Support for entries in revocation list
208 static void nssRevokedEntryToCssm(
209 NSS_RevokedCert
&nssEntry
,
210 CSSM_X509_REVOKED_CERT_ENTRY
&cssmEntry
,
211 CssmAllocator
&alloc
)
213 clAllocCopyData(alloc
, nssEntry
.userCertificate
, cssmEntry
.certificateSerialNumber
);
214 CL_nssTimeToCssm(nssEntry
.revocationDate
, cssmEntry
.revocationDate
, alloc
);
216 /* CSSM_X509_EXTENSIONS extensions */
217 NSS_CertExtension
**nssExtens
= nssEntry
.extensions
;
218 if(nssExtens
== NULL
) {
224 * First we have to decode the NSS-style Extensions into a
225 * DecodedExtensions object. For cert- and CRL-wide extensions, this
226 * is done at the construction of Decoded{Cert,Crl}. However for
227 * per-CRL-entry entensions, this is (currently) the only place
228 * this decoding is done.
231 DecodedExtensions
decodedExtens(coder
, alloc
);
232 decodedExtens
.decodeFromNss(nssExtens
);
234 /* convert to CDSA style */
235 decodedExtens
.convertToCdsa(cssmEntry
.extensions
, alloc
);
238 static void freeCssmEntry(
239 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
,
240 CssmAllocator
&alloc
)
242 if(cssmEntry
== NULL
) {
245 if(cssmEntry
->certificateSerialNumber
.Data
) {
246 alloc
.free(cssmEntry
->certificateSerialNumber
.Data
);
247 cssmEntry
->certificateSerialNumber
.Data
= NULL
;
248 cssmEntry
->certificateSerialNumber
.Length
= 0;
250 CL_freeCssmTime(&cssmEntry
->revocationDate
, alloc
);
252 /* CSSM_X509_EXTENSIONS extensions */
253 CL_freeCssmExtensions(cssmEntry
->extensions
, alloc
);
255 memset(cssmEntry
, 0, sizeof(CSSM_X509_REVOKED_CERT_ENTRY
));
258 static void nssRevokedListToCssm(
259 NSS_RevokedCert
**nssList
, // may be NULL
260 CSSM_X509_REVOKED_CERT_LIST_PTR cssmList
,
261 CssmAllocator
&alloc
)
263 unsigned numEntries
= clNssArraySize((const void **)nssList
);
264 cssmList
->numberOfRevokedCertEntries
= numEntries
;
265 if(numEntries
== 0) {
266 cssmList
->revokedCertEntry
= NULL
;
269 cssmList
->revokedCertEntry
= (CSSM_X509_REVOKED_CERT_ENTRY_PTR
)alloc
.malloc(
270 sizeof(CSSM_X509_REVOKED_CERT_ENTRY
) * numEntries
);
271 memset(cssmList
->revokedCertEntry
, 0,
272 sizeof(CSSM_X509_REVOKED_CERT_ENTRY
) * numEntries
);
273 for(unsigned dex
=0; dex
<numEntries
; dex
++) {
274 NSS_RevokedCert
*nssEntry
= nssList
[dex
];
275 assert(nssEntry
!= NULL
);
276 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
=
277 &cssmList
->revokedCertEntry
[dex
];
278 nssRevokedEntryToCssm(*nssEntry
, *cssmEntry
, alloc
);
283 static void freeCssmRevokedList(
284 CSSM_X509_REVOKED_CERT_LIST_PTR cssmList
,
285 CssmAllocator
&alloc
)
287 if(cssmList
== NULL
) {
290 for(unsigned dex
=0; dex
<cssmList
->numberOfRevokedCertEntries
; dex
++) {
291 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
=
292 &cssmList
->revokedCertEntry
[dex
];
293 freeCssmEntry(cssmEntry
, alloc
);
295 if(cssmList
->revokedCertEntry
) {
296 alloc
.free(cssmList
->revokedCertEntry
);
298 memset(cssmList
, 0, sizeof(CSSM_X509_REVOKED_CERT_LIST
));
303 *** Format: CSSM_X509_SIGNED_CRL (the whole enchilada, parsed)
305 static bool getField_SignedCrl (
307 unsigned index
, // which occurrence (0 = first)
308 uint32
&numFields
, // RETURNED
309 CssmOwnedData
&fieldValue
) // RETURNED
311 CssmAllocator
&alloc
= fieldValue
.allocator
;
313 const DecodedCrl
&nssCrl
= dynamic_cast<const DecodedCrl
&>(item
);
314 const NSS_TBSCrl
&nssTbs
= nssCrl
.mCrl
.tbs
;
315 fieldValue
.malloc(sizeof(CSSM_X509_SIGNED_CRL
));
316 CSSM_X509_SIGNED_CRL
&cssmCrl
= *((CSSM_X509_SIGNED_CRL
*)fieldValue
.data());
318 memset(&cssmCrl
, 0, sizeof(CSSM_X509_SIGNED_CRL
));
319 CSSM_X509_TBS_CERTLIST
&cssmTbs
= cssmCrl
.tbsCertList
;
322 clAllocCopyData(alloc
, nssTbs
.version
, cssmTbs
.version
);
324 /* CSSM_X509_ALGORITHM_IDENTIFIER signature - in TBS and CRL */
325 CL_copyAlgId(nssTbs
.signature
, cssmTbs
.signature
, alloc
);
326 CL_copyAlgId(nssCrl
.mCrl
.signatureAlgorithm
,
327 cssmCrl
.signature
.algorithmIdentifier
, alloc
);
329 /* CSSM_X509_NAME issuer */
330 CL_nssNameToCssm(nssTbs
.issuer
, cssmTbs
.issuer
, alloc
);
332 /* CSSM_X509_TIME thisUpdate, nextUpdate */
333 CL_nssTimeToCssm(nssTbs
.thisUpdate
, cssmTbs
.thisUpdate
, alloc
);
334 CL_nssTimeToCssm(nssTbs
.nextUpdate
, cssmTbs
.nextUpdate
, alloc
);
336 /* CSSM_X509_REVOKED_CERT_LIST_PTR revokedCertificates */
337 if(nssTbs
.revokedCerts
!= NULL
) {
338 cssmTbs
.revokedCertificates
= (CSSM_X509_REVOKED_CERT_LIST_PTR
)
339 alloc
.malloc(sizeof(CSSM_X509_REVOKED_CERT_LIST
));
340 memset(cssmTbs
.revokedCertificates
, 0, sizeof(CSSM_X509_REVOKED_CERT_LIST
));
341 nssRevokedListToCssm(nssTbs
.revokedCerts
,
342 cssmTbs
.revokedCertificates
, alloc
);
345 /* CSSM_X509_EXTENSIONS extensions */
346 const DecodedExtensions
&decodedExtens
= nssCrl
.decodedExtens();
347 decodedExtens
.convertToCdsa(cssmTbs
.extensions
, alloc
);
349 /* raw signature - stored in bits - note signature.algId set above */
350 CSSM_DATA nssSig
= nssCrl
.mCrl
.signature
;
351 nssSig
.Length
= (nssSig
.Length
+ 7) / 8;
352 clAllocCopyData(alloc
, nssSig
, cssmCrl
.signature
.encrypted
);
357 static void setField_SignedCrl (
359 const CssmData
&fieldValue
)
361 /* TBD - writing CRLs not supported now */
362 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
);
365 void freeField_SignedCrl (
366 CssmOwnedData
&fieldValue
)
368 CSSM_X509_SIGNED_CRL
*cssmCrl
=
369 (CSSM_X509_SIGNED_CRL
*)fieldValue
.data();
371 if(cssmCrl
== NULL
) {
374 if(fieldValue
.length() != sizeof(CSSM_X509_SIGNED_CRL
)) {
375 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
377 CssmAllocator
&alloc
= fieldValue
.allocator
;
378 CSSM_X509_TBS_CERTLIST_PTR cssmTbs
= &cssmCrl
->tbsCertList
;
379 if(cssmTbs
== NULL
) {
380 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
383 /* run down the fields */
384 if(cssmTbs
->version
.Data
) {
385 alloc
.free(cssmTbs
->version
.Data
);
388 /* CSSM_X509_ALGORITHM_IDENTIFIER signature - in TBS and CRL */
389 CL_freeCssmAlgId(&cssmTbs
->signature
, alloc
);
390 CL_freeCssmAlgId(&cssmCrl
->signature
.algorithmIdentifier
, alloc
);
392 /* issuer, thisUpdate, nextUpdate */
393 CL_freeX509Name(&cssmTbs
->issuer
, alloc
);
394 CL_freeCssmTime(&cssmTbs
->thisUpdate
, alloc
);
395 CL_freeCssmTime(&cssmTbs
->nextUpdate
, alloc
);
397 /* CSSM_X509_REVOKED_CERT_LIST_PTR revokedCertificates */
398 freeCssmRevokedList(cssmTbs
->revokedCertificates
, alloc
);
399 alloc
.free(cssmTbs
->revokedCertificates
);
401 /* CSSM_X509_EXTENSIONS extensions */
402 CL_freeCssmExtensions(cssmTbs
->extensions
, alloc
);
404 /* raw signature - note signature.algId freed above */
405 alloc
.free(cssmCrl
->signature
.encrypted
.Data
);
407 memset(cssmCrl
, 0, sizeof(CSSM_X509_SIGNED_CRL
));
411 * Table to map OID to {get,set,free}field
414 const CSSM_OID
*fieldId
;
415 getItemFieldFcn
*getFcn
;
416 setItemFieldFcn
*setFcn
;
417 freeFieldFcn
*freeFcn
; // OPTIONAL - NULL means just free the
422 static const oidToFieldFuncs crlFieldTable
[] = {
423 /* this first one, which returns everything in a parsed format,
424 * is intended to be normally the only field used */
425 { &CSSMOID_X509V2CRLSignedCrlCStruct
,
426 &getField_SignedCrl
, &setField_SignedCrl
, &freeField_SignedCrl
},
427 { &CSSMOID_X509V2CRLVersion
,
428 &getField_Version
, &setField_Version
, NULL
},
429 { &CSSMOID_X509V1CRLIssuerNameCStruct
,
430 &getField_Issuer
, &setField_Issuer
, &freeField_RDN
},
431 { &CSSMOID_X509V1CRLThisUpdate
,
432 &getField_ThisUpdate
, &setField_ThisUpdate
, &freeField_Time
},
433 { &CSSMOID_X509V1CRLNextUpdate
,
434 &getField_NextUpdate
, &setField_NextUpdate
, &freeField_Time
},
435 { &CSSMOID_X509V1IssuerName
,
436 getFieldIssuerNorm
, &setField_ReadOnly
, NULL
},
437 { &CSSMOID_X509V1SignatureAlgorithmTBS
,
438 &getField_CrlTbsAlgId
, &setField_ReadOnly
, &freeField_AlgId
},
441 * Extensions, implemented in CrlExtensions.cpp
442 * When adding new ones, also add to:
443 * -- clOidToNssInfo() in CLFieldsCommon.cpp
444 * -- get/set/free functions in CrlExtensions.{cpp,h}
445 * -- DecodedExten::parse in DecodedExtensions.cpp
447 { &CSSMOID_CrlNumber
,
448 &getFieldCrlNumber
, &setFieldCrlNumber
, freeFieldSimpleExtension
},
449 { &CSSMOID_DeltaCrlIndicator
,
450 &getFieldDeltaCrl
, &setFieldCrlNumber
, freeFieldSimpleExtension
},
451 { &CSSMOID_CertIssuer
, // get/set not implemented
452 &getField_Unimplemented
, &setField_ReadOnly
,
453 &freeFieldSubjIssuerAltName
},
454 { &CSSMOID_CrlReason
, // get/set not implemented
455 &getField_Unimplemented
, &setField_ReadOnly
,
456 freeFieldSimpleExtension
},
457 { &CSSMOID_IssuingDistributionPoint
, // get/set not implemented
458 &getField_Unimplemented
, &setField_ReadOnly
,
459 &freeFieldIssuingDistPoint
},
460 { &CSSMOID_HoldInstructionCode
, // get/set not implemented
461 &getField_Unimplemented
, &setField_ReadOnly
,
462 &freeFieldOidOrData
},
463 { &CSSMOID_InvalidityDate
, // get/set not implemented
464 &getField_Unimplemented
, &setField_ReadOnly
,
465 &freeFieldOidOrData
},
467 /* in common with CertExtensions */
468 { &CSSMOID_AuthorityKeyIdentifier
, &getFieldAuthorityKeyId
,
469 &setFieldAuthorityKeyId
, &freeFieldAuthorityKeyId
} ,
470 { &CSSMOID_X509V3CertificateExtensionCStruct
, &getFieldUnknownExt
,
471 &setFieldUnknownExt
, &freeFieldUnknownExt
},
472 { &CSSMOID_SubjectAltName
, &getFieldSubjAltName
,
473 &setFieldSubjIssuerAltName
, &freeFieldSubjIssuerAltName
} ,
474 { &CSSMOID_IssuerAltName
, &getFieldIssuerAltName
,
475 &setFieldSubjIssuerAltName
, &freeFieldSubjIssuerAltName
} ,
479 #define NUM_KNOWN_FIELDS (sizeof(crlFieldTable) / sizeof(oidToFieldFuncs))
480 #define NUM_STD_CRL_FIELDS 2 /* TBD not including extensions */
482 /* map an OID to an oidToFieldFuncs */
483 static const oidToFieldFuncs
*oidToFields(
484 const CssmOid
&fieldId
)
486 const oidToFieldFuncs
*fieldTable
= crlFieldTable
;
487 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
488 if(fieldId
== CssmData::overlay(*fieldTable
->fieldId
)) {
493 CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG
);
497 * Common routine to free OID-specific field data. Used in the
498 * public DecodedCrl::freeCrlFieldData and when freeing
499 * extensions in a CSSM_X509_TBS_CERTLIST.
501 static void CL_freeCrlFieldData(
502 const CssmOid
&fieldId
,
503 CssmOwnedData
&fieldValue
,
506 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
507 CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER
);
509 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
510 if(fieldFuncs
->freeFcn
!= NULL
) {
511 /* optional - simple cases handled below */
512 fieldFuncs
->freeFcn(fieldValue
);
516 fieldValue
.release();
521 * Common routime to free a CSSM_X509_EXTENSIONS. Used to free
522 * CSSM_X509_TBS_CERTLIST.extensions and
523 * CSSM_X509_REVOKED_CERT_ENTRY.extensions.
524 * We just cook up a CssmOid and a CssmOwnedData for each extension
525 * and pass to CL_freeCrlFieldData().
527 static void CL_freeCssmExtensions(
528 CSSM_X509_EXTENSIONS
&extens
,
529 CssmAllocator
&alloc
)
531 for(uint32 dex
=0; dex
<extens
.numberOfExtensions
; dex
++) {
532 CSSM_X509_EXTENSION_PTR exten
= &extens
.extensions
[dex
];
533 const CSSM_OID
*fieldOid
;
536 * The field OID is either the same as the extension's OID (if we parsed
537 * it) or CSSMOID_X509V3CertificateExtensionCStruct (if we didn't).
539 switch(exten
->format
) {
540 case CSSM_X509_DATAFORMAT_ENCODED
:
541 fieldOid
= &CSSMOID_X509V3CertificateExtensionCStruct
;
543 case CSSM_X509_DATAFORMAT_PARSED
:
544 case CSSM_X509_DATAFORMAT_PAIR
:
545 fieldOid
= &exten
->extnId
;
548 clErrorLog("CL_freeCssmExtensions: bad exten->format (%d)",
550 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
553 const CssmOid
&fieldId
= CssmOid::overlay(*fieldOid
);
554 CssmData
cData((uint8
*)exten
, sizeof(CSSM_X509_EXTENSION
));
555 CssmRemoteData
fieldValue(alloc
, cData
);
556 CL_freeCrlFieldData(fieldId
, fieldValue
, false);
557 fieldValue
.release(); // but no free (via reset() */
559 alloc
.free(extens
.extensions
);
560 memset(&extens
, 0, sizeof(CSSM_X509_EXTENSIONS
));
570 * Obtain the index'th occurrence of field specified by fieldId in specified cert.
571 * Format of the returned field depends on fieldId.
572 * Returns total number of fieldId fields in the cert if index is 0.
573 * FieldValue assumed to be empty on entry.
574 * Returns true if specified field was found, else returns false.
576 bool DecodedCrl::getCrlFieldData(
577 const CssmOid
&fieldId
, // which field
578 unsigned index
, // which occurrence (0 = first)
579 uint32
&numFields
, // RETURNED
580 CssmOwnedData
&fieldValue
) // RETURNED
585 clErrorLog("DecodedCrl::getCrlField: can't parse undecoded CRL!");
586 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
591 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
592 return fieldFuncs
->getFcn(*this, index
, numFields
, fieldValue
);
596 * Set the field specified by fieldId in the specified Cert.
597 * Note no index - individual field routines either append (for extensions)
598 * or if field already set ::throwMe(for all others)
600 void DecodedCrl::setCrlField(
601 const CssmOid
&fieldId
, // which field
602 const CssmData
&fieldValue
)
605 case IS_Empty
: // first time thru
606 mState
= IS_Building
;
608 case IS_Building
: // subsequent passes
612 clErrorLog("DecodedCrl::setCrlField: can't build on a decoded CRL!");
613 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
615 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
616 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
618 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
619 const CssmData
&value
= CssmData::overlay(fieldValue
);
620 fieldFuncs
->setFcn(*this, value
);
624 * Free the fieldId-specific data referred to by fieldValue->Data.
625 * No state from DecodedCrl needed; use the routine shared with
626 * CL_freeCssmExtensions().
628 void DecodedCrl::freeCrlFieldData(
629 const CssmOid
&fieldId
,
630 CssmOwnedData
&fieldValue
)
632 CL_freeCrlFieldData(fieldId
, fieldValue
);
637 * Common means to get all fields from a decoded CRL. Used in
638 * CrlGetAllTemplateFields and CrlGetAllFields.
640 void DecodedCrl::getAllParsedCrlFields(
641 uint32
&NumberOfFields
, // RETURNED
642 CSSM_FIELD_PTR
&CrlFields
) // RETURNED
644 /* this is the max - some might be missing */
645 uint32 maxFields
= NUM_STD_CRL_FIELDS
+ mDecodedExtensions
.numExtensions();
646 CSSM_FIELD_PTR outFields
= (CSSM_FIELD_PTR
)mAlloc
.malloc(
647 maxFields
* sizeof(CSSM_FIELD
));
650 * We'll be copying oids and values for fields we find into
651 * outFields; current number of valid fields found in numOutFields.
653 memset(outFields
, 0, maxFields
* sizeof(CSSM_FIELD
));
654 uint32 numOutFields
= 0;
655 CSSM_FIELD_PTR currOutField
;
657 const CSSM_OID
*currOid
;
658 CssmAutoData
aData(mAlloc
); // for malloc/copy of outgoing data
660 /* query for each OID we know about */
661 for(currOidDex
=0; currOidDex
<NUM_KNOWN_FIELDS
; currOidDex
++) {
662 const oidToFieldFuncs
*fieldFuncs
= &crlFieldTable
[currOidDex
];
663 currOid
= fieldFuncs
->fieldId
;
664 uint32 numFields
; // for THIS oid
667 * Return false if field not there, which is not an error here.
668 * Actual exceptions are fatal.
670 if(!fieldFuncs
->getFcn(*this,
671 0, // index - looking for first one
677 /* got some data for this oid - copy it and oid to outgoing CrlFields */
678 assert(numOutFields
< maxFields
);
679 currOutField
= &outFields
[numOutFields
];
680 currOutField
->FieldValue
= aData
.release();
681 aData
.copy(*currOid
);
682 currOutField
->FieldOid
= aData
.release();
685 /* if more fields are available for this OID, snag them too */
686 for(uint32 fieldDex
=1; fieldDex
<numFields
; fieldDex
++) {
687 /* note this should always succeed */
688 bool brtn
= fieldFuncs
->getFcn(*this,
690 numFields
, // shouldn't change
693 clErrorLog("getAllParsedCrlFields: index screwup");
694 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
696 assert(numOutFields
< maxFields
);
697 currOutField
= &outFields
[numOutFields
];
698 currOutField
->FieldValue
= aData
.release();
699 aData
.copy(*currOid
);
700 currOutField
->FieldOid
= aData
.release();
702 } /* multiple fields for currOid */
703 } /* for each known OID */
705 NumberOfFields
= numOutFields
;
706 CrlFields
= outFields
;
710 DecodedCrl::describeFormat(
711 CssmAllocator
&alloc
,
712 uint32
&NumberOfFields
,
713 CSSM_OID_PTR
&OidList
)
715 /* malloc in app's space, do deep copy (including ->Data) */
716 CSSM_OID_PTR oidList
= (CSSM_OID_PTR
)alloc
.malloc(
717 NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
718 memset(oidList
, 0, NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
719 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
720 CssmAutoData
oidCopy(alloc
, *crlFieldTable
[i
].fieldId
);
721 oidList
[i
] = oidCopy
.release();
723 NumberOfFields
= NUM_KNOWN_FIELDS
;