crmfreq.c 19 KB

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