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_utilities/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/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
,
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
,
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
,
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
,
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
,
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 Allocator
&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 Allocator
&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
} ,
477 { &CSSMOID_CrlDistributionPoints
, // get/set not implemented
478 &getField_Unimplemented
, &setField_ReadOnly
,
479 &freeFieldCrlDistributionPoints
},
483 #define NUM_KNOWN_FIELDS (sizeof(crlFieldTable) / sizeof(oidToFieldFuncs))
484 #define NUM_STD_CRL_FIELDS 2 /* TBD not including extensions */
486 /* map an OID to an oidToFieldFuncs */
487 static const oidToFieldFuncs
*oidToFields(
488 const CssmOid
&fieldId
)
490 const oidToFieldFuncs
*fieldTable
= crlFieldTable
;
491 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
492 if(fieldId
== CssmData::overlay(*fieldTable
->fieldId
)) {
497 CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG
);
501 * Common routine to free OID-specific field data. Used in the
502 * public DecodedCrl::freeCrlFieldData and when freeing
503 * extensions in a CSSM_X509_TBS_CERTLIST.
505 static void CL_freeCrlFieldData(
506 const CssmOid
&fieldId
,
507 CssmOwnedData
&fieldValue
,
510 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
511 CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER
);
513 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
514 if(fieldFuncs
->freeFcn
!= NULL
) {
515 /* optional - simple cases handled below */
516 fieldFuncs
->freeFcn(fieldValue
);
520 fieldValue
.release();
525 * Common routime to free a CSSM_X509_EXTENSIONS. Used to free
526 * CSSM_X509_TBS_CERTLIST.extensions and
527 * CSSM_X509_REVOKED_CERT_ENTRY.extensions.
528 * We just cook up a CssmOid and a CssmOwnedData for each extension
529 * and pass to CL_freeCrlFieldData().
531 static void CL_freeCssmExtensions(
532 CSSM_X509_EXTENSIONS
&extens
,
535 for(uint32 dex
=0; dex
<extens
.numberOfExtensions
; dex
++) {
536 CSSM_X509_EXTENSION_PTR exten
= &extens
.extensions
[dex
];
537 const CSSM_OID
*fieldOid
;
540 * The field OID is either the same as the extension's OID (if we parsed
541 * it) or CSSMOID_X509V3CertificateExtensionCStruct (if we didn't).
543 switch(exten
->format
) {
544 case CSSM_X509_DATAFORMAT_ENCODED
:
545 fieldOid
= &CSSMOID_X509V3CertificateExtensionCStruct
;
547 case CSSM_X509_DATAFORMAT_PARSED
:
548 case CSSM_X509_DATAFORMAT_PAIR
:
549 fieldOid
= &exten
->extnId
;
552 clErrorLog("CL_freeCssmExtensions: bad exten->format (%d)",
554 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
557 const CssmOid
&fieldId
= CssmOid::overlay(*fieldOid
);
559 if (exten
->extnId
.Data
!= NULL
) // if this is null, something threw when it was instantiated
561 CssmData
cData((uint8
*)exten
, sizeof(CSSM_X509_EXTENSION
));
562 CssmRemoteData
fieldValue(alloc
, cData
);
563 CL_freeCrlFieldData(fieldId
, fieldValue
, false);
564 fieldValue
.release(); // but no free (via reset() */
567 alloc
.free(extens
.extensions
);
568 memset(&extens
, 0, sizeof(CSSM_X509_EXTENSIONS
));
578 * Obtain the index'th occurrence of field specified by fieldId in specified cert.
579 * Format of the returned field depends on fieldId.
580 * Returns total number of fieldId fields in the cert if index is 0.
581 * FieldValue assumed to be empty on entry.
582 * Returns true if specified field was found, else returns false.
584 bool DecodedCrl::getCrlFieldData(
585 const CssmOid
&fieldId
, // which field
586 unsigned index
, // which occurrence (0 = first)
587 uint32
&numFields
, // RETURNED
588 CssmOwnedData
&fieldValue
) // RETURNED
593 clErrorLog("DecodedCrl::getCrlField: can't parse undecoded CRL!");
594 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
599 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
600 return fieldFuncs
->getFcn(*this, index
, numFields
, fieldValue
);
604 * Set the field specified by fieldId in the specified Cert.
605 * Note no index - individual field routines either append (for extensions)
606 * or if field already set ::throwMe(for all others)
608 void DecodedCrl::setCrlField(
609 const CssmOid
&fieldId
, // which field
610 const CssmData
&fieldValue
)
613 case IS_Empty
: // first time thru
614 mState
= IS_Building
;
616 case IS_Building
: // subsequent passes
620 clErrorLog("DecodedCrl::setCrlField: can't build on a decoded CRL!");
621 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
623 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
624 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
626 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
627 const CssmData
&value
= CssmData::overlay(fieldValue
);
628 fieldFuncs
->setFcn(*this, value
);
632 * Free the fieldId-specific data referred to by fieldValue->Data.
633 * No state from DecodedCrl needed; use the routine shared with
634 * CL_freeCssmExtensions().
636 void DecodedCrl::freeCrlFieldData(
637 const CssmOid
&fieldId
,
638 CssmOwnedData
&fieldValue
)
640 CL_freeCrlFieldData(fieldId
, fieldValue
);
645 * Common means to get all fields from a decoded CRL. Used in
646 * CrlGetAllTemplateFields and CrlGetAllFields.
648 void DecodedCrl::getAllParsedCrlFields(
649 uint32
&NumberOfFields
, // RETURNED
650 CSSM_FIELD_PTR
&CrlFields
) // RETURNED
652 /* this is the max - some might be missing */
653 uint32 maxFields
= NUM_STD_CRL_FIELDS
+ mDecodedExtensions
.numExtensions();
654 CSSM_FIELD_PTR outFields
= (CSSM_FIELD_PTR
)mAlloc
.malloc(
655 maxFields
* sizeof(CSSM_FIELD
));
658 * We'll be copying oids and values for fields we find into
659 * outFields; current number of valid fields found in numOutFields.
661 memset(outFields
, 0, maxFields
* sizeof(CSSM_FIELD
));
662 uint32 numOutFields
= 0;
663 CSSM_FIELD_PTR currOutField
;
665 const CSSM_OID
*currOid
;
666 CssmAutoData
aData(mAlloc
); // for malloc/copy of outgoing data
668 /* query for each OID we know about */
669 for(currOidDex
=0; currOidDex
<NUM_KNOWN_FIELDS
; currOidDex
++) {
670 const oidToFieldFuncs
*fieldFuncs
= &crlFieldTable
[currOidDex
];
671 currOid
= fieldFuncs
->fieldId
;
672 uint32 numFields
; // for THIS oid
675 * Return false if field not there, which is not an error here.
676 * Actual exceptions are fatal.
678 if(!fieldFuncs
->getFcn(*this,
679 0, // index - looking for first one
685 /* got some data for this oid - copy it and oid to outgoing CrlFields */
686 assert(numOutFields
< maxFields
);
687 currOutField
= &outFields
[numOutFields
];
688 currOutField
->FieldValue
= aData
.release();
689 aData
.copy(*currOid
);
690 currOutField
->FieldOid
= aData
.release();
693 /* if more fields are available for this OID, snag them too */
694 for(uint32 fieldDex
=1; fieldDex
<numFields
; fieldDex
++) {
695 /* note this should always succeed */
696 bool brtn
= fieldFuncs
->getFcn(*this,
698 numFields
, // shouldn't change
701 clErrorLog("getAllParsedCrlFields: index screwup");
702 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
704 assert(numOutFields
< maxFields
);
705 currOutField
= &outFields
[numOutFields
];
706 currOutField
->FieldValue
= aData
.release();
707 aData
.copy(*currOid
);
708 currOutField
->FieldOid
= aData
.release();
710 } /* multiple fields for currOid */
711 } /* for each known OID */
713 NumberOfFields
= numOutFields
;
714 CrlFields
= outFields
;
718 DecodedCrl::describeFormat(
720 uint32
&NumberOfFields
,
721 CSSM_OID_PTR
&OidList
)
723 /* malloc in app's space, do deep copy (including ->Data) */
724 CSSM_OID_PTR oidList
= (CSSM_OID_PTR
)alloc
.malloc(
725 NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
726 memset(oidList
, 0, NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
727 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
728 CssmAutoData
oidCopy(alloc
, *crlFieldTable
[i
].fieldId
);
729 oidList
[i
] = oidCopy
.release();
731 NumberOfFields
= NUM_KNOWN_FIELDS
;