PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/security/nss/lib/certhigh/certvfypkix.c

https://bitbucket.org/mkato/mozilla-1.9.0-win64
C | 2286 lines | 1529 code | 312 blank | 445 comment | 278 complexity | 91b1ac44c86385175b16fe2a0ba81f4e 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

Large files files are truncated, but you can click here to view the full file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the Netscape security libraries.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Netscape Communications Corporation.
  18. * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. * Sun Microsystems
  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. * nss_pkix_proxy.h
  39. *
  40. * PKIX - NSS proxy functions
  41. *
  42. * NOTE: All structures, functions, data types are parts of library private
  43. * api and are subjects to change in any following releases.
  44. *
  45. */
  46. #include "prerror.h"
  47. #include "prprf.h"
  48. #include "nspr.h"
  49. #include "pk11func.h"
  50. #include "certdb.h"
  51. #include "cert.h"
  52. #include "secerr.h"
  53. #include "nssb64.h"
  54. #include "secasn1.h"
  55. #include "secder.h"
  56. #include "pkit.h"
  57. #include "pkix_pl_common.h"
  58. extern PRLogModuleInfo *pkixLog;
  59. #ifdef DEBUG_volkov
  60. /* Temporary declarations of functioins. Will be removed with fix for
  61. * 391183 */
  62. extern char *
  63. pkix_Error2ASCII(PKIX_Error *error, void *plContext);
  64. extern void
  65. cert_PrintCert(PKIX_PL_Cert *pkixCert, void *plContext);
  66. extern PKIX_Error *
  67. cert_PrintCertChain(PKIX_List *pkixCertChain, void *plContext);
  68. #endif /* DEBUG */
  69. #ifdef PKIX_OBJECT_LEAK_TEST
  70. extern PKIX_UInt32
  71. pkix_pl_lifecycle_ObjectLeakCheck(int *);
  72. extern SECStatus
  73. pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
  74. PRInt32 parallelFnInvocationCount;
  75. #endif /* PKIX_OBJECT_LEAK_TEST */
  76. static PRBool usePKIXValidationEngine = PR_FALSE;
  77. /*
  78. * FUNCTION: CERT_SetUsePKIXForValidation
  79. * DESCRIPTION:
  80. *
  81. * Enables or disables use of libpkix for certificate validation
  82. *
  83. * PARAMETERS:
  84. * "enable"
  85. * PR_TRUE: enables use of libpkix for cert validation.
  86. * PR_FALSE: disables.
  87. * THREAD SAFETY:
  88. * NOT Thread Safe.
  89. * RETURNS:
  90. * Returns SECSuccess if successfully enabled
  91. */
  92. SECStatus
  93. CERT_SetUsePKIXForValidation(PRBool enable)
  94. {
  95. usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
  96. return SECSuccess;
  97. }
  98. /*
  99. * FUNCTION: CERT_GetUsePKIXForValidation
  100. * DESCRIPTION:
  101. *
  102. * Checks if libpkix building function should be use for certificate
  103. * chain building.
  104. *
  105. * PARAMETERS:
  106. * NONE
  107. * THREAD SAFETY:
  108. * NOT Thread Safe
  109. * RETURNS:
  110. * Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise.
  111. */
  112. PRBool
  113. CERT_GetUsePKIXForValidation()
  114. {
  115. return usePKIXValidationEngine;
  116. }
  117. /*
  118. * FUNCTION: cert_NssKeyUsagesToPkix
  119. * DESCRIPTION:
  120. *
  121. * Converts nss key usage bit field(PRUint32) to pkix key usage
  122. * bit field.
  123. *
  124. * PARAMETERS:
  125. * "nssKeyUsage"
  126. * Nss key usage bit field.
  127. * "pkixKeyUsage"
  128. * Pkix key usage big field.
  129. * "plContext"
  130. * Platform-specific context pointer.
  131. * THREAD SAFETY:
  132. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  133. * RETURNS:
  134. * Returns NULL if the function succeeds.
  135. * Returns a Fatal Error if the function fails in an unrecoverable way.
  136. */
  137. static PKIX_Error*
  138. cert_NssKeyUsagesToPkix(
  139. PRUint32 nssKeyUsage,
  140. PKIX_UInt32 *pPkixKeyUsage,
  141. void *plContext)
  142. {
  143. PKIX_UInt32 pkixKeyUsage = 0;
  144. PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix");
  145. PKIX_NULLCHECK_ONE(pPkixKeyUsage);
  146. *pPkixKeyUsage = 0;
  147. if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
  148. pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
  149. }
  150. if (nssKeyUsage & KU_NON_REPUDIATION) {
  151. pkixKeyUsage |= PKIX_NON_REPUDIATION;
  152. }
  153. if (nssKeyUsage & KU_KEY_ENCIPHERMENT) {
  154. pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT;
  155. }
  156. if (nssKeyUsage & KU_DATA_ENCIPHERMENT) {
  157. pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT;
  158. }
  159. if (nssKeyUsage & KU_KEY_AGREEMENT) {
  160. pkixKeyUsage |= PKIX_KEY_AGREEMENT;
  161. }
  162. if (nssKeyUsage & KU_KEY_CERT_SIGN) {
  163. pkixKeyUsage |= PKIX_KEY_CERT_SIGN;
  164. }
  165. if (nssKeyUsage & KU_CRL_SIGN) {
  166. pkixKeyUsage |= PKIX_CRL_SIGN;
  167. }
  168. if (nssKeyUsage & KU_ENCIPHER_ONLY) {
  169. pkixKeyUsage |= PKIX_ENCIPHER_ONLY;
  170. }
  171. /* Not supported. XXX we should support this once it is
  172. * fixed in NSS */
  173. /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */
  174. *pPkixKeyUsage = pkixKeyUsage;
  175. PKIX_RETURN(CERTVFYPKIX);
  176. }
  177. extern char* ekuOidStrings[];
  178. enum {
  179. ekuIndexSSLServer = 0,
  180. ekuIndexSSLClient,
  181. ekuIndexCodeSigner,
  182. ekuIndexEmail,
  183. ekuIndexTimeStamp,
  184. ekuIndexStatusResponder,
  185. ekuIndexUnknown
  186. } ekuIndex;
  187. typedef struct {
  188. SECCertUsage certUsage;
  189. PRUint32 ekuStringIndex;
  190. } SECCertUsageToEku;
  191. const SECCertUsageToEku certUsageEkuStringMap[] = {
  192. {certUsageSSLClient, ekuIndexSSLClient},
  193. {certUsageSSLServer, ekuIndexSSLServer},
  194. {certUsageSSLServerWithStepUp, ekuIndexSSLServer}, /* need to add oids to
  195. * the list of eku.
  196. * see 390381*/
  197. {certUsageSSLCA, ekuIndexSSLServer},
  198. {certUsageEmailSigner, ekuIndexEmail},
  199. {certUsageEmailRecipient, ekuIndexEmail},
  200. {certUsageObjectSigner, ekuIndexCodeSigner},
  201. {certUsageUserCertImport, ekuIndexUnknown},
  202. {certUsageVerifyCA, ekuIndexUnknown},
  203. {certUsageProtectedObjectSigner, ekuIndexUnknown},
  204. {certUsageStatusResponder, ekuIndexStatusResponder},
  205. {certUsageAnyCA, ekuIndexUnknown},
  206. };
  207. #define CERT_USAGE_EKU_STRING_MAPS_TOTAL 12
  208. /*
  209. * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU
  210. * DESCRIPTION:
  211. *
  212. * Converts nss CERTCertificateUsage bit field to pkix key and
  213. * extended key usages.
  214. *
  215. * PARAMETERS:
  216. * "cert"
  217. * Pointer to CERTCertificate structure of validating cert.
  218. * "requiredCertUsages"
  219. * Required usage that will be converted to pkix eku and ku.
  220. * "requiredKeyUsage",
  221. * Additional key usages impose to cert.
  222. * "isCA",
  223. * it true, convert usages for cert that is a CA cert.
  224. * "ppkixEKUList"
  225. * Returned address of a list of pkix extended key usages.
  226. * "ppkixKU"
  227. * Returned address of pkix required key usages bit field.
  228. * "plContext"
  229. * Platform-specific context pointer.
  230. * THREAD SAFETY:
  231. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  232. * RETURNS:
  233. * Returns NULL if the function succeeds.
  234. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  235. * Returns a Fatal Error if the function fails in an unrecoverable way.
  236. */
  237. static PKIX_Error*
  238. cert_NssCertificateUsageToPkixKUAndEKU(
  239. CERTCertificate *cert,
  240. SECCertUsage requiredCertUsage,
  241. PRUint32 requiredKeyUsages,
  242. PRBool isCA,
  243. PKIX_List **ppkixEKUList,
  244. PKIX_UInt32 *ppkixKU,
  245. void *plContext)
  246. {
  247. PKIX_List *ekuOidsList = NULL;
  248. PKIX_PL_OID *ekuOid = NULL;
  249. int i = 0;
  250. int ekuIndex = ekuIndexUnknown;
  251. PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku");
  252. PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU);
  253. PKIX_CHECK(
  254. PKIX_List_Create(&ekuOidsList, plContext),
  255. PKIX_LISTCREATEFAILED);
  256. for (;i < CERT_USAGE_EKU_STRING_MAPS_TOTAL;i++) {
  257. const SECCertUsageToEku *usageToEkuElem =
  258. &certUsageEkuStringMap[i];
  259. if (usageToEkuElem->certUsage == requiredCertUsage) {
  260. ekuIndex = usageToEkuElem->ekuStringIndex;
  261. break;
  262. }
  263. }
  264. if (ekuIndex != ekuIndexUnknown) {
  265. PRUint32 reqKeyUsage = 0;
  266. PRUint32 reqCertType = 0;
  267. CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA,
  268. &reqKeyUsage,
  269. &reqCertType);
  270. requiredKeyUsages |= reqKeyUsage;
  271. PKIX_CHECK(
  272. PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid,
  273. plContext),
  274. PKIX_OIDCREATEFAILED);
  275. PKIX_CHECK(
  276. PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid,
  277. plContext),
  278. PKIX_LISTAPPENDITEMFAILED);
  279. PKIX_DECREF(ekuOid);
  280. }
  281. PKIX_CHECK(
  282. cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext),
  283. PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED);
  284. *ppkixEKUList = ekuOidsList;
  285. ekuOidsList = NULL;
  286. cleanup:
  287. PKIX_DECREF(ekuOid);
  288. PKIX_DECREF(ekuOidsList);
  289. PKIX_RETURN(CERTVFYPKIX);
  290. }
  291. /*
  292. * FUNCTION: cert_ProcessingParamsSetKuAndEku
  293. * DESCRIPTION:
  294. *
  295. * Converts cert usage to pkix KU and EKU types and sets
  296. * converted data into PKIX_ProcessingParams object. It also sets
  297. * proper cert usage into nsscontext object.
  298. *
  299. * PARAMETERS:
  300. * "procParams"
  301. * Pointer to PKIX_ProcessingParams used during validation.
  302. * "requiredCertUsage"
  303. * Required certificate usages the certificate and chain is built and
  304. * validated for.
  305. * "requiredKeyUsage"
  306. * Request additional key usages the certificate should be validated for.
  307. * "isCA"
  308. * Should the cert be verifyed as CA cert for the usages.
  309. * "plContext"
  310. * Platform-specific context pointer.
  311. * THREAD SAFETY:
  312. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  313. * RETURNS:
  314. * Returns NULL if the function succeeds.
  315. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  316. * Returns a Fatal Error if the function fails in an unrecoverable way.
  317. */
  318. static PKIX_Error*
  319. cert_ProcessingParamsSetKuAndEku(
  320. PKIX_ProcessingParams *procParams,
  321. CERTCertificate *cert,
  322. PRBool isCA,
  323. SECCertUsage requiredCertUsage,
  324. PRUint32 requiredKeyUsages,
  325. void *plContext)
  326. {
  327. PKIX_List *extKeyUsage = NULL;
  328. PKIX_CertSelector *certSelector = NULL;
  329. PKIX_ComCertSelParams *certSelParams = NULL;
  330. PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext*)plContext;
  331. PKIX_UInt32 keyUsage = 0;
  332. PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKuAndEku");
  333. PKIX_NULLCHECK_TWO(procParams, nssContext);
  334. PKIX_CHECK(
  335. pkix_pl_NssContext_SetCertUsage(
  336. ((SECCertificateUsage)1) << requiredCertUsage, nssContext),
  337. PKIX_NSSCONTEXTSETCERTUSAGEFAILED);
  338. PKIX_CHECK(
  339. cert_NssCertificateUsageToPkixKUAndEKU(cert, requiredCertUsage,
  340. requiredKeyUsages, isCA,
  341. &extKeyUsage, &keyUsage,
  342. plContext),
  343. PKIX_CANNOTCONVERTCERTUSAGETOPKIXKEYANDEKUSAGES);
  344. PKIX_CHECK(
  345. PKIX_ProcessingParams_GetTargetCertConstraints(procParams,
  346. &certSelector, plContext),
  347. PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
  348. PKIX_CHECK(
  349. PKIX_CertSelector_GetCommonCertSelectorParams(certSelector,
  350. &certSelParams, plContext),
  351. PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
  352. PKIX_CHECK(
  353. PKIX_ComCertSelParams_SetKeyUsage(certSelParams, keyUsage,
  354. plContext),
  355. PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
  356. PKIX_CHECK(
  357. PKIX_ComCertSelParams_SetExtendedKeyUsage(certSelParams,
  358. extKeyUsage,
  359. plContext),
  360. PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED);
  361. cleanup:
  362. PKIX_DECREF(extKeyUsage);
  363. PKIX_DECREF(certSelector);
  364. PKIX_DECREF(certSelParams);
  365. PKIX_RETURN(CERTVFYPKIX);
  366. }
  367. /*
  368. * Unused parameters:
  369. *
  370. * CERTCertList *initialChain,
  371. * CERTCertStores certStores,
  372. * CERTCertRevCheckers certRevCheckers,
  373. * CERTCertChainCheckers certChainCheckers,
  374. * SECItem *initPolicies,
  375. * PRBool policyQualifierRejected,
  376. * PRBool anyPolicyInhibited,
  377. * PRBool reqExplicitPolicy,
  378. * PRBool policyMappingInhibited,
  379. * PKIX_CertSelector certConstraints,
  380. */
  381. /*
  382. * FUNCTION: cert_CreatePkixProcessingParams
  383. * DESCRIPTION:
  384. *
  385. * Creates and fills in PKIX_ProcessingParams structure to be used
  386. * for certificate chain building.
  387. *
  388. * PARAMETERS:
  389. * "cert"
  390. * Pointer to the CERTCertificate: the leaf certificate of a chain.
  391. * "time"
  392. * Validity time.
  393. * "wincx"
  394. * Nss db password token.
  395. * "useArena"
  396. * Flags to use arena for data allocation during chain building process.
  397. * "pprocParams"
  398. * Address to return created processing parameters.
  399. * "plContext"
  400. * Platform-specific context pointer.
  401. * THREAD SAFETY:
  402. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  403. * RETURNS:
  404. * Returns NULL if the function succeeds.
  405. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  406. * Returns a Fatal Error if the function fails in an unrecoverable way.
  407. */
  408. static PKIX_Error*
  409. cert_CreatePkixProcessingParams(
  410. CERTCertificate *cert,
  411. PRBool checkSig, /* not used yet. See bug 391476 */
  412. PRTime time,
  413. void *wincx,
  414. PRBool useArena,
  415. PRBool disableOCSPRemoteFetching,
  416. PKIX_ProcessingParams **pprocParams,
  417. void **pplContext)
  418. {
  419. PKIX_List *anchors = NULL;
  420. PKIX_PL_Cert *targetCert = NULL;
  421. PKIX_PL_Date *date = NULL;
  422. PKIX_ProcessingParams *procParams = NULL;
  423. PKIX_CertSelector *certSelector = NULL;
  424. PKIX_ComCertSelParams *certSelParams = NULL;
  425. PKIX_CertStore *certStore = NULL;
  426. PKIX_List *certStores = NULL;
  427. PKIX_RevocationChecker *revChecker = NULL;
  428. PKIX_UInt32 methodFlags = 0;
  429. void *plContext = NULL;
  430. PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams");
  431. PKIX_NULLCHECK_TWO(cert, pprocParams);
  432. PKIX_CHECK(
  433. PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext),
  434. PKIX_NSSCONTEXTCREATEFAILED);
  435. *pplContext = plContext;
  436. #ifdef PKIX_NOTDEF
  437. /* Functions should be implemented in patch for 390532 */
  438. PKIX_CHECK(
  439. pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
  440. (PKIX_PL_NssContext*)plContext),
  441. PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);
  442. #endif /* PKIX_NOTDEF */
  443. PKIX_CHECK(
  444. PKIX_ProcessingParams_Create(&procParams, plContext),
  445. PKIX_PROCESSINGPARAMSCREATEFAILED);
  446. PKIX_CHECK(
  447. PKIX_ComCertSelParams_Create(&certSelParams, plContext),
  448. PKIX_COMCERTSELPARAMSCREATEFAILED);
  449. PKIX_CHECK(
  450. PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext),
  451. PKIX_CERTCREATEWITHNSSCERTFAILED);
  452. PKIX_CHECK(
  453. PKIX_ComCertSelParams_SetCertificate(certSelParams,
  454. targetCert, plContext),
  455. PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);
  456. PKIX_CHECK(
  457. PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext),
  458. PKIX_COULDNOTCREATECERTSELECTOROBJECT);
  459. PKIX_CHECK(
  460. PKIX_CertSelector_SetCommonCertSelectorParams(certSelector,
  461. certSelParams, plContext),
  462. PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
  463. PKIX_CHECK(
  464. PKIX_ProcessingParams_SetTargetCertConstraints(procParams,
  465. certSelector, plContext),
  466. PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);
  467. PKIX_CHECK(
  468. PKIX_PL_Pk11CertStore_Create(&certStore, plContext),
  469. PKIX_PK11CERTSTORECREATEFAILED);
  470. PKIX_CHECK(
  471. PKIX_List_Create(&certStores, plContext),
  472. PKIX_UNABLETOCREATELIST);
  473. PKIX_CHECK(
  474. PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore,
  475. plContext),
  476. PKIX_LISTAPPENDITEMFAILED);
  477. PKIX_CHECK(
  478. PKIX_ProcessingParams_SetCertStores(procParams, certStores,
  479. plContext),
  480. PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED);
  481. PKIX_CHECK(
  482. PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
  483. PKIX_DATECREATEFROMPRTIMEFAILED);
  484. PKIX_CHECK(
  485. PKIX_ProcessingParams_SetDate(procParams, date, plContext),
  486. PKIX_PROCESSINGPARAMSSETDATEFAILED);
  487. PKIX_CHECK(
  488. PKIX_RevocationChecker_Create(
  489. PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
  490. PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
  491. PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
  492. PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
  493. &revChecker, plContext),
  494. PKIX_REVOCATIONCHECKERCREATEFAILED);
  495. PKIX_CHECK(
  496. PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker,
  497. plContext),
  498. PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);
  499. /* CRL method flags */
  500. methodFlags =
  501. PKIX_REV_M_TEST_USING_THIS_METHOD |
  502. PKIX_REV_M_FORBID_NETWORK_FETCHING |
  503. PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
  504. PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
  505. PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
  506. /* add CRL revocation method to check the leaf certificate */
  507. PKIX_CHECK(
  508. PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
  509. PKIX_RevocationMethod_CRL, methodFlags,
  510. 0, NULL, PKIX_TRUE, plContext),
  511. PKIX_REVOCATIONCHECKERADDMETHODFAILED);
  512. /* add CRL revocation method for other certs in the chain. */
  513. PKIX_CHECK(
  514. PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
  515. PKIX_RevocationMethod_CRL, methodFlags,
  516. 0, NULL, PKIX_FALSE, plContext),
  517. PKIX_REVOCATIONCHECKERADDMETHODFAILED);
  518. /* OCSP method flags */
  519. methodFlags =
  520. PKIX_REV_M_TEST_USING_THIS_METHOD |
  521. PKIX_REV_M_ALLOW_NETWORK_FETCHING | /* 0 */
  522. PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */
  523. PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
  524. PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
  525. PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
  526. /* Disabling ocsp fetching when checking the status
  527. * of ocsp response signer. Here and in the next if,
  528. * adjust flags for ocsp signer cert validation case. */
  529. if (disableOCSPRemoteFetching) {
  530. methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
  531. }
  532. if (ocsp_FetchingFailureIsVerificationFailure()
  533. && !disableOCSPRemoteFetching) {
  534. methodFlags |=
  535. PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
  536. }
  537. /* add OCSP revocation method to check only the leaf certificate.*/
  538. PKIX_CHECK(
  539. PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
  540. PKIX_RevocationMethod_OCSP, methodFlags,
  541. 1, NULL, PKIX_TRUE, plContext),
  542. PKIX_REVOCATIONCHECKERADDMETHODFAILED);
  543. PKIX_CHECK(
  544. PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
  545. plContext),
  546. PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);
  547. PKIX_CHECK(
  548. PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
  549. plContext),
  550. PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);
  551. PKIX_CHECK(
  552. PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
  553. plContext),
  554. PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);
  555. *pprocParams = procParams;
  556. procParams = NULL;
  557. cleanup:
  558. PKIX_DECREF(anchors);
  559. PKIX_DECREF(targetCert);
  560. PKIX_DECREF(date);
  561. PKIX_DECREF(certSelector);
  562. PKIX_DECREF(certSelParams);
  563. PKIX_DECREF(certStore);
  564. PKIX_DECREF(certStores);
  565. PKIX_DECREF(procParams);
  566. PKIX_DECREF(revChecker);
  567. PKIX_RETURN(CERTVFYPKIX);
  568. }
  569. /*
  570. * FUNCTION: cert_PkixToNssCertsChain
  571. * DESCRIPTION:
  572. *
  573. * Converts pkix cert list into nss cert list.
  574. *
  575. * PARAMETERS:
  576. * "pkixCertChain"
  577. * Pkix certificate list.
  578. * "pvalidChain"
  579. * An address of returned nss certificate list.
  580. * "plContext"
  581. * Platform-specific context pointer.
  582. * THREAD SAFETY:
  583. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  584. * RETURNS:
  585. * Returns NULL if the function succeeds.
  586. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  587. * Returns a Fatal Error if the function fails in an unrecoverable way.
  588. */
  589. static PKIX_Error*
  590. cert_PkixToNssCertsChain(
  591. PKIX_List *pkixCertChain,
  592. CERTCertList **pvalidChain,
  593. void *plContext)
  594. {
  595. PRArenaPool *arena = NULL;
  596. CERTCertificate *nssCert = NULL;
  597. CERTCertList *validChain = NULL;
  598. PKIX_PL_Object *certItem = NULL;
  599. PKIX_UInt32 length = 0;
  600. PKIX_UInt32 i = 0;
  601. PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain");
  602. PKIX_NULLCHECK_ONE(pvalidChain);
  603. if (pkixCertChain == NULL) {
  604. goto cleanup;
  605. }
  606. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  607. if (arena == NULL) {
  608. PKIX_ERROR(PKIX_OUTOFMEMORY);
  609. }
  610. validChain = (CERTCertList*)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
  611. if (validChain == NULL) {
  612. PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
  613. }
  614. PR_INIT_CLIST(&validChain->list);
  615. validChain->arena = arena;
  616. arena = NULL;
  617. PKIX_CHECK(
  618. PKIX_List_GetLength(pkixCertChain, &length, plContext),
  619. PKIX_LISTGETLENGTHFAILED);
  620. for (i = 0; i < length; i++){
  621. CERTCertListNode *node = NULL;
  622. PKIX_CHECK(
  623. PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext),
  624. PKIX_LISTGETITEMFAILED);
  625. PKIX_CHECK(
  626. PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert*)certItem, &nssCert,
  627. plContext),
  628. PKIX_CERTGETCERTCERTIFICATEFAILED);
  629. node =
  630. (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
  631. sizeof(CERTCertListNode));
  632. if ( node == NULL ) {
  633. PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
  634. }
  635. PR_INSERT_BEFORE(&node->links, &validChain->list);
  636. node->cert = nssCert;
  637. nssCert = NULL;
  638. PKIX_DECREF(certItem);
  639. }
  640. *pvalidChain = validChain;
  641. cleanup:
  642. if (PKIX_ERROR_RECEIVED){
  643. if (validChain) {
  644. CERT_DestroyCertList(validChain);
  645. } else if (arena) {
  646. PORT_FreeArena(arena, PR_FALSE);
  647. }
  648. if (nssCert) {
  649. CERT_DestroyCertificate(nssCert);
  650. }
  651. }
  652. PKIX_DECREF(certItem);
  653. PKIX_RETURN(CERTVFYPKIX);
  654. }
  655. /*
  656. * FUNCTION: cert_BuildAndValidateChain
  657. * DESCRIPTION:
  658. *
  659. * The function builds and validates a cert chain based on certificate
  660. * selection criterias from procParams. This function call PKIX_BuildChain
  661. * to accomplish chain building. If PKIX_BuildChain returns with incomplete
  662. * IO, the function waits with PR_Poll until the blocking IO is finished and
  663. * return control back to PKIX_BuildChain.
  664. *
  665. * PARAMETERS:
  666. * "procParams"
  667. * Processing parameters to be used during chain building.
  668. * "pResult"
  669. * Returned build result.
  670. * "pVerifyNode"
  671. * Returned pointed to verify node structure: the tree-like structure
  672. * that reports points of chain building failures.
  673. * "plContext"
  674. * Platform-specific context pointer.
  675. * THREAD SAFETY:
  676. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  677. * RETURNS:
  678. * Returns NULL if the function succeeds.
  679. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  680. * Returns a Fatal Error if the function fails in an unrecoverable way.
  681. */
  682. static PKIX_Error*
  683. cert_BuildAndValidateChain(
  684. PKIX_ProcessingParams *procParams,
  685. PKIX_BuildResult **pResult,
  686. PKIX_VerifyNode **pVerifyNode,
  687. void *plContext)
  688. {
  689. PKIX_BuildResult *result = NULL;
  690. PKIX_VerifyNode *verifyNode = NULL;
  691. void *nbioContext = NULL;
  692. void *state = NULL;
  693. PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain");
  694. PKIX_NULLCHECK_TWO(procParams, pResult);
  695. do {
  696. if (nbioContext && state) {
  697. /* PKIX-XXX: need to test functionality of NBIO handling in libPkix.
  698. * See bug 391180 */
  699. PRInt32 filesReady = 0;
  700. PRPollDesc *pollDesc = (PRPollDesc*)nbioContext;
  701. filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
  702. if (filesReady <= 0) {
  703. PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
  704. }
  705. }
  706. PKIX_CHECK(
  707. PKIX_BuildChain(procParams, &nbioContext, &state,
  708. &result, &verifyNode, plContext),
  709. PKIX_UNABLETOBUILDCHAIN);
  710. } while (nbioContext && state);
  711. *pResult = result;
  712. cleanup:
  713. if (pVerifyNode) {
  714. *pVerifyNode = verifyNode;
  715. }
  716. PKIX_RETURN(CERTVFYPKIX);
  717. }
  718. /*
  719. * FUNCTION: cert_PkixErrorToNssCode
  720. * DESCRIPTION:
  721. *
  722. * Converts pkix error(PKIX_Error) structure to PR error codes.
  723. *
  724. * PKIX-XXX to be implemented. See 391183.
  725. *
  726. * PARAMETERS:
  727. * "error"
  728. * Pkix error that will be converted.
  729. * "nssCode"
  730. * Corresponding nss error code.
  731. * "plContext"
  732. * Platform-specific context pointer.
  733. * THREAD SAFETY:
  734. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  735. * RETURNS:
  736. * Returns NULL if the function succeeds.
  737. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  738. * Returns a Fatal Error if the function fails in an unrecoverable way.
  739. */
  740. static PKIX_Error *
  741. cert_PkixErrorToNssCode(
  742. PKIX_Error *error,
  743. SECErrorCodes *pNssErr,
  744. void *plContext)
  745. {
  746. int errLevel = 0;
  747. PKIX_UInt32 nssErr = 0;
  748. PKIX_Error *errPtr = error;
  749. PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode");
  750. PKIX_NULLCHECK_TWO(error, pNssErr);
  751. /* Loop until we find at least one error with non-null
  752. * plErr code, that is going to be nss error code. */
  753. while (errPtr) {
  754. if (errPtr->plErr && !nssErr) {
  755. nssErr = errPtr->plErr;
  756. if (!pkixLog) break;
  757. }
  758. if (pkixLog) {
  759. #ifdef PKIX_ERROR_DESCRIPTION
  760. PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
  761. PKIX_ErrorText[errPtr->errCode]));
  762. #else
  763. PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel,
  764. errPtr->errCode));
  765. #endif /* PKIX_ERROR_DESCRIPTION */
  766. }
  767. errPtr = errPtr->cause;
  768. errLevel += 1;
  769. }
  770. PORT_Assert(nssErr);
  771. if (!nssErr) {
  772. *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL;
  773. } else {
  774. *pNssErr = nssErr;
  775. }
  776. PKIX_RETURN(CERTVFYPKIX);
  777. }
  778. /*
  779. * FUNCTION: cert_GetLogFromVerifyNode
  780. * DESCRIPTION:
  781. *
  782. * Recursive function that converts verify node tree-like set of structures
  783. * to CERTVerifyLog.
  784. *
  785. * PARAMETERS:
  786. * "log"
  787. * Pointed to already allocated CERTVerifyLog structure.
  788. * "node"
  789. * A node of PKIX_VerifyNode tree.
  790. * "plContext"
  791. * Platform-specific context pointer.
  792. * THREAD SAFETY:
  793. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  794. * RETURNS:
  795. * Returns NULL if the function succeeds.
  796. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  797. * Returns a Fatal Error if the function fails in an unrecoverable way.
  798. */
  799. static PKIX_Error *
  800. cert_GetLogFromVerifyNode(
  801. CERTVerifyLog *log,
  802. PKIX_VerifyNode *node,
  803. void *plContext)
  804. {
  805. PKIX_List *children = NULL;
  806. PKIX_VerifyNode *childNode = NULL;
  807. PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
  808. children = node->children;
  809. if (children == NULL) {
  810. PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
  811. if (node->error && node->error->errCode != errCode) {
  812. #ifdef DEBUG_volkov
  813. char *string = pkix_Error2ASCII(node->error, plContext);
  814. fprintf(stderr, "Branch search finished with error: \t%s\n", string);
  815. PKIX_PL_Free(string, NULL);
  816. #endif
  817. if (log != NULL) {
  818. SECErrorCodes nssErrorCode = 0;
  819. CERTCertificate *cert = NULL;
  820. cert = node->verifyCert->nssCert;
  821. PKIX_CHECK(
  822. cert_PkixErrorToNssCode(node->error, &nssErrorCode,
  823. plContext),
  824. PKIX_GETPKIXERRORCODEFAILED);
  825. cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL);
  826. }
  827. }
  828. PKIX_RETURN(CERTVFYPKIX);
  829. } else {
  830. PRUint32 i = 0;
  831. PKIX_UInt32 length = 0;
  832. PKIX_CHECK(
  833. PKIX_List_GetLength(children, &length, plContext),
  834. PKIX_LISTGETLENGTHFAILED);
  835. for (i = 0; i < length; i++){
  836. PKIX_CHECK(
  837. PKIX_List_GetItem(children, i, (PKIX_PL_Object**)&childNode,
  838. plContext),
  839. PKIX_LISTGETITEMFAILED);
  840. PKIX_CHECK(
  841. cert_GetLogFromVerifyNode(log, childNode, plContext),
  842. PKIX_ERRORINRECURSIVEEQUALSCALL);
  843. PKIX_DECREF(childNode);
  844. }
  845. }
  846. cleanup:
  847. PKIX_DECREF(childNode);
  848. PKIX_RETURN(CERTVFYPKIX);
  849. }
  850. /*
  851. * FUNCTION: cert_GetBuildResults
  852. * DESCRIPTION:
  853. *
  854. * Converts pkix build results to nss results. This function is called
  855. * regardless of build result.
  856. *
  857. * If it called after chain was successfully constructed, then it will
  858. * convert:
  859. * * pkix cert list that represent the chain to nss cert list
  860. * * trusted root the chain was anchored to nss certificate.
  861. *
  862. * In case of failure it will convert:
  863. * * pkix error to PR error code(will set it with PORT_SetError)
  864. * * pkix validation log to nss CERTVerifyLog
  865. *
  866. * PARAMETERS:
  867. * "buildResult"
  868. * Build results returned by PKIX_BuildChain.
  869. * "verifyNode"
  870. * Tree-like structure of chain building/validation failures
  871. * returned by PKIX_BuildChain. Ignored in case of success.
  872. * "error"
  873. * Final error returned by PKIX_BuildChain. Should be NULL in
  874. * case of success.
  875. * "log"
  876. * Address of pre-allocated(if not NULL) CERTVerifyLog structure.
  877. * "ptrustedRoot"
  878. * Address of returned trusted root the chain was anchored to.
  879. * "pvalidChain"
  880. * Address of returned valid chain.
  881. * "plContext"
  882. * Platform-specific context pointer.
  883. * THREAD SAFETY:
  884. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  885. * RETURNS:
  886. * Returns NULL if the function succeeds.
  887. * Returns a Cert Verify Error if the function fails in an unrecoverable way.
  888. * Returns a Fatal Error if the function fails in an unrecoverable way.
  889. */
  890. static PKIX_Error*
  891. cert_GetBuildResults(
  892. PKIX_BuildResult *buildResult,
  893. PKIX_VerifyNode *verifyNode,
  894. PKIX_Error *error,
  895. CERTVerifyLog *log,
  896. CERTCertificate **ptrustedRoot,
  897. CERTCertList **pvalidChain,
  898. void *plContext)
  899. {
  900. PKIX_ValidateResult *validResult = NULL;
  901. CERTCertList *validChain = NULL;
  902. CERTCertificate *trustedRoot = NULL;
  903. PKIX_TrustAnchor *trustAnchor = NULL;
  904. PKIX_PL_Cert *trustedCert = NULL;
  905. PKIX_List *pkixCertChain = NULL;
  906. #ifdef DEBUG_volkov
  907. PKIX_Error *tmpPkixError = NULL;
  908. #endif /* DEBUG */
  909. PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
  910. if (buildResult == NULL && error == NULL) {
  911. PKIX_ERROR(PKIX_NULLARGUMENT);
  912. }
  913. if (error) {
  914. SECErrorCodes nssErrorCode = 0;
  915. #ifdef DEBUG_volkov
  916. char *temp = pkix_Error2ASCII(error, plContext);
  917. fprintf(stderr, "BUILD ERROR:\n%s\n", temp);
  918. PKIX_PL_Free(temp, NULL);
  919. #endif /* DEBUG */
  920. if (verifyNode) {
  921. PKIX_Error *tmpError =
  922. cert_GetLogFromVerifyNode(log, verifyNode, plContext);
  923. if (tmpError) {
  924. PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
  925. }
  926. }
  927. cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
  928. PORT_SetError(nssErrorCode);
  929. goto cleanup;
  930. }
  931. if (pvalidChain) {
  932. PKIX_CHECK(
  933. PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
  934. plContext),
  935. PKIX_BUILDRESULTGETCERTCHAINFAILED);
  936. #ifdef DEBUG_volkov
  937. tmpPkixError = cert_PrintCertChain(pkixCertChain, plContext);
  938. if (tmpPkixError) {
  939. PKIX_PL_Object_DecRef((PKIX_PL_Object*)tmpPkixError, plContext);
  940. }
  941. #endif
  942. PKIX_CHECK(
  943. cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
  944. PKIX_CERTCHAINTONSSCHAINFAILED);
  945. }
  946. if (ptrustedRoot) {
  947. PKIX_CHECK(
  948. PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
  949. plContext),
  950. PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
  951. PKIX_CHECK(
  952. PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor,
  953. plContext),
  954. PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
  955. PKIX_CHECK(
  956. PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
  957. plContext),
  958. PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
  959. #ifdef DEBUG_volkov
  960. if (pvalidChain == NULL) {
  961. cert_PrintCert(trustedCert, plContext);
  962. }
  963. #endif
  964. PKIX_CHECK(
  965. PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
  966. plContext),
  967. PKIX_CERTGETCERTCERTIFICATEFAILED);
  968. }
  969. PORT_Assert(!PKIX_ERROR_RECEIVED);
  970. if (trustedRoot) {
  971. *ptrustedRoot = trustedRoot;
  972. }
  973. if (validChain) {
  974. *pvalidChain = validChain;
  975. }
  976. cleanup:
  977. if (PKIX_ERROR_RECEIVED) {
  978. if (trustedRoot) {
  979. CERT_DestroyCertificate(trustedRoot);
  980. }
  981. if (validChain) {
  982. CERT_DestroyCertList(validChain);
  983. }
  984. }
  985. PKIX_DECREF(trustAnchor);
  986. PKIX_DECREF(trustedCert);
  987. PKIX_DECREF(pkixCertChain);
  988. PKIX_DECREF(validResult);
  989. PKIX_DECREF(error);
  990. PKIX_DECREF(verifyNode);
  991. PKIX_DECREF(buildResult);
  992. PKIX_RETURN(CERTVFYPKIX);
  993. }
  994. /*
  995. * FUNCTION: cert_VerifyCertChainPkix
  996. * DESCRIPTION:
  997. *
  998. * The main wrapper function that is called from CERT_VerifyCert and
  999. * CERT_VerifyCACertForUsage functions to validate cert with libpkix.
  1000. *
  1001. * PARAMETERS:
  1002. * "cert"
  1003. * Leaf certificate of a chain we want to build.
  1004. * "checkSig"
  1005. * Certificate signatures will not be verified if this
  1006. * flag is set to PR_FALSE.
  1007. * "requiredUsage"
  1008. * Required usage for certificate and chain.
  1009. * "time"
  1010. * Validity time.
  1011. * "wincx"
  1012. * Nss database password token.
  1013. * "log"
  1014. * Address of already allocated CERTVerifyLog structure. Not
  1015. * used if NULL;
  1016. * "pSigerror"
  1017. * Address of PRBool. If not NULL, returns true is cert chain
  1018. * was invalidated because of bad certificate signature.
  1019. * "pRevoked"
  1020. * Address of PRBool. If not NULL, returns true is cert chain
  1021. * was invalidated because a revoked certificate was found in
  1022. * the chain.
  1023. * THREAD SAFETY:
  1024. * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  1025. * RETURNS:
  1026. * SECFailure is chain building process has failed. SECSuccess otherwise.
  1027. */
  1028. SECStatus
  1029. cert_VerifyCertChainPkix(
  1030. CERTCertificate *cert,
  1031. PRBool checkSig,
  1032. SECCertUsage requiredUsage,
  1033. PRTime time,
  1034. void *wincx,
  1035. CERTVerifyLog *log,
  1036. PRBool *pSigerror,
  1037. PRBool *pRevoked)
  1038. {
  1039. PKIX_ProcessingParams *procParams = NULL;
  1040. PKIX_BuildResult *result = NULL;
  1041. PKIX_VerifyNode *verifyNode = NULL;
  1042. PKIX_Error *error = NULL;
  1043. SECStatus rv = SECFailure;
  1044. void *plContext = NULL;
  1045. #ifdef DEBUG_volkov
  1046. CERTCertificate *trustedRoot = NULL;
  1047. CERTCertList *validChain = NULL;
  1048. #endif /* DEBUG */
  1049. #ifdef PKIX_OBJECT_LEAK_TEST
  1050. int leakedObjNum = 0;
  1051. int memLeakLoopCount = 0;
  1052. int objCountTable[PKIX_NUMTYPES];
  1053. int fnInvLocalCount = 0;
  1054. testStartFnStackPosition = 2;
  1055. fnStackNameArr[0] = "cert_VerifyCertChainPkix";
  1056. fnStackInvCountArr[0] = 0;
  1057. PKIX_Boolean abortOnLeak =
  1058. (PR_GetEnv("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ?
  1059. PKIX_FALSE : PKIX_TRUE;
  1060. runningLeakTest = PKIX_TRUE;
  1061. /* Prevent multi-threaded run of object leak test */
  1062. fnInvLocalCount = PR_AtomicIncrement(&parallelFnInvocationCount);
  1063. PORT_Assert(fnInvLocalCount == 1);
  1064. do {
  1065. rv = SECFailure;
  1066. plContext = NULL;
  1067. procParams = NULL;
  1068. result = NULL;
  1069. verifyNode = NULL;
  1070. error = NULL;
  1071. #ifdef DEBUG_volkov
  1072. trustedRoot = NULL;
  1073. validChain = NULL;
  1074. #endif /* DEBUG */
  1075. errorGenerated = PKIX_FALSE;
  1076. stackPosition = 0;
  1077. if (leakedObjNum) {
  1078. pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
  1079. }
  1080. memLeakLoopCount += 1;
  1081. #endif /* PKIX_OBJECT_LEAK_TEST */
  1082. error =
  1083. cert_CreatePkixProcessingParams(cert, checkSig, time, wincx,
  1084. PR_FALSE/*use arena*/,
  1085. requiredUsage == certUsageStatusResponder,
  1086. &procParams, &plContext);
  1087. if (error) {
  1088. goto cleanup;
  1089. }
  1090. error =
  1091. cert_ProcessingParamsSetKuAndEku(procParams, cert, PR_TRUE,
  1092. requiredUsage, 0, plContext);
  1093. if (error) {
  1094. goto cleanup;
  1095. }
  1096. error =
  1097. cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
  1098. if (error) {
  1099. goto cleanup;
  1100. }
  1101. if (pRevoked) {
  1102. /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
  1103. *pRevoked = PR_FALSE;
  1104. }
  1105. if (pSigerror) {
  1106. /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
  1107. *pSigerror = PR_FALSE;
  1108. }
  1109. rv = SECSuccess;
  1110. cleanup:
  1111. error = cert_GetBuildResults(result, verifyNode, error, log,
  1112. #ifdef DEBUG_volkov
  1113. &trustedRoot, &validChain,
  1114. #else
  1115. NULL, NULL,
  1116. #endif /* DEBUG */
  1117. plContext);
  1118. if (error) {
  1119. #ifdef DEBUG_volkov
  1120. char *temp = pkix_Error2ASCII(error, plContext);
  1121. fprintf(stderr, "GET BUILD RES ERRORS:\n%s\n", temp);
  1122. PKIX_PL_Free(temp, NULL);
  1123. #endif /* DEBUG */
  1124. PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
  1125. }
  1126. #ifdef DEBUG_volkov
  1127. if (trustedRoot) {
  1128. CERT_DestroyCertificate(trustedRoot);
  1129. }
  1130. if (validChain) {
  1131. CERT_DestroyCertList(validChain);
  1132. }
  1133. #endif /* DEBUG */
  1134. if (procParams) {
  1135. PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
  1136. }
  1137. if (plContext) {
  1138. PKIX_PL_NssContext_Destroy(plContext);
  1139. }
  1140. #ifdef PKIX_OBJECT_LEAK_TEST
  1141. leakedObjNum =
  1142. pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
  1143. if (pkixLog && leakedObjNum) {
  1144. PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
  1145. "Stack %s\n", memLeakLoopCount, errorFnStackString));
  1146. }
  1147. PR_Free(errorFnStackString);
  1148. errorFnStackString = NULL;
  1149. if (abortOnLeak) {
  1150. PORT_Assert(leakedObjNum == 0);
  1151. }
  1152. } while (errorGenerated);
  1153. runningLeakTest = PKIX_FALSE;
  1154. PR_AtomicDecrement(&parallelFnInvocationCount);
  1155. #endif /* PKIX_OBJECT_LEAK_TEST */
  1156. return rv;
  1157. }
  1158. PKIX_CertSelector *
  1159. cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
  1160. {
  1161. PKIX_ComCertSelParams *certSelParams = NULL;
  1162. PKIX_CertSelector *certSelector = NULL;
  1163. PKIX_CertSelector *r= NULL;
  1164. PKIX_PL_Cert *eeCert = NULL;
  1165. PKIX_Error *error = NULL;
  1166. error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext);
  1167. if (error != NULL) goto cleanup;
  1168. error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
  1169. if (error != NULL) goto cleanup;
  1170. error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
  1171. if (error != NULL) goto cleanup;
  1172. error = PKIX_ComCertSelParams_SetCertificate(
  1173. certSelParams, eeCert, plContext);
  1174. if (error != NULL) goto cleanup;
  1175. error = PKIX_CertSelector_SetCommonCertSelectorParams
  1176. (certSelector, certSelParams, plContext);
  1177. if (error != NULL) goto cleanup;
  1178. error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext);
  1179. if (error == NULL) r = certSelector;
  1180. cleanup:
  1181. if (certSelParams != NULL)
  1182. PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);
  1183. if (eeCert != NULL)
  1184. PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);
  1185. if (certSelector != NULL)
  1186. PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
  1187. if (error != NULL) {
  1188. SECErrorCodes nssErr;
  1189. cert_PkixErrorToNssCode(error, &nssErr, plContext);
  1190. PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
  1191. PORT_SetError(nssErr);
  1192. }
  1193. return r;
  1194. }
  1195. static PKIX_List *
  1196. cert_GetCertStores(void *plContext)
  1197. {
  1198. PKIX_CertStore *certStore = NULL;
  1199. PKIX_List *certStores = NULL;
  1200. PKIX_List *r = NULL;
  1201. PKIX_Error *error = NULL;
  1202. error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
  1203. if (error != NULL) goto cleanup;
  1204. error = PKIX_List_Create(&certStores, plContext);
  1205. if (error != NULL) goto cleanup;
  1206. error = PKIX_List_AppendItem( certStores,
  1207. (PKIX_PL_Object *)certStore, plContext);
  1208. if (error != NULL) goto cleanup;
  1209. error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext);
  1210. if (error == NULL) r = certStores;
  1211. cleanup:
  1212. if (certStores != NULL)
  1213. PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
  1214. if (certStore != NULL)
  1215. PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);
  1216. if (error != NULL) {
  1217. SECErrorCodes nssErr;
  1218. cert_PkixErrorToNssCode(error, &nssErr, plContext);
  1219. PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
  1220. PORT_SetError(nssErr);
  1221. }
  1222. return r;
  1223. }
  1224. /* XXX
  1225. * There is no NSS SECItem -> PKIX OID
  1226. * conversion function. For now, I go via the ascii
  1227. * representation
  1228. * this should be in PKIX_PL_*
  1229. */
  1230. PKIX_PL_OID *
  1231. CERT_PKIXOIDFromNSSOid(SECOidTag tag, void*plContext)
  1232. {
  1233. char *oidstring = NULL;
  1234. char *oidstring_adj = NULL;
  1235. PKIX_PL_OID *policyOID = NULL;
  1236. SECOidData *data;
  1237. data = SECOID_FindOIDByTag(tag);
  1238. if (data != NULL) {
  1239. oidstring = CERT_GetOidString(&data->oid);
  1240. if (oidstring == NULL) {
  1241. goto cleanup;
  1242. }
  1243. oidstring_adj = oidstring;
  1244. if (PORT_Strncmp("OID.",oidstring_adj,4) == 0) {
  1245. oidstring_adj += 4;
  1246. }
  1247. PKIX_PL_OID_Create(oidstring_adj, &policyOID, plContext);
  1248. }
  1249. cleanup:
  1250. if (oidstring != NULL) PR_smprintf_free(oidstring);
  1251. return policyOID;
  1252. }
  1253. struct fake_PKIX_PL_CertStruct {
  1254. CERTCertificate *nssCert;
  1255. };
  1256. /* This needs to be part of the PKIX_PL_* */
  1257. /* This definitely needs to go away, and be replaced with
  1258. a real accessor function in PKIX */
  1259. CERTCertificate *
  1260. cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert, void *plContext)
  1261. {
  1262. struct fake_PKIX_PL_CertStruct *fcert = NULL;
  1263. fcert = (struct fake_PKIX_PL_CertStruct*)pkix_cert;
  1264. return CERT_DupCertificate(fcert->nssCert);
  1265. }
  1266. PKIX_List *cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
  1267. {
  1268. PKIX_List *r = NULL;
  1269. PKIX_List *policyList = NULL;
  1270. PKIX_PL_OID *policyOID = NULL;
  1271. PKIX_Error *error = NULL;
  1272. int i;
  1273. error = PKIX_List_Create(&policyList, plContext);
  1274. if (error != NULL) {
  1275. goto cleanup;
  1276. }
  1277. for (i=0; i<oidCount; i++) {
  1278. policyOID = CERT_PKIXOIDFromNSSOid(oids[i],plContext);
  1279. if (policyOID == NULL) {
  1280. goto cleanup;
  1281. }
  1282. error = PKIX_List_AppendItem(policyList,
  1283. (PKIX_PL_Object *)policyOID, plContext);
  1284. if (error != NULL) {
  1285. PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
  1286. goto cleanup;
  1287. }
  1288. }
  1289. error = PKIX_List_SetImmutable(policyList, plContext);
  1290. if (error != NULL) goto cleanup;
  1291. error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
  1292. if (error == NULL) r = policyList;
  1293. cleanup:
  1294. if (policyOID != NULL) {
  1295. PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
  1296. }
  1297. if (policyList != NULL) {
  1298. PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
  1299. }
  1300. if (error != NULL) {
  1301. PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
  1302. }
  1303. return r;
  1304. }
  1305. CERTValOutParam *
  1306. cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
  1307. {
  1308. CERTValOutParam *i;
  1309. if (params == NULL) {
  1310. return NULL;
  1311. }
  1312. for (i = params; i->type != cert_po_end; i++) {
  1313. if (i->type == t) {
  1314. return i;
  1315. }
  1316. }
  1317. return NULL;
  1318. }
  1319. static PKIX_Error*
  1320. setRevocationMethod(PKIX_RevocationChecker *revChecker,
  1321. PKIX_ProcessingParams *procParams,
  1322. const CERTRevocationTests *revTest,
  1323. CERTRevocationMethodIndex certRevMethod,
  1324. PKIX_RevocationMethodType pkixRevMethod,
  1325. PKIX_Boolean verifyResponderUsages,
  1326. PKIX_Boolean isLeafTest,
  1327. void *plContext)
  1328. {
  1329. PKIX_UInt32 methodFlags = 0;
  1330. PKIX_Error *error = NULL;
  1331. int priority = 0;
  1332. if (revTest->number_of_defined_methods < certRevMethod) {
  1333. return NULL;
  1334. }
  1335. if (revTest->preferred_methods) {
  1336. int i = 0;
  1337. for (;i < revTest->number_of_preferred_methods;i++) {
  1338. if (revTest->preferred_methods[i] == certRevMethod)
  1339. break;
  1340. }
  1341. priority = i;
  1342. }
  1343. methodFlags = revTest->cert_rev_flags_per_method[certRevMethod];
  1344. if (verifyResponderUsages &&
  1345. pkixRevMethod == PKIX_RevocationMethod_OCSP) {
  1346. methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
  1347. }
  1348. error =
  1349. PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
  1350. pkixRevMethod, methodFlags,
  1351. priority, NULL,
  1352. isLeafTest, plContext);
  1353. return error;
  1354. }
  1355. SECStatus
  1356. cert_pkixSetParam(PKIX_ProcessingParams *procParams,
  1357. const CERTValInParam *param, void *plContext)
  1358. {
  1359. PKIX_Error * error = NULL;
  1360. SECStatus r=SECSuccess;
  1361. PKIX_PL_Date *date = NULL;
  1362. PKIX_List *policyOIDList = NULL;
  1363. PKIX_List *certListPkix = NULL;
  1364. const CERTRevocationFlags *flags;
  1365. SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS;
  1366. const CERTCertList *certList = NULL;
  1367. CERTCertListNode *node;
  1368. PKIX_PL_Cert *certPkix = NULL;
  1369. PKIX_TrustAnchor *trustAnchor = NULL;
  1370. PKIX_PL_Date *revDate = NULL;
  1371. PKIX_RevocationChecker *revChecker = NULL;
  1372. /* XXX we need a way to map generic PKIX error to generic NSS errors */
  1373. switch (param->type) {
  1374. case cert_pi_policyOID:
  1375. /* needed? */
  1376. error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
  1377. procParams, PKIX_TRUE, plContext);
  1378. if (error != NULL) {
  1379. break;
  1380. }
  1381. policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids,
  1382. param->value.arraySize,plContext);
  1383. if (policyOIDList == NULL) {
  1384. r = SECFailure;
  1385. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  1386. break;
  1387. }
  1388. error = PKIX_ProcessingParams_SetInitialPolicies(

Large files files are truncated, but you can click here to view the full file