security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 /*
     5  * pkix_ekuchecker.c
     6  *
     7  * User Defined ExtenedKeyUsage Function Definitions
     8  *
     9  */
    11 #include "pkix_ekuchecker.h"
    13 SECOidTag ekuOidStrings[] = {
    14     PKIX_KEY_USAGE_SERVER_AUTH_OID,
    15     PKIX_KEY_USAGE_CLIENT_AUTH_OID,
    16     PKIX_KEY_USAGE_CODE_SIGN_OID,
    17     PKIX_KEY_USAGE_EMAIL_PROTECT_OID,
    18     PKIX_KEY_USAGE_TIME_STAMP_OID,
    19     PKIX_KEY_USAGE_OCSP_RESPONDER_OID,
    20     PKIX_UNKNOWN_OID
    21 };
    23 typedef struct pkix_EkuCheckerStruct {
    24     PKIX_List *requiredExtKeyUsageOids;
    25     PKIX_PL_OID *ekuOID;
    26 } pkix_EkuChecker;
    29 /*
    30  * FUNCTION: pkix_EkuChecker_Destroy
    31  * (see comments for PKIX_DestructorCallback in pkix_pl_system.h)
    32  */
    33 static PKIX_Error *
    34 pkix_EkuChecker_Destroy(
    35         PKIX_PL_Object *object,
    36         void *plContext)
    37 {
    38         pkix_EkuChecker *ekuCheckerState = NULL;
    40         PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Destroy");
    41         PKIX_NULLCHECK_ONE(object);
    43         PKIX_CHECK(pkix_CheckType(object, PKIX_EKUCHECKER_TYPE, plContext),
    44                     PKIX_OBJECTNOTANEKUCHECKERSTATE);
    46         ekuCheckerState = (pkix_EkuChecker *)object;
    48         PKIX_DECREF(ekuCheckerState->ekuOID);
    49         PKIX_DECREF(ekuCheckerState->requiredExtKeyUsageOids);
    51 cleanup:
    53         PKIX_RETURN(EKUCHECKER);
    54 }
    56 /*
    57  * FUNCTION: pkix_EkuChecker_RegisterSelf
    58  *
    59  * DESCRIPTION:
    60  *  Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
    61  *  functions with systemClasses[]
    62  *
    63  * THREAD SAFETY:
    64  *  Not Thread Safe - for performance and complexity reasons
    65  *
    66  *  Since this function is only called by PKIX_PL_Initialize, which should
    67  *  only be called once, it is acceptable that this function is not
    68  *  thread-safe.
    69  */
    70 PKIX_Error *
    71 pkix_EkuChecker_RegisterSelf(void *plContext)
    72 {
    73         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    74         pkix_ClassTable_Entry *entry = &systemClasses[PKIX_EKUCHECKER_TYPE];
    76         PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_RegisterSelf");
    78         entry->description = "EkuChecker";
    79         entry->typeObjectSize = sizeof(pkix_EkuChecker);
    80         entry->destructor = pkix_EkuChecker_Destroy;
    82         PKIX_RETURN(EKUCHECKER);
    83 }
    85 /*
    86  * FUNCTION: pkix_EkuChecker_Create
    87  * DESCRIPTION:
    88  *
    89  *  Creates a new Extend Key Usage CheckerState using "params" to retrieve
    90  *  application specified EKU for verification and stores it at "pState".
    91  *
    92  * PARAMETERS:
    93  *  "params"
    94  *      a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
    95  *      Extended Key Usage OIDs specified by application can be retrieved for
    96  *      verification.
    97  *  "pState"
    98  *      Address where state pointer will be stored. Must be non-NULL.
    99  *  "plContext"
   100  *      Platform-specific context pointer.
   101  * THREAD SAFETY:
   102  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   103  * RETURNS:
   104  *  Returns NULL if the function succeeds.
   105  *  Returns a UserDefinedModules Error if the function fails in a
   106  *      non-fatal way.
   107  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   108  */
   109 static PKIX_Error *
   110 pkix_EkuChecker_Create(
   111         PKIX_ProcessingParams *params,
   112         pkix_EkuChecker **pState,
   113         void *plContext)
   114 {
   115         pkix_EkuChecker *state = NULL;
   116         PKIX_CertSelector *certSelector = NULL;
   117         PKIX_ComCertSelParams *comCertSelParams = NULL;
   118         PKIX_List *requiredOids = NULL;
   120         PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Create");
   121         PKIX_NULLCHECK_TWO(params, pState);
   123         PKIX_CHECK(PKIX_PL_Object_Alloc
   124                     (PKIX_EKUCHECKER_TYPE,
   125                     sizeof (pkix_EkuChecker),
   126                     (PKIX_PL_Object **)&state,
   127                     plContext),
   128                     PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT);
   131         PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
   132                     (params, &certSelector, plContext),
   133                     PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
   135         if (certSelector != NULL) {
   137             /* Get initial EKU OIDs from ComCertSelParams, if set */
   138             PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
   139                        (certSelector, &comCertSelParams, plContext),
   140                        PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
   142             if (comCertSelParams != NULL) {
   143                 PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
   144                            (comCertSelParams, &requiredOids, plContext),
   145                            PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
   147             }
   148         }
   150         PKIX_CHECK(PKIX_PL_OID_Create
   151                     (PKIX_EXTENDEDKEYUSAGE_OID,
   152                     &state->ekuOID,
   153                     plContext),
   154                     PKIX_OIDCREATEFAILED);
   156         state->requiredExtKeyUsageOids = requiredOids;
   157         requiredOids = NULL;
   158         *pState = state;
   159         state = NULL;
   161 cleanup:
   163         PKIX_DECREF(certSelector);
   164         PKIX_DECREF(comCertSelParams);
   165         PKIX_DECREF(requiredOids);
   166         PKIX_DECREF(state);
   168         PKIX_RETURN(EKUCHECKER);
   169 }
   171 /*
   172  * FUNCTION: pkix_EkuChecker_Check
   173  * DESCRIPTION:
   174  *
   175  *  This function determines the Extended Key Usage OIDs specified by the
   176  *  application is included in the Extended Key Usage OIDs of this "cert".
   177  *
   178  * PARAMETERS:
   179  *  "checker"
   180  *      Address of CertChainChecker which has the state data.
   181  *      Must be non-NULL.
   182  *  "cert"
   183  *      Address of Certificate that is to be validated. Must be non-NULL.
   184  *  "unresolvedCriticalExtensions"
   185  *      A List OIDs. The OID for Extended Key Usage is removed.
   186  *  "plContext"
   187  *      Platform-specific context pointer.
   188  * THREAD SAFETY:
   189  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   190  * RETURNS:
   191  *  Returns NULL if the function succeeds.
   192  *  Returns a UserDefinedModules Error if the function fails in
   193  *      a non-fatal way.
   194  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   195  */
   196 static PKIX_Error *
   197 pkix_EkuChecker_Check(
   198         PKIX_CertChainChecker *checker,
   199         PKIX_PL_Cert *cert,
   200         PKIX_List *unresolvedCriticalExtensions,
   201         void **pNBIOContext,
   202         void *plContext)
   203 {
   204         pkix_EkuChecker *state = NULL;
   205         PKIX_List *requiredExtKeyUsageList = NULL;
   206         PKIX_List *certExtKeyUsageList = NULL;
   207         PKIX_PL_OID *ekuOid = NULL;
   208         PKIX_Boolean isContained = PKIX_FALSE;
   209         PKIX_UInt32 numItems = 0;
   210         PKIX_UInt32 i;
   211         PKIX_Boolean checkResult = PKIX_TRUE;
   213         PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Check");
   214         PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
   216         *pNBIOContext = NULL; /* no non-blocking IO */
   218         PKIX_CHECK(
   219             PKIX_CertChainChecker_GetCertChainCheckerState
   220             (checker, (PKIX_PL_Object **)&state, plContext),
   221             PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
   223         requiredExtKeyUsageList = state->requiredExtKeyUsageOids;
   224         if (requiredExtKeyUsageList == NULL) {
   225             goto cleanup;
   226         }
   228         PKIX_CHECK(
   229             PKIX_List_GetLength(requiredExtKeyUsageList, &numItems,
   230                                 plContext),
   231             PKIX_LISTGETLENGTHFAILED);
   232         if (numItems == 0) {
   233             goto cleanup;
   234         }
   236         PKIX_CHECK(
   237             PKIX_PL_Cert_GetExtendedKeyUsage(cert, &certExtKeyUsageList,
   238                                              plContext),
   239             PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
   241         if (certExtKeyUsageList == NULL) {
   242             goto cleanup;
   243         }
   245         for (i = 0; i < numItems; i++) {
   247             PKIX_CHECK(
   248                 PKIX_List_GetItem(requiredExtKeyUsageList, i,
   249                                   (PKIX_PL_Object **)&ekuOid, plContext),
   250                 PKIX_LISTGETITEMFAILED);
   252             PKIX_CHECK(
   253                 pkix_List_Contains(certExtKeyUsageList,
   254                                    (PKIX_PL_Object *)ekuOid,
   255                                    &isContained,
   256                                    plContext),
   257                 PKIX_LISTCONTAINSFAILED);
   259             PKIX_DECREF(ekuOid);
   260             if (isContained != PKIX_TRUE) {
   261                 checkResult = PKIX_FALSE;
   262                 goto cleanup;
   263             }
   264         }
   266 cleanup:
   267         if (!pkixErrorResult && checkResult == PKIX_FALSE) {
   268             pkixErrorReceived = PKIX_TRUE;
   269             pkixErrorCode = PKIX_EXTENDEDKEYUSAGECHECKINGFAILED;
   270         }
   272         PKIX_DECREF(ekuOid);
   273         PKIX_DECREF(certExtKeyUsageList);
   274         PKIX_DECREF(state);
   276         PKIX_RETURN(EKUCHECKER);
   277 }
   279 /*
   280  * FUNCTION: pkix_EkuChecker_Initialize
   281  * (see comments in pkix_sample_modules.h)
   282  */
   283 PKIX_Error *
   284 PKIX_EkuChecker_Create(
   285         PKIX_ProcessingParams *params,
   286         PKIX_CertChainChecker **pEkuChecker,
   287         void *plContext)
   288 {
   289         pkix_EkuChecker *state = NULL;
   290         PKIX_List *critExtOIDsList = NULL;
   292         PKIX_ENTER(EKUCHECKER, "PKIX_EkuChecker_Initialize");
   293         PKIX_NULLCHECK_ONE(params);
   295         /*
   296          * This function and functions in this file provide an example of how
   297          * an application defined checker can be hooked into libpkix.
   298          */
   300         PKIX_CHECK(pkix_EkuChecker_Create
   301                     (params, &state, plContext),
   302                     PKIX_EKUCHECKERSTATECREATEFAILED);
   304         PKIX_CHECK(PKIX_List_Create(&critExtOIDsList, plContext),
   305                     PKIX_LISTCREATEFAILED);
   307         PKIX_CHECK(PKIX_List_AppendItem
   308                     (critExtOIDsList,
   309                     (PKIX_PL_Object *)state->ekuOID,
   310                     plContext),
   311                     PKIX_LISTAPPENDITEMFAILED);
   313         PKIX_CHECK(PKIX_CertChainChecker_Create
   314                 (pkix_EkuChecker_Check,
   315                 PKIX_TRUE,                 /* forwardCheckingSupported */
   316                 PKIX_FALSE,                /* forwardDirectionExpected */
   317                 critExtOIDsList,
   318                 (PKIX_PL_Object *) state,
   319                 pEkuChecker,
   320                 plContext),
   321                 PKIX_CERTCHAINCHECKERCREATEFAILED);
   322 cleanup:
   324         PKIX_DECREF(critExtOIDsList);
   325         PKIX_DECREF(state);
   327         PKIX_RETURN(EKUCHECKER);
   328 }

mercurial