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_certselector.c
6  *
7  * CertSelector Object Functions
8  *
9  */
10 
11 #include "pkix_certselector.h"
12 
13 /* --Private-Functions-------------------------------------------- */
14 
15 /*
16  * FUNCTION: pkix_CertSelector_Destroy
17  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
18  */
19 static PKIX_Error *
pkix_CertSelector_Destroy(PKIX_PL_Object * object,void * plContext)20 pkix_CertSelector_Destroy(
21         PKIX_PL_Object *object,
22         void *plContext)
23 {
24         PKIX_CertSelector *selector = NULL;
25 
26         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Destroy");
27         PKIX_NULLCHECK_ONE(object);
28 
29         /* Check that this object is a cert selector */
30         PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
31                     PKIX_OBJECTNOTCERTSELECTOR);
32 
33         selector = (PKIX_CertSelector *)object;
34         PKIX_DECREF(selector->params);
35         PKIX_DECREF(selector->context);
36 
37 cleanup:
38 
39         PKIX_RETURN(CERTSELECTOR);
40 }
41 
42 /*
43  * FUNCTION: pkix_CertSelector_Duplicate
44  * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
45  */
46 static PKIX_Error *
pkix_CertSelector_Duplicate(PKIX_PL_Object * object,PKIX_PL_Object ** pNewObject,void * plContext)47 pkix_CertSelector_Duplicate(
48         PKIX_PL_Object *object,
49         PKIX_PL_Object **pNewObject,
50         void *plContext)
51 {
52         PKIX_CertSelector *certSelector = NULL;
53         PKIX_CertSelector *certSelectorDuplicate = NULL;
54 
55         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Duplicate");
56         PKIX_NULLCHECK_TWO(object, pNewObject);
57 
58         PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
59                     PKIX_OBJECTNOTCERTSELECTOR);
60 
61         certSelector = (PKIX_CertSelector *)object;
62 
63         PKIX_CHECK(PKIX_CertSelector_Create
64                     (certSelector->matchCallback,
65                     certSelector->context,
66                     &certSelectorDuplicate,
67                     plContext),
68                     PKIX_CERTSELECTORCREATEFAILED);
69 
70         PKIX_CHECK(PKIX_PL_Object_Duplicate
71                     ((PKIX_PL_Object *)certSelector->params,
72                     (PKIX_PL_Object **)&certSelectorDuplicate->params,
73                     plContext),
74                     PKIX_OBJECTDUPLICATEFAILED);
75 
76         *pNewObject = (PKIX_PL_Object *)certSelectorDuplicate;
77 
78 cleanup:
79 
80         if (PKIX_ERROR_RECEIVED){
81                 PKIX_DECREF(certSelectorDuplicate);
82         }
83 
84         PKIX_RETURN(CERTSELECTOR);
85 }
86 
87 /*
88  * FUNCTION: pkix_CertSelector_Match_BasicConstraint
89  * DESCRIPTION:
90  *
91  *  Determines whether the Cert pointed to by "cert" matches the basic
92  *  constraints criterion using the basic constraints field of the
93  *  ComCertSelParams pointed to by "params". If the basic constraints field is
94  *  -1, no basic constraints check is done and the Cert is considered to match
95  *  the basic constraints criterion. If the Cert does not match the basic
96  *  constraints criterion, an Error pointer is returned.
97  *
98  *  In order to match against this criterion, there are several possibilities.
99  *
100  *  1) If the criterion's minimum path length is greater than or equal to zero,
101  *  a certificate must include a BasicConstraints extension with a pathLen of
102  *  at least this value.
103  *
104  *  2) If the criterion's minimum path length is -2, a certificate must be an
105  *  end-entity certificate.
106  *
107  *  3) If the criterion's minimum path length is -1, no basic constraints check
108  *  is done and all certificates are considered to match this criterion.
109  *
110  * PARAMETERS:
111  *  "params"
112  *      Address of ComCertSelParams whose basic constraints field is used.
113  *      Must be non-NULL.
114  *  "cert"
115  *      Address of Cert that is to be matched. Must be non-NULL.
116  *  "pResult"
117  *      Address of PKIX_Boolean that returns the match result.
118  *  "plContext"
119  *      Platform-specific context pointer.
120  * OUTPUT PARAMETERS ON FAILURE:
121  *   If the function returns a failure,
122  *   the output parameters of this function are undefined.
123  * THREAD SAFETY:
124  *  Conditionally Thread Safe
125  *      (see Thread Safety Definitions in Programmer's Guide)
126  * RETURNS:
127  *  Returns NULL if the function succeeds.
128  *  Returns a CertSelector Error if the function fails in a non-fatal way.
129  *  Returns a Fatal Error if the function fails in an unrecoverable way.
130  */
131 static PKIX_Error *
pkix_CertSelector_Match_BasicConstraint(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)132 pkix_CertSelector_Match_BasicConstraint(
133         PKIX_ComCertSelParams *params,
134         PKIX_PL_Cert *cert,
135         PKIX_Boolean *pResult,
136         void *plContext)
137 {
138         PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
139         PKIX_Boolean caFlag = PKIX_FALSE; /* EE Cert by default */
140         PKIX_Int32 pathLength = 0;
141         PKIX_Int32 minPathLength = 0;
142 
143         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_BasicConstraint");
144         PKIX_NULLCHECK_THREE(params, cert, pResult);
145         *pResult = PKIX_TRUE;
146 
147         PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
148                 (params, &minPathLength, plContext),
149                 PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
150 
151         /* If the minPathLength is unlimited (-1), no checking */
152         if (minPathLength == PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH) {
153                 goto cleanup;
154         }
155 
156         PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
157                     (cert, &basicConstraints, plContext),
158                     PKIX_CERTGETBASICCONSTRAINTSFAILED);
159 
160         if (basicConstraints != NULL) {
161                 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
162                             (basicConstraints, &caFlag, plContext),
163                             PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
164 
165                 PKIX_CHECK(PKIX_PL_BasicConstraints_GetPathLenConstraint
166                         (basicConstraints, &pathLength, plContext),
167                         PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
168         }
169 
170         /*
171          * if minPathLength >= 0, the cert must have a BasicConstraints ext and
172          * the pathLength in this cert
173          * BasicConstraints needs to be >= minPathLength.
174          */
175         if (minPathLength >= 0){
176                 if ((!basicConstraints) || (caFlag == PKIX_FALSE)){
177                         PKIX_ERROR(PKIX_CERTNOTALLOWEDTOSIGNCERTIFICATES);
178                 } else if ((pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) &&
179                             (pathLength < minPathLength)){
180                         PKIX_CERTSELECTOR_DEBUG
181                             ("Basic Constraints path length match failed\n");
182                         *pResult = PKIX_FALSE;
183                         PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
184                 }
185         }
186 
187         /* if the minPathLength is -2, this cert must be an end-entity cert. */
188         if (minPathLength == PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH) {
189                 if (caFlag == PKIX_TRUE) {
190                     PKIX_CERTSELECTOR_DEBUG
191                         ("Basic Constraints end-entity match failed\n");
192                     *pResult = PKIX_FALSE;
193                     PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
194                 }
195         }
196 
197 cleanup:
198 
199         PKIX_DECREF(basicConstraints);
200         PKIX_RETURN(CERTSELECTOR);
201 }
202 
203 /*
204  * FUNCTION: pkix_CertSelector_Match_Policies
205  * DESCRIPTION:
206  *
207  *  Determines whether the Cert pointed to by "cert" matches the policy
208  *  constraints specified in the ComCertsSelParams given by "params".
209  *  If "params" specifies a policy constraint of NULL, all certificates
210  *  match. If "params" specifies an empty list, "cert" must have at least
211  *  some policy. Otherwise "cert" must include at least one of the
212  *  policies in the list. See the description of PKIX_CertSelector in
213  *  pkix_certsel.h for more.
214  *
215  * PARAMETERS:
216  *  "params"
217  *      Address of ComCertSelParams whose policy criterion (if any) is used.
218  *      Must be non-NULL.
219  *  "cert"
220  *      Address of Cert that is to be matched. Must be non-NULL.
221  *  "pResult"
222  *      Address of PKIX_Boolean that returns the match result.
223  *  "plContext"
224  *      Platform-specific context pointer.
225  * THREAD SAFETY:
226  *  Conditionally Thread Safe
227  *      (see Thread Safety Definitions in Programmer's Guide)
228  * RETURNS:
229  *  Returns NULL if the function succeeds.
230  *  Returns a CertSelector Error if the function fails in a non-fatal way.
231  *  Returns a Fatal Error if the function fails in an unrecoverable way.
232  */
233 static PKIX_Error *
pkix_CertSelector_Match_Policies(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)234 pkix_CertSelector_Match_Policies(
235         PKIX_ComCertSelParams *params,
236         PKIX_PL_Cert *cert,
237         PKIX_Boolean *pResult,
238         void *plContext)
239 {
240         PKIX_UInt32 numConstraintPolicies = 0;
241         PKIX_UInt32 numCertPolicies = 0;
242         PKIX_UInt32 certPolicyIndex = 0;
243         PKIX_Boolean result = PKIX_FALSE;
244         PKIX_List *constraintPolicies = NULL; /* List of PKIX_PL_OID */
245         PKIX_List *certPolicyInfos = NULL; /* List of PKIX_PL_CertPolicyInfo */
246         PKIX_PL_CertPolicyInfo *policyInfo = NULL;
247         PKIX_PL_OID *polOID = NULL;
248 
249         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_Policies");
250         PKIX_NULLCHECK_THREE(params, cert, pResult);
251 
252         PKIX_CHECK(PKIX_ComCertSelParams_GetPolicy
253                 (params, &constraintPolicies, plContext),
254                 PKIX_COMCERTSELPARAMSGETPOLICYFAILED);
255 
256         /* If constraintPolicies is NULL, all certificates "match" */
257         if (constraintPolicies) {
258             PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
259                 (cert, &certPolicyInfos, plContext),
260                 PKIX_CERTGETPOLICYINFORMATIONFAILED);
261 
262             /* No hope of a match if cert has no policies */
263             if (!certPolicyInfos) {
264                 PKIX_CERTSELECTOR_DEBUG("Certificate has no policies\n");
265                 *pResult = PKIX_FALSE;
266                 PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
267             }
268 
269             PKIX_CHECK(PKIX_List_GetLength
270                 (constraintPolicies, &numConstraintPolicies, plContext),
271                 PKIX_LISTGETLENGTHFAILED);
272 
273             if (numConstraintPolicies > 0) {
274 
275                 PKIX_CHECK(PKIX_List_GetLength
276                         (certPolicyInfos, &numCertPolicies, plContext),
277                         PKIX_LISTGETLENGTHFAILED);
278 
279                 for (certPolicyIndex = 0;
280                         ((!result) && (certPolicyIndex < numCertPolicies));
281                         certPolicyIndex++) {
282 
283                         PKIX_CHECK(PKIX_List_GetItem
284                                 (certPolicyInfos,
285                                 certPolicyIndex,
286                                 (PKIX_PL_Object **)&policyInfo,
287                                 plContext),
288                                 PKIX_LISTGETELEMENTFAILED);
289                         PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
290                                 (policyInfo, &polOID, plContext),
291                                 PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
292 
293                         PKIX_CHECK(pkix_List_Contains
294                                 (constraintPolicies,
295                                 (PKIX_PL_Object *)polOID,
296                                 &result,
297                                 plContext),
298                                 PKIX_LISTCONTAINSFAILED);
299                         PKIX_DECREF(policyInfo);
300                         PKIX_DECREF(polOID);
301                 }
302                 if (!result) {
303                     *pResult = PKIX_FALSE;
304                     PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
305                 }
306             }
307         }
308 
309 cleanup:
310 
311         PKIX_DECREF(constraintPolicies);
312         PKIX_DECREF(certPolicyInfos);
313         PKIX_DECREF(policyInfo);
314         PKIX_DECREF(polOID);
315 
316         PKIX_RETURN(CERTSELECTOR);
317 
318 }
319 
320 /*
321  * FUNCTION: pkix_CertSelector_Match_CertificateValid
322  * DESCRIPTION:
323  *
324  *  Determines whether the Cert pointed to by "cert" matches the certificate
325  *  validity criterion using the CertificateValid field of the
326  *  ComCertSelParams pointed to by "params". If the CertificateValid field is
327  *  NULL, no validity check is done and the Cert is considered to match
328  *  the CertificateValid criterion. If the CertificateValid field specifies a
329  *  Date prior to the notBefore field in the Cert, or greater than the notAfter
330  *  field in the Cert, an Error is returned.
331  *
332  * PARAMETERS:
333  *  "params"
334  *      Address of ComCertSelParams whose certValid field is used.
335  *      Must be non-NULL.
336  *  "cert"
337  *      Address of Cert that is to be matched. Must be non-NULL.
338  *  "pResult"
339  *      Address of PKIX_Boolean that returns the match result.
340  *  "plContext"
341  *      Platform-specific context pointer.
342  * THREAD SAFETY:
343  *  Conditionally Thread Safe
344  *      (see Thread Safety Definitions in Programmer's Guide)
345  * RETURNS:
346  *  Returns NULL if the function succeeds.
347  *  Returns a CertSelector Error if the function fails in a non-fatal way.
348  *  Returns a Fatal Error if the function fails in an unrecoverable way.
349  */
350 static PKIX_Error *
pkix_CertSelector_Match_CertificateValid(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)351 pkix_CertSelector_Match_CertificateValid(
352         PKIX_ComCertSelParams *params,
353         PKIX_PL_Cert *cert,
354         PKIX_Boolean *pResult,
355         void *plContext)
356 {
357         PKIX_PL_Date *validityTime = NULL;
358 
359         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_CertificateValid");
360         PKIX_NULLCHECK_THREE(params, cert, pResult);
361 
362         PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
363                 (params, &validityTime, plContext),
364                 PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
365 
366         /* If the validityTime is not set, all certificates are acceptable */
367         if (validityTime) {
368                 PKIX_CHECK(PKIX_PL_Cert_CheckValidity
369                         (cert, validityTime, plContext),
370                         PKIX_CERTCHECKVALIDITYFAILED);
371         }
372 
373 cleanup:
374         if (PKIX_ERROR_RECEIVED) {
375             *pResult = PKIX_FALSE;
376         }
377         PKIX_DECREF(validityTime);
378 
379         PKIX_RETURN(CERTSELECTOR);
380 }
381 
382 /*
383  * FUNCTION: pkix_CertSelector_Match_NameConstraints
384  * DESCRIPTION:
385  *
386  *  Determines whether the Cert pointed to by "cert" matches the name
387  *  constraints criterion specified in the ComCertSelParams pointed to by
388  *  "params". If the name constraints field is NULL, no name constraints check
389  *  is done and the Cert is considered to match the name constraints criterion.
390  *  If the Cert does not match the name constraints criterion, an Error pointer
391  *  is returned.
392  *
393  * PARAMETERS:
394  *  "params"
395  *      Address of ComCertSelParams whose name constraints field is used.
396  *      Must be non-NULL.
397  *  "cert"
398  *      Address of Cert that is to be matched. Must be non-NULL.
399  *  "pResult"
400  *      Address of PKIX_Boolean that returns the match result.
401  *  "plContext"
402  *      Platform-specific context pointer.
403  * THREAD SAFETY:
404  *  Conditionally Thread Safe
405  *      (see Thread Safety Definitions in Programmer's Guide)
406  * RETURNS:
407  *  Returns NULL if the function succeeds.
408  *  Returns a CertSelector Error if the function fails in a non-fatal way.
409  *  Returns a Fatal Error if the function fails in an unrecoverable way.
410  */
411 static PKIX_Error *
pkix_CertSelector_Match_NameConstraints(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)412 pkix_CertSelector_Match_NameConstraints(
413         PKIX_ComCertSelParams *params,
414         PKIX_PL_Cert *cert,
415         PKIX_Boolean *pResult,
416         void *plContext)
417 {
418         PKIX_PL_CertNameConstraints *nameConstraints = NULL;
419 
420         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_NameConstraints");
421         PKIX_NULLCHECK_THREE(params, cert, pResult);
422 
423         PKIX_CHECK(PKIX_ComCertSelParams_GetNameConstraints
424                 (params, &nameConstraints, plContext),
425                 PKIX_COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED);
426 
427         if (nameConstraints != NULL) {
428                 /* As only the end-entity certificate should have
429                  * the common name constrained as if it was a dNSName,
430                  * do not constrain the common name when building a
431                  * forward path.
432                  */
433                 PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
434                     (cert, nameConstraints, PKIX_FALSE, plContext),
435                     PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
436         }
437 
438 cleanup:
439         if (PKIX_ERROR_RECEIVED) {
440             *pResult = PKIX_FALSE;
441         }
442 
443         PKIX_DECREF(nameConstraints);
444         PKIX_RETURN(CERTSELECTOR);
445 }
446 
447 /*
448  * FUNCTION: pkix_CertSelector_Match_PathToNames
449  * DESCRIPTION:
450  *
451  *  Determines whether the names at pathToNames in "params" complies with the
452  *  NameConstraints pointed to by "cert". If the pathToNames field is NULL
453  *  or there is no name constraints for this "cert", no checking is done
454  *  and the Cert is considered to match the name constraints criterion.
455  *  If the Cert does not match the name constraints criterion, an Error
456  *  pointer is returned.
457  *
458  * PARAMETERS:
459  *  "params"
460  *      Address of ComCertSelParams whose PathToNames field is used.
461  *      Must be non-NULL.
462  *  "cert"
463  *      Address of Cert that is to be matched. Must be non-NULL.
464  *  "pResult"
465  *      Address of PKIX_Boolean that returns the match result.
466  *  "plContext"
467  *      Platform-specific context pointer.
468  * THREAD SAFETY:
469  *  Conditionally Thread Safe
470  *      (see Thread Safety Definitions in Programmer's Guide)
471  * RETURNS:
472  *  Returns NULL if the function succeeds.
473  *  Returns a CertSelector Error if the function fails in a non-fatal way.
474  *  Returns a Fatal Error if the function fails in an unrecoverable way.
475  */
476 static PKIX_Error *
pkix_CertSelector_Match_PathToNames(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)477 pkix_CertSelector_Match_PathToNames(
478         PKIX_ComCertSelParams *params,
479         PKIX_PL_Cert *cert,
480         PKIX_Boolean *pResult,
481         void *plContext)
482 {
483         PKIX_List *pathToNamesList = NULL;
484         PKIX_Boolean passed = PKIX_FALSE;
485         PKIX_PL_CertNameConstraints *nameConstraints = NULL;
486 
487         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_PathToNames");
488         PKIX_NULLCHECK_THREE(params, cert, pResult);
489 
490         PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
491                 (params, &pathToNamesList, plContext),
492                 PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
493 
494         if (pathToNamesList != NULL) {
495 
496             PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
497                     (cert, &nameConstraints, plContext),
498                     PKIX_CERTGETNAMECONSTRAINTSFAILED);
499 
500             if (nameConstraints != NULL) {
501 
502                 PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
503                         (pathToNamesList, nameConstraints, &passed, plContext),
504                         PKIX_CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED);
505 
506                 if (passed != PKIX_TRUE) {
507                     *pResult = PKIX_FALSE;
508                     PKIX_ERROR(PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
509                 }
510             }
511 
512         }
513 
514 cleanup:
515 
516         PKIX_DECREF(nameConstraints);
517         PKIX_DECREF(pathToNamesList);
518 
519         PKIX_RETURN(CERTSELECTOR);
520 }
521 
522 /*
523  * FUNCTION: pkix_CertSelector_Match_SubjAltNames
524  * DESCRIPTION:
525  *
526  *  Determines whether the names at subjAltNames in "params" match with the
527  *  SubjAltNames pointed to by "cert". If the subjAltNames field is NULL,
528  *  no name checking is done and the Cert is considered to match the
529  *  criterion. If the Cert does not match the criterion, an Error pointer
530  *  is returned.
531  *
532  * PARAMETERS:
533  *  "params"
534  *      Address of ComCertSelParams whose SubjAltNames field is used.
535  *      Must be non-NULL.
536  *  "cert"
537  *      Address of Cert that is to be matched. Must be non-NULL.
538  *  "pResult"
539  *      Address of PKIX_Boolean that returns the match result.
540  *  "plContext"
541  *      Platform-specific context pointer.
542  * THREAD SAFETY:
543  *  Conditionally Thread Safe
544  *      (see Thread Safety Definitions in Programmer's Guide)
545  * RETURNS:
546  *  Returns NULL if the function succeeds.
547  *  Returns a CertSelector Error if the function fails in a non-fatal way.
548  *  Returns a Fatal Error if the function fails in an unrecoverable way.
549  */
550 static PKIX_Error *
pkix_CertSelector_Match_SubjAltNames(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)551 pkix_CertSelector_Match_SubjAltNames(
552         PKIX_ComCertSelParams *params,
553         PKIX_PL_Cert *cert,
554         PKIX_Boolean *pResult,
555         void *plContext)
556 {
557         PKIX_List *subjAltNamesList = NULL;
558         PKIX_List *certSubjAltNames = NULL;
559         PKIX_PL_GeneralName *name = NULL;
560         PKIX_Boolean checkPassed = PKIX_FALSE;
561         PKIX_Boolean matchAll = PKIX_TRUE;
562         PKIX_UInt32 i, numItems;
563         PKIX_UInt32 matchCount = 0;
564 
565         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjAltNames");
566         PKIX_NULLCHECK_THREE(params, cert, pResult);
567 
568         PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
569                     (params, &matchAll, plContext),
570                     PKIX_COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED);
571 
572         PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
573                     (params, &subjAltNamesList, plContext),
574                     PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
575 
576         if (subjAltNamesList != NULL) {
577 
578             PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
579                     (cert, &certSubjAltNames, plContext),
580                     PKIX_CERTGETSUBJALTNAMESFAILED);
581 
582             if (certSubjAltNames == NULL) {
583                 *pResult = PKIX_FALSE;
584                 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
585             }
586 
587             PKIX_CHECK(PKIX_List_GetLength
588                        (subjAltNamesList, &numItems, plContext),
589                        PKIX_LISTGETLENGTHFAILED);
590 
591             for (i = 0; i < numItems; i++) {
592 
593                 PKIX_CHECK(PKIX_List_GetItem
594                            (subjAltNamesList,
595                             i,
596                             (PKIX_PL_Object **) &name,
597                             plContext),
598                            PKIX_LISTGETITEMFAILED);
599 
600                 PKIX_CHECK(pkix_List_Contains
601                            (certSubjAltNames,
602                             (PKIX_PL_Object *) name,
603                             &checkPassed,
604                             plContext),
605                            PKIX_LISTCONTAINSFAILED);
606 
607                 PKIX_DECREF(name);
608 
609                 if (checkPassed == PKIX_TRUE) {
610 
611                     if (matchAll == PKIX_FALSE) {
612                         /* one match is good enough */
613                         matchCount = numItems;
614                         break;
615                     } else {
616                         /* else continue checking next */
617                         matchCount++;
618                     }
619 
620                 }
621 
622             }
623 
624             if (matchCount != numItems) {
625                 *pResult = PKIX_FALSE;
626                 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
627             }
628         }
629 
630 cleanup:
631 
632         PKIX_DECREF(name);
633         PKIX_DECREF(certSubjAltNames);
634         PKIX_DECREF(subjAltNamesList);
635 
636         PKIX_RETURN(CERTSELECTOR);
637 }
638 
639 /*
640  * FUNCTION: pkix_CertSelector_Match_ExtendedKeyUsage
641  * DESCRIPTION:
642  *
643  *  Determines whether the names at ExtKeyUsage in "params" matches with the
644  *  ExtKeyUsage pointed to by "cert". If the ExtKeyUsage criterion or
645  *  ExtKeyUsage in "cert" is NULL, no checking is done and the Cert is
646  *  considered a match. If the Cert does not match, an Error pointer is
647  *  returned.
648  *
649  * PARAMETERS:
650  *  "params"
651  *      Address of ComCertSelParams whose ExtKeyUsage field is used.
652  *      Must be non-NULL.
653  *  "cert"
654  *      Address of Cert that is to be matched. Must be non-NULL.
655  *  "pResult"
656  *      Address of PKIX_Boolean that returns the match result.
657  *  "plContext"
658  *      Platform-specific context pointer.
659  * THREAD SAFETY:
660  *  Conditionally Thread Safe
661  *      (see Thread Safety Definitions in Programmer's Guide)
662  * RETURNS:
663  *  Returns NULL if the function succeeds.
664  *  Returns a CertSelector Error if the function fails in a non-fatal way.
665  *  Returns a Fatal Error if the function fails in an unrecoverable way.
666  */
667 static PKIX_Error *
pkix_CertSelector_Match_ExtendedKeyUsage(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)668 pkix_CertSelector_Match_ExtendedKeyUsage(
669         PKIX_ComCertSelParams *params,
670         PKIX_PL_Cert *cert,
671         PKIX_Boolean *pResult,
672         void *plContext)
673 {
674         PKIX_List *extKeyUsageList = NULL;
675         PKIX_List *certExtKeyUsageList = NULL;
676         PKIX_PL_OID *ekuOid = NULL;
677         PKIX_Boolean isContained = PKIX_FALSE;
678         PKIX_UInt32 numItems = 0;
679         PKIX_UInt32 i;
680 
681         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_ExtendedKeyUsage");
682         PKIX_NULLCHECK_THREE(params, cert, pResult);
683 
684         PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
685                     (params, &extKeyUsageList, plContext),
686                     PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
687 
688         if (extKeyUsageList == NULL) {
689                 goto cleanup;
690         }
691 
692         PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
693                     (cert, &certExtKeyUsageList, plContext),
694                     PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
695 
696         if (certExtKeyUsageList != NULL) {
697 
698             PKIX_CHECK(PKIX_List_GetLength
699                     (extKeyUsageList, &numItems, plContext),
700                     PKIX_LISTGETLENGTHFAILED);
701 
702             for (i = 0; i < numItems; i++) {
703 
704                 PKIX_CHECK(PKIX_List_GetItem
705                     (extKeyUsageList, i, (PKIX_PL_Object **)&ekuOid, plContext),
706                     PKIX_LISTGETITEMFAILED);
707 
708                 PKIX_CHECK(pkix_List_Contains
709                     (certExtKeyUsageList,
710                     (PKIX_PL_Object *)ekuOid,
711                     &isContained,
712                     plContext),
713                     PKIX_LISTCONTAINSFAILED);
714 
715                 PKIX_DECREF(ekuOid);
716 
717                 if (isContained != PKIX_TRUE) {
718                     *pResult = PKIX_FALSE;
719                     PKIX_ERROR(PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
720                 }
721             }
722         }
723 
724 cleanup:
725 
726         PKIX_DECREF(ekuOid);
727         PKIX_DECREF(extKeyUsageList);
728         PKIX_DECREF(certExtKeyUsageList);
729 
730         PKIX_RETURN(CERTSELECTOR);
731 }
732 
733 /*
734  * FUNCTION: pkix_CertSelector_Match_KeyUsage
735  * DESCRIPTION:
736  *
737  *  Determines whether the bits at KeyUsage in "params" matches with the
738  *  KeyUsage pointed to by "cert". If the KeyUsage in params is 0
739  *  no checking is done and the Cert is considered a match. If the Cert does
740  *  not match, an Error pointer is returned.
741  *
742  * PARAMETERS:
743  *  "params"
744  *      Address of ComCertSelParams whose ExtKeyUsage field is used.
745  *      Must be non-NULL.
746  *  "cert"
747  *      Address of Cert that is to be matched. Must be non-NULL.
748  *  "pResult"
749  *      Address of PKIX_Boolean that returns the match result.
750  *  "plContext"
751  *      Platform-specific context pointer.
752  * THREAD SAFETY:
753  *  Conditionally Thread Safe
754  *      (see Thread Safety Definitions in Programmer's Guide)
755  * RETURNS:
756  *  Returns NULL if the function succeeds.
757  *  Returns a CertSelector Error if the function fails in a non-fatal way.
758  *  Returns a Fatal Error if the function fails in an unrecoverable way.
759  */
760 static PKIX_Error *
pkix_CertSelector_Match_KeyUsage(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)761 pkix_CertSelector_Match_KeyUsage(
762         PKIX_ComCertSelParams *params,
763         PKIX_PL_Cert *cert,
764         PKIX_Boolean *pResult,
765         void *plContext)
766 {
767         PKIX_UInt32 keyUsage = 0;
768 
769         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_KeyUsage");
770         PKIX_NULLCHECK_THREE(params, cert, pResult);
771 
772         PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
773                     (params, &keyUsage, plContext),
774                     PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED);
775 
776         if (keyUsage != 0) {
777 
778             PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage
779                         (cert, keyUsage, plContext),
780                         PKIX_CERTVERIFYKEYUSAGEFAILED);
781 
782         }
783 
784 cleanup:
785         if (PKIX_ERROR_RECEIVED) {
786             *pResult = PKIX_FALSE;
787         }
788 
789         PKIX_RETURN(CERTSELECTOR);
790 }
791 
792 /*
793  * FUNCTION: pkix_CertSelector_Match_SubjKeyId
794  * DESCRIPTION:
795  *
796  *  Determines whether the bytes at subjKeyId in "params" matches with the
797  *  Subject Key Identifier pointed to by "cert". If the subjKeyId in params is
798  *  set to NULL or the Cert doesn't have a Subject Key Identifier, no checking
799  *  is done and the Cert is considered a match. If the Cert does not match, an
800  *  Error pointer is returned.
801  *
802  * PARAMETERS:
803  *  "params"
804  *      Address of ComCertSelParams whose subjKeyId field is used.
805  *      Must be non-NULL.
806  *  "cert"
807  *      Address of Cert that is to be matched. Must be non-NULL.
808  *  "pResult"
809  *      Address of PKIX_Boolean that returns the match result.
810  *  "plContext"
811  *      Platform-specific context pointer.
812  * THREAD SAFETY:
813  *  Conditionally Thread Safe
814  *      (see Thread Safety Definitions in Programmer's Guide)
815  * RETURNS:
816  *  Returns NULL if the function succeeds.
817  *  Returns a CertSelector Error if the function fails in a non-fatal way.
818  *  Returns a Fatal Error if the function fails in an unrecoverable way.
819  */
820 static PKIX_Error *
pkix_CertSelector_Match_SubjKeyId(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)821 pkix_CertSelector_Match_SubjKeyId(
822         PKIX_ComCertSelParams *params,
823         PKIX_PL_Cert *cert,
824         PKIX_Boolean *pResult,
825         void *plContext)
826 {
827         PKIX_PL_ByteArray *selSubjKeyId = NULL;
828         PKIX_PL_ByteArray *certSubjKeyId = NULL;
829         PKIX_Boolean equals = PKIX_FALSE;
830 
831         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjKeyId");
832         PKIX_NULLCHECK_THREE(params, cert, pResult);
833 
834         PKIX_CHECK(PKIX_ComCertSelParams_GetSubjKeyIdentifier
835                     (params, &selSubjKeyId, plContext),
836                     PKIX_COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED);
837 
838         if (selSubjKeyId != NULL) {
839 
840                 PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
841                     (cert, &certSubjKeyId, plContext),
842                     PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
843 
844                 if (certSubjKeyId == NULL) {
845                     goto cleanup;
846                 }
847 
848                 PKIX_CHECK(PKIX_PL_Object_Equals
849                            ((PKIX_PL_Object *)selSubjKeyId,
850                             (PKIX_PL_Object *)certSubjKeyId,
851                             &equals,
852                             plContext),
853                            PKIX_OBJECTEQUALSFAILED);
854 
855                 if (equals == PKIX_FALSE) {
856                     *pResult = PKIX_FALSE;
857                     PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
858                 }
859         }
860 
861 cleanup:
862 
863         PKIX_DECREF(selSubjKeyId);
864         PKIX_DECREF(certSubjKeyId);
865 
866         PKIX_RETURN(CERTSELECTOR);
867 }
868 
869 /*
870  * FUNCTION: pkix_CertSelector_Match_AuthKeyId
871  * DESCRIPTION:
872  *
873  *  Determines whether the bytes at authKeyId in "params" matches with the
874  *  Authority Key Identifier pointed to by "cert". If the authKeyId in params
875  *  is set to NULL, no checking is done and the Cert is considered a match. If
876  *  the Cert does not match, an Error pointer is returned.
877  *
878  * PARAMETERS:
879  *  "params"
880  *      Address of ComCertSelParams whose authKeyId field is used.
881  *      Must be non-NULL.
882  *  "cert"
883  *      Address of Cert that is to be matched. Must be non-NULL.
884  *  "pResult"
885  *      Address of PKIX_Boolean that returns the match result.
886  *  "plContext"
887  *      Platform-specific context pointer.
888  * THREAD SAFETY:
889  *  Conditionally Thread Safe
890  *      (see Thread Safety Definitions in Programmer's Guide)
891  * RETURNS:
892  *  Returns NULL if the function succeeds.
893  *  Returns a CertSelector Error if the function fails in a non-fatal way.
894  *  Returns a Fatal Error if the function fails in an unrecoverable way.
895  */
896 static PKIX_Error *
pkix_CertSelector_Match_AuthKeyId(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)897 pkix_CertSelector_Match_AuthKeyId(
898         PKIX_ComCertSelParams *params,
899         PKIX_PL_Cert *cert,
900         PKIX_Boolean *pResult,
901         void *plContext)
902 {
903         PKIX_PL_ByteArray *selAuthKeyId = NULL;
904         PKIX_PL_ByteArray *certAuthKeyId = NULL;
905         PKIX_Boolean equals = PKIX_FALSE;
906 
907         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_AuthKeyId");
908         PKIX_NULLCHECK_THREE(params, cert, pResult);
909 
910         PKIX_CHECK(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
911                     (params, &selAuthKeyId, plContext),
912                     PKIX_COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED);
913 
914         if (selAuthKeyId != NULL) {
915 
916                 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
917                     (cert, &certAuthKeyId, plContext),
918                     PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
919 
920                 if (certAuthKeyId == NULL) {
921                     *pResult = PKIX_FALSE;
922                     PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
923                 }
924                 PKIX_CHECK(PKIX_PL_Object_Equals
925                            ((PKIX_PL_Object *)selAuthKeyId,
926                             (PKIX_PL_Object *)certAuthKeyId,
927                             &equals,
928                             plContext),
929                            PKIX_OBJECTEQUALSFAILED);
930 
931                 if (equals != PKIX_TRUE) {
932                     *pResult = PKIX_FALSE;
933                     PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
934                 }
935         }
936 
937 cleanup:
938 
939         PKIX_DECREF(selAuthKeyId);
940         PKIX_DECREF(certAuthKeyId);
941 
942         PKIX_RETURN(CERTSELECTOR);
943 }
944 
945 /*
946  * FUNCTION: pkix_CertSelector_Match_SubjPKAlgId
947  * DESCRIPTION:
948  *
949  *  Determines whether the OID at subjPKAlgId in "params" matches with the
950  *  Subject Public Key Alg Id pointed to by "cert". If the subjPKAlgId in params
951  *  is set to NULL, no checking is done and the Cert is considered a match. If
952  *  the Cert does not match, an Error pointer is returned.
953  *
954  * PARAMETERS:
955  *  "params"
956  *      Address of ComCertSelParams whose subjPKAlgId field is used.
957  *      Must be non-NULL.
958  *  "cert"
959  *      Address of Cert that is to be matched. Must be non-NULL.
960  *  "pResult"
961  *      Address of PKIX_Boolean that returns the match result.
962  *  "plContext"
963  *      Platform-specific context pointer.
964  * THREAD SAFETY:
965  *  Conditionally Thread Safe
966  *      (see Thread Safety Definitions in Programmer's Guide)
967  * RETURNS:
968  *  Returns NULL if the function succeeds.
969  *  Returns a CertSelector Error if the function fails in a non-fatal way.
970  *  Returns a Fatal Error if the function fails in an unrecoverable way.
971  */
972 static PKIX_Error *
pkix_CertSelector_Match_SubjPKAlgId(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)973 pkix_CertSelector_Match_SubjPKAlgId(
974         PKIX_ComCertSelParams *params,
975         PKIX_PL_Cert *cert,
976         PKIX_Boolean *pResult,
977         void *plContext)
978 {
979         PKIX_PL_OID *selPKAlgId = NULL;
980         PKIX_PL_OID *certPKAlgId = NULL;
981         PKIX_Boolean equals = PKIX_FALSE;
982 
983         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPKAlgId");
984         PKIX_NULLCHECK_THREE(params, cert, pResult);
985 
986         PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPKAlgId
987                     (params, &selPKAlgId, plContext),
988                     PKIX_COMCERTSELPARAMSGETSUBJPKALGIDFAILED);
989 
990         if (selPKAlgId != NULL) {
991 
992                 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKeyAlgId
993                     (cert, &certPKAlgId, plContext),
994                     PKIX_CERTGETSUBJECTPUBLICKEYALGIDFAILED);
995 
996                 if (certPKAlgId != NULL) {
997                     *pResult = PKIX_FALSE;
998                     PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
999                 }
1000                 PKIX_CHECK(PKIX_PL_Object_Equals
1001                            ((PKIX_PL_Object *)selPKAlgId,
1002                             (PKIX_PL_Object *)certPKAlgId,
1003                             &equals,
1004                             plContext),
1005                            PKIX_OBJECTEQUALSFAILED);
1006 
1007                 if (equals != PKIX_TRUE) {
1008                     *pResult = PKIX_FALSE;
1009                     PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
1010                 }
1011         }
1012 
1013 cleanup:
1014 
1015         PKIX_DECREF(selPKAlgId);
1016         PKIX_DECREF(certPKAlgId);
1017 
1018         PKIX_RETURN(CERTSELECTOR);
1019 }
1020 
1021 /*
1022  * FUNCTION: pkix_CertSelector_Match_SubjPubKey
1023  * DESCRIPTION:
1024  *
1025  *  Determines whether the key at subjPubKey in "params" matches with the
1026  *  Subject Public Key pointed to by "cert". If the subjPubKey in params
1027  *  is set to NULL, no checking is done and the Cert is considered a match. If
1028  *  the Cert does not match, an Error pointer is returned.
1029  *
1030  * PARAMETERS:
1031  *  "params"
1032  *      Address of ComCertSelParams whose subPubKey field is used.
1033  *      Must be non-NULL.
1034  *  "cert"
1035  *      Address of Cert that is to be matched. Must be non-NULL.
1036  *  "pResult"
1037  *      Address of PKIX_Boolean that returns the match result.
1038  *  "plContext"
1039  *      Platform-specific context pointer.
1040  * THREAD SAFETY:
1041  *  Conditionally Thread Safe
1042  *      (see Thread Safety Definitions in Programmer's Guide)
1043  * RETURNS:
1044  *  Returns NULL if the function succeeds.
1045  *  Returns a CertSelector Error if the function fails in a non-fatal way.
1046  *  Returns a Fatal Error if the function fails in an unrecoverable way.
1047  */
1048 static PKIX_Error *
pkix_CertSelector_Match_SubjPubKey(PKIX_ComCertSelParams * params,PKIX_PL_Cert * cert,PKIX_Boolean * pResult,void * plContext)1049 pkix_CertSelector_Match_SubjPubKey(
1050         PKIX_ComCertSelParams *params,
1051         PKIX_PL_Cert *cert,
1052         PKIX_Boolean *pResult,
1053         void *plContext)
1054 {
1055         PKIX_PL_PublicKey *selPK = NULL;
1056         PKIX_PL_PublicKey *certPK = NULL;
1057         PKIX_Boolean equals = PKIX_FALSE;
1058 
1059         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPubKey");
1060         PKIX_NULLCHECK_THREE(params, cert, pResult);
1061 
1062         PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPubKey
1063                     (params, &selPK, plContext),
1064                     PKIX_COMCERTSELPARAMSGETSUBJPUBKEYFAILED);
1065 
1066         if (selPK != NULL) {
1067 
1068                 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
1069                     (cert, &certPK, plContext),
1070                     PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
1071 
1072                 if (certPK == NULL) {
1073                     *pResult = PKIX_FALSE;
1074                     PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
1075                 }
1076                 PKIX_CHECK(PKIX_PL_Object_Equals
1077                            ((PKIX_PL_Object *)selPK,
1078                             (PKIX_PL_Object *)certPK,
1079                             &equals,
1080                             plContext),
1081                            PKIX_OBJECTEQUALSFAILED);
1082 
1083                 if (equals != PKIX_TRUE) {
1084                     *pResult = PKIX_FALSE;
1085                     PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
1086                 }
1087         }
1088 
1089 cleanup:
1090 
1091         PKIX_DECREF(selPK);
1092         PKIX_DECREF(certPK);
1093 
1094         PKIX_RETURN(CERTSELECTOR);
1095 }
1096 
1097 /*
1098  * FUNCTION: pkix_CertSelector_DefaultMatch
1099  * DESCRIPTION:
1100  *
1101  *  This default match function determines whether the specified Cert pointed
1102  *  to by "cert" matches the criteria of the CertSelector pointed to by
1103  *  "selector". If the Cert does not match the CertSelector's
1104  *  criteria, an error will be thrown.
1105  *
1106  *  This default match function understands how to process the most common
1107  *  parameters. Any common parameter that is not set is assumed to be disabled,
1108  *  which means this function will select all certificates without regard to
1109  *  that particular disabled parameter. For example, if the SerialNumber
1110  *  parameter is not set, this function will not filter out any certificate
1111  *  based on its serial number. As such, if no parameters are set, all are
1112  *  disabled and any certificate will match. If a parameter is disabled, its
1113  *  associated PKIX_ComCertSelParams_Get* function returns a default value.
1114  *  That value is -1 for PKIX_ComCertSelParams_GetBasicConstraints and
1115  *  PKIX_ComCertSelParams_GetVersion, 0 for PKIX_ComCertSelParams_GetKeyUsage,
1116  *  and NULL for all other Get functions.
1117  *
1118  * PARAMETERS:
1119  *  "selector"
1120  *      Address of CertSelector whose MatchCallback logic and parameters are
1121  *      to be used. Must be non-NULL.
1122  *  "cert"
1123  *      Address of Cert that is to be matched using "selector".
1124  *      Must be non-NULL.
1125  *  "plContext"
1126  *      Platform-specific context pointer.
1127  * THREAD SAFETY:
1128  *  Conditionally Thread Safe
1129  *      (see Thread Safety Definitions in Programmer's Guide)
1130  * RETURNS:
1131  *  Returns NULL if the function succeeds.
1132  *  Returns a CertSelector Error if the function fails in a non-fatal way.
1133  *  Returns a Fatal Error if the function fails in an unrecoverable way.
1134  */
1135 static PKIX_Error *
pkix_CertSelector_DefaultMatch(PKIX_CertSelector * selector,PKIX_PL_Cert * cert,void * plContext)1136 pkix_CertSelector_DefaultMatch(
1137         PKIX_CertSelector *selector,
1138         PKIX_PL_Cert *cert,
1139         void *plContext)
1140 {
1141         PKIX_ComCertSelParams *params = NULL;
1142         PKIX_PL_X500Name *certSubject = NULL;
1143         PKIX_PL_X500Name *selSubject = NULL;
1144         PKIX_PL_X500Name *certIssuer = NULL;
1145         PKIX_PL_X500Name *selIssuer = NULL;
1146         PKIX_PL_BigInt *certSerialNumber = NULL;
1147         PKIX_PL_BigInt *selSerialNumber = NULL;
1148         PKIX_PL_Cert *selCert = NULL;
1149         PKIX_PL_Date *selDate = NULL;
1150         PKIX_UInt32 selVersion = 0xFFFFFFFF;
1151         PKIX_UInt32 certVersion = 0;
1152         PKIX_Boolean result = PKIX_TRUE;
1153         PKIX_Boolean isLeafCert = PKIX_TRUE;
1154 
1155 #ifdef PKIX_BUILDDEBUG
1156         PKIX_PL_String *certString = NULL;
1157         void *certAscii = NULL;
1158         PKIX_UInt32 certAsciiLen;
1159 #endif
1160 
1161         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_DefaultMatch");
1162         PKIX_NULLCHECK_TWO(selector, cert);
1163 
1164         PKIX_INCREF(selector->params);
1165         params = selector->params;
1166 
1167         /* Are we looking for CAs? */
1168         PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag
1169                     (params, &isLeafCert, plContext),
1170                     PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED);
1171 
1172         if (params == NULL){
1173                 goto cleanup;
1174         }
1175 
1176         PKIX_CHECK(PKIX_ComCertSelParams_GetVersion
1177                     (params, &selVersion, plContext),
1178                     PKIX_COMCERTSELPARAMSGETVERSIONFAILED);
1179 
1180         if (selVersion != 0xFFFFFFFF){
1181                 PKIX_CHECK(PKIX_PL_Cert_GetVersion
1182                             (cert, &certVersion, plContext),
1183                             PKIX_CERTGETVERSIONFAILED);
1184 
1185                 if (selVersion != certVersion) {
1186                         PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTVERSIONFAILED);
1187                 }
1188         }
1189 
1190         PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
1191                     (params, &selSubject, plContext),
1192                     PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
1193 
1194         if (selSubject){
1195                 PKIX_CHECK(PKIX_PL_Cert_GetSubject
1196                             (cert, &certSubject, plContext),
1197                             PKIX_CERTGETSUBJECTFAILED);
1198 
1199                 if (certSubject){
1200                         PKIX_CHECK(PKIX_PL_X500Name_Match
1201                             (selSubject, certSubject, &result, plContext),
1202                             PKIX_X500NAMEMATCHFAILED);
1203 
1204                         if (result == PKIX_FALSE){
1205                             PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
1206                         }
1207                 } else { /* cert has no subject */
1208                         PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
1209                 }
1210         }
1211 
1212         PKIX_CHECK(PKIX_ComCertSelParams_GetIssuer
1213                     (params, &selIssuer, plContext),
1214                     PKIX_COMCERTSELPARAMSGETISSUERFAILED);
1215 
1216         if (selIssuer){
1217                 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
1218                             (cert, &certIssuer, plContext),
1219                             PKIX_CERTGETISSUERFAILED);
1220 
1221                 PKIX_CHECK(PKIX_PL_X500Name_Match
1222                             (selIssuer, certIssuer, &result, plContext),
1223                             PKIX_X500NAMEMATCHFAILED);
1224 
1225                 if (result == PKIX_FALSE){
1226                         PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTISSUERFAILED);
1227                 }
1228         }
1229 
1230         PKIX_CHECK(PKIX_ComCertSelParams_GetSerialNumber
1231                     (params, &selSerialNumber, plContext),
1232                     PKIX_COMCERTSELPARAMSGETSERIALNUMBERFAILED);
1233 
1234         if (selSerialNumber){
1235                 PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber
1236                             (cert, &certSerialNumber, plContext),
1237                             PKIX_CERTGETSERIALNUMBERFAILED);
1238 
1239                 PKIX_CHECK(PKIX_PL_Object_Equals
1240                             ((PKIX_PL_Object *)selSerialNumber,
1241                             (PKIX_PL_Object *)certSerialNumber,
1242                             &result,
1243                             plContext),
1244                             PKIX_OBJECTEQUALSFAILED);
1245 
1246                 if (result == PKIX_FALSE){
1247                         PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSERIALNUMFAILED);
1248                 }
1249         }
1250 
1251         PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
1252                     (params, &selCert, plContext),
1253                     PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
1254 
1255         if (selCert){
1256                 PKIX_CHECK(PKIX_PL_Object_Equals
1257                             ((PKIX_PL_Object *) selCert,
1258                             (PKIX_PL_Object *) cert,
1259                             &result,
1260                             plContext),
1261                             PKIX_OBJECTEQUALSFAILED);
1262 
1263                 if (result == PKIX_FALSE){
1264                         PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTOBJECTFAILED);
1265                 }
1266         }
1267 
1268         PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
1269                     (params, &selDate, plContext),
1270                     PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
1271 
1272         if (selDate){
1273                 PKIX_CHECK(PKIX_PL_Cert_CheckValidity
1274                             (cert, selDate, plContext),
1275                             PKIX_CERTCHECKVALIDITYFAILED);
1276         }
1277 
1278         PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint
1279                     (params, cert, &result, plContext),
1280                     PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED);
1281 
1282         PKIX_CHECK(pkix_CertSelector_Match_Policies
1283                     (params, cert, &result, plContext),
1284                     PKIX_CERTSELECTORMATCHPOLICIESFAILED);
1285 
1286         PKIX_CHECK(pkix_CertSelector_Match_CertificateValid
1287                     (params, cert, &result, plContext),
1288                     PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED);
1289 
1290         PKIX_CHECK(pkix_CertSelector_Match_NameConstraints
1291                     (params, cert, &result, plContext),
1292                     PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED);
1293 
1294         PKIX_CHECK(pkix_CertSelector_Match_PathToNames
1295                     (params, cert, &result, plContext),
1296                     PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
1297 
1298         PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames
1299                     (params, cert, &result, plContext),
1300                     PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
1301 
1302         /* Check key usage and cert type based on certificate usage. */
1303         PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert,
1304                                                      plContext),
1305                    PKIX_CERTVERIFYCERTTYPEFAILED);
1306 
1307         /* Next two check are for user supplied additional KU and EKU. */
1308         PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage
1309                     (params, cert, &result, plContext),
1310                     PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
1311 
1312         PKIX_CHECK(pkix_CertSelector_Match_KeyUsage
1313                     (params, cert, &result, plContext),
1314                     PKIX_CERTSELECTORMATCHKEYUSAGEFAILED);
1315 
1316         PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId
1317                     (params, cert, &result, plContext),
1318                     PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
1319 
1320         PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId
1321                     (params, cert, &result, plContext),
1322                     PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
1323 
1324         PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId
1325                     (params, cert, &result, plContext),
1326                     PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
1327 
1328         PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey
1329                     (params, cert, &result, plContext),
1330                     PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
1331 
1332         /* if we reach here, the cert has successfully matched criteria */
1333 
1334 
1335 #ifdef PKIX_BUILDDEBUG
1336 
1337         PKIX_CHECK(pkix_pl_Cert_ToString_Helper
1338                     (cert, PKIX_TRUE, &certString, plContext),
1339                     PKIX_CERTTOSTRINGHELPERFAILED);
1340 
1341         PKIX_CHECK(PKIX_PL_String_GetEncoded
1342                 (certString,
1343                 PKIX_ESCASCII,
1344                 &certAscii,
1345                 &certAsciiLen,
1346                 plContext),
1347                 PKIX_STRINGGETENCODEDFAILED);
1348 
1349         PKIX_CERTSELECTOR_DEBUG_ARG("Cert Selected:\n%s\n", certAscii);
1350 
1351 #endif
1352 
1353 cleanup:
1354 
1355 #ifdef PKIX_BUILDDEBUG
1356         PKIX_DECREF(certString);
1357         PKIX_FREE(certAscii);
1358 #endif
1359 
1360         PKIX_DECREF(certSubject);
1361         PKIX_DECREF(selSubject);
1362         PKIX_DECREF(certIssuer);
1363         PKIX_DECREF(selIssuer);
1364         PKIX_DECREF(certSerialNumber);
1365         PKIX_DECREF(selSerialNumber);
1366         PKIX_DECREF(selCert);
1367         PKIX_DECREF(selDate);
1368         PKIX_DECREF(params);
1369         PKIX_RETURN(CERTSELECTOR);
1370 }
1371 
1372 /*
1373  * FUNCTION: pkix_CertSelector_RegisterSelf
1374  * DESCRIPTION:
1375  *  Registers PKIX_CERTSELECTOR_TYPE and its related functions with
1376  *  systemClasses[]
1377  * THREAD SAFETY:
1378  *  Not Thread Safe - for performance and complexity reasons
1379  *
1380  *  Since this function is only called by PKIX_PL_Initialize, which should
1381  *  only be called once, it is acceptable that this function is not
1382  *  thread-safe.
1383  */
1384 PKIX_Error *
pkix_CertSelector_RegisterSelf(void * plContext)1385 pkix_CertSelector_RegisterSelf(void *plContext)
1386 {
1387         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1388         pkix_ClassTable_Entry entry;
1389 
1390         PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_RegisterSelf");
1391 
1392         entry.description = "CertSelector";
1393         entry.objCounter = 0;
1394         entry.typeObjectSize = sizeof(PKIX_CertSelector);
1395         entry.destructor = pkix_CertSelector_Destroy;
1396         entry.equalsFunction = NULL;
1397         entry.hashcodeFunction = NULL;
1398         entry.toStringFunction = NULL;
1399         entry.comparator = NULL;
1400         entry.duplicateFunction = pkix_CertSelector_Duplicate;
1401 
1402         systemClasses[PKIX_CERTSELECTOR_TYPE] = entry;
1403 
1404         PKIX_RETURN(CERTSELECTOR);
1405 }
1406 
1407 /* --Public-Functions--------------------------------------------- */
1408 
1409 
1410 /*
1411  * FUNCTION: PKIX_CertSelector_Create (see comments in pkix_certsel.h)
1412  */
1413 PKIX_Error *
PKIX_CertSelector_Create(PKIX_CertSelector_MatchCallback callback,PKIX_PL_Object * certSelectorContext,PKIX_CertSelector ** pSelector,void * plContext)1414 PKIX_CertSelector_Create(
1415         PKIX_CertSelector_MatchCallback callback,
1416         PKIX_PL_Object *certSelectorContext,
1417         PKIX_CertSelector **pSelector,
1418         void *plContext)
1419 {
1420         PKIX_CertSelector *selector = NULL;
1421 
1422         PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Create");
1423         PKIX_NULLCHECK_ONE(pSelector);
1424 
1425         PKIX_CHECK(PKIX_PL_Object_Alloc
1426                     (PKIX_CERTSELECTOR_TYPE,
1427                     sizeof (PKIX_CertSelector),
1428                     (PKIX_PL_Object **)&selector,
1429                     plContext),
1430                     PKIX_COULDNOTCREATECERTSELECTOROBJECT);
1431 
1432         /*
1433          * if user specified a particular match callback, we use that one.
1434          * otherwise, we use the default match implementation which
1435          * understands how to process PKIX_ComCertSelParams
1436          */
1437 
1438         if (callback){
1439                 selector->matchCallback = callback;
1440         } else {
1441                 selector->matchCallback = pkix_CertSelector_DefaultMatch;
1442         }
1443 
1444         /* initialize other fields */
1445         selector->params = NULL;
1446 
1447         PKIX_INCREF(certSelectorContext);
1448         selector->context = certSelectorContext;
1449 
1450         *pSelector = selector;
1451 
1452 cleanup:
1453 
1454         PKIX_RETURN(CERTSELECTOR);
1455 
1456 }
1457 
1458 /*
1459  * FUNCTION: PKIX_CertSelector_GetMatchCallback
1460  *      (see comments in pkix_certsel.h)
1461  */
1462 PKIX_Error *
PKIX_CertSelector_GetMatchCallback(PKIX_CertSelector * selector,PKIX_CertSelector_MatchCallback * pCallback,void * plContext)1463 PKIX_CertSelector_GetMatchCallback(
1464         PKIX_CertSelector *selector,
1465         PKIX_CertSelector_MatchCallback *pCallback,
1466         void *plContext)
1467 {
1468         PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetMatchCallback");
1469         PKIX_NULLCHECK_TWO(selector, pCallback);
1470 
1471         *pCallback = selector->matchCallback;
1472 
1473         PKIX_RETURN(CERTSELECTOR);
1474 }
1475 
1476 /*
1477  * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
1478  *      (see comments in pkix_certsel.h)
1479  */
1480 PKIX_Error *
PKIX_CertSelector_GetCertSelectorContext(PKIX_CertSelector * selector,PKIX_PL_Object ** pCertSelectorContext,void * plContext)1481 PKIX_CertSelector_GetCertSelectorContext(
1482         PKIX_CertSelector *selector,
1483         PKIX_PL_Object **pCertSelectorContext,
1484         void *plContext)
1485 {
1486         PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetCertSelectorContext");
1487         PKIX_NULLCHECK_TWO(selector, pCertSelectorContext);
1488 
1489         PKIX_INCREF(selector->context);
1490 
1491         *pCertSelectorContext = selector->context;
1492 
1493 cleanup:
1494         PKIX_RETURN(CERTSELECTOR);
1495 }
1496 
1497 /*
1498  * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
1499  *      (see comments in pkix_certsel.h)
1500  */
1501 PKIX_Error *
PKIX_CertSelector_GetCommonCertSelectorParams(PKIX_CertSelector * selector,PKIX_ComCertSelParams ** pParams,void * plContext)1502 PKIX_CertSelector_GetCommonCertSelectorParams(
1503         PKIX_CertSelector *selector,
1504         PKIX_ComCertSelParams **pParams,
1505         void *plContext)
1506 {
1507         PKIX_ENTER(CERTSELECTOR,
1508                     "PKIX_CertSelector_GetCommonCertSelectorParams");
1509 
1510         PKIX_NULLCHECK_TWO(selector, pParams);
1511 
1512         PKIX_INCREF(selector->params);
1513         *pParams = selector->params;
1514 
1515 cleanup:
1516         PKIX_RETURN(CERTSELECTOR);
1517 
1518 }
1519 
1520 /*
1521  * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
1522  *      (see comments in pkix_certsel.h)
1523  */
1524 PKIX_Error *
PKIX_CertSelector_SetCommonCertSelectorParams(PKIX_CertSelector * selector,PKIX_ComCertSelParams * params,void * plContext)1525 PKIX_CertSelector_SetCommonCertSelectorParams(
1526         PKIX_CertSelector *selector,
1527         PKIX_ComCertSelParams *params,
1528         void *plContext)
1529 {
1530         PKIX_ENTER(CERTSELECTOR,
1531                     "PKIX_CertSelector_SetCommonCertSelectorParams");
1532 
1533         PKIX_NULLCHECK_ONE(selector);
1534 
1535         PKIX_DECREF(selector->params);
1536         PKIX_INCREF(params);
1537         selector->params = params;
1538 
1539         PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1540                     ((PKIX_PL_Object *)selector, plContext),
1541                     PKIX_OBJECTINVALIDATECACHEFAILED);
1542 
1543 cleanup:
1544 
1545         PKIX_RETURN(CERTSELECTOR);
1546 
1547 }
1548 
1549 /*
1550  * FUNCTION: pkix_CertSelector_Select
1551  * DESCRIPTION:
1552  *
1553  *  This function applies the selector pointed to by "selector" to each Cert,
1554  *  in turn, in the List pointed to by "before", and creates a List containing
1555  *  all the Certs that matched, or passed the selection process, storing that
1556  *  List at "pAfter". If no Certs match, an empty List is stored at "pAfter".
1557  *
1558  *  The List returned in "pAfter" is immutable.
1559  *
1560  * PARAMETERS:
1561  *  "selector"
1562  *      Address of CertSelelector to be applied to the List. Must be non-NULL.
1563  *  "before"
1564  *      Address of List that is to be filtered. Must be non-NULL.
1565  *  "pAfter"
1566  *      Address at which resulting List, possibly empty, is stored. Must be
1567  *      non-NULL.
1568  *  "plContext"
1569  *      Platform-specific context pointer.
1570  * THREAD SAFETY:
1571  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1572  * RETURNS:
1573  *  Returns NULL if the function succeeds.
1574  *  Returns a CertSelector Error if the function fails in a non-fatal way.
1575  *  Returns a Fatal Error if the function fails in an unrecoverable way.
1576  */
1577 PKIX_Error *
pkix_CertSelector_Select(PKIX_CertSelector * selector,PKIX_List * before,PKIX_List ** pAfter,void * plContext)1578 pkix_CertSelector_Select(
1579 	PKIX_CertSelector *selector,
1580 	PKIX_List *before,
1581 	PKIX_List **pAfter,
1582 	void *plContext)
1583 {
1584 	PKIX_UInt32 numBefore = 0;
1585 	PKIX_UInt32 i = 0;
1586 	PKIX_List *filtered = NULL;
1587 	PKIX_PL_Cert *candidate = NULL;
1588 
1589         PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Select");
1590         PKIX_NULLCHECK_THREE(selector, before, pAfter);
1591 
1592         PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
1593                 PKIX_LISTCREATEFAILED);
1594 
1595         PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
1596                 PKIX_LISTGETLENGTHFAILED);
1597 
1598         for (i = 0; i < numBefore; i++) {
1599 
1600                 PKIX_CHECK(PKIX_List_GetItem
1601                         (before, i, (PKIX_PL_Object **)&candidate, plContext),
1602                         PKIX_LISTGETITEMFAILED);
1603 
1604                 PKIX_CHECK_ONLY_FATAL(selector->matchCallback
1605                         (selector, candidate, plContext),
1606                         PKIX_CERTSELECTORMATCHCALLBACKFAILED);
1607 
1608                 if (!(PKIX_ERROR_RECEIVED)) {
1609 
1610                         PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
1611                                 (filtered,
1612                                 (PKIX_PL_Object *)candidate,
1613                                 plContext),
1614                                 PKIX_LISTAPPENDITEMFAILED);
1615                 }
1616 
1617                 pkixTempErrorReceived = PKIX_FALSE;
1618                 PKIX_DECREF(candidate);
1619         }
1620 
1621         PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
1622                 PKIX_LISTSETIMMUTABLEFAILED);
1623 
1624         /* Don't throw away the list if one Cert was bad! */
1625         pkixTempErrorReceived = PKIX_FALSE;
1626 
1627         *pAfter = filtered;
1628         filtered = NULL;
1629 
1630 cleanup:
1631 
1632         PKIX_DECREF(filtered);
1633         PKIX_DECREF(candidate);
1634 
1635         PKIX_RETURN(CERTSELECTOR);
1636 
1637 }
1638