nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / module / pkix_pl_ekuchecker.c
blob19777d6feb8ecf7c2ff9eae2e59de79b360ff8f3
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
12 * License.
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.
21 * Contributor(s):
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 */
53 NULL
56 #define CERTUSAGE_NONE (-1)
58 PKIX_Int32 ekuCertUsages[] = {
59 1<<certUsageSSLServer,
60 1<<certUsageSSLClient,
61 1<<certUsageObjectSigner,
62 1<<certUsageEmailRecipient | 1<<certUsageEmailSigner,
63 CERTUSAGE_NONE,
64 1<<certUsageStatusResponder
68 * FUNCTION: pkix_pl_EkuChecker_Destroy
69 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
71 static PKIX_Error *
72 pkix_pl_EkuChecker_Destroy(
73 PKIX_PL_Object *object,
74 void *plContext)
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);
88 cleanup:
90 PKIX_RETURN(EKUCHECKER);
94 * FUNCTION: pkix_pl_EkuChecker_GetRequiredEku
96 * DESCRIPTION:
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".
101 * PARAMETERS
102 * "certSelector"
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.
108 * "plContext"
109 * Platform-specific context pointer.
111 * THREAD SAFETY:
112 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
114 * RETURNS:
115 * Returns NULL if the function succeeds.
116 * Returns a UserDefinedModules Error if the function fails in a non-fatal
117 * way.
118 * Returns a Fatal Error
120 PKIX_Error *
121 pkix_pl_EkuChecker_GetRequiredEku(
122 PKIX_CertSelector *certSelector,
123 PKIX_UInt32 *pRequiredExtKeyUsage,
124 void *plContext)
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;
132 PKIX_UInt32 i;
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 */
159 i = 0;
160 while (ekuOidStrings[i] != NULL) {
162 PKIX_CHECK(PKIX_PL_OID_Create
163 (ekuOidStrings[i],
164 &ekuOid,
165 plContext),
166 PKIX_OIDCREATEFAILED);
168 PKIX_CHECK(PKIX_List_AppendItem
169 (supportedOids,
170 (PKIX_PL_Object *)ekuOid,
171 plContext),
172 PKIX_LISTAPPENDITEMFAILED);
174 PKIX_DECREF(ekuOid);
175 i++;
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
186 (supportedOids,
188 (PKIX_PL_Object **)&ekuOid,
189 plContext),
190 PKIX_LISTGETITEMFAILED);
192 PKIX_CHECK(pkix_List_Contains
193 (requiredOid,
194 (PKIX_PL_Object *)ekuOid,
195 &isContained,
196 plContext),
197 PKIX_LISTCONTAINSFAILED);
199 PKIX_DECREF(ekuOid);
201 if (isContained == PKIX_TRUE &&
202 ekuCertUsages[i] != CERTUSAGE_NONE) {
204 requiredExtKeyUsage |= ekuCertUsages[i];
209 *pRequiredExtKeyUsage = requiredExtKeyUsage;
211 cleanup:
213 PKIX_DECREF(ekuOid);
214 PKIX_DECREF(requiredOid);
215 PKIX_DECREF(supportedOids);
216 PKIX_DECREF(comCertSelParams);
218 PKIX_RETURN(EKUCHECKER);
222 * FUNCTION: pkix_EkuChecker_Create
223 * DESCRIPTION:
225 * Creates a new Extend Key Usage CheckerState using "params" to retrieve
226 * application specified EKU for verification and stores it at "pState".
228 * PARAMETERS:
229 * "params"
230 * a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
231 * Extended Key Usage OIDs specified by application can be retrieved for
232 * verification.
233 * "pState"
234 * Address where state pointer will be stored. Must be non-NULL.
235 * "plContext"
236 * Platform-specific context pointer.
237 * THREAD SAFETY:
238 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
239 * RETURNS:
240 * Returns NULL if the function succeeds.
241 * Returns a UserDefinedModules Error if the function fails in a
242 * non-fatal way.
243 * Returns a Fatal Error if the function fails in an unrecoverable way.
245 static PKIX_Error *
246 pkix_pl_EkuChecker_Create(
247 PKIX_ProcessingParams *params,
248 pkix_pl_EkuChecker **pState,
249 void *plContext)
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,
262 plContext),
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,
279 &state->ekuOID,
280 plContext),
281 PKIX_OIDCREATEFAILED);
283 state->requiredExtKeyUsage = requiredExtKeyUsage;
285 *pState = state;
286 state = NULL;
288 cleanup:
290 PKIX_DECREF(certSelector);
292 PKIX_DECREF(state);
294 PKIX_RETURN(EKUCHECKER);
298 * FUNCTION: pkix_pl_EkuChecker_Check
299 * DESCRIPTION:
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".
304 * PARAMETERS:
305 * "checker"
306 * Address of CertChainChecker which has the state data.
307 * Must be non-NULL.
308 * "cert"
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.
312 * "plContext"
313 * Platform-specific context pointer.
314 * THREAD SAFETY:
315 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
316 * RETURNS:
317 * Returns NULL if the function succeeds.
318 * Returns a UserDefinedModules Error if the function fails in
319 * a non-fatal way.
320 * Returns a Fatal Error if the function fails in an unrecoverable way.
322 static PKIX_Error *
323 pkix_pl_EkuChecker_Check(
324 PKIX_CertChainChecker *checker,
325 PKIX_PL_Cert *cert,
326 PKIX_List *unresolvedCriticalExtensions,
327 void **pNBIOContext,
328 void *plContext)
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
345 (cert,
346 state->requiredExtKeyUsage,
347 &checkPassed,
348 plContext),
349 PKIX_CERTCHECKEXTENDEDKEYUSAGEFAILED);
351 if (checkPassed == PKIX_FALSE) {
352 PKIX_ERROR(PKIX_EXTENDEDKEYUSAGECHECKINGFAILED);
357 cleanup:
359 PKIX_DECREF(state);
361 PKIX_RETURN(EKUCHECKER);
365 * FUNCTION: pkix_pl_EkuChecker_RegisterSelf
367 * DESCRIPTION:
368 * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
369 * functions with systemClasses[]
371 * THREAD SAFETY:
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
376 * thread-safe.
378 PKIX_Error *
379 pkix_pl_EkuChecker_RegisterSelf(void *plContext)
381 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
382 pkix_ClassTable_Entry entry;
384 PKIX_ENTER
385 (EKUCHECKER,
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)
407 PKIX_Error *
408 PKIX_PL_EkuChecker_Create(
409 PKIX_ProcessingParams *params,
410 void *plContext)
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
432 (critExtOIDsList,
433 (PKIX_PL_Object *)state->ekuOID,
434 plContext),
435 PKIX_LISTAPPENDITEMFAILED);
437 PKIX_CHECK(PKIX_CertChainChecker_Create
438 (pkix_pl_EkuChecker_Check,
439 PKIX_TRUE, /* forwardCheckingSupported */
440 PKIX_FALSE, /* forwardDirectionExpected */
441 critExtOIDsList,
442 (PKIX_PL_Object *) state,
443 &checker,
444 plContext),
445 PKIX_CERTCHAINCHECKERCREATEFAILED);
447 PKIX_CHECK(PKIX_ProcessingParams_AddCertChainChecker
448 (params, checker, plContext),
449 PKIX_PROCESSINGPARAMSADDCERTCHAINCHECKERFAILED);
451 cleanup:
453 PKIX_DECREF(critExtOIDsList);
454 PKIX_DECREF(checker);
455 PKIX_DECREF(state);
457 PKIX_RETURN(EKUCHECKER);