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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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_basicconstraintschecker.c
     6  *
     7  * Functions for basic constraints validation
     8  *
     9  */
    11 #include "pkix_basicconstraintschecker.h"
    13 /* --Private-BasicConstraintsCheckerState-Functions------------------------- */
    15 /*
    16  * FUNCTION: pkix_BasicConstraintsCheckerState_Destroy
    17  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
    18  */
    19 static PKIX_Error *
    20 pkix_BasicConstraintsCheckerState_Destroy(
    21         PKIX_PL_Object *object,
    22         void *plContext)
    23 {
    24         pkix_BasicConstraintsCheckerState *state = NULL;
    26         PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
    27                     "pkix_BasicConstraintsCheckerState_Destroy");
    29         PKIX_NULLCHECK_ONE(object);
    31         /* Check that this object is a basic constraints checker state */
    32         PKIX_CHECK(pkix_CheckType
    33                 (object, PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, plContext),
    34                 PKIX_OBJECTNOTBASICCONSTRAINTSCHECKERSTATE);
    36         state = (pkix_BasicConstraintsCheckerState *)object;
    38         PKIX_DECREF(state->basicConstraintsOID);
    40 cleanup:
    42         PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
    43 }
    45 /*
    46  * FUNCTION: pkix_BasicConstraintsCheckerState_RegisterSelf
    47  * DESCRIPTION:
    48  *  Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
    49  * THREAD SAFETY:
    50  *  Not Thread Safe - for performance and complexity reasons
    51  *
    52  *  Since this function is only called by PKIX_PL_Initialize, which should
    53  *  only be called once, it is acceptable that this function is not
    54  *  thread-safe.
    55  */
    56 PKIX_Error *
    57 pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext)
    58 {
    59         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    60         pkix_ClassTable_Entry entry;
    62         PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
    63                 "pkix_BasicConstraintsCheckerState_RegisterSelf");
    65         entry.description = "BasicConstraintsCheckerState";
    66         entry.objCounter = 0;
    67         entry.typeObjectSize = sizeof(pkix_BasicConstraintsCheckerState);
    68         entry.destructor = pkix_BasicConstraintsCheckerState_Destroy;
    69         entry.equalsFunction = NULL;
    70         entry.hashcodeFunction = NULL;
    71         entry.toStringFunction = NULL;
    72         entry.comparator = NULL;
    73         entry.duplicateFunction = NULL;
    75         systemClasses[PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE] = entry;
    77         PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
    78 }
    80 /*
    81  * FUNCTION: pkix_BasicConstraintsCheckerState_Create
    82  * DESCRIPTION:
    83  *
    84  *  Creates a new BasicConstraintsCheckerState using the number of certs in
    85  *  the chain represented by "certsRemaining" and stores it at "pState".
    86  *
    87  * PARAMETERS:
    88  *  "certsRemaining"
    89  *      Number of certificates in the chain.
    90  *  "pState"
    91  *      Address where object pointer will be stored. Must be non-NULL.
    92  *  "plContext"
    93  *      Platform-specific context pointer.
    94  * THREAD SAFETY:
    95  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    96  * RETURNS:
    97  *  Returns NULL if the function succeeds.
    98  *  Returns a BasicConstraintsCheckerState Error if the function fails in a
    99  *      non-fatal way.
   100  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   101  */
   102 static PKIX_Error *
   103 pkix_BasicConstraintsCheckerState_Create(
   104         PKIX_UInt32 certsRemaining,
   105         pkix_BasicConstraintsCheckerState **pState,
   106         void *plContext)
   107 {
   108         pkix_BasicConstraintsCheckerState *state = NULL;
   110         PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
   111                     "pkix_BasicConstraintsCheckerState_Create");
   113         PKIX_NULLCHECK_ONE(pState);
   115         PKIX_CHECK(PKIX_PL_Object_Alloc
   116                     (PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE,
   117                     sizeof (pkix_BasicConstraintsCheckerState),
   118                     (PKIX_PL_Object **)&state,
   119                     plContext),
   120                     PKIX_COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT);
   122         /* initialize fields */
   123         state->certsRemaining = certsRemaining;
   124         state->maxPathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
   126         PKIX_CHECK(PKIX_PL_OID_Create
   127                     (PKIX_BASICCONSTRAINTS_OID,
   128                     &state->basicConstraintsOID,
   129                     plContext),
   130                     PKIX_OIDCREATEFAILED);
   132         *pState = state;
   133         state = NULL;
   135 cleanup:
   137         PKIX_DECREF(state);
   139         PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
   140 }
   142 /* --Private-BasicConstraintsChecker-Functions------------------------------ */
   144 /*
   145  * FUNCTION: pkix_BasicConstraintsChecker_Check
   146  * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
   147  */
   148 PKIX_Error *
   149 pkix_BasicConstraintsChecker_Check(
   150         PKIX_CertChainChecker *checker,
   151         PKIX_PL_Cert *cert,
   152         PKIX_List *unresolvedCriticalExtensions,  /* list of PKIX_PL_OID */
   153         void **pNBIOContext,
   154         void *plContext)
   155 {
   156         PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
   157         pkix_BasicConstraintsCheckerState *state = NULL;
   158         PKIX_Boolean caFlag = PKIX_FALSE;
   159         PKIX_Int32 pathLength = 0;
   160         PKIX_Int32 maxPathLength_now;
   161         PKIX_Boolean isSelfIssued = PKIX_FALSE;
   163         PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Check");
   164         PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
   166         *pNBIOContext = NULL; /* we never block on pending I/O */
   168         PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
   169                     (checker, (PKIX_PL_Object **)&state, plContext),
   170                     PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
   172         state->certsRemaining--;
   174         if (state->certsRemaining != 0) {
   176                 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
   177                     (cert, &basicConstraints, plContext),
   178                     PKIX_CERTGETBASICCONSTRAINTSFAILED);
   180                 /* get CA Flag and path length */
   181                 if (basicConstraints != NULL) {
   182                         PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
   183                             (basicConstraints,
   184                             &caFlag,
   185                             plContext),
   186                             PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
   188                 if (caFlag == PKIX_TRUE) {
   189                         PKIX_CHECK
   190                             (PKIX_PL_BasicConstraints_GetPathLenConstraint
   191                             (basicConstraints,
   192                             &pathLength,
   193                             plContext),
   194                             PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
   195                 }
   197                 }else{
   198                         caFlag = PKIX_FALSE;
   199                         pathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
   200                 }
   202                 PKIX_CHECK(pkix_IsCertSelfIssued
   203                         (cert,
   204                         &isSelfIssued,
   205                         plContext),
   206                         PKIX_ISCERTSELFISSUEDFAILED);
   208                 maxPathLength_now = state->maxPathLength;
   210                 if (isSelfIssued != PKIX_TRUE) {
   212                     /* Not last CA Cert, but maxPathLength is down to zero */
   213                     if (maxPathLength_now == 0) {
   214                         PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDLN);
   215                     }
   217                     if (caFlag == PKIX_FALSE) {
   218                         PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDCA);
   219                     }
   221                     if (maxPathLength_now > 0) { /* can be unlimited (-1) */
   222                         maxPathLength_now--;
   223                     }
   225                 }
   227                 if (caFlag == PKIX_TRUE) {
   228                     if (maxPathLength_now == PKIX_UNLIMITED_PATH_CONSTRAINT){
   229                             maxPathLength_now = pathLength;
   230                     } else {
   231                             /* If pathLength is not specified, don't set */
   232                         if (pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) {
   233                             maxPathLength_now =
   234                                     (maxPathLength_now > pathLength)?
   235                                     pathLength:maxPathLength_now;
   236                         }
   237                     }
   238                 }
   240                 state->maxPathLength = maxPathLength_now;
   241         }
   243         /* Remove Basic Constraints Extension OID from list */
   244         if (unresolvedCriticalExtensions != NULL) {
   246                 PKIX_CHECK(pkix_List_Remove
   247                             (unresolvedCriticalExtensions,
   248                             (PKIX_PL_Object *) state->basicConstraintsOID,
   249                             plContext),
   250                             PKIX_LISTREMOVEFAILED);
   251         }
   254         PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
   255                     (checker, (PKIX_PL_Object *)state, plContext),
   256                     PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
   259 cleanup:
   260         PKIX_DECREF(state);
   261         PKIX_DECREF(basicConstraints);
   262         PKIX_RETURN(CERTCHAINCHECKER);
   264 }
   266 /*
   267  * FUNCTION: pkix_BasicConstraintsChecker_Initialize
   268  * DESCRIPTION:
   269  *  Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
   270  * THREAD SAFETY:
   271  *  Not Thread Safe - for performance and complexity reasons
   272  *
   273  *  Since this function is only called by PKIX_PL_Initialize, which should
   274  *  only be called once, it is acceptable that this function is not
   275  *  thread-safe.
   276  */
   277 PKIX_Error *
   278 pkix_BasicConstraintsChecker_Initialize(
   279         PKIX_UInt32 certsRemaining,
   280         PKIX_CertChainChecker **pChecker,
   281         void *plContext)
   282 {
   283         pkix_BasicConstraintsCheckerState *state = NULL;
   285         PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Initialize");
   286         PKIX_NULLCHECK_ONE(pChecker);
   288         PKIX_CHECK(pkix_BasicConstraintsCheckerState_Create
   289                     (certsRemaining, &state, plContext),
   290                     PKIX_BASICCONSTRAINTSCHECKERSTATECREATEFAILED);
   292         PKIX_CHECK(PKIX_CertChainChecker_Create
   293                     (pkix_BasicConstraintsChecker_Check,
   294                     PKIX_FALSE,
   295                     PKIX_FALSE,
   296                     NULL,
   297                     (PKIX_PL_Object *)state,
   298                     pChecker,
   299                     plContext),
   300                     PKIX_CERTCHAINCHECKERCHECKFAILED);
   302 cleanup:
   303         PKIX_DECREF(state);
   305         PKIX_RETURN(CERTCHAINCHECKER);
   306 }

mercurial