|
1 /* -*- Mode: C; tab-width: 8 -*-*/ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "crmf.h" |
|
7 #include "crmfi.h" |
|
8 #include "keyhi.h" |
|
9 #include "secder.h" |
|
10 |
|
11 /* |
|
12 * Macro that returns PR_TRUE if the pointer is not NULL. |
|
13 * If the pointer is NULL, then the macro will return PR_FALSE. |
|
14 */ |
|
15 #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE |
|
16 |
|
17 const unsigned char hexTrue = 0xff; |
|
18 const unsigned char hexFalse = 0x00; |
|
19 |
|
20 |
|
21 SECStatus |
|
22 crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value) |
|
23 { |
|
24 SECItem *dummy; |
|
25 |
|
26 dummy = SEC_ASN1EncodeInteger(poolp, dest, value); |
|
27 PORT_Assert (dummy == dest); |
|
28 if (dummy == NULL) { |
|
29 return SECFailure; |
|
30 } |
|
31 return SECSuccess; |
|
32 } |
|
33 |
|
34 SECStatus |
|
35 crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest, |
|
36 unsigned long value) |
|
37 { |
|
38 SECItem *dummy; |
|
39 |
|
40 dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); |
|
41 PORT_Assert (dummy == dest); |
|
42 if (dummy != dest) { |
|
43 return SECFailure; |
|
44 } |
|
45 return SECSuccess; |
|
46 } |
|
47 |
|
48 static SECStatus |
|
49 crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) |
|
50 { |
|
51 return SECITEM_CopyItem (poolp, dest, src); |
|
52 } |
|
53 |
|
54 PRBool |
|
55 CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq, |
|
56 CRMFCertTemplateField inField) |
|
57 { |
|
58 |
|
59 PORT_Assert(inCertReq != NULL); |
|
60 if (inCertReq == NULL) { |
|
61 return PR_FALSE; |
|
62 } |
|
63 switch (inField) { |
|
64 case crmfVersion: |
|
65 return inCertReq->certTemplate.version.data != NULL; |
|
66 case crmfSerialNumber: |
|
67 return inCertReq->certTemplate.serialNumber.data != NULL; |
|
68 case crmfSigningAlg: |
|
69 return inCertReq->certTemplate.signingAlg != NULL; |
|
70 case crmfIssuer: |
|
71 return inCertReq->certTemplate.issuer != NULL; |
|
72 case crmfValidity: |
|
73 return inCertReq->certTemplate.validity != NULL; |
|
74 case crmfSubject: |
|
75 return inCertReq->certTemplate.subject != NULL; |
|
76 case crmfPublicKey: |
|
77 return inCertReq->certTemplate.publicKey != NULL; |
|
78 case crmfIssuerUID: |
|
79 return inCertReq->certTemplate.issuerUID.data != NULL; |
|
80 case crmfSubjectUID: |
|
81 return inCertReq->certTemplate.subjectUID.data != NULL; |
|
82 case crmfExtension: |
|
83 return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0; |
|
84 } |
|
85 return PR_FALSE; |
|
86 } |
|
87 |
|
88 CRMFCertRequest * |
|
89 CRMF_CreateCertRequest (PRUint32 inRequestID) |
|
90 { |
|
91 PLArenaPool *poolp; |
|
92 CRMFCertRequest *certReq; |
|
93 SECStatus rv; |
|
94 |
|
95 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); |
|
96 if (poolp == NULL) { |
|
97 goto loser; |
|
98 } |
|
99 |
|
100 certReq=PORT_ArenaZNew(poolp,CRMFCertRequest); |
|
101 if (certReq == NULL) { |
|
102 goto loser; |
|
103 } |
|
104 |
|
105 certReq->poolp = poolp; |
|
106 certReq->requestID = inRequestID; |
|
107 |
|
108 rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), |
|
109 inRequestID); |
|
110 if (rv != SECSuccess) { |
|
111 goto loser; |
|
112 } |
|
113 |
|
114 return certReq; |
|
115 loser: |
|
116 if (poolp) { |
|
117 PORT_FreeArena(poolp, PR_FALSE); |
|
118 } |
|
119 return NULL; |
|
120 } |
|
121 |
|
122 SECStatus |
|
123 CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq) |
|
124 { |
|
125 PORT_Assert(inCertReq != NULL); |
|
126 if (inCertReq != NULL) { |
|
127 if (inCertReq->certTemplate.extensions) { |
|
128 PORT_Free(inCertReq->certTemplate.extensions); |
|
129 } |
|
130 if (inCertReq->controls) { |
|
131 /* Right now we don't support EnveloppedData option, |
|
132 * so we won't go through and delete each occurrence of |
|
133 * an EnveloppedData in the control. |
|
134 */ |
|
135 PORT_Free(inCertReq->controls); |
|
136 } |
|
137 if (inCertReq->poolp) { |
|
138 PORT_FreeArena(inCertReq->poolp, PR_TRUE); |
|
139 } |
|
140 } |
|
141 return SECSuccess; |
|
142 } |
|
143 |
|
144 static SECStatus |
|
145 crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version) |
|
146 { |
|
147 return (crmf_encode_integer(poolp, dest, version)); |
|
148 } |
|
149 |
|
150 static SECStatus |
|
151 crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial) |
|
152 { |
|
153 return (crmf_encode_integer(poolp, dest, serial)); |
|
154 } |
|
155 |
|
156 SECStatus |
|
157 crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest, |
|
158 SECAlgorithmID* src) |
|
159 { |
|
160 SECStatus rv; |
|
161 void *mark = NULL; |
|
162 SECAlgorithmID *mySecAlg; |
|
163 |
|
164 if (!poolp) { |
|
165 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
|
166 return SECFailure; |
|
167 } |
|
168 |
|
169 mark = PORT_ArenaMark(poolp); |
|
170 *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); |
|
171 if (mySecAlg == NULL) { |
|
172 goto loser; |
|
173 } |
|
174 rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src); |
|
175 if (rv != SECSuccess) { |
|
176 goto loser; |
|
177 } |
|
178 if (mark) { |
|
179 PORT_ArenaUnmark(poolp, mark); |
|
180 } |
|
181 return SECSuccess; |
|
182 |
|
183 loser: |
|
184 *dest = NULL; |
|
185 if (mark) { |
|
186 PORT_ArenaRelease(poolp, mark); |
|
187 } |
|
188 return SECFailure; |
|
189 } |
|
190 |
|
191 SECStatus |
|
192 crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest, |
|
193 CERTName *src) |
|
194 { |
|
195 CERTName *newName; |
|
196 SECStatus rv; |
|
197 void *mark; |
|
198 |
|
199 mark = PORT_ArenaMark(poolp); |
|
200 *dest = newName = PORT_ArenaZNew(poolp, CERTName); |
|
201 if (newName == NULL) { |
|
202 goto loser; |
|
203 } |
|
204 |
|
205 rv = CERT_CopyName(poolp, newName, src); |
|
206 if (rv != SECSuccess) { |
|
207 goto loser; |
|
208 } |
|
209 PORT_ArenaUnmark(poolp, mark); |
|
210 return SECSuccess; |
|
211 loser: |
|
212 PORT_ArenaRelease(poolp, mark); |
|
213 *dest = NULL; |
|
214 return SECFailure; |
|
215 } |
|
216 |
|
217 static SECStatus |
|
218 crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest, |
|
219 CERTName* issuerName) |
|
220 { |
|
221 return crmf_copy_cert_name(poolp, dest, issuerName); |
|
222 } |
|
223 |
|
224 |
|
225 static SECStatus |
|
226 crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest, |
|
227 CRMFValidityCreationInfo *info) |
|
228 { |
|
229 SECStatus rv; |
|
230 void *mark; |
|
231 CRMFOptionalValidity *myValidity; |
|
232 |
|
233 /*First off, let's make sure at least one of the two fields is present*/ |
|
234 if (!info || (!info->notBefore && !info->notAfter)) { |
|
235 return SECFailure; |
|
236 } |
|
237 mark = PORT_ArenaMark (poolp); |
|
238 *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity); |
|
239 if (myValidity == NULL) { |
|
240 goto loser; |
|
241 } |
|
242 |
|
243 if (info->notBefore) { |
|
244 rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore, |
|
245 *info->notBefore); |
|
246 if (rv != SECSuccess) { |
|
247 goto loser; |
|
248 } |
|
249 } |
|
250 if (info->notAfter) { |
|
251 rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter, |
|
252 *info->notAfter); |
|
253 if (rv != SECSuccess) { |
|
254 goto loser; |
|
255 } |
|
256 } |
|
257 PORT_ArenaUnmark(poolp, mark); |
|
258 return SECSuccess; |
|
259 loser: |
|
260 PORT_ArenaRelease(poolp, mark); |
|
261 *dest = NULL; |
|
262 return SECFailure; |
|
263 } |
|
264 |
|
265 static SECStatus |
|
266 crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest, |
|
267 CERTName *subject) |
|
268 { |
|
269 return crmf_copy_cert_name(poolp, dest, subject); |
|
270 } |
|
271 |
|
272 SECStatus |
|
273 crmf_template_add_public_key(PLArenaPool *poolp, |
|
274 CERTSubjectPublicKeyInfo **dest, |
|
275 CERTSubjectPublicKeyInfo *pubKey) |
|
276 { |
|
277 CERTSubjectPublicKeyInfo *spki; |
|
278 SECStatus rv; |
|
279 |
|
280 *dest = spki = (poolp == NULL) ? |
|
281 PORT_ZNew(CERTSubjectPublicKeyInfo) : |
|
282 PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo); |
|
283 if (spki == NULL) { |
|
284 goto loser; |
|
285 } |
|
286 rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey); |
|
287 if (rv != SECSuccess) { |
|
288 goto loser; |
|
289 } |
|
290 return SECSuccess; |
|
291 loser: |
|
292 if (poolp == NULL && spki != NULL) { |
|
293 SECKEY_DestroySubjectPublicKeyInfo(spki); |
|
294 } |
|
295 *dest = NULL; |
|
296 return SECFailure; |
|
297 } |
|
298 |
|
299 static SECStatus |
|
300 crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src) |
|
301 { |
|
302 SECStatus rv; |
|
303 SECItem byteSrc; |
|
304 |
|
305 byteSrc = *src; |
|
306 byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len); |
|
307 rv = crmf_copy_secitem(poolp, dest, &byteSrc); |
|
308 dest->len = src->len; |
|
309 return rv; |
|
310 } |
|
311 |
|
312 static SECStatus |
|
313 crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest, |
|
314 const SECItem *issuerUID) |
|
315 { |
|
316 return crmf_copy_bitstring (poolp, dest, issuerUID); |
|
317 } |
|
318 |
|
319 static SECStatus |
|
320 crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest, |
|
321 const SECItem *subjectUID) |
|
322 { |
|
323 return crmf_copy_bitstring (poolp, dest, subjectUID); |
|
324 } |
|
325 |
|
326 static void |
|
327 crmf_zeroize_new_extensions (CRMFCertExtension **extensions, |
|
328 int numToZeroize) |
|
329 { |
|
330 PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize); |
|
331 } |
|
332 |
|
333 /* |
|
334 * The strategy for adding templates will differ from all the other |
|
335 * attributes in the template. First, we want to allow the client |
|
336 * of this API to set extensions more than just once. So we will |
|
337 * need the ability grow the array of extensions. Since arenas don't |
|
338 * give us the realloc function, we'll use the generic PORT_* functions |
|
339 * to allocate the array of pointers *ONLY*. Then we will allocate each |
|
340 * individual extension from the arena that comes along with the certReq |
|
341 * structure that owns this template. |
|
342 */ |
|
343 static SECStatus |
|
344 crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate, |
|
345 CRMFCertExtCreationInfo *extensions) |
|
346 { |
|
347 void *mark; |
|
348 int newSize, oldSize, i; |
|
349 SECStatus rv; |
|
350 CRMFCertExtension **extArray; |
|
351 CRMFCertExtension *newExt, *currExt; |
|
352 |
|
353 mark = PORT_ArenaMark(poolp); |
|
354 if (inTemplate->extensions == NULL) { |
|
355 newSize = extensions->numExtensions; |
|
356 extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1); |
|
357 } else { |
|
358 newSize = inTemplate->numExtensions + extensions->numExtensions; |
|
359 extArray = PORT_Realloc(inTemplate->extensions, |
|
360 sizeof(CRMFCertExtension*)*(newSize+1)); |
|
361 } |
|
362 if (extArray == NULL) { |
|
363 goto loser; |
|
364 } |
|
365 oldSize = inTemplate->numExtensions; |
|
366 inTemplate->extensions = extArray; |
|
367 inTemplate->numExtensions = newSize; |
|
368 for (i=oldSize; i < newSize; i++) { |
|
369 newExt = PORT_ArenaZNew(poolp, CRMFCertExtension); |
|
370 if (newExt == NULL) { |
|
371 goto loser2; |
|
372 } |
|
373 currExt = extensions->extensions[i-oldSize]; |
|
374 rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id)); |
|
375 if (rv != SECSuccess) { |
|
376 goto loser2; |
|
377 } |
|
378 rv = crmf_copy_secitem(poolp, &(newExt->critical), |
|
379 &(currExt->critical)); |
|
380 if (rv != SECSuccess) { |
|
381 goto loser2; |
|
382 } |
|
383 rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value)); |
|
384 if (rv != SECSuccess) { |
|
385 goto loser2; |
|
386 } |
|
387 extArray[i] = newExt; |
|
388 } |
|
389 extArray[newSize] = NULL; |
|
390 PORT_ArenaUnmark(poolp, mark); |
|
391 return SECSuccess; |
|
392 loser2: |
|
393 crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]), |
|
394 extensions->numExtensions); |
|
395 inTemplate->numExtensions = oldSize; |
|
396 loser: |
|
397 PORT_ArenaRelease(poolp, mark); |
|
398 return SECFailure; |
|
399 } |
|
400 |
|
401 SECStatus |
|
402 CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq, |
|
403 CRMFCertTemplateField inTemplateField, |
|
404 void *data) |
|
405 { |
|
406 CRMFCertTemplate *certTemplate; |
|
407 PLArenaPool *poolp; |
|
408 SECStatus rv = SECFailure; |
|
409 void *mark; |
|
410 |
|
411 |
|
412 if (inCertReq == NULL) { |
|
413 return SECFailure; |
|
414 } |
|
415 |
|
416 certTemplate = &(inCertReq->certTemplate); |
|
417 |
|
418 poolp = inCertReq->poolp; |
|
419 mark = PORT_ArenaMark(poolp); |
|
420 switch (inTemplateField) { |
|
421 case crmfVersion: |
|
422 rv = crmf_template_add_version(poolp,&(certTemplate->version), |
|
423 *(long*)data); |
|
424 break; |
|
425 case crmfSerialNumber: |
|
426 rv = crmf_template_add_serialnumber(poolp, |
|
427 &(certTemplate->serialNumber), |
|
428 *(long*)data); |
|
429 break; |
|
430 case crmfSigningAlg: |
|
431 rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg), |
|
432 (SECAlgorithmID*)data); |
|
433 break; |
|
434 case crmfIssuer: |
|
435 rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer), |
|
436 (CERTName*)data); |
|
437 break; |
|
438 case crmfValidity: |
|
439 rv = crmf_template_add_validity (poolp, &(certTemplate->validity), |
|
440 (CRMFValidityCreationInfo*)data); |
|
441 break; |
|
442 case crmfSubject: |
|
443 rv = crmf_template_add_subject (poolp, &(certTemplate->subject), |
|
444 (CERTName*)data); |
|
445 break; |
|
446 case crmfPublicKey: |
|
447 rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey), |
|
448 (CERTSubjectPublicKeyInfo*)data); |
|
449 break; |
|
450 case crmfIssuerUID: |
|
451 rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID), |
|
452 (SECItem*)data); |
|
453 break; |
|
454 case crmfSubjectUID: |
|
455 rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID), |
|
456 (SECItem*)data); |
|
457 break; |
|
458 case crmfExtension: |
|
459 rv = crmf_template_add_extensions(poolp, certTemplate, |
|
460 (CRMFCertExtCreationInfo*)data); |
|
461 break; |
|
462 } |
|
463 if (rv != SECSuccess) { |
|
464 PORT_ArenaRelease(poolp, mark); |
|
465 } else { |
|
466 PORT_ArenaUnmark(poolp, mark); |
|
467 } |
|
468 return rv; |
|
469 } |
|
470 |
|
471 SECStatus |
|
472 CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg, |
|
473 CRMFCertRequest *inCertReq) |
|
474 { |
|
475 PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL); |
|
476 if (inCertReqMsg == NULL || inCertReq == NULL) { |
|
477 return SECFailure; |
|
478 } |
|
479 inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp, |
|
480 inCertReq); |
|
481 return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess; |
|
482 } |
|
483 |
|
484 CRMFCertReqMsg* |
|
485 CRMF_CreateCertReqMsg(void) |
|
486 { |
|
487 PLArenaPool *poolp; |
|
488 CRMFCertReqMsg *reqMsg; |
|
489 |
|
490 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); |
|
491 if (poolp == NULL) { |
|
492 goto loser; |
|
493 } |
|
494 reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); |
|
495 if (reqMsg == NULL) { |
|
496 goto loser; |
|
497 } |
|
498 reqMsg->poolp = poolp; |
|
499 return reqMsg; |
|
500 |
|
501 loser: |
|
502 if (poolp) { |
|
503 PORT_FreeArena(poolp, PR_FALSE); |
|
504 } |
|
505 return NULL; |
|
506 } |
|
507 |
|
508 SECStatus |
|
509 CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg) |
|
510 { |
|
511 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL); |
|
512 if (!inCertReqMsg->isDecoded) { |
|
513 if (inCertReqMsg->certReq->certTemplate.extensions != NULL) { |
|
514 PORT_Free(inCertReqMsg->certReq->certTemplate.extensions); |
|
515 } |
|
516 if (inCertReqMsg->certReq->controls != NULL) { |
|
517 PORT_Free(inCertReqMsg->certReq->controls); |
|
518 } |
|
519 } |
|
520 PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE); |
|
521 return SECSuccess; |
|
522 } |
|
523 |
|
524 CRMFCertExtension* |
|
525 crmf_create_cert_extension(PLArenaPool *poolp, |
|
526 SECOidTag id, |
|
527 PRBool isCritical, |
|
528 SECItem *data) |
|
529 { |
|
530 CRMFCertExtension *newExt; |
|
531 SECOidData *oidData; |
|
532 SECStatus rv; |
|
533 |
|
534 newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) : |
|
535 PORT_ArenaZNew(poolp, CRMFCertExtension); |
|
536 if (newExt == NULL) { |
|
537 goto loser; |
|
538 } |
|
539 oidData = SECOID_FindOIDByTag(id); |
|
540 if (oidData == NULL || |
|
541 oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) { |
|
542 goto loser; |
|
543 } |
|
544 |
|
545 rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid)); |
|
546 if (rv != SECSuccess) { |
|
547 goto loser; |
|
548 } |
|
549 |
|
550 rv = SECITEM_CopyItem(poolp, &(newExt->value), data); |
|
551 if (rv != SECSuccess) { |
|
552 goto loser; |
|
553 } |
|
554 |
|
555 if (isCritical) { |
|
556 newExt->critical.data = (poolp == NULL) ? |
|
557 PORT_New(unsigned char) : |
|
558 PORT_ArenaNew(poolp, unsigned char); |
|
559 if (newExt->critical.data == NULL) { |
|
560 goto loser; |
|
561 } |
|
562 newExt->critical.data[0] = hexTrue; |
|
563 newExt->critical.len = 1; |
|
564 } |
|
565 return newExt; |
|
566 loser: |
|
567 if (newExt != NULL && poolp == NULL) { |
|
568 CRMF_DestroyCertExtension(newExt); |
|
569 } |
|
570 return NULL; |
|
571 } |
|
572 |
|
573 CRMFCertExtension * |
|
574 CRMF_CreateCertExtension(SECOidTag id, |
|
575 PRBool isCritical, |
|
576 SECItem *data) |
|
577 { |
|
578 return crmf_create_cert_extension(NULL, id, isCritical, data); |
|
579 } |
|
580 |
|
581 static SECStatus |
|
582 crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit) |
|
583 { |
|
584 if (inExtension != NULL) { |
|
585 SECITEM_FreeItem (&(inExtension->id), PR_FALSE); |
|
586 SECITEM_FreeItem (&(inExtension->value), PR_FALSE); |
|
587 SECITEM_FreeItem (&(inExtension->critical), PR_FALSE); |
|
588 if (freeit) { |
|
589 PORT_Free(inExtension); |
|
590 } |
|
591 } |
|
592 return SECSuccess; |
|
593 } |
|
594 |
|
595 SECStatus |
|
596 CRMF_DestroyCertExtension(CRMFCertExtension *inExtension) |
|
597 { |
|
598 return crmf_destroy_cert_extension(inExtension, PR_TRUE); |
|
599 } |
|
600 |
|
601 SECStatus |
|
602 CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) |
|
603 { |
|
604 PORT_Assert (inCertReqMsgs != NULL); |
|
605 if (inCertReqMsgs != NULL) { |
|
606 PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE); |
|
607 } |
|
608 return SECSuccess; |
|
609 } |
|
610 |
|
611 static PRBool |
|
612 crmf_item_has_data(SECItem *item) |
|
613 { |
|
614 if (item != NULL && item->data != NULL) { |
|
615 return PR_TRUE; |
|
616 } |
|
617 return PR_FALSE; |
|
618 } |
|
619 |
|
620 PRBool |
|
621 CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq, |
|
622 CRMFCertTemplateField inTemplateField) |
|
623 { |
|
624 PRBool retVal; |
|
625 CRMFCertTemplate *certTemplate; |
|
626 |
|
627 PORT_Assert(inCertReq != NULL); |
|
628 if (inCertReq == NULL) { |
|
629 /* This is probably some kind of error, but this is |
|
630 * the safest return value for this function. |
|
631 */ |
|
632 return PR_FALSE; |
|
633 } |
|
634 certTemplate = &inCertReq->certTemplate; |
|
635 switch (inTemplateField) { |
|
636 case crmfVersion: |
|
637 retVal = crmf_item_has_data(&certTemplate->version); |
|
638 break; |
|
639 case crmfSerialNumber: |
|
640 retVal = crmf_item_has_data(&certTemplate->serialNumber); |
|
641 break; |
|
642 case crmfSigningAlg: |
|
643 retVal = IS_NOT_NULL(certTemplate->signingAlg); |
|
644 break; |
|
645 case crmfIssuer: |
|
646 retVal = IS_NOT_NULL(certTemplate->issuer); |
|
647 break; |
|
648 case crmfValidity: |
|
649 retVal = IS_NOT_NULL(certTemplate->validity); |
|
650 break; |
|
651 case crmfSubject: |
|
652 retVal = IS_NOT_NULL(certTemplate->subject); |
|
653 break; |
|
654 case crmfPublicKey: |
|
655 retVal = IS_NOT_NULL(certTemplate->publicKey); |
|
656 break; |
|
657 case crmfIssuerUID: |
|
658 retVal = crmf_item_has_data(&certTemplate->issuerUID); |
|
659 break; |
|
660 case crmfSubjectUID: |
|
661 retVal = crmf_item_has_data(&certTemplate->subjectUID); |
|
662 break; |
|
663 case crmfExtension: |
|
664 retVal = IS_NOT_NULL(certTemplate->extensions); |
|
665 break; |
|
666 default: |
|
667 retVal = PR_FALSE; |
|
668 } |
|
669 return retVal; |
|
670 } |