12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- * nss_pkix_proxy.h
- *
- * PKIX - NSS proxy functions
- *
- * NOTE: All structures, functions, data types are parts of library private
- * api and are subjects to change in any following releases.
- *
- */
- #include "prerror.h"
- #include "prprf.h"
- #include "nspr.h"
- #include "pk11func.h"
- #include "certdb.h"
- #include "cert.h"
- #include "secerr.h"
- #include "nssb64.h"
- #include "secasn1.h"
- #include "secder.h"
- #include "pkit.h"
- #ifndef NSS_DISABLE_LIBPKIX
- #include "pkix_pl_common.h"
- extern PRLogModuleInfo *pkixLog;
- #ifdef PKIX_OBJECT_LEAK_TEST
- extern PKIX_UInt32
- pkix_pl_lifecycle_ObjectLeakCheck(int *);
- extern SECStatus
- pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
- PRInt32 parallelFnInvocationCount;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- static PRBool usePKIXValidationEngine = PR_FALSE;
- #endif /* NSS_DISABLE_LIBPKIX */
- /*
- * FUNCTION: CERT_SetUsePKIXForValidation
- * DESCRIPTION:
- *
- * Enables or disables use of libpkix for certificate validation
- *
- * PARAMETERS:
- * "enable"
- * PR_TRUE: enables use of libpkix for cert validation.
- * PR_FALSE: disables.
- * THREAD SAFETY:
- * NOT Thread Safe.
- * RETURNS:
- * Returns SECSuccess if successfully enabled
- */
- SECStatus
- CERT_SetUsePKIXForValidation(PRBool enable)
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
- #else
- usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
- return SECSuccess;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- /*
- * FUNCTION: CERT_GetUsePKIXForValidation
- * DESCRIPTION:
- *
- * Checks if libpkix building function should be use for certificate
- * chain building.
- *
- * PARAMETERS:
- * NONE
- * THREAD SAFETY:
- * NOT Thread Safe
- * RETURNS:
- * Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise.
- */
- PRBool
- CERT_GetUsePKIXForValidation()
- {
- #ifdef NSS_DISABLE_LIBPKIX
- return PR_FALSE;
- #else
- return usePKIXValidationEngine;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- #ifndef NSS_DISABLE_LIBPKIX
- #ifdef NOTDEF
- /*
- * FUNCTION: cert_NssKeyUsagesToPkix
- * DESCRIPTION:
- *
- * Converts nss key usage bit field(PRUint32) to pkix key usage
- * bit field.
- *
- * PARAMETERS:
- * "nssKeyUsage"
- * Nss key usage bit field.
- * "pkixKeyUsage"
- * Pkix key usage big field.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_NssKeyUsagesToPkix(
- PRUint32 nssKeyUsage,
- PKIX_UInt32 *pPkixKeyUsage,
- void *plContext)
- {
- PKIX_UInt32 pkixKeyUsage = 0;
- PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix");
- PKIX_NULLCHECK_ONE(pPkixKeyUsage);
- *pPkixKeyUsage = 0;
- if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
- pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
- }
- if (nssKeyUsage & KU_NON_REPUDIATION) {
- pkixKeyUsage |= PKIX_NON_REPUDIATION;
- }
- if (nssKeyUsage & KU_KEY_ENCIPHERMENT) {
- pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT;
- }
- if (nssKeyUsage & KU_DATA_ENCIPHERMENT) {
- pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT;
- }
- if (nssKeyUsage & KU_KEY_AGREEMENT) {
- pkixKeyUsage |= PKIX_KEY_AGREEMENT;
- }
- if (nssKeyUsage & KU_KEY_CERT_SIGN) {
- pkixKeyUsage |= PKIX_KEY_CERT_SIGN;
- }
- if (nssKeyUsage & KU_CRL_SIGN) {
- pkixKeyUsage |= PKIX_CRL_SIGN;
- }
- if (nssKeyUsage & KU_ENCIPHER_ONLY) {
- pkixKeyUsage |= PKIX_ENCIPHER_ONLY;
- }
- /* Not supported. XXX we should support this once it is
- * fixed in NSS */
- /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */
- *pPkixKeyUsage = pkixKeyUsage;
- PKIX_RETURN(CERTVFYPKIX);
- }
- extern SECOidTag ekuOidStrings[];
- enum {
- ekuIndexSSLServer = 0,
- ekuIndexSSLClient,
- ekuIndexCodeSigner,
- ekuIndexEmail,
- ekuIndexTimeStamp,
- ekuIndexStatusResponder,
- ekuIndexUnknown
- } ekuIndex;
- typedef struct {
- SECCertUsage certUsage;
- PRUint32 ekuStringIndex;
- } SECCertUsageToEku;
- const SECCertUsageToEku certUsageEkuStringMap[] = {
- { certUsageSSLClient, ekuIndexSSLClient },
- { certUsageSSLServer, ekuIndexSSLServer },
- { certUsageSSLCA, ekuIndexSSLServer },
- { certUsageEmailSigner, ekuIndexEmail },
- { certUsageEmailRecipient, ekuIndexEmail },
- { certUsageObjectSigner, ekuIndexCodeSigner },
- { certUsageUserCertImport, ekuIndexUnknown },
- { certUsageVerifyCA, ekuIndexUnknown },
- { certUsageProtectedObjectSigner, ekuIndexUnknown },
- { certUsageStatusResponder, ekuIndexStatusResponder },
- { certUsageAnyCA, ekuIndexUnknown },
- };
- /*
- * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU
- * DESCRIPTION:
- *
- * Converts nss CERTCertificateUsage bit field to pkix key and
- * extended key usages.
- *
- * PARAMETERS:
- * "cert"
- * Pointer to CERTCertificate structure of validating cert.
- * "requiredCertUsages"
- * Required usage that will be converted to pkix eku and ku.
- * "requiredKeyUsage",
- * Additional key usages impose to cert.
- * "isCA",
- * it true, convert usages for cert that is a CA cert.
- * "ppkixEKUList"
- * Returned address of a list of pkix extended key usages.
- * "ppkixKU"
- * Returned address of pkix required key usages bit field.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_NssCertificateUsageToPkixKUAndEKU(
- CERTCertificate *cert,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- PRBool isCA,
- PKIX_List **ppkixEKUList,
- PKIX_UInt32 *ppkixKU,
- void *plContext)
- {
- PKIX_List *ekuOidsList = NULL;
- PKIX_PL_OID *ekuOid = NULL;
- int i = 0;
- int ekuIndex = ekuIndexUnknown;
- PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku");
- PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU);
- PKIX_CHECK(
- PKIX_List_Create(&ekuOidsList, plContext),
- PKIX_LISTCREATEFAILED);
- for (; i < PR_ARRAY_SIZE(certUsageEkuStringMap); i++) {
- const SECCertUsageToEku *usageToEkuElem =
- &certUsageEkuStringMap[i];
- if (usageToEkuElem->certUsage == requiredCertUsage) {
- ekuIndex = usageToEkuElem->ekuStringIndex;
- break;
- }
- }
- if (ekuIndex != ekuIndexUnknown) {
- PRUint32 reqKeyUsage = 0;
- PRUint32 reqCertType = 0;
- CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA,
- &reqKeyUsage,
- &reqCertType);
- requiredKeyUsages |= reqKeyUsage;
- PKIX_CHECK(
- PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid,
- plContext),
- PKIX_OIDCREATEFAILED);
- PKIX_CHECK(
- PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(ekuOid);
- }
- PKIX_CHECK(
- cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext),
- PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED);
- *ppkixEKUList = ekuOidsList;
- ekuOidsList = NULL;
- cleanup:
- PKIX_DECREF(ekuOid);
- PKIX_DECREF(ekuOidsList);
- PKIX_RETURN(CERTVFYPKIX);
- }
- #endif
- /*
- * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage
- * DESCRIPTION:
- *
- * Converts cert usage to pkix KU type and sets
- * converted data into PKIX_ProcessingParams object. It also sets
- * proper cert usage into nsscontext object.
- *
- * PARAMETERS:
- * "procParams"
- * Pointer to PKIX_ProcessingParams used during validation.
- * "requiredCertUsage"
- * Required certificate usages the certificate and chain is built and
- * validated for.
- * "requiredKeyUsage"
- * Request additional key usages the certificate should be validated for.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_ProcessingParamsSetKeyAndCertUsage(
- PKIX_ProcessingParams *procParams,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- void *plContext)
- {
- PKIX_CertSelector *certSelector = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
- PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage");
- PKIX_NULLCHECK_TWO(procParams, nssContext);
- PKIX_CHECK(
- pkix_pl_NssContext_SetCertUsage(
- ((SECCertificateUsage)1) << requiredCertUsage, nssContext),
- PKIX_NSSCONTEXTSETCERTUSAGEFAILED);
- if (requiredKeyUsages) {
- PKIX_CHECK(
- PKIX_ProcessingParams_GetTargetCertConstraints(procParams,
- &certSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
- PKIX_CHECK(
- PKIX_CertSelector_GetCommonCertSelectorParams(certSelector,
- &certSelParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetKeyUsage(certSelParams, requiredKeyUsages,
- plContext),
- PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
- }
- cleanup:
- PKIX_DECREF(certSelector);
- PKIX_DECREF(certSelParams);
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * Unused parameters:
- *
- * CERTCertList *initialChain,
- * CERTCertStores certStores,
- * CERTCertRevCheckers certRevCheckers,
- * CERTCertChainCheckers certChainCheckers,
- * SECItem *initPolicies,
- * PRBool policyQualifierRejected,
- * PRBool anyPolicyInhibited,
- * PRBool reqExplicitPolicy,
- * PRBool policyMappingInhibited,
- * PKIX_CertSelector certConstraints,
- */
- /*
- * FUNCTION: cert_CreatePkixProcessingParams
- * DESCRIPTION:
- *
- * Creates and fills in PKIX_ProcessingParams structure to be used
- * for certificate chain building.
- *
- * PARAMETERS:
- * "cert"
- * Pointer to the CERTCertificate: the leaf certificate of a chain.
- * "time"
- * Validity time.
- * "wincx"
- * Nss db password token.
- * "useArena"
- * Flags to use arena for data allocation during chain building process.
- * "pprocParams"
- * Address to return created processing parameters.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_CreatePkixProcessingParams(
- CERTCertificate *cert,
- PRBool checkSig, /* not used yet. See bug 391476 */
- PRTime time,
- void *wincx,
- PRBool useArena,
- PRBool disableOCSPRemoteFetching,
- PKIX_ProcessingParams **pprocParams,
- void **pplContext)
- {
- PKIX_List *anchors = NULL;
- PKIX_PL_Cert *targetCert = NULL;
- PKIX_PL_Date *date = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertStore *certStore = NULL;
- PKIX_List *certStores = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_UInt32 methodFlags = 0;
- void *plContext = NULL;
- CERTStatusConfig *statusConfig = NULL;
- PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams");
- PKIX_NULLCHECK_TWO(cert, pprocParams);
- PKIX_CHECK(
- PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext),
- PKIX_NSSCONTEXTCREATEFAILED);
- *pplContext = plContext;
- #ifdef PKIX_NOTDEF
- /* Functions should be implemented in patch for 390532 */
- PKIX_CHECK(
- pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
- (PKIX_PL_NssContext *)plContext),
- PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);
- #endif /* PKIX_NOTDEF */
- PKIX_CHECK(
- PKIX_ProcessingParams_Create(&procParams, plContext),
- PKIX_PROCESSINGPARAMSCREATEFAILED);
- PKIX_CHECK(
- PKIX_ComCertSelParams_Create(&certSelParams, plContext),
- PKIX_COMCERTSELPARAMSCREATEFAILED);
- PKIX_CHECK(
- PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetCertificate(certSelParams,
- targetCert, plContext),
- PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);
- PKIX_CHECK(
- PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext),
- PKIX_COULDNOTCREATECERTSELECTOROBJECT);
- PKIX_CHECK(
- PKIX_CertSelector_SetCommonCertSelectorParams(certSelector,
- certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetTargetCertConstraints(procParams,
- certSelector, plContext),
- PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);
- /* Turn off quialification of target cert since leaf cert is
- * already check for date validity, key usages and extended
- * key usages. */
- PKIX_CHECK(
- PKIX_ProcessingParams_SetQualifyTargetCert(procParams, PKIX_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED);
- PKIX_CHECK(
- PKIX_PL_Pk11CertStore_Create(&certStore, plContext),
- PKIX_PK11CERTSTORECREATEFAILED);
- PKIX_CHECK(
- PKIX_List_Create(&certStores, plContext),
- PKIX_UNABLETOCREATELIST);
- PKIX_CHECK(
- PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetCertStores(procParams, certStores,
- plContext),
- PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED);
- PKIX_CHECK(
- PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
- PKIX_DATECREATEFROMPRTIMEFAILED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetDate(procParams, date, plContext),
- PKIX_PROCESSINGPARAMSSETDATEFAILED);
- PKIX_CHECK(
- PKIX_RevocationChecker_Create(
- PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
- PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
- PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
- PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
- &revChecker, plContext),
- PKIX_REVOCATIONCHECKERCREATEFAILED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker,
- plContext),
- PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);
- /* CRL method flags */
- methodFlags =
- PKIX_REV_M_TEST_USING_THIS_METHOD |
- PKIX_REV_M_FORBID_NETWORK_FETCHING |
- PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
- PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
- PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
- /* add CRL revocation method to check the leaf certificate */
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_CRL, methodFlags,
- 0, NULL, PKIX_TRUE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
- /* add CRL revocation method for other certs in the chain. */
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_CRL, methodFlags,
- 0, NULL, PKIX_FALSE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
- /* For compatibility with the old code, need to check that
- * statusConfig is set in the db handle and status checker
- * is defined befor allow ocsp status check on the leaf cert.*/
- statusConfig = CERT_GetStatusConfig(CERT_GetDefaultCertDB());
- if (statusConfig != NULL && statusConfig->statusChecker != NULL) {
- /* Enable OCSP revocation checking for the leaf cert. */
- /* OCSP method flags */
- methodFlags =
- PKIX_REV_M_TEST_USING_THIS_METHOD |
- PKIX_REV_M_ALLOW_NETWORK_FETCHING | /* 0 */
- PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */
- PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
- PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
- PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
- /* Disabling ocsp fetching when checking the status
- * of ocsp response signer. Here and in the next if,
- * adjust flags for ocsp signer cert validation case. */
- if (disableOCSPRemoteFetching) {
- methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
- }
- if (ocsp_FetchingFailureIsVerificationFailure() &&
- !disableOCSPRemoteFetching) {
- methodFlags |=
- PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
- }
- /* add OCSP revocation method to check only the leaf certificate.*/
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_OCSP, methodFlags,
- 1, NULL, PKIX_TRUE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
- }
- PKIX_CHECK(
- PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);
- PKIX_CHECK(
- PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);
- *pprocParams = procParams;
- procParams = NULL;
- cleanup:
- PKIX_DECREF(anchors);
- PKIX_DECREF(targetCert);
- PKIX_DECREF(date);
- PKIX_DECREF(certSelector);
- PKIX_DECREF(certSelParams);
- PKIX_DECREF(certStore);
- PKIX_DECREF(certStores);
- PKIX_DECREF(procParams);
- PKIX_DECREF(revChecker);
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * FUNCTION: cert_PkixToNssCertsChain
- * DESCRIPTION:
- *
- * Converts pkix cert list into nss cert list.
- *
- * PARAMETERS:
- * "pkixCertChain"
- * Pkix certificate list.
- * "pvalidChain"
- * An address of returned nss certificate list.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_PkixToNssCertsChain(
- PKIX_List *pkixCertChain,
- CERTCertList **pvalidChain,
- void *plContext)
- {
- PLArenaPool *arena = NULL;
- CERTCertificate *nssCert = NULL;
- CERTCertList *validChain = NULL;
- PKIX_PL_Object *certItem = NULL;
- PKIX_UInt32 length = 0;
- PKIX_UInt32 i = 0;
- PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain");
- PKIX_NULLCHECK_ONE(pvalidChain);
- if (pkixCertChain == NULL) {
- goto cleanup;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- validChain = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
- if (validChain == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
- PR_INIT_CLIST(&validChain->list);
- validChain->arena = arena;
- arena = NULL;
- PKIX_CHECK(
- PKIX_List_GetLength(pkixCertChain, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
- for (i = 0; i < length; i++) {
- CERTCertListNode *node = NULL;
- PKIX_CHECK(
- PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert *)certItem, &nssCert,
- plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
- node =
- (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
- sizeof(CERTCertListNode));
- if (node == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
- PR_INSERT_BEFORE(&node->links, &validChain->list);
- node->cert = nssCert;
- nssCert = NULL;
- PKIX_DECREF(certItem);
- }
- *pvalidChain = validChain;
- cleanup:
- if (PKIX_ERROR_RECEIVED) {
- if (validChain) {
- CERT_DestroyCertList(validChain);
- } else if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if (nssCert) {
- CERT_DestroyCertificate(nssCert);
- }
- }
- PKIX_DECREF(certItem);
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * FUNCTION: cert_BuildAndValidateChain
- * DESCRIPTION:
- *
- * The function builds and validates a cert chain based on certificate
- * selection criterias from procParams. This function call PKIX_BuildChain
- * to accomplish chain building. If PKIX_BuildChain returns with incomplete
- * IO, the function waits with PR_Poll until the blocking IO is finished and
- * return control back to PKIX_BuildChain.
- *
- * PARAMETERS:
- * "procParams"
- * Processing parameters to be used during chain building.
- * "pResult"
- * Returned build result.
- * "pVerifyNode"
- * Returned pointed to verify node structure: the tree-like structure
- * that reports points of chain building failures.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_BuildAndValidateChain(
- PKIX_ProcessingParams *procParams,
- PKIX_BuildResult **pResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext)
- {
- PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- void *nbioContext = NULL;
- void *state = NULL;
- PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain");
- PKIX_NULLCHECK_TWO(procParams, pResult);
- do {
- if (nbioContext && state) {
- /* PKIX-XXX: need to test functionality of NBIO handling in libPkix.
- * See bug 391180 */
- PRInt32 filesReady = 0;
- PRPollDesc *pollDesc = (PRPollDesc *)nbioContext;
- filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
- if (filesReady <= 0) {
- PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
- }
- }
- PKIX_CHECK(
- PKIX_BuildChain(procParams, &nbioContext, &state,
- &result, &verifyNode, plContext),
- PKIX_UNABLETOBUILDCHAIN);
- } while (nbioContext && state);
- *pResult = result;
- cleanup:
- if (pVerifyNode) {
- *pVerifyNode = verifyNode;
- }
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * FUNCTION: cert_PkixErrorToNssCode
- * DESCRIPTION:
- *
- * Converts pkix error(PKIX_Error) structure to PR error codes.
- *
- * PKIX-XXX to be implemented. See 391183.
- *
- * PARAMETERS:
- * "error"
- * Pkix error that will be converted.
- * "nssCode"
- * Corresponding nss error code.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_PkixErrorToNssCode(
- PKIX_Error *error,
- SECErrorCodes *pNssErr,
- void *plContext)
- {
- int errLevel = 0;
- PKIX_Int32 nssErr = 0;
- PKIX_Error *errPtr = error;
- PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode");
- PKIX_NULLCHECK_TWO(error, pNssErr);
- /* Loop until we find at least one error with non-null
- * plErr code, that is going to be nss error code. */
- while (errPtr) {
- if (errPtr->plErr && !nssErr) {
- nssErr = errPtr->plErr;
- if (!pkixLog)
- break;
- }
- if (pkixLog) {
- #ifdef PKIX_ERROR_DESCRIPTION
- PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
- PKIX_ErrorText[errPtr->errCode]));
- #else
- PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel,
- errPtr->errCode));
- #endif /* PKIX_ERROR_DESCRIPTION */
- }
- errPtr = errPtr->cause;
- errLevel += 1;
- }
- PORT_Assert(nssErr);
- if (!nssErr) {
- *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL;
- } else {
- *pNssErr = nssErr;
- }
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * FUNCTION: cert_GetLogFromVerifyNode
- * DESCRIPTION:
- *
- * Recursive function that converts verify node tree-like set of structures
- * to CERTVerifyLog.
- *
- * PARAMETERS:
- * "log"
- * Pointed to already allocated CERTVerifyLog structure.
- * "node"
- * A node of PKIX_VerifyNode tree.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_GetLogFromVerifyNode(
- CERTVerifyLog *log,
- PKIX_VerifyNode *node,
- void *plContext)
- {
- PKIX_List *children = NULL;
- PKIX_VerifyNode *childNode = NULL;
- PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
- children = node->children;
- if (children == NULL) {
- PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
- if (node->error && node->error->errCode != errCode) {
- if (log != NULL) {
- SECErrorCodes nssErrorCode = 0;
- CERTCertificate *cert = NULL;
- cert = node->verifyCert->nssCert;
- PKIX_CHECK(
- cert_PkixErrorToNssCode(node->error, &nssErrorCode,
- plContext),
- PKIX_GETPKIXERRORCODEFAILED);
- cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL);
- }
- }
- PKIX_RETURN(CERTVFYPKIX);
- } else {
- PRUint32 i = 0;
- PKIX_UInt32 length = 0;
- PKIX_CHECK(
- PKIX_List_GetLength(children, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
- for (i = 0; i < length; i++) {
- PKIX_CHECK(
- PKIX_List_GetItem(children, i, (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(
- cert_GetLogFromVerifyNode(log, childNode, plContext),
- PKIX_ERRORINRECURSIVEEQUALSCALL);
- PKIX_DECREF(childNode);
- }
- }
- cleanup:
- PKIX_DECREF(childNode);
- PKIX_RETURN(CERTVFYPKIX);
- }
- /*
- * FUNCTION: cert_GetBuildResults
- * DESCRIPTION:
- *
- * Converts pkix build results to nss results. This function is called
- * regardless of build result.
- *
- * If it called after chain was successfully constructed, then it will
- * convert:
- * * pkix cert list that represent the chain to nss cert list
- * * trusted root the chain was anchored to nss certificate.
- *
- * In case of failure it will convert:
- * * pkix error to PR error code(will set it with PORT_SetError)
- * * pkix validation log to nss CERTVerifyLog
- *
- * PARAMETERS:
- * "buildResult"
- * Build results returned by PKIX_BuildChain.
- * "verifyNode"
- * Tree-like structure of chain building/validation failures
- * returned by PKIX_BuildChain. Ignored in case of success.
- * "error"
- * Final error returned by PKIX_BuildChain. Should be NULL in
- * case of success.
- * "log"
- * Address of pre-allocated(if not NULL) CERTVerifyLog structure.
- * "ptrustedRoot"
- * Address of returned trusted root the chain was anchored to.
- * "pvalidChain"
- * Address of returned valid chain.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
- static PKIX_Error *
- cert_GetBuildResults(
- PKIX_BuildResult *buildResult,
- PKIX_VerifyNode *verifyNode,
- PKIX_Error *error,
- CERTVerifyLog *log,
- CERTCertificate **ptrustedRoot,
- CERTCertList **pvalidChain,
- void *plContext)
- {
- PKIX_ValidateResult *validResult = NULL;
- CERTCertList *validChain = NULL;
- CERTCertificate *trustedRoot = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_List *pkixCertChain = NULL;
- PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
- if (buildResult == NULL && error == NULL) {
- PKIX_ERROR(PKIX_NULLARGUMENT);
- }
- if (error) {
- SECErrorCodes nssErrorCode = 0;
- if (verifyNode) {
- PKIX_Error *tmpError =
- cert_GetLogFromVerifyNode(log, verifyNode, plContext);
- if (tmpError) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
- }
- }
- cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
- PORT_SetError(nssErrorCode);
- goto cleanup;
- }
- if (pvalidChain) {
- PKIX_CHECK(
- PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
- plContext),
- PKIX_BUILDRESULTGETCERTCHAINFAILED);
- PKIX_CHECK(
- cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
- PKIX_CERTCHAINTONSSCHAINFAILED);
- }
- if (ptrustedRoot) {
- PKIX_CHECK(
- PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
- plContext),
- PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
- PKIX_CHECK(
- PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor,
- plContext),
- PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
- PKIX_CHECK(
- PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
- plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
- plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
- }
- PORT_Assert(!PKIX_ERROR_RECEIVED);
- if (trustedRoot) {
- *ptrustedRoot = trustedRoot;
- }
- if (validChain) {
- *pvalidChain = validChain;
- }
- cleanup:
- if (PKIX_ERROR_RECEIVED) {
- if (trustedRoot) {
- CERT_DestroyCertificate(trustedRoot);
- }
- if (validChain) {
- CERT_DestroyCertList(validChain);
- }
- }
- PKIX_DECREF(trustAnchor);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(pkixCertChain);
- PKIX_DECREF(validResult);
- PKIX_DECREF(error);
- PKIX_DECREF(verifyNode);
- PKIX_DECREF(buildResult);
- PKIX_RETURN(CERTVFYPKIX);
- }
- #endif /* NSS_DISABLE_LIBPKIX */
- /*
- * FUNCTION: cert_VerifyCertChainPkix
- * DESCRIPTION:
- *
- * The main wrapper function that is called from CERT_VerifyCert and
- * CERT_VerifyCACertForUsage functions to validate cert with libpkix.
- *
- * PARAMETERS:
- * "cert"
- * Leaf certificate of a chain we want to build.
- * "checkSig"
- * Certificate signatures will not be verified if this
- * flag is set to PR_FALSE.
- * "requiredUsage"
- * Required usage for certificate and chain.
- * "time"
- * Validity time.
- * "wincx"
- * Nss database password token.
- * "log"
- * Address of already allocated CERTVerifyLog structure. Not
- * used if NULL;
- * "pSigerror"
- * Address of PRBool. If not NULL, returns true is cert chain
- * was invalidated because of bad certificate signature.
- * "pRevoked"
- * Address of PRBool. If not NULL, returns true is cert chain
- * was invalidated because a revoked certificate was found in
- * the chain.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * SECFailure is chain building process has failed. SECSuccess otherwise.
- */
- SECStatus
- cert_VerifyCertChainPkix(
- CERTCertificate *cert,
- PRBool checkSig,
- SECCertUsage requiredUsage,
- PRTime time,
- void *wincx,
- CERTVerifyLog *log,
- PRBool *pSigerror,
- PRBool *pRevoked)
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
- #else
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_Error *error = NULL;
- SECStatus rv = SECFailure;
- void *plContext = NULL;
- #ifdef PKIX_OBJECT_LEAK_TEST
- int leakedObjNum = 0;
- int memLeakLoopCount = 0;
- int objCountTable[PKIX_NUMTYPES];
- int fnInvLocalCount = 0;
- PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
- if (usePKIXValidationEngine) {
- /* current memory leak testing implementation does not allow
- * to run simultaneous tests one the same or a different threads.
- * Setting the variable to false, to make additional chain
- * validations be handled by old nss. */
- usePKIXValidationEngine = PR_FALSE;
- }
- testStartFnStackPosition = 2;
- fnStackNameArr[0] = "cert_VerifyCertChainPkix";
- fnStackInvCountArr[0] = 0;
- PKIX_Boolean abortOnLeak =
- (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
- : PKIX_TRUE;
- runningLeakTest = PKIX_TRUE;
- /* Prevent multi-threaded run of object leak test */
- fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount);
- PORT_Assert(fnInvLocalCount == 1);
- do {
- rv = SECFailure;
- plContext = NULL;
- procParams = NULL;
- result = NULL;
- verifyNode = NULL;
- error = NULL;
- errorGenerated = PKIX_FALSE;
- stackPosition = 0;
- if (leakedObjNum) {
- pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
- }
- memLeakLoopCount += 1;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- error =
- cert_CreatePkixProcessingParams(cert, checkSig, time, wincx,
- PR_FALSE /*use arena*/,
- requiredUsage == certUsageStatusResponder,
- &procParams, &plContext);
- if (error) {
- goto cleanup;
- }
- error =
- cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0,
- plContext);
- if (error) {
- goto cleanup;
- }
- error =
- cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
- if (error) {
- goto cleanup;
- }
- if (pRevoked) {
- /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
- *pRevoked = PR_FALSE;
- }
- if (pSigerror) {
- /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
- *pSigerror = PR_FALSE;
- }
- rv = SECSuccess;
- cleanup:
- error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL,
- plContext);
- if (error) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
- if (procParams) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
- }
- if (plContext) {
- PKIX_PL_NssContext_Destroy(plContext);
- }
- #ifdef PKIX_OBJECT_LEAK_TEST
- leakedObjNum =
- pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
- if (pkixLog && leakedObjNum) {
- PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
- "Stack %s\n",
- memLeakLoopCount, errorFnStackString));
- }
- PR_Free(errorFnStackString);
- errorFnStackString = NULL;
- if (abortOnLeak) {
- PORT_Assert(leakedObjNum == 0);
- }
- } while (errorGenerated);
- runningLeakTest = PKIX_FALSE;
- PR_ATOMIC_DECREMENT(¶llelFnInvocationCount);
- usePKIXValidationEngine = savedUsePkixEngFlag;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- return rv;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- #ifndef NSS_DISABLE_LIBPKIX
- PKIX_CertSelector *
- cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
- {
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_CertSelector *r = NULL;
- PKIX_PL_Cert *eeCert = NULL;
- PKIX_Error *error = NULL;
- error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_ComCertSelParams_SetCertificate(
- certSelParams, eeCert, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext);
- if (error == NULL)
- r = certSelector;
- cleanup:
- if (certSelParams != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);
- if (eeCert != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);
- if (certSelector != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
- if (error != NULL) {
- SECErrorCodes nssErr;
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
- }
- return r;
- }
- static PKIX_List *
- cert_GetCertStores(void *plContext)
- {
- PKIX_CertStore *certStore = NULL;
- PKIX_List *certStores = NULL;
- PKIX_List *r = NULL;
- PKIX_Error *error = NULL;
- error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_List_Create(&certStores, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_List_AppendItem(certStores,
- (PKIX_PL_Object *)certStore, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext);
- if (error == NULL)
- r = certStores;
- cleanup:
- if (certStores != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
- if (certStore != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);
- if (error != NULL) {
- SECErrorCodes nssErr;
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
- }
- return r;
- }
- struct fake_PKIX_PL_CertStruct {
- CERTCertificate *nssCert;
- };
- /* This needs to be part of the PKIX_PL_* */
- /* This definitely needs to go away, and be replaced with
- a real accessor function in PKIX */
- static CERTCertificate *
- cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
- {
- struct fake_PKIX_PL_CertStruct *fcert = NULL;
- fcert = (struct fake_PKIX_PL_CertStruct *)pkix_cert;
- return CERT_DupCertificate(fcert->nssCert);
- }
- PKIX_List *
- cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
- {
- PKIX_List *r = NULL;
- PKIX_List *policyList = NULL;
- PKIX_PL_OID *policyOID = NULL;
- PKIX_Error *error = NULL;
- int i;
- error = PKIX_List_Create(&policyList, plContext);
- if (error != NULL) {
- goto cleanup;
- }
- for (i = 0; i < oidCount; i++) {
- error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext);
- if (error) {
- goto cleanup;
- }
- error = PKIX_List_AppendItem(policyList,
- (PKIX_PL_Object *)policyOID, plContext);
- if (error != NULL) {
- goto cleanup;
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
- policyOID = NULL;
- }
- error = PKIX_List_SetImmutable(policyList, plContext);
- if (error != NULL)
- goto cleanup;
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
- if (error == NULL)
- r = policyList;
- cleanup:
- if (policyOID != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
- }
- if (policyList != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
- }
- if (error != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
- return r;
- }
- CERTValOutParam *
- cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
- {
- CERTValOutParam *i;
- if (params == NULL) {
- return NULL;
- }
- for (i = params; i->type != cert_po_end; i++) {
- if (i->type == t) {
- return i;
- }
- }
- return NULL;
- }
- static PKIX_Error *
- setRevocationMethod(PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *procParams,
- const CERTRevocationTests *revTest,
- CERTRevocationMethodIndex certRevMethod,
- PKIX_RevocationMethodType pkixRevMethod,
- PKIX_Boolean verifyResponderUsages,
- PKIX_Boolean isLeafTest,
- void *plContext)
- {
- PKIX_UInt32 methodFlags = 0;
- PKIX_Error *error = NULL;
- PKIX_UInt32 priority = 0;
- if (revTest->number_of_defined_methods <= (PRUint32)certRevMethod) {
- return NULL;
- }
- if (revTest->preferred_methods) {
- unsigned int i = 0;
- for (; i < revTest->number_of_preferred_methods; i++) {
- if (revTest->preferred_methods[i] == certRevMethod)
- break;
- }
- priority = i;
- }
- methodFlags = revTest->cert_rev_flags_per_method[certRevMethod];
- if (verifyResponderUsages &&
- pkixRevMethod == PKIX_RevocationMethod_OCSP) {
- methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
- }
- error =
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- pkixRevMethod, methodFlags,
- priority, NULL,
- isLeafTest, plContext);
- return error;
- }
- SECStatus
- cert_pkixSetParam(PKIX_ProcessingParams *procParams,
- const CERTValInParam *param, void *plContext)
- {
- PKIX_Error *error = NULL;
- SECStatus r = SECSuccess;
- PKIX_PL_Date *date = NULL;
- PKIX_List *policyOIDList = NULL;
- PKIX_List *certListPkix = NULL;
- const CERTRevocationFlags *flags;
- SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS;
- const CERTCertList *certList = NULL;
- CERTCertListNode *node;
- PKIX_PL_Cert *certPkix = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
- /* XXX we need a way to map generic PKIX error to generic NSS errors */
- switch (param->type) {
- case cert_pi_policyOID:
- /* needed? */
- error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
- procParams, PKIX_TRUE, plContext);
- if (error != NULL) {
- break;
- }
- policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids,
- param->value.arraySize, plContext);
- if (policyOIDList == NULL) {
- r = SECFailure;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- break;
- }
- error = PKIX_ProcessingParams_SetInitialPolicies(
- procParams, policyOIDList, plContext);
- break;
- case cert_pi_date:
- if (param->value.scalar.time == 0) {
- error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- break;
- }
- } else {
- error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time,
- &date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- break;
- }
- }
- error = PKIX_ProcessingParams_SetDate(procParams, date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- }
- break;
- case cert_pi_revocationFlags: {
- PKIX_UInt32 leafIMFlags = 0;
- PKIX_UInt32 chainIMFlags = 0;
- PKIX_Boolean validatingResponderCert = PKIX_FALSE;
- flags = param->value.pointer.revocation;
- if (!flags) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
- leafIMFlags =
- flags->leafTests.cert_rev_method_independent_flags;
- chainIMFlags =
- flags->chainTests.cert_rev_method_independent_flags;
- error =
- PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags,
- &revChecker, plContext);
- if (error) {
- break;
- }
- error =
- PKIX_ProcessingParams_SetRevocationChecker(procParams,
- revChecker, plContext);
- if (error) {
- break;
- }
- if (((PKIX_PL_NssContext *)plContext)->certificateUsage &
- certificateUsageStatusResponder) {
- validatingResponderCert = PKIX_TRUE;
- }
- error = setRevocationMethod(revChecker,
- procParams, &flags->leafTests,
- cert_revocation_method_crl,
- PKIX_RevocationMethod_CRL,
- validatingResponderCert,
- PKIX_TRUE, plContext);
- if (error) {
- break;
- }
- error = setRevocationMethod(revChecker,
- procParams, &flags->leafTests,
- cert_revocation_method_ocsp,
- PKIX_RevocationMethod_OCSP,
- validatingResponderCert,
- PKIX_TRUE, plContext);
- if (error) {
- break;
- }
- error = setRevocationMethod(revChecker,
- procParams, &flags->chainTests,
- cert_revocation_method_crl,
- PKIX_RevocationMethod_CRL,
- validatingResponderCert,
- PKIX_FALSE, plContext);
- if (error) {
- break;
- }
- error = setRevocationMethod(revChecker,
- procParams, &flags->chainTests,
- cert_revocation_method_ocsp,
- PKIX_RevocationMethod_OCSP,
- validatingResponderCert,
- PKIX_FALSE, plContext);
- if (error) {
- break;
- }
- } break;
- case cert_pi_trustAnchors:
- certList = param->value.pointer.chain;
- if (!certList) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
- error = PKIX_List_Create(&certListPkix, plContext);
- if (error != NULL) {
- break;
- }
- for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
- node = CERT_LIST_NEXT(node)) {
- error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert,
- &certPkix, plContext);
- if (error) {
- break;
- }
- error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor,
- plContext);
- if (error) {
- break;
- }
- error = PKIX_List_AppendItem(certListPkix,
- (PKIX_PL_Object *)trustAnchor, plContext);
- if (error) {
- break;
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
- trustAnchor = NULL;
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
- certPkix = NULL;
- }
- error =
- PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix,
- plContext);
- break;
- case cert_pi_useAIACertFetch:
- error =
- PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams,
- (PRBool)(param->value.scalar.b !=
- 0),
- plContext);
- break;
- case cert_pi_chainVerifyCallback: {
- const CERTChainVerifyCallback *chainVerifyCallback =
- param->value.pointer.chainVerifyCallback;
- if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
- nssContext->chainVerifyCallback = *chainVerifyCallback;
- } break;
- case cert_pi_useOnlyTrustAnchors:
- error =
- PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams,
- (PRBool)(param->value.scalar.b !=
- 0),
- plContext);
- break;
- default:
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
- if (policyOIDList != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext);
- if (date != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);
- if (revChecker != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);
- if (certListPkix)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext);
- if (trustAnchor)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
- if (certPkix)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
- if (error != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(errCode);
- r = SECFailure;
- }
- return r;
- }
- void
- cert_pkixDestroyValOutParam(CERTValOutParam *params)
- {
- CERTValOutParam *i;
- if (params == NULL) {
- return;
- }
- for (i = params; i->type != cert_po_end; i++) {
- switch (i->type) {
- case cert_po_trustAnchor:
- if (i->value.pointer.cert) {
- CERT_DestroyCertificate(i->value.pointer.cert);
- i->value.pointer.cert = NULL;
- }
- break;
- case cert_po_certList:
- if (i->value.pointer.chain) {
- CERT_DestroyCertList(i->value.pointer.chain);
- i->value.pointer.chain = NULL;
- }
- break;
- default:
- break;
- }
- }
- }
- static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- CERT_REV_M_TEST_USING_THIS_METHOD
- };
- static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
- };
- static CERTRevocationMethodIndex
- certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = {
- cert_revocation_method_crl
- };
- static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = {
- { /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags,
- 1,
- &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference,
- 0 },
- { /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags,
- 0,
- 0,
- 0 }
- };
- #endif /* NSS_DISABLE_LIBPKIX */
- extern const CERTRevocationFlags *
- CERT_GetClassicOCSPEnabledSoftFailurePolicy()
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- #else
- return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- #ifndef NSS_DISABLE_LIBPKIX
- static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
- };
- static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
- };
- static CERTRevocationMethodIndex
- certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = {
- cert_revocation_method_crl
- };
- static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = {
- { /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags,
- 1,
- &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference,
- 0 },
- { /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags,
- 0,
- 0,
- 0 }
- };
- #endif /* NSS_DISABLE_LIBPKIX */
- extern const CERTRevocationFlags *
- CERT_GetClassicOCSPEnabledHardFailurePolicy()
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- #else
- return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- #ifndef NSS_DISABLE_LIBPKIX
- static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
- };
- static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FORBID_NETWORK_FETCHING |
- CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
- };
- static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = {
- { /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags,
- 0,
- 0,
- 0 },
- { /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags,
- 0,
- 0,
- 0 }
- };
- #endif /* NSS_DISABLE_LIBPKIX */
- extern const CERTRevocationFlags *
- CERT_GetClassicOCSPDisabledPolicy()
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- #else
- return &certRev_NSS_3_11_Ocsp_Disabled_Policy;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- #ifndef NSS_DISABLE_LIBPKIX
- static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
- CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
- /* ocsp */
- 0
- };
- static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD |
- CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
- CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
- /* ocsp */
- 0
- };
- static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = {
- { /* leafTests */
- 2,
- certRev_PKIX_Verify_Nist_Policy_LeafFlags,
- 0,
- 0,
- 0 },
- { /* chainTests */
- 2,
- certRev_PKIX_Verify_Nist_Policy_ChainFlags,
- 0,
- 0,
- 0 }
- };
- #endif /* NSS_DISABLE_LIBPKIX */
- extern const CERTRevocationFlags *
- CERT_GetPKIXVerifyNistRevocationPolicy()
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- #else
- return &certRev_PKIX_Verify_Nist_Policy;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- CERTRevocationFlags *
- CERT_AllocCERTRevocationFlags(
- PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
- PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods)
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- #else
- CERTRevocationFlags *flags;
- flags = PORT_New(CERTRevocationFlags);
- if (!flags)
- return (NULL);
- flags->leafTests.number_of_defined_methods = number_leaf_methods;
- flags->leafTests.cert_rev_flags_per_method =
- PORT_NewArray(PRUint64, number_leaf_methods);
- flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods;
- flags->leafTests.preferred_methods =
- PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods);
- flags->chainTests.number_of_defined_methods = number_chain_methods;
- flags->chainTests.cert_rev_flags_per_method =
- PORT_NewArray(PRUint64, number_chain_methods);
- flags->chainTests.number_of_preferred_methods = number_chain_pref_methods;
- flags->chainTests.preferred_methods =
- PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods);
- if (!flags->leafTests.cert_rev_flags_per_method ||
- !flags->leafTests.preferred_methods ||
- !flags->chainTests.cert_rev_flags_per_method ||
- !flags->chainTests.preferred_methods) {
- CERT_DestroyCERTRevocationFlags(flags);
- return (NULL);
- }
- return flags;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- void
- CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return;
- #else
- if (!flags)
- return;
- if (flags->leafTests.cert_rev_flags_per_method)
- PORT_Free(flags->leafTests.cert_rev_flags_per_method);
- if (flags->leafTests.preferred_methods)
- PORT_Free(flags->leafTests.preferred_methods);
- if (flags->chainTests.cert_rev_flags_per_method)
- PORT_Free(flags->chainTests.cert_rev_flags_per_method);
- if (flags->chainTests.preferred_methods)
- PORT_Free(flags->chainTests.preferred_methods);
- PORT_Free(flags);
- #endif /* NSS_DISABLE_LIBPKIX */
- }
- /*
- * CERT_PKIXVerifyCert
- *
- * Verify a Certificate using the PKIX library.
- *
- * Parameters:
- * cert - the target certificate to verify. Must be non-null
- * params - an array of type/value parameters which can be
- * used to modify the behavior of the validation
- * algorithm, or supply additional constraints.
- *
- * outputTrustAnchor - the trust anchor which the certificate
- * chains to. The caller is responsible
- * for freeing this.
- *
- * Example Usage:
- * CERTValParam args[3];
- * args[0].type = cvpt_policyOID;
- * args[0].value.si = oid;
- * args[1].type = revCheckRequired;
- * args[1].value.b = PR_TRUE;
- * args[2].type = cvpt_end;
- *
- * CERT_PKIXVerifyCert(cert, &output, args
- */
- SECStatus
- CERT_PKIXVerifyCert(
- CERTCertificate *cert,
- SECCertificateUsage usages,
- CERTValInParam *paramsIn,
- CERTValOutParam *paramsOut,
- void *wincx)
- {
- #ifdef NSS_DISABLE_LIBPKIX
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
- #else
- SECStatus r = SECFailure;
- PKIX_Error *error = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_BuildResult *buildResult = NULL;
- void *nbioContext = NULL; /* for non-blocking IO */
- void *buildState = NULL; /* for non-blocking IO */
- PKIX_CertSelector *certSelector = NULL;
- PKIX_List *certStores = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_PL_Cert *trustAnchorCert = NULL;
- PKIX_List *builtCertList = NULL;
- CERTValOutParam *oparam = NULL;
- int i = 0;
- void *plContext = NULL;
- #ifdef PKIX_OBJECT_LEAK_TEST
- int leakedObjNum = 0;
- int memLeakLoopCount = 0;
- int objCountTable[PKIX_NUMTYPES];
- int fnInvLocalCount = 0;
- PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
- if (usePKIXValidationEngine) {
- /* current memory leak testing implementation does not allow
- * to run simultaneous tests one the same or a different threads.
- * Setting the variable to false, to make additional chain
- * validations be handled by old nss. */
- usePKIXValidationEngine = PR_FALSE;
- }
- testStartFnStackPosition = 1;
- fnStackNameArr[0] = "CERT_PKIXVerifyCert";
- fnStackInvCountArr[0] = 0;
- PKIX_Boolean abortOnLeak =
- (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
- : PKIX_TRUE;
- runningLeakTest = PKIX_TRUE;
- /* Prevent multi-threaded run of object leak test */
- fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount);
- PORT_Assert(fnInvLocalCount == 1);
- do {
- r = SECFailure;
- error = NULL;
- procParams = NULL;
- buildResult = NULL;
- nbioContext = NULL; /* for non-blocking IO */
- buildState = NULL; /* for non-blocking IO */
- certSelector = NULL;
- certStores = NULL;
- valResult = NULL;
- verifyNode = NULL;
- trustAnchor = NULL;
- trustAnchorCert = NULL;
- builtCertList = NULL;
- oparam = NULL;
- i = 0;
- errorGenerated = PKIX_FALSE;
- stackPosition = 0;
- if (leakedObjNum) {
- pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
- }
- memLeakLoopCount += 1;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- error = PKIX_PL_NssContext_Create(
- 0, PR_FALSE /*use arena*/, wincx, &plContext);
- if (error != NULL) { /* need pkix->nss error map */
- PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
- goto cleanup;
- }
- error = pkix_pl_NssContext_SetCertUsage(usages, plContext);
- if (error != NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- error = PKIX_ProcessingParams_Create(&procParams, plContext);
- if (error != NULL) { /* need pkix->nss error map */
- PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
- goto cleanup;
- }
- /* local cert store should be set into procParams before
- * filling in revocation settings. */
- certStores = cert_GetCertStores(plContext);
- if (certStores == NULL) {
- goto cleanup;
- }
- error = PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext);
- if (error != NULL) {
- goto cleanup;
- }
- /* now process the extensible input parameters structure */
- if (paramsIn != NULL) {
- i = 0;
- while (paramsIn[i].type != cert_pi_end) {
- if (paramsIn[i].type >= cert_pi_max) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- if (cert_pkixSetParam(procParams,
- ¶msIn[i], plContext) !=
- SECSuccess) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- i++;
- }
- }
- certSelector = cert_GetTargetCertConstraints(cert, plContext);
- if (certSelector == NULL) {
- goto cleanup;
- }
- error = PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
- if (error != NULL) {
- goto cleanup;
- }
- error = PKIX_BuildChain(procParams, &nbioContext,
- &buildState, &buildResult, &verifyNode,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- error = PKIX_BuildResult_GetValidateResult(buildResult, &valResult,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- error = PKIX_ValidateResult_GetTrustAnchor(valResult, &trustAnchor,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- if (trustAnchor != NULL) {
- error = PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustAnchorCert,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- }
- #ifdef PKIX_OBJECT_LEAK_TEST
- /* Can not continue if error was generated but not returned.
- * Jumping to cleanup. */
- if (errorGenerated)
- goto cleanup;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
- if (oparam != NULL) {
- if (trustAnchorCert != NULL) {
- oparam->value.pointer.cert =
- cert_NSSCertFromPKIXCert(trustAnchorCert);
- } else {
- oparam->value.pointer.cert = NULL;
- }
- }
- error = PKIX_BuildResult_GetCertChain(buildResult, &builtCertList,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList);
- if (oparam != NULL) {
- error = cert_PkixToNssCertsChain(builtCertList,
- &oparam->value.pointer.chain,
- plContext);
- if (error)
- goto cleanup;
- }
- r = SECSuccess;
- cleanup:
- if (verifyNode) {
- /* Return validation log only upon error. */
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
- #ifdef PKIX_OBJECT_LEAK_TEST
- if (!errorGenerated)
- #endif /* PKIX_OBJECT_LEAK_TEST */
- if (r && oparam != NULL) {
- PKIX_Error *tmpError =
- cert_GetLogFromVerifyNode(oparam->value.pointer.log,
- verifyNode, plContext);
- if (tmpError) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
- }
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext);
- }
- if (procParams != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
- if (trustAnchorCert != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext);
- if (trustAnchor != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
- if (valResult != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext);
- if (buildResult != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext);
- if (certStores != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
- if (certSelector != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
- if (builtCertList != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext);
- if (error != NULL) {
- SECErrorCodes nssErrorCode = 0;
- cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
- cert_pkixDestroyValOutParam(paramsOut);
- PORT_SetError(nssErrorCode);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
- PKIX_PL_NssContext_Destroy(plContext);
- #ifdef PKIX_OBJECT_LEAK_TEST
- leakedObjNum =
- pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
- if (pkixLog && leakedObjNum) {
- PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
- "Stack %s\n",
- memLeakLoopCount, errorFnStackString));
- }
- PR_Free(errorFnStackString);
- errorFnStackString = NULL;
- if (abortOnLeak) {
- PORT_Assert(leakedObjNum == 0);
- }
- } while (errorGenerated);
- runningLeakTest = PKIX_FALSE;
- PR_ATOMIC_DECREMENT(¶llelFnInvocationCount);
- usePKIXValidationEngine = savedUsePkixEngFlag;
- #endif /* PKIX_OBJECT_LEAK_TEST */
- return r;
- #endif /* NSS_DISABLE_LIBPKIX */
- }
|