/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c

http://github.com/zpao/v8monkey · C · 913 lines · 520 code · 161 blank · 232 comment · 59 complexity · 5d567ceaa5e41b44be0b18907ad06882 MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the PKIX-C library.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Sun Microsystems, Inc.
  18. * Portions created by the Initial Developer are
  19. * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. * Sun Microsystems, Inc.
  23. *
  24. * Alternatively, the contents of this file may be used under the terms of
  25. * either the GNU General Public License Version 2 or later (the "GPL"), or
  26. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27. * in which case the provisions of the GPL or the LGPL are applicable instead
  28. * of those above. If you wish to allow use of your version of this file only
  29. * under the terms of either the GPL or the LGPL, and not to allow others to
  30. * use your version of this file under the terms of the MPL, indicate your
  31. * decision by deleting the provisions above and replace them with the notice
  32. * and other provisions required by the GPL or the LGPL. If you do not delete
  33. * the provisions above, a recipient may use your version of this file under
  34. * the terms of any one of the MPL, the GPL or the LGPL.
  35. *
  36. * ***** END LICENSE BLOCK ***** */
  37. /*
  38. * pkix_pl_crlentry.c
  39. *
  40. * CRLENTRY Function Definitions
  41. *
  42. */
  43. #include "pkix_pl_crlentry.h"
  44. /* --Private-CRLEntry-Functions------------------------------------- */
  45. /*
  46. * FUNCTION: pkix_pl_CRLEntry_Destroy
  47. * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
  48. */
  49. static PKIX_Error *
  50. pkix_pl_CRLEntry_Destroy(
  51. PKIX_PL_Object *object,
  52. void *plContext)
  53. {
  54. PKIX_PL_CRLEntry *crlEntry = NULL;
  55. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Destroy");
  56. PKIX_NULLCHECK_ONE(object);
  57. PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
  58. PKIX_OBJECTNOTCRLENTRY);
  59. crlEntry = (PKIX_PL_CRLEntry*)object;
  60. /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */
  61. crlEntry->userReasonCode = 0;
  62. crlEntry->userReasonCodeAbsent = PKIX_FALSE;
  63. crlEntry->nssCrlEntry = NULL;
  64. PKIX_DECREF(crlEntry->serialNumber);
  65. PKIX_DECREF(crlEntry->critExtOids);
  66. cleanup:
  67. PKIX_RETURN(CRLENTRY);
  68. }
  69. /*
  70. * FUNCTION: pkix_pl_CRLEntry_ToString_Helper
  71. *
  72. * DESCRIPTION:
  73. * Helper function that creates a string representation of the CRLEntry
  74. * pointed to by "crlEntry" and stores it at "pString".
  75. *
  76. * PARAMETERS
  77. * "crlEntry"
  78. * Address of CRLEntry whose string representation is desired.
  79. * Must be non-NULL.
  80. * "pString"
  81. * Address where object pointer will be stored. Must be non-NULL.
  82. * "plContext"
  83. * Platform-specific context pointer.
  84. * THREAD SAFETY:
  85. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  86. * RETURNS:
  87. * Returns NULL if the function succeeds.
  88. * Returns a CRLEntry Error if the function fails in a non-fatal way.
  89. * Returns a Fatal Error if the function fails in an unrecoverable way.
  90. */
  91. PKIX_Error *
  92. pkix_pl_CRLEntry_ToString_Helper(
  93. PKIX_PL_CRLEntry *crlEntry,
  94. PKIX_PL_String **pString,
  95. void *plContext)
  96. {
  97. char *asciiFormat = NULL;
  98. PKIX_List *critExtOIDs = NULL;
  99. PKIX_PL_String *crlEntryString = NULL;
  100. PKIX_PL_String *formatString = NULL;
  101. PKIX_PL_String *crlSerialNumberString = NULL;
  102. PKIX_PL_String *crlRevocationDateString = NULL;
  103. PKIX_PL_String *critExtOIDsString = NULL;
  104. PKIX_Int32 reasonCode = 0;
  105. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString_Helper");
  106. PKIX_NULLCHECK_FOUR
  107. (crlEntry,
  108. crlEntry->serialNumber,
  109. crlEntry->nssCrlEntry,
  110. pString);
  111. asciiFormat =
  112. "\n\t[\n"
  113. "\tSerialNumber: %s\n"
  114. "\tReasonCode: %d\n"
  115. "\tRevocationDate: %s\n"
  116. "\tCritExtOIDs: %s\n"
  117. "\t]\n\t";
  118. PKIX_CHECK(PKIX_PL_String_Create
  119. (PKIX_ESCASCII,
  120. asciiFormat,
  121. 0,
  122. &formatString,
  123. plContext),
  124. PKIX_STRINGCREATEFAILED);
  125. /* SerialNumber */
  126. PKIX_CHECK(PKIX_PL_Object_ToString
  127. ((PKIX_PL_Object *)crlEntry->serialNumber,
  128. &crlSerialNumberString,
  129. plContext),
  130. PKIX_BIGINTTOSTRINGHELPERFAILED);
  131. /* RevocationDate - No Date object created, use nss data directly */
  132. PKIX_CHECK(pkix_pl_Date_ToString_Helper
  133. (&(crlEntry->nssCrlEntry->revocationDate),
  134. &crlRevocationDateString,
  135. plContext),
  136. PKIX_DATETOSTRINGHELPERFAILED);
  137. /* CriticalExtensionOIDs */
  138. PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
  139. (crlEntry, &critExtOIDs, plContext),
  140. PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED);
  141. PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
  142. PKIX_LISTTOSTRINGFAILED);
  143. /* Revocation Reason Code */
  144. PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
  145. (crlEntry, &reasonCode, plContext),
  146. PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
  147. PKIX_CHECK(PKIX_PL_Sprintf
  148. (&crlEntryString,
  149. plContext,
  150. formatString,
  151. crlSerialNumberString,
  152. reasonCode,
  153. crlRevocationDateString,
  154. critExtOIDsString),
  155. PKIX_SPRINTFFAILED);
  156. *pString = crlEntryString;
  157. cleanup:
  158. PKIX_DECREF(critExtOIDs);
  159. PKIX_DECREF(crlSerialNumberString);
  160. PKIX_DECREF(crlRevocationDateString);
  161. PKIX_DECREF(critExtOIDsString);
  162. PKIX_DECREF(formatString);
  163. PKIX_RETURN(CRLENTRY);
  164. }
  165. /*
  166. * FUNCTION: pkix_pl_CRLEntry_ToString
  167. * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
  168. */
  169. static PKIX_Error *
  170. pkix_pl_CRLEntry_ToString(
  171. PKIX_PL_Object *object,
  172. PKIX_PL_String **pString,
  173. void *plContext)
  174. {
  175. PKIX_PL_String *crlEntryString = NULL;
  176. PKIX_PL_CRLEntry *crlEntry = NULL;
  177. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString");
  178. PKIX_NULLCHECK_TWO(object, pString);
  179. PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
  180. PKIX_OBJECTNOTCRLENTRY);
  181. crlEntry = (PKIX_PL_CRLEntry *) object;
  182. PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper
  183. (crlEntry, &crlEntryString, plContext),
  184. PKIX_CRLENTRYTOSTRINGHELPERFAILED);
  185. *pString = crlEntryString;
  186. cleanup:
  187. PKIX_RETURN(CRLENTRY);
  188. }
  189. /*
  190. * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode
  191. * DESCRIPTION:
  192. *
  193. * For each CRL Entry extension stored at NSS structure CERTCertExtension,
  194. * get its derbyte data and do the hash.
  195. *
  196. * PARAMETERS
  197. * "extensions"
  198. * Address of arrray of CERTCertExtension whose hash value is desired.
  199. * Must be non-NULL.
  200. * "pHashValue"
  201. * Address where the final hash value is returned. Must be non-NULL.
  202. * "plContext"
  203. * Platform-specific context pointer.
  204. * THREAD SAFETY:
  205. * Conditional Thread Safe
  206. * Though the value of extensions once created is not supposed to change,
  207. * it may be de-allocated while we are accessing it. But since we are
  208. * validating the object, it is unlikely we or someone is de-allocating
  209. * at the moment.
  210. * RETURNS:
  211. * Returns NULL if the function succeeds.
  212. * Returns an OID Error if the function fails in a non-fatal way.
  213. * Returns a Fatal Error if the function fails in an unrecoverable way.
  214. */
  215. static PKIX_Error *
  216. pkix_pl_CRLEntry_Extensions_Hashcode(
  217. CERTCertExtension **extensions,
  218. PKIX_UInt32 *pHashValue,
  219. void *plContext)
  220. {
  221. CERTCertExtension *extension = NULL;
  222. PRArenaPool *arena = NULL;
  223. PKIX_UInt32 extHash = 0;
  224. PKIX_UInt32 hashValue = 0;
  225. SECItem *derBytes = NULL;
  226. SECItem *resultSecItem = NULL;
  227. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Hashcode");
  228. PKIX_NULLCHECK_TWO(extensions, pHashValue);
  229. if (extensions) {
  230. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
  231. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  232. if (arena == NULL) {
  233. PKIX_ERROR(PKIX_OUTOFMEMORY);
  234. }
  235. while (*extensions) {
  236. extension = *extensions++;
  237. PKIX_NULLCHECK_ONE(extension);
  238. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
  239. derBytes = PORT_ArenaZNew(arena, SECItem);
  240. if (derBytes == NULL) {
  241. PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
  242. }
  243. PKIX_CRLENTRY_DEBUG
  244. ("\t\tCalling SEC_ASN1EncodeItem\n");
  245. resultSecItem = SEC_ASN1EncodeItem
  246. (arena,
  247. derBytes,
  248. extension,
  249. CERT_CertExtensionTemplate);
  250. if (resultSecItem == NULL){
  251. PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
  252. }
  253. PKIX_CHECK(pkix_hash
  254. (derBytes->data,
  255. derBytes->len,
  256. &extHash,
  257. plContext),
  258. PKIX_HASHFAILED);
  259. hashValue += (extHash << 7);
  260. }
  261. }
  262. *pHashValue = hashValue;
  263. cleanup:
  264. if (arena){
  265. /* Note that freeing the arena also frees derBytes */
  266. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
  267. PORT_FreeArena(arena, PR_FALSE);
  268. arena = NULL;
  269. }
  270. PKIX_RETURN(CRLENTRY);
  271. }
  272. /*
  273. * FUNCTION: pkix_pl_CRLEntry_Hashcode
  274. * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
  275. */
  276. static PKIX_Error *
  277. pkix_pl_CRLEntry_Hashcode(
  278. PKIX_PL_Object *object,
  279. PKIX_UInt32 *pHashcode,
  280. void *plContext)
  281. {
  282. SECItem *nssDate = NULL;
  283. PKIX_PL_CRLEntry *crlEntry = NULL;
  284. PKIX_UInt32 crlEntryHash;
  285. PKIX_UInt32 hashValue;
  286. PKIX_Int32 reasonCode = 0;
  287. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Hashcode");
  288. PKIX_NULLCHECK_TWO(object, pHashcode);
  289. PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
  290. PKIX_OBJECTNOTCRLENTRY);
  291. crlEntry = (PKIX_PL_CRLEntry *)object;
  292. PKIX_NULLCHECK_ONE(crlEntry->nssCrlEntry);
  293. nssDate = &(crlEntry->nssCrlEntry->revocationDate);
  294. PKIX_NULLCHECK_ONE(nssDate->data);
  295. PKIX_CHECK(pkix_hash
  296. ((const unsigned char *)nssDate->data,
  297. nssDate->len,
  298. &crlEntryHash,
  299. plContext),
  300. PKIX_ERRORGETTINGHASHCODE);
  301. PKIX_CHECK(PKIX_PL_Object_Hashcode
  302. ((PKIX_PL_Object *)crlEntry->serialNumber,
  303. &hashValue,
  304. plContext),
  305. PKIX_OBJECTHASHCODEFAILED);
  306. crlEntryHash += (hashValue << 7);
  307. hashValue = 0;
  308. if (crlEntry->nssCrlEntry->extensions) {
  309. PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode
  310. (crlEntry->nssCrlEntry->extensions, &hashValue, plContext),
  311. PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED);
  312. }
  313. crlEntryHash += (hashValue << 7);
  314. PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
  315. (crlEntry, &reasonCode, plContext),
  316. PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
  317. crlEntryHash += (reasonCode + 777) << 3;
  318. *pHashcode = crlEntryHash;
  319. cleanup:
  320. PKIX_RETURN(CRLENTRY);
  321. }
  322. /*
  323. * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals
  324. * DESCRIPTION:
  325. *
  326. * Compare each extension's DERbyte data in "firstExtensions" with extension
  327. * in "secondExtensions" in sequential order and store the result in
  328. * "pResult".
  329. *
  330. * PARAMETERS
  331. * "firstExtensions"
  332. * Address of first NSS structure CERTCertExtension to be compared.
  333. * Must be non-NULL.
  334. * "secondExtensions"
  335. * Address of second NSS structure CERTCertExtension to be compared.
  336. * Must be non-NULL.
  337. * "pResult"
  338. * Address where the comparison result is returned. Must be non-NULL.
  339. * "plContext"
  340. * Platform-specific context pointer.
  341. * THREAD SAFETY:
  342. * Conditionally Thread Safe
  343. * Though the value of extensions once created is not supposed to change,
  344. * it may be de-allocated while we are accessing it. But since we are
  345. * validating the object, it is unlikely we or someone is de-allocating
  346. * at the moment.
  347. * RETURNS:
  348. * Returns NULL if the function succeeds.
  349. * Returns an OID Error if the function fails in a non-fatal way.
  350. * Returns a Fatal Error if the function fails in an unrecoverable way.
  351. */
  352. static PKIX_Error *
  353. pkix_pl_CRLEntry_Extensions_Equals(
  354. CERTCertExtension **extensions1,
  355. CERTCertExtension **extensions2,
  356. PKIX_Boolean *pResult,
  357. void *plContext)
  358. {
  359. CERTCertExtension **firstExtensions;
  360. CERTCertExtension **secondExtensions;
  361. CERTCertExtension *firstExtension = NULL;
  362. CERTCertExtension *secondExtension = NULL;
  363. PRArenaPool *arena = NULL;
  364. PKIX_Boolean cmpResult = PKIX_FALSE;
  365. SECItem *firstDerBytes = NULL;
  366. SECItem *secondDerBytes = NULL;
  367. SECItem *firstResultSecItem = NULL;
  368. SECItem *secondResultSecItem = NULL;
  369. PKIX_UInt32 firstNumExt = 0;
  370. PKIX_UInt32 secondNumExt = 0;
  371. SECComparison secResult;
  372. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Equals");
  373. PKIX_NULLCHECK_THREE(extensions1, extensions2, pResult);
  374. firstExtensions = extensions1;
  375. secondExtensions = extensions2;
  376. if (firstExtensions) {
  377. while (*firstExtensions) {
  378. firstExtension = *firstExtensions++;
  379. firstNumExt++;
  380. }
  381. }
  382. if (secondExtensions) {
  383. while (*secondExtensions) {
  384. secondExtension = *secondExtensions++;
  385. secondNumExt++;
  386. }
  387. }
  388. if (firstNumExt != secondNumExt) {
  389. *pResult = PKIX_FALSE;
  390. goto cleanup;
  391. }
  392. if (firstNumExt == 0 && secondNumExt == 0) {
  393. *pResult = PKIX_TRUE;
  394. goto cleanup;
  395. }
  396. /* now have equal number, but non-zero extension items to compare */
  397. firstExtensions = extensions1;
  398. secondExtensions = extensions2;
  399. cmpResult = PKIX_TRUE;
  400. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
  401. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE*2);
  402. if (arena == NULL) {
  403. PKIX_ERROR(PKIX_OUTOFMEMORY);
  404. }
  405. while (firstNumExt--) {
  406. firstExtension = *firstExtensions++;
  407. secondExtension = *secondExtensions++;
  408. PKIX_NULLCHECK_TWO(firstExtension, secondExtension);
  409. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
  410. firstDerBytes = PORT_ArenaZNew(arena, SECItem);
  411. if (firstDerBytes == NULL) {
  412. PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
  413. }
  414. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
  415. secondDerBytes = PORT_ArenaZNew(arena, SECItem);
  416. if (secondDerBytes == NULL) {
  417. PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
  418. }
  419. PKIX_CRLENTRY_DEBUG
  420. ("\t\tCalling SEC_ASN1EncodeItem\n");
  421. firstResultSecItem = SEC_ASN1EncodeItem
  422. (arena,
  423. firstDerBytes,
  424. firstExtension,
  425. CERT_CertExtensionTemplate);
  426. if (firstResultSecItem == NULL){
  427. PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
  428. }
  429. PKIX_CRLENTRY_DEBUG
  430. ("\t\tCalling SEC_ASN1EncodeItem\n");
  431. secondResultSecItem = SEC_ASN1EncodeItem
  432. (arena,
  433. secondDerBytes,
  434. secondExtension,
  435. CERT_CertExtensionTemplate);
  436. if (secondResultSecItem == NULL){
  437. PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
  438. }
  439. PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
  440. secResult = SECITEM_CompareItem
  441. (firstResultSecItem, secondResultSecItem);
  442. if (secResult != SECEqual) {
  443. cmpResult = PKIX_FALSE;
  444. break;
  445. }
  446. }
  447. *pResult = cmpResult;
  448. cleanup:
  449. if (arena){
  450. /* Note that freeing the arena also frees derBytes */
  451. PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
  452. PORT_FreeArena(arena, PR_FALSE);
  453. arena = NULL;
  454. }
  455. PKIX_RETURN(CRLENTRY);
  456. }
  457. /*
  458. * FUNCTION: pkix_pl_CRLEntry_Equals
  459. * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
  460. */
  461. static PKIX_Error *
  462. pkix_pl_CRLEntry_Equals(
  463. PKIX_PL_Object *firstObject,
  464. PKIX_PL_Object *secondObject,
  465. PKIX_Boolean *pResult,
  466. void *plContext)
  467. {
  468. PKIX_PL_CRLEntry *firstCrlEntry = NULL;
  469. PKIX_PL_CRLEntry *secondCrlEntry = NULL;
  470. PKIX_UInt32 secondType;
  471. PKIX_Boolean cmpResult = PKIX_FALSE;
  472. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Equals");
  473. PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
  474. /* test that firstObject is a CRLEntry */
  475. PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRLENTRY_TYPE, plContext),
  476. PKIX_FIRSTOBJECTNOTCRLENTRY);
  477. firstCrlEntry = (PKIX_PL_CRLEntry *)firstObject;
  478. secondCrlEntry = (PKIX_PL_CRLEntry *)secondObject;
  479. PKIX_NULLCHECK_TWO
  480. (firstCrlEntry->nssCrlEntry, secondCrlEntry->nssCrlEntry);
  481. /*
  482. * Since we know firstObject is a CRLEntry, if both references are
  483. * identical, they must be equal
  484. */
  485. if (firstCrlEntry == secondCrlEntry){
  486. *pResult = PKIX_TRUE;
  487. goto cleanup;
  488. }
  489. /*
  490. * If secondCrlEntry isn't a CRL Entry, we don't throw an error.
  491. * We simply return a Boolean result of FALSE
  492. */
  493. *pResult = PKIX_FALSE;
  494. PKIX_CHECK(PKIX_PL_Object_GetType
  495. ((PKIX_PL_Object *)secondCrlEntry, &secondType, plContext),
  496. PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
  497. if (secondType != PKIX_CRLENTRY_TYPE) goto cleanup;
  498. /* Compare userSerialNumber */
  499. PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
  500. if (SECITEM_CompareItem(
  501. &(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->serialNumber),
  502. &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->serialNumber))
  503. != SECEqual) {
  504. *pResult = PKIX_FALSE;
  505. goto cleanup;
  506. }
  507. /* Compare revocationDate */
  508. PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
  509. if (SECITEM_CompareItem
  510. (&(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->
  511. revocationDate),
  512. &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->
  513. revocationDate))
  514. != SECEqual) {
  515. *pResult = PKIX_FALSE;
  516. goto cleanup;
  517. }
  518. /* Compare Critical Extension List */
  519. PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals
  520. (firstCrlEntry->nssCrlEntry->extensions,
  521. secondCrlEntry->nssCrlEntry->extensions,
  522. &cmpResult,
  523. plContext),
  524. PKIX_CRLENTRYEXTENSIONSEQUALSFAILED);
  525. if (cmpResult != PKIX_TRUE){
  526. *pResult = PKIX_FALSE;
  527. goto cleanup;
  528. }
  529. cmpResult = (firstCrlEntry->userReasonCode ==
  530. secondCrlEntry->userReasonCode);
  531. *pResult = cmpResult;
  532. cleanup:
  533. PKIX_RETURN(CRLENTRY);
  534. }
  535. /*
  536. * FUNCTION: pkix_pl_CRLEntry_RegisterSelf
  537. * DESCRIPTION:
  538. * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[]
  539. * THREAD SAFETY:
  540. * Not Thread Safe - for performance and complexity reasons
  541. *
  542. * Since this function is only called by PKIX_PL_Initialize, which should
  543. * only be called once, it is acceptable that this function is not
  544. * thread-safe.
  545. */
  546. PKIX_Error *
  547. pkix_pl_CRLEntry_RegisterSelf(void *plContext)
  548. {
  549. extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
  550. pkix_ClassTable_Entry entry;
  551. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_RegisterSelf");
  552. entry.description = "CRLEntry";
  553. entry.objCounter = 0;
  554. entry.typeObjectSize = sizeof(PKIX_PL_CRLEntry);
  555. entry.destructor = pkix_pl_CRLEntry_Destroy;
  556. entry.equalsFunction = pkix_pl_CRLEntry_Equals;
  557. entry.hashcodeFunction = pkix_pl_CRLEntry_Hashcode;
  558. entry.toStringFunction = pkix_pl_CRLEntry_ToString;
  559. entry.comparator = NULL;
  560. entry.duplicateFunction = pkix_duplicateImmutable;
  561. systemClasses[PKIX_CRLENTRY_TYPE] = entry;
  562. PKIX_RETURN(CRLENTRY);
  563. }
  564. /*
  565. * FUNCTION: pkix_pl_CRLEntry_CreateEntry
  566. * DESCRIPTION:
  567. *
  568. * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry"
  569. * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable.
  570. *
  571. * revokedCertificates SEQUENCE OF SEQUENCE {
  572. * userCertificate CertificateSerialNumber,
  573. * revocationDate Time,
  574. * crlEntryExtensions Extensions OPTIONAL
  575. * -- if present, MUST be v2
  576. *
  577. * PARAMETERS:
  578. * "nssCrlEntry"
  579. * Address of CERTCrlEntry representing an NSS CRL entry.
  580. * Must be non-NULL.
  581. * "pCrlEntry"
  582. * Address where object pointer will be stored. Must be non-NULL.
  583. * "plContext"
  584. * Platform-specific context pointer.
  585. * THREAD SAFETY:
  586. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  587. * RETURNS:
  588. * Returns NULL if the function succeeds.
  589. * Returns a CRLEntry Error if the function fails in a non-fatal way.
  590. * Returns a Fatal Error if the function fails in an unrecoverable way.
  591. */
  592. static PKIX_Error *
  593. pkix_pl_CRLEntry_CreateEntry(
  594. CERTCrlEntry *nssCrlEntry, /* entry data to be created from */
  595. PKIX_PL_CRLEntry **pCrlEntry,
  596. void *plContext)
  597. {
  598. PKIX_PL_CRLEntry *crlEntry = NULL;
  599. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_CreateEntry");
  600. PKIX_NULLCHECK_TWO(nssCrlEntry, pCrlEntry);
  601. PKIX_CHECK(PKIX_PL_Object_Alloc
  602. (PKIX_CRLENTRY_TYPE,
  603. sizeof (PKIX_PL_CRLEntry),
  604. (PKIX_PL_Object **)&crlEntry,
  605. plContext),
  606. PKIX_COULDNOTCREATECRLENTRYOBJECT);
  607. crlEntry->nssCrlEntry = nssCrlEntry;
  608. crlEntry->serialNumber = NULL;
  609. crlEntry->critExtOids = NULL;
  610. crlEntry->userReasonCode = 0;
  611. crlEntry->userReasonCodeAbsent = PKIX_FALSE;
  612. *pCrlEntry = crlEntry;
  613. cleanup:
  614. PKIX_RETURN(CRLENTRY);
  615. }
  616. /*
  617. * FUNCTION: pkix_pl_CRLEntry_Create
  618. * DESCRIPTION:
  619. *
  620. * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to
  621. * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is
  622. * NULL, this function stores an empty List at "pCrlEntryList".
  623. * }
  624. * PARAMETERS:
  625. * "nssCrlEntries"
  626. * Address of array of CERTCrlEntries representing NSS CRL entries.
  627. * Can be NULL if CRL has no NSS CRL entries.
  628. * "pCrlEntryList"
  629. * Address where object pointer will be stored. Must be non-NULL.
  630. * "plContext"
  631. * Platform-specific context pointer.
  632. * THREAD SAFETY:
  633. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  634. * RETURNS:
  635. * Returns NULL if the function succeeds.
  636. * Returns a CRLEntry Error if the function fails in a non-fatal way.
  637. * Returns a Fatal Error if the function fails in an unrecoverable way.
  638. */
  639. PKIX_Error *
  640. pkix_pl_CRLEntry_Create(
  641. CERTCrlEntry **nssCrlEntries, /* head of entry list */
  642. PKIX_List **pCrlEntryList,
  643. void *plContext)
  644. {
  645. PKIX_List *entryList = NULL;
  646. PKIX_PL_CRLEntry *crlEntry = NULL;
  647. CERTCrlEntry **entries = NULL;
  648. SECItem serialNumberItem;
  649. PKIX_PL_BigInt *serialNumber;
  650. char *bytes = NULL;
  651. PKIX_UInt32 length;
  652. PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Create");
  653. PKIX_NULLCHECK_ONE(pCrlEntryList);
  654. entries = nssCrlEntries;
  655. PKIX_CHECK(PKIX_List_Create(&entryList, plContext),
  656. PKIX_LISTCREATEFAILED);
  657. if (entries) {
  658. while (*entries){
  659. PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry
  660. (*entries, &crlEntry, plContext),
  661. PKIX_COULDNOTCREATECRLENTRYOBJECT);
  662. /* Get Serial Number */
  663. serialNumberItem = (*entries)->serialNumber;
  664. length = serialNumberItem.len;
  665. bytes = (char *)serialNumberItem.data;
  666. PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
  667. (bytes, length, &serialNumber, plContext),
  668. PKIX_BIGINTCREATEWITHBYTESFAILED);
  669. crlEntry->serialNumber = serialNumber;
  670. crlEntry->nssCrlEntry = *entries;
  671. PKIX_CHECK(PKIX_List_AppendItem
  672. (entryList, (PKIX_PL_Object *)crlEntry, plContext),
  673. PKIX_LISTAPPENDITEMFAILED);
  674. PKIX_DECREF(crlEntry);
  675. entries++;
  676. }
  677. }
  678. *pCrlEntryList = entryList;
  679. cleanup:
  680. PKIX_DECREF(crlEntry);
  681. if (PKIX_ERROR_RECEIVED){
  682. PKIX_DECREF(entryList);
  683. }
  684. PKIX_RETURN(CRLENTRY);
  685. }
  686. /* --Public-CRLENTRY-Functions------------------------------------- */
  687. /*
  688. * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode
  689. * (see comments in pkix_pl_pki.h)
  690. */
  691. PKIX_Error *
  692. PKIX_PL_CRLEntry_GetCRLEntryReasonCode (
  693. PKIX_PL_CRLEntry *crlEntry,
  694. PKIX_Int32 *pReason,
  695. void *plContext)
  696. {
  697. SECStatus status;
  698. CERTCRLEntryReasonCode nssReasonCode;
  699. PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode");
  700. PKIX_NULLCHECK_TWO(crlEntry, pReason);
  701. if (!crlEntry->userReasonCodeAbsent && crlEntry->userReasonCode == 0) {
  702. PKIX_OBJECT_LOCK(crlEntry);
  703. if (!crlEntry->userReasonCodeAbsent &&
  704. crlEntry->userReasonCode == 0) {
  705. /* reason code has not been cached in */
  706. PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n");
  707. status = CERT_FindCRLEntryReasonExten
  708. (crlEntry->nssCrlEntry, &nssReasonCode);
  709. if (status == SECSuccess) {
  710. crlEntry->userReasonCode = (PKIX_Int32) nssReasonCode;
  711. } else {
  712. crlEntry->userReasonCodeAbsent = PKIX_TRUE;
  713. }
  714. }
  715. PKIX_OBJECT_UNLOCK(crlEntry);
  716. }
  717. *pReason = crlEntry->userReasonCode;
  718. cleanup:
  719. PKIX_RETURN(CRLENTRY);
  720. }
  721. /*
  722. * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
  723. * (see comments in pkix_pl_pki.h)
  724. */
  725. PKIX_Error *
  726. PKIX_PL_CRLEntry_GetCriticalExtensionOIDs (
  727. PKIX_PL_CRLEntry *crlEntry,
  728. PKIX_List **pList, /* list of PKIX_PL_OID */
  729. void *plContext)
  730. {
  731. PKIX_List *oidsList = NULL;
  732. CERTCertExtension **extensions;
  733. PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs");
  734. PKIX_NULLCHECK_THREE(crlEntry, crlEntry->nssCrlEntry, pList);
  735. /* if we don't have a cached copy from before, we create one */
  736. if (crlEntry->critExtOids == NULL) {
  737. PKIX_OBJECT_LOCK(crlEntry);
  738. if (crlEntry->critExtOids == NULL) {
  739. extensions = crlEntry->nssCrlEntry->extensions;
  740. PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
  741. (extensions, &oidsList, plContext),
  742. PKIX_GETCRITICALEXTENSIONOIDSFAILED);
  743. crlEntry->critExtOids = oidsList;
  744. }
  745. PKIX_OBJECT_UNLOCK(crlEntry);
  746. }
  747. /* We should return a copy of the List since this list changes */
  748. PKIX_DUPLICATE(crlEntry->critExtOids, pList, plContext,
  749. PKIX_OBJECTDUPLICATELISTFAILED);
  750. cleanup:
  751. PKIX_RETURN(CRLENTRY);
  752. }