diff options
Diffstat (limited to 'security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c')
-rw-r--r-- | security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c new file mode 100644 index 000000000..a2b843739 --- /dev/null +++ b/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c @@ -0,0 +1,328 @@ +/* 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/. */ +/* + * pkix_ekuchecker.c + * + * User Defined ExtenedKeyUsage Function Definitions + * + */ + +#include "pkix_ekuchecker.h" + +SECOidTag ekuOidStrings[] = { + PKIX_KEY_USAGE_SERVER_AUTH_OID, + PKIX_KEY_USAGE_CLIENT_AUTH_OID, + PKIX_KEY_USAGE_CODE_SIGN_OID, + PKIX_KEY_USAGE_EMAIL_PROTECT_OID, + PKIX_KEY_USAGE_TIME_STAMP_OID, + PKIX_KEY_USAGE_OCSP_RESPONDER_OID, + PKIX_UNKNOWN_OID +}; + +typedef struct pkix_EkuCheckerStruct { + PKIX_List *requiredExtKeyUsageOids; + PKIX_PL_OID *ekuOID; +} pkix_EkuChecker; + + +/* + * FUNCTION: pkix_EkuChecker_Destroy + * (see comments for PKIX_DestructorCallback in pkix_pl_system.h) + */ +static PKIX_Error * +pkix_EkuChecker_Destroy( + PKIX_PL_Object *object, + void *plContext) +{ + pkix_EkuChecker *ekuCheckerState = NULL; + + PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Destroy"); + PKIX_NULLCHECK_ONE(object); + + PKIX_CHECK(pkix_CheckType(object, PKIX_EKUCHECKER_TYPE, plContext), + PKIX_OBJECTNOTANEKUCHECKERSTATE); + + ekuCheckerState = (pkix_EkuChecker *)object; + + PKIX_DECREF(ekuCheckerState->ekuOID); + PKIX_DECREF(ekuCheckerState->requiredExtKeyUsageOids); + +cleanup: + + PKIX_RETURN(EKUCHECKER); +} + +/* + * FUNCTION: pkix_EkuChecker_RegisterSelf + * + * DESCRIPTION: + * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related + * functions with systemClasses[] + * + * THREAD SAFETY: + * Not Thread Safe - for performance and complexity reasons + * + * Since this function is only called by PKIX_PL_Initialize, which should + * only be called once, it is acceptable that this function is not + * thread-safe. + */ +PKIX_Error * +pkix_EkuChecker_RegisterSelf(void *plContext) +{ + extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; + pkix_ClassTable_Entry *entry = &systemClasses[PKIX_EKUCHECKER_TYPE]; + + PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_RegisterSelf"); + + entry->description = "EkuChecker"; + entry->typeObjectSize = sizeof(pkix_EkuChecker); + entry->destructor = pkix_EkuChecker_Destroy; + + PKIX_RETURN(EKUCHECKER); +} + +/* + * FUNCTION: pkix_EkuChecker_Create + * DESCRIPTION: + * + * Creates a new Extend Key Usage CheckerState using "params" to retrieve + * application specified EKU for verification and stores it at "pState". + * + * PARAMETERS: + * "params" + * a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of + * Extended Key Usage OIDs specified by application can be retrieved for + * verification. + * "pState" + * Address where state pointer will be stored. Must be non-NULL. + * "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 UserDefinedModules Error if the function fails in a + * non-fatal way. + * Returns a Fatal Error if the function fails in an unrecoverable way. + */ +static PKIX_Error * +pkix_EkuChecker_Create( + PKIX_ProcessingParams *params, + pkix_EkuChecker **pState, + void *plContext) +{ + pkix_EkuChecker *state = NULL; + PKIX_CertSelector *certSelector = NULL; + PKIX_ComCertSelParams *comCertSelParams = NULL; + PKIX_List *requiredOids = NULL; + + PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Create"); + PKIX_NULLCHECK_TWO(params, pState); + + PKIX_CHECK(PKIX_PL_Object_Alloc + (PKIX_EKUCHECKER_TYPE, + sizeof (pkix_EkuChecker), + (PKIX_PL_Object **)&state, + plContext), + PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT); + + + PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints + (params, &certSelector, plContext), + PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED); + + if (certSelector != NULL) { + + /* Get initial EKU OIDs from ComCertSelParams, if set */ + PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams + (certSelector, &comCertSelParams, plContext), + PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED); + + if (comCertSelParams != NULL) { + PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage + (comCertSelParams, &requiredOids, plContext), + PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); + + } + } + + PKIX_CHECK(PKIX_PL_OID_Create + (PKIX_EXTENDEDKEYUSAGE_OID, + &state->ekuOID, + plContext), + PKIX_OIDCREATEFAILED); + + state->requiredExtKeyUsageOids = requiredOids; + requiredOids = NULL; + *pState = state; + state = NULL; + +cleanup: + + PKIX_DECREF(certSelector); + PKIX_DECREF(comCertSelParams); + PKIX_DECREF(requiredOids); + PKIX_DECREF(state); + + PKIX_RETURN(EKUCHECKER); +} + +/* + * FUNCTION: pkix_EkuChecker_Check + * DESCRIPTION: + * + * This function determines the Extended Key Usage OIDs specified by the + * application is included in the Extended Key Usage OIDs of this "cert". + * + * PARAMETERS: + * "checker" + * Address of CertChainChecker which has the state data. + * Must be non-NULL. + * "cert" + * Address of Certificate that is to be validated. Must be non-NULL. + * "unresolvedCriticalExtensions" + * A List OIDs. The OID for Extended Key Usage is removed. + * "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 UserDefinedModules Error if the function fails in + * a non-fatal way. + * Returns a Fatal Error if the function fails in an unrecoverable way. + */ +static PKIX_Error * +pkix_EkuChecker_Check( + PKIX_CertChainChecker *checker, + PKIX_PL_Cert *cert, + PKIX_List *unresolvedCriticalExtensions, + void **pNBIOContext, + void *plContext) +{ + pkix_EkuChecker *state = NULL; + PKIX_List *requiredExtKeyUsageList = NULL; + PKIX_List *certExtKeyUsageList = NULL; + PKIX_PL_OID *ekuOid = NULL; + PKIX_Boolean isContained = PKIX_FALSE; + PKIX_UInt32 numItems = 0; + PKIX_UInt32 i; + PKIX_Boolean checkResult = PKIX_TRUE; + + PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Check"); + PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); + + *pNBIOContext = NULL; /* no non-blocking IO */ + + PKIX_CHECK( + PKIX_CertChainChecker_GetCertChainCheckerState + (checker, (PKIX_PL_Object **)&state, plContext), + PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); + + requiredExtKeyUsageList = state->requiredExtKeyUsageOids; + if (requiredExtKeyUsageList == NULL) { + goto cleanup; + } + + PKIX_CHECK( + PKIX_List_GetLength(requiredExtKeyUsageList, &numItems, + plContext), + PKIX_LISTGETLENGTHFAILED); + if (numItems == 0) { + goto cleanup; + } + + PKIX_CHECK( + PKIX_PL_Cert_GetExtendedKeyUsage(cert, &certExtKeyUsageList, + plContext), + PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); + + if (certExtKeyUsageList == NULL) { + goto cleanup; + } + + for (i = 0; i < numItems; i++) { + + PKIX_CHECK( + PKIX_List_GetItem(requiredExtKeyUsageList, i, + (PKIX_PL_Object **)&ekuOid, plContext), + PKIX_LISTGETITEMFAILED); + + PKIX_CHECK( + pkix_List_Contains(certExtKeyUsageList, + (PKIX_PL_Object *)ekuOid, + &isContained, + plContext), + PKIX_LISTCONTAINSFAILED); + + PKIX_DECREF(ekuOid); + if (isContained != PKIX_TRUE) { + checkResult = PKIX_FALSE; + goto cleanup; + } + } + +cleanup: + if (!pkixErrorResult && checkResult == PKIX_FALSE) { + pkixErrorReceived = PKIX_TRUE; + pkixErrorCode = PKIX_EXTENDEDKEYUSAGECHECKINGFAILED; + } + + PKIX_DECREF(ekuOid); + PKIX_DECREF(certExtKeyUsageList); + PKIX_DECREF(state); + + PKIX_RETURN(EKUCHECKER); +} + +/* + * FUNCTION: pkix_EkuChecker_Initialize + * (see comments in pkix_sample_modules.h) + */ +PKIX_Error * +PKIX_EkuChecker_Create( + PKIX_ProcessingParams *params, + PKIX_CertChainChecker **pEkuChecker, + void *plContext) +{ + pkix_EkuChecker *state = NULL; + PKIX_List *critExtOIDsList = NULL; + + PKIX_ENTER(EKUCHECKER, "PKIX_EkuChecker_Initialize"); + PKIX_NULLCHECK_ONE(params); + + /* + * This function and functions in this file provide an example of how + * an application defined checker can be hooked into libpkix. + */ + + PKIX_CHECK(pkix_EkuChecker_Create + (params, &state, plContext), + PKIX_EKUCHECKERSTATECREATEFAILED); + + PKIX_CHECK(PKIX_List_Create(&critExtOIDsList, plContext), + PKIX_LISTCREATEFAILED); + + PKIX_CHECK(PKIX_List_AppendItem + (critExtOIDsList, + (PKIX_PL_Object *)state->ekuOID, + plContext), + PKIX_LISTAPPENDITEMFAILED); + + PKIX_CHECK(PKIX_CertChainChecker_Create + (pkix_EkuChecker_Check, + PKIX_TRUE, /* forwardCheckingSupported */ + PKIX_FALSE, /* forwardDirectionExpected */ + critExtOIDsList, + (PKIX_PL_Object *) state, + pEkuChecker, + plContext), + PKIX_CERTCHAINCHECKERCREATEFAILED); +cleanup: + + PKIX_DECREF(critExtOIDsList); + PKIX_DECREF(state); + + PKIX_RETURN(EKUCHECKER); +} |