/security/nss/lib/libpkix/pkix/results/pkix_policynode.c

http://github.com/zpao/v8monkey · C · 1410 lines · 749 code · 221 blank · 440 comment · 49 complexity · 0edfe3a56cb2f823cf524847b7a8cd57 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_policynode.c
  39. *
  40. * Policy Node Object Type Definition
  41. *
  42. */
  43. #include "pkix_policynode.h"
  44. /* --Private-PolicyNode-Functions---------------------------------- */
  45. /*
  46. * FUNCTION: pkix_PolicyNode_GetChildrenMutable
  47. * DESCRIPTION:
  48. *
  49. * Retrieves the List of PolicyNodes representing the child nodes of the
  50. * Policy Node pointed to by "node" and stores it at "pChildren". If "node"
  51. * has no List of child nodes, this function stores NULL at "pChildren".
  52. *
  53. * Note that the List returned by this function may be mutable. This function
  54. * differs from the public function PKIX_PolicyNode_GetChildren in that
  55. * respect. (It also differs in that the public function creates an empty
  56. * List, if necessary, rather than storing NULL.)
  57. *
  58. * During certificate processing, children Lists are created and modified.
  59. * Once the list is accessed using the public call, the List is set immutable.
  60. *
  61. * PARAMETERS:
  62. * "node"
  63. * Address of PolicyNode whose child nodes are to be stored.
  64. * Must be non-NULL.
  65. * "pChildren"
  66. * Address where object pointer will be stored. Must be non-NULL.
  67. * "plContext"
  68. * Platform-specific context pointer.
  69. * THREAD SAFETY:
  70. * Conditionally Thread Safe
  71. * (see Thread Safety Definitions in Programmer's Guide)
  72. * RETURNS:
  73. * Returns NULL if the function succeeds.
  74. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  75. * Returns a Fatal Error if the function fails in an unrecoverable way.
  76. */
  77. PKIX_Error *
  78. pkix_PolicyNode_GetChildrenMutable(
  79. PKIX_PolicyNode *node,
  80. PKIX_List **pChildren, /* list of PKIX_PolicyNode */
  81. void *plContext)
  82. {
  83. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_GetChildrenMutable");
  84. PKIX_NULLCHECK_TWO(node, pChildren);
  85. PKIX_INCREF(node->children);
  86. *pChildren = node->children;
  87. cleanup:
  88. PKIX_RETURN(CERTPOLICYNODE);
  89. }
  90. /*
  91. * FUNCTION: pkix_PolicyNode_Create
  92. * DESCRIPTION:
  93. *
  94. * Creates a new PolicyNode using the OID pointed to by "validPolicy", the List
  95. * of CertPolicyQualifiers pointed to by "qualifierSet", the criticality
  96. * indicated by the Boolean value of "criticality", and the List of OIDs
  97. * pointed to by "expectedPolicySet", and stores the result at "pObject". The
  98. * criticality should be derived from whether the certificate policy extension
  99. * was marked as critical in the certificate that led to creation of this
  100. * PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made
  101. * immutable. The PolicyNode pointers to parent and to children are initialized
  102. * to NULL, and the depth is set to zero; those values should be set by using
  103. * the pkix_PolicyNode_AddToParent function.
  104. *
  105. * PARAMETERS
  106. * "validPolicy"
  107. * Address of OID of the valid policy for the path. Must be non-NULL
  108. * "qualifierSet"
  109. * Address of List of CertPolicyQualifiers associated with the validpolicy.
  110. * May be NULL
  111. * "criticality"
  112. * Boolean indicator of whether the criticality should be set in this
  113. * PolicyNode
  114. * "expectedPolicySet"
  115. * Address of List of OIDs that would satisfy this policy in the next
  116. * certificate. Must be non-NULL
  117. * "pObject"
  118. * Address where the PolicyNode pointer will be stored. Must be non-NULL.
  119. * "plContext"
  120. * Platform-specific context pointer.
  121. * THREAD SAFETY:
  122. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  123. * RETURNS:
  124. * Returns NULL if the function succeeds.
  125. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  126. * Returns a Fatal Error if the function fails in an unrecoverable way.
  127. */
  128. PKIX_Error *
  129. pkix_PolicyNode_Create(
  130. PKIX_PL_OID *validPolicy,
  131. PKIX_List *qualifierSet,
  132. PKIX_Boolean criticality,
  133. PKIX_List *expectedPolicySet,
  134. PKIX_PolicyNode **pObject,
  135. void *plContext)
  136. {
  137. PKIX_PolicyNode *node = NULL;
  138. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create");
  139. PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject);
  140. PKIX_CHECK(PKIX_PL_Object_Alloc
  141. (PKIX_CERTPOLICYNODE_TYPE,
  142. sizeof (PKIX_PolicyNode),
  143. (PKIX_PL_Object **)&node,
  144. plContext),
  145. PKIX_COULDNOTCREATEPOLICYNODEOBJECT);
  146. PKIX_INCREF(validPolicy);
  147. node->validPolicy = validPolicy;
  148. PKIX_INCREF(qualifierSet);
  149. node->qualifierSet = qualifierSet;
  150. if (qualifierSet) {
  151. PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext),
  152. PKIX_LISTSETIMMUTABLEFAILED);
  153. }
  154. node->criticality = criticality;
  155. PKIX_INCREF(expectedPolicySet);
  156. node->expectedPolicySet = expectedPolicySet;
  157. PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext),
  158. PKIX_LISTSETIMMUTABLEFAILED);
  159. node->parent = NULL;
  160. node->children = NULL;
  161. node->depth = 0;
  162. *pObject = node;
  163. node = NULL;
  164. cleanup:
  165. PKIX_DECREF(node);
  166. PKIX_RETURN(CERTPOLICYNODE);
  167. }
  168. /*
  169. * FUNCTION: pkix_PolicyNode_AddToParent
  170. * DESCRIPTION:
  171. *
  172. * Adds the PolicyNode pointed to by "child" to the List of children of
  173. * the PolicyNode pointed to by "parentNode". If "parentNode" had a
  174. * NULL pointer for the List of children, a new List is created containing
  175. * "child". Otherwise "child" is appended to the existing List. The
  176. * parent field in "child" is set to "parent", and the depth field is
  177. * set to one more than the corresponding value in "parent".
  178. *
  179. * Depth, in this context, means distance from the root node, which
  180. * is at depth zero.
  181. *
  182. * PARAMETERS:
  183. * "parentNode"
  184. * Address of PolicyNode whose List of child PolicyNodes is to be
  185. * created or appended to. Must be non-NULL.
  186. * "child"
  187. * Address of PolicyNode to be added to parentNode's List. Must be
  188. * non-NULL.
  189. * "plContext"
  190. * Platform-specific context pointer.
  191. * THREAD SAFETY:
  192. * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  193. * RETURNS:
  194. * Returns NULL if the function succeeds.
  195. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  196. * Returns a Fatal Error if the function fails in an unrecoverable way.
  197. */
  198. PKIX_Error *
  199. pkix_PolicyNode_AddToParent(
  200. PKIX_PolicyNode *parentNode,
  201. PKIX_PolicyNode *child,
  202. void *plContext)
  203. {
  204. PKIX_List *listOfChildren = NULL;
  205. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_AddToParent");
  206. PKIX_NULLCHECK_TWO(parentNode, child);
  207. listOfChildren = parentNode->children;
  208. if (listOfChildren == NULL) {
  209. PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
  210. PKIX_LISTCREATEFAILED);
  211. parentNode->children = listOfChildren;
  212. }
  213. /*
  214. * Note: this link is not reference-counted. The link from parent
  215. * to child is counted (actually, the parent "owns" a List which
  216. * "owns" children), but the children do not "own" the parent.
  217. * Otherwise, there would be loops.
  218. */
  219. child->parent = parentNode;
  220. child->depth = 1 + (parentNode->depth);
  221. PKIX_CHECK(PKIX_List_AppendItem
  222. (listOfChildren, (PKIX_PL_Object *)child, plContext),
  223. PKIX_COULDNOTAPPENDCHILDTOPARENTSPOLICYNODELIST);
  224. PKIX_CHECK(PKIX_PL_Object_InvalidateCache
  225. ((PKIX_PL_Object *)parentNode, plContext),
  226. PKIX_OBJECTINVALIDATECACHEFAILED);
  227. PKIX_CHECK(PKIX_PL_Object_InvalidateCache
  228. ((PKIX_PL_Object *)child, plContext),
  229. PKIX_OBJECTINVALIDATECACHEFAILED);
  230. cleanup:
  231. PKIX_RETURN(CERTPOLICYNODE);
  232. }
  233. /*
  234. * FUNCTION: pkix_PolicyNode_Prune
  235. * DESCRIPTION:
  236. *
  237. * Prunes a tree below the PolicyNode whose address is pointed to by "node",
  238. * using the UInt32 value of "height" as the distance from the leaf level,
  239. * and storing at "pDelete" the Boolean value of whether this PolicyNode is,
  240. * after pruning, childless and should be pruned.
  241. *
  242. * Any PolicyNode at height 0 is allowed to survive. If the height is greater
  243. * than zero, pkix_PolicyNode_Prune is called recursively for each child of
  244. * the current PolicyNode. After this process, a node with no children
  245. * stores PKIX_TRUE in "pDelete" to indicate that it should be deleted.
  246. *
  247. * PARAMETERS:
  248. * "node"
  249. * Address of the PolicyNode to be pruned. Must be non-NULL.
  250. * "height"
  251. * UInt32 value for the distance from the leaf level
  252. * "pDelete"
  253. * Address to store the Boolean return value of PKIX_TRUE if this node
  254. * should be pruned, or PKIX_FALSE if there remains at least one
  255. * branch of the required height. Must be non-NULL.
  256. * "plContext"
  257. * Platform-specific context pointer.
  258. * THREAD SAFETY:
  259. * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  260. * RETURNS:
  261. * Returns NULL if the function succeeds.
  262. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  263. * Returns a Fatal Error if the function fails in an unrecoverable way.
  264. */
  265. PKIX_Error *
  266. pkix_PolicyNode_Prune(
  267. PKIX_PolicyNode *node,
  268. PKIX_UInt32 height,
  269. PKIX_Boolean *pDelete,
  270. void *plContext)
  271. {
  272. PKIX_Boolean childless = PKIX_FALSE;
  273. PKIX_Boolean shouldBePruned = PKIX_FALSE;
  274. PKIX_UInt32 listSize = 0;
  275. PKIX_UInt32 listIndex = 0;
  276. PKIX_PolicyNode *candidate = NULL;
  277. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Prune");
  278. PKIX_NULLCHECK_TWO(node, pDelete);
  279. /* Don't prune at the leaf */
  280. if (height == 0) {
  281. goto cleanup;
  282. }
  283. /* Above the bottom level, childless nodes get pruned */
  284. if (!(node->children)) {
  285. childless = PKIX_TRUE;
  286. goto cleanup;
  287. }
  288. /*
  289. * This node has children. If they are leaf nodes,
  290. * we know they will live. Otherwise, check them out.
  291. */
  292. if (height > 1) {
  293. PKIX_CHECK(PKIX_List_GetLength
  294. (node->children, &listSize, plContext),
  295. PKIX_LISTGETLENGTHFAILED);
  296. /*
  297. * By working backwards from the end of the list,
  298. * we avoid having to worry about possible
  299. * decreases in the size of the list, as we
  300. * delete items. The only nuisance is that since the
  301. * index is UInt32, we can't check for it to reach -1;
  302. * we have to use the 1-based index, rather than the
  303. * 0-based index that PKIX_List functions require.
  304. */
  305. for (listIndex = listSize; listIndex > 0; listIndex--) {
  306. PKIX_CHECK(PKIX_List_GetItem
  307. (node->children,
  308. (listIndex - 1),
  309. (PKIX_PL_Object **)&candidate,
  310. plContext),
  311. PKIX_LISTGETITEMFAILED);
  312. PKIX_CHECK(pkix_PolicyNode_Prune
  313. (candidate,
  314. height - 1,
  315. &shouldBePruned,
  316. plContext),
  317. PKIX_POLICYNODEPRUNEFAILED);
  318. if (shouldBePruned == PKIX_TRUE) {
  319. PKIX_CHECK(PKIX_List_DeleteItem
  320. (node->children,
  321. (listIndex - 1),
  322. plContext),
  323. PKIX_LISTDELETEITEMFAILED);
  324. }
  325. PKIX_DECREF(candidate);
  326. }
  327. }
  328. /* Prune if this node has *become* childless */
  329. PKIX_CHECK(PKIX_List_GetLength
  330. (node->children, &listSize, plContext),
  331. PKIX_LISTGETLENGTHFAILED);
  332. if (listSize == 0) {
  333. childless = PKIX_TRUE;
  334. }
  335. /*
  336. * Even if we did not change this node, or any of its children,
  337. * maybe a [great-]*grandchild was pruned.
  338. */
  339. PKIX_CHECK(PKIX_PL_Object_InvalidateCache
  340. ((PKIX_PL_Object *)node, plContext),
  341. PKIX_OBJECTINVALIDATECACHEFAILED);
  342. cleanup:
  343. *pDelete = childless;
  344. PKIX_DECREF(candidate);
  345. PKIX_RETURN(CERTPOLICYNODE);
  346. }
  347. /*
  348. * FUNCTION: pkix_SinglePolicyNode_ToString
  349. * DESCRIPTION:
  350. *
  351. * Creates a String representation of the attributes of the PolicyNode
  352. * pointed to by "node", other than its parents or children, and
  353. * stores the result at "pString".
  354. *
  355. * PARAMETERS:
  356. * "node"
  357. * Address of PolicyNode to be described by the string. Must be non-NULL.
  358. * "pString"
  359. * Address where object pointer will be stored. Must be non-NULL.
  360. * "plContext"
  361. * Platform-specific context pointer.
  362. * THREAD SAFETY:
  363. * Conditionally Thread Safe
  364. * (see Thread Safety Definitions in Programmer's Guide)
  365. * RETURNS:
  366. * Returns NULL if function succeeds
  367. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  368. * Returns a Fatal Error if the function fails in a fatal way
  369. */
  370. PKIX_Error *
  371. pkix_SinglePolicyNode_ToString(
  372. PKIX_PolicyNode *node,
  373. PKIX_PL_String **pString,
  374. void *plContext)
  375. {
  376. PKIX_PL_String *fmtString = NULL;
  377. PKIX_PL_String *validString = NULL;
  378. PKIX_PL_String *qualifierString = NULL;
  379. PKIX_PL_String *criticalityString = NULL;
  380. PKIX_PL_String *expectedString = NULL;
  381. PKIX_PL_String *outString = NULL;
  382. PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_ToString");
  383. PKIX_NULLCHECK_TWO(node, pString);
  384. PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
  385. PKIX_CHECK(PKIX_PL_String_Create
  386. (PKIX_ESCASCII,
  387. "{%s,%s,%s,%s,%d}",
  388. 0,
  389. &fmtString,
  390. plContext),
  391. PKIX_CANTCREATESTRING);
  392. PKIX_CHECK(PKIX_PL_Object_ToString
  393. ((PKIX_PL_Object *)(node->validPolicy),
  394. &validString,
  395. plContext),
  396. PKIX_OIDTOSTRINGFAILED);
  397. PKIX_CHECK(PKIX_PL_Object_ToString
  398. ((PKIX_PL_Object *)(node->expectedPolicySet),
  399. &expectedString,
  400. plContext),
  401. PKIX_LISTTOSTRINGFAILED);
  402. if (node->qualifierSet) {
  403. PKIX_CHECK(PKIX_PL_Object_ToString
  404. ((PKIX_PL_Object *)(node->qualifierSet),
  405. &qualifierString,
  406. plContext),
  407. PKIX_LISTTOSTRINGFAILED);
  408. } else {
  409. PKIX_CHECK(PKIX_PL_String_Create
  410. (PKIX_ESCASCII,
  411. "{}",
  412. 0,
  413. &qualifierString,
  414. plContext),
  415. PKIX_CANTCREATESTRING);
  416. }
  417. PKIX_CHECK(PKIX_PL_String_Create
  418. (PKIX_ESCASCII,
  419. (node->criticality)?"Critical":"Not Critical",
  420. 0,
  421. &criticalityString,
  422. plContext),
  423. PKIX_CANTCREATESTRING);
  424. PKIX_CHECK(PKIX_PL_Sprintf
  425. (&outString,
  426. plContext,
  427. fmtString,
  428. validString,
  429. qualifierString,
  430. criticalityString,
  431. expectedString,
  432. node->depth),
  433. PKIX_SPRINTFFAILED);
  434. *pString = outString;
  435. cleanup:
  436. PKIX_DECREF(fmtString);
  437. PKIX_DECREF(validString);
  438. PKIX_DECREF(qualifierString);
  439. PKIX_DECREF(criticalityString);
  440. PKIX_DECREF(expectedString);
  441. PKIX_RETURN(CERTPOLICYNODE);
  442. }
  443. /*
  444. * FUNCTION: pkix_PolicyNode_ToString_Helper
  445. * DESCRIPTION:
  446. *
  447. * Produces a String representation of a PolicyNode tree below the PolicyNode
  448. * pointed to by "rootNode", with each line of output prefixed by the String
  449. * pointed to by "indent", and stores the result at "pTreeString". It is
  450. * called recursively, with ever-increasing indentation, for successively
  451. * lower nodes on the tree.
  452. *
  453. * PARAMETERS:
  454. * "rootNode"
  455. * Address of PolicyNode subtree. Must be non-NULL.
  456. * "indent"
  457. * Address of String to be prefixed to each line of output. May be NULL
  458. * if no indentation is desired
  459. * "pTreeString"
  460. * Address where the resulting String will be stored; must be non-NULL
  461. * "plContext"
  462. * Platform-specific context pointer.
  463. * THREAD SAFETY:
  464. * Conditionally Thread Safe
  465. * (see Thread Safety Definitions in Programmer's Guide)
  466. * RETURNS:
  467. * Returns NULL if the function succeeds.
  468. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  469. * Returns a Fatal Error if the function fails in an unrecoverable way.
  470. */
  471. static PKIX_Error *
  472. pkix_PolicyNode_ToString_Helper(
  473. PKIX_PolicyNode *rootNode,
  474. PKIX_PL_String *indent,
  475. PKIX_PL_String **pTreeString,
  476. void *plContext)
  477. {
  478. PKIX_PL_String *nextIndentFormat = NULL;
  479. PKIX_PL_String *thisNodeFormat = NULL;
  480. PKIX_PL_String *childrenFormat = NULL;
  481. PKIX_PL_String *nextIndentString = NULL;
  482. PKIX_PL_String *resultString = NULL;
  483. PKIX_PL_String *thisItemString = NULL;
  484. PKIX_PL_String *childString = NULL;
  485. PKIX_PolicyNode *childNode = NULL;
  486. PKIX_UInt32 numberOfChildren = 0;
  487. PKIX_UInt32 childIndex = 0;
  488. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString_Helper");
  489. PKIX_NULLCHECK_TWO(rootNode, pTreeString);
  490. /* Create a string for this node */
  491. PKIX_CHECK(pkix_SinglePolicyNode_ToString
  492. (rootNode, &thisItemString, plContext),
  493. PKIX_ERRORINSINGLEPOLICYNODETOSTRING);
  494. if (indent) {
  495. PKIX_CHECK(PKIX_PL_String_Create
  496. (PKIX_ESCASCII,
  497. "%s%s",
  498. 0,
  499. &thisNodeFormat,
  500. plContext),
  501. PKIX_ERRORCREATINGFORMATSTRING);
  502. PKIX_CHECK(PKIX_PL_Sprintf
  503. (&resultString,
  504. plContext,
  505. thisNodeFormat,
  506. indent,
  507. thisItemString),
  508. PKIX_ERRORINSPRINTF);
  509. } else {
  510. PKIX_CHECK(PKIX_PL_String_Create
  511. (PKIX_ESCASCII,
  512. "%s",
  513. 0,
  514. &thisNodeFormat,
  515. plContext),
  516. PKIX_ERRORCREATINGFORMATSTRING);
  517. PKIX_CHECK(PKIX_PL_Sprintf
  518. (&resultString,
  519. plContext,
  520. thisNodeFormat,
  521. thisItemString),
  522. PKIX_ERRORINSPRINTF);
  523. }
  524. PKIX_DECREF(thisItemString);
  525. thisItemString = resultString;
  526. /* if no children, we are done */
  527. if (rootNode->children) {
  528. PKIX_CHECK(PKIX_List_GetLength
  529. (rootNode->children, &numberOfChildren, plContext),
  530. PKIX_LISTGETLENGTHFAILED);
  531. }
  532. if (numberOfChildren != 0) {
  533. /*
  534. * We create a string for each child in turn,
  535. * concatenating them to thisItemString.
  536. */
  537. /* Prepare an indent string for each child */
  538. if (indent) {
  539. PKIX_CHECK(PKIX_PL_String_Create
  540. (PKIX_ESCASCII,
  541. "%s. ",
  542. 0,
  543. &nextIndentFormat,
  544. plContext),
  545. PKIX_ERRORCREATINGFORMATSTRING);
  546. PKIX_CHECK(PKIX_PL_Sprintf
  547. (&nextIndentString,
  548. plContext,
  549. nextIndentFormat,
  550. indent),
  551. PKIX_ERRORINSPRINTF);
  552. } else {
  553. PKIX_CHECK(PKIX_PL_String_Create
  554. (PKIX_ESCASCII,
  555. ". ",
  556. 0,
  557. &nextIndentString,
  558. plContext),
  559. PKIX_ERRORCREATINGINDENTSTRING);
  560. }
  561. /* Prepare the format for concatenation. */
  562. PKIX_CHECK(PKIX_PL_String_Create
  563. (PKIX_ESCASCII,
  564. "%s\n%s",
  565. 0,
  566. &childrenFormat,
  567. plContext),
  568. PKIX_ERRORCREATINGFORMATSTRING);
  569. for (childIndex = 0;
  570. childIndex < numberOfChildren;
  571. childIndex++) {
  572. PKIX_CHECK(PKIX_List_GetItem
  573. (rootNode->children,
  574. childIndex,
  575. (PKIX_PL_Object **)&childNode,
  576. plContext),
  577. PKIX_LISTGETITEMFAILED);
  578. PKIX_CHECK(pkix_PolicyNode_ToString_Helper
  579. (childNode,
  580. nextIndentString,
  581. &childString,
  582. plContext),
  583. PKIX_ERRORCREATINGCHILDSTRING);
  584. PKIX_CHECK(PKIX_PL_Sprintf
  585. (&resultString,
  586. plContext,
  587. childrenFormat,
  588. thisItemString,
  589. childString),
  590. PKIX_ERRORINSPRINTF);
  591. PKIX_DECREF(childNode);
  592. PKIX_DECREF(childString);
  593. PKIX_DECREF(thisItemString);
  594. thisItemString = resultString;
  595. }
  596. }
  597. *pTreeString = thisItemString;
  598. cleanup:
  599. if (PKIX_ERROR_RECEIVED) {
  600. PKIX_DECREF(thisItemString);
  601. }
  602. PKIX_DECREF(nextIndentFormat);
  603. PKIX_DECREF(thisNodeFormat);
  604. PKIX_DECREF(childrenFormat);
  605. PKIX_DECREF(nextIndentString);
  606. PKIX_DECREF(childString);
  607. PKIX_DECREF(childNode);
  608. PKIX_RETURN(CERTPOLICYNODE);
  609. }
  610. /*
  611. * FUNCTION: pkix_PolicyNode_ToString
  612. * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
  613. */
  614. static PKIX_Error *
  615. pkix_PolicyNode_ToString(
  616. PKIX_PL_Object *object,
  617. PKIX_PL_String **pTreeString,
  618. void *plContext)
  619. {
  620. PKIX_PolicyNode *rootNode = NULL;
  621. PKIX_PL_String *resultString = NULL;
  622. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString");
  623. PKIX_NULLCHECK_TWO(object, pTreeString);
  624. PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
  625. PKIX_OBJECTNOTPOLICYNODE);
  626. rootNode = (PKIX_PolicyNode *)object;
  627. PKIX_CHECK(pkix_PolicyNode_ToString_Helper
  628. (rootNode, NULL, &resultString, plContext),
  629. PKIX_ERRORCREATINGSUBTREESTRING);
  630. *pTreeString = resultString;
  631. cleanup:
  632. PKIX_RETURN(CERTPOLICYNODE);
  633. }
  634. /*
  635. * FUNCTION: pkix_PolicyNode_Destroy
  636. * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
  637. */
  638. static PKIX_Error *
  639. pkix_PolicyNode_Destroy(
  640. PKIX_PL_Object *object,
  641. void *plContext)
  642. {
  643. PKIX_PolicyNode *node = NULL;
  644. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Destroy");
  645. PKIX_NULLCHECK_ONE(object);
  646. PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
  647. PKIX_OBJECTNOTPOLICYNODE);
  648. node = (PKIX_PolicyNode*)object;
  649. node->criticality = PKIX_FALSE;
  650. PKIX_DECREF(node->validPolicy);
  651. PKIX_DECREF(node->qualifierSet);
  652. PKIX_DECREF(node->expectedPolicySet);
  653. PKIX_DECREF(node->children);
  654. /*
  655. * Note: the link to parent is not reference-counted. See comment
  656. * in pkix_PolicyNode_AddToParent for more details.
  657. */
  658. node->parent = NULL;
  659. node->depth = 0;
  660. cleanup:
  661. PKIX_RETURN(CERTPOLICYNODE);
  662. }
  663. /*
  664. * FUNCTION: pkix_SinglePolicyNode_Hashcode
  665. * DESCRIPTION:
  666. *
  667. * Computes the hashcode of the attributes of the PolicyNode pointed to by
  668. * "node", other than its parents and children, and stores the result at
  669. * "pHashcode".
  670. *
  671. * PARAMETERS:
  672. * "node"
  673. * Address of PolicyNode to be hashcoded; must be non-NULL
  674. * "pHashcode"
  675. * Address where UInt32 result will be stored; must be non-NULL
  676. * "plContext"
  677. * Platform-specific context pointer.
  678. * THREAD SAFETY:
  679. * Conditionally Thread Safe
  680. * (see Thread Safety Definitions in Programmer's Guide)
  681. * RETURNS:
  682. * Returns NULL if function succeeds
  683. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  684. * Returns a Fatal Error if the function fails in a fatal way
  685. */
  686. static PKIX_Error *
  687. pkix_SinglePolicyNode_Hashcode(
  688. PKIX_PolicyNode *node,
  689. PKIX_UInt32 *pHashcode,
  690. void *plContext)
  691. {
  692. PKIX_UInt32 componentHash = 0;
  693. PKIX_UInt32 nodeHash = 0;
  694. PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Hashcode");
  695. PKIX_NULLCHECK_TWO(node, pHashcode);
  696. PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
  697. PKIX_HASHCODE
  698. (node->qualifierSet,
  699. &nodeHash,
  700. plContext,
  701. PKIX_FAILUREHASHINGLISTQUALIFIERSET);
  702. if (PKIX_TRUE == (node->criticality)) {
  703. nodeHash = 31*nodeHash + 0xff;
  704. } else {
  705. nodeHash = 31*nodeHash + 0x00;
  706. }
  707. PKIX_CHECK(PKIX_PL_Object_Hashcode
  708. ((PKIX_PL_Object *)node->validPolicy,
  709. &componentHash,
  710. plContext),
  711. PKIX_FAILUREHASHINGOIDVALIDPOLICY);
  712. nodeHash = 31*nodeHash + componentHash;
  713. PKIX_CHECK(PKIX_PL_Object_Hashcode
  714. ((PKIX_PL_Object *)node->expectedPolicySet,
  715. &componentHash,
  716. plContext),
  717. PKIX_FAILUREHASHINGLISTEXPECTEDPOLICYSET);
  718. nodeHash = 31*nodeHash + componentHash;
  719. *pHashcode = nodeHash;
  720. cleanup:
  721. PKIX_RETURN(CERTPOLICYNODE);
  722. }
  723. /*
  724. * FUNCTION: pkix_PolicyNode_Hashcode
  725. * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
  726. */
  727. static PKIX_Error *
  728. pkix_PolicyNode_Hashcode(
  729. PKIX_PL_Object *object,
  730. PKIX_UInt32 *pHashcode,
  731. void *plContext)
  732. {
  733. PKIX_PolicyNode *node = NULL;
  734. PKIX_UInt32 childrenHash = 0;
  735. PKIX_UInt32 nodeHash = 0;
  736. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Hashcode");
  737. PKIX_NULLCHECK_TWO(object, pHashcode);
  738. PKIX_CHECK(pkix_CheckType
  739. (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
  740. PKIX_OBJECTNOTPOLICYNODE);
  741. node = (PKIX_PolicyNode *)object;
  742. PKIX_CHECK(pkix_SinglePolicyNode_Hashcode
  743. (node, &nodeHash, plContext),
  744. PKIX_SINGLEPOLICYNODEHASHCODEFAILED);
  745. nodeHash = 31*nodeHash + (PKIX_UInt32)(node->parent);
  746. PKIX_HASHCODE
  747. (node->children,
  748. &childrenHash,
  749. plContext,
  750. PKIX_OBJECTHASHCODEFAILED);
  751. nodeHash = 31*nodeHash + childrenHash;
  752. *pHashcode = nodeHash;
  753. cleanup:
  754. PKIX_RETURN(CERTPOLICYNODE);
  755. }
  756. /*
  757. * FUNCTION: pkix_SinglePolicyNode_Equals
  758. * DESCRIPTION:
  759. *
  760. * Compares for equality the components of the PolicyNode pointed to by
  761. * "firstPN", other than its parents and children, with those of the
  762. * PolicyNode pointed to by "secondPN" and stores the result at "pResult"
  763. * (PKIX_TRUE if equal; PKIX_FALSE if not).
  764. *
  765. * PARAMETERS:
  766. * "firstPN"
  767. * Address of first of the PolicyNodes to be compared; must be non-NULL
  768. * "secondPN"
  769. * Address of second of the PolicyNodes to be compared; must be non-NULL
  770. * "pResult"
  771. * Address where Boolean will be stored; must be non-NULL
  772. * "plContext"
  773. * Platform-specific context pointer.
  774. * THREAD SAFETY:
  775. * Conditionally Thread Safe
  776. * (see Thread Safety Definitions in Programmer's Guide)
  777. * RETURNS:
  778. * Returns NULL if function succeeds
  779. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  780. * Returns a Fatal Error if the function fails in a fatal way
  781. */
  782. static PKIX_Error *
  783. pkix_SinglePolicyNode_Equals(
  784. PKIX_PolicyNode *firstPN,
  785. PKIX_PolicyNode *secondPN,
  786. PKIX_Boolean *pResult,
  787. void *plContext)
  788. {
  789. PKIX_Boolean compResult = PKIX_FALSE;
  790. PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Equals");
  791. PKIX_NULLCHECK_THREE(firstPN, secondPN, pResult);
  792. /* If both references are identical, they must be equal */
  793. if (firstPN == secondPN) {
  794. compResult = PKIX_TRUE;
  795. goto cleanup;
  796. }
  797. /*
  798. * It seems we have to do the comparisons. Do
  799. * the easiest ones first.
  800. */
  801. if ((firstPN->criticality) != (secondPN->criticality)) {
  802. goto cleanup;
  803. }
  804. if ((firstPN->depth) != (secondPN->depth)) {
  805. goto cleanup;
  806. }
  807. PKIX_EQUALS
  808. (firstPN->qualifierSet,
  809. secondPN->qualifierSet,
  810. &compResult,
  811. plContext,
  812. PKIX_OBJECTEQUALSFAILED);
  813. if (compResult == PKIX_FALSE) {
  814. goto cleanup;
  815. }
  816. /* These fields must be non-NULL */
  817. PKIX_NULLCHECK_TWO(firstPN->validPolicy, secondPN->validPolicy);
  818. PKIX_EQUALS
  819. (firstPN->validPolicy,
  820. secondPN->validPolicy,
  821. &compResult,
  822. plContext,
  823. PKIX_OBJECTEQUALSFAILED);
  824. if (compResult == PKIX_FALSE) {
  825. goto cleanup;
  826. }
  827. /* These fields must be non-NULL */
  828. PKIX_NULLCHECK_TWO
  829. (firstPN->expectedPolicySet, secondPN->expectedPolicySet);
  830. PKIX_EQUALS
  831. (firstPN->expectedPolicySet,
  832. secondPN->expectedPolicySet,
  833. &compResult,
  834. plContext,
  835. PKIX_OBJECTEQUALSFAILEDONEXPECTEDPOLICYSETS);
  836. cleanup:
  837. *pResult = compResult;
  838. PKIX_RETURN(CERTPOLICYNODE);
  839. }
  840. /*
  841. * FUNCTION: pkix_PolicyNode_Equals
  842. * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
  843. */
  844. static PKIX_Error *
  845. pkix_PolicyNode_Equals(
  846. PKIX_PL_Object *firstObject,
  847. PKIX_PL_Object *secondObject,
  848. PKIX_Boolean *pResult,
  849. void *plContext)
  850. {
  851. PKIX_PolicyNode *firstPN = NULL;
  852. PKIX_PolicyNode *secondPN = NULL;
  853. PKIX_UInt32 secondType;
  854. PKIX_Boolean compResult = PKIX_FALSE;
  855. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Equals");
  856. PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
  857. /* test that firstObject is a PolicyNode */
  858. PKIX_CHECK(pkix_CheckType
  859. (firstObject, PKIX_CERTPOLICYNODE_TYPE, plContext),
  860. PKIX_FIRSTOBJECTNOTPOLICYNODE);
  861. /*
  862. * Since we know firstObject is a PolicyNode,
  863. * if both references are identical, they must be equal
  864. */
  865. if (firstObject == secondObject){
  866. compResult = PKIX_TRUE;
  867. goto cleanup;
  868. }
  869. /*
  870. * If secondObject isn't a PolicyNode, we
  871. * don't throw an error. We simply return FALSE.
  872. */
  873. PKIX_CHECK(PKIX_PL_Object_GetType
  874. (secondObject, &secondType, plContext),
  875. PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
  876. if (secondType != PKIX_CERTPOLICYNODE_TYPE) {
  877. goto cleanup;
  878. }
  879. /*
  880. * Oh, well, we have to do the comparisons. Do
  881. * the easiest ones first.
  882. */
  883. firstPN = (PKIX_PolicyNode *)firstObject;
  884. secondPN = (PKIX_PolicyNode *)secondObject;
  885. /*
  886. * We don't require the parents to be identical. In the
  887. * course of traversing the tree, we will have checked the
  888. * attributes of the parent nodes, and checking the lists
  889. * of children will determine whether they match.
  890. */
  891. PKIX_EQUALS
  892. (firstPN->children,
  893. secondPN->children,
  894. &compResult,
  895. plContext,
  896. PKIX_OBJECTEQUALSFAILEDONCHILDREN);
  897. if (compResult == PKIX_FALSE) {
  898. goto cleanup;
  899. }
  900. PKIX_CHECK(pkix_SinglePolicyNode_Equals
  901. (firstPN, secondPN, &compResult, plContext),
  902. PKIX_SINGLEPOLICYNODEEQUALSFAILED);
  903. cleanup:
  904. *pResult = compResult;
  905. PKIX_RETURN(CERTPOLICYNODE);
  906. }
  907. /*
  908. * FUNCTION: pkix_PolicyNode_DuplicateHelper
  909. * DESCRIPTION:
  910. *
  911. * Duplicates the PolicyNode whose address is pointed to by "original",
  912. * and stores the result at "pNewNode", if a non-NULL pointer is provided
  913. * for "pNewNode". In addition, the created PolicyNode is added as a child
  914. * to "parent", if a non-NULL pointer is provided for "parent". Then this
  915. * function is called recursively to duplicate each of the children of
  916. * "original". At the top level this function is called with a null
  917. * "parent" and a non-NULL "pNewNode". Below the top level "parent" will
  918. * be non-NULL and "pNewNode" will be NULL.
  919. *
  920. * PARAMETERS:
  921. * "original"
  922. * Address of PolicyNode to be copied; must be non-NULL
  923. * "parent"
  924. * Address of PolicyNode to which the created node is to be added as a
  925. * child; NULL for the top-level call and non-NULL below the top level
  926. * "pNewNode"
  927. * Address to store the node created; should be NULL if "parent" is
  928. * non-NULL and vice versa
  929. * "plContext"
  930. * Platform-specific context pointer.
  931. * THREAD SAFETY:
  932. * Conditionally Thread Safe
  933. * (see Thread Safety Definitions in Programmer's Guide)
  934. * RETURNS:
  935. * Returns NULL if function succeeds
  936. * Returns a PolicyNode Error if the function fails in a non-fatal way.
  937. * Returns a Fatal Error if the function fails in a fatal way
  938. */
  939. static PKIX_Error *
  940. pkix_PolicyNode_DuplicateHelper(
  941. PKIX_PolicyNode *original,
  942. PKIX_PolicyNode *parent,
  943. PKIX_PolicyNode **pNewNode,
  944. void *plContext)
  945. {
  946. PKIX_UInt32 numChildren = 0;
  947. PKIX_UInt32 childIndex = 0;
  948. PKIX_List *children = NULL; /* List of PKIX_PolicyNode */
  949. PKIX_PolicyNode *copy = NULL;
  950. PKIX_PolicyNode *child = NULL;
  951. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_DuplicateHelper");
  952. PKIX_NULLCHECK_THREE
  953. (original, original->validPolicy, original->expectedPolicySet);
  954. /*
  955. * These components are immutable, so copying the pointers
  956. * is sufficient. The create function increments the reference
  957. * counts as it stores the pointers into the new object.
  958. */
  959. PKIX_CHECK(pkix_PolicyNode_Create
  960. (original->validPolicy,
  961. original->qualifierSet,
  962. original->criticality,
  963. original->expectedPolicySet,
  964. &copy,
  965. plContext),
  966. PKIX_POLICYNODECREATEFAILED);
  967. if (parent) {
  968. PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, copy, plContext),
  969. PKIX_POLICYNODEADDTOPARENTFAILED);
  970. }
  971. /* Are there any children to duplicate? */
  972. children = original->children;
  973. if (children) {
  974. PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
  975. PKIX_LISTGETLENGTHFAILED);
  976. }
  977. for (childIndex = 0; childIndex < numChildren; childIndex++) {
  978. PKIX_CHECK(PKIX_List_GetItem
  979. (children,
  980. childIndex,
  981. (PKIX_PL_Object **)&child,
  982. plContext),
  983. PKIX_LISTGETITEMFAILED);
  984. PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
  985. (child, copy, NULL, plContext),
  986. PKIX_POLICYNODEDUPLICATEHELPERFAILED);
  987. PKIX_DECREF(child);
  988. }
  989. if (pNewNode) {
  990. *pNewNode = copy;
  991. copy = NULL; /* no DecRef if we give our handle away */
  992. }
  993. cleanup:
  994. PKIX_DECREF(copy);
  995. PKIX_DECREF(child);
  996. PKIX_RETURN(CERTPOLICYNODE);
  997. }
  998. /*
  999. * FUNCTION: pkix_PolicyNode_Duplicate
  1000. * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
  1001. */
  1002. static PKIX_Error *
  1003. pkix_PolicyNode_Duplicate(
  1004. PKIX_PL_Object *object,
  1005. PKIX_PL_Object **pNewObject,
  1006. void *plContext)
  1007. {
  1008. PKIX_PolicyNode *original = NULL;
  1009. PKIX_PolicyNode *copy = NULL;
  1010. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Duplicate");
  1011. PKIX_NULLCHECK_TWO(object, pNewObject);
  1012. PKIX_CHECK(pkix_CheckType
  1013. (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
  1014. PKIX_OBJECTNOTPOLICYNODE);
  1015. original = (PKIX_PolicyNode *)object;
  1016. PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
  1017. (original, NULL, &copy, plContext),
  1018. PKIX_POLICYNODEDUPLICATEHELPERFAILED);
  1019. *pNewObject = (PKIX_PL_Object *)copy;
  1020. cleanup:
  1021. PKIX_RETURN(CERTPOLICYNODE);
  1022. }
  1023. /*
  1024. * FUNCTION: pkix_PolicyNode_RegisterSelf
  1025. * DESCRIPTION:
  1026. *
  1027. * Registers PKIX_CERTPOLICYNODE_TYPE and its related
  1028. * functions with systemClasses[]
  1029. *
  1030. * THREAD SAFETY:
  1031. * Not Thread Safe - for performance and complexity reasons
  1032. *
  1033. * Since this function is only called by PKIX_PL_Initialize,
  1034. * which should only be called once, it is acceptable that
  1035. * this function is not thread-safe.
  1036. */
  1037. PKIX_Error *
  1038. pkix_PolicyNode_RegisterSelf(void *plContext)
  1039. {
  1040. extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
  1041. pkix_ClassTable_Entry entry;
  1042. PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_RegisterSelf");
  1043. entry.description = "PolicyNode";
  1044. entry.objCounter = 0;
  1045. entry.typeObjectSize = sizeof(PKIX_PolicyNode);
  1046. entry.destructor = pkix_PolicyNode_Destroy;
  1047. entry.equalsFunction = pkix_PolicyNode_Equals;
  1048. entry.hashcodeFunction = pkix_PolicyNode_Hashcode;
  1049. entry.toStringFunction = pkix_PolicyNode_ToString;
  1050. entry.comparator = NULL;
  1051. entry.duplicateFunction = pkix_PolicyNode_Duplicate;
  1052. systemClasses[PKIX_CERTPOLICYNODE_TYPE] = entry;
  1053. PKIX_RETURN(CERTPOLICYNODE);
  1054. }
  1055. /* --Public-PolicyNode-Functions----------------------------------- */
  1056. /*
  1057. * FUNCTION: PKIX_PolicyNode_GetChildren
  1058. * (see description of this function in pkix_results.h)
  1059. */
  1060. PKIX_Error *
  1061. PKIX_PolicyNode_GetChildren(
  1062. PKIX_PolicyNode *node,
  1063. PKIX_List **pChildren, /* list of PKIX_PolicyNode */
  1064. void *plContext)
  1065. {
  1066. PKIX_List *children = NULL;
  1067. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetChildren");
  1068. PKIX_NULLCHECK_TWO(node, pChildren);
  1069. PKIX_INCREF(node->children);
  1070. children = node->children;
  1071. if (!children) {
  1072. PKIX_CHECK(PKIX_List_Create(&children, plContext),
  1073. PKIX_LISTCREATEFAILED);
  1074. }
  1075. PKIX_CHECK(PKIX_List_SetImmutable(children, plContext),
  1076. PKIX_LISTSETIMMUTABLEFAILED);
  1077. *pChildren = children;
  1078. cleanup:
  1079. if (PKIX_ERROR_RECEIVED) {
  1080. PKIX_DECREF(children);
  1081. }
  1082. PKIX_RETURN(CERTPOLICYNODE);
  1083. }
  1084. /*
  1085. * FUNCTION: PKIX_PolicyNode_GetParent
  1086. * (see description of this function in pkix_results.h)
  1087. */
  1088. PKIX_Error *
  1089. PKIX_PolicyNode_GetParent(
  1090. PKIX_PolicyNode *node,
  1091. PKIX_PolicyNode **pParent,
  1092. void *plContext)
  1093. {
  1094. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetParent");
  1095. PKIX_NULLCHECK_TWO(node, pParent);
  1096. PKIX_INCREF(node->parent);
  1097. *pParent = node->parent;
  1098. cleanup:
  1099. PKIX_RETURN(CERTPOLICYNODE);
  1100. }
  1101. /*
  1102. * FUNCTION: PKIX_PolicyNode_GetValidPolicy
  1103. * (see description of this function in pkix_results.h)
  1104. */
  1105. PKIX_Error *
  1106. PKIX_PolicyNode_GetValidPolicy(
  1107. PKIX_PolicyNode *node,
  1108. PKIX_PL_OID **pValidPolicy,
  1109. void *plContext)
  1110. {
  1111. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetValidPolicy");
  1112. PKIX_NULLCHECK_TWO(node, pValidPolicy);
  1113. PKIX_INCREF(node->validPolicy);
  1114. *pValidPolicy = node->validPolicy;
  1115. cleanup:
  1116. PKIX_RETURN(CERTPOLICYNODE);
  1117. }
  1118. /*
  1119. * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers
  1120. * (see description of this function in pkix_results.h)
  1121. */
  1122. PKIX_Error *
  1123. PKIX_PolicyNode_GetPolicyQualifiers(
  1124. PKIX_PolicyNode *node,
  1125. PKIX_List **pQualifiers, /* list of PKIX_PL_CertPolicyQualifier */
  1126. void *plContext)
  1127. {
  1128. PKIX_List *qualifiers = NULL;
  1129. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetPolicyQualifiers");
  1130. PKIX_NULLCHECK_TWO(node, pQualifiers);
  1131. PKIX_INCREF(node->qualifierSet);
  1132. qualifiers = node->qualifierSet;
  1133. if (!qualifiers) {
  1134. PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
  1135. PKIX_LISTCREATEFAILED);
  1136. }
  1137. PKIX_CHECK(PKIX_List_SetImmutable(qualifiers, plContext),
  1138. PKIX_LISTSETIMMUTABLEFAILED);
  1139. *pQualifiers = qualifiers;
  1140. cleanup:
  1141. PKIX_RETURN(CERTPOLICYNODE);
  1142. }
  1143. /*
  1144. * FUNCTION: PKIX_PolicyNode_GetExpectedPolicies
  1145. * (see description of this function in pkix_results.h)
  1146. */
  1147. PKIX_Error *
  1148. PKIX_PolicyNode_GetExpectedPolicies(
  1149. PKIX_PolicyNode *node,
  1150. PKIX_List **pExpPolicies, /* list of PKIX_PL_OID */
  1151. void *plContext)
  1152. {
  1153. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetExpectedPolicies");
  1154. PKIX_NULLCHECK_TWO(node, pExpPolicies);
  1155. PKIX_INCREF(node->expectedPolicySet);
  1156. *pExpPolicies = node->expectedPolicySet;
  1157. cleanup:
  1158. PKIX_RETURN(CERTPOLICYNODE);
  1159. }
  1160. /*
  1161. * FUNCTION: PKIX_PolicyNode_IsCritical
  1162. * (see description of this function in pkix_results.h)
  1163. */
  1164. PKIX_Error *
  1165. PKIX_PolicyNode_IsCritical(
  1166. PKIX_PolicyNode *node,
  1167. PKIX_Boolean *pCritical,
  1168. void *plContext)
  1169. {
  1170. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_IsCritical");
  1171. PKIX_NULLCHECK_TWO(node, pCritical);
  1172. *pCritical = node->criticality;
  1173. PKIX_RETURN(CERTPOLICYNODE);
  1174. }
  1175. /*
  1176. * FUNCTION: PKIX_PolicyNode_GetDepth
  1177. * (see description of this function in pkix_results.h)
  1178. */
  1179. PKIX_Error *
  1180. PKIX_PolicyNode_GetDepth(
  1181. PKIX_PolicyNode *node,
  1182. PKIX_UInt32 *pDepth,
  1183. void *plContext)
  1184. {
  1185. PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetDepth");
  1186. PKIX_NULLCHECK_TWO(node, pDepth);
  1187. *pDepth = node->depth;
  1188. PKIX_RETURN(CERTPOLICYNODE);
  1189. }