2 * Copyright (c) 2000-2001,2011-2012,2014 Apple 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 * Copyright (c) 2002,2011-2012,2014 Apple Inc.
26 #include "DecodedCrl.h"
27 #include <security_utilities/debugging.h>
28 #include "cldebugging.h"
29 #include "CLCrlExtensions.h"
30 #include "CLCertExtensions.h"
31 #include "CLFieldsCommon.h"
32 #include "clNssUtils.h"
33 #include "clNameUtils.h"
34 #include <security_utilities/utilities.h>
35 #include <Security/oidscrl.h>
36 #include <Security/oidscert.h>
37 #include <Security/cssmerr.h>
38 #include <Security/x509defs.h>
40 static void CL_freeCssmExtensions(
41 CSSM_X509_EXTENSIONS
&extens
,
46 *** Format = DER-encoded int (max of four bytes in this case)
48 static bool getField_Version (
50 unsigned index
, // which occurrence (0 = first)
51 uint32
&numFields
, // RETURNED
52 CssmOwnedData
&fieldValue
) // RETURNED
54 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
55 const CSSM_DATA
&vers
= crl
.mCrl
.tbs
.version
;
56 if(!tbsGetCheck(vers
.Data
, index
)) {
57 /* not present, optional */
60 fieldValue
.copy(vers
.Data
, vers
.Length
);
65 static void setField_Version (
67 const CssmData
&fieldValue
)
69 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
70 CSSM_DATA
&vers
= crl
.mCrl
.tbs
.version
;
71 tbsSetCheck(vers
.Data
, fieldValue
, 0, "version");
72 crl
.coder().allocCopyItem(fieldValue
, vers
);
76 *** Format = CSSM_X509_NAME
77 *** class Name from sm_x501if
79 static bool getField_Issuer (
81 unsigned index
, // which occurrence (0 = first)
82 uint32
&numFields
, // RETURNED
83 CssmOwnedData
&fieldValue
) // RETURNED
91 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
93 brtn
= getField_RDN_NSS(crl
.mCrl
.tbs
.issuer
, fieldValue
);
99 freeField_RDN(fieldValue
);
105 static void setField_Issuer (
107 const CssmData
&fieldValue
)
109 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
110 const CSSM_X509_NAME
*cssmName
= (const CSSM_X509_NAME
*)fieldValue
.Data
;
111 NSS_Name
&nssName
= crl
.mCrl
.tbs
.issuer
;
112 tbsSetCheck(nssName
.rdns
, fieldValue
, sizeof(CSSM_X509_NAME
),
114 CL_cssmNameToNss(*cssmName
, nssName
, crl
.coder());
119 *** Format: CSSM_X509_TIME
121 static bool getField_ThisUpdate (
123 unsigned index
, // which occurrence (0 = first)
124 uint32
&numFields
, // RETURNED
125 CssmOwnedData
&fieldValue
) // RETURNED
127 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
128 const NSS_Time
&srcTime
= crl
.mCrl
.tbs
.thisUpdate
;
129 return getField_TimeNSS(srcTime
, index
, numFields
, fieldValue
);
132 static void setField_ThisUpdate (
134 const CssmData
&fieldValue
)
136 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
137 NSS_Time
&dstTime
= crl
.mCrl
.tbs
.thisUpdate
;
138 tbsSetCheck(dstTime
.item
.Data
, fieldValue
,
139 sizeof(CSSM_X509_TIME
), "NotBefore");
140 setField_TimeNSS(fieldValue
, dstTime
, crl
.coder());
143 static bool getField_NextUpdate (
145 unsigned index
, // which occurrence (0 = first)
146 uint32
&numFields
, // RETURNED
147 CssmOwnedData
&fieldValue
) // RETURNED
149 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
150 const NSS_Time
&srcTime
= crl
.mCrl
.tbs
.nextUpdate
;
151 return getField_TimeNSS(srcTime
, index
, numFields
, fieldValue
);
154 static void setField_NextUpdate (
156 const CssmData
&fieldValue
)
158 DecodedCrl
&crl
= dynamic_cast<DecodedCrl
&>(item
);
159 NSS_Time
&dstTime
= crl
.mCrl
.tbs
.nextUpdate
;
160 tbsSetCheck(dstTime
.item
.Data
, fieldValue
,
161 sizeof(CSSM_X509_TIME
), "NotBefore");
162 setField_TimeNSS(fieldValue
, dstTime
, crl
.coder());
166 *** Issuer Name (normalized and encoded version)
167 *** Format = CSSM_DATA containing the DER encoding of the normalized name
169 static bool getFieldIssuerNorm(
171 unsigned index
, // which occurrence (0 = first)
172 uint32
&numFields
, // RETURNED
173 CssmOwnedData
&fieldValue
) // RETURNED
178 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
179 return getField_normRDN_NSS(crl
.mCrl
.tbs
.derIssuer
, numFields
,
185 *** Format = CSSM_X509_ALGORITHM_IDENTIFIER
187 static bool getField_CrlTbsAlgId (
189 unsigned index
, // which occurrence (0 = first)
190 uint32
&numFields
, // RETURNED
191 CssmOwnedData
&fieldValue
) // RETURNED
193 const DecodedCrl
&crl
= dynamic_cast<const DecodedCrl
&>(item
);
194 const CSSM_X509_ALGORITHM_IDENTIFIER
&srcAlgId
=
195 crl
.mCrl
.signatureAlgorithm
;
196 if(!tbsGetCheck(srcAlgId
.algorithm
.Data
, index
)) {
199 getField_AlgIdNSS(srcAlgId
, fieldValue
);
205 * Support for entries in revocation list
207 static void nssRevokedEntryToCssm(
208 NSS_RevokedCert
&nssEntry
,
209 CSSM_X509_REVOKED_CERT_ENTRY
&cssmEntry
,
212 clAllocCopyData(alloc
, nssEntry
.userCertificate
, cssmEntry
.certificateSerialNumber
);
213 CL_nssTimeToCssm(nssEntry
.revocationDate
, cssmEntry
.revocationDate
, alloc
);
215 /* CSSM_X509_EXTENSIONS extensions */
216 NSS_CertExtension
**nssExtens
= nssEntry
.extensions
;
217 if(nssExtens
== NULL
) {
223 * First we have to decode the NSS-style Extensions into a
224 * DecodedExtensions object. For cert- and CRL-wide extensions, this
225 * is done at the construction of Decoded{Cert,Crl}. However for
226 * per-CRL-entry entensions, this is (currently) the only place
227 * this decoding is done.
230 DecodedExtensions
decodedExtens(coder
, alloc
);
231 decodedExtens
.decodeFromNss(nssExtens
);
233 /* convert to CDSA style */
234 decodedExtens
.convertToCdsa(cssmEntry
.extensions
, alloc
);
237 static void freeCssmEntry(
238 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
,
241 if(cssmEntry
== NULL
) {
244 if(cssmEntry
->certificateSerialNumber
.Data
) {
245 alloc
.free(cssmEntry
->certificateSerialNumber
.Data
);
246 cssmEntry
->certificateSerialNumber
.Data
= NULL
;
247 cssmEntry
->certificateSerialNumber
.Length
= 0;
249 CL_freeCssmTime(&cssmEntry
->revocationDate
, alloc
);
251 /* CSSM_X509_EXTENSIONS extensions */
252 CL_freeCssmExtensions(cssmEntry
->extensions
, alloc
);
254 memset(cssmEntry
, 0, sizeof(CSSM_X509_REVOKED_CERT_ENTRY
));
257 static void nssRevokedListToCssm(
258 NSS_RevokedCert
**nssList
, // may be NULL
259 CSSM_X509_REVOKED_CERT_LIST_PTR cssmList
,
262 unsigned numEntries
= clNssArraySize((const void **)nssList
);
263 cssmList
->numberOfRevokedCertEntries
= numEntries
;
264 if(numEntries
== 0) {
265 cssmList
->revokedCertEntry
= NULL
;
268 cssmList
->revokedCertEntry
= (CSSM_X509_REVOKED_CERT_ENTRY_PTR
)alloc
.malloc(
269 sizeof(CSSM_X509_REVOKED_CERT_ENTRY
) * numEntries
);
270 memset(cssmList
->revokedCertEntry
, 0,
271 sizeof(CSSM_X509_REVOKED_CERT_ENTRY
) * numEntries
);
272 for(unsigned dex
=0; dex
<numEntries
; dex
++) {
273 NSS_RevokedCert
*nssEntry
= nssList
[dex
];
274 assert(nssEntry
!= NULL
);
275 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
=
276 &cssmList
->revokedCertEntry
[dex
];
277 nssRevokedEntryToCssm(*nssEntry
, *cssmEntry
, alloc
);
282 static void freeCssmRevokedList(
283 CSSM_X509_REVOKED_CERT_LIST_PTR cssmList
,
286 if(cssmList
== NULL
) {
289 for(unsigned dex
=0; dex
<cssmList
->numberOfRevokedCertEntries
; dex
++) {
290 CSSM_X509_REVOKED_CERT_ENTRY_PTR cssmEntry
=
291 &cssmList
->revokedCertEntry
[dex
];
292 freeCssmEntry(cssmEntry
, alloc
);
294 if(cssmList
->revokedCertEntry
) {
295 alloc
.free(cssmList
->revokedCertEntry
);
297 memset(cssmList
, 0, sizeof(CSSM_X509_REVOKED_CERT_LIST
));
302 *** Format: CSSM_X509_SIGNED_CRL (the whole enchilada, parsed)
304 static bool getField_SignedCrl (
306 unsigned index
, // which occurrence (0 = first)
307 uint32
&numFields
, // RETURNED
308 CssmOwnedData
&fieldValue
) // RETURNED
310 Allocator
&alloc
= fieldValue
.allocator
;
312 const DecodedCrl
&nssCrl
= dynamic_cast<const DecodedCrl
&>(item
);
313 const NSS_TBSCrl
&nssTbs
= nssCrl
.mCrl
.tbs
;
314 fieldValue
.malloc(sizeof(CSSM_X509_SIGNED_CRL
));
315 CSSM_X509_SIGNED_CRL
&cssmCrl
= *((CSSM_X509_SIGNED_CRL
*)fieldValue
.data());
317 memset(&cssmCrl
, 0, sizeof(CSSM_X509_SIGNED_CRL
));
318 CSSM_X509_TBS_CERTLIST
&cssmTbs
= cssmCrl
.tbsCertList
;
321 clAllocCopyData(alloc
, nssTbs
.version
, cssmTbs
.version
);
323 /* CSSM_X509_ALGORITHM_IDENTIFIER signature - in TBS and CRL */
324 CL_copyAlgId(nssTbs
.signature
, cssmTbs
.signature
, alloc
);
325 CL_copyAlgId(nssCrl
.mCrl
.signatureAlgorithm
,
326 cssmCrl
.signature
.algorithmIdentifier
, alloc
);
328 /* CSSM_X509_NAME issuer */
329 CL_nssNameToCssm(nssTbs
.issuer
, cssmTbs
.issuer
, alloc
);
331 /* CSSM_X509_TIME thisUpdate, nextUpdate */
332 CL_nssTimeToCssm(nssTbs
.thisUpdate
, cssmTbs
.thisUpdate
, alloc
);
333 CL_nssTimeToCssm(nssTbs
.nextUpdate
, cssmTbs
.nextUpdate
, alloc
);
335 /* CSSM_X509_REVOKED_CERT_LIST_PTR revokedCertificates */
336 if(nssTbs
.revokedCerts
!= NULL
) {
337 cssmTbs
.revokedCertificates
= (CSSM_X509_REVOKED_CERT_LIST_PTR
)
338 alloc
.malloc(sizeof(CSSM_X509_REVOKED_CERT_LIST
));
339 memset(cssmTbs
.revokedCertificates
, 0, sizeof(CSSM_X509_REVOKED_CERT_LIST
));
340 nssRevokedListToCssm(nssTbs
.revokedCerts
,
341 cssmTbs
.revokedCertificates
, alloc
);
344 /* CSSM_X509_EXTENSIONS extensions */
345 const DecodedExtensions
&decodedExtens
= nssCrl
.decodedExtens();
346 decodedExtens
.convertToCdsa(cssmTbs
.extensions
, alloc
);
348 /* raw signature - stored in bits - note signature.algId set above */
349 CSSM_DATA nssSig
= nssCrl
.mCrl
.signature
;
350 nssSig
.Length
= (nssSig
.Length
+ 7) / 8;
351 clAllocCopyData(alloc
, nssSig
, cssmCrl
.signature
.encrypted
);
356 static void setField_SignedCrl (
358 const CssmData
&fieldValue
)
360 /* TBD - writing CRLs not supported now */
361 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED
);
364 static void freeField_SignedCrl (
365 CssmOwnedData
&fieldValue
)
367 CSSM_X509_SIGNED_CRL
*cssmCrl
=
368 (CSSM_X509_SIGNED_CRL
*)fieldValue
.data();
370 if(cssmCrl
== NULL
) {
373 if(fieldValue
.length() != sizeof(CSSM_X509_SIGNED_CRL
)) {
374 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
376 Allocator
&alloc
= fieldValue
.allocator
;
377 CSSM_X509_TBS_CERTLIST_PTR cssmTbs
= &cssmCrl
->tbsCertList
;
378 if(cssmTbs
== NULL
) {
379 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
382 /* run down the fields */
383 if(cssmTbs
->version
.Data
) {
384 alloc
.free(cssmTbs
->version
.Data
);
387 /* CSSM_X509_ALGORITHM_IDENTIFIER signature - in TBS and CRL */
388 CL_freeCssmAlgId(&cssmTbs
->signature
, alloc
);
389 CL_freeCssmAlgId(&cssmCrl
->signature
.algorithmIdentifier
, alloc
);
391 /* issuer, thisUpdate, nextUpdate */
392 CL_freeX509Name(&cssmTbs
->issuer
, alloc
);
393 CL_freeCssmTime(&cssmTbs
->thisUpdate
, alloc
);
394 CL_freeCssmTime(&cssmTbs
->nextUpdate
, alloc
);
396 /* CSSM_X509_REVOKED_CERT_LIST_PTR revokedCertificates */
397 freeCssmRevokedList(cssmTbs
->revokedCertificates
, alloc
);
398 alloc
.free(cssmTbs
->revokedCertificates
);
400 /* CSSM_X509_EXTENSIONS extensions */
401 CL_freeCssmExtensions(cssmTbs
->extensions
, alloc
);
403 /* raw signature - note signature.algId freed above */
404 alloc
.free(cssmCrl
->signature
.encrypted
.Data
);
406 memset(cssmCrl
, 0, sizeof(CSSM_X509_SIGNED_CRL
));
410 * Table to map OID to {get,set,free}field
413 const CSSM_OID
*fieldId
;
414 getItemFieldFcn
*getFcn
;
415 setItemFieldFcn
*setFcn
;
416 freeFieldFcn
*freeFcn
; // OPTIONAL - NULL means just free the
421 static const oidToFieldFuncs crlFieldTable
[] = {
422 /* this first one, which returns everything in a parsed format,
423 * is intended to be normally the only field used */
424 { &CSSMOID_X509V2CRLSignedCrlCStruct
,
425 &getField_SignedCrl
, &setField_SignedCrl
, &freeField_SignedCrl
},
426 { &CSSMOID_X509V2CRLVersion
,
427 &getField_Version
, &setField_Version
, NULL
},
428 { &CSSMOID_X509V1CRLIssuerNameCStruct
,
429 &getField_Issuer
, &setField_Issuer
, &freeField_RDN
},
430 { &CSSMOID_X509V1CRLThisUpdate
,
431 &getField_ThisUpdate
, &setField_ThisUpdate
, &freeField_Time
},
432 { &CSSMOID_X509V1CRLNextUpdate
,
433 &getField_NextUpdate
, &setField_NextUpdate
, &freeField_Time
},
434 { &CSSMOID_X509V1IssuerName
,
435 getFieldIssuerNorm
, &setField_ReadOnly
, NULL
},
436 { &CSSMOID_X509V1SignatureAlgorithmTBS
,
437 &getField_CrlTbsAlgId
, &setField_ReadOnly
, &freeField_AlgId
},
440 * Extensions, implemented in CrlExtensions.cpp
441 * When adding new ones, also add to:
442 * -- clOidToNssInfo() in CLFieldsCommon.cpp
443 * -- get/set/free functions in CrlExtensions.{cpp,h}
444 * -- DecodedExten::parse in DecodedExtensions.cpp
446 { &CSSMOID_CrlNumber
,
447 &getFieldCrlNumber
, &setFieldCrlNumber
, freeFieldSimpleExtension
},
448 { &CSSMOID_DeltaCrlIndicator
,
449 &getFieldDeltaCrl
, &setFieldCrlNumber
, freeFieldSimpleExtension
},
450 { &CSSMOID_CertIssuer
, // get/set not implemented
451 &getField_Unimplemented
, &setField_ReadOnly
,
452 &freeFieldSubjIssuerAltName
},
453 { &CSSMOID_CrlReason
, // get/set not implemented
454 &getField_Unimplemented
, &setField_ReadOnly
,
455 freeFieldSimpleExtension
},
456 { &CSSMOID_IssuingDistributionPoint
, // get/set not implemented
457 &getField_Unimplemented
, &setField_ReadOnly
,
458 &freeFieldIssuingDistPoint
},
459 { &CSSMOID_HoldInstructionCode
, // get/set not implemented
460 &getField_Unimplemented
, &setField_ReadOnly
,
461 &freeFieldOidOrData
},
462 { &CSSMOID_InvalidityDate
, // get/set not implemented
463 &getField_Unimplemented
, &setField_ReadOnly
,
464 &freeFieldOidOrData
},
466 /* in common with CertExtensions */
467 { &CSSMOID_AuthorityKeyIdentifier
, &getFieldAuthorityKeyId
,
468 &setFieldAuthorityKeyId
, &freeFieldAuthorityKeyId
} ,
469 { &CSSMOID_X509V3CertificateExtensionCStruct
, &getFieldUnknownExt
,
470 &setFieldUnknownExt
, &freeFieldUnknownExt
},
471 { &CSSMOID_SubjectAltName
, &getFieldSubjAltName
,
472 &setFieldSubjIssuerAltName
, &freeFieldSubjIssuerAltName
} ,
473 { &CSSMOID_IssuerAltName
, &getFieldIssuerAltName
,
474 &setFieldSubjIssuerAltName
, &freeFieldSubjIssuerAltName
} ,
476 { &CSSMOID_CrlDistributionPoints
, // get/set not implemented
477 &getField_Unimplemented
, &setField_ReadOnly
,
478 &freeFieldCrlDistributionPoints
},
482 #define NUM_KNOWN_FIELDS (sizeof(crlFieldTable) / sizeof(oidToFieldFuncs))
483 #define NUM_STD_CRL_FIELDS 2 /* TBD not including extensions */
485 /* map an OID to an oidToFieldFuncs */
486 static const oidToFieldFuncs
*oidToFields(
487 const CssmOid
&fieldId
)
489 const oidToFieldFuncs
*fieldTable
= crlFieldTable
;
490 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
491 if(fieldId
== CssmData::overlay(*fieldTable
->fieldId
)) {
496 CssmError::throwMe(CSSMERR_CL_UNKNOWN_TAG
);
500 * Common routine to free OID-specific field data. Used in the
501 * public DecodedCrl::freeCrlFieldData and when freeing
502 * extensions in a CSSM_X509_TBS_CERTLIST.
504 static void CL_freeCrlFieldData(
505 const CssmOid
&fieldId
,
506 CssmOwnedData
&fieldValue
,
509 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
510 CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER
);
512 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
513 if(fieldFuncs
->freeFcn
!= NULL
) {
514 /* optional - simple cases handled below */
515 fieldFuncs
->freeFcn(fieldValue
);
519 fieldValue
.release();
524 * Common routime to free a CSSM_X509_EXTENSIONS. Used to free
525 * CSSM_X509_TBS_CERTLIST.extensions and
526 * CSSM_X509_REVOKED_CERT_ENTRY.extensions.
527 * We just cook up a CssmOid and a CssmOwnedData for each extension
528 * and pass to CL_freeCrlFieldData().
530 static void CL_freeCssmExtensions(
531 CSSM_X509_EXTENSIONS
&extens
,
534 for(uint32 dex
=0; dex
<extens
.numberOfExtensions
; dex
++) {
535 CSSM_X509_EXTENSION_PTR exten
= &extens
.extensions
[dex
];
536 const CSSM_OID
*fieldOid
;
539 * The field OID is either the same as the extension's OID (if we parsed
540 * it) or CSSMOID_X509V3CertificateExtensionCStruct (if we didn't).
542 switch(exten
->format
) {
543 case CSSM_X509_DATAFORMAT_ENCODED
:
544 fieldOid
= &CSSMOID_X509V3CertificateExtensionCStruct
;
546 case CSSM_X509_DATAFORMAT_PARSED
:
547 case CSSM_X509_DATAFORMAT_PAIR
:
548 fieldOid
= &exten
->extnId
;
551 clErrorLog("CL_freeCssmExtensions: bad exten->format (%d)",
553 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
556 const CssmOid
&fieldId
= CssmOid::overlay(*fieldOid
);
558 if (exten
->extnId
.Data
!= NULL
) // if this is null, something threw when it was instantiated
560 CssmData
cData((uint8
*)exten
, sizeof(CSSM_X509_EXTENSION
));
561 CssmRemoteData
fieldValue(alloc
, cData
);
562 CL_freeCrlFieldData(fieldId
, fieldValue
, false);
563 fieldValue
.release(); // but no free (via reset() */
566 alloc
.free(extens
.extensions
);
567 memset(&extens
, 0, sizeof(CSSM_X509_EXTENSIONS
));
577 * Obtain the index'th occurrence of field specified by fieldId in specified cert.
578 * Format of the returned field depends on fieldId.
579 * Returns total number of fieldId fields in the cert if index is 0.
580 * FieldValue assumed to be empty on entry.
581 * Returns true if specified field was found, else returns false.
583 bool DecodedCrl::getCrlFieldData(
584 const CssmOid
&fieldId
, // which field
585 unsigned index
, // which occurrence (0 = first)
586 uint32
&numFields
, // RETURNED
587 CssmOwnedData
&fieldValue
) // RETURNED
592 clErrorLog("DecodedCrl::getCrlField: can't parse undecoded CRL!");
593 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
598 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
599 return fieldFuncs
->getFcn(*this, index
, numFields
, fieldValue
);
603 * Set the field specified by fieldId in the specified Cert.
604 * Note no index - individual field routines either append (for extensions)
605 * or if field already set ::throwMe(for all others)
607 void DecodedCrl::setCrlField(
608 const CssmOid
&fieldId
, // which field
609 const CssmData
&fieldValue
)
612 case IS_Empty
: // first time thru
613 mState
= IS_Building
;
615 case IS_Building
: // subsequent passes
619 clErrorLog("DecodedCrl::setCrlField: can't build on a decoded CRL!");
620 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
622 if((fieldValue
.data() == NULL
) || (fieldValue
.length() == 0)) {
623 CssmError::throwMe(CSSMERR_CL_INVALID_FIELD_POINTER
);
625 const oidToFieldFuncs
*fieldFuncs
= oidToFields(fieldId
);
626 const CssmData
&value
= CssmData::overlay(fieldValue
);
627 fieldFuncs
->setFcn(*this, value
);
631 * Free the fieldId-specific data referred to by fieldValue->Data.
632 * No state from DecodedCrl needed; use the routine shared with
633 * CL_freeCssmExtensions().
635 void DecodedCrl::freeCrlFieldData(
636 const CssmOid
&fieldId
,
637 CssmOwnedData
&fieldValue
)
639 CL_freeCrlFieldData(fieldId
, fieldValue
);
644 * Common means to get all fields from a decoded CRL. Used in
645 * CrlGetAllTemplateFields and CrlGetAllFields.
647 void DecodedCrl::getAllParsedCrlFields(
648 uint32
&NumberOfFields
, // RETURNED
649 CSSM_FIELD_PTR
&CrlFields
) // RETURNED
651 /* this is the max - some might be missing */
652 uint32 maxFields
= NUM_STD_CRL_FIELDS
+ mDecodedExtensions
.numExtensions();
653 CSSM_FIELD_PTR outFields
= (CSSM_FIELD_PTR
)mAlloc
.malloc(
654 maxFields
* sizeof(CSSM_FIELD
));
657 * We'll be copying oids and values for fields we find into
658 * outFields; current number of valid fields found in numOutFields.
660 memset(outFields
, 0, maxFields
* sizeof(CSSM_FIELD
));
661 uint32 numOutFields
= 0;
662 CSSM_FIELD_PTR currOutField
;
664 const CSSM_OID
*currOid
;
665 CssmAutoData
aData(mAlloc
); // for malloc/copy of outgoing data
667 /* query for each OID we know about */
668 for(currOidDex
=0; currOidDex
<NUM_KNOWN_FIELDS
; currOidDex
++) {
669 const oidToFieldFuncs
*fieldFuncs
= &crlFieldTable
[currOidDex
];
670 currOid
= fieldFuncs
->fieldId
;
671 uint32 numFields
; // for THIS oid
674 * Return false if field not there, which is not an error here.
675 * Actual exceptions are fatal.
677 if(!fieldFuncs
->getFcn(*this,
678 0, // index - looking for first one
684 /* got some data for this oid - copy it and oid to outgoing CrlFields */
685 assert(numOutFields
< maxFields
);
686 currOutField
= &outFields
[numOutFields
];
687 currOutField
->FieldValue
= aData
.release();
688 aData
.copy(*currOid
);
689 currOutField
->FieldOid
= aData
.release();
692 /* if more fields are available for this OID, snag them too */
693 for(uint32 fieldDex
=1; fieldDex
<numFields
; fieldDex
++) {
694 /* note this should always succeed */
695 bool brtn
= fieldFuncs
->getFcn(*this,
697 numFields
, // shouldn't change
700 clErrorLog("getAllParsedCrlFields: index screwup");
701 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR
);
703 assert(numOutFields
< maxFields
);
704 currOutField
= &outFields
[numOutFields
];
705 currOutField
->FieldValue
= aData
.release();
706 aData
.copy(*currOid
);
707 currOutField
->FieldOid
= aData
.release();
709 } /* multiple fields for currOid */
710 } /* for each known OID */
712 NumberOfFields
= numOutFields
;
713 CrlFields
= outFields
;
717 DecodedCrl::describeFormat(
719 uint32
&NumberOfFields
,
720 CSSM_OID_PTR
&OidList
)
722 /* malloc in app's space, do deep copy (including ->Data) */
723 CSSM_OID_PTR oidList
= (CSSM_OID_PTR
)alloc
.malloc(
724 NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
725 memset(oidList
, 0, NUM_KNOWN_FIELDS
* sizeof(CSSM_OID
));
726 for(unsigned i
=0; i
<NUM_KNOWN_FIELDS
; i
++) {
727 CssmAutoData
oidCopy(alloc
, *crlFieldTable
[i
].fieldId
);
728 oidList
[i
] = oidCopy
.release();
730 NumberOfFields
= NUM_KNOWN_FIELDS
;