PageRenderTime 61ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://bitbucket.org/mkato/mozilla-1.9.0-win64
C | 3599 lines | 2283 code | 658 blank | 658 comment | 294 complexity | a2cff297d4276fb777167a69d835656c MD5 | raw file
Possible License(s): LGPL-3.0, MIT, BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-2.0, LGPL-2.1
  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_cert.c
  39. *
  40. * Certificate Object Functions
  41. *
  42. */
  43. #include "pkix_pl_cert.h"
  44. extern PKIX_PL_HashTable *cachedCertSigTable;
  45. /* --Private-Cert-Functions------------------------------------- */
  46. /*
  47. * FUNCTION: pkix_pl_Cert_IsExtensionCritical
  48. * DESCRIPTION:
  49. *
  50. * Checks the Cert specified by "cert" to determine whether the extension
  51. * whose tag is the UInt32 value given by "tag" is marked as a critical
  52. * extension, and stores the result in "pCritical".
  53. *
  54. * Tags are the index into the table "oids" of SECOidData defined in the
  55. * file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are
  56. * are defined in secoidt.h for most of the table entries.
  57. *
  58. * If the specified tag is invalid (not in the list of tags) or if the
  59. * extension is not found in the certificate, PKIX_FALSE is stored.
  60. *
  61. * PARAMETERS
  62. * "cert"
  63. * Address of Cert whose extensions are to be examined. Must be non-NULL.
  64. * "tag"
  65. * The UInt32 value of the tag for the extension whose criticality is
  66. * to be determined
  67. * "pCritical"
  68. * Address where the Boolean value will be stored. Must be non-NULL.
  69. * "plContext"
  70. * Platform-specific context pointer.
  71. * THREAD SAFETY:
  72. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  73. * RETURNS:
  74. * Returns NULL if the function succeeds.
  75. * Returns a Fatal Error if the function fails in an unrecoverable way.
  76. */
  77. static PKIX_Error *
  78. pkix_pl_Cert_IsExtensionCritical(
  79. PKIX_PL_Cert *cert,
  80. PKIX_UInt32 tag,
  81. PKIX_Boolean *pCritical,
  82. void *plContext)
  83. {
  84. PKIX_Boolean criticality = PKIX_FALSE;
  85. CERTCertExtension **extensions = NULL;
  86. SECStatus rv;
  87. PKIX_ENTER(CERT, "pkix_pl_Cert_IsExtensionCritical");
  88. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCritical);
  89. extensions = cert->nssCert->extensions;
  90. PKIX_NULLCHECK_ONE(extensions);
  91. PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n");
  92. rv = CERT_GetExtenCriticality(extensions, tag, &criticality);
  93. if (SECSuccess == rv) {
  94. *pCritical = criticality;
  95. } else {
  96. *pCritical = PKIX_FALSE;
  97. }
  98. PKIX_RETURN(CERT);
  99. }
  100. /*
  101. * FUNCTION: pkix_pl_Cert_DecodePolicyInfo
  102. * DESCRIPTION:
  103. *
  104. * Decodes the contents of the CertificatePolicy extension in the
  105. * CERTCertificate pointed to by "nssCert", to create a List of
  106. * CertPolicyInfos, which is stored at the address "pCertPolicyInfos".
  107. * A CERTCertificate contains the DER representation of the Cert.
  108. * If this certificate does not have a CertificatePolicy extension,
  109. * NULL will be stored. If a List is returned, it will be immutable.
  110. *
  111. * PARAMETERS
  112. * "nssCert"
  113. * Address of the Cert data whose extension is to be examined. Must be
  114. * non-NULL.
  115. * "pCertPolicyInfos"
  116. * Address where the List of CertPolicyInfos will be stored. Must be
  117. * non-NULL.
  118. * "plContext"
  119. * Platform-specific context pointer.
  120. * THREAD SAFETY:
  121. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  122. * RETURNS:
  123. * Returns NULL if the function succeeds.
  124. * Returns a Cert Error if the function fails in a non-fatal way.
  125. * Returns a Fatal Error if the function fails in an unrecoverable way.
  126. */
  127. static PKIX_Error *
  128. pkix_pl_Cert_DecodePolicyInfo(
  129. CERTCertificate *nssCert,
  130. PKIX_List **pCertPolicyInfos,
  131. void *plContext)
  132. {
  133. SECStatus rv;
  134. SECItem encodedCertPolicyInfo;
  135. /* Allocated in the arena; freed in CERT_Destroy... */
  136. CERTCertificatePolicies *certPol = NULL;
  137. CERTPolicyInfo **policyInfos = NULL;
  138. CERTPolicyInfo *policyInfo = NULL;
  139. CERTPolicyQualifier **policyQualifiers = NULL;
  140. CERTPolicyQualifier *policyQualifier = NULL;
  141. /* Holder for the return value */
  142. PKIX_List *infos = NULL;
  143. char *oidAscii = NULL;
  144. PKIX_PL_OID *pkixOID = NULL;
  145. PKIX_List *qualifiers = NULL;
  146. PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL;
  147. PKIX_PL_CertPolicyQualifier *certPolicyQualifier = NULL;
  148. PKIX_PL_ByteArray *qualifierArray = NULL;
  149. PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyInfo");
  150. PKIX_NULLCHECK_TWO(nssCert, pCertPolicyInfos);
  151. /* get PolicyInfo as a SECItem */
  152. PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
  153. rv = CERT_FindCertExtension
  154. (nssCert,
  155. SEC_OID_X509_CERTIFICATE_POLICIES,
  156. &encodedCertPolicyInfo);
  157. if (SECSuccess != rv) {
  158. *pCertPolicyInfos = NULL;
  159. goto cleanup;
  160. }
  161. /* translate PolicyInfo to CERTCertificatePolicies */
  162. PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n");
  163. certPol = CERT_DecodeCertificatePoliciesExtension
  164. (&encodedCertPolicyInfo);
  165. PORT_Free(encodedCertPolicyInfo.data);
  166. if (NULL == certPol) {
  167. PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED);
  168. }
  169. /*
  170. * Check whether there are any policyInfos, so we can
  171. * avoid creating an unnecessary List
  172. */
  173. policyInfos = certPol->policyInfos;
  174. if (!policyInfos) {
  175. *pCertPolicyInfos = NULL;
  176. goto cleanup;
  177. }
  178. /* create a List of CertPolicyInfo Objects */
  179. PKIX_CHECK(PKIX_List_Create(&infos, plContext),
  180. PKIX_LISTCREATEFAILED);
  181. /*
  182. * Traverse the CERTCertificatePolicies structure,
  183. * building each PKIX_PL_CertPolicyInfo object in turn
  184. */
  185. while (*policyInfos != NULL) {
  186. policyInfo = *policyInfos;
  187. policyQualifiers = policyInfo->policyQualifiers;
  188. if (policyQualifiers) {
  189. /* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */
  190. PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
  191. PKIX_LISTCREATEFAILED);
  192. while (*policyQualifiers != NULL) {
  193. policyQualifier = *policyQualifiers;
  194. /* create the qualifier's OID object */
  195. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  196. (&(policyQualifier->qualifierID),
  197. &oidAscii,
  198. plContext),
  199. PKIX_OIDBYTES2ASCIIFAILED);
  200. PKIX_CHECK(PKIX_PL_OID_Create
  201. (oidAscii, &pkixOID, plContext),
  202. PKIX_OIDCREATEFAILED);
  203. /* create qualifier's ByteArray object */
  204. PKIX_CHECK(PKIX_PL_ByteArray_Create
  205. (policyQualifier->qualifierValue.data,
  206. policyQualifier->qualifierValue.len,
  207. &qualifierArray,
  208. plContext),
  209. PKIX_BYTEARRAYCREATEFAILED);
  210. /* create a CertPolicyQualifier object */
  211. PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create
  212. (pkixOID,
  213. qualifierArray,
  214. &certPolicyQualifier,
  215. plContext),
  216. PKIX_CERTPOLICYQUALIFIERCREATEFAILED);
  217. PKIX_CHECK(PKIX_List_AppendItem
  218. (qualifiers,
  219. (PKIX_PL_Object *)certPolicyQualifier,
  220. plContext),
  221. PKIX_LISTAPPENDITEMFAILED);
  222. PKIX_FREE(oidAscii);
  223. PKIX_DECREF(pkixOID);
  224. PKIX_DECREF(qualifierArray);
  225. PKIX_DECREF(certPolicyQualifier);
  226. policyQualifiers++;
  227. }
  228. PKIX_CHECK(PKIX_List_SetImmutable
  229. (qualifiers, plContext),
  230. PKIX_LISTSETIMMUTABLEFAILED);
  231. }
  232. /*
  233. * Create an OID object pkixOID from policyInfo->policyID.
  234. * (The CERTPolicyInfo structure has an oid field, but it
  235. * is of type SECOidTag. This function wants a SECItem.)
  236. */
  237. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  238. (&(policyInfo->policyID), &oidAscii, plContext),
  239. PKIX_OIDBYTES2ASCIIFAILED);
  240. PKIX_CHECK(PKIX_PL_OID_Create
  241. (oidAscii, &pkixOID, plContext),
  242. PKIX_OIDCREATEFAILED);
  243. /* Create a CertPolicyInfo object */
  244. PKIX_CHECK(pkix_pl_CertPolicyInfo_Create
  245. (pkixOID, qualifiers, &certPolicyInfo, plContext),
  246. PKIX_CERTPOLICYINFOCREATEFAILED);
  247. /* Append the new CertPolicyInfo object to the list */
  248. PKIX_CHECK(PKIX_List_AppendItem
  249. (infos, (PKIX_PL_Object *)certPolicyInfo, plContext),
  250. PKIX_LISTAPPENDITEMFAILED);
  251. PKIX_FREE(oidAscii);
  252. PKIX_DECREF(pkixOID);
  253. PKIX_DECREF(qualifiers);
  254. PKIX_DECREF(certPolicyInfo);
  255. policyInfos++;
  256. }
  257. /*
  258. * If there were no policies, we went straight to
  259. * cleanup, so we don't have to NULLCHECK infos.
  260. */
  261. PKIX_CHECK(PKIX_List_SetImmutable(infos, plContext),
  262. PKIX_LISTSETIMMUTABLEFAILED);
  263. *pCertPolicyInfos = infos;
  264. infos = NULL;
  265. cleanup:
  266. if (certPol) {
  267. PKIX_CERT_DEBUG
  268. ("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n");
  269. CERT_DestroyCertificatePoliciesExtension(certPol);
  270. }
  271. PKIX_FREE(oidAscii);
  272. PKIX_DECREF(infos);
  273. PKIX_DECREF(pkixOID);
  274. PKIX_DECREF(qualifiers);
  275. PKIX_DECREF(certPolicyInfo);
  276. PKIX_DECREF(certPolicyQualifier);
  277. PKIX_DECREF(qualifierArray);
  278. PKIX_RETURN(CERT);
  279. }
  280. /*
  281. * FUNCTION: pkix_pl_Cert_DecodePolicyMapping
  282. * DESCRIPTION:
  283. *
  284. * Decodes the contents of the PolicyMapping extension of the CERTCertificate
  285. * pointed to by "nssCert", storing the resulting List of CertPolicyMaps at
  286. * the address pointed to by "pCertPolicyMaps". If this certificate does not
  287. * have a PolicyMapping extension, NULL will be stored. If a List is returned,
  288. * it will be immutable.
  289. *
  290. * PARAMETERS
  291. * "nssCert"
  292. * Address of the Cert data whose extension is to be examined. Must be
  293. * non-NULL.
  294. * "pCertPolicyMaps"
  295. * Address where the List of CertPolicyMaps will be stored. Must be
  296. * non-NULL.
  297. * "plContext"
  298. * Platform-specific context pointer.
  299. * THREAD SAFETY:
  300. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  301. * RETURNS:
  302. * Returns NULL if the function succeeds.
  303. * Returns a Cert Error if the function fails in a non-fatal way.
  304. * Returns a Fatal Error if the function fails in an unrecoverable way.
  305. */
  306. static PKIX_Error *
  307. pkix_pl_Cert_DecodePolicyMapping(
  308. CERTCertificate *nssCert,
  309. PKIX_List **pCertPolicyMaps,
  310. void *plContext)
  311. {
  312. SECStatus rv;
  313. SECItem encodedCertPolicyMaps;
  314. /* Allocated in the arena; freed in CERT_Destroy... */
  315. CERTCertificatePolicyMappings *certPolMaps = NULL;
  316. CERTPolicyMap **policyMaps = NULL;
  317. CERTPolicyMap *policyMap = NULL;
  318. /* Holder for the return value */
  319. PKIX_List *maps = NULL;
  320. char *issuerPolicyOIDAscii = NULL;
  321. char *subjectPolicyOIDAscii = NULL;
  322. PKIX_PL_OID *issuerDomainOID = NULL;
  323. PKIX_PL_OID *subjectDomainOID = NULL;
  324. PKIX_PL_CertPolicyMap *certPolicyMap = NULL;
  325. PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyMapping");
  326. PKIX_NULLCHECK_TWO(nssCert, pCertPolicyMaps);
  327. /* get PolicyMappings as a SECItem */
  328. PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
  329. rv = CERT_FindCertExtension
  330. (nssCert, SEC_OID_X509_POLICY_MAPPINGS, &encodedCertPolicyMaps);
  331. if (SECSuccess != rv) {
  332. *pCertPolicyMaps = NULL;
  333. goto cleanup;
  334. }
  335. /* translate PolicyMaps to CERTCertificatePolicyMappings */
  336. certPolMaps = CERT_DecodePolicyMappingsExtension
  337. (&encodedCertPolicyMaps);
  338. PORT_Free(encodedCertPolicyMaps.data);
  339. if (!certPolMaps) {
  340. PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED);
  341. }
  342. PKIX_NULLCHECK_ONE(certPolMaps->policyMaps);
  343. policyMaps = certPolMaps->policyMaps;
  344. /* create a List of CertPolicyMap Objects */
  345. PKIX_CHECK(PKIX_List_Create(&maps, plContext),
  346. PKIX_LISTCREATEFAILED);
  347. /*
  348. * Traverse the CERTCertificatePolicyMappings structure,
  349. * building each CertPolicyMap object in turn
  350. */
  351. do {
  352. policyMap = *policyMaps;
  353. /* create the OID for the issuer Domain Policy */
  354. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  355. (&(policyMap->issuerDomainPolicy),
  356. &issuerPolicyOIDAscii,
  357. plContext),
  358. PKIX_OIDBYTES2ASCIIFAILED);
  359. PKIX_CHECK(PKIX_PL_OID_Create
  360. (issuerPolicyOIDAscii, &issuerDomainOID, plContext),
  361. PKIX_OIDCREATEFAILED);
  362. /* create the OID for the subject Domain Policy */
  363. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  364. (&(policyMap->subjectDomainPolicy),
  365. &subjectPolicyOIDAscii,
  366. plContext),
  367. PKIX_OIDBYTES2ASCIIFAILED);
  368. PKIX_CHECK(PKIX_PL_OID_Create
  369. (subjectPolicyOIDAscii, &subjectDomainOID, plContext),
  370. PKIX_OIDCREATEFAILED);
  371. /* create the CertPolicyMap */
  372. PKIX_CHECK(pkix_pl_CertPolicyMap_Create
  373. (issuerDomainOID,
  374. subjectDomainOID,
  375. &certPolicyMap,
  376. plContext),
  377. PKIX_CERTPOLICYMAPCREATEFAILED);
  378. PKIX_CHECK(PKIX_List_AppendItem
  379. (maps, (PKIX_PL_Object *)certPolicyMap, plContext),
  380. PKIX_LISTAPPENDITEMFAILED);
  381. PKIX_FREE(issuerPolicyOIDAscii);
  382. PKIX_FREE(subjectPolicyOIDAscii);
  383. PKIX_DECREF(issuerDomainOID);
  384. PKIX_DECREF(subjectDomainOID);
  385. PKIX_DECREF(certPolicyMap);
  386. policyMaps++;
  387. } while (*policyMaps != NULL);
  388. PKIX_CHECK(PKIX_List_SetImmutable(maps, plContext),
  389. PKIX_LISTSETIMMUTABLEFAILED);
  390. *pCertPolicyMaps = maps;
  391. maps = NULL;
  392. cleanup:
  393. if (certPolMaps) {
  394. PKIX_CERT_DEBUG
  395. ("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n");
  396. CERT_DestroyPolicyMappingsExtension(certPolMaps);
  397. }
  398. PKIX_FREE(issuerPolicyOIDAscii);
  399. PKIX_FREE(subjectPolicyOIDAscii);
  400. PKIX_DECREF(maps);
  401. PKIX_DECREF(issuerDomainOID);
  402. PKIX_DECREF(subjectDomainOID);
  403. PKIX_DECREF(certPolicyMap);
  404. PKIX_RETURN(CERT);
  405. }
  406. /*
  407. * FUNCTION: pkix_pl_Cert_DecodePolicyConstraints
  408. * DESCRIPTION:
  409. *
  410. * Decodes the contents of the PolicyConstraints extension in the
  411. * CERTCertificate pointed to by "nssCert", to obtain SkipCerts values
  412. * which are stored at the addresses "pExplicitPolicySkipCerts" and
  413. * "pInhibitMappingSkipCerts", respectively. If this certificate does
  414. * not have an PolicyConstraints extension, or if either of the optional
  415. * components is not supplied, this function stores a value of -1 for any
  416. * missing component.
  417. *
  418. * PARAMETERS
  419. * "nssCert"
  420. * Address of the Cert data whose extension is to be examined. Must be
  421. * non-NULL.
  422. * "pExplicitPolicySkipCerts"
  423. * Address where the SkipCert value for the requireExplicitPolicy
  424. * component will be stored. Must be non-NULL.
  425. * "pInhibitMappingSkipCerts"
  426. * Address where the SkipCert value for the inhibitPolicyMapping
  427. * component will be stored. Must be non-NULL.
  428. * "plContext"
  429. * Platform-specific context pointer.
  430. * THREAD SAFETY:
  431. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  432. * RETURNS:
  433. * Returns NULL if the function succeeds.
  434. * Returns a Cert Error if the function fails in a non-fatal way.
  435. * Returns a Fatal Error if the function fails in an unrecoverable way.
  436. */
  437. static PKIX_Error *
  438. pkix_pl_Cert_DecodePolicyConstraints(
  439. CERTCertificate *nssCert,
  440. PKIX_Int32 *pExplicitPolicySkipCerts,
  441. PKIX_Int32 *pInhibitMappingSkipCerts,
  442. void *plContext)
  443. {
  444. CERTCertificatePolicyConstraints policyConstraints;
  445. SECStatus rv;
  446. SECItem encodedCertPolicyConstraints;
  447. PKIX_Int32 explicitPolicySkipCerts = -1;
  448. PKIX_Int32 inhibitMappingSkipCerts = -1;
  449. PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyConstraints");
  450. PKIX_NULLCHECK_THREE
  451. (nssCert, pExplicitPolicySkipCerts, pInhibitMappingSkipCerts);
  452. /* get the two skipCert values as SECItems */
  453. PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
  454. rv = CERT_FindCertExtension
  455. (nssCert,
  456. SEC_OID_X509_POLICY_CONSTRAINTS,
  457. &encodedCertPolicyConstraints);
  458. if (rv == SECSuccess) {
  459. policyConstraints.explicitPolicySkipCerts.data =
  460. (unsigned char *)&explicitPolicySkipCerts;
  461. policyConstraints.inhibitMappingSkipCerts.data =
  462. (unsigned char *)&inhibitMappingSkipCerts;
  463. /* translate DER to CERTCertificatePolicyConstraints */
  464. rv = CERT_DecodePolicyConstraintsExtension
  465. (&policyConstraints, &encodedCertPolicyConstraints);
  466. PORT_Free(encodedCertPolicyConstraints.data);
  467. if (rv != SECSuccess) {
  468. PKIX_ERROR
  469. (PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED);
  470. }
  471. }
  472. *pExplicitPolicySkipCerts = explicitPolicySkipCerts;
  473. *pInhibitMappingSkipCerts = inhibitMappingSkipCerts;
  474. cleanup:
  475. PKIX_RETURN(CERT);
  476. }
  477. /*
  478. * FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy
  479. * DESCRIPTION:
  480. *
  481. * Decodes the contents of the InhibitAnyPolicy extension in the
  482. * CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value,
  483. * which is stored at the address "pSkipCerts". If this certificate does
  484. * not have an InhibitAnyPolicy extension, -1 will be stored.
  485. *
  486. * PARAMETERS
  487. * "nssCert"
  488. * Address of the Cert data whose InhibitAnyPolicy extension is to be
  489. * processed. Must be non-NULL.
  490. * "pSkipCerts"
  491. * Address where the SkipCert value from the InhibitAnyPolicy extension
  492. * will be stored. Must be non-NULL.
  493. * "plContext"
  494. * Platform-specific context pointer.
  495. * THREAD SAFETY:
  496. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  497. * RETURNS:
  498. * Returns NULL if the function succeeds.
  499. * Returns a Cert Error if the function fails in a non-fatal way.
  500. * Returns a Fatal Error if the function fails in an unrecoverable way.
  501. */
  502. PKIX_Error *
  503. pkix_pl_Cert_DecodeInhibitAnyPolicy(
  504. CERTCertificate *nssCert,
  505. PKIX_Int32 *pSkipCerts,
  506. void *plContext)
  507. {
  508. CERTCertificateInhibitAny inhibitAny;
  509. SECStatus rv;
  510. SECItem encodedCertInhibitAny;
  511. PKIX_Int32 skipCerts = -1;
  512. PKIX_ENTER(CERT, "pkix_pl_Cert_DecodeInhibitAnyPolicy");
  513. PKIX_NULLCHECK_TWO(nssCert, pSkipCerts);
  514. /* get InhibitAny as a SECItem */
  515. PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
  516. rv = CERT_FindCertExtension
  517. (nssCert, SEC_OID_X509_INHIBIT_ANY_POLICY, &encodedCertInhibitAny);
  518. if (rv == SECSuccess) {
  519. inhibitAny.inhibitAnySkipCerts.data =
  520. (unsigned char *)&skipCerts;
  521. /* translate DER to CERTCertificateInhibitAny */
  522. rv = CERT_DecodeInhibitAnyExtension
  523. (&inhibitAny, &encodedCertInhibitAny);
  524. PORT_Free(encodedCertInhibitAny.data);
  525. if (rv != SECSuccess) {
  526. PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED);
  527. }
  528. }
  529. *pSkipCerts = skipCerts;
  530. cleanup:
  531. PKIX_RETURN(CERT);
  532. }
  533. /*
  534. * FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames
  535. * DESCRIPTION:
  536. *
  537. * Retrieves the Subject Alternative Names of the certificate specified by
  538. * "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative
  539. * Name extension is not present, NULL is returned at "pNssSubjAltNames".
  540. * If the Subject Alternative Names has not been previously decoded, it is
  541. * decoded here with lock on the "cert" unless the flag "hasLock" indicates
  542. * the lock had been obtained at a higher call level.
  543. *
  544. * PARAMETERS
  545. * "cert"
  546. * Address of the certificate whose Subject Alternative Names extensions
  547. * is retrieved. Must be non-NULL.
  548. * "hasLock"
  549. * Boolean indicates caller has acquired a lock.
  550. * Must be non-NULL.
  551. * "pNssSubjAltNames"
  552. * Address where the returned Subject Alternative Names will be stored.
  553. * Must be non-NULL.
  554. * "plContext"
  555. * Platform-specific context pointer.
  556. * THREAD SAFETY:
  557. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  558. * RETURNS:
  559. * Returns NULL if the function succeeds.
  560. * Returns a Cert Error if the function fails in a non-fatal way.
  561. * Returns a Fatal Error if the function fails in an unrecoverable way.
  562. */
  563. static PKIX_Error *
  564. pkix_pl_Cert_GetNssSubjectAltNames(
  565. PKIX_PL_Cert *cert,
  566. PKIX_Boolean hasLock,
  567. CERTGeneralName **pNssSubjAltNames,
  568. void *plContext)
  569. {
  570. CERTCertificate *nssCert = NULL;
  571. CERTGeneralName *nssOriginalAltName = NULL;
  572. PLArenaPool *arena = NULL;
  573. SECItem altNameExtension = {siBuffer, NULL, 0};
  574. SECStatus rv = SECFailure;
  575. PKIX_ENTER(CERT, "pkix_pl_Cert_GetNssSubjectAltNames");
  576. PKIX_NULLCHECK_THREE(cert, pNssSubjAltNames, cert->nssCert);
  577. nssCert = cert->nssCert;
  578. if ((cert->nssSubjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
  579. if (!hasLock) {
  580. PKIX_OBJECT_LOCK(cert);
  581. }
  582. if ((cert->nssSubjAltNames == NULL) &&
  583. (!cert->subjAltNamesAbsent)){
  584. PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
  585. (nssCert,
  586. SEC_OID_X509_SUBJECT_ALT_NAME,
  587. &altNameExtension));
  588. if (rv != SECSuccess) {
  589. *pNssSubjAltNames = NULL;
  590. cert->subjAltNamesAbsent = PKIX_TRUE;
  591. goto cleanup;
  592. }
  593. if (cert->arenaNameConstraints == NULL) {
  594. PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
  595. (DER_DEFAULT_CHUNKSIZE));
  596. if (arena == NULL) {
  597. PKIX_ERROR(PKIX_OUTOFMEMORY);
  598. }
  599. cert->arenaNameConstraints = arena;
  600. }
  601. PKIX_PL_NSSCALLRV
  602. (CERT,
  603. nssOriginalAltName,
  604. (CERTGeneralName *) CERT_DecodeAltNameExtension,
  605. (cert->arenaNameConstraints, &altNameExtension));
  606. PKIX_PL_NSSCALL(CERT, PORT_Free, (altNameExtension.data));
  607. if (nssOriginalAltName == NULL) {
  608. PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED);
  609. }
  610. cert->nssSubjAltNames = nssOriginalAltName;
  611. }
  612. if (!hasLock) {
  613. PKIX_OBJECT_UNLOCK(cert);
  614. }
  615. }
  616. *pNssSubjAltNames = cert->nssSubjAltNames;
  617. cleanup:
  618. PKIX_OBJECT_UNLOCK(lockedObject);
  619. PKIX_RETURN(CERT);
  620. }
  621. /*
  622. * FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage
  623. * DESCRIPTION:
  624. *
  625. * For each of the ON bit in "requiredExtendedKeyUsages" that represents its
  626. * SECCertUsageEnum type, this function checks "cert"'s certType (extended
  627. * key usage) and key usage with what is required for SECCertUsageEnum type.
  628. *
  629. * PARAMETERS
  630. * "cert"
  631. * Address of the certificate whose Extended Key Usage extensions
  632. * is retrieved. Must be non-NULL.
  633. * "requiredExtendedKeyUsages"
  634. * An unsigned integer, its bit location is ON based on the required key
  635. * usage value representing in SECCertUsageEnum.
  636. * "pPass"
  637. * Address where the return value, indicating key usage check passed, is
  638. * stored. Must be non-NULL.
  639. * "plContext"
  640. * Platform-specific context pointer.
  641. * THREAD SAFETY:
  642. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  643. * RETURNS:
  644. * Returns NULL if the function succeeds.
  645. * Returns a Cert Error if the function fails in a non-fatal way.
  646. * Returns a Fatal Error if the function fails in an unrecoverable way.
  647. */
  648. PKIX_Error *
  649. pkix_pl_Cert_CheckExtendedKeyUsage(
  650. PKIX_PL_Cert *cert,
  651. PKIX_UInt32 requiredExtendedKeyUsages,
  652. PKIX_Boolean *pPass,
  653. void *plContext)
  654. {
  655. PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
  656. PKIX_UInt32 certType = 0;
  657. PKIX_UInt32 requiredKeyUsage = 0;
  658. PKIX_UInt32 requiredCertType = 0;
  659. PKIX_UInt32 requiredExtendedKeyUsage = 0;
  660. PKIX_UInt32 i;
  661. PKIX_Boolean isCA = PKIX_FALSE;
  662. SECStatus rv = SECFailure;
  663. PKIX_ENTER(CERT, "pkix_pl_Cert_CheckExtendKeyUsage");
  664. PKIX_NULLCHECK_THREE(cert, pPass, cert->nssCert);
  665. *pPass = PKIX_FALSE;
  666. PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n");
  667. cert_GetCertType(cert->nssCert);
  668. certType = cert->nssCert->nsCertType;
  669. PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
  670. (cert,
  671. &basicConstraints,
  672. plContext),
  673. PKIX_CERTGETBASICCONSTRAINTFAILED);
  674. if (basicConstraints != NULL) {
  675. PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
  676. (basicConstraints, &isCA, plContext),
  677. PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
  678. }
  679. i = 0;
  680. while (requiredExtendedKeyUsages != 0) {
  681. /* Find the bit location of the right-most non-zero bit */
  682. while (requiredExtendedKeyUsages != 0) {
  683. if (((1 << i) & requiredExtendedKeyUsages) != 0) {
  684. requiredExtendedKeyUsage = 1 << i;
  685. break;
  686. }
  687. i++;
  688. }
  689. requiredExtendedKeyUsages ^= requiredExtendedKeyUsage;
  690. requiredExtendedKeyUsage = i;
  691. PKIX_PL_NSSCALLRV(CERT, rv, CERT_KeyUsageAndTypeForCertUsage,
  692. (requiredExtendedKeyUsage,
  693. isCA,
  694. &requiredKeyUsage,
  695. &requiredCertType));
  696. if (!(certType & requiredCertType)) {
  697. goto cleanup;
  698. }
  699. PKIX_PL_NSSCALLRV(CERT, rv, CERT_CheckKeyUsage,
  700. (cert->nssCert, requiredKeyUsage));
  701. if (rv != SECSuccess) {
  702. goto cleanup;
  703. }
  704. i++;
  705. }
  706. *pPass = PKIX_TRUE;
  707. cleanup:
  708. PKIX_DECREF(basicConstraints);
  709. PKIX_RETURN(CERT);
  710. }
  711. /*
  712. * FUNCTION: pkix_pl_Cert_ToString_Helper
  713. * DESCRIPTION:
  714. *
  715. * Helper function that creates a string representation of the Cert pointed
  716. * to by "cert" and stores it at "pString", where the value of
  717. * "partialString" determines whether a full or partial representation of
  718. * the Cert is stored.
  719. *
  720. * PARAMETERS
  721. * "cert"
  722. * Address of Cert whose string representation is desired.
  723. * Must be non-NULL.
  724. * "partialString"
  725. * Boolean indicating whether a partial Cert representation is desired.
  726. * "pString"
  727. * Address where object pointer will be stored. Must be non-NULL.
  728. * "plContext"
  729. * Platform-specific context pointer.
  730. * THREAD SAFETY:
  731. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  732. * RETURNS:
  733. * Returns NULL if the function succeeds.
  734. * Returns a Cert Error if the function fails in a non-fatal way.
  735. * Returns a Fatal Error if the function fails in an unrecoverable way.
  736. */
  737. PKIX_Error *
  738. pkix_pl_Cert_ToString_Helper(
  739. PKIX_PL_Cert *cert,
  740. PKIX_Boolean partialString,
  741. PKIX_PL_String **pString,
  742. void *plContext)
  743. {
  744. PKIX_PL_String *certString = NULL;
  745. char *asciiFormat = NULL;
  746. PKIX_PL_String *formatString = NULL;
  747. PKIX_UInt32 certVersion;
  748. PKIX_PL_BigInt *certSN = NULL;
  749. PKIX_PL_String *certSNString = NULL;
  750. PKIX_PL_X500Name *certIssuer = NULL;
  751. PKIX_PL_String *certIssuerString = NULL;
  752. PKIX_PL_X500Name *certSubject = NULL;
  753. PKIX_PL_String *certSubjectString = NULL;
  754. PKIX_PL_String *notBeforeString = NULL;
  755. PKIX_PL_String *notAfterString = NULL;
  756. PKIX_List *subjAltNames = NULL;
  757. PKIX_PL_String *subjAltNamesString = NULL;
  758. PKIX_PL_ByteArray *authKeyId = NULL;
  759. PKIX_PL_String *authKeyIdString = NULL;
  760. PKIX_PL_ByteArray *subjKeyId = NULL;
  761. PKIX_PL_String *subjKeyIdString = NULL;
  762. PKIX_PL_PublicKey *nssPubKey = NULL;
  763. PKIX_PL_String *nssPubKeyString = NULL;
  764. PKIX_List *critExtOIDs = NULL;
  765. PKIX_PL_String *critExtOIDsString = NULL;
  766. PKIX_List *extKeyUsages = NULL;
  767. PKIX_PL_String *extKeyUsagesString = NULL;
  768. PKIX_PL_CertBasicConstraints *basicConstraint = NULL;
  769. PKIX_PL_String *certBasicConstraintsString = NULL;
  770. PKIX_List *policyInfo = NULL;
  771. PKIX_PL_String *certPolicyInfoString = NULL;
  772. PKIX_List *certPolicyMappings = NULL;
  773. PKIX_PL_String *certPolicyMappingsString = NULL;
  774. PKIX_Int32 certExplicitPolicy = 0;
  775. PKIX_Int32 certInhibitMapping = 0;
  776. PKIX_Int32 certInhibitAnyPolicy = 0;
  777. PKIX_PL_CertNameConstraints *nameConstraints = NULL;
  778. PKIX_PL_String *nameConstraintsString = NULL;
  779. PKIX_List *authorityInfoAccess = NULL;
  780. PKIX_PL_String *authorityInfoAccessString = NULL;
  781. PKIX_List *subjectInfoAccess = NULL;
  782. PKIX_PL_String *subjectInfoAccessString = NULL;
  783. PKIX_ENTER(CERT, "pkix_pl_Cert_ToString_Helper");
  784. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pString);
  785. /*
  786. * XXX Add to this format as certificate components are developed.
  787. */
  788. if (partialString){
  789. asciiFormat =
  790. "\t[Issuer: %s\n"
  791. "\t Subject: %s]";
  792. } else {
  793. asciiFormat =
  794. "[\n"
  795. "\tVersion: v%d\n"
  796. "\tSerialNumber: %s\n"
  797. "\tIssuer: %s\n"
  798. "\tSubject: %s\n"
  799. "\tValidity: [From: %s\n"
  800. "\t To: %s]\n"
  801. "\tSubjectAltNames: %s\n"
  802. "\tAuthorityKeyId: %s\n"
  803. "\tSubjectKeyId: %s\n"
  804. "\tSubjPubKeyAlgId: %s\n"
  805. "\tCritExtOIDs: %s\n"
  806. "\tExtKeyUsages: %s\n"
  807. "\tBasicConstraint: %s\n"
  808. "\tCertPolicyInfo: %s\n"
  809. "\tPolicyMappings: %s\n"
  810. "\tExplicitPolicy: %d\n"
  811. "\tInhibitMapping: %d\n"
  812. "\tInhibitAnyPolicy:%d\n"
  813. "\tNameConstraints: %s\n"
  814. "\tAuthorityInfoAccess: %s\n"
  815. "\tSubjectInfoAccess: %s\n"
  816. "\tCacheFlag: %d\n"
  817. "]\n";
  818. }
  819. PKIX_CHECK(PKIX_PL_String_Create
  820. (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
  821. PKIX_STRINGCREATEFAILED);
  822. /* Issuer */
  823. PKIX_CHECK(PKIX_PL_Cert_GetIssuer
  824. (cert, &certIssuer, plContext),
  825. PKIX_CERTGETISSUERFAILED);
  826. PKIX_CHECK(PKIX_PL_Object_ToString
  827. ((PKIX_PL_Object *)certIssuer, &certIssuerString, plContext),
  828. PKIX_X500NAMETOSTRINGFAILED);
  829. /* Subject */
  830. PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &certSubject, plContext),
  831. PKIX_CERTGETSUBJECTFAILED);
  832. PKIX_TOSTRING(certSubject, &certSubjectString, plContext,
  833. PKIX_X500NAMETOSTRINGFAILED);
  834. if (partialString){
  835. PKIX_CHECK(PKIX_PL_Sprintf
  836. (&certString,
  837. plContext,
  838. formatString,
  839. certIssuerString,
  840. certSubjectString),
  841. PKIX_SPRINTFFAILED);
  842. *pString = certString;
  843. goto cleanup;
  844. }
  845. /* Version */
  846. PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert, &certVersion, plContext),
  847. PKIX_CERTGETVERSIONFAILED);
  848. /* SerialNumber */
  849. PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert, &certSN, plContext),
  850. PKIX_CERTGETSERIALNUMBERFAILED);
  851. PKIX_CHECK(PKIX_PL_Object_ToString
  852. ((PKIX_PL_Object *)certSN, &certSNString, plContext),
  853. PKIX_BIGINTTOSTRINGFAILED);
  854. /* Validity: NotBefore */
  855. PKIX_CHECK(pkix_pl_Date_ToString_Helper
  856. (&(cert->nssCert->validity.notBefore),
  857. &notBeforeString,
  858. plContext),
  859. PKIX_DATETOSTRINGHELPERFAILED);
  860. /* Validity: NotAfter */
  861. PKIX_CHECK(pkix_pl_Date_ToString_Helper
  862. (&(cert->nssCert->validity.notAfter),
  863. &notAfterString,
  864. plContext),
  865. PKIX_DATETOSTRINGHELPERFAILED);
  866. /* SubjectAltNames */
  867. PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
  868. (cert, &subjAltNames, plContext),
  869. PKIX_CERTGETSUBJECTALTNAMESFAILED);
  870. PKIX_TOSTRING(subjAltNames, &subjAltNamesString, plContext,
  871. PKIX_LISTTOSTRINGFAILED);
  872. /* AuthorityKeyIdentifier */
  873. PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
  874. (cert, &authKeyId, plContext),
  875. PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
  876. PKIX_TOSTRING(authKeyId, &authKeyIdString, plContext,
  877. PKIX_BYTEARRAYTOSTRINGFAILED);
  878. /* SubjectKeyIdentifier */
  879. PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
  880. (cert, &subjKeyId, plContext),
  881. PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
  882. PKIX_TOSTRING(subjKeyId, &subjKeyIdString, plContext,
  883. PKIX_BYTEARRAYTOSTRINGFAILED);
  884. /* SubjectPublicKey */
  885. PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
  886. (cert, &nssPubKey, plContext),
  887. PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
  888. PKIX_CHECK(PKIX_PL_Object_ToString
  889. ((PKIX_PL_Object *)nssPubKey, &nssPubKeyString, plContext),
  890. PKIX_PUBLICKEYTOSTRINGFAILED);
  891. /* CriticalExtensionOIDs */
  892. PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
  893. (cert, &critExtOIDs, plContext),
  894. PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
  895. PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
  896. PKIX_LISTTOSTRINGFAILED);
  897. /* ExtendedKeyUsages */
  898. PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
  899. (cert, &extKeyUsages, plContext),
  900. PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
  901. PKIX_TOSTRING(extKeyUsages, &extKeyUsagesString, plContext,
  902. PKIX_LISTTOSTRINGFAILED);
  903. /* CertBasicConstraints */
  904. PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
  905. (cert, &basicConstraint, plContext),
  906. PKIX_CERTGETBASICCONSTRAINTSFAILED);
  907. PKIX_TOSTRING(basicConstraint, &certBasicConstraintsString, plContext,
  908. PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED);
  909. /* CertPolicyInfo */
  910. PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
  911. (cert, &policyInfo, plContext),
  912. PKIX_CERTGETPOLICYINFORMATIONFAILED);
  913. PKIX_TOSTRING(policyInfo, &certPolicyInfoString, plContext,
  914. PKIX_LISTTOSTRINGFAILED);
  915. /* Advanced Policies */
  916. PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
  917. (cert, &certPolicyMappings, plContext),
  918. PKIX_CERTGETPOLICYMAPPINGSFAILED);
  919. PKIX_TOSTRING(certPolicyMappings, &certPolicyMappingsString, plContext,
  920. PKIX_LISTTOSTRINGFAILED);
  921. PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
  922. (cert, &certExplicitPolicy, plContext),
  923. PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
  924. PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
  925. (cert, &certInhibitMapping, plContext),
  926. PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
  927. PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
  928. (cert, &certInhibitAnyPolicy, plContext),
  929. PKIX_CERTGETINHIBITANYPOLICYFAILED);
  930. /* Name Constraints */
  931. PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
  932. (cert, &nameConstraints, plContext),
  933. PKIX_CERTGETNAMECONSTRAINTSFAILED);
  934. PKIX_TOSTRING(nameConstraints, &nameConstraintsString, plContext,
  935. PKIX_LISTTOSTRINGFAILED);
  936. /* Authority Information Access */
  937. PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
  938. (cert, &authorityInfoAccess, plContext),
  939. PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
  940. PKIX_TOSTRING(authorityInfoAccess, &authorityInfoAccessString, plContext,
  941. PKIX_LISTTOSTRINGFAILED);
  942. /* Subject Information Access */
  943. PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess
  944. (cert, &subjectInfoAccess, plContext),
  945. PKIX_CERTGETSUBJECTINFOACCESSFAILED);
  946. PKIX_TOSTRING(subjectInfoAccess, &subjectInfoAccessString, plContext,
  947. PKIX_LISTTOSTRINGFAILED);
  948. PKIX_CHECK(PKIX_PL_Sprintf
  949. (&certString,
  950. plContext,
  951. formatString,
  952. certVersion + 1,
  953. certSNString,
  954. certIssuerString,
  955. certSubjectString,
  956. notBeforeString,
  957. notAfterString,
  958. subjAltNamesString,
  959. authKeyIdString,
  960. subjKeyIdString,
  961. nssPubKeyString,
  962. critExtOIDsString,
  963. extKeyUsagesString,
  964. certBasicConstraintsString,
  965. certPolicyInfoString,
  966. certPolicyMappingsString,
  967. certExplicitPolicy, /* an Int32, not a String */
  968. certInhibitMapping, /* an Int32, not a String */
  969. certInhibitAnyPolicy, /* an Int32, not a String */
  970. nameConstraintsString,
  971. authorityInfoAccessString,
  972. subjectInfoAccessString,
  973. cert->cacheFlag), /* a boolean */
  974. PKIX_SPRINTFFAILED);
  975. *pString = certString;
  976. cleanup:
  977. PKIX_DECREF(certSN);
  978. PKIX_DECREF(certSNString);
  979. PKIX_DECREF(certIssuer);
  980. PKIX_DECREF(certIssuerString);
  981. PKIX_DECREF(certSubject);
  982. PKIX_DECREF(certSubjectString);
  983. PKIX_DECREF(notBeforeString);
  984. PKIX_DECREF(notAfterString);
  985. PKIX_DECREF(subjAltNames);
  986. PKIX_DECREF(subjAltNamesString);
  987. PKIX_DECREF(authKeyId);
  988. PKIX_DECREF(authKeyIdString);
  989. PKIX_DECREF(subjKeyId);
  990. PKIX_DECREF(subjKeyIdString);
  991. PKIX_DECREF(nssPubKey);
  992. PKIX_DECREF(nssPubKeyString);
  993. PKIX_DECREF(critExtOIDs);
  994. PKIX_DECREF(critExtOIDsString);
  995. PKIX_DECREF(extKeyUsages);
  996. PKIX_DECREF(extKeyUsagesString);
  997. PKIX_DECREF(basicConstraint);
  998. PKIX_DECREF(certBasicConstraintsString);
  999. PKIX_DECREF(policyInfo);
  1000. PKIX_DECREF(certPolicyInfoString);
  1001. PKIX_DECREF(certPolicyMappings);
  1002. PKIX_DECREF(certPolicyMappingsString);
  1003. PKIX_DECREF(nameConstraints);
  1004. PKIX_DECREF(nameConstraintsString);
  1005. PKIX_DECREF(authorityInfoAccess);
  1006. PKIX_DECREF(authorityInfoAccessString);
  1007. PKIX_DECREF(subjectInfoAccess);
  1008. PKIX_DECREF(subjectInfoAccessString);
  1009. PKIX_DECREF(formatString);
  1010. PKIX_RETURN(CERT);
  1011. }
  1012. /*
  1013. * FUNCTION: pkix_pl_Cert_Destroy
  1014. * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
  1015. */
  1016. static PKIX_Error *
  1017. pkix_pl_Cert_Destroy(
  1018. PKIX_PL_Object *object,
  1019. void *plContext)
  1020. {
  1021. PKIX_PL_Cert *cert = NULL;
  1022. PKIX_ENTER(CERT, "pkix_pl_Cert_Destroy");
  1023. PKIX_NULLCHECK_ONE(object);
  1024. PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
  1025. PKIX_OBJECTNOTCERT);
  1026. cert = (PKIX_PL_Cert*)object;
  1027. PKIX_DECREF(cert->subject);
  1028. PKIX_DECREF(cert->issuer);
  1029. PKIX_DECREF(cert->subjAltNames);
  1030. PKIX_DECREF(cert->publicKeyAlgId);
  1031. PKIX_DECREF(cert->publicKey);
  1032. PKIX_DECREF(cert->serialNumber);
  1033. PKIX_DECREF(cert->critExtOids);
  1034. PKIX_DECREF(cert->authKeyId);
  1035. PKIX_DECREF(cert->subjKeyId);
  1036. PKIX_DECREF(cert->extKeyUsages);
  1037. PKIX_DECREF(cert->certBasicConstraints);
  1038. PKIX_DECREF(cert->certPolicyInfos);
  1039. PKIX_DECREF(cert->certPolicyMappings);
  1040. PKIX_DECREF(cert->nameConstraints);
  1041. PKIX_DECREF(cert->store);
  1042. PKIX_DECREF(cert->authorityInfoAccess);
  1043. PKIX_DECREF(cert->subjectInfoAccess);
  1044. if (cert->arenaNameConstraints){
  1045. /* This arena was allocated for SubjectAltNames */
  1046. PKIX_PL_NSSCALL(CERT, PORT_FreeArena,
  1047. (cert->arenaNameConstraints, PR_FALSE));
  1048. cert->arenaNameConstraints = NULL;
  1049. cert->nssSubjAltNames = NULL;
  1050. }
  1051. CERT_DestroyCertificate(cert->nssCert);
  1052. cert->nssCert = NULL;
  1053. cleanup:
  1054. PKIX_RETURN(CERT);
  1055. }
  1056. /*
  1057. * FUNCTION: pkix_pl_Cert_ToString
  1058. * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
  1059. */
  1060. static PKIX_Error *
  1061. pkix_pl_Cert_ToString(
  1062. PKIX_PL_Object *object,
  1063. PKIX_PL_String **pString,
  1064. void *plContext)
  1065. {
  1066. PKIX_PL_String *certString = NULL;
  1067. PKIX_PL_Cert *pkixCert = NULL;
  1068. PKIX_ENTER(CERT, "pkix_pl_Cert_toString");
  1069. PKIX_NULLCHECK_TWO(object, pString);
  1070. PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
  1071. PKIX_OBJECTNOTCERT);
  1072. pkixCert = (PKIX_PL_Cert *)object;
  1073. PKIX_CHECK(pkix_pl_Cert_ToString_Helper
  1074. (pkixCert, PKIX_FALSE, &certString, plContext),
  1075. PKIX_CERTTOSTRINGHELPERFAILED);
  1076. *pString = certString;
  1077. cleanup:
  1078. PKIX_RETURN(CERT);
  1079. }
  1080. /*
  1081. * FUNCTION: pkix_pl_Cert_Hashcode
  1082. * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
  1083. */
  1084. static PKIX_Error *
  1085. pkix_pl_Cert_Hashcode(
  1086. PKIX_PL_Object *object,
  1087. PKIX_UInt32 *pHashcode,
  1088. void *plContext)
  1089. {
  1090. PKIX_PL_Cert *pkixCert = NULL;
  1091. CERTCertificate *nssCert = NULL;
  1092. unsigned char *derBytes = NULL;
  1093. PKIX_UInt32 derLength;
  1094. PKIX_UInt32 certHash;
  1095. PKIX_ENTER(CERT, "pkix_pl_Cert_Hashcode");
  1096. PKIX_NULLCHECK_TWO(object, pHashcode);
  1097. PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
  1098. PKIX_OBJECTNOTCERT);
  1099. pkixCert = (PKIX_PL_Cert *)object;
  1100. nssCert = pkixCert->nssCert;
  1101. derBytes = (nssCert->derCert).data;
  1102. derLength = (nssCert->derCert).len;
  1103. PKIX_CHECK(pkix_hash(derBytes, derLength, &certHash, plContext),
  1104. PKIX_HASHFAILED);
  1105. *pHashcode = certHash;
  1106. cleanup:
  1107. PKIX_RETURN(CERT);
  1108. }
  1109. /*
  1110. * FUNCTION: pkix_pl_Cert_Equals
  1111. * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
  1112. */
  1113. static PKIX_Error *
  1114. pkix_pl_Cert_Equals(
  1115. PKIX_PL_Object *firstObject,
  1116. PKIX_PL_Object *secondObject,
  1117. PKIX_Boolean *pResult,
  1118. void *plContext)
  1119. {
  1120. CERTCertificate *firstCert = NULL;
  1121. CERTCertificate *secondCert = NULL;
  1122. PKIX_UInt32 secondType;
  1123. PKIX_Boolean cmpResult;
  1124. PKIX_ENTER(CERT, "pkix_pl_Cert_Equals");
  1125. PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
  1126. /* test that firstObject is a Cert */
  1127. PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CERT_TYPE, plContext),
  1128. PKIX_FIRSTOBJECTNOTCERT);
  1129. /*
  1130. * Since we know firstObject is a Cert, if both references are
  1131. * identical, they must be equal
  1132. */
  1133. if (firstObject == secondObject){
  1134. *pResult = PKIX_TRUE;
  1135. goto cleanup;
  1136. }
  1137. /*
  1138. * If secondObject isn't a Cert, we don't throw an error.
  1139. * We simply return a Boolean result of FALSE
  1140. */
  1141. *pResult = PKIX_FALSE;
  1142. PKIX_CHECK(PKIX_PL_Object_GetType
  1143. (secondObject, &secondType, plContext),
  1144. PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
  1145. if (secondType != PKIX_CERT_TYPE) goto cleanup;
  1146. firstCert = ((PKIX_PL_Cert *)firstObject)->nssCert;
  1147. secondCert = ((PKIX_PL_Cert *)secondObject)->nssCert;
  1148. PKIX_NULLCHECK_TWO(firstCert, secondCert);
  1149. /* CERT_CompareCerts does byte comparison on DER encodings of certs */
  1150. PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n");
  1151. cmpResult = CERT_CompareCerts(firstCert, secondCert);
  1152. *pResult = cmpResult;
  1153. cleanup:
  1154. PKIX_RETURN(CERT);
  1155. }
  1156. /*
  1157. * FUNCTION: pkix_pl_Cert_RegisterSelf
  1158. * DESCRIPTION:
  1159. * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
  1160. * THREAD SAFETY:
  1161. * Not Thread Safe - for performance and complexity reasons
  1162. *
  1163. * Since this function is only called by PKIX_PL_Initialize, which should
  1164. * only be called once, it is acceptable that this function is not
  1165. * thread-safe.
  1166. */
  1167. PKIX_Error *
  1168. pkix_pl_Cert_RegisterSelf(void *plContext)
  1169. {
  1170. extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
  1171. pkix_ClassTable_Entry entry;
  1172. PKIX_ENTER(CERT, "pkix_pl_Cert_RegisterSelf");
  1173. entry.description = "Cert";
  1174. entry.objCounter = 0;
  1175. entry.typeObjectSize = sizeof(PKIX_PL_Cert);
  1176. entry.destructor = pkix_pl_Cert_Destroy;
  1177. entry.equalsFunction = pkix_pl_Cert_Equals;
  1178. entry.hashcodeFunction = pkix_pl_Cert_Hashcode;
  1179. entry.toStringFunction = pkix_pl_Cert_ToString;
  1180. entry.comparator = NULL;
  1181. entry.duplicateFunction = pkix_duplicateImmutable;
  1182. systemClasses[PKIX_CERT_TYPE] = entry;
  1183. PKIX_RETURN(CERT);
  1184. }
  1185. /*
  1186. * FUNCTION: pkix_pl_Cert_CreateWithNSSCert
  1187. * DESCRIPTION:
  1188. *
  1189. * Creates a new certificate using the CERTCertificate pointed to by "nssCert"
  1190. * and stores it at "pCert". Once created, a Cert is immutable.
  1191. *
  1192. * This function is primarily used as a convenience function for the
  1193. * performance tests that have easy access to a CERTCertificate.
  1194. *
  1195. * PARAMETERS:
  1196. * "nssCert"
  1197. * Address of CERTCertificate representing the NSS certificate.
  1198. * Must be non-NULL.
  1199. * "pCert"
  1200. * Address where object pointer will be stored. Must be non-NULL.
  1201. * "plContext"
  1202. * Platform-specific context pointer.
  1203. * THREAD SAFETY:
  1204. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  1205. * RETURNS:
  1206. * Returns NULL if the function succeeds.
  1207. * Returns a Cert Error if the function fails in a non-fatal way.
  1208. * Returns a Fatal Error if the function fails in an unrecoverable way.
  1209. */
  1210. PKIX_Error *
  1211. pkix_pl_Cert_CreateWithNSSCert(
  1212. CERTCertificate *nssCert,
  1213. PKIX_PL_Cert **pCert,
  1214. void *plContext)
  1215. {
  1216. PKIX_PL_Cert *cert = NULL;
  1217. PKIX_ENTER(CERT, "pkix_pl_Cert_CreateWithNSSCert");
  1218. PKIX_NULLCHECK_TWO(pCert, nssCert);
  1219. /* create a PKIX_PL_Cert object */
  1220. PKIX_CHECK(PKIX_PL_Object_Alloc
  1221. (PKIX_CERT_TYPE,
  1222. sizeof (PKIX_PL_Cert),
  1223. (PKIX_PL_Object **)&cert,
  1224. plContext),
  1225. PKIX_COULDNOTCREATEOBJECT);
  1226. /* populate the nssCert field */
  1227. cert->nssCert = nssCert;
  1228. /* initialize remaining fields */
  1229. /*
  1230. * Fields ending with Absent are initialized to PKIX_FALSE so that the
  1231. * first time we need the value we will look for it. If we find it is
  1232. * actually absent, the flag will at that time be set to PKIX_TRUE to
  1233. * prevent searching for it later.
  1234. * Fields ending with Processed are those where a value is defined
  1235. * for the Absent case, and a value of zero is possible. When the
  1236. * flag is still true we have to look for the field, set the default
  1237. * value if necessary, and set the Processed flag to PKIX_TRUE.
  1238. */
  1239. cert->subject = NULL;
  1240. cert->issuer = NULL;
  1241. cert->subjAltNames = NULL;
  1242. cert->subjAltNamesAbsent = PKIX_FALSE;
  1243. cert->publicKeyAlgId = NULL;
  1244. cert->publicKey = NULL;
  1245. cert->serialNumber = NULL;
  1246. cert->critExtOids = NULL;
  1247. cert->subjKeyId = NULL;
  1248. cert->subjKeyIdAbsent = PKIX_FALSE;
  1249. cert->authKeyId = NULL;
  1250. cert->authKeyIdAbsent = PKIX_FALSE;
  1251. cert->extKeyUsages = NULL;
  1252. cert->extKeyUsagesAbsent = PKIX_FALSE;
  1253. cert->certBasicConstraints = NULL;
  1254. cert->basicConstraintsAbsent = PKIX_FALSE;
  1255. cert->certPolicyInfos = NULL;
  1256. cert->policyInfoAbsent = PKIX_FALSE;
  1257. cert->policyMappingsAbsent = PKIX_FALSE;
  1258. cert->certPolicyMappings = NULL;
  1259. cert->policyConstraintsProcessed = PKIX_FALSE;
  1260. cert->policyConstraintsExplicitPolicySkipCerts = 0;
  1261. cert->policyConstraintsInhibitMappingSkipCerts = 0;
  1262. cert->inhibitAnyPolicyProcessed = PKIX_FALSE;
  1263. cert->inhibitAnySkipCerts = 0;
  1264. cert->nameConstraints = NULL;
  1265. cert->nameConstraintsAbsent = PKIX_FALSE;
  1266. cert->arenaNameConstraints = NULL;
  1267. cert->nssSubjAltNames = NULL;
  1268. cert->cacheFlag = PKIX_FALSE;
  1269. cert->store = NULL;
  1270. cert->authorityInfoAccess = NULL;
  1271. cert->subjectInfoAccess = NULL;
  1272. cert->isUserTrustAnchor = PKIX_FALSE;
  1273. *pCert = cert;
  1274. cleanup:
  1275. PKIX_RETURN(CERT);
  1276. }
  1277. /*
  1278. * FUNCTION: pkix_pl_Cert_CreateToList
  1279. * DESCRIPTION:
  1280. *
  1281. * Creates a new certificate using the DER-encoding pointed to by "derCertItem"
  1282. * and appends it to the list pointed to by "certList". If Cert creation fails,
  1283. * the function returns with certList unchanged, but any decoding Error is
  1284. * discarded.
  1285. *
  1286. * PARAMETERS:
  1287. * "derCertItem"
  1288. * Address of SECItem containing the DER representation of a certificate.
  1289. * Must be non-NULL.
  1290. * "certList"
  1291. * Address of List to which the Cert will be appended, if successfully
  1292. * created. May be empty, but must be non-NULL.
  1293. * "plContext"
  1294. * Platform-specific context pointer.
  1295. * THREAD SAFETY:
  1296. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  1297. * RETURNS:
  1298. * Returns NULL if the function succeeds.
  1299. * Returns a Cert Error if the function fails in a non-fatal way.
  1300. * Returns a Fatal Error if the function fails in an unrecoverable way.
  1301. */
  1302. PKIX_Error *
  1303. pkix_pl_Cert_CreateToList(
  1304. SECItem *derCertItem,
  1305. PKIX_List *certList,
  1306. void *plContext)
  1307. {
  1308. CERTCertificate *nssCert = NULL;
  1309. PKIX_PL_Cert *cert = NULL;
  1310. CERTCertDBHandle *handle;
  1311. PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList");
  1312. PKIX_NULLCHECK_TWO(derCertItem, certList);
  1313. handle = CERT_GetDefaultCertDB();
  1314. nssCert = CERT_NewTempCertificate(handle, derCertItem,
  1315. /* nickname */ NULL,
  1316. /* isPerm */ PR_FALSE,
  1317. /* copyDer */ PR_TRUE);
  1318. if (!nssCert) {
  1319. goto cleanup;
  1320. }
  1321. PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
  1322. (nssCert, &cert, plContext),
  1323. PKIX_CERTCREATEWITHNSSCERTFAILED);
  1324. nssCert = NULL;
  1325. PKIX_CHECK(PKIX_List_AppendItem
  1326. (certList, (PKIX_PL_Object *) cert, plContext),
  1327. PKIX_LISTAPPENDITEMFAILED);
  1328. cleanup:
  1329. if (nssCert) {
  1330. CERT_DestroyCertificate(nssCert);
  1331. }
  1332. PKIX_DECREF(cert);
  1333. PKIX_RETURN(CERT);
  1334. }
  1335. /* --Public-Functions------------------------------------------------------- */
  1336. /*
  1337. * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
  1338. * XXX We may want to cache the cert after parsing it, so it can be reused
  1339. * XXX Are the NSS/NSPR functions thread safe
  1340. */
  1341. PKIX_Error *
  1342. PKIX_PL_Cert_Create(
  1343. PKIX_PL_ByteArray *byteArray,
  1344. PKIX_PL_Cert **pCert,
  1345. void *plContext)
  1346. {
  1347. CERTCertificate *nssCert = NULL;
  1348. SECItem *derCertItem = NULL;
  1349. void *derBytes = NULL;
  1350. PKIX_UInt32 derLength;
  1351. PKIX_Boolean copyDER;
  1352. PKIX_PL_Cert *cert = NULL;
  1353. CERTCertDBHandle *handle;
  1354. PKIX_ENTER(CERT, "PKIX_PL_Cert_Create");
  1355. PKIX_NULLCHECK_TWO(pCert, byteArray);
  1356. PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
  1357. (byteArray, &derBytes, plContext),
  1358. PKIX_BYTEARRAYGETPOINTERFAILED);
  1359. PKIX_CHECK(PKIX_PL_ByteArray_GetLength
  1360. (byteArray, &derLength, plContext),
  1361. PKIX_BYTEARRAYGETLENGTHFAILED);
  1362. derCertItem = SECITEM_AllocItem(NULL, NULL, derLength);
  1363. if (derCertItem == NULL){
  1364. PKIX_ERROR(PKIX_OUTOFMEMORY);
  1365. }
  1366. (void) PORT_Memcpy(derCertItem->data, derBytes, derLength);
  1367. /*
  1368. * setting copyDER to true forces NSS to make its own copy of the DER,
  1369. * allowing us to free our copy without worrying about whether NSS
  1370. * is still using it
  1371. */
  1372. copyDER = PKIX_TRUE;
  1373. handle = CERT_GetDefaultCertDB();
  1374. nssCert = CERT_NewTempCertificate(handle, derCertItem,
  1375. /* nickname */ NULL,
  1376. /* isPerm */ PR_FALSE,
  1377. /* copyDer */ PR_TRUE);
  1378. if (!nssCert){
  1379. PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED);
  1380. }
  1381. PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
  1382. (nssCert, &cert, plContext),
  1383. PKIX_CERTCREATEWITHNSSCERTFAILED);
  1384. *pCert = cert;
  1385. cleanup:
  1386. if (derCertItem){
  1387. SECITEM_FreeItem(derCertItem, PKIX_TRUE);
  1388. }
  1389. if (nssCert && PKIX_ERROR_RECEIVED){
  1390. PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
  1391. CERT_DestroyCertificate(nssCert);
  1392. nssCert = NULL;
  1393. }
  1394. PKIX_FREE(derBytes);
  1395. PKIX_RETURN(CERT);
  1396. }
  1397. /*
  1398. * FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate
  1399. * (see comments in pkix_pl_pki.h)
  1400. */
  1401. PKIX_Error *
  1402. PKIX_PL_Cert_CreateFromCERTCertificate(
  1403. const CERTCertificate *nssCert,
  1404. PKIX_PL_Cert **pCert,
  1405. void *plContext)
  1406. {
  1407. void *buf = NULL;
  1408. PKIX_UInt32 len;
  1409. PKIX_PL_ByteArray *byteArray = NULL;
  1410. PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNssCert");
  1411. PKIX_NULLCHECK_TWO(pCert, nssCert);
  1412. buf = (void*)nssCert->derCert.data;
  1413. len = nssCert->derCert.len;
  1414. PKIX_CHECK(
  1415. PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext),
  1416. PKIX_BYTEARRAYCREATEFAILED);
  1417. PKIX_CHECK(
  1418. PKIX_PL_Cert_Create(byteArray, pCert, plContext),
  1419. PKIX_CERTCREATEWITHNSSCERTFAILED);
  1420. #ifdef PKIX_UNDEF
  1421. /* will be tested and used as a patch for bug 391612 */
  1422. nssCert = CERT_DupCertificate(nssInCert);
  1423. PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
  1424. (nssCert, &cert, plContext),
  1425. PKIX_CERTCREATEWITHNSSCERTFAILED);
  1426. #endif /* PKIX_UNDEF */
  1427. cleanup:
  1428. #ifdef PKIX_UNDEF
  1429. if (nssCert && PKIX_ERROR_RECEIVED){
  1430. PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
  1431. CERT_DestroyCertificate(nssCert);
  1432. nssCert = NULL;
  1433. }
  1434. #endif /* PKIX_UNDEF */
  1435. PKIX_DECREF(byteArray);
  1436. PKIX_RETURN(CERT);
  1437. }
  1438. /*
  1439. * FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h)
  1440. */
  1441. PKIX_Error *
  1442. PKIX_PL_Cert_GetVersion(
  1443. PKIX_PL_Cert *cert,
  1444. PKIX_UInt32 *pVersion,
  1445. void *plContext)
  1446. {
  1447. CERTCertificate *nssCert = NULL;
  1448. PKIX_UInt32 myVersion = 1;
  1449. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion");
  1450. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion);
  1451. nssCert = cert->nssCert;
  1452. if (nssCert->version.data) {
  1453. myVersion = *(nssCert->version.data);
  1454. }
  1455. if (myVersion > 2){
  1456. PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3);
  1457. }
  1458. *pVersion = myVersion;
  1459. cleanup:
  1460. PKIX_RETURN(CERT);
  1461. }
  1462. /*
  1463. * FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h)
  1464. */
  1465. PKIX_Error *
  1466. PKIX_PL_Cert_GetSerialNumber(
  1467. PKIX_PL_Cert *cert,
  1468. PKIX_PL_BigInt **pSerialNumber,
  1469. void *plContext)
  1470. {
  1471. CERTCertificate *nssCert = NULL;
  1472. SECItem serialNumItem;
  1473. PKIX_PL_BigInt *serialNumber = NULL;
  1474. char *bytes = NULL;
  1475. PKIX_UInt32 length;
  1476. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSerialNumber");
  1477. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSerialNumber);
  1478. if (cert->serialNumber == NULL){
  1479. PKIX_OBJECT_LOCK(cert);
  1480. if (cert->serialNumber == NULL){
  1481. nssCert = cert->nssCert;
  1482. serialNumItem = nssCert->serialNumber;
  1483. length = serialNumItem.len;
  1484. bytes = (char *)serialNumItem.data;
  1485. PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
  1486. (bytes, length, &serialNumber, plContext),
  1487. PKIX_BIGINTCREATEWITHBYTESFAILED);
  1488. /* save a cached copy in case it is asked for again */
  1489. cert->serialNumber = serialNumber;
  1490. }
  1491. PKIX_OBJECT_UNLOCK(cert);
  1492. }
  1493. PKIX_INCREF(cert->serialNumber);
  1494. *pSerialNumber = cert->serialNumber;
  1495. cleanup:
  1496. PKIX_OBJECT_UNLOCK(lockedObject);
  1497. PKIX_RETURN(CERT);
  1498. }
  1499. /*
  1500. * FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h)
  1501. */
  1502. PKIX_Error *
  1503. PKIX_PL_Cert_GetSubject(
  1504. PKIX_PL_Cert *cert,
  1505. PKIX_PL_X500Name **pCertSubject,
  1506. void *plContext)
  1507. {
  1508. PKIX_PL_X500Name *pkixSubject = NULL;
  1509. CERTName *subjName = NULL;
  1510. SECItem *derSubjName = NULL;
  1511. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubject");
  1512. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertSubject);
  1513. /* if we don't have a cached copy from before, we create one */
  1514. if (cert->subject == NULL){
  1515. PKIX_OBJECT_LOCK(cert);
  1516. if (cert->subject == NULL){
  1517. subjName = &cert->nssCert->subject;
  1518. derSubjName = &cert->nssCert->derSubject;
  1519. /* if there is no subject name */
  1520. if (derSubjName->data == NULL) {
  1521. pkixSubject = NULL;
  1522. } else {
  1523. PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
  1524. (derSubjName, subjName, &pkixSubject,
  1525. plContext),
  1526. PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
  1527. }
  1528. /* save a cached copy in case it is asked for again */
  1529. cert->subject = pkixSubject;
  1530. }
  1531. PKIX_OBJECT_UNLOCK(cert);
  1532. }
  1533. PKIX_INCREF(cert->subject);
  1534. *pCertSubject = cert->subject;
  1535. cleanup:
  1536. PKIX_OBJECT_UNLOCK(lockedObject);
  1537. PKIX_RETURN(CERT);
  1538. }
  1539. /*
  1540. * FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h)
  1541. */
  1542. PKIX_Error *
  1543. PKIX_PL_Cert_GetIssuer(
  1544. PKIX_PL_Cert *cert,
  1545. PKIX_PL_X500Name **pCertIssuer,
  1546. void *plContext)
  1547. {
  1548. PKIX_PL_X500Name *pkixIssuer = NULL;
  1549. SECItem *derIssuerName = NULL;
  1550. CERTName *issuerName = NULL;
  1551. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetIssuer");
  1552. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertIssuer);
  1553. /* if we don't have a cached copy from before, we create one */
  1554. if (cert->issuer == NULL){
  1555. PKIX_OBJECT_LOCK(cert);
  1556. if (cert->issuer == NULL){
  1557. issuerName = &cert->nssCert->issuer;
  1558. derIssuerName = &cert->nssCert->derIssuer;
  1559. /* if there is no subject name */
  1560. PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
  1561. (derIssuerName, issuerName,
  1562. &pkixIssuer, plContext),
  1563. PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
  1564. /* save a cached copy in case it is asked for again */
  1565. cert->issuer = pkixIssuer;
  1566. }
  1567. PKIX_OBJECT_UNLOCK(cert);
  1568. }
  1569. PKIX_INCREF(cert->issuer);
  1570. *pCertIssuer = cert->issuer;
  1571. cleanup:
  1572. PKIX_RETURN(CERT);
  1573. }
  1574. /*
  1575. * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h)
  1576. */
  1577. PKIX_Error *
  1578. PKIX_PL_Cert_GetSubjectAltNames(
  1579. PKIX_PL_Cert *cert,
  1580. PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */
  1581. void *plContext)
  1582. {
  1583. PKIX_PL_GeneralName *pkixAltName = NULL;
  1584. PKIX_List *altNamesList = NULL;
  1585. CERTGeneralName *nssOriginalAltName = NULL;
  1586. CERTGeneralName *nssTempAltName = NULL;
  1587. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectAltNames");
  1588. PKIX_NULLCHECK_TWO(cert, pSubjectAltNames);
  1589. /* if we don't have a cached copy from before, we create one */
  1590. if ((cert->subjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
  1591. PKIX_OBJECT_LOCK(cert);
  1592. if ((cert->subjAltNames == NULL) &&
  1593. (!cert->subjAltNamesAbsent)){
  1594. PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
  1595. (cert,
  1596. PKIX_TRUE,
  1597. &nssOriginalAltName,
  1598. plContext),
  1599. PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
  1600. if (nssOriginalAltName == NULL) {
  1601. cert->subjAltNamesAbsent = PKIX_TRUE;
  1602. pSubjectAltNames = NULL;
  1603. goto cleanup;
  1604. }
  1605. nssTempAltName = nssOriginalAltName;
  1606. PKIX_CHECK(PKIX_List_Create(&altNamesList, plContext),
  1607. PKIX_LISTCREATEFAILED);
  1608. do {
  1609. PKIX_CHECK(pkix_pl_GeneralName_Create
  1610. (nssTempAltName, &pkixAltName, plContext),
  1611. PKIX_GENERALNAMECREATEFAILED);
  1612. PKIX_CHECK(PKIX_List_AppendItem
  1613. (altNamesList,
  1614. (PKIX_PL_Object *)pkixAltName,
  1615. plContext),
  1616. PKIX_LISTAPPENDITEMFAILED);
  1617. PKIX_DECREF(pkixAltName);
  1618. PKIX_CERT_DEBUG
  1619. ("\t\tCalling CERT_GetNextGeneralName).\n");
  1620. nssTempAltName = CERT_GetNextGeneralName
  1621. (nssTempAltName);
  1622. } while (nssTempAltName != nssOriginalAltName);
  1623. /* save a cached copy in case it is asked for again */
  1624. cert->subjAltNames = altNamesList;
  1625. PKIX_CHECK(PKIX_List_SetImmutable
  1626. (cert->subjAltNames, plContext),
  1627. PKIX_LISTSETIMMUTABLEFAILED);
  1628. }
  1629. PKIX_OBJECT_UNLOCK(cert);
  1630. }
  1631. PKIX_INCREF(cert->subjAltNames);
  1632. *pSubjectAltNames = cert->subjAltNames;
  1633. cleanup:
  1634. PKIX_DECREF(pkixAltName);
  1635. if (PKIX_ERROR_RECEIVED){
  1636. PKIX_DECREF(altNamesList);
  1637. }
  1638. PKIX_RETURN(CERT);
  1639. }
  1640. /*
  1641. * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h)
  1642. */
  1643. PKIX_Error *
  1644. PKIX_PL_Cert_GetAllSubjectNames(
  1645. PKIX_PL_Cert *cert,
  1646. PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */
  1647. void *plContext)
  1648. {
  1649. CERTGeneralName *nssOriginalSubjectName = NULL;
  1650. CERTGeneralName *nssTempSubjectName = NULL;
  1651. PKIX_List *allSubjectNames = NULL;
  1652. PKIX_PL_GeneralName *pkixSubjectName = NULL;
  1653. PLArenaPool *arena = NULL;
  1654. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAllSubjectNames");
  1655. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAllSubjectNames);
  1656. if (cert->nssCert->subjectName == NULL){
  1657. /* if there is no subject DN, just get altnames */
  1658. PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
  1659. (cert,
  1660. PKIX_FALSE, /* hasLock */
  1661. &nssOriginalSubjectName,
  1662. plContext),
  1663. PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
  1664. } else { /* get subject DN and altnames */
  1665. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1666. if (arena == NULL) {
  1667. PKIX_ERROR(PKIX_OUTOFMEMORY);
  1668. }
  1669. /* This NSS call returns both Subject and Subject Alt Names */
  1670. PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
  1671. nssOriginalSubjectName =
  1672. CERT_GetCertificateNames(cert->nssCert, arena);
  1673. }
  1674. if (nssOriginalSubjectName == NULL) {
  1675. pAllSubjectNames = NULL;
  1676. goto cleanup;
  1677. }
  1678. nssTempSubjectName = nssOriginalSubjectName;
  1679. PKIX_CHECK(PKIX_List_Create(&allSubjectNames, plContext),
  1680. PKIX_LISTCREATEFAILED);
  1681. do {
  1682. PKIX_CHECK(pkix_pl_GeneralName_Create
  1683. (nssTempSubjectName, &pkixSubjectName, plContext),
  1684. PKIX_GENERALNAMECREATEFAILED);
  1685. PKIX_CHECK(PKIX_List_AppendItem
  1686. (allSubjectNames,
  1687. (PKIX_PL_Object *)pkixSubjectName,
  1688. plContext),
  1689. PKIX_LISTAPPENDITEMFAILED);
  1690. PKIX_DECREF(pkixSubjectName);
  1691. PKIX_CERT_DEBUG
  1692. ("\t\tCalling CERT_GetNextGeneralName).\n");
  1693. nssTempSubjectName = CERT_GetNextGeneralName
  1694. (nssTempSubjectName);
  1695. } while (nssTempSubjectName != nssOriginalSubjectName);
  1696. *pAllSubjectNames = allSubjectNames;
  1697. cleanup:
  1698. if (PKIX_ERROR_RECEIVED){
  1699. PKIX_DECREF(allSubjectNames);
  1700. }
  1701. if (arena){
  1702. PORT_FreeArena(arena, PR_FALSE);
  1703. }
  1704. PKIX_DECREF(pkixSubjectName);
  1705. PKIX_RETURN(CERT);
  1706. }
  1707. /*
  1708. * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
  1709. * (see comments in pkix_pl_pki.h)
  1710. */
  1711. PKIX_Error *
  1712. PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
  1713. PKIX_PL_Cert *cert,
  1714. PKIX_PL_OID **pSubjKeyAlgId,
  1715. void *plContext)
  1716. {
  1717. CERTCertificate *nssCert = NULL;
  1718. PKIX_PL_OID *pubKeyAlgId = NULL;
  1719. SECAlgorithmID algorithm;
  1720. SECItem algBytes;
  1721. char *asciiOID = NULL;
  1722. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
  1723. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyAlgId);
  1724. /* if we don't have a cached copy from before, we create one */
  1725. if (cert->publicKeyAlgId == NULL){
  1726. PKIX_OBJECT_LOCK(cert);
  1727. if (cert->publicKeyAlgId == NULL){
  1728. nssCert = cert->nssCert;
  1729. algorithm = nssCert->subjectPublicKeyInfo.algorithm;
  1730. algBytes = algorithm.algorithm;
  1731. PKIX_NULLCHECK_ONE(algBytes.data);
  1732. if (algBytes.len == 0) {
  1733. PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0);
  1734. }
  1735. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  1736. (&algBytes, &asciiOID, plContext),
  1737. PKIX_OIDBYTES2ASCIIFAILED);
  1738. PKIX_CHECK(PKIX_PL_OID_Create
  1739. (asciiOID, &pubKeyAlgId, plContext),
  1740. PKIX_OIDCREATEFAILED);
  1741. /* save a cached copy in case it is asked for again */
  1742. cert->publicKeyAlgId = pubKeyAlgId;
  1743. }
  1744. PKIX_OBJECT_UNLOCK(cert);
  1745. }
  1746. PKIX_INCREF(cert->publicKeyAlgId);
  1747. *pSubjKeyAlgId = cert->publicKeyAlgId;
  1748. cleanup:
  1749. PKIX_FREE(asciiOID);
  1750. PKIX_RETURN(CERT);
  1751. }
  1752. /*
  1753. * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h)
  1754. */
  1755. PKIX_Error *
  1756. PKIX_PL_Cert_GetSubjectPublicKey(
  1757. PKIX_PL_Cert *cert,
  1758. PKIX_PL_PublicKey **pPublicKey,
  1759. void *plContext)
  1760. {
  1761. PKIX_PL_PublicKey *pkixPubKey = NULL;
  1762. SECStatus rv;
  1763. CERTSubjectPublicKeyInfo *from = NULL;
  1764. CERTSubjectPublicKeyInfo *to = NULL;
  1765. SECItem *fromItem = NULL;
  1766. SECItem *toItem = NULL;
  1767. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKey");
  1768. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPublicKey);
  1769. /* if we don't have a cached copy from before, we create one */
  1770. if (cert->publicKey == NULL){
  1771. PKIX_OBJECT_LOCK(cert);
  1772. if (cert->publicKey == NULL){
  1773. /* create a PKIX_PL_PublicKey object */
  1774. PKIX_CHECK(PKIX_PL_Object_Alloc
  1775. (PKIX_PUBLICKEY_TYPE,
  1776. sizeof (PKIX_PL_PublicKey),
  1777. (PKIX_PL_Object **)&pkixPubKey,
  1778. plContext),
  1779. PKIX_COULDNOTCREATEOBJECT);
  1780. /* initialize fields */
  1781. pkixPubKey->nssSPKI = NULL;
  1782. /* populate the SPKI field */
  1783. PKIX_CHECK(PKIX_PL_Malloc
  1784. (sizeof (CERTSubjectPublicKeyInfo),
  1785. (void **)&pkixPubKey->nssSPKI,
  1786. plContext),
  1787. PKIX_MALLOCFAILED);
  1788. to = pkixPubKey->nssSPKI;
  1789. from = &cert->nssCert->subjectPublicKeyInfo;
  1790. PKIX_NULLCHECK_TWO(to, from);
  1791. PKIX_CERT_DEBUG
  1792. ("\t\tCalling SECOID_CopyAlgorithmID).\n");
  1793. rv = SECOID_CopyAlgorithmID
  1794. (NULL, &to->algorithm, &from->algorithm);
  1795. if (rv != SECSuccess) {
  1796. PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED);
  1797. }
  1798. /*
  1799. * NSS stores the length of subjectPublicKey in bits.
  1800. * Therefore, we use that length converted to bytes
  1801. * using ((length+7)>>3) before calling PORT_Memcpy
  1802. * in order to avoid "read from uninitialized memory"
  1803. * errors.
  1804. */
  1805. toItem = &to->subjectPublicKey;
  1806. fromItem = &from->subjectPublicKey;
  1807. PKIX_NULLCHECK_TWO(toItem, fromItem);
  1808. toItem->type = fromItem->type;
  1809. toItem->data =
  1810. (unsigned char*) PORT_ZAlloc(fromItem->len);
  1811. if (!toItem->data){
  1812. PKIX_ERROR(PKIX_OUTOFMEMORY);
  1813. }
  1814. (void) PORT_Memcpy(toItem->data,
  1815. fromItem->data,
  1816. (fromItem->len + 7)>>3);
  1817. toItem->len = fromItem->len;
  1818. /* save a cached copy in case it is asked for again */
  1819. cert->publicKey = pkixPubKey;
  1820. }
  1821. PKIX_OBJECT_UNLOCK(cert);
  1822. }
  1823. PKIX_INCREF(cert->publicKey);
  1824. *pPublicKey = cert->publicKey;
  1825. cleanup:
  1826. if (PKIX_ERROR_RECEIVED && pkixPubKey){
  1827. PKIX_DECREF(pkixPubKey);
  1828. cert->publicKey = NULL;
  1829. }
  1830. PKIX_RETURN(CERT);
  1831. }
  1832. /*
  1833. * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
  1834. * (see comments in pkix_pl_pki.h)
  1835. */
  1836. PKIX_Error *
  1837. PKIX_PL_Cert_GetCriticalExtensionOIDs(
  1838. PKIX_PL_Cert *cert,
  1839. PKIX_List **pList, /* list of PKIX_PL_OID */
  1840. void *plContext)
  1841. {
  1842. PKIX_List *oidsList = NULL;
  1843. CERTCertExtension **extensions = NULL;
  1844. CERTCertificate *nssCert = NULL;
  1845. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCriticalExtensionOIDs");
  1846. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pList);
  1847. /* if we don't have a cached copy from before, we create one */
  1848. if (cert->critExtOids == NULL) {
  1849. PKIX_OBJECT_LOCK(cert);
  1850. if (cert->critExtOids == NULL) {
  1851. nssCert = cert->nssCert;
  1852. /*
  1853. * ASN.1 for Extension
  1854. *
  1855. * Extension ::= SEQUENCE {
  1856. * extnID OBJECT IDENTIFIER,
  1857. * critical BOOLEAN DEFAULT FALSE,
  1858. * extnValue OCTET STRING }
  1859. *
  1860. */
  1861. extensions = nssCert->extensions;
  1862. PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
  1863. (extensions, &oidsList, plContext),
  1864. PKIX_GETCRITICALEXTENSIONOIDSFAILED);
  1865. /* save a cached copy in case it is asked for again */
  1866. cert->critExtOids = oidsList;
  1867. }
  1868. PKIX_OBJECT_UNLOCK(cert);
  1869. }
  1870. /* We should return a copy of the List since this list changes */
  1871. PKIX_DUPLICATE(cert->critExtOids, pList, plContext,
  1872. PKIX_OBJECTDUPLICATELISTFAILED);
  1873. cleanup:
  1874. PKIX_OBJECT_UNLOCK(lockedObject);
  1875. PKIX_RETURN(CERT);
  1876. }
  1877. /*
  1878. * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
  1879. * (see comments in pkix_pl_pki.h)
  1880. */
  1881. PKIX_Error *
  1882. PKIX_PL_Cert_GetAuthorityKeyIdentifier(
  1883. PKIX_PL_Cert *cert,
  1884. PKIX_PL_ByteArray **pAuthKeyId,
  1885. void *plContext)
  1886. {
  1887. PKIX_PL_ByteArray *authKeyId = NULL;
  1888. CERTCertificate *nssCert = NULL;
  1889. CERTAuthKeyID *authKeyIdExtension = NULL;
  1890. PLArenaPool *arena = NULL;
  1891. SECItem retItem;
  1892. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityKeyIdentifier");
  1893. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAuthKeyId);
  1894. /* if we don't have a cached copy from before, we create one */
  1895. if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
  1896. PKIX_OBJECT_LOCK(cert);
  1897. if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
  1898. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1899. if (arena == NULL) {
  1900. PKIX_ERROR(PKIX_OUTOFMEMORY);
  1901. }
  1902. nssCert = cert->nssCert;
  1903. authKeyIdExtension =
  1904. CERT_FindAuthKeyIDExten(arena, nssCert);
  1905. if (authKeyIdExtension == NULL){
  1906. cert->authKeyIdAbsent = PKIX_TRUE;
  1907. *pAuthKeyId = NULL;
  1908. goto cleanup;
  1909. }
  1910. retItem = authKeyIdExtension->keyID;
  1911. if (retItem.len == 0){
  1912. cert->authKeyIdAbsent = PKIX_TRUE;
  1913. *pAuthKeyId = NULL;
  1914. goto cleanup;
  1915. }
  1916. PKIX_CHECK(PKIX_PL_ByteArray_Create
  1917. (retItem.data,
  1918. retItem.len,
  1919. &authKeyId,
  1920. plContext),
  1921. PKIX_BYTEARRAYCREATEFAILED);
  1922. /* save a cached copy in case it is asked for again */
  1923. cert->authKeyId = authKeyId;
  1924. }
  1925. PKIX_OBJECT_UNLOCK(cert);
  1926. }
  1927. PKIX_INCREF(cert->authKeyId);
  1928. *pAuthKeyId = cert->authKeyId;
  1929. cleanup:
  1930. PKIX_OBJECT_UNLOCK(lockedObject);
  1931. if (arena){
  1932. PORT_FreeArena(arena, PR_FALSE);
  1933. }
  1934. PKIX_RETURN(CERT);
  1935. }
  1936. /*
  1937. * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
  1938. * (see comments in pkix_pl_pki.h)
  1939. */
  1940. PKIX_Error *
  1941. PKIX_PL_Cert_GetSubjectKeyIdentifier(
  1942. PKIX_PL_Cert *cert,
  1943. PKIX_PL_ByteArray **pSubjKeyId,
  1944. void *plContext)
  1945. {
  1946. PKIX_PL_ByteArray *subjKeyId = NULL;
  1947. CERTCertificate *nssCert = NULL;
  1948. SECItem *retItem = NULL;
  1949. SECStatus status;
  1950. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectKeyIdentifier");
  1951. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyId);
  1952. /* if we don't have a cached copy from before, we create one */
  1953. if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
  1954. PKIX_OBJECT_LOCK(cert);
  1955. if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
  1956. retItem = SECITEM_AllocItem(NULL, NULL, 0);
  1957. if (retItem == NULL){
  1958. PKIX_ERROR(PKIX_OUTOFMEMORY);
  1959. }
  1960. nssCert = cert->nssCert;
  1961. status = CERT_FindSubjectKeyIDExtension
  1962. (nssCert, retItem);
  1963. if (status != SECSuccess) {
  1964. cert->subjKeyIdAbsent = PKIX_TRUE;
  1965. *pSubjKeyId = NULL;
  1966. goto cleanup;
  1967. }
  1968. PKIX_CHECK(PKIX_PL_ByteArray_Create
  1969. (retItem->data,
  1970. retItem->len,
  1971. &subjKeyId,
  1972. plContext),
  1973. PKIX_BYTEARRAYCREATEFAILED);
  1974. /* save a cached copy in case it is asked for again */
  1975. cert->subjKeyId = subjKeyId;
  1976. }
  1977. PKIX_OBJECT_UNLOCK(cert);
  1978. }
  1979. PKIX_INCREF(cert->subjKeyId);
  1980. *pSubjKeyId = cert->subjKeyId;
  1981. cleanup:
  1982. PKIX_OBJECT_UNLOCK(lockedObject);
  1983. if (retItem){
  1984. SECITEM_FreeItem(retItem, PKIX_TRUE);
  1985. }
  1986. PKIX_RETURN(CERT);
  1987. }
  1988. /*
  1989. * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h)
  1990. */
  1991. PKIX_Error *
  1992. PKIX_PL_Cert_GetExtendedKeyUsage(
  1993. PKIX_PL_Cert *cert,
  1994. PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */
  1995. void *plContext)
  1996. {
  1997. CERTOidSequence *extKeyUsage = NULL;
  1998. CERTCertificate *nssCert = NULL;
  1999. PKIX_PL_OID *pkixOID = NULL;
  2000. PKIX_List *oidsList = NULL;
  2001. char *oidAscii = NULL;
  2002. SECItem **oids = NULL;
  2003. SECItem *oid = NULL;
  2004. SECItem encodedExtKeyUsage;
  2005. SECStatus rv;
  2006. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetExtendedKeyUsage");
  2007. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pKeyUsage);
  2008. /* if we don't have a cached copy from before, we create one */
  2009. if ((cert->extKeyUsages == NULL) && (!cert->extKeyUsagesAbsent)){
  2010. PKIX_OBJECT_LOCK(cert);
  2011. if ((cert->extKeyUsages == NULL) &&
  2012. (!cert->extKeyUsagesAbsent)){
  2013. nssCert = cert->nssCert;
  2014. rv = CERT_FindCertExtension
  2015. (nssCert, SEC_OID_X509_EXT_KEY_USAGE,
  2016. &encodedExtKeyUsage);
  2017. if (rv != SECSuccess){
  2018. cert->extKeyUsagesAbsent = PKIX_TRUE;
  2019. *pKeyUsage = NULL;
  2020. goto cleanup;
  2021. }
  2022. extKeyUsage =
  2023. CERT_DecodeOidSequence(&encodedExtKeyUsage);
  2024. if (extKeyUsage == NULL){
  2025. PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED);
  2026. }
  2027. PORT_Free(encodedExtKeyUsage.data);
  2028. oids = extKeyUsage->oids;
  2029. if (!oids){
  2030. /* no extended key usage extensions found */
  2031. cert->extKeyUsagesAbsent = PKIX_TRUE;
  2032. *pKeyUsage = NULL;
  2033. goto cleanup;
  2034. }
  2035. PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
  2036. PKIX_LISTCREATEFAILED);
  2037. while (*oids){
  2038. oid = *oids++;
  2039. PKIX_CHECK(pkix_pl_oidBytes2Ascii
  2040. (oid, &oidAscii, plContext),
  2041. PKIX_OIDBYTES2ASCIIFAILED);
  2042. PKIX_CHECK(PKIX_PL_OID_Create
  2043. (oidAscii, &pkixOID, plContext),
  2044. PKIX_OIDCREATEFAILED);
  2045. PKIX_CHECK(PKIX_List_AppendItem
  2046. (oidsList,
  2047. (PKIX_PL_Object *)pkixOID,
  2048. plContext),
  2049. PKIX_LISTAPPENDITEMFAILED);
  2050. PKIX_FREE(oidAscii);
  2051. PKIX_DECREF(pkixOID);
  2052. }
  2053. /* save a cached copy in case it is asked for again */
  2054. cert->extKeyUsages = oidsList;
  2055. oidsList = NULL;
  2056. }
  2057. PKIX_CHECK(PKIX_List_SetImmutable
  2058. (cert->extKeyUsages, plContext),
  2059. PKIX_LISTSETIMMUTABLEFAILED);
  2060. PKIX_OBJECT_UNLOCK(cert);
  2061. }
  2062. PKIX_INCREF(cert->extKeyUsages);
  2063. *pKeyUsage = cert->extKeyUsages;
  2064. cleanup:
  2065. PKIX_OBJECT_UNLOCK(lockedObject);
  2066. PKIX_FREE(oidAscii);
  2067. PKIX_DECREF(pkixOID);
  2068. PKIX_DECREF(oidsList);
  2069. CERT_DestroyOidSequence(extKeyUsage);
  2070. PKIX_RETURN(CERT);
  2071. }
  2072. /*
  2073. * FUNCTION: PKIX_PL_Cert_GetBasicConstraints
  2074. * (see comments in pkix_pl_pki.h)
  2075. */
  2076. PKIX_Error *
  2077. PKIX_PL_Cert_GetBasicConstraints(
  2078. PKIX_PL_Cert *cert,
  2079. PKIX_PL_CertBasicConstraints **pBasicConstraints,
  2080. void *plContext)
  2081. {
  2082. CERTCertificate *nssCert = NULL;
  2083. CERTBasicConstraints nssBasicConstraint;
  2084. SECStatus rv;
  2085. PKIX_PL_CertBasicConstraints *basic;
  2086. PKIX_Int32 pathLen = 0;
  2087. PKIX_Boolean isCA = PKIX_FALSE;
  2088. enum {
  2089. realBC, synthBC, absentBC
  2090. } constraintSource = absentBC;
  2091. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetBasicConstraints");
  2092. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pBasicConstraints);
  2093. /* if we don't have a cached copy from before, we create one */
  2094. if ((cert->certBasicConstraints == NULL) &&
  2095. (!cert->basicConstraintsAbsent)) {
  2096. PKIX_OBJECT_LOCK(cert);
  2097. if ((cert->certBasicConstraints == NULL) &&
  2098. (!cert->basicConstraintsAbsent)) {
  2099. nssCert = cert->nssCert;
  2100. PKIX_CERT_DEBUG(
  2101. "\t\tCalling Cert_FindBasicConstraintExten\n");
  2102. rv = CERT_FindBasicConstraintExten
  2103. (nssCert, &nssBasicConstraint);
  2104. if (rv == SECSuccess) {
  2105. constraintSource = realBC;
  2106. }
  2107. if (constraintSource == absentBC) {
  2108. /* can we deduce it's a CA and create a
  2109. synthetic constraint?
  2110. */
  2111. CERTCertTrust trust;
  2112. rv = CERT_GetCertTrust(nssCert, &trust);
  2113. if (rv == SECSuccess) {
  2114. int anyWantedFlag = CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
  2115. if ((trust.sslFlags & anyWantedFlag)
  2116. || (trust.emailFlags & anyWantedFlag)
  2117. || (trust.objectSigningFlags & anyWantedFlag)) {
  2118. constraintSource = synthBC;
  2119. }
  2120. }
  2121. }
  2122. if (constraintSource == absentBC) {
  2123. cert->basicConstraintsAbsent = PKIX_TRUE;
  2124. *pBasicConstraints = NULL;
  2125. goto cleanup;
  2126. }
  2127. }
  2128. if (constraintSource == synthBC) {
  2129. isCA = PKIX_TRUE;
  2130. pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
  2131. } else {
  2132. isCA = (nssBasicConstraint.isCA)?PKIX_TRUE:PKIX_FALSE;
  2133. /* The pathLen has meaning only for CAs */
  2134. if (isCA) {
  2135. if (CERT_UNLIMITED_PATH_CONSTRAINT ==
  2136. nssBasicConstraint.pathLenConstraint) {
  2137. pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
  2138. } else {
  2139. pathLen = nssBasicConstraint.pathLenConstraint;
  2140. }
  2141. }
  2142. }
  2143. PKIX_CHECK(pkix_pl_CertBasicConstraints_Create
  2144. (isCA, pathLen, &basic, plContext),
  2145. PKIX_CERTBASICCONSTRAINTSCREATEFAILED);
  2146. /* save a cached copy in case it is asked for again */
  2147. cert->certBasicConstraints = basic;
  2148. }
  2149. PKIX_INCREF(cert->certBasicConstraints);
  2150. *pBasicConstraints = cert->certBasicConstraints;
  2151. cleanup:
  2152. PKIX_OBJECT_UNLOCK(lockedObject);
  2153. PKIX_RETURN(CERT);
  2154. }
  2155. /*
  2156. * FUNCTION: PKIX_PL_Cert_GetPolicyInformation
  2157. * (see comments in pkix_pl_pki.h)
  2158. */
  2159. PKIX_Error *
  2160. PKIX_PL_Cert_GetPolicyInformation(
  2161. PKIX_PL_Cert *cert,
  2162. PKIX_List **pPolicyInfo,
  2163. void *plContext)
  2164. {
  2165. PKIX_List *policyList = NULL;
  2166. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyInformation");
  2167. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyInfo);
  2168. /* if we don't have a cached copy from before, we create one */
  2169. if ((cert->certPolicyInfos == NULL) &&
  2170. (!cert->policyInfoAbsent)) {
  2171. PKIX_OBJECT_LOCK(cert);
  2172. if ((cert->certPolicyInfos == NULL) &&
  2173. (!cert->policyInfoAbsent)) {
  2174. PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo
  2175. (cert->nssCert, &policyList, plContext),
  2176. PKIX_CERTDECODEPOLICYINFOFAILED);
  2177. if (!policyList) {
  2178. cert->policyInfoAbsent = PKIX_TRUE;
  2179. *pPolicyInfo = NULL;
  2180. goto cleanup;
  2181. }
  2182. }
  2183. PKIX_OBJECT_UNLOCK(cert);
  2184. /* save a cached copy in case it is asked for again */
  2185. cert->certPolicyInfos = policyList;
  2186. policyList = NULL;
  2187. }
  2188. PKIX_INCREF(cert->certPolicyInfos);
  2189. *pPolicyInfo = cert->certPolicyInfos;
  2190. cleanup:
  2191. PKIX_OBJECT_UNLOCK(lockedObject);
  2192. PKIX_DECREF(policyList);
  2193. PKIX_RETURN(CERT);
  2194. }
  2195. /*
  2196. * FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h)
  2197. */
  2198. PKIX_Error *
  2199. PKIX_PL_Cert_GetPolicyMappings(
  2200. PKIX_PL_Cert *cert,
  2201. PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */
  2202. void *plContext)
  2203. {
  2204. PKIX_List *policyMappings = NULL; /* list of PKIX_PL_CertPolicyMap */
  2205. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappings");
  2206. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyMappings);
  2207. /* if we don't have a cached copy from before, we create one */
  2208. if (!(cert->certPolicyMappings) && !(cert->policyMappingsAbsent)) {
  2209. PKIX_OBJECT_LOCK(cert);
  2210. if (!(cert->certPolicyMappings) &&
  2211. !(cert->policyMappingsAbsent)) {
  2212. PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping
  2213. (cert->nssCert, &policyMappings, plContext),
  2214. PKIX_CERTDECODEPOLICYMAPPINGFAILED);
  2215. if (!policyMappings) {
  2216. cert->policyMappingsAbsent = PKIX_TRUE;
  2217. *pPolicyMappings = NULL;
  2218. goto cleanup;
  2219. }
  2220. }
  2221. PKIX_OBJECT_UNLOCK(cert);
  2222. /* save a cached copy in case it is asked for again */
  2223. cert->certPolicyMappings = policyMappings;
  2224. policyMappings = NULL;
  2225. }
  2226. PKIX_INCREF(cert->certPolicyMappings);
  2227. *pPolicyMappings = cert->certPolicyMappings;
  2228. cleanup:
  2229. PKIX_OBJECT_UNLOCK(lockedObject);
  2230. PKIX_DECREF(policyMappings);
  2231. PKIX_RETURN(CERT);
  2232. }
  2233. /*
  2234. * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
  2235. * (see comments in pkix_pl_pki.h)
  2236. */
  2237. PKIX_Error *
  2238. PKIX_PL_Cert_GetRequireExplicitPolicy(
  2239. PKIX_PL_Cert *cert,
  2240. PKIX_Int32 *pSkipCerts,
  2241. void *plContext)
  2242. {
  2243. PKIX_Int32 explicitPolicySkipCerts = 0;
  2244. PKIX_Int32 inhibitMappingSkipCerts = 0;
  2245. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetRequireExplicitPolicy");
  2246. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
  2247. if (!(cert->policyConstraintsProcessed)) {
  2248. PKIX_OBJECT_LOCK(cert);
  2249. if (!(cert->policyConstraintsProcessed)) {
  2250. /*
  2251. * If we can't process it now, we probably will be
  2252. * unable to process it later. Set the default value.
  2253. */
  2254. cert->policyConstraintsProcessed = PKIX_TRUE;
  2255. cert->policyConstraintsExplicitPolicySkipCerts = -1;
  2256. cert->policyConstraintsInhibitMappingSkipCerts = -1;
  2257. PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
  2258. (cert->nssCert,
  2259. &explicitPolicySkipCerts,
  2260. &inhibitMappingSkipCerts,
  2261. plContext),
  2262. PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
  2263. cert->policyConstraintsExplicitPolicySkipCerts =
  2264. explicitPolicySkipCerts;
  2265. cert->policyConstraintsInhibitMappingSkipCerts =
  2266. inhibitMappingSkipCerts;
  2267. }
  2268. PKIX_OBJECT_UNLOCK(cert);
  2269. }
  2270. *pSkipCerts = cert->policyConstraintsExplicitPolicySkipCerts;
  2271. cleanup:
  2272. PKIX_OBJECT_UNLOCK(lockedObject);
  2273. PKIX_RETURN(CERT);
  2274. }
  2275. /*
  2276. * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
  2277. * (see comments in pkix_pl_pki.h)
  2278. */
  2279. PKIX_Error *
  2280. PKIX_PL_Cert_GetPolicyMappingInhibited(
  2281. PKIX_PL_Cert *cert,
  2282. PKIX_Int32 *pSkipCerts,
  2283. void *plContext)
  2284. {
  2285. PKIX_Int32 explicitPolicySkipCerts = 0;
  2286. PKIX_Int32 inhibitMappingSkipCerts = 0;
  2287. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappingInhibited");
  2288. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
  2289. if (!(cert->policyConstraintsProcessed)) {
  2290. PKIX_OBJECT_LOCK(cert);
  2291. if (!(cert->policyConstraintsProcessed)) {
  2292. /*
  2293. * If we can't process it now, we probably will be
  2294. * unable to process it later. Set the default value.
  2295. */
  2296. cert->policyConstraintsProcessed = PKIX_TRUE;
  2297. cert->policyConstraintsExplicitPolicySkipCerts = -1;
  2298. cert->policyConstraintsInhibitMappingSkipCerts = -1;
  2299. PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
  2300. (cert->nssCert,
  2301. &explicitPolicySkipCerts,
  2302. &inhibitMappingSkipCerts,
  2303. plContext),
  2304. PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
  2305. cert->policyConstraintsExplicitPolicySkipCerts =
  2306. explicitPolicySkipCerts;
  2307. cert->policyConstraintsInhibitMappingSkipCerts =
  2308. inhibitMappingSkipCerts;
  2309. }
  2310. PKIX_OBJECT_UNLOCK(cert);
  2311. }
  2312. *pSkipCerts = cert->policyConstraintsInhibitMappingSkipCerts;
  2313. cleanup:
  2314. PKIX_OBJECT_UNLOCK(lockedObject);
  2315. PKIX_RETURN(CERT);
  2316. }
  2317. /*
  2318. * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h)
  2319. */
  2320. PKIX_Error *
  2321. PKIX_PL_Cert_GetInhibitAnyPolicy(
  2322. PKIX_PL_Cert *cert,
  2323. PKIX_Int32 *pSkipCerts,
  2324. void *plContext)
  2325. {
  2326. PKIX_Int32 skipCerts = 0;
  2327. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetInhibitAnyPolicy");
  2328. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
  2329. if (!(cert->inhibitAnyPolicyProcessed)) {
  2330. PKIX_OBJECT_LOCK(cert);
  2331. if (!(cert->inhibitAnyPolicyProcessed)) {
  2332. /*
  2333. * If we can't process it now, we probably will be
  2334. * unable to process it later. Set the default value.
  2335. */
  2336. cert->inhibitAnyPolicyProcessed = PKIX_TRUE;
  2337. cert->inhibitAnySkipCerts = -1;
  2338. PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy
  2339. (cert->nssCert, &skipCerts, plContext),
  2340. PKIX_CERTDECODEINHIBITANYPOLICYFAILED);
  2341. cert->inhibitAnySkipCerts = skipCerts;
  2342. }
  2343. PKIX_OBJECT_UNLOCK(cert);
  2344. }
  2345. cleanup:
  2346. PKIX_OBJECT_UNLOCK(lockedObject);
  2347. *pSkipCerts = cert->inhibitAnySkipCerts;
  2348. PKIX_RETURN(CERT);
  2349. }
  2350. /*
  2351. * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
  2352. * (see comments in pkix_pl_pki.h)
  2353. */
  2354. PKIX_Error *
  2355. PKIX_PL_Cert_AreCertPoliciesCritical(
  2356. PKIX_PL_Cert *cert,
  2357. PKIX_Boolean *pCritical,
  2358. void *plContext)
  2359. {
  2360. PKIX_Boolean criticality = PKIX_FALSE;
  2361. PKIX_ENTER(CERT, "PKIX_PL_Cert_AreCertPoliciesCritical");
  2362. PKIX_NULLCHECK_TWO(cert, pCritical);
  2363. PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical(
  2364. cert,
  2365. SEC_OID_X509_CERTIFICATE_POLICIES,
  2366. &criticality,
  2367. plContext),
  2368. PKIX_CERTISEXTENSIONCRITICALFAILED);
  2369. *pCritical = criticality;
  2370. cleanup:
  2371. PKIX_RETURN(CERT);
  2372. }
  2373. /*
  2374. * FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h)
  2375. */
  2376. PKIX_Error *
  2377. PKIX_PL_Cert_VerifySignature(
  2378. PKIX_PL_Cert *cert,
  2379. PKIX_PL_PublicKey *pubKey,
  2380. void *plContext)
  2381. {
  2382. CERTCertificate *nssCert = NULL;
  2383. SECKEYPublicKey *nssPubKey = NULL;
  2384. CERTSignedData *tbsCert = NULL;
  2385. PKIX_PL_Cert *cachedCert = NULL;
  2386. PKIX_Error *verifySig = NULL;
  2387. PKIX_Error *cachedSig = NULL;
  2388. SECStatus status;
  2389. PKIX_Boolean certEqual = PKIX_FALSE;
  2390. PKIX_Boolean certInHash = PKIX_FALSE;
  2391. void* wincx = NULL;
  2392. PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifySignature");
  2393. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pubKey);
  2394. verifySig = PKIX_PL_HashTable_Lookup
  2395. (cachedCertSigTable,
  2396. (PKIX_PL_Object *) pubKey,
  2397. (PKIX_PL_Object **) &cachedCert,
  2398. plContext);
  2399. if (cachedCert != NULL && verifySig == NULL) {
  2400. /* Cached Signature Table lookup succeed */
  2401. PKIX_EQUALS(cert, cachedCert, &certEqual, plContext,
  2402. PKIX_OBJECTEQUALSFAILED);
  2403. if (certEqual == PKIX_TRUE) {
  2404. goto cleanup;
  2405. }
  2406. /* Different PubKey may hash to same value, skip add */
  2407. certInHash = PKIX_TRUE;
  2408. }
  2409. nssCert = cert->nssCert;
  2410. tbsCert = &nssCert->signatureWrap;
  2411. PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n");
  2412. nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
  2413. if (!nssPubKey){
  2414. PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
  2415. }
  2416. PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n");
  2417. PKIX_CHECK(pkix_pl_NssContext_GetWincx
  2418. ((PKIX_PL_NssContext *)plContext, &wincx),
  2419. PKIX_NSSCONTEXTGETWINCXFAILED);
  2420. status = CERT_VerifySignedDataWithPublicKey(tbsCert, nssPubKey, wincx);
  2421. if (status != SECSuccess) {
  2422. PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
  2423. }
  2424. if (certInHash == PKIX_FALSE) {
  2425. cachedSig = PKIX_PL_HashTable_Add
  2426. (cachedCertSigTable,
  2427. (PKIX_PL_Object *) pubKey,
  2428. (PKIX_PL_Object *) cert,
  2429. plContext);
  2430. if (cachedSig != NULL) {
  2431. PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
  2432. }
  2433. }
  2434. cleanup:
  2435. if (nssPubKey){
  2436. PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n");
  2437. SECKEY_DestroyPublicKey(nssPubKey);
  2438. }
  2439. PKIX_DECREF(cachedCert);
  2440. PKIX_DECREF(verifySig);
  2441. PKIX_DECREF(cachedSig);
  2442. PKIX_RETURN(CERT);
  2443. }
  2444. /*
  2445. * FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h)
  2446. */
  2447. PKIX_Error *
  2448. PKIX_PL_Cert_CheckValidity(
  2449. PKIX_PL_Cert *cert,
  2450. PKIX_PL_Date *date,
  2451. void *plContext)
  2452. {
  2453. SECCertTimeValidity val;
  2454. PRTime timeToCheck;
  2455. PKIX_Boolean allowOverride;
  2456. SECCertificateUsage requiredUsages;
  2457. PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckValidity");
  2458. PKIX_NULLCHECK_ONE(cert);
  2459. /* if the caller supplies a date, we use it; else, use current time */
  2460. if (date != NULL){
  2461. PKIX_CHECK(pkix_pl_Date_GetPRTime
  2462. (date, &timeToCheck, plContext),
  2463. PKIX_DATEGETPRTIMEFAILED);
  2464. } else {
  2465. timeToCheck = PR_Now();
  2466. }
  2467. requiredUsages = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
  2468. allowOverride =
  2469. (PRBool)((requiredUsages & certificateUsageSSLServer) ||
  2470. (requiredUsages & certificateUsageSSLServerWithStepUp));
  2471. val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, allowOverride);
  2472. if (val != secCertTimeValid){
  2473. PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED);
  2474. }
  2475. cleanup:
  2476. PKIX_RETURN(CERT);
  2477. }
  2478. /*
  2479. * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h)
  2480. */
  2481. PKIX_Error *
  2482. PKIX_PL_Cert_GetValidityNotAfter(
  2483. PKIX_PL_Cert *cert,
  2484. PKIX_PL_Date **pDate,
  2485. void *plContext)
  2486. {
  2487. PRTime prtime;
  2488. SECStatus rv = SECFailure;
  2489. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetValidityNotAfter");
  2490. PKIX_NULLCHECK_TWO(cert, pDate);
  2491. PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n");
  2492. rv = DER_DecodeTimeChoice(&prtime, &(cert->nssCert->validity.notAfter));
  2493. if (rv != SECSuccess){
  2494. PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED);
  2495. }
  2496. PKIX_CHECK(pkix_pl_Date_CreateFromPRTime
  2497. (prtime, pDate, plContext),
  2498. PKIX_DATECREATEFROMPRTIMEFAILED);
  2499. cleanup:
  2500. PKIX_RETURN(CERT);
  2501. }
  2502. /*
  2503. * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h)
  2504. */
  2505. PKIX_Error *
  2506. PKIX_PL_Cert_VerifyKeyUsage(
  2507. PKIX_PL_Cert *cert,
  2508. PKIX_UInt32 keyUsage,
  2509. void *plContext)
  2510. {
  2511. CERTCertificate *nssCert = NULL;
  2512. PKIX_UInt32 nssKeyUsage = 0;
  2513. SECStatus status;
  2514. PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyKeyUsage");
  2515. PKIX_NULLCHECK_TWO(cert, cert->nssCert);
  2516. nssCert = cert->nssCert;
  2517. /* if cert doesn't have keyUsage extension, all keyUsages are valid */
  2518. if (!nssCert->keyUsagePresent){
  2519. goto cleanup;
  2520. }
  2521. if (keyUsage & PKIX_DIGITAL_SIGNATURE){
  2522. nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
  2523. }
  2524. if (keyUsage & PKIX_NON_REPUDIATION){
  2525. nssKeyUsage = nssKeyUsage | KU_NON_REPUDIATION;
  2526. }
  2527. if (keyUsage & PKIX_KEY_ENCIPHERMENT){
  2528. nssKeyUsage = nssKeyUsage | KU_KEY_ENCIPHERMENT;
  2529. }
  2530. if (keyUsage & PKIX_DATA_ENCIPHERMENT){
  2531. nssKeyUsage = nssKeyUsage | KU_DATA_ENCIPHERMENT;
  2532. }
  2533. if (keyUsage & PKIX_KEY_AGREEMENT){
  2534. nssKeyUsage = nssKeyUsage | KU_KEY_AGREEMENT;
  2535. }
  2536. if (keyUsage & PKIX_KEY_CERT_SIGN){
  2537. nssKeyUsage = nssKeyUsage | KU_KEY_CERT_SIGN;
  2538. }
  2539. if (keyUsage & PKIX_CRL_SIGN){
  2540. nssKeyUsage = nssKeyUsage | KU_CRL_SIGN;
  2541. }
  2542. if (keyUsage & PKIX_ENCIPHER_ONLY){
  2543. nssKeyUsage = nssKeyUsage | 0x01;
  2544. }
  2545. if (keyUsage & PKIX_DECIPHER_ONLY){
  2546. /* XXX we should support this once it is fixed in NSS */
  2547. PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED);
  2548. }
  2549. status = CERT_CheckKeyUsage(nssCert, nssKeyUsage);
  2550. if (status != SECSuccess) {
  2551. PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
  2552. }
  2553. cleanup:
  2554. PKIX_RETURN(CERT);
  2555. }
  2556. /*
  2557. * FUNCTION: PKIX_PL_Cert_GetNameConstraints
  2558. * (see comments in pkix_pl_pki.h)
  2559. */
  2560. PKIX_Error *
  2561. PKIX_PL_Cert_GetNameConstraints(
  2562. PKIX_PL_Cert *cert,
  2563. PKIX_PL_CertNameConstraints **pNameConstraints,
  2564. void *plContext)
  2565. {
  2566. PKIX_PL_CertNameConstraints *nameConstraints = NULL;
  2567. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNameConstraints");
  2568. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pNameConstraints);
  2569. /* if we don't have a cached copy from before, we create one */
  2570. if (cert->nameConstraints == NULL && !cert->nameConstraintsAbsent) {
  2571. PKIX_OBJECT_LOCK(cert);
  2572. if (cert->nameConstraints == NULL &&
  2573. !cert->nameConstraintsAbsent) {
  2574. PKIX_CHECK(pkix_pl_CertNameConstraints_Create
  2575. (cert->nssCert, &nameConstraints, plContext),
  2576. PKIX_CERTNAMECONSTRAINTSCREATEFAILED);
  2577. if (nameConstraints == NULL) {
  2578. cert->nameConstraintsAbsent = PKIX_TRUE;
  2579. }
  2580. cert->nameConstraints = nameConstraints;
  2581. }
  2582. PKIX_OBJECT_UNLOCK(cert);
  2583. }
  2584. PKIX_INCREF(cert->nameConstraints);
  2585. *pNameConstraints = cert->nameConstraints;
  2586. cleanup:
  2587. PKIX_OBJECT_UNLOCK(lockedObject);
  2588. PKIX_RETURN(CERT);
  2589. }
  2590. /*
  2591. * FUNCTION: PKIX_PL_Cert_CheckNameConstraints
  2592. * (see comments in pkix_pl_pki.h)
  2593. */
  2594. PKIX_Error *
  2595. PKIX_PL_Cert_CheckNameConstraints(
  2596. PKIX_PL_Cert *cert,
  2597. PKIX_PL_CertNameConstraints *nameConstraints,
  2598. void *plContext)
  2599. {
  2600. PKIX_Boolean checkPass = PKIX_TRUE;
  2601. CERTGeneralName *nssSubjectNames = NULL;
  2602. PLArenaPool *arena = NULL;
  2603. PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckNameConstraints");
  2604. PKIX_NULLCHECK_ONE(cert);
  2605. if (nameConstraints != NULL) {
  2606. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  2607. if (arena == NULL) {
  2608. PKIX_ERROR(PKIX_OUTOFMEMORY);
  2609. }
  2610. /* This NSS call returns both Subject and Subject Alt Names */
  2611. PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
  2612. nssSubjectNames = CERT_GetCertificateNames
  2613. (cert->nssCert, arena);
  2614. PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
  2615. (nssSubjectNames,
  2616. nameConstraints,
  2617. &checkPass,
  2618. plContext),
  2619. PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED);
  2620. if (checkPass != PKIX_TRUE) {
  2621. PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING);
  2622. }
  2623. }
  2624. cleanup:
  2625. if (arena){
  2626. PORT_FreeArena(arena, PR_FALSE);
  2627. }
  2628. PKIX_RETURN(CERT);
  2629. }
  2630. /*
  2631. * FUNCTION: PKIX_PL_Cert_MergeNameConstraints
  2632. * (see comments in pkix_pl_pki.h)
  2633. */
  2634. PKIX_Error *
  2635. PKIX_PL_Cert_MergeNameConstraints(
  2636. PKIX_PL_CertNameConstraints *firstNC,
  2637. PKIX_PL_CertNameConstraints *secondNC,
  2638. PKIX_PL_CertNameConstraints **pResultNC,
  2639. void *plContext)
  2640. {
  2641. PKIX_PL_CertNameConstraints *mergedNC = NULL;
  2642. PKIX_ENTER(CERT, "PKIX_PL_Cert_MergeNameConstraints");
  2643. PKIX_NULLCHECK_TWO(firstNC, pResultNC);
  2644. if (secondNC == NULL) {
  2645. PKIX_INCREF(firstNC);
  2646. *pResultNC = firstNC;
  2647. goto cleanup;
  2648. }
  2649. PKIX_CHECK(pkix_pl_CertNameConstraints_Merge
  2650. (firstNC, secondNC, &mergedNC, plContext),
  2651. PKIX_CERTNAMECONSTRAINTSMERGEFAILED);
  2652. *pResultNC = mergedNC;
  2653. cleanup:
  2654. PKIX_RETURN(CERT);
  2655. }
  2656. /*
  2657. * FUNCTION: PKIX_PL_Cert_IsCertTrusted
  2658. * (see comments in pkix_pl_pki.h)
  2659. */
  2660. PKIX_Error *
  2661. PKIX_PL_Cert_IsCertTrusted(
  2662. PKIX_PL_Cert *cert,
  2663. PKIX_Boolean trustOnlyUserAnchors,
  2664. PKIX_Boolean *pTrusted,
  2665. void *plContext)
  2666. {
  2667. PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
  2668. SECCertUsage certUsage = 0;
  2669. PKIX_Boolean trusted = PKIX_FALSE;
  2670. SECStatus rv = SECFailure;
  2671. unsigned int requiredFlags;
  2672. SECTrustType trustType;
  2673. CERTCertTrust trust;
  2674. CERTCertificate *nssCert = NULL;
  2675. SECCertificateUsage certificateUsage;
  2676. PKIX_ENTER(CERT, "pkix_pl_Cert_IsCertTrusted");
  2677. PKIX_NULLCHECK_TWO(cert, pTrusted);
  2678. if (trustOnlyUserAnchors) {
  2679. *pTrusted = cert->isUserTrustAnchor;
  2680. goto cleanup;
  2681. }
  2682. /* no key usage information and store is not trusted */
  2683. if (plContext == NULL || cert->store == NULL) {
  2684. *pTrusted = PKIX_FALSE;
  2685. goto cleanup;
  2686. }
  2687. if (cert->store) {
  2688. PKIX_CHECK(PKIX_CertStore_GetTrustCallback
  2689. (cert->store, &trustCallback, plContext),
  2690. PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
  2691. PKIX_CHECK_ONLY_FATAL(trustCallback
  2692. (cert->store, cert, &trusted, plContext),
  2693. PKIX_CHECKTRUSTCALLBACKFAILED);
  2694. if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
  2695. *pTrusted = PKIX_FALSE;
  2696. goto cleanup;
  2697. }
  2698. }
  2699. certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
  2700. /* ensure we obtained a single usage bit only */
  2701. PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
  2702. /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
  2703. while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
  2704. rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType);
  2705. if (rv != SECSuccess) {
  2706. *pTrusted = PKIX_FALSE;
  2707. goto cleanup;
  2708. }
  2709. nssCert = cert->nssCert;
  2710. rv = CERT_GetCertTrust(nssCert, &trust);
  2711. if (rv == SECSuccess) {
  2712. unsigned int certFlags;
  2713. certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType);
  2714. if ((certFlags & requiredFlags) == requiredFlags) {
  2715. trusted = PKIX_TRUE;
  2716. }
  2717. }
  2718. *pTrusted = trusted;
  2719. cleanup:
  2720. PKIX_RETURN(CERT);
  2721. }
  2722. /* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
  2723. PKIX_Error*
  2724. PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,
  2725. void *plContext)
  2726. {
  2727. PKIX_ENTER(CERT, "PKIX_PL_Cert_SetAsTrustAnchor");
  2728. PKIX_NULLCHECK_ONE(cert);
  2729. cert->isUserTrustAnchor = PKIX_TRUE;
  2730. PKIX_RETURN(CERT);
  2731. }
  2732. /*
  2733. * FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h)
  2734. */
  2735. PKIX_Error *
  2736. PKIX_PL_Cert_GetCacheFlag(
  2737. PKIX_PL_Cert *cert,
  2738. PKIX_Boolean *pCacheFlag,
  2739. void *plContext)
  2740. {
  2741. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCacheFlag");
  2742. PKIX_NULLCHECK_TWO(cert, pCacheFlag);
  2743. *pCacheFlag = cert->cacheFlag;
  2744. PKIX_RETURN(CERT);
  2745. }
  2746. /*
  2747. * FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h)
  2748. */
  2749. PKIX_Error *
  2750. PKIX_PL_Cert_SetCacheFlag(
  2751. PKIX_PL_Cert *cert,
  2752. PKIX_Boolean cacheFlag,
  2753. void *plContext)
  2754. {
  2755. PKIX_ENTER(CERT, "PKIX_PL_Cert_SetCacheFlag");
  2756. PKIX_NULLCHECK_ONE(cert);
  2757. cert->cacheFlag = cacheFlag;
  2758. PKIX_RETURN(CERT);
  2759. }
  2760. /*
  2761. * FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h)
  2762. */
  2763. PKIX_Error *
  2764. PKIX_PL_Cert_GetTrustCertStore(
  2765. PKIX_PL_Cert *cert,
  2766. PKIX_CertStore **pTrustCertStore,
  2767. void *plContext)
  2768. {
  2769. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetTrustCertStore");
  2770. PKIX_NULLCHECK_TWO(cert, pTrustCertStore);
  2771. PKIX_INCREF(cert->store);
  2772. *pTrustCertStore = cert->store;
  2773. cleanup:
  2774. PKIX_RETURN(CERT);
  2775. }
  2776. /*
  2777. * FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h)
  2778. */
  2779. PKIX_Error *
  2780. PKIX_PL_Cert_SetTrustCertStore(
  2781. PKIX_PL_Cert *cert,
  2782. PKIX_CertStore *trustCertStore,
  2783. void *plContext)
  2784. {
  2785. PKIX_ENTER(CERT, "PKIX_PL_Cert_SetTrustCertStore");
  2786. PKIX_NULLCHECK_TWO(cert, trustCertStore);
  2787. PKIX_INCREF(trustCertStore);
  2788. cert->store = trustCertStore;
  2789. cleanup:
  2790. PKIX_RETURN(CERT);
  2791. }
  2792. /*
  2793. * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
  2794. * (see comments in pkix_pl_pki.h)
  2795. */
  2796. PKIX_Error *
  2797. PKIX_PL_Cert_GetAuthorityInfoAccess(
  2798. PKIX_PL_Cert *cert,
  2799. PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
  2800. void *plContext)
  2801. {
  2802. PKIX_List *aiaList = NULL; /* of PKIX_PL_InfoAccess */
  2803. SECItem *encodedAIA = NULL;
  2804. CERTAuthInfoAccess **aia = NULL;
  2805. PLArenaPool *arena = NULL;
  2806. SECStatus rv;
  2807. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityInfoAccess");
  2808. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAiaList);
  2809. /* if we don't have a cached copy from before, we create one */
  2810. if (cert->authorityInfoAccess == NULL) {
  2811. PKIX_OBJECT_LOCK(cert);
  2812. if (cert->authorityInfoAccess == NULL) {
  2813. PKIX_PL_NSSCALLRV(CERT, encodedAIA, SECITEM_AllocItem,
  2814. (NULL, NULL, 0));
  2815. if (encodedAIA == NULL) {
  2816. PKIX_ERROR(PKIX_OUTOFMEMORY);
  2817. }
  2818. PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
  2819. (cert->nssCert,
  2820. SEC_OID_X509_AUTH_INFO_ACCESS,
  2821. encodedAIA));
  2822. if (rv == SECFailure) {
  2823. goto cleanup;
  2824. }
  2825. PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
  2826. (DER_DEFAULT_CHUNKSIZE));
  2827. if (arena == NULL) {
  2828. PKIX_ERROR(PKIX_OUTOFMEMORY);
  2829. }
  2830. PKIX_PL_NSSCALLRV
  2831. (CERT, aia, CERT_DecodeAuthInfoAccessExtension,
  2832. (arena, encodedAIA));
  2833. PKIX_CHECK(pkix_pl_InfoAccess_CreateList
  2834. (aia, &aiaList, plContext),
  2835. PKIX_INFOACCESSCREATELISTFAILED);
  2836. cert->authorityInfoAccess = aiaList;
  2837. }
  2838. PKIX_OBJECT_UNLOCK(cert);
  2839. }
  2840. PKIX_INCREF(cert->authorityInfoAccess);
  2841. *pAiaList = cert->authorityInfoAccess;
  2842. cleanup:
  2843. PKIX_OBJECT_UNLOCK(lockedObject);
  2844. if (arena != NULL) {
  2845. PORT_FreeArena(arena, PR_FALSE);
  2846. }
  2847. if (encodedAIA != NULL) {
  2848. SECITEM_FreeItem(encodedAIA, PR_TRUE);
  2849. }
  2850. PKIX_RETURN(CERT);
  2851. }
  2852. /* XXX Following defines belongs to NSS */
  2853. static const unsigned char siaOIDString[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
  2854. 0x07, 0x01, 0x0b};
  2855. #define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
  2856. /*
  2857. * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
  2858. * (see comments in pkix_pl_pki.h)
  2859. */
  2860. PKIX_Error *
  2861. PKIX_PL_Cert_GetSubjectInfoAccess(
  2862. PKIX_PL_Cert *cert,
  2863. PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */
  2864. void *plContext)
  2865. {
  2866. PKIX_List *siaList; /* of PKIX_PL_InfoAccess */
  2867. SECItem siaOID = OI(siaOIDString);
  2868. SECItem *encodedSubjInfoAccess = NULL;
  2869. CERTAuthInfoAccess **subjInfoAccess = NULL;
  2870. PLArenaPool *arena = NULL;
  2871. SECStatus rv;
  2872. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectInfoAccess");
  2873. PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSiaList);
  2874. /* XXX
  2875. * Codes to deal with SubjectInfoAccess OID should be moved to
  2876. * NSS soon. I implemented them here so we don't touch NSS
  2877. * source tree, from JP's suggestion.
  2878. */
  2879. /* if we don't have a cached copy from before, we create one */
  2880. if (cert->subjectInfoAccess == NULL) {
  2881. PKIX_OBJECT_LOCK(cert);
  2882. if (cert->subjectInfoAccess == NULL) {
  2883. encodedSubjInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
  2884. if (encodedSubjInfoAccess == NULL) {
  2885. PKIX_ERROR(PKIX_OUTOFMEMORY);
  2886. }
  2887. PKIX_CERT_DEBUG
  2888. ("\t\tCalling CERT_FindCertExtensionByOID).\n");
  2889. rv = CERT_FindCertExtensionByOID
  2890. (cert->nssCert, &siaOID, encodedSubjInfoAccess);
  2891. if (rv == SECFailure) {
  2892. goto cleanup;
  2893. }
  2894. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  2895. if (arena == NULL) {
  2896. PKIX_ERROR(PKIX_OUTOFMEMORY);
  2897. }
  2898. /* XXX
  2899. * Decode Subject Information Access -
  2900. * since its type is the same as Authority Information
  2901. * Access, reuse the call. NSS- change name to avoid
  2902. * confusion.
  2903. */
  2904. PKIX_CERT_DEBUG
  2905. ("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n");
  2906. subjInfoAccess = CERT_DecodeAuthInfoAccessExtension
  2907. (arena, encodedSubjInfoAccess);
  2908. PKIX_CHECK(pkix_pl_InfoAccess_CreateList
  2909. (subjInfoAccess, &siaList, plContext),
  2910. PKIX_INFOACCESSCREATELISTFAILED);
  2911. cert->subjectInfoAccess = siaList;
  2912. }
  2913. PKIX_OBJECT_UNLOCK(cert);
  2914. }
  2915. PKIX_INCREF(cert->subjectInfoAccess);
  2916. *pSiaList = cert->subjectInfoAccess;
  2917. cleanup:
  2918. PKIX_OBJECT_UNLOCK(lockedObject);
  2919. if (arena != NULL) {
  2920. PORT_FreeArena(arena, PR_FALSE);
  2921. }
  2922. if (encodedSubjInfoAccess != NULL) {
  2923. SECITEM_FreeItem(encodedSubjInfoAccess, PR_TRUE);
  2924. }
  2925. PKIX_RETURN(CERT);
  2926. }
  2927. /*
  2928. * FUNCTION: PKIX_PL_Cert_GetCERTCertificate
  2929. * (see comments in pkix_pl_pki.h)
  2930. */
  2931. PKIX_Error *
  2932. PKIX_PL_Cert_GetCERTCertificate(
  2933. PKIX_PL_Cert *cert,
  2934. CERTCertificate **pnssCert,
  2935. void *plContext)
  2936. {
  2937. PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNssCert");
  2938. PKIX_NULLCHECK_TWO(cert, pnssCert);
  2939. *pnssCert = CERT_DupCertificate(cert->nssCert);
  2940. PKIX_RETURN(CERT);
  2941. }