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);