security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.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_nameconstraintschecker.c
     6  *
     7  * Functions for Name Constraints Checkers
     8  *
     9  */
    11 #include "pkix_nameconstraintschecker.h"
    13 /* --Private-NameConstraintsCheckerState-Functions---------------------- */
    15 /*
    16  * FUNCTION: pkix_NameConstraintsCheckerstate_Destroy
    17  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
    18  */
    19 static PKIX_Error *
    20 pkix_NameConstraintsCheckerState_Destroy(
    21         PKIX_PL_Object *object,
    22         void *plContext)
    23 {
    24         pkix_NameConstraintsCheckerState *state = NULL;
    26         PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
    27                     "pkix_NameConstraintsCheckerState_Destroy");
    28         PKIX_NULLCHECK_ONE(object);
    30         /* Check that object type */
    31         PKIX_CHECK(pkix_CheckType
    32             (object, PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, plContext),
    33             PKIX_OBJECTNOTNAMECONSTRAINTSCHECKERSTATE);
    35         state = (pkix_NameConstraintsCheckerState *)object;
    37         PKIX_DECREF(state->nameConstraints);
    38         PKIX_DECREF(state->nameConstraintsOID);
    40 cleanup:
    42         PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
    43 }
    45 /*
    46  * FUNCTION: pkix_NameConstraintsCheckerState_RegisterSelf
    47  *
    48  * DESCRIPTION:
    49  *  Registers PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE and its related
    50  *  functions with systemClasses[]
    51  *
    52  * THREAD SAFETY:
    53  *  Not Thread Safe - for performance and complexity reasons
    54  *
    55  *  Since this function is only called by PKIX_PL_Initialize, which should
    56  *  only be called once, it is acceptable that this function is not
    57  *  thread-safe.
    58  */
    59 PKIX_Error *
    60 pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext)
    61 {
    62         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    63         pkix_ClassTable_Entry entry;
    65         PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
    66                     "pkix_NameConstraintsCheckerState_RegisterSelf");
    68         entry.description = "NameConstraintsCheckerState";
    69         entry.objCounter = 0;
    70         entry.typeObjectSize = sizeof(pkix_NameConstraintsCheckerState);
    71         entry.destructor = pkix_NameConstraintsCheckerState_Destroy;
    72         entry.equalsFunction = NULL;
    73         entry.hashcodeFunction = NULL;
    74         entry.toStringFunction = NULL;
    75         entry.comparator = NULL;
    76         entry.duplicateFunction = NULL;
    78         systemClasses[PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE] = entry;
    80         PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
    81 }
    83 /*
    84  * FUNCTION: pkix_NameConstraintsCheckerState_Create
    85  *
    86  * DESCRIPTION:
    87  *  Allocate and initialize NameConstraintsChecker state data.
    88  *
    89  * PARAMETERS
    90  *  "nameConstraints"
    91  *      Address of NameConstraints to be stored in state. May be NULL.
    92  *  "numCerts"
    93  *      Number of certificates in the validation chain. This data is used
    94  *      to identify end-entity.
    95  *  "pCheckerState"
    96  *      Address of NameConstraintsCheckerState that is returned. Must be
    97  *      non-NULL.
    98  *  "plContext" - Platform-specific context pointer.
    99  *
   100  * THREAD SAFETY:
   101  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   102  *
   103  * RETURNS:
   104  *  Returns NULL if the function succeeds.
   105  *  Returns a CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in
   106  *  a non-fatal way.
   107  *  Returns a Fatal Error
   108  */
   109 static PKIX_Error *
   110 pkix_NameConstraintsCheckerState_Create(
   111     PKIX_PL_CertNameConstraints *nameConstraints,
   112     PKIX_UInt32 numCerts,
   113     pkix_NameConstraintsCheckerState **pCheckerState,
   114     void *plContext)
   115 {
   116         pkix_NameConstraintsCheckerState *state = NULL;
   118         PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
   119                     "pkix_NameConstraintsCheckerState_Create");
   120         PKIX_NULLCHECK_ONE(pCheckerState);
   122         PKIX_CHECK(PKIX_PL_Object_Alloc
   123                     (PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE,
   124                     sizeof (pkix_NameConstraintsCheckerState),
   125                     (PKIX_PL_Object **)&state,
   126                     plContext),
   127                     PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT);
   129         /* Initialize fields */
   131         PKIX_CHECK(PKIX_PL_OID_Create
   132                     (PKIX_NAMECONSTRAINTS_OID,
   133                     &state->nameConstraintsOID,
   134                     plContext),
   135                     PKIX_OIDCREATEFAILED);
   137         PKIX_INCREF(nameConstraints);
   139         state->nameConstraints = nameConstraints;
   140         state->certsRemaining = numCerts;
   142         *pCheckerState = state;
   143         state = NULL;
   145 cleanup:
   147         PKIX_DECREF(state);
   149         PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
   150 }
   152 /* --Private-NameConstraintsChecker-Functions------------------------- */
   154 /*
   155  * FUNCTION: pkix_NameConstraintsChecker_Check
   156  * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
   157  */
   158 static PKIX_Error *
   159 pkix_NameConstraintsChecker_Check(
   160         PKIX_CertChainChecker *checker,
   161         PKIX_PL_Cert *cert,
   162         PKIX_List *unresolvedCriticalExtensions,
   163         void **pNBIOContext,
   164         void *plContext)
   165 {
   166         pkix_NameConstraintsCheckerState *state = NULL;
   167         PKIX_PL_CertNameConstraints *nameConstraints = NULL;
   168         PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL;
   169         PKIX_Boolean selfIssued = PKIX_FALSE;
   170         PKIX_Boolean lastCert = PKIX_FALSE;
   172         PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check");
   173         PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
   175         *pNBIOContext = NULL; /* we never block on pending I/O */
   177         PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
   178                     (checker, (PKIX_PL_Object **)&state, plContext),
   179                     PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
   181         state->certsRemaining--;
   182         lastCert = state->certsRemaining == 0;
   184         /* Get status of self issued */
   185         PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
   186                     PKIX_ISCERTSELFISSUEDFAILED);
   188         /* Check on non self-issued and if so only for last cert */
   189         if (selfIssued == PKIX_FALSE ||
   190             (selfIssued == PKIX_TRUE && lastCert)) {
   191                 PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
   192                     (cert, state->nameConstraints, lastCert,
   193                       plContext),
   194                     PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
   195         }
   197         if (!lastCert) {
   199             PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
   200                     (cert, &nameConstraints, plContext),
   201                     PKIX_CERTGETNAMECONSTRAINTSFAILED);
   203             /* Merge with previous name constraints kept in state */
   205             if (nameConstraints != NULL) {
   207                 if (state->nameConstraints == NULL) {
   209                         state->nameConstraints = nameConstraints;
   211                 } else {
   213                         PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints
   214                                 (nameConstraints,
   215                                 state->nameConstraints,
   216                                 &mergedNameConstraints,
   217                                 plContext),
   218                                 PKIX_CERTMERGENAMECONSTRAINTSFAILED);
   220                         PKIX_DECREF(nameConstraints);
   221                         PKIX_DECREF(state->nameConstraints);
   223                         state->nameConstraints = mergedNameConstraints;
   224                 }
   226                 /* Remove Name Constraints Extension OID from list */
   227                 if (unresolvedCriticalExtensions != NULL) {
   228                         PKIX_CHECK(pkix_List_Remove
   229                                     (unresolvedCriticalExtensions,
   230                                     (PKIX_PL_Object *)state->nameConstraintsOID,
   231                                     plContext),
   232                                     PKIX_LISTREMOVEFAILED);
   233                 }
   234             }
   235         }
   237         PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
   238                     (checker, (PKIX_PL_Object *)state, plContext),
   239                     PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
   241 cleanup:
   243         PKIX_DECREF(state);
   245         PKIX_RETURN(CERTCHAINCHECKER);
   246 }
   248 /*
   249  * FUNCTION: pkix_NameConstraintsChecker_Initialize
   250  *
   251  * DESCRIPTION:
   252  *  Create a CertChainChecker with a NameConstraintsCheckerState. The
   253  *  NameConstraintsCheckerState is created with "trustedNC" and "numCerts"
   254  *  as its initial state. The CertChainChecker for the NameConstraints is
   255  *  returned at address of "pChecker".
   256  *
   257  * PARAMETERS
   258  *  "trustedNC"
   259  *      The NameConstraints from trusted anchor Cert is stored at "trustedNC"
   260  *      for initialization. May be NULL.
   261  *  "numCerts"
   262  *      Number of certificates in the validation chain. This data is used
   263  *      to identify end-entity.
   264  *  "pChecker"
   265  *      Address of CertChainChecker to bo created and returned.
   266  *      Must be non-NULL.
   267  *  "plContext" - Platform-specific context pointer.
   268  *
   269  * THREAD SAFETY:
   270  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   271  *
   272  * RETURNS:
   273  *  Returns NULL if the function succeeds.
   274  *  Returns a CERTCHAINCHECKER Error if the function fails in a non-fatal way.
   275  *  Returns a Fatal Error
   276  */
   277 PKIX_Error *
   278 pkix_NameConstraintsChecker_Initialize(
   279         PKIX_PL_CertNameConstraints *trustedNC,
   280         PKIX_UInt32 numCerts,
   281         PKIX_CertChainChecker **pChecker,
   282         void *plContext)
   283 {
   284         pkix_NameConstraintsCheckerState *state = NULL;
   286         PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Initialize");
   287         PKIX_NULLCHECK_ONE(pChecker);
   289         PKIX_CHECK(pkix_NameConstraintsCheckerState_Create
   290                     (trustedNC, numCerts, &state, plContext),
   291                     PKIX_NAMECONSTRAINTSCHECKERSTATECREATEFAILED);
   293         PKIX_CHECK(PKIX_CertChainChecker_Create
   294                     (pkix_NameConstraintsChecker_Check,
   295                     PKIX_FALSE,
   296                     PKIX_FALSE,
   297                     NULL,
   298                     (PKIX_PL_Object *) state,
   299                     pChecker,
   300                     plContext),
   301                     PKIX_CERTCHAINCHECKERCREATEFAILED);
   303 cleanup:
   305         PKIX_DECREF(state);
   307         PKIX_RETURN(CERTCHAINCHECKER);
   308 }

mercurial