1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_pl_ekuchecker.c
40 * User Defined ExtenedKeyUsage Function Definitions
44 #include "pkix_pl_ekuchecker.h"
46 char *ekuOidStrings
[] = {
47 "1.3.6.1.5.5.7.3.1", /* id-kp-serverAuth */
48 "1.3.6.1.5.5.7.3.2", /* id-kp-clientAuth */
49 "1.3.6.1.5.5.7.3.3", /* id-kp-codeSigning */
50 "1.3.6.1.5.5.7.3.4", /* id-kp-emailProtection */
51 "1.3.6.1.5.5.7.3.8", /* id-kp-timeStamping */
52 "1.3.6.1.5.5.7.3.9", /* id-kp-OCSPSigning */
56 #define CERTUSAGE_NONE (-1)
58 PKIX_Int32 ekuCertUsages
[] = {
59 1<<certUsageSSLServer
,
60 1<<certUsageSSLClient
,
61 1<<certUsageObjectSigner
,
62 1<<certUsageEmailRecipient
| 1<<certUsageEmailSigner
,
64 1<<certUsageStatusResponder
68 * FUNCTION: pkix_pl_EkuChecker_Destroy
69 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
72 pkix_pl_EkuChecker_Destroy(
73 PKIX_PL_Object
*object
,
76 pkix_pl_EkuChecker
*ekuCheckerState
= NULL
;
78 PKIX_ENTER(EKUCHECKER
, "pkix_pl_EkuChecker_Destroy");
79 PKIX_NULLCHECK_ONE(object
);
81 PKIX_CHECK(pkix_CheckType(object
, PKIX_EKUCHECKER_TYPE
, plContext
),
82 PKIX_OBJECTNOTANEKUCHECKERSTATE
);
84 ekuCheckerState
= (pkix_pl_EkuChecker
*)object
;
86 PKIX_DECREF(ekuCheckerState
->ekuOID
);
90 PKIX_RETURN(EKUCHECKER
);
94 * FUNCTION: pkix_pl_EkuChecker_GetRequiredEku
97 * This function retrieves application specified ExtenedKeyUsage(s) from
98 * ComCertSetparams and converts its OID representations to SECCertUsageEnum.
99 * The result is stored and returned in bit mask at "pRequiredExtKeyUsage".
103 * a PKIX_CertSelector links to PKIX_ComCertSelParams where a list of
104 * Extended Key Usage OIDs specified by application can be retrieved for
105 * verification. Must be non-NULL.
106 * "pRequiredExtKeyUsage"
107 * Address where the result is returned. Must be non-NULL.
109 * Platform-specific context pointer.
112 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
115 * Returns NULL if the function succeeds.
116 * Returns a UserDefinedModules Error if the function fails in a non-fatal
118 * Returns a Fatal Error
121 pkix_pl_EkuChecker_GetRequiredEku(
122 PKIX_CertSelector
*certSelector
,
123 PKIX_UInt32
*pRequiredExtKeyUsage
,
126 PKIX_ComCertSelParams
*comCertSelParams
= NULL
;
127 PKIX_List
*supportedOids
= NULL
;
128 PKIX_List
*requiredOid
= NULL
;
129 PKIX_UInt32 requiredExtKeyUsage
= 0;
130 PKIX_UInt32 numItems
= 0;
131 PKIX_PL_OID
*ekuOid
= NULL
;
133 PKIX_Boolean isContained
= PKIX_FALSE
;
135 PKIX_ENTER(EKUCHECKER
, "pkix_pl_EkuChecker_GetRequiredEku");
136 PKIX_NULLCHECK_TWO(certSelector
, pRequiredExtKeyUsage
);
138 /* Get initial EKU OIDs from ComCertSelParams, if set */
139 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
140 (certSelector
, &comCertSelParams
, plContext
),
141 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED
);
143 if (comCertSelParams
!= NULL
) {
145 PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
146 (comCertSelParams
, &requiredOid
, plContext
),
147 PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED
);
151 /* Map application specified EKU OIDs to NSS SECCertUsageEnum */
153 if (requiredOid
!= NULL
) {
155 PKIX_CHECK(PKIX_List_Create(&supportedOids
, plContext
),
156 PKIX_LISTCREATEFAILED
);
158 /* Create a supported OIDs list */
160 while (ekuOidStrings
[i
] != NULL
) {
162 PKIX_CHECK(PKIX_PL_OID_Create
166 PKIX_OIDCREATEFAILED
);
168 PKIX_CHECK(PKIX_List_AppendItem
170 (PKIX_PL_Object
*)ekuOid
,
172 PKIX_LISTAPPENDITEMFAILED
);
178 /* Map from OID's to SECCertUsageEnum */
179 PKIX_CHECK(PKIX_List_GetLength
180 (supportedOids
, &numItems
, plContext
),
181 PKIX_LISTGETLENGTHFAILED
);
183 for (i
= 0; i
< numItems
; i
++) {
185 PKIX_CHECK(PKIX_List_GetItem
188 (PKIX_PL_Object
**)&ekuOid
,
190 PKIX_LISTGETITEMFAILED
);
192 PKIX_CHECK(pkix_List_Contains
194 (PKIX_PL_Object
*)ekuOid
,
197 PKIX_LISTCONTAINSFAILED
);
201 if (isContained
== PKIX_TRUE
&&
202 ekuCertUsages
[i
] != CERTUSAGE_NONE
) {
204 requiredExtKeyUsage
|= ekuCertUsages
[i
];
209 *pRequiredExtKeyUsage
= requiredExtKeyUsage
;
214 PKIX_DECREF(requiredOid
);
215 PKIX_DECREF(supportedOids
);
216 PKIX_DECREF(comCertSelParams
);
218 PKIX_RETURN(EKUCHECKER
);
222 * FUNCTION: pkix_EkuChecker_Create
225 * Creates a new Extend Key Usage CheckerState using "params" to retrieve
226 * application specified EKU for verification and stores it at "pState".
230 * a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
231 * Extended Key Usage OIDs specified by application can be retrieved for
234 * Address where state pointer will be stored. Must be non-NULL.
236 * Platform-specific context pointer.
238 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
240 * Returns NULL if the function succeeds.
241 * Returns a UserDefinedModules Error if the function fails in a
243 * Returns a Fatal Error if the function fails in an unrecoverable way.
246 pkix_pl_EkuChecker_Create(
247 PKIX_ProcessingParams
*params
,
248 pkix_pl_EkuChecker
**pState
,
251 pkix_pl_EkuChecker
*state
= NULL
;
252 PKIX_CertSelector
*certSelector
= NULL
;
253 PKIX_UInt32 requiredExtKeyUsage
= 0;
255 PKIX_ENTER(EKUCHECKER
, "pkix_pl_EkuChecker_Create");
256 PKIX_NULLCHECK_TWO(params
, pState
);
258 PKIX_CHECK(PKIX_PL_Object_Alloc
259 (PKIX_EKUCHECKER_TYPE
,
260 sizeof (pkix_pl_EkuChecker
),
261 (PKIX_PL_Object
**)&state
,
263 PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT
);
266 PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
267 (params
, &certSelector
, plContext
),
268 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED
);
270 if (certSelector
!= NULL
) {
272 PKIX_CHECK(pkix_pl_EkuChecker_GetRequiredEku
273 (certSelector
, &requiredExtKeyUsage
, plContext
),
274 PKIX_EKUCHECKERGETREQUIREDEKUFAILED
);
277 PKIX_CHECK(PKIX_PL_OID_Create
278 (PKIX_EXTENDEDKEYUSAGE_OID
,
281 PKIX_OIDCREATEFAILED
);
283 state
->requiredExtKeyUsage
= requiredExtKeyUsage
;
290 PKIX_DECREF(certSelector
);
294 PKIX_RETURN(EKUCHECKER
);
298 * FUNCTION: pkix_pl_EkuChecker_Check
301 * This function determines the Extended Key Usage OIDs specified by the
302 * application is included in the Extended Key Usage OIDs of this "cert".
306 * Address of CertChainChecker which has the state data.
309 * Address of Certificate that is to be validated. Must be non-NULL.
310 * "unresolvedCriticalExtensions"
311 * A List OIDs. The OID for Extended Key Usage is removed.
313 * Platform-specific context pointer.
315 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
317 * Returns NULL if the function succeeds.
318 * Returns a UserDefinedModules Error if the function fails in
320 * Returns a Fatal Error if the function fails in an unrecoverable way.
323 pkix_pl_EkuChecker_Check(
324 PKIX_CertChainChecker
*checker
,
326 PKIX_List
*unresolvedCriticalExtensions
,
330 pkix_pl_EkuChecker
*state
= NULL
;
331 PKIX_Boolean checkPassed
= PKIX_TRUE
;
333 PKIX_ENTER(EKUCHECKER
, "pkix_pl_EkuChecker_Check");
334 PKIX_NULLCHECK_THREE(checker
, cert
, pNBIOContext
);
336 *pNBIOContext
= NULL
; /* no non-blocking IO */
338 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
339 (checker
, (PKIX_PL_Object
**)&state
, plContext
),
340 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED
);
342 if (state
->requiredExtKeyUsage
!= 0) {
344 PKIX_CHECK(pkix_pl_Cert_CheckExtendedKeyUsage
346 state
->requiredExtKeyUsage
,
349 PKIX_CERTCHECKEXTENDEDKEYUSAGEFAILED
);
351 if (checkPassed
== PKIX_FALSE
) {
352 PKIX_ERROR(PKIX_EXTENDEDKEYUSAGECHECKINGFAILED
);
361 PKIX_RETURN(EKUCHECKER
);
365 * FUNCTION: pkix_pl_EkuChecker_RegisterSelf
368 * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
369 * functions with systemClasses[]
372 * Not Thread Safe - for performance and complexity reasons
374 * Since this function is only called by PKIX_PL_Initialize, which should
375 * only be called once, it is acceptable that this function is not
379 pkix_pl_EkuChecker_RegisterSelf(void *plContext
)
381 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
382 pkix_ClassTable_Entry entry
;
386 "pkix_pl_EkuChecker_RegisterSelf");
388 entry
.description
= "EkuChecker";
389 entry
.objCounter
= 0;
390 entry
.typeObjectSize
= sizeof(pkix_pl_EkuChecker
);
391 entry
.destructor
= pkix_pl_EkuChecker_Destroy
,
392 entry
.equalsFunction
= NULL
;
393 entry
.hashcodeFunction
= NULL
;
394 entry
.toStringFunction
= NULL
;
395 entry
.comparator
= NULL
;
396 entry
.duplicateFunction
= NULL
;
398 systemClasses
[PKIX_EKUCHECKER_TYPE
] = entry
;
400 PKIX_RETURN(EKUCHECKER
);
404 * FUNCTION: pkix_pl_EkuChecker_Initialize
405 * (see comments in pkix_sample_modules.h)
408 PKIX_PL_EkuChecker_Create(
409 PKIX_ProcessingParams
*params
,
412 PKIX_CertChainChecker
*checker
= NULL
;
413 pkix_pl_EkuChecker
*state
= NULL
;
414 PKIX_List
*critExtOIDsList
= NULL
;
416 PKIX_ENTER(EKUCHECKER
, "PKIX_PL_EkuChecker_Initialize");
417 PKIX_NULLCHECK_ONE(params
);
420 * This function and functions in this file provide an example of how
421 * an application defined checker can be hooked into libpkix.
424 PKIX_CHECK(pkix_pl_EkuChecker_Create
425 (params
, &state
, plContext
),
426 PKIX_EKUCHECKERSTATECREATEFAILED
);
428 PKIX_CHECK(PKIX_List_Create(&critExtOIDsList
, plContext
),
429 PKIX_LISTCREATEFAILED
);
431 PKIX_CHECK(PKIX_List_AppendItem
433 (PKIX_PL_Object
*)state
->ekuOID
,
435 PKIX_LISTAPPENDITEMFAILED
);
437 PKIX_CHECK(PKIX_CertChainChecker_Create
438 (pkix_pl_EkuChecker_Check
,
439 PKIX_TRUE
, /* forwardCheckingSupported */
440 PKIX_FALSE
, /* forwardDirectionExpected */
442 (PKIX_PL_Object
*) state
,
445 PKIX_CERTCHAINCHECKERCREATEFAILED
);
447 PKIX_CHECK(PKIX_ProcessingParams_AddCertChainChecker
448 (params
, checker
, plContext
),
449 PKIX_PROCESSINGPARAMSADDCERTCHAINCHECKERFAILED
);
453 PKIX_DECREF(critExtOIDsList
);
454 PKIX_DECREF(checker
);
457 PKIX_RETURN(EKUCHECKER
);