mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
48
security/nss/lib/libpkix/pkix/checker/Makefile
Normal file
48
security/nss/lib/libpkix/pkix/checker/Makefile
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#! gmake
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
export:: private_export
|
||||
|
||||
35
security/nss/lib/libpkix/pkix/checker/checker.gyp
Normal file
35
security/nss/lib/libpkix/pkix/checker/checker.gyp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
{
|
||||
'includes': [
|
||||
'../../../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'pkixchecker',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'pkix_basicconstraintschecker.c',
|
||||
'pkix_certchainchecker.c',
|
||||
'pkix_crlchecker.c',
|
||||
'pkix_ekuchecker.c',
|
||||
'pkix_expirationchecker.c',
|
||||
'pkix_namechainingchecker.c',
|
||||
'pkix_nameconstraintschecker.c',
|
||||
'pkix_ocspchecker.c',
|
||||
'pkix_policychecker.c',
|
||||
'pkix_revocationchecker.c',
|
||||
'pkix_revocationmethod.c',
|
||||
'pkix_signaturechecker.c',
|
||||
'pkix_targetcertchecker.c'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
]
|
||||
}
|
||||
],
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
15
security/nss/lib/libpkix/pkix/checker/config.mk
Normal file
15
security/nss/lib/libpkix/pkix/checker/config.mk
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
37
security/nss/lib/libpkix/pkix/checker/exports.gyp
Normal file
37
security/nss/lib/libpkix/pkix/checker/exports.gyp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
{
|
||||
'includes': [
|
||||
'../../../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'lib_libpkix_pkix_checker_exports',
|
||||
'type': 'none',
|
||||
'copies': [
|
||||
{
|
||||
'files': [
|
||||
'pkix_basicconstraintschecker.h',
|
||||
'pkix_certchainchecker.h',
|
||||
'pkix_crlchecker.h',
|
||||
'pkix_ekuchecker.h',
|
||||
'pkix_expirationchecker.h',
|
||||
'pkix_namechainingchecker.h',
|
||||
'pkix_nameconstraintschecker.h',
|
||||
'pkix_ocspchecker.h',
|
||||
'pkix_policychecker.h',
|
||||
'pkix_revocationchecker.h',
|
||||
'pkix_revocationmethod.h',
|
||||
'pkix_signaturechecker.h',
|
||||
'pkix_targetcertchecker.h'
|
||||
],
|
||||
'destination': '<(nss_private_dist_dir)/<(module)'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
45
security/nss/lib/libpkix/pkix/checker/manifest.mn
Normal file
45
security/nss/lib/libpkix/pkix/checker/manifest.mn
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
CORE_DEPTH = ../../../..
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
pkix_basicconstraintschecker.h \
|
||||
pkix_certchainchecker.h \
|
||||
pkix_crlchecker.h \
|
||||
pkix_ekuchecker.h \
|
||||
pkix_expirationchecker.h \
|
||||
pkix_namechainingchecker.h \
|
||||
pkix_nameconstraintschecker.h \
|
||||
pkix_ocspchecker.h \
|
||||
pkix_policychecker.h \
|
||||
pkix_revocationmethod.h \
|
||||
pkix_revocationchecker.h \
|
||||
pkix_signaturechecker.h \
|
||||
pkix_targetcertchecker.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = nss
|
||||
|
||||
CSRCS = \
|
||||
pkix_basicconstraintschecker.c \
|
||||
pkix_certchainchecker.c \
|
||||
pkix_crlchecker.c \
|
||||
pkix_ekuchecker.c \
|
||||
pkix_expirationchecker.c \
|
||||
pkix_namechainingchecker.c \
|
||||
pkix_nameconstraintschecker.c \
|
||||
pkix_ocspchecker.c \
|
||||
pkix_revocationmethod.c \
|
||||
pkix_revocationchecker.c \
|
||||
pkix_policychecker.c \
|
||||
pkix_signaturechecker.c \
|
||||
pkix_targetcertchecker.c \
|
||||
$(NULL)
|
||||
|
||||
LIBRARY_NAME = pkixchecker
|
||||
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_basicconstraintschecker.c
|
||||
*
|
||||
* Functions for basic constraints validation
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_basicconstraintschecker.h"
|
||||
|
||||
/* --Private-BasicConstraintsCheckerState-Functions------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_BasicConstraintsCheckerState_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_BasicConstraintsCheckerState_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_BasicConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
|
||||
"pkix_BasicConstraintsCheckerState_Destroy");
|
||||
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a basic constraints checker state */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, plContext),
|
||||
PKIX_OBJECTNOTBASICCONSTRAINTSCHECKERSTATE);
|
||||
|
||||
state = (pkix_BasicConstraintsCheckerState *)object;
|
||||
|
||||
PKIX_DECREF(state->basicConstraintsOID);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_BasicConstraintsCheckerState_RegisterSelf
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
|
||||
"pkix_BasicConstraintsCheckerState_RegisterSelf");
|
||||
|
||||
entry.description = "BasicConstraintsCheckerState";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(pkix_BasicConstraintsCheckerState);
|
||||
entry.destructor = pkix_BasicConstraintsCheckerState_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = NULL;
|
||||
|
||||
systemClasses[PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_BasicConstraintsCheckerState_Create
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new BasicConstraintsCheckerState using the number of certs in
|
||||
* the chain represented by "certsRemaining" and stores it at "pState".
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "certsRemaining"
|
||||
* Number of certificates in the chain.
|
||||
* "pState"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a BasicConstraintsCheckerState Error if the function fails in a
|
||||
* non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_BasicConstraintsCheckerState_Create(
|
||||
PKIX_UInt32 certsRemaining,
|
||||
pkix_BasicConstraintsCheckerState **pState,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_BasicConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
|
||||
"pkix_BasicConstraintsCheckerState_Create");
|
||||
|
||||
PKIX_NULLCHECK_ONE(pState);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE,
|
||||
sizeof (pkix_BasicConstraintsCheckerState),
|
||||
(PKIX_PL_Object **)&state,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT);
|
||||
|
||||
/* initialize fields */
|
||||
state->certsRemaining = certsRemaining;
|
||||
state->maxPathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_BASICCONSTRAINTS_OID,
|
||||
&state->basicConstraintsOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
*pState = state;
|
||||
state = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/* --Private-BasicConstraintsChecker-Functions------------------------------ */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_BasicConstraintsChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_BasicConstraintsChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
|
||||
pkix_BasicConstraintsCheckerState *state = NULL;
|
||||
PKIX_Boolean caFlag = PKIX_FALSE;
|
||||
PKIX_Int32 pathLength = 0;
|
||||
PKIX_Int32 maxPathLength_now;
|
||||
PKIX_Boolean isSelfIssued = PKIX_FALSE;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&state, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
state->certsRemaining--;
|
||||
|
||||
if (state->certsRemaining != 0) {
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
|
||||
(cert, &basicConstraints, plContext),
|
||||
PKIX_CERTGETBASICCONSTRAINTSFAILED);
|
||||
|
||||
/* get CA Flag and path length */
|
||||
if (basicConstraints != NULL) {
|
||||
PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
|
||||
(basicConstraints,
|
||||
&caFlag,
|
||||
plContext),
|
||||
PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
|
||||
|
||||
if (caFlag == PKIX_TRUE) {
|
||||
PKIX_CHECK
|
||||
(PKIX_PL_BasicConstraints_GetPathLenConstraint
|
||||
(basicConstraints,
|
||||
&pathLength,
|
||||
plContext),
|
||||
PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
|
||||
}
|
||||
|
||||
}else{
|
||||
caFlag = PKIX_FALSE;
|
||||
pathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
|
||||
}
|
||||
|
||||
PKIX_CHECK(pkix_IsCertSelfIssued
|
||||
(cert,
|
||||
&isSelfIssued,
|
||||
plContext),
|
||||
PKIX_ISCERTSELFISSUEDFAILED);
|
||||
|
||||
maxPathLength_now = state->maxPathLength;
|
||||
|
||||
if (isSelfIssued != PKIX_TRUE) {
|
||||
|
||||
/* Not last CA Cert, but maxPathLength is down to zero */
|
||||
if (maxPathLength_now == 0) {
|
||||
PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDLN);
|
||||
}
|
||||
|
||||
if (caFlag == PKIX_FALSE) {
|
||||
PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDCA);
|
||||
}
|
||||
|
||||
if (maxPathLength_now > 0) { /* can be unlimited (-1) */
|
||||
maxPathLength_now--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (caFlag == PKIX_TRUE) {
|
||||
if (maxPathLength_now == PKIX_UNLIMITED_PATH_CONSTRAINT){
|
||||
maxPathLength_now = pathLength;
|
||||
} else {
|
||||
/* If pathLength is not specified, don't set */
|
||||
if (pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) {
|
||||
maxPathLength_now =
|
||||
(maxPathLength_now > pathLength)?
|
||||
pathLength:maxPathLength_now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state->maxPathLength = maxPathLength_now;
|
||||
}
|
||||
|
||||
/* Remove Basic Constraints Extension OID from list */
|
||||
if (unresolvedCriticalExtensions != NULL) {
|
||||
|
||||
PKIX_CHECK(pkix_List_Remove
|
||||
(unresolvedCriticalExtensions,
|
||||
(PKIX_PL_Object *) state->basicConstraintsOID,
|
||||
plContext),
|
||||
PKIX_LISTREMOVEFAILED);
|
||||
}
|
||||
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object *)state, plContext),
|
||||
PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(state);
|
||||
PKIX_DECREF(basicConstraints);
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_BasicConstraintsChecker_Initialize
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_BasicConstraintsChecker_Initialize(
|
||||
PKIX_UInt32 certsRemaining,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_BasicConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Initialize");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(pkix_BasicConstraintsCheckerState_Create
|
||||
(certsRemaining, &state, plContext),
|
||||
PKIX_BASICCONSTRAINTSCHECKERSTATECREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_BasicConstraintsChecker_Check,
|
||||
PKIX_FALSE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *)state,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCHECKFAILED);
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_basicconstraintschecker.h
|
||||
*
|
||||
* Header file for basic constraints checker.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_BASICCONSTRAINTSCHECKER_H
|
||||
#define _PKIX_BASICCONSTRAINTSCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pkix_BasicConstraintsCheckerStateStruct \
|
||||
pkix_BasicConstraintsCheckerState;
|
||||
|
||||
struct pkix_BasicConstraintsCheckerStateStruct{
|
||||
PKIX_PL_OID *basicConstraintsOID;
|
||||
PKIX_Int32 certsRemaining;
|
||||
PKIX_Int32 maxPathLength;
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_BasicConstraintsChecker_Initialize(
|
||||
PKIX_UInt32 numCerts,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_BASICCONSTRAINTSCHECKER_H */
|
||||
322
security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c
Normal file
322
security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_certchainchecker.c
|
||||
*
|
||||
* CertChainChecker Object Functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_certchainchecker.h"
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CertChainChecker_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_CertChainChecker_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_CertChainChecker *checker = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a cert chain checker */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_CERTCHAINCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTCERTCHAINCHECKER);
|
||||
|
||||
checker = (PKIX_CertChainChecker *)object;
|
||||
|
||||
PKIX_DECREF(checker->extensions);
|
||||
PKIX_DECREF(checker->state);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CertChainChecker_Duplicate
|
||||
* (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_CertChainChecker_Duplicate(
|
||||
PKIX_PL_Object *object,
|
||||
PKIX_PL_Object **pNewObject,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_CertChainChecker *checker = NULL;
|
||||
PKIX_CertChainChecker *checkerDuplicate = NULL;
|
||||
PKIX_List *extensionsDuplicate = NULL;
|
||||
PKIX_PL_Object *stateDuplicate = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_Duplicate");
|
||||
PKIX_NULLCHECK_TWO(object, pNewObject);
|
||||
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_CERTCHAINCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTCERTCHAINCHECKER);
|
||||
|
||||
checker = (PKIX_CertChainChecker *)object;
|
||||
|
||||
if (checker->extensions){
|
||||
PKIX_CHECK(PKIX_PL_Object_Duplicate
|
||||
((PKIX_PL_Object *)checker->extensions,
|
||||
(PKIX_PL_Object **)&extensionsDuplicate,
|
||||
plContext),
|
||||
PKIX_OBJECTDUPLICATEFAILED);
|
||||
}
|
||||
|
||||
if (checker->state){
|
||||
PKIX_CHECK(PKIX_PL_Object_Duplicate
|
||||
((PKIX_PL_Object *)checker->state,
|
||||
(PKIX_PL_Object **)&stateDuplicate,
|
||||
plContext),
|
||||
PKIX_OBJECTDUPLICATEFAILED);
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(checker->checkCallback,
|
||||
checker->forwardChecking,
|
||||
checker->isForwardDirectionExpected,
|
||||
extensionsDuplicate,
|
||||
stateDuplicate,
|
||||
&checkerDuplicate,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
*pNewObject = (PKIX_PL_Object *)checkerDuplicate;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(extensionsDuplicate);
|
||||
PKIX_DECREF(stateDuplicate);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CertChainChecker_RegisterSelf
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_CERTCHAINCHECKER_TYPE and its related functions with
|
||||
* systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_CertChainChecker_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_RegisterSelf");
|
||||
|
||||
entry.description = "CertChainChecker";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(PKIX_CertChainChecker);
|
||||
entry.destructor = pkix_CertChainChecker_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = pkix_CertChainChecker_Duplicate;
|
||||
|
||||
systemClasses[PKIX_CERTCHAINCHECKER_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/* --Public-Functions--------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_Create (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_Create(
|
||||
PKIX_CertChainChecker_CheckCallback callback,
|
||||
PKIX_Boolean forwardCheckingSupported,
|
||||
PKIX_Boolean isForwardDirectionExpected,
|
||||
PKIX_List *list, /* list of PKIX_PL_OID */
|
||||
PKIX_PL_Object *initialState,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_CertChainChecker *checker = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CertChainChecker_Create");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_CERTCHAINCHECKER_TYPE,
|
||||
sizeof (PKIX_CertChainChecker),
|
||||
(PKIX_PL_Object **)&checker,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
|
||||
|
||||
/* initialize fields */
|
||||
checker->checkCallback = callback;
|
||||
checker->forwardChecking = forwardCheckingSupported;
|
||||
checker->isForwardDirectionExpected = isForwardDirectionExpected;
|
||||
|
||||
PKIX_INCREF(list);
|
||||
checker->extensions = list;
|
||||
|
||||
PKIX_INCREF(initialState);
|
||||
checker->state = initialState;
|
||||
|
||||
*pChecker = checker;
|
||||
checker = NULL;
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(checker);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_GetCheckCallback
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_GetCheckCallback(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_CertChainChecker_CheckCallback *pCallback,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CertChainChecker_GetCheckCallback");
|
||||
PKIX_NULLCHECK_TWO(checker, pCallback);
|
||||
|
||||
*pCallback = checker->checkCallback;
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_IsForwardCheckingSupported
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_IsForwardCheckingSupported(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_Boolean *pForwardCheckingSupported,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER
|
||||
(CERTCHAINCHECKER,
|
||||
"PKIX_CertChainChecker_IsForwardCheckingSupported");
|
||||
PKIX_NULLCHECK_TWO(checker, pForwardCheckingSupported);
|
||||
|
||||
*pForwardCheckingSupported = checker->forwardChecking;
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_IsForwardDirectionExpected
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_IsForwardDirectionExpected(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_Boolean *pForwardDirectionExpected,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER
|
||||
(CERTCHAINCHECKER,
|
||||
"PKIX_CertChainChecker_IsForwardDirectionExpected");
|
||||
PKIX_NULLCHECK_TWO(checker, pForwardDirectionExpected);
|
||||
|
||||
*pForwardDirectionExpected = checker->isForwardDirectionExpected;
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_GetCertChainCheckerState(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Object **pCertChainCheckerState,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(CERTCHAINCHECKER,
|
||||
"PKIX_CertChainChecker_GetCertChainCheckerState");
|
||||
|
||||
PKIX_NULLCHECK_TWO(checker, pCertChainCheckerState);
|
||||
|
||||
PKIX_INCREF(checker->state);
|
||||
|
||||
*pCertChainCheckerState = checker->state;
|
||||
|
||||
cleanup:
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_SetCertChainCheckerState
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_SetCertChainCheckerState(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Object *certChainCheckerState,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(CERTCHAINCHECKER,
|
||||
"PKIX_CertChainChecker_SetCertChainCheckerState");
|
||||
|
||||
PKIX_NULLCHECK_ONE(checker);
|
||||
|
||||
/* DecRef old contents */
|
||||
PKIX_DECREF(checker->state);
|
||||
|
||||
PKIX_INCREF(certChainCheckerState);
|
||||
checker->state = certChainCheckerState;
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_InvalidateCache
|
||||
((PKIX_PL_Object *)checker, plContext),
|
||||
PKIX_OBJECTINVALIDATECACHEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_CertChainChecker_GetSupportedExtensions
|
||||
* (see comments in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_CertChainChecker_GetSupportedExtensions(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_List **pExtensions, /* list of PKIX_PL_OID */
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(CERTCHAINCHECKER,
|
||||
"PKIX_CertChainChecker_GetSupportedExtensions");
|
||||
|
||||
PKIX_NULLCHECK_TWO(checker, pExtensions);
|
||||
|
||||
PKIX_INCREF(checker->extensions);
|
||||
|
||||
*pExtensions = checker->extensions;
|
||||
|
||||
cleanup:
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_certchainchecker.h
|
||||
*
|
||||
* CertChainChecker Object Type Definition
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_CERTCHAINCHECKER_H
|
||||
#define _PKIX_CERTCHAINCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct PKIX_CertChainCheckerStruct {
|
||||
PKIX_CertChainChecker_CheckCallback checkCallback;
|
||||
PKIX_List *extensions;
|
||||
PKIX_PL_Object *state;
|
||||
PKIX_Boolean forwardChecking;
|
||||
PKIX_Boolean isForwardDirectionExpected;
|
||||
};
|
||||
|
||||
/* see source file for function documentation */
|
||||
|
||||
PKIX_Error *pkix_CertChainChecker_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_CERTCHAINCHECKER_H */
|
||||
438
security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c
Normal file
438
security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_defaultcrlchecker.c
|
||||
*
|
||||
* Functions for default CRL Checkers
|
||||
*
|
||||
*/
|
||||
#include "pkix.h"
|
||||
#include "pkix_crlchecker.h"
|
||||
#include "pkix_tools.h"
|
||||
|
||||
/* --Private-CRLChecker-Data-and-Types------------------------------- */
|
||||
|
||||
typedef struct pkix_CrlCheckerStruct {
|
||||
/* RevocationMethod is the super class of CrlChecker. */
|
||||
pkix_RevocationMethod method;
|
||||
PKIX_List *certStores; /* list of CertStore */
|
||||
PKIX_PL_VerifyCallback crlVerifyFn;
|
||||
} pkix_CrlChecker;
|
||||
|
||||
|
||||
/* --Private-CRLChecker-Functions----------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CrlCheckerstate_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_CrlChecker_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_CrlChecker *state = NULL;
|
||||
|
||||
PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a default CRL checker state */
|
||||
PKIX_CHECK(
|
||||
pkix_CheckType(object, PKIX_CRLCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTCRLCHECKER);
|
||||
|
||||
state = (pkix_CrlChecker *)object;
|
||||
|
||||
PKIX_DECREF(state->certStores);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(CRLCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CrlChecker_RegisterSelf
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_CRLCHECKER_TYPE and its related functions
|
||||
* with systemClasses[]
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry* entry = &systemClasses[PKIX_CRLCHECKER_TYPE];
|
||||
|
||||
PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_RegisterSelf");
|
||||
|
||||
entry->description = "CRLChecker";
|
||||
entry->typeObjectSize = sizeof(pkix_CrlChecker);
|
||||
entry->destructor = pkix_CrlChecker_Destroy;
|
||||
|
||||
PKIX_RETURN(CRLCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CrlChecker_Create
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Allocate and initialize CRLChecker state data.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "certStores"
|
||||
* Address of CertStore List to be stored in state. Must be non-NULL.
|
||||
* "testDate"
|
||||
* Address of PKIX_PL_Date to be checked. May be NULL.
|
||||
* "trustedPubKey"
|
||||
* Trusted Anchor Public Key for verifying first Cert in the chain.
|
||||
* Must be non-NULL.
|
||||
* "certsRemaining"
|
||||
* Number of certificates remaining in the chain.
|
||||
* "nistCRLPolicyEnabled"
|
||||
* If enabled, enforce nist crl policy.
|
||||
* "pChecker"
|
||||
* Address of CRLChecker that is returned. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a DefaultCrlChecker Error if the function fails in a
|
||||
* non-fatal way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_Create(PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
PKIX_List *certStores,
|
||||
PKIX_PL_VerifyCallback crlVerifyFn,
|
||||
pkix_RevocationMethod **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_CrlChecker *crlChecker = NULL;
|
||||
|
||||
PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_Create");
|
||||
PKIX_NULLCHECK_TWO(certStores, pChecker);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_CRLCHECKER_TYPE,
|
||||
sizeof (pkix_CrlChecker),
|
||||
(PKIX_PL_Object **)&crlChecker,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATECRLCHECKEROBJECT);
|
||||
|
||||
pkixErrorResult = pkix_RevocationMethod_Init(
|
||||
(pkix_RevocationMethod*)crlChecker, methodType, flags, priority,
|
||||
localRevChecker, externalRevChecker, plContext);
|
||||
if (pkixErrorResult) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Initialize fields */
|
||||
PKIX_INCREF(certStores);
|
||||
crlChecker->certStores = certStores;
|
||||
|
||||
crlChecker->crlVerifyFn = crlVerifyFn;
|
||||
*pChecker = (pkix_RevocationMethod*)crlChecker;
|
||||
crlChecker = NULL;
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(crlChecker);
|
||||
|
||||
PKIX_RETURN(CRLCHECKER);
|
||||
}
|
||||
|
||||
/* --Private-CRLChecker-Functions------------------------------------ */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CrlChecker_CheckLocal
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Check if the Cert has been revoked based the CRLs data. This function
|
||||
* maintains the checker state to be current.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "checker"
|
||||
* Address of CertChainChecker which has the state data.
|
||||
* Must be non-NULL.
|
||||
* "cert"
|
||||
* Address of Certificate that is to be validated. Must be non-NULL.
|
||||
* "unreslvdCrtExts"
|
||||
* A List OIDs. Not **yet** used in this checker function.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe
|
||||
* (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_CheckLocal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *pReasonCode,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_CertStore_CheckRevokationByCrlCallback storeCheckRevocationFn;
|
||||
PKIX_CertStore *certStore = NULL;
|
||||
pkix_CrlChecker *state = NULL;
|
||||
PKIX_UInt32 crlStoreIndex = 0;
|
||||
PKIX_UInt32 numCrlStores = 0;
|
||||
PKIX_Boolean storeIsLocal = PKIX_FALSE;
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_CrlChecker_CheckLocal");
|
||||
PKIX_NULLCHECK_FOUR(cert, issuer, checkerObject, checkerObject);
|
||||
|
||||
state = (pkix_CrlChecker*)checkerObject;
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetLength(state->certStores, &numCrlStores, plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
|
||||
for (;crlStoreIndex < numCrlStores;crlStoreIndex++) {
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(state->certStores, crlStoreIndex,
|
||||
(PKIX_PL_Object **)&certStore,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetLocalFlag(certStore, &storeIsLocal,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETLOCALFLAGFAILED);
|
||||
if (storeIsLocal) {
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetCrlCheckerFn(certStore,
|
||||
&storeCheckRevocationFn,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
|
||||
|
||||
if (storeCheckRevocationFn) {
|
||||
PKIX_CHECK(
|
||||
(*storeCheckRevocationFn)(certStore, cert, issuer,
|
||||
/* delay sig check if building
|
||||
* a chain by not specifying the time*/
|
||||
chainVerificationState ? date : NULL,
|
||||
/* crl downloading is not done. */
|
||||
PKIX_FALSE,
|
||||
pReasonCode, &revStatus, plContext),
|
||||
PKIX_CERTSTORECRLCHECKFAILED);
|
||||
if (revStatus == PKIX_RevStatus_Revoked) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PKIX_DECREF(certStore);
|
||||
} /* while */
|
||||
|
||||
cleanup:
|
||||
*pRevStatus = revStatus;
|
||||
PKIX_DECREF(certStore);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_CrlChecker_CheckRemote
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Check if the Cert has been revoked based the CRLs data. This function
|
||||
* maintains the checker state to be current.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "checker"
|
||||
* Address of CertChainChecker which has the state data.
|
||||
* Must be non-NULL.
|
||||
* "cert"
|
||||
* Address of Certificate that is to be validated. Must be non-NULL.
|
||||
* "unreslvdCrtExts"
|
||||
* A List OIDs. Not **yet** used in this checker function.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe
|
||||
* (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_CheckExternal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *pReasonCode,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_CertStore_CheckRevokationByCrlCallback storeCheckRevocationFn = NULL;
|
||||
PKIX_CertStore_ImportCrlCallback storeImportCrlFn = NULL;
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
PKIX_CertStore *certStore = NULL;
|
||||
PKIX_CertStore *localStore = NULL;
|
||||
PKIX_CRLSelector *crlSelector = NULL;
|
||||
PKIX_PL_X500Name *issuerName = NULL;
|
||||
pkix_CrlChecker *state = NULL;
|
||||
PKIX_UInt32 crlStoreIndex = 0;
|
||||
PKIX_UInt32 numCrlStores = 0;
|
||||
PKIX_Boolean storeIsLocal = PKIX_FALSE;
|
||||
PKIX_List *crlList = NULL;
|
||||
PKIX_List *dpList = NULL;
|
||||
void *nbioContext = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_CrlChecker_CheckExternal");
|
||||
PKIX_NULLCHECK_FOUR(cert, issuer, checkerObject, pNBIOContext);
|
||||
|
||||
nbioContext = *pNBIOContext;
|
||||
*pNBIOContext = NULL; /* prepare for Error exit */
|
||||
|
||||
state = (pkix_CrlChecker*)checkerObject;
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetLength(state->certStores, &numCrlStores, plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
|
||||
/* Find a cert store that is capable of storing crls */
|
||||
for (;crlStoreIndex < numCrlStores;crlStoreIndex++) {
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(state->certStores, crlStoreIndex,
|
||||
(PKIX_PL_Object **)&certStore,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetLocalFlag(certStore, &storeIsLocal,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETLOCALFLAGFAILED);
|
||||
if (storeIsLocal) {
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetImportCrlCallback(certStore,
|
||||
&storeImportCrlFn,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetCrlCheckerFn(certStore,
|
||||
&storeCheckRevocationFn,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
|
||||
|
||||
if (storeImportCrlFn && storeCheckRevocationFn) {
|
||||
localStore = certStore;
|
||||
certStore = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PKIX_DECREF(certStore);
|
||||
} /* while */
|
||||
|
||||
/* Report unknown status if we can not check crl in one of the
|
||||
* local stores. */
|
||||
if (!localStore) {
|
||||
PKIX_ERROR_FATAL(PKIX_CRLCHECKERNOLOCALCERTSTOREFOUND);
|
||||
}
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_VerifyKeyUsage(issuer, PKIX_CRL_SIGN, plContext),
|
||||
PKIX_CERTCHECKKEYUSAGEFAILED);
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_GetCrlDp(cert, &dpList, plContext),
|
||||
PKIX_CERTGETCRLDPFAILED);
|
||||
if (!(methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
|
||||
(!dpList || !dpList->length)) {
|
||||
goto cleanup;
|
||||
}
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_GetIssuer(cert, &issuerName, plContext),
|
||||
PKIX_CERTGETISSUERFAILED);
|
||||
PKIX_CHECK(
|
||||
PKIX_CRLSelector_Create(issuer, dpList, date, &crlSelector, plContext),
|
||||
PKIX_CRLCHECKERSETSELECTORFAILED);
|
||||
/* Fetch crl and store in a local cert store */
|
||||
for (crlStoreIndex = 0;crlStoreIndex < numCrlStores;crlStoreIndex++) {
|
||||
PKIX_CertStore_CRLCallback getCrlsFn;
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(state->certStores, crlStoreIndex,
|
||||
(PKIX_PL_Object **)&certStore,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_CertStore_GetCRLCallback(certStore, &getCrlsFn,
|
||||
plContext),
|
||||
PKIX_CERTSTOREGETCRLCALLBACKFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
(*getCrlsFn)(certStore, crlSelector, &nbioContext,
|
||||
&crlList, plContext),
|
||||
PKIX_GETCRLSFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
(*storeImportCrlFn)(localStore, issuerName, crlList, plContext),
|
||||
PKIX_CERTSTOREFAILTOIMPORTCRLLIST);
|
||||
|
||||
PKIX_CHECK(
|
||||
(*storeCheckRevocationFn)(certStore, cert, issuer, date,
|
||||
/* done with crl downloading */
|
||||
PKIX_TRUE,
|
||||
pReasonCode, &revStatus, plContext),
|
||||
PKIX_CERTSTORECRLCHECKFAILED);
|
||||
if (revStatus != PKIX_RevStatus_NoInfo) {
|
||||
break;
|
||||
}
|
||||
PKIX_DECREF(crlList);
|
||||
PKIX_DECREF(certStore);
|
||||
} /* while */
|
||||
|
||||
cleanup:
|
||||
/* Update return flags */
|
||||
if (revStatus == PKIX_RevStatus_NoInfo &&
|
||||
((dpList && dpList->length > 0) ||
|
||||
(methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE)) &&
|
||||
methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
|
||||
revStatus = PKIX_RevStatus_Revoked;
|
||||
}
|
||||
*pRevStatus = revStatus;
|
||||
|
||||
PKIX_DECREF(dpList);
|
||||
PKIX_DECREF(crlList);
|
||||
PKIX_DECREF(certStore);
|
||||
PKIX_DECREF(issuerName);
|
||||
PKIX_DECREF(localStore);
|
||||
PKIX_DECREF(crlSelector);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
68
security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h
Normal file
68
security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_defaultcrlchecker.h
|
||||
*
|
||||
* Header file for default CRL function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_CRLCHECKER_H
|
||||
#define _PKIX_CRLCHECKER_H
|
||||
|
||||
#include "pkixt.h"
|
||||
#include "pkix_revocationmethod.h"
|
||||
#include "pkix_crlsel.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NOTE: nbio logic removed. Will be replaced later. */
|
||||
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_CheckLocal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_CheckExternal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void **pNBIOContext,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_Create(PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
PKIX_List *certStores,
|
||||
PKIX_PL_VerifyCallback crlVerifyFn,
|
||||
pkix_RevocationMethod **pChecker,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_CrlChecker_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_CRLCHECKER_H */
|
||||
328
security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c
Normal file
328
security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_ekuchecker.c
|
||||
*
|
||||
* User Defined ExtenedKeyUsage Function Definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_ekuchecker.h"
|
||||
|
||||
SECOidTag ekuOidStrings[] = {
|
||||
PKIX_KEY_USAGE_SERVER_AUTH_OID,
|
||||
PKIX_KEY_USAGE_CLIENT_AUTH_OID,
|
||||
PKIX_KEY_USAGE_CODE_SIGN_OID,
|
||||
PKIX_KEY_USAGE_EMAIL_PROTECT_OID,
|
||||
PKIX_KEY_USAGE_TIME_STAMP_OID,
|
||||
PKIX_KEY_USAGE_OCSP_RESPONDER_OID,
|
||||
PKIX_UNKNOWN_OID
|
||||
};
|
||||
|
||||
typedef struct pkix_EkuCheckerStruct {
|
||||
PKIX_List *requiredExtKeyUsageOids;
|
||||
PKIX_PL_OID *ekuOID;
|
||||
} pkix_EkuChecker;
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_EkuChecker_Destroy
|
||||
* (see comments for PKIX_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_EkuChecker_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_EkuChecker *ekuCheckerState = NULL;
|
||||
|
||||
PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
PKIX_CHECK(pkix_CheckType(object, PKIX_EKUCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTANEKUCHECKERSTATE);
|
||||
|
||||
ekuCheckerState = (pkix_EkuChecker *)object;
|
||||
|
||||
PKIX_DECREF(ekuCheckerState->ekuOID);
|
||||
PKIX_DECREF(ekuCheckerState->requiredExtKeyUsageOids);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(EKUCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_EkuChecker_RegisterSelf
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
|
||||
* functions with systemClasses[]
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_EkuChecker_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry *entry = &systemClasses[PKIX_EKUCHECKER_TYPE];
|
||||
|
||||
PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_RegisterSelf");
|
||||
|
||||
entry->description = "EkuChecker";
|
||||
entry->typeObjectSize = sizeof(pkix_EkuChecker);
|
||||
entry->destructor = pkix_EkuChecker_Destroy;
|
||||
|
||||
PKIX_RETURN(EKUCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_EkuChecker_Create
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new Extend Key Usage CheckerState using "params" to retrieve
|
||||
* application specified EKU for verification and stores it at "pState".
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "params"
|
||||
* a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
|
||||
* Extended Key Usage OIDs specified by application can be retrieved for
|
||||
* verification.
|
||||
* "pState"
|
||||
* Address where state pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a UserDefinedModules Error if the function fails in a
|
||||
* non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_EkuChecker_Create(
|
||||
PKIX_ProcessingParams *params,
|
||||
pkix_EkuChecker **pState,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_EkuChecker *state = NULL;
|
||||
PKIX_CertSelector *certSelector = NULL;
|
||||
PKIX_ComCertSelParams *comCertSelParams = NULL;
|
||||
PKIX_List *requiredOids = NULL;
|
||||
|
||||
PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Create");
|
||||
PKIX_NULLCHECK_TWO(params, pState);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_EKUCHECKER_TYPE,
|
||||
sizeof (pkix_EkuChecker),
|
||||
(PKIX_PL_Object **)&state,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT);
|
||||
|
||||
|
||||
PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
|
||||
(params, &certSelector, plContext),
|
||||
PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
|
||||
|
||||
if (certSelector != NULL) {
|
||||
|
||||
/* Get initial EKU OIDs from ComCertSelParams, if set */
|
||||
PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
|
||||
(certSelector, &comCertSelParams, plContext),
|
||||
PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
|
||||
|
||||
if (comCertSelParams != NULL) {
|
||||
PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
|
||||
(comCertSelParams, &requiredOids, plContext),
|
||||
PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_EXTENDEDKEYUSAGE_OID,
|
||||
&state->ekuOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
state->requiredExtKeyUsageOids = requiredOids;
|
||||
requiredOids = NULL;
|
||||
*pState = state;
|
||||
state = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(certSelector);
|
||||
PKIX_DECREF(comCertSelParams);
|
||||
PKIX_DECREF(requiredOids);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(EKUCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_EkuChecker_Check
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function determines the Extended Key Usage OIDs specified by the
|
||||
* application is included in the Extended Key Usage OIDs of this "cert".
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "checker"
|
||||
* Address of CertChainChecker which has the state data.
|
||||
* Must be non-NULL.
|
||||
* "cert"
|
||||
* Address of Certificate that is to be validated. Must be non-NULL.
|
||||
* "unresolvedCriticalExtensions"
|
||||
* A List OIDs. The OID for Extended Key Usage is removed.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a UserDefinedModules Error if the function fails in
|
||||
* a non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_EkuChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_EkuChecker *state = NULL;
|
||||
PKIX_List *requiredExtKeyUsageList = NULL;
|
||||
PKIX_List *certExtKeyUsageList = NULL;
|
||||
PKIX_PL_OID *ekuOid = NULL;
|
||||
PKIX_Boolean isContained = PKIX_FALSE;
|
||||
PKIX_UInt32 numItems = 0;
|
||||
PKIX_UInt32 i;
|
||||
PKIX_Boolean checkResult = PKIX_TRUE;
|
||||
|
||||
PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* no non-blocking IO */
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&state, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
requiredExtKeyUsageList = state->requiredExtKeyUsageOids;
|
||||
if (requiredExtKeyUsageList == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetLength(requiredExtKeyUsageList, &numItems,
|
||||
plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
if (numItems == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Cert_GetExtendedKeyUsage(cert, &certExtKeyUsageList,
|
||||
plContext),
|
||||
PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
|
||||
|
||||
if (certExtKeyUsageList == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < numItems; i++) {
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(requiredExtKeyUsageList, i,
|
||||
(PKIX_PL_Object **)&ekuOid, plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(
|
||||
pkix_List_Contains(certExtKeyUsageList,
|
||||
(PKIX_PL_Object *)ekuOid,
|
||||
&isContained,
|
||||
plContext),
|
||||
PKIX_LISTCONTAINSFAILED);
|
||||
|
||||
PKIX_DECREF(ekuOid);
|
||||
if (isContained != PKIX_TRUE) {
|
||||
checkResult = PKIX_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (!pkixErrorResult && checkResult == PKIX_FALSE) {
|
||||
pkixErrorReceived = PKIX_TRUE;
|
||||
pkixErrorCode = PKIX_EXTENDEDKEYUSAGECHECKINGFAILED;
|
||||
}
|
||||
|
||||
PKIX_DECREF(ekuOid);
|
||||
PKIX_DECREF(certExtKeyUsageList);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(EKUCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_EkuChecker_Initialize
|
||||
* (see comments in pkix_sample_modules.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_EkuChecker_Create(
|
||||
PKIX_ProcessingParams *params,
|
||||
PKIX_CertChainChecker **pEkuChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_EkuChecker *state = NULL;
|
||||
PKIX_List *critExtOIDsList = NULL;
|
||||
|
||||
PKIX_ENTER(EKUCHECKER, "PKIX_EkuChecker_Initialize");
|
||||
PKIX_NULLCHECK_ONE(params);
|
||||
|
||||
/*
|
||||
* This function and functions in this file provide an example of how
|
||||
* an application defined checker can be hooked into libpkix.
|
||||
*/
|
||||
|
||||
PKIX_CHECK(pkix_EkuChecker_Create
|
||||
(params, &state, plContext),
|
||||
PKIX_EKUCHECKERSTATECREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_List_Create(&critExtOIDsList, plContext),
|
||||
PKIX_LISTCREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_List_AppendItem
|
||||
(critExtOIDsList,
|
||||
(PKIX_PL_Object *)state->ekuOID,
|
||||
plContext),
|
||||
PKIX_LISTAPPENDITEMFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_EkuChecker_Check,
|
||||
PKIX_TRUE, /* forwardCheckingSupported */
|
||||
PKIX_FALSE, /* forwardDirectionExpected */
|
||||
critExtOIDsList,
|
||||
(PKIX_PL_Object *) state,
|
||||
pEkuChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(critExtOIDsList);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(EKUCHECKER);
|
||||
}
|
||||
92
security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h
Normal file
92
security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_ekuchecker.h
|
||||
*
|
||||
* User Defined Object Type Extended Key Usage Definition
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_EKUCHECKER_H
|
||||
#define _PKIX_EKUCHECKER_H
|
||||
|
||||
#include "pkix_pl_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_PL_EkuChecker_Create
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Create a CertChainChecker with EkuCheckerState and add it into
|
||||
* PKIX_ProcessingParams object.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "params"
|
||||
* a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
|
||||
* Extended Key Usage OIDs specified by application can be retrieved for
|
||||
* verification.
|
||||
* "ekuChecker"
|
||||
* Address of created ekuchecker.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a UserDefinedModules Error if the function fails in a non-fatal
|
||||
* way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_EkuChecker_Create(
|
||||
PKIX_ProcessingParams *params,
|
||||
PKIX_CertChainChecker **ekuChecker,
|
||||
void *plContext);
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_PL_EkuChecker_GetRequiredEku
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* This function retrieves application specified ExtenedKeyUsage(s) from
|
||||
* ComCertSetparams and converts its OID representations to SECCertUsageEnum.
|
||||
* The result is stored and returned in bit mask at "pRequiredExtKeyUsage".
|
||||
*
|
||||
* PARAMETERS
|
||||
* "certSelector"
|
||||
* a PKIX_CertSelector links to PKIX_ComCertSelParams where a list of
|
||||
* Extended Key Usage OIDs specified by application can be retrieved for
|
||||
* verification. Must be non-NULL.
|
||||
* "pRequiredExtKeyUsage"
|
||||
* Address where the result is returned. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a UserDefinedModules Error if the function fails in a non-fatal
|
||||
* way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_EkuChecker_GetRequiredEku(
|
||||
PKIX_CertSelector *certSelector,
|
||||
PKIX_UInt32 *pRequiredExtKeyUsage,
|
||||
void *plContext);
|
||||
|
||||
/* see source file for function documentation */
|
||||
PKIX_Error *pkix_EkuChecker_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_PL_EKUCHECKER_H */
|
||||
113
security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c
Normal file
113
security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_expirationchecker.c
|
||||
*
|
||||
* Functions for expiration validation
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "pkix_expirationchecker.h"
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_ExpirationChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_ExpirationChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_PL_Date *testDate = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_ExpirationChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&testDate, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_CheckValidity(cert, testDate, plContext),
|
||||
PKIX_CERTCHECKVALIDITYFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(testDate);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_ExpirationChecker_Initialize
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new CertChainChecker and stores it at "pChecker", where it will
|
||||
* used by pkix_ExpirationChecker_Check to check that the certificate has not
|
||||
* expired with respect to the Date pointed to by "testDate." If "testDate"
|
||||
* is NULL, then the CertChainChecker will check that a certificate has not
|
||||
* expired with respect to the current date and time.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "testDate"
|
||||
* Address of Date representing the point in time at which the cert is to
|
||||
* be validated. If "testDate" is NULL, the current date and time is used.
|
||||
* "pChecker"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_ExpirationChecker_Initialize(
|
||||
PKIX_PL_Date *testDate,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_PL_Date *myDate = NULL;
|
||||
PKIX_PL_Date *nowDate = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_ExpirationChecker_Initialize");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
/* if testDate is NULL, we use the current time */
|
||||
if (!testDate){
|
||||
PKIX_CHECK(PKIX_PL_Date_Create_UTCTime
|
||||
(NULL, &nowDate, plContext),
|
||||
PKIX_DATECREATEUTCTIMEFAILED);
|
||||
myDate = nowDate;
|
||||
} else {
|
||||
myDate = testDate;
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_ExpirationChecker_Check,
|
||||
PKIX_TRUE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *)myDate,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(nowDate);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_expirationchecker.h
|
||||
*
|
||||
* Header file for validate expiration function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_EXPIRATIONCHECKER_H
|
||||
#define _PKIX_EXPIRATIONCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PKIX_Error *
|
||||
pkix_ExpirationChecker_Initialize(
|
||||
PKIX_PL_Date *testDate,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_EXPIRATIONCHECKER_H */
|
||||
121
security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c
Normal file
121
security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_namechainingchecker.c
|
||||
*
|
||||
* Functions for name chaining validation
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "pkix_namechainingchecker.h"
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameChainingChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_NameChainingChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_PL_X500Name *prevSubject = NULL;
|
||||
PKIX_PL_X500Name *currIssuer = NULL;
|
||||
PKIX_PL_X500Name *currSubject = NULL;
|
||||
PKIX_Boolean result;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameChainingChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&prevSubject, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetIssuer(cert, &currIssuer, plContext),
|
||||
PKIX_CERTGETISSUERFAILED);
|
||||
|
||||
if (prevSubject){
|
||||
PKIX_CHECK(PKIX_PL_X500Name_Match
|
||||
(prevSubject, currIssuer, &result, plContext),
|
||||
PKIX_X500NAMEMATCHFAILED);
|
||||
if (!result){
|
||||
PKIX_ERROR(PKIX_NAMECHAININGCHECKFAILED);
|
||||
}
|
||||
} else {
|
||||
PKIX_ERROR(PKIX_NAMECHAININGCHECKFAILED);
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &currSubject, plContext),
|
||||
PKIX_CERTGETSUBJECTFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object *)currSubject, plContext),
|
||||
PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(prevSubject);
|
||||
PKIX_DECREF(currIssuer);
|
||||
PKIX_DECREF(currSubject);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameChainingChecker_Initialize
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new CertChainChecker and stores it at "pChecker", where it will
|
||||
* be used by pkix_NameChainingChecker_Check to check that the issuer name
|
||||
* of the certificate matches the subject name in the checker's state. The
|
||||
* X500Name pointed to by "trustedCAName" is used to initialize the checker's
|
||||
* state.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "trustedCAName"
|
||||
* Address of X500Name representing the trusted CA Name used to
|
||||
* initialize the state of this checker. Must be non-NULL.
|
||||
* "pChecker"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_NameChainingChecker_Initialize(
|
||||
PKIX_PL_X500Name *trustedCAName,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "PKIX_NameChainingChecker_Initialize");
|
||||
PKIX_NULLCHECK_TWO(pChecker, trustedCAName);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_NameChainingChecker_Check,
|
||||
PKIX_FALSE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *)trustedCAName,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_namechainingchecker.h
|
||||
*
|
||||
* Header file for name chaining checker.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_NAMECHAININGCHECKER_H
|
||||
#define _PKIX_NAMECHAININGCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PKIX_Error *
|
||||
pkix_NameChainingChecker_Initialize(
|
||||
PKIX_PL_X500Name *trustedCAName,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_NAMECHAININGCHECKER_H */
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_nameconstraintschecker.c
|
||||
*
|
||||
* Functions for Name Constraints Checkers
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_nameconstraintschecker.h"
|
||||
|
||||
/* --Private-NameConstraintsCheckerState-Functions---------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameConstraintsCheckerstate_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_NameConstraintsCheckerState_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_NameConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
|
||||
"pkix_NameConstraintsCheckerState_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that object type */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, plContext),
|
||||
PKIX_OBJECTNOTNAMECONSTRAINTSCHECKERSTATE);
|
||||
|
||||
state = (pkix_NameConstraintsCheckerState *)object;
|
||||
|
||||
PKIX_DECREF(state->nameConstraints);
|
||||
PKIX_DECREF(state->nameConstraintsOID);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameConstraintsCheckerState_RegisterSelf
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE and its related
|
||||
* functions with systemClasses[]
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
|
||||
"pkix_NameConstraintsCheckerState_RegisterSelf");
|
||||
|
||||
entry.description = "NameConstraintsCheckerState";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(pkix_NameConstraintsCheckerState);
|
||||
entry.destructor = pkix_NameConstraintsCheckerState_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = NULL;
|
||||
|
||||
systemClasses[PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameConstraintsCheckerState_Create
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Allocate and initialize NameConstraintsChecker state data.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "nameConstraints"
|
||||
* Address of NameConstraints to be stored in state. May be NULL.
|
||||
* "numCerts"
|
||||
* Number of certificates in the validation chain. This data is used
|
||||
* to identify end-entity.
|
||||
* "pCheckerState"
|
||||
* Address of NameConstraintsCheckerState that is returned. Must be
|
||||
* non-NULL.
|
||||
* "plContext" - Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in
|
||||
* a non-fatal way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_NameConstraintsCheckerState_Create(
|
||||
PKIX_PL_CertNameConstraints *nameConstraints,
|
||||
PKIX_UInt32 numCerts,
|
||||
pkix_NameConstraintsCheckerState **pCheckerState,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_NameConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
|
||||
"pkix_NameConstraintsCheckerState_Create");
|
||||
PKIX_NULLCHECK_ONE(pCheckerState);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE,
|
||||
sizeof (pkix_NameConstraintsCheckerState),
|
||||
(PKIX_PL_Object **)&state,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT);
|
||||
|
||||
/* Initialize fields */
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_NAMECONSTRAINTS_OID,
|
||||
&state->nameConstraintsOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
PKIX_INCREF(nameConstraints);
|
||||
|
||||
state->nameConstraints = nameConstraints;
|
||||
state->certsRemaining = numCerts;
|
||||
|
||||
*pCheckerState = state;
|
||||
state = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
|
||||
}
|
||||
|
||||
/* --Private-NameConstraintsChecker-Functions------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameConstraintsChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_NameConstraintsChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_NameConstraintsCheckerState *state = NULL;
|
||||
PKIX_PL_CertNameConstraints *nameConstraints = NULL;
|
||||
PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL;
|
||||
PKIX_Boolean selfIssued = PKIX_FALSE;
|
||||
PKIX_Boolean lastCert = PKIX_FALSE;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&state, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
state->certsRemaining--;
|
||||
lastCert = state->certsRemaining == 0;
|
||||
|
||||
/* Get status of self issued */
|
||||
PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
|
||||
PKIX_ISCERTSELFISSUEDFAILED);
|
||||
|
||||
/* Check on non self-issued and if so only for last cert */
|
||||
if (selfIssued == PKIX_FALSE ||
|
||||
(selfIssued == PKIX_TRUE && lastCert)) {
|
||||
PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
|
||||
(cert, state->nameConstraints, lastCert,
|
||||
plContext),
|
||||
PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
|
||||
}
|
||||
|
||||
if (!lastCert) {
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
|
||||
(cert, &nameConstraints, plContext),
|
||||
PKIX_CERTGETNAMECONSTRAINTSFAILED);
|
||||
|
||||
/* Merge with previous name constraints kept in state */
|
||||
|
||||
if (nameConstraints != NULL) {
|
||||
|
||||
if (state->nameConstraints == NULL) {
|
||||
|
||||
state->nameConstraints = nameConstraints;
|
||||
|
||||
} else {
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints
|
||||
(nameConstraints,
|
||||
state->nameConstraints,
|
||||
&mergedNameConstraints,
|
||||
plContext),
|
||||
PKIX_CERTMERGENAMECONSTRAINTSFAILED);
|
||||
|
||||
PKIX_DECREF(nameConstraints);
|
||||
PKIX_DECREF(state->nameConstraints);
|
||||
|
||||
state->nameConstraints = mergedNameConstraints;
|
||||
}
|
||||
|
||||
/* Remove Name Constraints Extension OID from list */
|
||||
if (unresolvedCriticalExtensions != NULL) {
|
||||
PKIX_CHECK(pkix_List_Remove
|
||||
(unresolvedCriticalExtensions,
|
||||
(PKIX_PL_Object *)state->nameConstraintsOID,
|
||||
plContext),
|
||||
PKIX_LISTREMOVEFAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object *)state, plContext),
|
||||
PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_NameConstraintsChecker_Initialize
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Create a CertChainChecker with a NameConstraintsCheckerState. The
|
||||
* NameConstraintsCheckerState is created with "trustedNC" and "numCerts"
|
||||
* as its initial state. The CertChainChecker for the NameConstraints is
|
||||
* returned at address of "pChecker".
|
||||
*
|
||||
* PARAMETERS
|
||||
* "trustedNC"
|
||||
* The NameConstraints from trusted anchor Cert is stored at "trustedNC"
|
||||
* for initialization. May be NULL.
|
||||
* "numCerts"
|
||||
* Number of certificates in the validation chain. This data is used
|
||||
* to identify end-entity.
|
||||
* "pChecker"
|
||||
* Address of CertChainChecker to bo created and returned.
|
||||
* Must be non-NULL.
|
||||
* "plContext" - Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CERTCHAINCHECKER Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_NameConstraintsChecker_Initialize(
|
||||
PKIX_PL_CertNameConstraints *trustedNC,
|
||||
PKIX_UInt32 numCerts,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_NameConstraintsCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Initialize");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(pkix_NameConstraintsCheckerState_Create
|
||||
(trustedNC, numCerts, &state, plContext),
|
||||
PKIX_NAMECONSTRAINTSCHECKERSTATECREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_NameConstraintsChecker_Check,
|
||||
PKIX_FALSE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *) state,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_nameconstraintschecker.h
|
||||
*
|
||||
* Header file for validate Name Constraints Checker function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_NAMECONSTRAINTSCHECKER_H
|
||||
#define _PKIX_NAMECONSTRAINTSCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pkix_NameConstraintsCheckerState \
|
||||
pkix_NameConstraintsCheckerState;
|
||||
|
||||
struct pkix_NameConstraintsCheckerState {
|
||||
PKIX_PL_CertNameConstraints *nameConstraints;
|
||||
PKIX_PL_OID *nameConstraintsOID;
|
||||
PKIX_UInt32 certsRemaining;
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_NameConstraintsChecker_Initialize(
|
||||
PKIX_PL_CertNameConstraints *trustedNC,
|
||||
PKIX_UInt32 numCerts,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_NAMECONSTRAINTSCHECKER_H */
|
||||
419
security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
Normal file
419
security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_ocspchecker.c
|
||||
*
|
||||
* OcspChecker Object Functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_ocspchecker.h"
|
||||
#include "pkix_pl_ocspcertid.h"
|
||||
#include "pkix_error.h"
|
||||
|
||||
|
||||
/* --Private-Data-and-Types--------------------------------------- */
|
||||
|
||||
typedef struct pkix_OcspCheckerStruct {
|
||||
/* RevocationMethod is the super class of OcspChecker. */
|
||||
pkix_RevocationMethod method;
|
||||
PKIX_PL_VerifyCallback certVerifyFcn;
|
||||
} pkix_OcspChecker;
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_OcspChecker_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_OcspChecker_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_OcspChecker_RegisterSelf
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_OCSPCHECKER_TYPE and its related functions with
|
||||
* systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry* entry = &systemClasses[PKIX_OCSPCHECKER_TYPE];
|
||||
|
||||
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_RegisterSelf");
|
||||
|
||||
entry->description = "OcspChecker";
|
||||
entry->typeObjectSize = sizeof(pkix_OcspChecker);
|
||||
entry->destructor = pkix_OcspChecker_Destroy;
|
||||
|
||||
PKIX_RETURN(OCSPCHECKER);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_OcspChecker_Create
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_Create(PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
PKIX_PL_VerifyCallback verifyFn,
|
||||
pkix_RevocationMethod **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_OcspChecker *method = NULL;
|
||||
|
||||
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Create");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_OCSPCHECKER_TYPE,
|
||||
sizeof (pkix_OcspChecker),
|
||||
(PKIX_PL_Object **)&method,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
|
||||
|
||||
pkixErrorResult = pkix_RevocationMethod_Init(
|
||||
(pkix_RevocationMethod*)method, methodType, flags, priority,
|
||||
localRevChecker, externalRevChecker, plContext);
|
||||
if (pkixErrorResult) {
|
||||
goto cleanup;
|
||||
}
|
||||
method->certVerifyFcn = (PKIX_PL_VerifyCallback)verifyFn;
|
||||
|
||||
*pChecker = (pkix_RevocationMethod*)method;
|
||||
method = NULL;
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(method);
|
||||
|
||||
PKIX_RETURN(OCSPCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_OcspChecker_MapResultCodeToRevStatus
|
||||
*/
|
||||
PKIX_RevocationStatus
|
||||
pkix_OcspChecker_MapResultCodeToRevStatus(SECErrorCodes resultCode)
|
||||
{
|
||||
switch (resultCode) {
|
||||
case SEC_ERROR_REVOKED_CERTIFICATE:
|
||||
return PKIX_RevStatus_Revoked;
|
||||
default:
|
||||
return PKIX_RevStatus_NoInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/* --Public-Functions--------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_OcspChecker_Check (see comments in pkix_checker.h)
|
||||
*/
|
||||
|
||||
/*
|
||||
* The OCSPChecker is created in an idle state, and remains in this state until
|
||||
* either (a) the default Responder has been set and enabled, and a Check
|
||||
* request is received with no responder specified, or (b) a Check request is
|
||||
* received with a specified responder. A request message is constructed and
|
||||
* given to the HttpClient. If non-blocking I/O is used the client may return
|
||||
* with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK
|
||||
* condition to its caller in turn. On a subsequent call the I/O is resumed.
|
||||
* When a response is received it is decoded and the results provided to the
|
||||
* caller.
|
||||
*
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_CheckLocal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *pReasonCode,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_PL_OcspCertID *cid = NULL;
|
||||
PKIX_Boolean hasFreshStatus = PKIX_FALSE;
|
||||
PKIX_Boolean statusIsGood = PKIX_FALSE;
|
||||
SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
|
||||
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckLocal");
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
|
||||
plContext),
|
||||
PKIX_OCSPCERTIDCREATEFAILED);
|
||||
if (!cid) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_OcspCertID_GetFreshCacheStatus(cid, date,
|
||||
&hasFreshStatus,
|
||||
&statusIsGood,
|
||||
&resultCode,
|
||||
plContext),
|
||||
PKIX_OCSPCERTIDGETFRESHCACHESTATUSFAILED);
|
||||
if (hasFreshStatus) {
|
||||
if (statusIsGood) {
|
||||
revStatus = PKIX_RevStatus_Success;
|
||||
resultCode = 0;
|
||||
} else {
|
||||
revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
*pRevStatus = revStatus;
|
||||
|
||||
/* ocsp carries only tree statuses: good, bad, and unknown.
|
||||
* revStatus is used to pass them. reasonCode is always set
|
||||
* to be unknown. */
|
||||
*pReasonCode = crlEntryReasonUnspecified;
|
||||
PKIX_DECREF(cid);
|
||||
|
||||
PKIX_RETURN(OCSPCHECKER);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The OCSPChecker is created in an idle state, and remains in this state until
|
||||
* either (a) the default Responder has been set and enabled, and a Check
|
||||
* request is received with no responder specified, or (b) a Check request is
|
||||
* received with a specified responder. A request message is constructed and
|
||||
* given to the HttpClient. When a response is received it is decoded and the
|
||||
* results provided to the caller.
|
||||
*
|
||||
* During the most recent enhancement of this function, it has been found that
|
||||
* it doesn't correctly implement non-blocking I/O.
|
||||
*
|
||||
* The nbioContext is used in two places, for "response-obtaining" and
|
||||
* for "response-verification".
|
||||
*
|
||||
* However, if this function gets called to resume, it always
|
||||
* repeats the "request creation" and "response fetching" steps!
|
||||
* As a result, the earlier operation is never resumed.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_CheckExternal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *pReasonCode,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
|
||||
PKIX_Boolean uriFound = PKIX_FALSE;
|
||||
PKIX_Boolean passed = PKIX_TRUE;
|
||||
pkix_OcspChecker *checker = NULL;
|
||||
PKIX_PL_OcspCertID *cid = NULL;
|
||||
PKIX_PL_OcspRequest *request = NULL;
|
||||
PKIX_PL_OcspResponse *response = NULL;
|
||||
PKIX_PL_Date *validity = NULL;
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
void *nbioContext = NULL;
|
||||
enum { stageGET, stagePOST } currentStage;
|
||||
PRBool retry = PR_FALSE;
|
||||
|
||||
PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckExternal");
|
||||
|
||||
PKIX_CHECK(
|
||||
pkix_CheckType((PKIX_PL_Object*)checkerObject,
|
||||
PKIX_OCSPCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTOCSPCHECKER);
|
||||
|
||||
checker = (pkix_OcspChecker *)checkerObject;
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
|
||||
plContext),
|
||||
PKIX_OCSPCERTIDCREATEFAILED);
|
||||
|
||||
/* create request */
|
||||
PKIX_CHECK(
|
||||
pkix_pl_OcspRequest_Create(cert, cid, validity, NULL,
|
||||
methodFlags, &uriFound, &request,
|
||||
plContext),
|
||||
PKIX_OCSPREQUESTCREATEFAILED);
|
||||
|
||||
if (uriFound == PKIX_FALSE) {
|
||||
/* no caching for certs lacking URI */
|
||||
resultCode = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (methodFlags & CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP) {
|
||||
/* Do not try HTTP GET, only HTTP POST */
|
||||
currentStage = stagePOST;
|
||||
} else {
|
||||
/* Try HTTP GET first, falling back to POST */
|
||||
currentStage = stageGET;
|
||||
}
|
||||
|
||||
do {
|
||||
const char *method;
|
||||
passed = PKIX_TRUE;
|
||||
|
||||
retry = PR_FALSE;
|
||||
if (currentStage == stageGET) {
|
||||
method = "GET";
|
||||
} else {
|
||||
PORT_Assert(currentStage == stagePOST);
|
||||
method = "POST";
|
||||
}
|
||||
|
||||
/* send request and create a response object */
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
pkix_pl_OcspResponse_Create(request, method, NULL,
|
||||
checker->certVerifyFcn,
|
||||
&nbioContext,
|
||||
&response,
|
||||
plContext),
|
||||
PKIX_OCSPRESPONSECREATEFAILED);
|
||||
|
||||
if (pkixErrorResult) {
|
||||
passed = PKIX_FALSE;
|
||||
}
|
||||
|
||||
if (passed && nbioContext != 0) {
|
||||
*pNBIOContext = nbioContext;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (passed){
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
pkix_pl_OcspResponse_Decode(response, &passed,
|
||||
&resultCode, plContext),
|
||||
PKIX_OCSPRESPONSEDECODEFAILED);
|
||||
if (pkixErrorResult) {
|
||||
passed = PKIX_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (passed){
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
pkix_pl_OcspResponse_GetStatus(response, &passed,
|
||||
&resultCode, plContext),
|
||||
PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
|
||||
if (pkixErrorResult) {
|
||||
passed = PKIX_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (passed){
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
pkix_pl_OcspResponse_VerifySignature(response, cert,
|
||||
procParams, &passed,
|
||||
&nbioContext, plContext),
|
||||
PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
|
||||
if (pkixErrorResult) {
|
||||
passed = PKIX_FALSE;
|
||||
} else {
|
||||
if (nbioContext != 0) {
|
||||
*pNBIOContext = nbioContext;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!passed && currentStage == stagePOST) {
|
||||
/* We won't retry a POST failure, so it's final.
|
||||
* Because the following block with its call to
|
||||
* pkix_pl_OcspResponse_GetStatusForCert
|
||||
* will take care of caching good or bad state,
|
||||
* but we only execute that next block if there hasn't
|
||||
* been a failure yet, we must cache the POST
|
||||
* failure now.
|
||||
*/
|
||||
|
||||
if (cid && cid->certID) {
|
||||
/* Caching MIGHT consume the cid. */
|
||||
PKIX_Error *err;
|
||||
err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
|
||||
cid, plContext);
|
||||
if (err) {
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (passed){
|
||||
PKIX_Boolean allowCachingOfFailures =
|
||||
(currentStage == stagePOST) ? PKIX_TRUE : PKIX_FALSE;
|
||||
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
pkix_pl_OcspResponse_GetStatusForCert(cid, response,
|
||||
allowCachingOfFailures,
|
||||
date,
|
||||
&passed, &resultCode,
|
||||
plContext),
|
||||
PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
|
||||
if (pkixErrorResult) {
|
||||
passed = PKIX_FALSE;
|
||||
} else if (passed == PKIX_FALSE) {
|
||||
revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
|
||||
} else {
|
||||
revStatus = PKIX_RevStatus_Success;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentStage == stageGET && revStatus != PKIX_RevStatus_Success &&
|
||||
revStatus != PKIX_RevStatus_Revoked) {
|
||||
/* we'll retry */
|
||||
PKIX_DECREF(response);
|
||||
retry = PR_TRUE;
|
||||
currentStage = stagePOST;
|
||||
revStatus = PKIX_RevStatus_NoInfo;
|
||||
if (pkixErrorResult) {
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
|
||||
plContext);
|
||||
pkixErrorResult = NULL;
|
||||
}
|
||||
}
|
||||
} while (retry);
|
||||
|
||||
cleanup:
|
||||
if (revStatus == PKIX_RevStatus_NoInfo && (uriFound ||
|
||||
methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
|
||||
methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
|
||||
revStatus = PKIX_RevStatus_Revoked;
|
||||
}
|
||||
*pRevStatus = revStatus;
|
||||
|
||||
/* ocsp carries only three statuses: good, bad, and unknown.
|
||||
* revStatus is used to pass them. reasonCode is always set
|
||||
* to be unknown. */
|
||||
*pReasonCode = crlEntryReasonUnspecified;
|
||||
|
||||
PKIX_DECREF(cid);
|
||||
PKIX_DECREF(request);
|
||||
PKIX_DECREF(response);
|
||||
|
||||
PKIX_RETURN(OCSPCHECKER);
|
||||
}
|
||||
|
||||
|
||||
67
security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h
Normal file
67
security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_ocspchecker.h
|
||||
*
|
||||
* OcspChecker Object Type Definition
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_OCSPCHECKER_H
|
||||
#define _PKIX_OCSPCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
#include "pkix_revocationmethod.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NOTE: nbio logic removed. Will be replaced later. */
|
||||
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_CheckLocal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_CheckExternal(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void **pNBIOContext,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_OcspChecker_Create(PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
PKIX_PL_VerifyCallback certVerifyFn,
|
||||
pkix_RevocationMethod **pChecker,
|
||||
void *plContext);
|
||||
|
||||
/* see source file for function documentation */
|
||||
|
||||
PKIX_Error *pkix_OcspChecker_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_OCSPCHECKER_H */
|
||||
2783
security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c
Normal file
2783
security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c
Normal file
File diff suppressed because it is too large
Load diff
73
security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h
Normal file
73
security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_policychecker.h
|
||||
*
|
||||
* Header file for policy checker.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_POLICYCHECKER_H
|
||||
#define _PKIX_POLICYCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct PKIX_PolicyCheckerStateStruct PKIX_PolicyCheckerState;
|
||||
|
||||
struct PKIX_PolicyCheckerStateStruct{
|
||||
PKIX_PL_OID *certPoliciesExtension; /* const */
|
||||
PKIX_PL_OID *policyMappingsExtension; /* const */
|
||||
PKIX_PL_OID *policyConstraintsExtension; /* const */
|
||||
PKIX_PL_OID *inhibitAnyPolicyExtension; /* const */
|
||||
PKIX_PL_OID *anyPolicyOID; /* const */
|
||||
PKIX_Boolean initialIsAnyPolicy; /* const */
|
||||
PKIX_PolicyNode *validPolicyTree;
|
||||
PKIX_List *userInitialPolicySet; /* immutable */
|
||||
PKIX_List *mappedUserInitialPolicySet;
|
||||
PKIX_Boolean policyQualifiersRejected;
|
||||
PKIX_Boolean initialPolicyMappingInhibit;
|
||||
PKIX_Boolean initialExplicitPolicy;
|
||||
PKIX_Boolean initialAnyPolicyInhibit;
|
||||
PKIX_UInt32 explicitPolicy;
|
||||
PKIX_UInt32 inhibitAnyPolicy;
|
||||
PKIX_UInt32 policyMapping;
|
||||
PKIX_UInt32 numCerts;
|
||||
PKIX_UInt32 certsProcessed;
|
||||
PKIX_PolicyNode *anyPolicyNodeAtBottom;
|
||||
PKIX_PolicyNode *newAnyPolicyNode;
|
||||
/*
|
||||
* The following variables do not survive from one
|
||||
* certificate to the next. They are needed at each
|
||||
* level of recursive routines, any by placing them
|
||||
* in the state object we can pass fewer arguments.
|
||||
*/
|
||||
PKIX_Boolean certPoliciesCritical;
|
||||
PKIX_List *mappedPolicyOIDs;
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_PolicyChecker_Initialize(
|
||||
PKIX_List *initialPolicies,
|
||||
PKIX_Boolean policyQualifiersRejected,
|
||||
PKIX_Boolean initialPolicyMappingInhibit,
|
||||
PKIX_Boolean initialExplicitPolicy,
|
||||
PKIX_Boolean initialAnyPolicyInhibit,
|
||||
PKIX_UInt32 numCerts,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
PKIX_Error *
|
||||
pkix_PolicyCheckerState_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_POLICYCHECKER_H */
|
||||
475
security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c
Normal file
475
security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c
Normal file
|
|
@ -0,0 +1,475 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_revocationchecker.c
|
||||
*
|
||||
* RevocationChecker Object Functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_revocationchecker.h"
|
||||
#include "pkix_tools.h"
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_RevocationChecker_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_RevocationChecker_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_RevocationChecker *checker = NULL;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a revocation checker */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTREVOCATIONCHECKER);
|
||||
|
||||
checker = (PKIX_RevocationChecker *)object;
|
||||
|
||||
PKIX_DECREF(checker->leafMethodList);
|
||||
PKIX_DECREF(checker->chainMethodList);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_RevocationChecker_Duplicate
|
||||
* (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_RevocationChecker_Duplicate(
|
||||
PKIX_PL_Object *object,
|
||||
PKIX_PL_Object **pNewObject,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_RevocationChecker *checker = NULL;
|
||||
PKIX_RevocationChecker *checkerDuplicate = NULL;
|
||||
PKIX_List *dupLeafList = NULL;
|
||||
PKIX_List *dupChainList = NULL;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Duplicate");
|
||||
PKIX_NULLCHECK_TWO(object, pNewObject);
|
||||
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
|
||||
PKIX_OBJECTNOTCERTCHAINCHECKER);
|
||||
|
||||
checker = (PKIX_RevocationChecker *)object;
|
||||
|
||||
if (checker->leafMethodList){
|
||||
PKIX_CHECK(PKIX_PL_Object_Duplicate
|
||||
((PKIX_PL_Object *)checker->leafMethodList,
|
||||
(PKIX_PL_Object **)&dupLeafList,
|
||||
plContext),
|
||||
PKIX_OBJECTDUPLICATEFAILED);
|
||||
}
|
||||
if (checker->chainMethodList){
|
||||
PKIX_CHECK(PKIX_PL_Object_Duplicate
|
||||
((PKIX_PL_Object *)checker->chainMethodList,
|
||||
(PKIX_PL_Object **)&dupChainList,
|
||||
plContext),
|
||||
PKIX_OBJECTDUPLICATEFAILED);
|
||||
}
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_RevocationChecker_Create(checker->leafMethodListFlags,
|
||||
checker->chainMethodListFlags,
|
||||
&checkerDuplicate,
|
||||
plContext),
|
||||
PKIX_REVOCATIONCHECKERCREATEFAILED);
|
||||
|
||||
checkerDuplicate->leafMethodList = dupLeafList;
|
||||
checkerDuplicate->chainMethodList = dupChainList;
|
||||
dupLeafList = NULL;
|
||||
dupChainList = NULL;
|
||||
|
||||
*pNewObject = (PKIX_PL_Object *)checkerDuplicate;
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(dupLeafList);
|
||||
PKIX_DECREF(dupChainList);
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_RevocationChecker_RegisterSelf
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_REVOCATIONCHECKER_TYPE and its related functions with
|
||||
* systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_RevocationChecker_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_RegisterSelf");
|
||||
|
||||
entry.description = "RevocationChecker";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(PKIX_RevocationChecker);
|
||||
entry.destructor = pkix_RevocationChecker_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = pkix_RevocationChecker_Duplicate;
|
||||
|
||||
systemClasses[PKIX_REVOCATIONCHECKER_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
/* Sort methods by their priorities (lower priority = higher preference) */
|
||||
static PKIX_Error *
|
||||
pkix_RevocationChecker_SortComparator(
|
||||
PKIX_PL_Object *obj1,
|
||||
PKIX_PL_Object *obj2,
|
||||
PKIX_Int32 *pResult,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_RevocationMethod *method1 = NULL, *method2 = NULL;
|
||||
|
||||
PKIX_ENTER(BUILD, "pkix_RevocationChecker_SortComparator");
|
||||
|
||||
method1 = (pkix_RevocationMethod *)obj1;
|
||||
method2 = (pkix_RevocationMethod *)obj2;
|
||||
|
||||
if (method1->priority < method2->priority) {
|
||||
*pResult = -1;
|
||||
} else if (method1->priority > method2->priority) {
|
||||
*pResult = 1;
|
||||
} else {
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
PKIX_RETURN(BUILD);
|
||||
}
|
||||
|
||||
|
||||
/* --Public-Functions--------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_RevocationChecker_Create (see comments in pkix_revchecker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_RevocationChecker_Create(
|
||||
PKIX_UInt32 leafMethodListFlags,
|
||||
PKIX_UInt32 chainMethodListFlags,
|
||||
PKIX_RevocationChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_RevocationChecker *checker = NULL;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Create");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(
|
||||
PKIX_PL_Object_Alloc(PKIX_REVOCATIONCHECKER_TYPE,
|
||||
sizeof (PKIX_RevocationChecker),
|
||||
(PKIX_PL_Object **)&checker,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
|
||||
|
||||
checker->leafMethodListFlags = leafMethodListFlags;
|
||||
checker->chainMethodListFlags = chainMethodListFlags;
|
||||
checker->leafMethodList = NULL;
|
||||
checker->chainMethodList = NULL;
|
||||
|
||||
*pChecker = checker;
|
||||
checker = NULL;
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(checker);
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_RevocationChecker_CreateAndAddMethod(
|
||||
PKIX_RevocationChecker *revChecker,
|
||||
PKIX_ProcessingParams *params,
|
||||
PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
PKIX_PL_VerifyCallback verificationFn,
|
||||
PKIX_Boolean isLeafMethod,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_List **methodList = NULL;
|
||||
PKIX_List *unsortedList = NULL;
|
||||
PKIX_List *certStores = NULL;
|
||||
pkix_RevocationMethod *method = NULL;
|
||||
pkix_LocalRevocationCheckFn *localRevChecker = NULL;
|
||||
pkix_ExternalRevocationCheckFn *externRevChecker = NULL;
|
||||
PKIX_UInt32 miFlags;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod");
|
||||
PKIX_NULLCHECK_ONE(revChecker);
|
||||
|
||||
/* If the caller has said "Either one is sufficient, then don't let the
|
||||
* absence of any one method's info lead to an overall failure.
|
||||
*/
|
||||
miFlags = isLeafMethod ? revChecker->leafMethodListFlags
|
||||
: revChecker->chainMethodListFlags;
|
||||
if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE)
|
||||
flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
|
||||
|
||||
switch (methodType) {
|
||||
case PKIX_RevocationMethod_CRL:
|
||||
localRevChecker = pkix_CrlChecker_CheckLocal;
|
||||
externRevChecker = pkix_CrlChecker_CheckExternal;
|
||||
PKIX_CHECK(
|
||||
PKIX_ProcessingParams_GetCertStores(params, &certStores,
|
||||
plContext),
|
||||
PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
|
||||
PKIX_CHECK(
|
||||
pkix_CrlChecker_Create(methodType, flags, priority,
|
||||
localRevChecker, externRevChecker,
|
||||
certStores, verificationFn,
|
||||
&method,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATECRLCHECKEROBJECT);
|
||||
break;
|
||||
case PKIX_RevocationMethod_OCSP:
|
||||
localRevChecker = pkix_OcspChecker_CheckLocal;
|
||||
externRevChecker = pkix_OcspChecker_CheckExternal;
|
||||
PKIX_CHECK(
|
||||
pkix_OcspChecker_Create(methodType, flags, priority,
|
||||
localRevChecker, externRevChecker,
|
||||
verificationFn,
|
||||
&method,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATEOCSPCHECKEROBJECT);
|
||||
break;
|
||||
default:
|
||||
PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD);
|
||||
}
|
||||
|
||||
if (isLeafMethod) {
|
||||
methodList = &revChecker->leafMethodList;
|
||||
} else {
|
||||
methodList = &revChecker->chainMethodList;
|
||||
}
|
||||
|
||||
if (*methodList == NULL) {
|
||||
PKIX_CHECK(
|
||||
PKIX_List_Create(methodList, plContext),
|
||||
PKIX_LISTCREATEFAILED);
|
||||
}
|
||||
unsortedList = *methodList;
|
||||
PKIX_CHECK(
|
||||
PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext),
|
||||
PKIX_LISTAPPENDITEMFAILED);
|
||||
PKIX_CHECK(
|
||||
pkix_List_BubbleSort(unsortedList,
|
||||
pkix_RevocationChecker_SortComparator,
|
||||
methodList, plContext),
|
||||
PKIX_LISTBUBBLESORTFAILED);
|
||||
|
||||
cleanup:
|
||||
PKIX_DECREF(method);
|
||||
PKIX_DECREF(unsortedList);
|
||||
PKIX_DECREF(certStores);
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: PKIX_RevocationChecker_Check
|
||||
*/
|
||||
PKIX_Error *
|
||||
PKIX_RevocationChecker_Check(
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_PL_Cert *issuer,
|
||||
PKIX_RevocationChecker *revChecker,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_Boolean testingLeafCert,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
PKIX_UInt32 *pReasonCode,
|
||||
void **pNbioContext,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_RevocationStatus overallStatus = PKIX_RevStatus_NoInfo;
|
||||
PKIX_RevocationStatus methodStatus[PKIX_RevocationMethod_MAX];
|
||||
PKIX_Boolean onlyUseRemoteMethods = PKIX_FALSE;
|
||||
PKIX_UInt32 revFlags = 0;
|
||||
PKIX_List *revList = NULL;
|
||||
PKIX_PL_Date *date = NULL;
|
||||
pkix_RevocationMethod *method = NULL;
|
||||
void *nbioContext;
|
||||
int tries;
|
||||
|
||||
PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Check");
|
||||
PKIX_NULLCHECK_TWO(revChecker, procParams);
|
||||
|
||||
nbioContext = *pNbioContext;
|
||||
*pNbioContext = NULL;
|
||||
|
||||
if (testingLeafCert) {
|
||||
revList = revChecker->leafMethodList;
|
||||
revFlags = revChecker->leafMethodListFlags;
|
||||
} else {
|
||||
revList = revChecker->chainMethodList;
|
||||
revFlags = revChecker->chainMethodListFlags;
|
||||
}
|
||||
if (!revList) {
|
||||
/* Return NoInfo status */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
PORT_Memset(methodStatus, PKIX_RevStatus_NoInfo,
|
||||
sizeof(PKIX_RevocationStatus) * PKIX_RevocationMethod_MAX);
|
||||
|
||||
date = procParams->date;
|
||||
|
||||
/* Need to have two loops if we testing all local info first:
|
||||
* first we are going to test all local(cached) info
|
||||
* second, all remote info(fetching) */
|
||||
for (tries = 0;tries < 2;tries++) {
|
||||
unsigned int methodNum = 0;
|
||||
for (;methodNum < revList->length;methodNum++) {
|
||||
PKIX_UInt32 methodFlags = 0;
|
||||
|
||||
PKIX_DECREF(method);
|
||||
PKIX_CHECK(
|
||||
PKIX_List_GetItem(revList, methodNum,
|
||||
(PKIX_PL_Object**)&method, plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
methodFlags = method->flags;
|
||||
if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) {
|
||||
/* Will not check with this method. Skipping... */
|
||||
continue;
|
||||
}
|
||||
if (!onlyUseRemoteMethods &&
|
||||
methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
(*method->localRevChecker)(cert, issuer, date,
|
||||
method, procParams,
|
||||
methodFlags,
|
||||
chainVerificationState,
|
||||
&revStatus,
|
||||
(CERTCRLEntryReasonCode *)pReasonCode,
|
||||
plContext),
|
||||
PKIX_REVCHECKERCHECKFAILED);
|
||||
methodStatus[methodNum] = revStatus;
|
||||
if (revStatus == PKIX_RevStatus_Revoked) {
|
||||
/* if error was generated use it as final error. */
|
||||
overallStatus = PKIX_RevStatus_Revoked;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pkixErrorResult) {
|
||||
/* Disregard errors. Only returned revStatus matters. */
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
|
||||
plContext);
|
||||
pkixErrorResult = NULL;
|
||||
}
|
||||
}
|
||||
if ((!(revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST) ||
|
||||
onlyUseRemoteMethods) &&
|
||||
chainVerificationState &&
|
||||
methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
|
||||
if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) {
|
||||
PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
|
||||
PKIX_CHECK_NO_GOTO(
|
||||
(*method->externalRevChecker)(cert, issuer, date,
|
||||
method,
|
||||
procParams, methodFlags,
|
||||
&revStatus,
|
||||
(CERTCRLEntryReasonCode *)pReasonCode,
|
||||
&nbioContext, plContext),
|
||||
PKIX_REVCHECKERCHECKFAILED);
|
||||
methodStatus[methodNum] = revStatus;
|
||||
if (revStatus == PKIX_RevStatus_Revoked) {
|
||||
/* if error was generated use it as final error. */
|
||||
overallStatus = PKIX_RevStatus_Revoked;
|
||||
goto cleanup;
|
||||
}
|
||||
if (pkixErrorResult) {
|
||||
/* Disregard errors. Only returned revStatus matters. */
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
|
||||
plContext);
|
||||
pkixErrorResult = NULL;
|
||||
}
|
||||
} else if (methodFlags &
|
||||
PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
|
||||
/* Info is not in the local cache. Network fetching is not
|
||||
* allowed. If need to fail on missing fresh info for the
|
||||
* the method, then we should fail right here.*/
|
||||
overallStatus = PKIX_RevStatus_Revoked;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* If success and we should not check the next method, then
|
||||
* return a success. */
|
||||
if (methodStatus[methodNum] == PKIX_RevStatus_Success &&
|
||||
!(methodFlags & PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO)) {
|
||||
overallStatus = PKIX_RevStatus_Success;
|
||||
goto cleanup;
|
||||
}
|
||||
} /* inner loop */
|
||||
if (!onlyUseRemoteMethods &&
|
||||
revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST &&
|
||||
chainVerificationState) {
|
||||
onlyUseRemoteMethods = PKIX_TRUE;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} /* outer loop */
|
||||
|
||||
if (overallStatus == PKIX_RevStatus_NoInfo &&
|
||||
chainVerificationState) {
|
||||
/* The following check makes sence only for chain
|
||||
* validation step, sinse we do not fetch info while
|
||||
* in the process of finding trusted anchor.
|
||||
* For chain building step it is enough to know, that
|
||||
* the cert was not directly revoked by any of the
|
||||
* methods. */
|
||||
|
||||
/* Still have no info. But one of the method could
|
||||
* have returned success status(possible if CONTINUE
|
||||
* TESTING ON FRESH INFO flag was used).
|
||||
* If any of the methods have returned Success status,
|
||||
* the overallStatus should be success. */
|
||||
int methodNum = 0;
|
||||
for (;methodNum < PKIX_RevocationMethod_MAX;methodNum++) {
|
||||
if (methodStatus[methodNum] == PKIX_RevStatus_Success) {
|
||||
overallStatus = PKIX_RevStatus_Success;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (revFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) {
|
||||
overallStatus = PKIX_RevStatus_Revoked;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
*pRevStatus = overallStatus;
|
||||
PKIX_DECREF(method);
|
||||
|
||||
PKIX_RETURN(REVOCATIONCHECKER);
|
||||
}
|
||||
|
||||
151
security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h
Normal file
151
security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_revocationchecker.h
|
||||
*
|
||||
* RevocationChecker Object Type Definition
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_REVOCATIONCHECKER_H
|
||||
#define _PKIX_REVOCATIONCHECKER_H
|
||||
|
||||
#include "pkixt.h"
|
||||
#include "certt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NOTE: nbio logistic removed. Will be replaced later. */
|
||||
|
||||
/*
|
||||
* All Flags are prefixed by CERT_REV_M_, where _M_ indicates
|
||||
* this is a method dependent flag.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Whether or not to use a method for revocation testing.
|
||||
* If set to "do not test", then all other flags are ignored.
|
||||
*/
|
||||
#define PKIX_REV_M_DO_NOT_TEST_USING_THIS_METHOD 0x00L
|
||||
#define PKIX_REV_M_TEST_USING_THIS_METHOD 0x01L
|
||||
|
||||
/*
|
||||
* Whether or not NSS is allowed to attempt to fetch fresh information
|
||||
* from the network.
|
||||
* (Although fetching will never happen if fresh information for the
|
||||
* method is already locally available.)
|
||||
*/
|
||||
#define PKIX_REV_M_ALLOW_NETWORK_FETCHING 0x00L
|
||||
#define PKIX_REV_M_FORBID_NETWORK_FETCHING 0x02L
|
||||
|
||||
/*
|
||||
* Example for an implicit default source:
|
||||
* The globally configured default OCSP responder.
|
||||
* IGNORE means:
|
||||
* ignore the implicit default source, whether it's configured or not.
|
||||
* ALLOW means:
|
||||
* if an implicit default source is configured,
|
||||
* then it overrides any available or missing source in the cert.
|
||||
* if no implicit default source is configured,
|
||||
* then we continue to use what's available (or not available)
|
||||
* in the certs.
|
||||
*/
|
||||
#define PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE 0x00L
|
||||
#define PKIX_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE 0x04L /* OCSP only */
|
||||
|
||||
/*
|
||||
* Defines the behavior if no fresh information is available,
|
||||
* fetching from the network is allowed, but the source of revocation
|
||||
* information is unknown (even after considering implicit sources,
|
||||
* if allowed by other flags).
|
||||
* SKIPT_TEST means:
|
||||
* We ignore that no fresh information is available and
|
||||
* skip this test.
|
||||
* REQUIRE_INFO means:
|
||||
* We still require that fresh information is available.
|
||||
* Other flags define what happens on missing fresh info.
|
||||
*/
|
||||
|
||||
#define PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE 0x00L
|
||||
#define PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE 0x08L
|
||||
|
||||
/*
|
||||
* Defines the behavior if we are unable to obtain fresh information.
|
||||
* INGORE means:
|
||||
* Return "cert status unknown"
|
||||
* FAIL means:
|
||||
* Return "cert revoked".
|
||||
*/
|
||||
|
||||
#define PKIX_REV_M_IGNORE_MISSING_FRESH_INFO 0x00L
|
||||
#define PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO 0x10L
|
||||
|
||||
/*
|
||||
* What should happen if we were able to find fresh information using
|
||||
* this method, and the data indicated the cert is good?
|
||||
* STOP_TESTING means:
|
||||
* Our success is sufficient, do not continue testing
|
||||
* other methods.
|
||||
* CONTINUE_TESTING means:
|
||||
* We will continue and test the next allowed
|
||||
* specified method.
|
||||
*/
|
||||
|
||||
#define PKIX_REV_M_STOP_TESTING_ON_FRESH_INFO 0x00L
|
||||
#define PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO 0x20L
|
||||
|
||||
/*
|
||||
* All Flags are prefixed by PKIX_REV_MI_, where _MI_ indicates
|
||||
* this is a method independent flag.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This defines the order to checking.
|
||||
* EACH_METHOD_SEPARATELY means:
|
||||
* Do all tests related to a particular allowed method
|
||||
* (both local information and network fetching) in a single step.
|
||||
* Only after testing for a particular method is done,
|
||||
* then switching to the next method will happen.
|
||||
* ALL_LOCAL_INFORMATION_FIRST means:
|
||||
* Start by testing the information for all allowed methods
|
||||
* which are already locally available. Only after that is done
|
||||
* consider to fetch from the network (as allowed by other flags).
|
||||
*/
|
||||
#define PKIX_REV_MI_TEST_EACH_METHOD_SEPARATELY 0x00L
|
||||
#define PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST 0x01L
|
||||
|
||||
/*
|
||||
* Use this flag to specify that it's necessary that fresh information
|
||||
* is available for at least one of the allowed methods, but it's
|
||||
* irrelevant which of the mechanisms succeeded.
|
||||
* NO_OVERALL_INFO_REQUIREMENT means:
|
||||
* We strictly follow the requirements for each individual method.
|
||||
* REQUIRE_SOME_FRESH_INFO_AVAILABLE means:
|
||||
* After the individual tests have been executed, we must have
|
||||
* been able to find fresh information using at least one method.
|
||||
* If we were unable to find fresh info, it's a failure.
|
||||
*/
|
||||
#define PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT 0x00L
|
||||
#define PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE 0x02L
|
||||
|
||||
/* Defines check time for the cert, revocation methods lists and
|
||||
* flags for leaf and chain certs revocation tests. */
|
||||
struct PKIX_RevocationCheckerStruct {
|
||||
PKIX_List *leafMethodList;
|
||||
PKIX_List *chainMethodList;
|
||||
PKIX_UInt32 leafMethodListFlags;
|
||||
PKIX_UInt32 chainMethodListFlags;
|
||||
};
|
||||
|
||||
/* see source file for function documentation */
|
||||
|
||||
PKIX_Error *pkix_RevocationChecker_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_REVOCATIONCHECKER_H */
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_revocationmethod.c
|
||||
*
|
||||
* RevocationMethod Object Functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_revocationmethod.h"
|
||||
#include "pkix_tools.h"
|
||||
|
||||
/* Constructor of revocation method object. Does not create an object,
|
||||
* but just initializez PKIX_RevocationMethodStruct fields. Object
|
||||
* suppose to be already created. */
|
||||
PKIX_Error *
|
||||
pkix_RevocationMethod_Init(
|
||||
pkix_RevocationMethod *method,
|
||||
PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
void *plContext)
|
||||
{
|
||||
PKIX_ENTER(REVOCATIONMETHOD, "PKIX_RevocationMethod_Init");
|
||||
|
||||
method->methodType = methodType;
|
||||
method->flags = flags;
|
||||
method->priority = priority;
|
||||
method->localRevChecker = localRevChecker;
|
||||
method->externalRevChecker = externalRevChecker;
|
||||
|
||||
PKIX_RETURN(REVOCATIONMETHOD);
|
||||
}
|
||||
|
||||
/* Data duplication data. Not create an object. Only initializes fields
|
||||
* in the new object by data from "object". */
|
||||
PKIX_Error *
|
||||
pkix_RevocationMethod_Duplicate(
|
||||
PKIX_PL_Object *object,
|
||||
PKIX_PL_Object *newObject,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_RevocationMethod *method = NULL;
|
||||
|
||||
PKIX_ENTER(REVOCATIONMETHOD, "pkix_RevocationMethod_Duplicate");
|
||||
PKIX_NULLCHECK_TWO(object, newObject);
|
||||
|
||||
method = (pkix_RevocationMethod *)object;
|
||||
|
||||
PKIX_CHECK(
|
||||
pkix_RevocationMethod_Init((pkix_RevocationMethod*)newObject,
|
||||
method->methodType,
|
||||
method->flags,
|
||||
method->priority,
|
||||
method->localRevChecker,
|
||||
method->externalRevChecker,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATEREVOCATIONMETHODOBJECT);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(REVOCATIONMETHOD);
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_revocationmethod.h
|
||||
*
|
||||
* RevocationMethod Object
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_REVOCATIONMETHOD_H
|
||||
#define _PKIX_REVOCATIONMETHOD_H
|
||||
|
||||
#include "pkixt.h"
|
||||
#include "pkix_revocationchecker.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pkix_RevocationMethodStruct pkix_RevocationMethod;
|
||||
|
||||
/* Local revocation check function prototype definition.
|
||||
* Revocation methods capable of checking revocation though local
|
||||
* means(cache) should implement this prototype. */
|
||||
typedef PKIX_Error *
|
||||
pkix_LocalRevocationCheckFn(PKIX_PL_Cert *cert, PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_Boolean chainVerificationState,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void *plContext);
|
||||
|
||||
/* External revocation check function prototype definition.
|
||||
* Revocation methods that required external communications(crldp
|
||||
* ocsp) shoult implement this prototype. */
|
||||
typedef PKIX_Error *
|
||||
pkix_ExternalRevocationCheckFn(PKIX_PL_Cert *cert, PKIX_PL_Cert *issuer,
|
||||
PKIX_PL_Date *date,
|
||||
pkix_RevocationMethod *checkerObject,
|
||||
PKIX_ProcessingParams *procParams,
|
||||
PKIX_UInt32 methodFlags,
|
||||
PKIX_RevocationStatus *pRevStatus,
|
||||
CERTCRLEntryReasonCode *reasonCode,
|
||||
void **pNBIOContext, void *plContext);
|
||||
|
||||
/* Revocation method structure assosiates revocation types with
|
||||
* a set of flags on the method, a priority of the method (0
|
||||
* corresponds to the highest priority), and method local/external
|
||||
* checker functions. */
|
||||
struct pkix_RevocationMethodStruct {
|
||||
PKIX_RevocationMethodType methodType;
|
||||
PKIX_UInt32 flags;
|
||||
PKIX_UInt32 priority;
|
||||
pkix_LocalRevocationCheckFn (*localRevChecker);
|
||||
pkix_ExternalRevocationCheckFn (*externalRevChecker);
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_RevocationMethod_Duplicate(PKIX_PL_Object *object,
|
||||
PKIX_PL_Object *newObject,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_RevocationMethod_Init(pkix_RevocationMethod *method,
|
||||
PKIX_RevocationMethodType methodType,
|
||||
PKIX_UInt32 flags,
|
||||
PKIX_UInt32 priority,
|
||||
pkix_LocalRevocationCheckFn localRevChecker,
|
||||
pkix_ExternalRevocationCheckFn externalRevChecker,
|
||||
void *plContext);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_REVOCATIONMETHOD_H */
|
||||
443
security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c
Normal file
443
security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_signaturechecker.c
|
||||
*
|
||||
* Functions for signature validation
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pkix_signaturechecker.h"
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_SignatureCheckerstate_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_SignatureCheckerState_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_SignatureCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(SIGNATURECHECKERSTATE,
|
||||
"pkix_SignatureCheckerState_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a signature checker state */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_SIGNATURECHECKERSTATE_TYPE, plContext),
|
||||
PKIX_OBJECTNOTSIGNATURECHECKERSTATE);
|
||||
|
||||
state = (pkix_SignatureCheckerState *) object;
|
||||
|
||||
state->prevCertCertSign = PKIX_FALSE;
|
||||
|
||||
PKIX_DECREF(state->prevPublicKey);
|
||||
PKIX_DECREF(state->prevPublicKeyList);
|
||||
PKIX_DECREF(state->keyUsageOID);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(SIGNATURECHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_SignatureCheckerState_RegisterSelf
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_SIGNATURECHECKERSTATE_TYPE and its related functions
|
||||
* with systemClasses[]
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_SignatureCheckerState_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(SIGNATURECHECKERSTATE,
|
||||
"pkix_SignatureCheckerState_RegisterSelf");
|
||||
|
||||
entry.description = "SignatureCheckerState";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(pkix_SignatureCheckerState);
|
||||
entry.destructor = pkix_SignatureCheckerState_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = NULL;
|
||||
|
||||
systemClasses[PKIX_SIGNATURECHECKERSTATE_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(SIGNATURECHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_SignatureCheckerState_Create
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Allocate and initialize SignatureChecker state data.
|
||||
*
|
||||
* PARAMETERS
|
||||
* "trustedPubKey"
|
||||
* Address of trusted Anchor Public Key for verifying first Cert in the
|
||||
* chain. Must be non-NULL.
|
||||
* "certsRemaining"
|
||||
* Number of certificates remaining in the chain.
|
||||
* "pCheckerState"
|
||||
* Address where SignatureCheckerState will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
*
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
*
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a SignatureCheckerState Error if the function fails in a
|
||||
* non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_SignatureCheckerState_Create(
|
||||
PKIX_PL_PublicKey *trustedPubKey,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
pkix_SignatureCheckerState **pCheckerState,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_SignatureCheckerState *state = NULL;
|
||||
PKIX_PL_OID *keyUsageOID = NULL;
|
||||
|
||||
PKIX_ENTER(SIGNATURECHECKERSTATE, "pkix_SignatureCheckerState_Create");
|
||||
PKIX_NULLCHECK_TWO(trustedPubKey, pCheckerState);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_SIGNATURECHECKERSTATE_TYPE,
|
||||
sizeof (pkix_SignatureCheckerState),
|
||||
(PKIX_PL_Object **)&state,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATESIGNATURECHECKERSTATEOBJECT);
|
||||
|
||||
/* Initialize fields */
|
||||
|
||||
state->prevCertCertSign = PKIX_TRUE;
|
||||
state->prevPublicKeyList = NULL;
|
||||
state->certsRemaining = certsRemaining;
|
||||
|
||||
PKIX_INCREF(trustedPubKey);
|
||||
state->prevPublicKey = trustedPubKey;
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_CERTKEYUSAGE_OID,
|
||||
&keyUsageOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
state->keyUsageOID = keyUsageOID;
|
||||
keyUsageOID = NULL;
|
||||
|
||||
*pCheckerState = state;
|
||||
state = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(keyUsageOID);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(SIGNATURECHECKERSTATE);
|
||||
}
|
||||
|
||||
/* --Private-Functions-------------------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_SignatureChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_SignatureChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_SignatureCheckerState *state = NULL;
|
||||
PKIX_PL_PublicKey *prevPubKey = NULL;
|
||||
PKIX_PL_PublicKey *currPubKey = NULL;
|
||||
PKIX_PL_PublicKey *newPubKey = NULL;
|
||||
PKIX_PL_PublicKey *pKey = NULL;
|
||||
PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
|
||||
PKIX_Error *checkKeyUsageFail = NULL;
|
||||
PKIX_Error *verifyFail = NULL;
|
||||
PKIX_Boolean certVerified = PKIX_FALSE;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_SignatureChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&state, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
(state->certsRemaining)--;
|
||||
|
||||
PKIX_INCREF(state->prevPublicKey);
|
||||
prevPubKey = state->prevPublicKey;
|
||||
|
||||
/*
|
||||
* Previous Cert doesn't have CertSign bit on for signature
|
||||
* verification and it is not a self-issued Cert so there is no
|
||||
* old key saved. This is considered error.
|
||||
*/
|
||||
if (state->prevCertCertSign == PKIX_FALSE &&
|
||||
state->prevPublicKeyList == NULL) {
|
||||
PKIX_ERROR(PKIX_KEYUSAGEKEYCERTSIGNBITNOTON);
|
||||
}
|
||||
|
||||
/* Previous Cert is valid for signature verification, try it first */
|
||||
if (state->prevCertCertSign == PKIX_TRUE) {
|
||||
verifyFail = PKIX_PL_Cert_VerifySignature
|
||||
(cert, prevPubKey, plContext);
|
||||
if (verifyFail == NULL) {
|
||||
certVerified = PKIX_TRUE;
|
||||
} else {
|
||||
certVerified = PKIX_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NIST_TEST_4_5_4_AND_4_5_6
|
||||
|
||||
/*
|
||||
* Following codes under this compiler flag is implemented for
|
||||
* special cases of NIST tests 4.5.4 and 4.5.6. We are not sure
|
||||
* we should handle these two tests as what is implemented so the
|
||||
* codes are commented out, and the tests fails (for now).
|
||||
* For Cert chain validation, our assumption is all the Certs on
|
||||
* the chain are using its previous Cert's public key to decode
|
||||
* its current key. But for thses two tests, keys are used not
|
||||
* in this precedent order, we can either
|
||||
* 1) Use what is implemented here: take in what Cert order NIST
|
||||
* specified and for continuous self-issued Certs, stacking up
|
||||
* their keys and tries all of them in FILO order.
|
||||
* But this method breaks the idea of chain key presdency.
|
||||
* 2) Use Build Chain facility: we will specify the valid Certs
|
||||
* order (means key precedency is kept) and count on Build Chain
|
||||
* to get the Certs that can fill for the needed keys. This may have
|
||||
* performance impact.
|
||||
* 3) Fetch Certs from CertStore: we will specifiy the valid Certs
|
||||
* order and use CertSelector on SubjectName to get a list of
|
||||
* candidates Certs to fill in for the needed keys.
|
||||
* Anyhow, the codes are kept around just in case we want to use
|
||||
* solution one...
|
||||
*/
|
||||
|
||||
/* If failed and previous key is self-issued, try its old key(s) */
|
||||
if (certVerified == PKIX_FALSE && state->prevPublicKeyList != NULL) {
|
||||
|
||||
/* Verify from keys on the list */
|
||||
PKIX_CHECK(PKIX_List_GetLength
|
||||
(state->prevPublicKeyList, &numKeys, plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
|
||||
for (i = numKeys - 1; i >= 0; i--) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_GetItem
|
||||
(state->prevPublicKeyList,
|
||||
i,
|
||||
(PKIX_PL_Object **) &pKey,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_DECREF(verifyFail);
|
||||
verifyFail = PKIX_PL_Cert_VerifySignature
|
||||
(cert, pKey, plContext);
|
||||
|
||||
if (verifyFail == NULL) {
|
||||
certVerified = PKIX_TRUE;
|
||||
break;
|
||||
} else {
|
||||
certVerified = PKIX_FALSE;
|
||||
}
|
||||
|
||||
PKIX_DECREF(pKey);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (certVerified == PKIX_FALSE) {
|
||||
pkixErrorResult = verifyFail;
|
||||
verifyFail = NULL;
|
||||
PKIX_ERROR(PKIX_VALIDATIONFAILEDCERTSIGNATURECHECKING);
|
||||
}
|
||||
|
||||
#ifdef NIST_TEST_4_5_4_AND_4_5_6
|
||||
/*
|
||||
* Check if Cert is self-issued. If so, the old key(s) is saved, in
|
||||
* conjunction to the new key, for verifying CERT validity later.
|
||||
*/
|
||||
PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
|
||||
PKIX_ISCERTSELFISSUEFAILED);
|
||||
|
||||
/*
|
||||
* Check if Cert is self-issued. If so, the public key of the Cert
|
||||
* that issues this Cert (old key) can be used together with this
|
||||
* current key (new key) for key verification. If there are multiple
|
||||
* self-issued certs, keys of those Certs (old keys) can also be used
|
||||
* for key verification. Old key(s) is saved in a list (PrevPublickKey-
|
||||
* List) and cleared when a Cert is no longer self-issued. PrevPublic-
|
||||
* Key keep key of the previous Cert.
|
||||
*/
|
||||
if (selfIssued == PKIX_TRUE) {
|
||||
|
||||
/* Make sure previous Cert is valid for signature verification */
|
||||
if (state->prevCertCertSign == PKIX_TRUE) {
|
||||
|
||||
if (state->prevPublicKeyList == NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_Create
|
||||
(&state->prevPublicKeyList, plContext),
|
||||
PKIX_LISTCREATEFALIED);
|
||||
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_List_AppendItem
|
||||
(state->prevPublicKeyList,
|
||||
(PKIX_PL_Object *) state->prevPublicKey,
|
||||
plContext),
|
||||
PKIX_LISTAPPENDITEMFAILED);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Not self-issued Cert any more, clear old key(s) saved */
|
||||
PKIX_DECREF(state->prevPublicKeyList);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Save current key as prevPublicKey */
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
|
||||
(cert, &currPubKey, plContext),
|
||||
PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_PublicKey_MakeInheritedDSAPublicKey
|
||||
(currPubKey, prevPubKey, &newPubKey, plContext),
|
||||
PKIX_PUBLICKEYMAKEINHERITEDDSAPUBLICKEYFAILED);
|
||||
|
||||
if (newPubKey == NULL){
|
||||
PKIX_INCREF(currPubKey);
|
||||
newPubKey = currPubKey;
|
||||
}
|
||||
|
||||
PKIX_INCREF(newPubKey);
|
||||
PKIX_DECREF(state->prevPublicKey);
|
||||
|
||||
state->prevPublicKey = newPubKey;
|
||||
|
||||
/* Save this Cert key usage CertSign bit */
|
||||
if (state->certsRemaining != 0) {
|
||||
checkKeyUsageFail = PKIX_PL_Cert_VerifyKeyUsage
|
||||
(cert, PKIX_KEY_CERT_SIGN, plContext);
|
||||
|
||||
state->prevCertCertSign = (checkKeyUsageFail == NULL)?
|
||||
PKIX_TRUE:PKIX_FALSE;
|
||||
|
||||
PKIX_DECREF(checkKeyUsageFail);
|
||||
}
|
||||
|
||||
/* Remove Key Usage Extension OID from list */
|
||||
if (unresolvedCriticalExtensions != NULL) {
|
||||
|
||||
PKIX_CHECK(pkix_List_Remove
|
||||
(unresolvedCriticalExtensions,
|
||||
(PKIX_PL_Object *) state->keyUsageOID,
|
||||
plContext),
|
||||
PKIX_LISTREMOVEFAILED);
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object *)state, plContext),
|
||||
PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
PKIX_DECREF(pKey);
|
||||
PKIX_DECREF(prevPubKey);
|
||||
PKIX_DECREF(currPubKey);
|
||||
PKIX_DECREF(newPubKey);
|
||||
PKIX_DECREF(basicConstraints);
|
||||
PKIX_DECREF(verifyFail);
|
||||
PKIX_DECREF(checkKeyUsageFail);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_SignatureChecker_Initialize
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new CertChainChecker and stores it at "pChecker", where it will
|
||||
* be used by pkix_SignatureChecker_Check to check that the public key in
|
||||
* the checker's state is able to successfully validate the certificate's
|
||||
* signature. The PublicKey pointed to by "trustedPubKey" is used to
|
||||
* initialize the checker's state.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "trustedPubKey"
|
||||
* Address of PublicKey representing the trusted public key used to
|
||||
* initialize the state of this checker. Must be non-NULL.
|
||||
* "certsRemaining"
|
||||
* Number of certificates remaining in the chain.
|
||||
* "pChecker"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_SignatureChecker_Initialize(
|
||||
PKIX_PL_PublicKey *trustedPubKey,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_SignatureCheckerState* state = NULL;
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "PKIX_SignatureChecker_Initialize");
|
||||
PKIX_NULLCHECK_TWO(pChecker, trustedPubKey);
|
||||
|
||||
PKIX_CHECK(pkix_SignatureCheckerState_Create
|
||||
(trustedPubKey, certsRemaining, &state, plContext),
|
||||
PKIX_SIGNATURECHECKERSTATECREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_SignatureChecker_Check,
|
||||
PKIX_FALSE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *) state,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_signaturechecker.h
|
||||
*
|
||||
* Header file for validate signature function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_SIGNATURECHECKER_H
|
||||
#define _PKIX_SIGNATURECHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pkix_SignatureCheckerState pkix_SignatureCheckerState;
|
||||
|
||||
struct pkix_SignatureCheckerState {
|
||||
PKIX_Boolean prevCertCertSign;
|
||||
PKIX_UInt32 certsRemaining;
|
||||
PKIX_PL_PublicKey *prevPublicKey; /* Subject PubKey of last cert */
|
||||
PKIX_List *prevPublicKeyList; /* of PKIX_PL_PublicKey */
|
||||
PKIX_PL_OID *keyUsageOID;
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_SignatureChecker_Initialize(
|
||||
PKIX_PL_PublicKey *trustedPubKey,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_SignatureCheckerState_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_SIGNATURECHECKER_H */
|
||||
516
security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c
Normal file
516
security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_targetcertchecker.c
|
||||
*
|
||||
* Functions for target cert validation
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "pkix_targetcertchecker.h"
|
||||
|
||||
/* --Private-TargetCertCheckerState-Functions------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_TargetCertCheckerState_Destroy
|
||||
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
||||
*/
|
||||
static PKIX_Error *
|
||||
pkix_TargetCertCheckerState_Destroy(
|
||||
PKIX_PL_Object *object,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_TargetCertCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(TARGETCERTCHECKERSTATE,
|
||||
"pkix_TargetCertCheckerState_Destroy");
|
||||
PKIX_NULLCHECK_ONE(object);
|
||||
|
||||
/* Check that this object is a target cert checker state */
|
||||
PKIX_CHECK(pkix_CheckType
|
||||
(object, PKIX_TARGETCERTCHECKERSTATE_TYPE, plContext),
|
||||
PKIX_OBJECTNOTTARGETCERTCHECKERSTATE);
|
||||
|
||||
state = (pkix_TargetCertCheckerState *)object;
|
||||
|
||||
PKIX_DECREF(state->certSelector);
|
||||
PKIX_DECREF(state->extKeyUsageOID);
|
||||
PKIX_DECREF(state->subjAltNameOID);
|
||||
PKIX_DECREF(state->pathToNameList);
|
||||
PKIX_DECREF(state->extKeyUsageList);
|
||||
PKIX_DECREF(state->subjAltNameList);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_RETURN(TARGETCERTCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_TargetCertCheckerState_RegisterSelf
|
||||
* DESCRIPTION:
|
||||
* Registers PKIX_TARGETCERTCHECKERSTATE_TYPE and its related functions with
|
||||
* systemClasses[]
|
||||
* THREAD SAFETY:
|
||||
* Not Thread Safe - for performance and complexity reasons
|
||||
*
|
||||
* Since this function is only called by PKIX_PL_Initialize, which should
|
||||
* only be called once, it is acceptable that this function is not
|
||||
* thread-safe.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_TargetCertCheckerState_RegisterSelf(void *plContext)
|
||||
{
|
||||
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
||||
pkix_ClassTable_Entry entry;
|
||||
|
||||
PKIX_ENTER(TARGETCERTCHECKERSTATE,
|
||||
"pkix_TargetCertCheckerState_RegisterSelf");
|
||||
|
||||
entry.description = "TargetCertCheckerState";
|
||||
entry.objCounter = 0;
|
||||
entry.typeObjectSize = sizeof(pkix_TargetCertCheckerState);
|
||||
entry.destructor = pkix_TargetCertCheckerState_Destroy;
|
||||
entry.equalsFunction = NULL;
|
||||
entry.hashcodeFunction = NULL;
|
||||
entry.toStringFunction = NULL;
|
||||
entry.comparator = NULL;
|
||||
entry.duplicateFunction = NULL;
|
||||
|
||||
systemClasses[PKIX_TARGETCERTCHECKERSTATE_TYPE] = entry;
|
||||
|
||||
PKIX_RETURN(TARGETCERTCHECKERSTATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_TargetCertCheckerState_Create
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new TargetCertCheckerState using the CertSelector pointed to
|
||||
* by "certSelector" and the number of certs represented by "certsRemaining"
|
||||
* and stores it at "pState".
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "certSelector"
|
||||
* Address of CertSelector representing the criteria against which the
|
||||
* final certificate in a chain is to be matched. Must be non-NULL.
|
||||
* "certsRemaining"
|
||||
* Number of certificates remaining in the chain.
|
||||
* "pState"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a TargetCertCheckerState Error if the function fails in a
|
||||
* non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_TargetCertCheckerState_Create(
|
||||
PKIX_CertSelector *certSelector,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
pkix_TargetCertCheckerState **pState,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_TargetCertCheckerState *state = NULL;
|
||||
PKIX_ComCertSelParams *certSelectorParams = NULL;
|
||||
PKIX_List *pathToNameList = NULL;
|
||||
PKIX_List *extKeyUsageList = NULL;
|
||||
PKIX_List *subjAltNameList = NULL;
|
||||
PKIX_PL_OID *extKeyUsageOID = NULL;
|
||||
PKIX_PL_OID *subjAltNameOID = NULL;
|
||||
PKIX_Boolean subjAltNameMatchAll = PKIX_TRUE;
|
||||
|
||||
PKIX_ENTER(TARGETCERTCHECKERSTATE,
|
||||
"pkix_TargetCertCheckerState_Create");
|
||||
PKIX_NULLCHECK_ONE(pState);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_EXTENDEDKEYUSAGE_OID,
|
||||
&extKeyUsageOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_OID_Create
|
||||
(PKIX_CERTSUBJALTNAME_OID,
|
||||
&subjAltNameOID,
|
||||
plContext),
|
||||
PKIX_OIDCREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Object_Alloc
|
||||
(PKIX_TARGETCERTCHECKERSTATE_TYPE,
|
||||
sizeof (pkix_TargetCertCheckerState),
|
||||
(PKIX_PL_Object **)&state,
|
||||
plContext),
|
||||
PKIX_COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT);
|
||||
|
||||
/* initialize fields */
|
||||
|
||||
if (certSelector != NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
|
||||
(certSelector, &certSelectorParams, plContext),
|
||||
PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED);
|
||||
|
||||
if (certSelectorParams != NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
|
||||
(certSelectorParams,
|
||||
&pathToNameList,
|
||||
plContext),
|
||||
PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
|
||||
(certSelectorParams,
|
||||
&extKeyUsageList,
|
||||
plContext),
|
||||
PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
|
||||
(certSelectorParams,
|
||||
&subjAltNameList,
|
||||
plContext),
|
||||
PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
|
||||
(certSelectorParams,
|
||||
&subjAltNameMatchAll,
|
||||
plContext),
|
||||
PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
|
||||
}
|
||||
}
|
||||
|
||||
state->certsRemaining = certsRemaining;
|
||||
state->subjAltNameMatchAll = subjAltNameMatchAll;
|
||||
|
||||
PKIX_INCREF(certSelector);
|
||||
state->certSelector = certSelector;
|
||||
|
||||
state->pathToNameList = pathToNameList;
|
||||
pathToNameList = NULL;
|
||||
|
||||
state->extKeyUsageList = extKeyUsageList;
|
||||
extKeyUsageList = NULL;
|
||||
|
||||
state->subjAltNameList = subjAltNameList;
|
||||
subjAltNameList = NULL;
|
||||
|
||||
state->extKeyUsageOID = extKeyUsageOID;
|
||||
extKeyUsageOID = NULL;
|
||||
|
||||
state->subjAltNameOID = subjAltNameOID;
|
||||
subjAltNameOID = NULL;
|
||||
|
||||
*pState = state;
|
||||
state = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(extKeyUsageOID);
|
||||
PKIX_DECREF(subjAltNameOID);
|
||||
PKIX_DECREF(pathToNameList);
|
||||
PKIX_DECREF(extKeyUsageList);
|
||||
PKIX_DECREF(subjAltNameList);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_DECREF(certSelectorParams);
|
||||
|
||||
PKIX_RETURN(TARGETCERTCHECKERSTATE);
|
||||
|
||||
}
|
||||
|
||||
/* --Private-TargetCertChecker-Functions------------------------------- */
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_TargetCertChecker_Check
|
||||
* (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_TargetCertChecker_Check(
|
||||
PKIX_CertChainChecker *checker,
|
||||
PKIX_PL_Cert *cert,
|
||||
PKIX_List *unresolvedCriticalExtensions,
|
||||
void **pNBIOContext,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_TargetCertCheckerState *state = NULL;
|
||||
PKIX_CertSelector_MatchCallback certSelectorMatch = NULL;
|
||||
PKIX_PL_CertNameConstraints *nameConstraints = NULL;
|
||||
PKIX_List *certSubjAltNames = NULL;
|
||||
PKIX_List *certExtKeyUsageList = NULL;
|
||||
PKIX_PL_GeneralName *name = NULL;
|
||||
PKIX_PL_X500Name *certSubjectName = NULL;
|
||||
PKIX_Boolean checkPassed = PKIX_FALSE;
|
||||
PKIX_UInt32 numItems, i;
|
||||
PKIX_UInt32 matchCount = 0;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Check");
|
||||
PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
|
||||
|
||||
*pNBIOContext = NULL; /* we never block on pending I/O */
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
|
||||
(checker, (PKIX_PL_Object **)&state, plContext),
|
||||
PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
|
||||
|
||||
(state->certsRemaining)--;
|
||||
|
||||
if (state->pathToNameList != NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
|
||||
(cert, &nameConstraints, plContext),
|
||||
PKIX_CERTGETNAMECONSTRAINTSFAILED);
|
||||
|
||||
/*
|
||||
* XXX We should either make the following call a public one
|
||||
* so it is legal to call from the portability layer or we
|
||||
* should try to create pathToNameList as CertNameConstraints
|
||||
* then call the existing check function.
|
||||
*/
|
||||
PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
|
||||
(state->pathToNameList,
|
||||
nameConstraints,
|
||||
&checkPassed,
|
||||
plContext),
|
||||
PKIX_CERTNAMECONSTRAINTSCHECKNAMEINNAMESPACEFAILED);
|
||||
|
||||
if (checkPassed != PKIX_TRUE) {
|
||||
PKIX_ERROR(PKIX_VALIDATIONFAILEDPATHTONAMECHECKFAILED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
|
||||
(cert, &certSubjAltNames, plContext),
|
||||
PKIX_CERTGETSUBJALTNAMESFAILED);
|
||||
|
||||
if (state->subjAltNameList != NULL && certSubjAltNames != NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_GetLength
|
||||
(state->subjAltNameList, &numItems, plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
|
||||
for (i = 0; i < numItems; i++) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_GetItem
|
||||
(state->subjAltNameList,
|
||||
i,
|
||||
(PKIX_PL_Object **) &name,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(pkix_List_Contains
|
||||
(certSubjAltNames,
|
||||
(PKIX_PL_Object *) name,
|
||||
&checkPassed,
|
||||
plContext),
|
||||
PKIX_LISTCONTAINSFAILED);
|
||||
|
||||
PKIX_DECREF(name);
|
||||
|
||||
if (checkPassed == PKIX_TRUE) {
|
||||
|
||||
if (state->subjAltNameMatchAll == PKIX_FALSE) {
|
||||
matchCount = numItems;
|
||||
break;
|
||||
} else {
|
||||
/* else continue checking next */
|
||||
matchCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (matchCount != numItems) {
|
||||
PKIX_ERROR(PKIX_SUBJALTNAMECHECKFAILED);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (state->certsRemaining == 0) {
|
||||
|
||||
if (state->certSelector != NULL) {
|
||||
PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
|
||||
(state->certSelector,
|
||||
&certSelectorMatch,
|
||||
plContext),
|
||||
PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
|
||||
|
||||
PKIX_CHECK(certSelectorMatch
|
||||
(state->certSelector,
|
||||
cert,
|
||||
plContext),
|
||||
PKIX_CERTSELECTORMATCHFAILED);
|
||||
} else {
|
||||
/* Check at least cert/key usages if target cert selector
|
||||
* is not set. */
|
||||
PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert,
|
||||
PKIX_FALSE /* is chain cert*/,
|
||||
plContext),
|
||||
PKIX_CERTVERIFYCERTTYPEFAILED);
|
||||
}
|
||||
/*
|
||||
* There are two Extended Key Usage Checkings
|
||||
* available :
|
||||
* 1) here at the targetcertchecker where we
|
||||
* verify the Extended Key Usage OIDs application
|
||||
* specifies via ComCertSelParams are included
|
||||
* in Cert's Extended Key Usage OID's. Note,
|
||||
* this is an OID to OID comparison and only last
|
||||
* Cert is checked.
|
||||
* 2) at user defined ekuchecker where checking
|
||||
* is applied to all Certs on the chain and
|
||||
* the NSS Extended Key Usage algorithm is
|
||||
* used. In order to invoke this checking, not
|
||||
* only does the ComCertSelparams needs to be
|
||||
* set, the EKU initialize call is required to
|
||||
* activate the checking.
|
||||
*
|
||||
* XXX We use the same ComCertSelParams Set/Get
|
||||
* functions to set the parameters for both cases.
|
||||
* We may want to separate them in the future.
|
||||
*/
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
|
||||
(cert, &certExtKeyUsageList, plContext),
|
||||
PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
|
||||
|
||||
|
||||
if (state->extKeyUsageList != NULL &&
|
||||
certExtKeyUsageList != NULL) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_GetLength
|
||||
(state->extKeyUsageList, &numItems, plContext),
|
||||
PKIX_LISTGETLENGTHFAILED);
|
||||
|
||||
for (i = 0; i < numItems; i++) {
|
||||
|
||||
PKIX_CHECK(PKIX_List_GetItem
|
||||
(state->extKeyUsageList,
|
||||
i,
|
||||
(PKIX_PL_Object **) &name,
|
||||
plContext),
|
||||
PKIX_LISTGETITEMFAILED);
|
||||
|
||||
PKIX_CHECK(pkix_List_Contains
|
||||
(certExtKeyUsageList,
|
||||
(PKIX_PL_Object *) name,
|
||||
&checkPassed,
|
||||
plContext),
|
||||
PKIX_LISTCONTAINSFAILED);
|
||||
|
||||
PKIX_DECREF(name);
|
||||
|
||||
if (checkPassed != PKIX_TRUE) {
|
||||
PKIX_ERROR
|
||||
(PKIX_EXTENDEDKEYUSAGECHECKINGFAILED);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Check key usage and cert type based on certificate usage. */
|
||||
PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_TRUE,
|
||||
plContext),
|
||||
PKIX_CERTVERIFYCERTTYPEFAILED);
|
||||
}
|
||||
|
||||
/* Remove Critical Extension OID from list */
|
||||
if (unresolvedCriticalExtensions != NULL) {
|
||||
|
||||
PKIX_CHECK(pkix_List_Remove
|
||||
(unresolvedCriticalExtensions,
|
||||
(PKIX_PL_Object *) state->extKeyUsageOID,
|
||||
plContext),
|
||||
PKIX_LISTREMOVEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_PL_Cert_GetSubject
|
||||
(cert, &certSubjectName, plContext),
|
||||
PKIX_CERTGETSUBJECTFAILED);
|
||||
|
||||
if (certSubjAltNames != NULL) {
|
||||
PKIX_CHECK(pkix_List_Remove
|
||||
(unresolvedCriticalExtensions,
|
||||
(PKIX_PL_Object *) state->subjAltNameOID,
|
||||
plContext),
|
||||
PKIX_LISTREMOVEFAILED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(name);
|
||||
PKIX_DECREF(nameConstraints);
|
||||
PKIX_DECREF(certSubjAltNames);
|
||||
PKIX_DECREF(certExtKeyUsageList);
|
||||
PKIX_DECREF(certSubjectName);
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: pkix_TargetCertChecker_Initialize
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates a new CertChainChecker and stores it at "pChecker", where it will
|
||||
* used by pkix_TargetCertChecker_Check to check that the final certificate
|
||||
* of a chain meets the criteria of the CertSelector pointed to by
|
||||
* "certSelector". The number of certs remaining in the chain, represented by
|
||||
* "certsRemaining" is used to initialize the checker's state.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "certSelector"
|
||||
* Address of CertSelector representing the criteria against which the
|
||||
* final certificate in a chain is to be matched. May be NULL.
|
||||
* "certsRemaining"
|
||||
* Number of certificates remaining in the chain.
|
||||
* "pChecker"
|
||||
* Address where object pointer will be stored. Must be non-NULL.
|
||||
* "plContext"
|
||||
* Platform-specific context pointer.
|
||||
* THREAD SAFETY:
|
||||
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
||||
* RETURNS:
|
||||
* Returns NULL if the function succeeds.
|
||||
* Returns a CertChainChecker Error if the function fails in a non-fatal way.
|
||||
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
||||
*/
|
||||
PKIX_Error *
|
||||
pkix_TargetCertChecker_Initialize(
|
||||
PKIX_CertSelector *certSelector,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext)
|
||||
{
|
||||
pkix_TargetCertCheckerState *state = NULL;
|
||||
|
||||
PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Initialize");
|
||||
PKIX_NULLCHECK_ONE(pChecker);
|
||||
|
||||
PKIX_CHECK(pkix_TargetCertCheckerState_Create
|
||||
(certSelector, certsRemaining, &state, plContext),
|
||||
PKIX_TARGETCERTCHECKERSTATECREATEFAILED);
|
||||
|
||||
PKIX_CHECK(PKIX_CertChainChecker_Create
|
||||
(pkix_TargetCertChecker_Check,
|
||||
PKIX_FALSE,
|
||||
PKIX_FALSE,
|
||||
NULL,
|
||||
(PKIX_PL_Object *)state,
|
||||
pChecker,
|
||||
plContext),
|
||||
PKIX_CERTCHAINCHECKERCREATEFAILED);
|
||||
|
||||
cleanup:
|
||||
|
||||
PKIX_DECREF(state);
|
||||
|
||||
PKIX_RETURN(CERTCHAINCHECKER);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* pkix_targetcertchecker.h
|
||||
*
|
||||
* Header file for validate target cert function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKIX_TARGETCERTCHECKER_H
|
||||
#define _PKIX_TARGETCERTCHECKER_H
|
||||
|
||||
#include "pkix_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct pkix_TargetCertCheckerState pkix_TargetCertCheckerState;
|
||||
|
||||
struct pkix_TargetCertCheckerState {
|
||||
PKIX_CertSelector *certSelector;
|
||||
PKIX_List *pathToNameList;
|
||||
PKIX_List *extKeyUsageList; /* List of PKIX_PL_OID */
|
||||
PKIX_List *subjAltNameList;
|
||||
PKIX_Boolean subjAltNameMatchAll;
|
||||
PKIX_UInt32 certsRemaining;
|
||||
PKIX_PL_OID *extKeyUsageOID;
|
||||
PKIX_PL_OID *subjAltNameOID;
|
||||
};
|
||||
|
||||
PKIX_Error *
|
||||
pkix_TargetCertChecker_Initialize(
|
||||
PKIX_CertSelector *certSelector,
|
||||
PKIX_UInt32 certsRemaining,
|
||||
PKIX_CertChainChecker **pChecker,
|
||||
void *plContext);
|
||||
|
||||
PKIX_Error *
|
||||
pkix_TargetCertCheckerState_RegisterSelf(void *plContext);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PKIX_TARGETCERTCHECKER_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue