]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * Copyright (c) 2000-2010 Apple Inc. All Rights Reserved. | |
3 | * | |
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 | |
8 | * using this file. | |
9 | * | |
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. | |
16 | */ | |
17 | ||
18 | ||
19 | /* | |
20 | * CLCertExtensions.cpp - extensions support. A major component of DecodedCert. | |
21 | * | |
22 | */ | |
23 | ||
24 | #include "DecodedCert.h" | |
25 | #include "cldebugging.h" | |
26 | #include "CLCertExtensions.h" | |
27 | #include "CLFieldsCommon.h" | |
28 | #include "clNssUtils.h" | |
29 | #include "clNameUtils.h" | |
30 | #include <security_utilities/utilities.h> | |
31 | #include <Security/oidscert.h> | |
32 | #include <Security/oidsattr.h> | |
33 | #include <Security/cssmerr.h> | |
34 | #include <Security/x509defs.h> | |
35 | #include <Security/certextensions.h> | |
36 | #include <security_utilities/globalizer.h> | |
37 | #include <Security/certExtensionTemplates.h> | |
38 | #include <Security/SecAsn1Templates.h> | |
39 | ||
40 | /*** | |
41 | *** get/set/free functions called out from CertFields.cpp | |
42 | ***/ | |
43 | ||
44 | /*** | |
45 | *** KeyUsage | |
46 | *** CDSA format CE_KeyUsage | |
47 | *** NSS format CSSM_DATA, length 2 | |
48 | *** OID CSSMOID_KeyUsage | |
49 | ***/ | |
50 | ||
51 | void setFieldKeyUsage( | |
52 | DecodedItem &cert, | |
53 | const CssmData &fieldValue) | |
54 | { | |
55 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
56 | false); | |
57 | CE_KeyUsage *cdsaObj = (CE_KeyUsage *)cssmExt->value.parsedValue; | |
58 | ||
59 | /* Alloc an NSS-style key usage in cert.coder's memory */ | |
60 | SecNssCoder &coder = cert.coder(); | |
61 | CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); | |
62 | coder.allocItem(*nssObj, 2); | |
63 | ||
64 | /* cdsaObj --> nssObj */ | |
65 | nssObj->Data[0] = (*cdsaObj) >> 8; | |
66 | nssObj->Data[1] = *cdsaObj; | |
67 | ||
68 | /* Adjust length for BIT STRING encoding */ | |
69 | clCssmBitStringToNss(*nssObj); | |
70 | ||
71 | /* add to mExtensions */ | |
72 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
73 | kSecAsn1KeyUsageTemplate); | |
74 | } | |
75 | ||
76 | ||
77 | bool getFieldKeyUsage( | |
78 | DecodedItem &cert, | |
79 | unsigned index, // which occurrence (0 = first) | |
80 | uint32 &numFields, // RETURNED | |
81 | CssmOwnedData &fieldValue) | |
82 | { | |
83 | const DecodedExten *decodedExt; | |
84 | CSSM_DATA *nssObj; | |
85 | CE_KeyUsage *cdsaObj; | |
86 | bool brtn; | |
87 | ||
88 | brtn = cert.GetExtenTop<CSSM_DATA, CE_KeyUsage>( | |
89 | index, | |
90 | numFields, | |
91 | fieldValue.allocator, | |
92 | CSSMOID_KeyUsage, | |
93 | nssObj, | |
94 | cdsaObj, | |
95 | decodedExt); | |
96 | if(!brtn) { | |
97 | return false; | |
98 | } | |
99 | ||
100 | /* make a copy - can't modify length in place */ | |
101 | CSSM_DATA bitString = *nssObj; | |
102 | clNssBitStringToCssm(bitString); | |
103 | unsigned toCopy = bitString.Length; | |
104 | if(toCopy > 2) { | |
105 | /* I hope I never see this... */ | |
106 | clErrorLog("getFieldKeyUsage: KeyUsage larger than 2 bytes!"); | |
107 | toCopy = 2; | |
108 | } | |
109 | unsigned char bits[2] = {0, 0}; | |
110 | memmove(bits, bitString.Data, toCopy); | |
111 | *cdsaObj = (((unsigned)bits[0]) << 8) | bits[1]; | |
112 | ||
113 | /* pass back to caller */ | |
114 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
115 | return true; | |
116 | } | |
117 | ||
118 | /*** | |
119 | *** Basic Constraints | |
120 | *** CDSA format: CE_BasicConstraints | |
121 | *** NSS format CE_BasicConstraints | |
122 | *** OID CSSMOID_BasicConstraints | |
123 | ***/ | |
124 | ||
125 | void setFieldBasicConstraints( | |
126 | DecodedItem &cert, | |
127 | const CssmData &fieldValue) | |
128 | { | |
129 | CSSM_X509_EXTENSION_PTR cssmExt = | |
130 | verifySetFreeExtension(fieldValue, false); | |
131 | CE_BasicConstraints *cdsaObj = | |
132 | (CE_BasicConstraints *)cssmExt->value.parsedValue; | |
133 | ||
134 | /* Alloc an NSS-style BasicConstraints in cert.coder's memory */ | |
135 | SecNssCoder &coder = cert.coder(); | |
136 | NSS_BasicConstraints *nssObj = | |
137 | (NSS_BasicConstraints *)coder.malloc(sizeof(NSS_BasicConstraints)); | |
138 | memset(nssObj, 0, sizeof(*nssObj)); | |
139 | ||
140 | /* cdsaObj --> nssObj */ | |
141 | ArenaAllocator arenaAlloc(coder); | |
142 | clCssmBoolToNss(cdsaObj->cA, nssObj->cA, arenaAlloc); | |
143 | if(cdsaObj->pathLenConstraintPresent) { | |
144 | clIntToData(cdsaObj->pathLenConstraint, | |
145 | nssObj->pathLenConstraint, arenaAlloc); | |
146 | } | |
147 | ||
148 | /* add to mExtensions */ | |
149 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
150 | kSecAsn1BasicConstraintsTemplate); | |
151 | } | |
152 | ||
153 | ||
154 | bool getFieldBasicConstraints( | |
155 | DecodedItem &cert, | |
156 | unsigned index, // which occurrence (0 = first) | |
157 | uint32 &numFields, // RETURNED | |
158 | CssmOwnedData &fieldValue) | |
159 | { | |
160 | const DecodedExten *decodedExt; | |
161 | NSS_BasicConstraints *nssObj; | |
162 | CE_BasicConstraints *cdsaObj; | |
163 | bool brtn; | |
164 | ||
165 | brtn = cert.GetExtenTop<NSS_BasicConstraints, CE_BasicConstraints>( | |
166 | index, | |
167 | numFields, | |
168 | fieldValue.allocator, | |
169 | CSSMOID_BasicConstraints, | |
170 | nssObj, | |
171 | cdsaObj, | |
172 | decodedExt); | |
173 | if(!brtn) { | |
174 | return false; | |
175 | } | |
176 | ||
177 | if(nssObj->cA.Data == NULL) { | |
178 | /* default */ | |
179 | cdsaObj->cA = CSSM_FALSE; | |
180 | } | |
181 | else { | |
182 | cdsaObj->cA = clNssBoolToCssm(nssObj->cA); | |
183 | } | |
184 | if(nssObj->pathLenConstraint.Data == NULL) { | |
185 | /* optional */ | |
186 | cdsaObj->pathLenConstraintPresent = CSSM_FALSE; | |
187 | cdsaObj->pathLenConstraint = 0; | |
188 | } | |
189 | else { | |
190 | cdsaObj->pathLenConstraintPresent = CSSM_TRUE; | |
191 | cdsaObj->pathLenConstraint = clDataToInt(nssObj->pathLenConstraint); | |
192 | } | |
193 | ||
194 | /* pass back to caller */ | |
195 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
196 | return true; | |
197 | } | |
198 | ||
199 | /*** | |
200 | *** Extended Key Usage | |
201 | *** CDSA format: CE_ExtendedKeyUsage | |
202 | *** NSS format: NSS_ExtKeyUsage | |
203 | *** OID CSSMOID_ExtendedKeyUsage | |
204 | ***/ | |
205 | void setFieldExtKeyUsage( | |
206 | DecodedItem &cert, | |
207 | const CssmData &fieldValue) | |
208 | { | |
209 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
210 | false); | |
211 | CE_ExtendedKeyUsage *cdsaObj = | |
212 | (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue; | |
213 | ||
214 | SecNssCoder &coder = cert.coder(); | |
215 | NSS_ExtKeyUsage *nssObj = | |
216 | (NSS_ExtKeyUsage *)coder.malloc(sizeof(NSS_ExtKeyUsage)); | |
217 | memset(nssObj, 0, sizeof(*nssObj)); | |
218 | if(cdsaObj->numPurposes != 0) { | |
219 | nssObj->purposes = | |
220 | (CSSM_OID **)clNssNullArray(cdsaObj->numPurposes, coder); | |
221 | } | |
222 | ||
223 | /* cdsaObj --> nssObj, one 'purpose' (OID) at a time */ | |
224 | for(unsigned dex=0; dex<cdsaObj->numPurposes; dex++) { | |
225 | nssObj->purposes[dex] = (CSSM_OID *)coder.malloc(sizeof(CSSM_OID)); | |
226 | coder.allocCopyItem(cdsaObj->purposes[dex], | |
227 | *nssObj->purposes[dex]); | |
228 | } | |
229 | ||
230 | /* add to mExtensions */ | |
231 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
232 | kSecAsn1ExtKeyUsageTemplate); | |
233 | } | |
234 | ||
235 | bool getFieldExtKeyUsage( | |
236 | DecodedItem &cert, | |
237 | unsigned index, // which occurrence (0 = first) | |
238 | uint32 &numFields, // RETURNED | |
239 | CssmOwnedData &fieldValue) | |
240 | { | |
241 | const DecodedExten *decodedExt; | |
242 | NSS_ExtKeyUsage *nssObj; | |
243 | CE_ExtendedKeyUsage *cdsaObj; | |
244 | bool brtn; | |
245 | Allocator &alloc = fieldValue.allocator; | |
246 | ||
247 | brtn = cert.GetExtenTop<NSS_ExtKeyUsage, CE_ExtendedKeyUsage>( | |
248 | index, | |
249 | numFields, | |
250 | alloc, | |
251 | CSSMOID_ExtendedKeyUsage, | |
252 | nssObj, | |
253 | cdsaObj, | |
254 | decodedExt); | |
255 | if(!brtn) { | |
256 | return false; | |
257 | } | |
258 | ||
259 | /* nssObj --> cdsaObj, one purpose at a time */ | |
260 | unsigned numPurposes = clNssArraySize((const void **)nssObj->purposes); | |
261 | cdsaObj->numPurposes = numPurposes; | |
262 | if(numPurposes) { | |
263 | unsigned len = numPurposes * sizeof(CSSM_OID); | |
264 | cdsaObj->purposes = (CSSM_OID_PTR)alloc.malloc(len); | |
265 | memset(cdsaObj->purposes, 0, len); | |
266 | } | |
267 | for(unsigned dex=0; dex<numPurposes; dex++) { | |
268 | clAllocCopyData(alloc, *nssObj->purposes[dex], cdsaObj->purposes[dex]); | |
269 | } | |
270 | ||
271 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
272 | return true; | |
273 | } | |
274 | ||
275 | void freeFieldExtKeyUsage( | |
276 | CssmOwnedData &fieldValue) | |
277 | { | |
278 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
279 | Allocator &alloc = fieldValue.allocator; | |
280 | CE_ExtendedKeyUsage *cdsaObj = | |
281 | (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue; | |
282 | unsigned oidDex; | |
283 | for(oidDex=0; oidDex<cdsaObj->numPurposes; oidDex++) { | |
284 | alloc.free(cdsaObj->purposes[oidDex].Data); | |
285 | } | |
286 | alloc.free(cdsaObj->purposes); | |
287 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
288 | } | |
289 | ||
290 | /*** | |
291 | *** Subject Key Identifier | |
292 | *** CDSA format: CE_SubjectKeyID, which is just a CSSM_DATA | |
293 | *** OID CSSMOID_SubjectKeyIdentifier | |
294 | ***/ | |
295 | ||
296 | void setFieldSubjectKeyId( | |
297 | DecodedItem &cert, | |
298 | const CssmData &fieldValue) | |
299 | { | |
300 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
301 | false); | |
302 | CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue; | |
303 | SecNssCoder &coder = cert.coder(); | |
304 | CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); | |
305 | coder.allocCopyItem(*cdsaObj, *nssObj); | |
306 | ||
307 | /* add to mExtensions */ | |
308 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
309 | kSecAsn1SubjectKeyIdTemplate); | |
310 | } | |
311 | ||
312 | bool getFieldSubjectKeyId( | |
313 | DecodedItem &cert, | |
314 | unsigned index, // which occurrence (0 = first) | |
315 | uint32 &numFields, // RETURNED | |
316 | CssmOwnedData &fieldValue) | |
317 | { | |
318 | const DecodedExten *decodedExt; | |
319 | CSSM_DATA *nssObj; | |
320 | CE_SubjectKeyID *cdsaObj; | |
321 | bool brtn; | |
322 | Allocator &alloc = fieldValue.allocator; | |
323 | ||
324 | brtn = cert.GetExtenTop<CSSM_DATA, CE_SubjectKeyID>( | |
325 | index, | |
326 | numFields, | |
327 | alloc, | |
328 | CSSMOID_SubjectKeyIdentifier, | |
329 | nssObj, | |
330 | cdsaObj, | |
331 | decodedExt); | |
332 | if(!brtn) { | |
333 | return false; | |
334 | } | |
335 | ||
336 | /* if this fails, we're out of sync with nssExtenInfo[] in | |
337 | * CLFieldsCommon.cpp */ | |
338 | assert(nssObj != NULL); | |
339 | clAllocCopyData(alloc, *nssObj, *cdsaObj); | |
340 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
341 | return true; | |
342 | } | |
343 | ||
344 | void freeFieldSubjectKeyId ( | |
345 | CssmOwnedData &fieldValue) | |
346 | { | |
347 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
348 | Allocator &alloc = fieldValue.allocator; | |
349 | CE_SubjectKeyID *cdsaObj = (CE_SubjectKeyID *)cssmExt->value.parsedValue; | |
350 | alloc.free(cdsaObj->Data); | |
351 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
352 | } | |
353 | ||
354 | /*** | |
355 | *** Authority Key Identifier | |
356 | *** CDSA format: CE_AuthorityKeyID | |
357 | *** NSS format: NSS_AuthorityKeyId | |
358 | *** OID CSSMOID_AuthorityKeyIdentifier | |
359 | ***/ | |
360 | ||
361 | void setFieldAuthorityKeyId( | |
362 | DecodedItem &cert, | |
363 | const CssmData &fieldValue) | |
364 | { | |
365 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
366 | false); | |
367 | CE_AuthorityKeyID *cdsaObj = | |
368 | (CE_AuthorityKeyID *)cssmExt->value.parsedValue; | |
369 | ||
370 | /* Alloc an NSS-style AuthorityKeyId in cert.coder's memory */ | |
371 | SecNssCoder &coder = cert.coder(); | |
372 | NSS_AuthorityKeyId *nssObj = | |
373 | (NSS_AuthorityKeyId *)coder.malloc(sizeof(NSS_AuthorityKeyId)); | |
374 | memset(nssObj, 0, sizeof(*nssObj)); | |
375 | ||
376 | /* convert caller's CDSA-style CE_AuthorityKeyID to NSS */ | |
377 | CL_cssmAuthorityKeyIdToNss(*cdsaObj, *nssObj, coder); | |
378 | ||
379 | /* add to mExtensions */ | |
380 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
381 | kSecAsn1AuthorityKeyIdTemplate); | |
382 | } | |
383 | ||
384 | bool getFieldAuthorityKeyId( | |
385 | DecodedItem &cert, | |
386 | unsigned index, // which occurrence (0 = first) | |
387 | uint32 &numFields, // RETURNED | |
388 | CssmOwnedData &fieldValue) | |
389 | { | |
390 | const DecodedExten *decodedExt; | |
391 | NSS_AuthorityKeyId *nssObj; | |
392 | CE_AuthorityKeyID *cdsaObj; | |
393 | bool brtn; | |
394 | Allocator &alloc = fieldValue.allocator; | |
395 | ||
396 | brtn = cert.GetExtenTop<NSS_AuthorityKeyId, CE_AuthorityKeyID>( | |
397 | index, | |
398 | numFields, | |
399 | alloc, | |
400 | CSSMOID_AuthorityKeyIdentifier, | |
401 | nssObj, | |
402 | cdsaObj, | |
403 | decodedExt); | |
404 | if(!brtn) { | |
405 | return false; | |
406 | } | |
407 | assert(nssObj != NULL); | |
408 | ||
409 | /* nssObj --> cdsaObj */ | |
410 | CL_nssAuthorityKeyIdToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
411 | ||
412 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
413 | return true; | |
414 | } | |
415 | ||
416 | void freeFieldAuthorityKeyId ( | |
417 | CssmOwnedData &fieldValue) | |
418 | { | |
419 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
420 | Allocator &alloc = fieldValue.allocator; | |
421 | CE_AuthorityKeyID *cdsaObj = (CE_AuthorityKeyID *)cssmExt->value.parsedValue; | |
422 | CL_freeAuthorityKeyId(*cdsaObj, alloc); | |
423 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
424 | } | |
425 | ||
426 | /*** | |
427 | *** Subject/Issuer alternate name | |
428 | *** CDSA Format: CE_GeneralNames | |
429 | *** NSS format: NSS_GeneralNames | |
430 | *** OID: CSSMOID_SubjectAltName, CSSMOID_IssuerAltName | |
431 | ***/ | |
432 | void setFieldSubjIssuerAltName( | |
433 | DecodedItem &cert, | |
434 | const CssmData &fieldValue) | |
435 | { | |
436 | CSSM_X509_EXTENSION_PTR cssmExt = | |
437 | verifySetFreeExtension(fieldValue, false); | |
438 | CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue; | |
439 | ||
440 | /* Alloc an NSS-style GeneralNames in cert.coder's memory */ | |
441 | SecNssCoder &coder = cert.coder(); | |
442 | NSS_GeneralNames *nssObj = | |
443 | (NSS_GeneralNames *)coder.malloc(sizeof(NSS_GeneralNames)); | |
444 | memset(nssObj, 0, sizeof(*nssObj)); | |
445 | ||
446 | /* cdsaObj --> nssObj */ | |
447 | CL_cssmGeneralNamesToNss(*cdsaObj, *nssObj, coder); | |
448 | ||
449 | /* add to mExtensions */ | |
450 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
451 | kSecAsn1GeneralNamesTemplate); | |
452 | } | |
453 | ||
454 | bool getFieldSubjAltName( | |
455 | DecodedItem &cert, | |
456 | unsigned index, // which occurrence (0 = first) | |
457 | uint32 &numFields, // RETURNED | |
458 | CssmOwnedData &fieldValue) | |
459 | { | |
460 | const DecodedExten *decodedExt; | |
461 | NSS_GeneralNames *nssObj; | |
462 | CE_GeneralNames *cdsaObj; | |
463 | bool brtn; | |
464 | ||
465 | brtn = cert.GetExtenTop<NSS_GeneralNames, CE_GeneralNames>( | |
466 | index, | |
467 | numFields, | |
468 | fieldValue.allocator, | |
469 | CSSMOID_SubjectAltName, | |
470 | nssObj, | |
471 | cdsaObj, | |
472 | decodedExt); | |
473 | if(!brtn) { | |
474 | return false; | |
475 | } | |
476 | CL_nssGeneralNamesToCssm(*nssObj, *cdsaObj, | |
477 | cert.coder(), fieldValue.allocator); | |
478 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
479 | return true; | |
480 | } | |
481 | ||
482 | bool getFieldIssuerAltName( | |
483 | DecodedItem &cert, | |
484 | unsigned index, // which occurrence (0 = first) | |
485 | uint32 &numFields, // RETURNED | |
486 | CssmOwnedData &fieldValue) | |
487 | { | |
488 | const DecodedExten *decodedExt; | |
489 | NSS_GeneralNames *nssObj; | |
490 | CE_GeneralNames *cdsaObj; | |
491 | bool brtn; | |
492 | ||
493 | brtn = cert.GetExtenTop<NSS_GeneralNames, CE_GeneralNames>( | |
494 | index, | |
495 | numFields, | |
496 | fieldValue.allocator, | |
497 | CSSMOID_IssuerAltName, | |
498 | nssObj, | |
499 | cdsaObj, | |
500 | decodedExt); | |
501 | if(!brtn) { | |
502 | return false; | |
503 | } | |
504 | CL_nssGeneralNamesToCssm(*nssObj, *cdsaObj, | |
505 | cert.coder(), fieldValue.allocator); | |
506 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
507 | return true; | |
508 | } | |
509 | ||
510 | void freeFieldSubjIssuerAltName ( | |
511 | CssmOwnedData &fieldValue) | |
512 | { | |
513 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
514 | Allocator &alloc = fieldValue.allocator; | |
515 | CE_GeneralNames *cdsaObj = (CE_GeneralNames *)cssmExt->value.parsedValue; | |
516 | CL_freeCssmGeneralNames(cdsaObj, alloc); | |
517 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
518 | } | |
519 | ||
520 | /*** | |
521 | *** Certificate Policies | |
522 | *** CDSA Format: CE_CertPolicies | |
523 | *** NSS format : NSS_CertPolicies | |
524 | *** OID: CSSMOID_CertificatePolicies | |
525 | ***/ | |
526 | ||
527 | #define MAX_IA5_NAME_SIZE 1024 | |
528 | ||
529 | void setFieldCertPolicies( | |
530 | DecodedItem &cert, | |
531 | const CssmData &fieldValue) | |
532 | { | |
533 | CSSM_X509_EXTENSION_PTR cssmExt = | |
534 | verifySetFreeExtension(fieldValue, false); | |
535 | SecNssCoder &coder = cert.coder(); | |
536 | NSS_CertPolicies *nssObj = | |
537 | (NSS_CertPolicies *)coder.malloc(sizeof(NSS_CertPolicies)); | |
538 | memset(nssObj, 0, sizeof(NSS_CertPolicies)); | |
539 | CE_CertPolicies *cdsaObj = | |
540 | (CE_CertPolicies *)cssmExt->value.parsedValue; | |
541 | ||
542 | if(cdsaObj->numPolicies) { | |
543 | nssObj->policies = | |
544 | (NSS_PolicyInformation **)clNssNullArray( | |
545 | cdsaObj->numPolicies, coder); | |
546 | } | |
547 | for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) { | |
548 | CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex]; | |
549 | NSS_PolicyInformation *nPolInfo = (NSS_PolicyInformation *) | |
550 | coder.malloc(sizeof(NSS_PolicyInformation)); | |
551 | memset(nPolInfo, 0, sizeof(*nPolInfo)); | |
552 | nssObj->policies[polDex] = nPolInfo; | |
553 | ||
554 | coder.allocCopyItem(cPolInfo->certPolicyId, nPolInfo->certPolicyId); | |
555 | ||
556 | unsigned numQual = cPolInfo->numPolicyQualifiers; | |
557 | if(numQual != 0) { | |
558 | nPolInfo->policyQualifiers = | |
559 | (NSS_PolicyQualifierInfo **)clNssNullArray(numQual, | |
560 | coder); | |
561 | } | |
562 | for(unsigned qualDex=0; qualDex<numQual; qualDex++) { | |
563 | CE_PolicyQualifierInfo *cQualInfo = | |
564 | &cPolInfo->policyQualifiers[qualDex]; | |
565 | NSS_PolicyQualifierInfo *nQualInfo = | |
566 | (NSS_PolicyQualifierInfo *)coder.malloc( | |
567 | sizeof(NSS_PolicyQualifierInfo)); | |
568 | memset(nQualInfo, 0, sizeof(NSS_PolicyQualifierInfo)); | |
569 | nPolInfo->policyQualifiers[qualDex] = nQualInfo; | |
570 | ||
571 | /* | |
572 | * OK we're at the lowest level. | |
573 | * policyQualifierId == id_qt_cps: qualifier is | |
574 | * an IA5 string, incoming data is its contents. | |
575 | * Else incoming data is an encoded blob we pass on directly. | |
576 | */ | |
577 | coder.allocCopyItem(cQualInfo->policyQualifierId, | |
578 | nQualInfo->policyQualifierId); | |
579 | ||
580 | if(clCompareCssmData(&cQualInfo->policyQualifierId, | |
581 | &CSSMOID_QT_CPS)) { | |
582 | if(coder.encodeItem(&cQualInfo->qualifier, | |
583 | kSecAsn1IA5StringTemplate, | |
584 | nQualInfo->qualifier)) { | |
585 | clErrorLog("setFieldCertPOlicies: IA5 encode error\n"); | |
586 | CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR); | |
587 | } | |
588 | } | |
589 | else { | |
590 | /* uninterpreted, copy over directly */ | |
591 | coder.allocCopyItem(cQualInfo->qualifier, | |
592 | nQualInfo->qualifier); | |
593 | } | |
594 | } /* for each qualifier */ | |
595 | } /* for each policy */ | |
596 | ||
597 | /* add to mExtensions */ | |
598 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
599 | kSecAsn1CertPoliciesTemplate); | |
600 | } | |
601 | ||
602 | bool getFieldCertPolicies( | |
603 | DecodedItem &cert, | |
604 | unsigned index, // which occurrence (0 = first) | |
605 | uint32 &numFields, // RETURNED | |
606 | CssmOwnedData &fieldValue) | |
607 | { | |
608 | const DecodedExten *decodedExt; | |
609 | NSS_CertPolicies *nssObj; | |
610 | CE_CertPolicies *cdsaObj; | |
611 | bool brtn; | |
612 | Allocator &alloc = fieldValue.allocator; | |
613 | brtn = cert.GetExtenTop<NSS_CertPolicies, CE_CertPolicies>( | |
614 | index, | |
615 | numFields, | |
616 | fieldValue.allocator, | |
617 | CSSMOID_CertificatePolicies, | |
618 | nssObj, | |
619 | cdsaObj, | |
620 | decodedExt); | |
621 | if(!brtn) { | |
622 | return false; | |
623 | } | |
624 | assert(nssObj != NULL); | |
625 | ||
626 | memset(cdsaObj, 0, sizeof(*cdsaObj)); | |
627 | cdsaObj->numPolicies = | |
628 | clNssArraySize((const void **)nssObj->policies); | |
629 | unsigned sz = cdsaObj->numPolicies * sizeof(CE_PolicyInformation); | |
630 | if(sz) { | |
631 | cdsaObj->policies = (CE_PolicyInformation *)alloc.malloc(sz); | |
632 | memset(cdsaObj->policies, 0, sz); | |
633 | } | |
634 | ||
635 | for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) { | |
636 | CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex]; | |
637 | NSS_PolicyInformation *nPolInfo = nssObj->policies[polDex]; | |
638 | clAllocCopyData(alloc, nPolInfo->certPolicyId, | |
639 | cPolInfo->certPolicyId); | |
640 | if(nPolInfo->policyQualifiers == NULL) { | |
641 | continue; | |
642 | } | |
643 | ||
644 | cPolInfo->numPolicyQualifiers = | |
645 | clNssArraySize((const void **)nPolInfo->policyQualifiers); | |
646 | sz = cPolInfo->numPolicyQualifiers * | |
647 | sizeof(CE_PolicyQualifierInfo); | |
648 | cPolInfo->policyQualifiers = (CE_PolicyQualifierInfo *) | |
649 | alloc.malloc(sz); | |
650 | memset(cPolInfo->policyQualifiers, 0, sz); | |
651 | ||
652 | for(unsigned qualDex=0; qualDex<cPolInfo->numPolicyQualifiers; | |
653 | qualDex++) { | |
654 | NSS_PolicyQualifierInfo *nQualInfo = | |
655 | nPolInfo->policyQualifiers[qualDex]; | |
656 | CE_PolicyQualifierInfo *cQualInfo = | |
657 | &cPolInfo->policyQualifiers[qualDex]; | |
658 | ||
659 | /* | |
660 | * leaf. | |
661 | * policyQualifierId == CSSMOID_QT_CPS : | |
662 | * IA5String - decode and return contents. | |
663 | * Else return whole thing. | |
664 | */ | |
665 | clAllocCopyData(alloc, nQualInfo->policyQualifierId, | |
666 | cQualInfo->policyQualifierId); | |
667 | CSSM_DATA toCopy = nQualInfo->qualifier; | |
668 | if(clCompareCssmData(&nQualInfo->policyQualifierId, | |
669 | &CSSMOID_QT_CPS)) { | |
670 | /* decode as IA5String to temp memory */ | |
671 | toCopy.Data = NULL; | |
672 | toCopy.Length = 0; | |
673 | if(cert.coder().decodeItem(nQualInfo->qualifier, | |
674 | kSecAsn1IA5StringTemplate, | |
675 | &toCopy)) { | |
676 | clErrorLog("***getCertPolicies: bad IA5String!\n"); | |
677 | CssmError::throwMe(CSSMERR_CL_UNKNOWN_FORMAT); | |
678 | } | |
679 | } | |
680 | /* else copy out nQualInfo->qualifier */ | |
681 | clAllocCopyData(alloc, toCopy, cQualInfo->qualifier); | |
682 | } /* for each qualifier */ | |
683 | } /* for each policy info */ | |
684 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
685 | return true; | |
686 | } | |
687 | ||
688 | void freeFieldCertPolicies ( | |
689 | CssmOwnedData &fieldValue) | |
690 | { | |
691 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
692 | Allocator &alloc = fieldValue.allocator; | |
693 | CE_CertPolicies *cdsaObj = (CE_CertPolicies *)cssmExt->value.parsedValue; | |
694 | for(unsigned polDex=0; polDex<cdsaObj->numPolicies; polDex++) { | |
695 | CE_PolicyInformation *cPolInfo = &cdsaObj->policies[polDex]; | |
696 | alloc.free(cPolInfo->certPolicyId.Data); | |
697 | for(unsigned qualDex=0; | |
698 | qualDex<cPolInfo->numPolicyQualifiers; | |
699 | qualDex++) { | |
700 | CE_PolicyQualifierInfo *cQualInfo = | |
701 | &cPolInfo->policyQualifiers[qualDex]; | |
702 | alloc.free(cQualInfo->policyQualifierId.Data); | |
703 | alloc.free(cQualInfo->qualifier.Data); | |
704 | } | |
705 | alloc.free(cPolInfo->policyQualifiers); | |
706 | } | |
707 | alloc.free(cdsaObj->policies); | |
708 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, | |
709 | // BERvalue | |
710 | } | |
711 | ||
712 | /*** | |
713 | *** Netscape cert type | |
714 | *** CDSA Format: CE_NetscapeCertType (a uint16) | |
715 | *** NSS format CSSM_DATA, length 2 | |
716 | *** OID: CSSMOID_NetscapeCertType | |
717 | ***/ | |
718 | void setFieldNetscapeCertType( | |
719 | DecodedItem &cert, | |
720 | const CssmData &fieldValue) | |
721 | { | |
722 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
723 | false); | |
724 | CE_NetscapeCertType *cdsaObj = | |
725 | (CE_NetscapeCertType *)cssmExt->value.parsedValue; | |
726 | ||
727 | /* Alloc an NSS-style key usage in cert.coder's memory */ | |
728 | SecNssCoder &coder = cert.coder(); | |
729 | CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); | |
730 | coder.allocItem(*nssObj, 2); | |
731 | ||
732 | /* cdsaObj --> nssObj */ | |
733 | nssObj->Data[0] = (*cdsaObj) >> 8; | |
734 | nssObj->Data[1] = *cdsaObj; | |
735 | ||
736 | /* Adjust length for BIT STRING encoding */ | |
737 | clCssmBitStringToNss(*nssObj); | |
738 | ||
739 | /* add to mExtensions */ | |
740 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
741 | kSecAsn1NetscapeCertTypeTemplate); | |
742 | } | |
743 | ||
744 | bool getFieldNetscapeCertType( | |
745 | DecodedItem &cert, | |
746 | unsigned index, // which occurrence (0 = first) | |
747 | uint32 &numFields, // RETURNED | |
748 | CssmOwnedData &fieldValue) | |
749 | { | |
750 | const DecodedExten *decodedExt; | |
751 | CSSM_DATA *nssObj; | |
752 | CE_NetscapeCertType *cdsaObj; | |
753 | bool brtn; | |
754 | ||
755 | brtn = cert.GetExtenTop<CSSM_DATA, CE_NetscapeCertType>( | |
756 | index, | |
757 | numFields, | |
758 | fieldValue.allocator, | |
759 | CSSMOID_NetscapeCertType, | |
760 | nssObj, | |
761 | cdsaObj, | |
762 | decodedExt); | |
763 | if(!brtn) { | |
764 | return false; | |
765 | } | |
766 | ||
767 | /* make a copy - can't modify length in place */ | |
768 | CSSM_DATA bitString = *nssObj; | |
769 | clNssBitStringToCssm(bitString); | |
770 | unsigned toCopy = bitString.Length; | |
771 | if(toCopy > 2) { | |
772 | /* I hope I never see this... */ | |
773 | clErrorLog("getFieldKeyUsage: CertType larger than 2 bytes!"); | |
774 | toCopy = 2; | |
775 | } | |
776 | unsigned char bits[2] = {0, 0}; | |
777 | memmove(bits, bitString.Data, toCopy); | |
778 | *cdsaObj = (((unsigned)bits[0]) << 8) | bits[1]; | |
779 | ||
780 | /* pass back to caller */ | |
781 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
782 | return true; | |
783 | } | |
784 | ||
785 | /*** | |
786 | *** CRL Distribution points | |
787 | *** CDSA Format: CE_CRLDistPointsSyntax | |
788 | *** NSS format: NSS_CRLDistributionPoints | |
789 | *** OID: CSSMOID_CrlDistributionPoints | |
790 | ***/ | |
791 | void setFieldCrlDistPoints( | |
792 | DecodedItem &cert, | |
793 | const CssmData &fieldValue) | |
794 | { | |
795 | CSSM_X509_EXTENSION_PTR cssmExt = | |
796 | verifySetFreeExtension(fieldValue, false); | |
797 | CE_CRLDistPointsSyntax *cdsaObj = | |
798 | (CE_CRLDistPointsSyntax *)cssmExt->value.parsedValue; | |
799 | SecNssCoder &coder = cert.coder(); | |
800 | NSS_CRLDistributionPoints *nssObj = | |
801 | (NSS_CRLDistributionPoints *)coder.malloc( | |
802 | sizeof(NSS_CRLDistributionPoints)); | |
803 | ||
804 | CL_cssmDistPointsToNss(*cdsaObj, *nssObj, coder); | |
805 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
806 | kSecAsn1CRLDistributionPointsTemplate); | |
807 | } | |
808 | ||
809 | bool getFieldCrlDistPoints( | |
810 | DecodedItem &cert, | |
811 | unsigned index, // which occurrence (0 = first) | |
812 | uint32 &numFields, // RETURNED | |
813 | CssmOwnedData &fieldValue) | |
814 | { | |
815 | const DecodedExten *decodedExt; | |
816 | NSS_CRLDistributionPoints *nssObj; | |
817 | CE_CRLDistPointsSyntax *cdsaObj; | |
818 | bool brtn; | |
819 | Allocator &alloc = fieldValue.allocator; | |
820 | ||
821 | brtn = cert.GetExtenTop<NSS_CRLDistributionPoints, | |
822 | CE_CRLDistPointsSyntax>( | |
823 | index, | |
824 | numFields, | |
825 | alloc, | |
826 | CSSMOID_CrlDistributionPoints, | |
827 | nssObj, | |
828 | cdsaObj, | |
829 | decodedExt); | |
830 | if(!brtn) { | |
831 | return false; | |
832 | } | |
833 | assert(nssObj != NULL); | |
834 | CL_nssDistPointsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
835 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
836 | return true; | |
837 | } | |
838 | ||
839 | void freeFieldCrlDistPoints ( | |
840 | CssmOwnedData &fieldValue) | |
841 | { | |
842 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
843 | Allocator &alloc = fieldValue.allocator; | |
844 | CE_CRLDistPointsSyntax *cdsaObj = | |
845 | (CE_CRLDistPointsSyntax *)cssmExt->value.parsedValue; | |
846 | CL_freeCssmDistPoints(cdsaObj, alloc); | |
847 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
848 | } | |
849 | ||
850 | /*** | |
851 | *** {Subject,Authority}InfoAccess | |
852 | *** | |
853 | *** CDSA Format: CE_AuthorityInfoAccess | |
854 | *** NSS format: NSS_AuthorityInfoAccess | |
855 | *** OID: CSSMOID_AuthorityInfoAccess, CSSMOID_SubjectInfoAccess | |
856 | ***/ | |
857 | void setFieldAuthInfoAccess( | |
858 | DecodedItem &cert, | |
859 | const CssmData &fieldValue) | |
860 | { | |
861 | CSSM_X509_EXTENSION_PTR cssmExt = | |
862 | verifySetFreeExtension(fieldValue, false); | |
863 | CE_AuthorityInfoAccess *cdsaObj = | |
864 | (CE_AuthorityInfoAccess *)cssmExt->value.parsedValue; | |
865 | SecNssCoder &coder = cert.coder(); | |
866 | NSS_AuthorityInfoAccess *nssObj = | |
867 | (NSS_AuthorityInfoAccess *)coder.malloc( | |
868 | sizeof(NSS_AuthorityInfoAccess)); | |
869 | ||
870 | CL_cssmInfoAccessToNss(*cdsaObj, *nssObj, coder); | |
871 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
872 | kSecAsn1AuthorityInfoAccessTemplate); | |
873 | } | |
874 | ||
875 | bool getFieldAuthInfoAccess( | |
876 | DecodedItem &cert, | |
877 | unsigned index, // which occurrence (0 = first) | |
878 | uint32 &numFields, // RETURNED | |
879 | CssmOwnedData &fieldValue) | |
880 | { | |
881 | const DecodedExten *decodedExt; | |
882 | NSS_AuthorityInfoAccess *nssObj; | |
883 | CE_AuthorityInfoAccess *cdsaObj; | |
884 | bool brtn; | |
885 | Allocator &alloc = fieldValue.allocator; | |
886 | ||
887 | brtn = cert.GetExtenTop<NSS_AuthorityInfoAccess, | |
888 | CE_AuthorityInfoAccess>( | |
889 | index, | |
890 | numFields, | |
891 | alloc, | |
892 | CSSMOID_AuthorityInfoAccess, | |
893 | nssObj, | |
894 | cdsaObj, | |
895 | decodedExt); | |
896 | if(!brtn) { | |
897 | return false; | |
898 | } | |
899 | assert(nssObj != NULL); | |
900 | CL_infoAccessToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
901 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
902 | return true; | |
903 | } | |
904 | ||
905 | bool getFieldSubjInfoAccess( | |
906 | DecodedItem &cert, | |
907 | unsigned index, // which occurrence (0 = first) | |
908 | uint32 &numFields, // RETURNED | |
909 | CssmOwnedData &fieldValue) | |
910 | { | |
911 | const DecodedExten *decodedExt; | |
912 | NSS_AuthorityInfoAccess *nssObj; | |
913 | CE_AuthorityInfoAccess *cdsaObj; | |
914 | bool brtn; | |
915 | Allocator &alloc = fieldValue.allocator; | |
916 | ||
917 | brtn = cert.GetExtenTop<NSS_AuthorityInfoAccess, | |
918 | CE_AuthorityInfoAccess>( | |
919 | index, | |
920 | numFields, | |
921 | alloc, | |
922 | CSSMOID_SubjectInfoAccess, | |
923 | nssObj, | |
924 | cdsaObj, | |
925 | decodedExt); | |
926 | if(!brtn) { | |
927 | return false; | |
928 | } | |
929 | assert(nssObj != NULL); | |
930 | CL_infoAccessToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
931 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
932 | return true; | |
933 | } | |
934 | ||
935 | void freeFieldInfoAccess ( | |
936 | CssmOwnedData &fieldValue) | |
937 | { | |
938 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
939 | Allocator &alloc = fieldValue.allocator; | |
940 | CE_AuthorityInfoAccess *cdsaObj = | |
941 | (CE_AuthorityInfoAccess *)cssmExt->value.parsedValue; | |
942 | CL_freeInfoAccess(*cdsaObj, alloc); | |
943 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
944 | ||
945 | } | |
946 | ||
947 | /*** | |
948 | *** Qualfied Cert Statements | |
949 | *** | |
950 | *** CDSA Format: CE_QC_Statements | |
951 | *** NSS format: NSS_QC_Statements | |
952 | *** OID: CSSMOID_QC_Statements | |
953 | ***/ | |
954 | void setFieldQualCertStatements( | |
955 | DecodedItem &cert, | |
956 | const CssmData &fieldValue) | |
957 | { | |
958 | CSSM_X509_EXTENSION_PTR cssmExt = | |
959 | verifySetFreeExtension(fieldValue, false); | |
960 | CE_QC_Statements *cdsaObj = | |
961 | (CE_QC_Statements *)cssmExt->value.parsedValue; | |
962 | SecNssCoder &coder = cert.coder(); | |
963 | NSS_QC_Statements *nssObj = | |
964 | (NSS_QC_Statements *)coder.malloc( | |
965 | sizeof(NSS_QC_Statements)); | |
966 | ||
967 | CL_cssmQualCertStatementsToNss(*cdsaObj, *nssObj, coder); | |
968 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
969 | kSecAsn1QC_StatementsTemplate); | |
970 | } | |
971 | ||
972 | bool getFieldQualCertStatements( | |
973 | DecodedItem &cert, | |
974 | unsigned index, // which occurrence (0 = first) | |
975 | uint32 &numFields, // RETURNED | |
976 | CssmOwnedData &fieldValue) | |
977 | { | |
978 | const DecodedExten *decodedExt; | |
979 | NSS_QC_Statements *nssObj; | |
980 | CE_QC_Statements *cdsaObj; | |
981 | bool brtn; | |
982 | Allocator &alloc = fieldValue.allocator; | |
983 | ||
984 | brtn = cert.GetExtenTop<NSS_QC_Statements, | |
985 | CE_QC_Statements>( | |
986 | index, | |
987 | numFields, | |
988 | alloc, | |
989 | CSSMOID_QC_Statements, | |
990 | nssObj, | |
991 | cdsaObj, | |
992 | decodedExt); | |
993 | if(!brtn) { | |
994 | return false; | |
995 | } | |
996 | assert(nssObj != NULL); | |
997 | CL_qualCertStatementsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
998 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
999 | return true; | |
1000 | } | |
1001 | ||
1002 | void freeFieldQualCertStatements( | |
1003 | CssmOwnedData &fieldValue) | |
1004 | { | |
1005 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
1006 | Allocator &alloc = fieldValue.allocator; | |
1007 | CE_QC_Statements *cdsaObj = | |
1008 | (CE_QC_Statements *)cssmExt->value.parsedValue; | |
1009 | CL_freeQualCertStatements(*cdsaObj, alloc); | |
1010 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
1011 | } | |
1012 | ||
1013 | /*** | |
1014 | *** Name Constraints | |
1015 | *** CDSA Format: CE_NameConstraints | |
1016 | *** NSS format: NSS_NameConstraints | |
1017 | *** OID: CSSMOID_NameConstraints | |
1018 | ***/ | |
1019 | void setFieldNameConstraints( | |
1020 | DecodedItem &cert, | |
1021 | const CssmData &fieldValue) | |
1022 | { | |
1023 | CSSM_X509_EXTENSION_PTR cssmExt = | |
1024 | verifySetFreeExtension(fieldValue, false); | |
1025 | CE_NameConstraints *cdsaObj = | |
1026 | (CE_NameConstraints *)cssmExt->value.parsedValue; | |
1027 | SecNssCoder &coder = cert.coder(); | |
1028 | NSS_NameConstraints *nssObj = | |
1029 | (NSS_NameConstraints *)coder.malloc( | |
1030 | sizeof(NSS_NameConstraints)); | |
1031 | CL_cssmNameConstraintsToNss(*cdsaObj, *nssObj, coder); | |
1032 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
1033 | kSecAsn1NameConstraintsTemplate); | |
1034 | } | |
1035 | ||
1036 | bool getFieldNameConstraints( | |
1037 | DecodedItem &cert, | |
1038 | unsigned index, // which occurrence (0 = first) | |
1039 | uint32 &numFields, // RETURNED | |
1040 | CssmOwnedData &fieldValue) | |
1041 | { | |
1042 | const DecodedExten *decodedExt; | |
1043 | NSS_NameConstraints *nssObj; | |
1044 | CE_NameConstraints *cdsaObj; | |
1045 | bool brtn; | |
1046 | Allocator &alloc = fieldValue.allocator; | |
1047 | ||
1048 | brtn = cert.GetExtenTop<NSS_NameConstraints, | |
1049 | CE_NameConstraints>( | |
1050 | index, | |
1051 | numFields, | |
1052 | alloc, | |
1053 | CSSMOID_NameConstraints, | |
1054 | nssObj, | |
1055 | cdsaObj, | |
1056 | decodedExt); | |
1057 | if(!brtn) { | |
1058 | return false; | |
1059 | } | |
1060 | assert(nssObj != NULL); | |
1061 | CL_nssNameConstraintsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
1062 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
1063 | return true; | |
1064 | } | |
1065 | ||
1066 | void freeFieldNameConstraints ( | |
1067 | CssmOwnedData &fieldValue) | |
1068 | { | |
1069 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
1070 | Allocator &alloc = fieldValue.allocator; | |
1071 | CE_NameConstraints *cdsaObj = | |
1072 | (CE_NameConstraints *)cssmExt->value.parsedValue; | |
1073 | CL_freeCssmNameConstraints(cdsaObj, alloc); | |
1074 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
1075 | } | |
1076 | ||
1077 | /*** | |
1078 | *** Policy Mappings | |
1079 | *** CDSA Format: CE_PolicyMappings | |
1080 | *** NSS format: NSS_PolicyMappings | |
1081 | *** OID: CSSMOID_PolicyMappings | |
1082 | ***/ | |
1083 | void setFieldPolicyMappings( | |
1084 | DecodedItem &cert, | |
1085 | const CssmData &fieldValue) | |
1086 | { | |
1087 | CSSM_X509_EXTENSION_PTR cssmExt = | |
1088 | verifySetFreeExtension(fieldValue, false); | |
1089 | CE_PolicyMappings *cdsaObj = | |
1090 | (CE_PolicyMappings *)cssmExt->value.parsedValue; | |
1091 | SecNssCoder &coder = cert.coder(); | |
1092 | NSS_PolicyMappings *nssObj = | |
1093 | (NSS_PolicyMappings *)coder.malloc( | |
1094 | sizeof(NSS_PolicyMappings)); | |
1095 | CL_cssmPolicyMappingsToNss(*cdsaObj, *nssObj, coder); | |
1096 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
1097 | kSecAsn1PolicyMappingsTemplate); | |
1098 | } | |
1099 | ||
1100 | bool getFieldPolicyMappings( | |
1101 | DecodedItem &cert, | |
1102 | unsigned index, // which occurrence (0 = first) | |
1103 | uint32 &numFields, // RETURNED | |
1104 | CssmOwnedData &fieldValue) | |
1105 | { | |
1106 | const DecodedExten *decodedExt; | |
1107 | NSS_PolicyMappings *nssObj; | |
1108 | CE_PolicyMappings *cdsaObj; | |
1109 | bool brtn; | |
1110 | Allocator &alloc = fieldValue.allocator; | |
1111 | ||
1112 | brtn = cert.GetExtenTop<NSS_PolicyMappings, | |
1113 | CE_PolicyMappings>( | |
1114 | index, | |
1115 | numFields, | |
1116 | alloc, | |
1117 | CSSMOID_PolicyMappings, | |
1118 | nssObj, | |
1119 | cdsaObj, | |
1120 | decodedExt); | |
1121 | if(!brtn) { | |
1122 | return false; | |
1123 | } | |
1124 | assert(nssObj != NULL); | |
1125 | CL_nssPolicyMappingsToCssm(*nssObj, *cdsaObj, cert.coder(), alloc); | |
1126 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
1127 | return true; | |
1128 | } | |
1129 | ||
1130 | void freeFieldPolicyMappings ( | |
1131 | CssmOwnedData &fieldValue) | |
1132 | { | |
1133 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
1134 | Allocator &alloc = fieldValue.allocator; | |
1135 | CE_PolicyMappings *cdsaObj = | |
1136 | (CE_PolicyMappings *)cssmExt->value.parsedValue; | |
1137 | CL_freeCssmPolicyMappings(cdsaObj, alloc); | |
1138 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
1139 | } | |
1140 | ||
1141 | /*** | |
1142 | *** Policy Constraints | |
1143 | *** CDSA Format: CE_PolicyConstraints | |
1144 | *** NSS format: NSS_PolicyConstraints | |
1145 | *** OID: CSSMOID_PolicyConstraints | |
1146 | ***/ | |
1147 | void setFieldPolicyConstraints( | |
1148 | DecodedItem &cert, | |
1149 | const CssmData &fieldValue) | |
1150 | { | |
1151 | CSSM_X509_EXTENSION_PTR cssmExt = | |
1152 | verifySetFreeExtension(fieldValue, false); | |
1153 | CE_PolicyConstraints *cdsaObj = | |
1154 | (CE_PolicyConstraints *)cssmExt->value.parsedValue; | |
1155 | SecNssCoder &coder = cert.coder(); | |
1156 | NSS_PolicyConstraints *nssObj = | |
1157 | (NSS_PolicyConstraints *)coder.malloc( | |
1158 | sizeof(NSS_PolicyConstraints)); | |
1159 | CL_cssmPolicyConstraintsToNss(cdsaObj, nssObj, coder); | |
1160 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
1161 | kSecAsn1PolicyConstraintsTemplate); | |
1162 | } | |
1163 | ||
1164 | bool getFieldPolicyConstraints( | |
1165 | DecodedItem &cert, | |
1166 | unsigned index, // which occurrence (0 = first) | |
1167 | uint32 &numFields, // RETURNED | |
1168 | CssmOwnedData &fieldValue) | |
1169 | { | |
1170 | const DecodedExten *decodedExt; | |
1171 | NSS_PolicyConstraints *nssObj; | |
1172 | CE_PolicyConstraints *cdsaObj; | |
1173 | bool brtn; | |
1174 | Allocator &alloc = fieldValue.allocator; | |
1175 | ||
1176 | brtn = cert.GetExtenTop<NSS_PolicyConstraints, | |
1177 | CE_PolicyConstraints>( | |
1178 | index, | |
1179 | numFields, | |
1180 | alloc, | |
1181 | CSSMOID_PolicyConstraints, | |
1182 | nssObj, | |
1183 | cdsaObj, | |
1184 | decodedExt); | |
1185 | if(!brtn) { | |
1186 | return false; | |
1187 | } | |
1188 | assert(nssObj != NULL); | |
1189 | CL_nssPolicyConstraintsToCssm(nssObj, cdsaObj, cert.coder(), alloc); | |
1190 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
1191 | return true; | |
1192 | } | |
1193 | ||
1194 | void freeFieldPolicyConstraints ( | |
1195 | CssmOwnedData &fieldValue) | |
1196 | { | |
1197 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, false); | |
1198 | Allocator &alloc = fieldValue.allocator; | |
1199 | CE_PolicyConstraints *cdsaObj = | |
1200 | (CE_PolicyConstraints *)cssmExt->value.parsedValue; | |
1201 | CL_freeCssmPolicyConstraints(cdsaObj, alloc); | |
1202 | freeFieldExtenCommon(cssmExt, alloc); // frees extnId, parsedValue, BERvalue | |
1203 | } | |
1204 | ||
1205 | /*** | |
1206 | *** Inhibit Any Policy | |
1207 | *** CDSA Format: CE_InhibitAnyPolicy (an integer) | |
1208 | *** NSS format: CSSM_DATA, sizeof(uint32) | |
1209 | *** OID: CSSMOID_InhibitAnyPolicy | |
1210 | ***/ | |
1211 | void setFieldInhibitAnyPolicy( | |
1212 | DecodedItem &cert, | |
1213 | const CssmData &fieldValue) | |
1214 | { | |
1215 | CSSM_X509_EXTENSION_PTR cssmExt = verifySetFreeExtension(fieldValue, | |
1216 | false); | |
1217 | CE_InhibitAnyPolicy *cdsaObj = | |
1218 | (CE_InhibitAnyPolicy *)cssmExt->value.parsedValue; | |
1219 | ||
1220 | /* Alloc in cert.coder's memory */ | |
1221 | SecNssCoder &coder = cert.coder(); | |
1222 | CSSM_DATA *nssObj = (CSSM_DATA *)coder.malloc(sizeof(CSSM_DATA)); | |
1223 | coder.allocItem(*nssObj, sizeof(uint32)); | |
1224 | ||
1225 | /* cdsaObj --> nssObj */ | |
1226 | nssObj->Data[0] = (*cdsaObj) >> 24; | |
1227 | nssObj->Data[1] = (*cdsaObj) >> 16; | |
1228 | nssObj->Data[2] = (*cdsaObj) >> 8; | |
1229 | nssObj->Data[3] = *cdsaObj; | |
1230 | ||
1231 | /* add to mExtensions */ | |
1232 | cert.addExtension(nssObj, cssmExt->extnId, cssmExt->critical, false, | |
1233 | kSecAsn1IntegerTemplate); | |
1234 | } | |
1235 | ||
1236 | bool getFieldInhibitAnyPolicy( | |
1237 | DecodedItem &cert, | |
1238 | unsigned index, // which occurrence (0 = first) | |
1239 | uint32 &numFields, // RETURNED | |
1240 | CssmOwnedData &fieldValue) | |
1241 | { | |
1242 | const DecodedExten *decodedExt; | |
1243 | CSSM_DATA *nssObj; | |
1244 | CE_InhibitAnyPolicy *cdsaObj; | |
1245 | bool brtn; | |
1246 | ||
1247 | brtn = cert.GetExtenTop<CSSM_DATA, CE_InhibitAnyPolicy>( | |
1248 | index, | |
1249 | numFields, | |
1250 | fieldValue.allocator, | |
1251 | CSSMOID_InhibitAnyPolicy, | |
1252 | nssObj, | |
1253 | cdsaObj, | |
1254 | decodedExt); | |
1255 | if(!brtn) { | |
1256 | return false; | |
1257 | } | |
1258 | ||
1259 | *cdsaObj = *(nssObj->Data); //%%%FIXME check this | |
1260 | ||
1261 | /* pass back to caller */ | |
1262 | getFieldExtenCommon(cdsaObj, *decodedExt, fieldValue); | |
1263 | return true; | |
1264 | } | |
1265 |