|
Packit |
40b132 |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
40b132 |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
40b132 |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* pkix_pl_infoaccess.c
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* InfoAccess Object Definitions
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
#include "pkix_pl_infoaccess.h"
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* --Private-InfoAccess-Functions----------------------------------*/
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_Create
|
|
Packit |
40b132 |
* DESCRIPTION:
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* This function creates an InfoAccess from the method provided in "method" and
|
|
Packit |
40b132 |
* the GeneralName provided in "generalName" and stores the result at
|
|
Packit |
40b132 |
* "pInfoAccess".
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* PARAMETERS
|
|
Packit |
40b132 |
* "method"
|
|
Packit |
40b132 |
* The UInt32 value to be stored as the method field of the InfoAccess.
|
|
Packit |
40b132 |
* "generalName"
|
|
Packit |
40b132 |
* The GeneralName to be stored as the generalName field of the InfoAccess.
|
|
Packit |
40b132 |
* Must be non-NULL.
|
|
Packit |
40b132 |
* "pInfoAccess"
|
|
Packit |
40b132 |
* Address where the result is stored. Must be non-NULL.
|
|
Packit |
40b132 |
* "plContext"
|
|
Packit |
40b132 |
* Platform-specific context pointer.
|
|
Packit |
40b132 |
* THREAD SAFETY:
|
|
Packit |
40b132 |
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
|
Packit |
40b132 |
* RETURNS:
|
|
Packit |
40b132 |
* Returns NULL if the function succeeds.
|
|
Packit |
40b132 |
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_Create(
|
|
Packit |
40b132 |
PKIX_UInt32 method,
|
|
Packit |
40b132 |
PKIX_PL_GeneralName *generalName,
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess **pInfoAccess,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Create");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(generalName, pInfoAccess);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_Object_Alloc
|
|
Packit |
40b132 |
(PKIX_INFOACCESS_TYPE,
|
|
Packit |
40b132 |
sizeof (PKIX_PL_InfoAccess),
|
|
Packit |
40b132 |
(PKIX_PL_Object **)&infoAccess,
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_COULDNOTCREATEINFOACCESSOBJECT);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
infoAccess->method = method;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_INCREF(generalName);
|
|
Packit |
40b132 |
infoAccess->location = generalName;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pInfoAccess = infoAccess;
|
|
Packit |
40b132 |
infoAccess = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
PKIX_DECREF(infoAccess);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_Destroy
|
|
Packit |
40b132 |
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_Destroy(
|
|
Packit |
40b132 |
PKIX_PL_Object *object,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Destroy");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_ONE(object);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_CheckType(object, PKIX_INFOACCESS_TYPE, plContext),
|
|
Packit |
40b132 |
PKIX_OBJECTNOTANINFOACCESS);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
infoAccess = (PKIX_PL_InfoAccess *)object;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_DECREF(infoAccess->location);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_ToString
|
|
Packit |
40b132 |
* (see comments for PKIX_PL_ToStringCallback in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_ToString(
|
|
Packit |
40b132 |
PKIX_PL_Object *object,
|
|
Packit |
40b132 |
PKIX_PL_String **pString,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess;
|
|
Packit |
40b132 |
PKIX_PL_String *infoAccessString = NULL;
|
|
Packit |
40b132 |
char *asciiFormat = NULL;
|
|
Packit |
40b132 |
char *asciiMethod = NULL;
|
|
Packit |
40b132 |
PKIX_PL_String *formatString = NULL;
|
|
Packit |
40b132 |
PKIX_PL_String *methodString = NULL;
|
|
Packit |
40b132 |
PKIX_PL_String *locationString = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ToString");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(object, pString);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_CheckType
|
|
Packit |
40b132 |
(object, PKIX_INFOACCESS_TYPE, plContext),
|
|
Packit |
40b132 |
PKIX_OBJECTNOTINFOACCESS);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
infoAccess = (PKIX_PL_InfoAccess *)object;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
asciiFormat =
|
|
Packit |
40b132 |
"["
|
|
Packit |
40b132 |
"method:%s, "
|
|
Packit |
40b132 |
"location:%s"
|
|
Packit |
40b132 |
"]";
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_String_Create
|
|
Packit |
40b132 |
(PKIX_ESCASCII,
|
|
Packit |
40b132 |
asciiFormat,
|
|
Packit |
40b132 |
0,
|
|
Packit |
40b132 |
&formatString,
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_STRINGCREATEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
switch(infoAccess->method) {
|
|
Packit |
40b132 |
case PKIX_INFOACCESS_CA_ISSUERS:
|
|
Packit |
40b132 |
asciiMethod = "caIssuers";
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case PKIX_INFOACCESS_OCSP:
|
|
Packit |
40b132 |
asciiMethod = "ocsp";
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case PKIX_INFOACCESS_TIMESTAMPING:
|
|
Packit |
40b132 |
asciiMethod = "timestamping";
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case PKIX_INFOACCESS_CA_REPOSITORY:
|
|
Packit |
40b132 |
asciiMethod = "caRepository";
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
default:
|
|
Packit |
40b132 |
asciiMethod = "unknown";
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_String_Create
|
|
Packit |
40b132 |
(PKIX_ESCASCII,
|
|
Packit |
40b132 |
asciiMethod,
|
|
Packit |
40b132 |
0,
|
|
Packit |
40b132 |
&methodString,
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_STRINGCREATEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
|
|
Packit |
40b132 |
PKIX_GENERALNAMETOSTRINGFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_Sprintf
|
|
Packit |
40b132 |
(&infoAccessString,
|
|
Packit |
40b132 |
plContext,
|
|
Packit |
40b132 |
formatString,
|
|
Packit |
40b132 |
methodString,
|
|
Packit |
40b132 |
locationString),
|
|
Packit |
40b132 |
PKIX_SPRINTFFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pString = infoAccessString;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_DECREF(formatString);
|
|
Packit |
40b132 |
PKIX_DECREF(methodString);
|
|
Packit |
40b132 |
PKIX_DECREF(locationString);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_Hashcode
|
|
Packit |
40b132 |
* (see comments for PKIX_PL_HashcodeCallback in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_Hashcode(
|
|
Packit |
40b132 |
PKIX_PL_Object *object,
|
|
Packit |
40b132 |
PKIX_UInt32 *pHashcode,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess = NULL;
|
|
Packit |
40b132 |
PKIX_UInt32 infoAccessHash;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Hashcode");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(object, pHashcode);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_CheckType
|
|
Packit |
40b132 |
(object, PKIX_INFOACCESS_TYPE, plContext),
|
|
Packit |
40b132 |
PKIX_OBJECTNOTINFOACCESS);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
infoAccess = (PKIX_PL_InfoAccess *)object;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_HASHCODE(infoAccess->location, &infoAccessHash, plContext,
|
|
Packit |
40b132 |
PKIX_OBJECTHASHCODEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
infoAccessHash += (infoAccess->method << 7);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pHashcode = infoAccessHash;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_Equals
|
|
Packit |
40b132 |
* (see comments for PKIX_PL_Equals_Callback in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_Equals(
|
|
Packit |
40b132 |
PKIX_PL_Object *firstObject,
|
|
Packit |
40b132 |
PKIX_PL_Object *secondObject,
|
|
Packit |
40b132 |
PKIX_Boolean *pResult,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *firstInfoAccess = NULL;
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *secondInfoAccess = NULL;
|
|
Packit |
40b132 |
PKIX_UInt32 secondType;
|
|
Packit |
40b132 |
PKIX_Boolean cmpResult;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Equals");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* test that firstObject is a InfoAccess */
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_CheckType
|
|
Packit |
40b132 |
(firstObject, PKIX_INFOACCESS_TYPE, plContext),
|
|
Packit |
40b132 |
PKIX_FIRSTOBJECTNOTINFOACCESS);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* Since we know firstObject is a InfoAccess, if both references are
|
|
Packit |
40b132 |
* identical, they must be equal
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
if (firstObject == secondObject){
|
|
Packit |
40b132 |
*pResult = PKIX_TRUE;
|
|
Packit |
40b132 |
goto cleanup;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* If secondObject isn't a InfoAccess, we don't throw an error.
|
|
Packit |
40b132 |
* We simply return a Boolean result of FALSE
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
*pResult = PKIX_FALSE;
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_Object_GetType
|
|
Packit |
40b132 |
(secondObject, &secondType, plContext),
|
|
Packit |
40b132 |
PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
|
|
Packit |
40b132 |
if (secondType != PKIX_INFOACCESS_TYPE) goto cleanup;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
firstInfoAccess = (PKIX_PL_InfoAccess *)firstObject;
|
|
Packit |
40b132 |
secondInfoAccess = (PKIX_PL_InfoAccess *)secondObject;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pResult = PKIX_FALSE;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (firstInfoAccess->method != secondInfoAccess->method) {
|
|
Packit |
40b132 |
goto cleanup;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_EQUALS(firstInfoAccess, secondInfoAccess, &cmpResult, plContext,
|
|
Packit |
40b132 |
PKIX_OBJECTEQUALSFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pResult = cmpResult;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_RegisterSelf
|
|
Packit |
40b132 |
* DESCRIPTION:
|
|
Packit |
40b132 |
* Registers PKIX_INFOACCESS_TYPE and its related functions with systemClasses[]
|
|
Packit |
40b132 |
* THREAD SAFETY:
|
|
Packit |
40b132 |
* Not Thread Safe - for performance and complexity reasons
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* Since this function is only called by PKIX_PL_Initialize, which should
|
|
Packit |
40b132 |
* only be called once, it is acceptable that this function is not
|
|
Packit |
40b132 |
* thread-safe.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_RegisterSelf(void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
|
Packit |
40b132 |
pkix_ClassTable_Entry entry;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS,
|
|
Packit |
40b132 |
"pkix_pl_InfoAccess_RegisterSelf");
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
entry.description = "InfoAccess";
|
|
Packit |
40b132 |
entry.objCounter = 0;
|
|
Packit |
40b132 |
entry.typeObjectSize = sizeof(PKIX_PL_InfoAccess);
|
|
Packit |
40b132 |
entry.destructor = pkix_pl_InfoAccess_Destroy;
|
|
Packit |
40b132 |
entry.equalsFunction = pkix_pl_InfoAccess_Equals;
|
|
Packit |
40b132 |
entry.hashcodeFunction = pkix_pl_InfoAccess_Hashcode;
|
|
Packit |
40b132 |
entry.toStringFunction = pkix_pl_InfoAccess_ToString;
|
|
Packit |
40b132 |
entry.comparator = NULL;
|
|
Packit |
40b132 |
entry.duplicateFunction = pkix_duplicateImmutable;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
systemClasses[PKIX_INFOACCESS_TYPE] = entry;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_CreateList
|
|
Packit |
40b132 |
* DESCRIPTION:
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* Based on data in CERTAuthInfoAccess array "nssInfoAccess", this function
|
|
Packit |
40b132 |
* creates and returns a PKIX_List of PKIX_PL_InfoAccess at "pInfoAccessList".
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* PARAMETERS
|
|
Packit |
40b132 |
* "nssInfoAccess"
|
|
Packit |
40b132 |
* The pointer array of CERTAuthInfoAccess that contains access data.
|
|
Packit |
40b132 |
* May be NULL.
|
|
Packit |
40b132 |
* "pInfoAccessList"
|
|
Packit |
40b132 |
* Address where a list of PKIX_PL_InfoAccess is returned.
|
|
Packit |
40b132 |
* Must be non-NULL.
|
|
Packit |
40b132 |
* "plContext"
|
|
Packit |
40b132 |
* Platform-specific context pointer.
|
|
Packit |
40b132 |
* THREAD SAFETY:
|
|
Packit |
40b132 |
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
|
Packit |
40b132 |
* RETURNS:
|
|
Packit |
40b132 |
* Returns NULL if the function succeeds.
|
|
Packit |
40b132 |
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_CreateList(
|
|
Packit |
40b132 |
CERTAuthInfoAccess **nssInfoAccess,
|
|
Packit |
40b132 |
PKIX_List **pInfoAccessList, /* of PKIX_PL_InfoAccess */
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_List *infoAccessList = NULL;
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess = NULL;
|
|
Packit |
40b132 |
PKIX_PL_GeneralName *location = NULL;
|
|
Packit |
40b132 |
PKIX_UInt32 method;
|
|
Packit |
40b132 |
int i;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_CreateList");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_ONE(pInfoAccessList);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_List_Create(&infoAccessList, plContext),
|
|
Packit |
40b132 |
PKIX_LISTCREATEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (nssInfoAccess == NULL) {
|
|
Packit |
40b132 |
goto cleanup;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
for (i = 0; nssInfoAccess[i] != NULL; i++) {
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (nssInfoAccess[i]->location == NULL) {
|
|
Packit |
40b132 |
continue;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_pl_GeneralName_Create
|
|
Packit |
40b132 |
(nssInfoAccess[i]->location, &location, plContext),
|
|
Packit |
40b132 |
PKIX_GENERALNAMECREATEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CERT_DEBUG("\t\tCalling SECOID_FindOIDTag).\n");
|
|
Packit |
40b132 |
method = SECOID_FindOIDTag(&nssInfoAccess[i]->method);
|
|
Packit |
40b132 |
/* Map NSS access method value into PKIX constant */
|
|
Packit |
40b132 |
switch(method) {
|
|
Packit |
40b132 |
case SEC_OID_PKIX_CA_ISSUERS:
|
|
Packit |
40b132 |
method = PKIX_INFOACCESS_CA_ISSUERS;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case SEC_OID_PKIX_OCSP:
|
|
Packit |
40b132 |
method = PKIX_INFOACCESS_OCSP;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case SEC_OID_PKIX_TIMESTAMPING:
|
|
Packit |
40b132 |
method = PKIX_INFOACCESS_TIMESTAMPING;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
case SEC_OID_PKIX_CA_REPOSITORY:
|
|
Packit |
40b132 |
method = PKIX_INFOACCESS_CA_REPOSITORY;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
default:
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_UNKNOWNINFOACCESSMETHOD);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_pl_InfoAccess_Create
|
|
Packit |
40b132 |
(method, location, &infoAccess, plContext),
|
|
Packit |
40b132 |
PKIX_INFOACCESSCREATEFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_List_AppendItem
|
|
Packit |
40b132 |
(infoAccessList,
|
|
Packit |
40b132 |
(PKIX_PL_Object *)infoAccess,
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_LISTAPPENDITEMFAILED);
|
|
Packit |
40b132 |
PKIX_DECREF(infoAccess);
|
|
Packit |
40b132 |
PKIX_DECREF(location);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pInfoAccessList = infoAccessList;
|
|
Packit |
40b132 |
infoAccessList = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_DECREF(infoAccessList);
|
|
Packit |
40b132 |
PKIX_DECREF(infoAccess);
|
|
Packit |
40b132 |
PKIX_DECREF(location);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* --Public-Functions------------------------------------------------------- */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: PKIX_PL_InfoAccess_GetMethod (see comments in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess_GetMethod(
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess,
|
|
Packit |
40b132 |
PKIX_UInt32 *pMethod,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetMethod");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(infoAccess, pMethod);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pMethod = infoAccess->method;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: PKIX_PL_InfoAccess_GetLocation (see comments in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess_GetLocation(
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess,
|
|
Packit |
40b132 |
PKIX_PL_GeneralName **pLocation,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocation");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(infoAccess, pLocation);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_INCREF(infoAccess->location);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pLocation = infoAccess->location;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: PKIX_PL_InfoAccess_GetLocationType (see comments in pkix_pl_pki.h)
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess_GetLocationType(
|
|
Packit |
40b132 |
PKIX_PL_InfoAccess *infoAccess,
|
|
Packit |
40b132 |
PKIX_UInt32 *pType,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_String *locationString = NULL;
|
|
Packit |
40b132 |
PKIX_UInt32 type = PKIX_INFOACCESS_LOCATION_UNKNOWN;
|
|
Packit |
40b132 |
PKIX_UInt32 len = 0;
|
|
Packit |
40b132 |
void *location = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocationType");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_TWO(infoAccess, pType);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (infoAccess->location != NULL) {
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
|
|
Packit |
40b132 |
PKIX_GENERALNAMETOSTRINGFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_String_GetEncoded
|
|
Packit |
40b132 |
(locationString, PKIX_ESCASCII, &location, &len, plContext),
|
|
Packit |
40b132 |
PKIX_STRINGGETENCODEDFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_OID_DEBUG("\tCalling PORT_Strcmp).\n");
|
|
Packit |
40b132 |
#ifndef NSS_PKIX_NO_LDAP
|
|
Packit |
40b132 |
if (PORT_Strncmp(location, "ldap:", 5) == 0){
|
|
Packit |
40b132 |
type = PKIX_INFOACCESS_LOCATION_LDAP;
|
|
Packit |
40b132 |
} else
|
|
Packit |
40b132 |
#endif
|
|
Packit |
40b132 |
if (PORT_Strncmp(location, "http:", 5) == 0){
|
|
Packit |
40b132 |
type = PKIX_INFOACCESS_LOCATION_HTTP;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pType = type;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_PL_Free(location, plContext);
|
|
Packit |
40b132 |
PKIX_DECREF(locationString);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
#ifndef NSS_PKIX_NO_LDAP
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_ParseTokens
|
|
Packit |
40b132 |
* DESCRIPTION:
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* This function parses the string beginning at "startPos" into tokens using
|
|
Packit |
40b132 |
* the separator contained in "separator" and the terminator contained in
|
|
Packit |
40b132 |
* "terminator", copying the tokens into space allocated from the arena
|
|
Packit |
40b132 |
* pointed to by "arena". It stores in "tokens" a null-terminated array of
|
|
Packit |
40b132 |
* pointers to those tokens.
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* PARAMETERS
|
|
Packit |
40b132 |
* "arena"
|
|
Packit |
40b132 |
* Address of a PLArenaPool to be used in populating the LDAPLocation.
|
|
Packit |
40b132 |
* Must be non-NULL.
|
|
Packit |
40b132 |
* "startPos"
|
|
Packit |
40b132 |
* The address of char string that contains a subset of ldap location.
|
|
Packit |
40b132 |
* "tokens"
|
|
Packit |
40b132 |
* The address of an array of char string for storing returned tokens.
|
|
Packit |
40b132 |
* Must be non-NULL.
|
|
Packit |
40b132 |
* "separator"
|
|
Packit |
40b132 |
* The character that is taken as token separator. Must be non-NULL.
|
|
Packit |
40b132 |
* "terminator"
|
|
Packit |
40b132 |
* The character that is taken as parsing terminator. Must be non-NULL.
|
|
Packit |
40b132 |
* "plContext"
|
|
Packit |
40b132 |
* Platform-specific context pointer.
|
|
Packit |
40b132 |
* THREAD SAFETY:
|
|
Packit |
40b132 |
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
|
Packit |
40b132 |
* RETURNS:
|
|
Packit |
40b132 |
* Returns NULL if the function succeeds.
|
|
Packit |
40b132 |
* Returns an InfoAccess Error if the function fails in a non-fatal way.
|
|
Packit |
40b132 |
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_ParseTokens(
|
|
Packit |
40b132 |
PLArenaPool *arena,
|
|
Packit |
40b132 |
char **startPos, /* return update */
|
|
Packit |
40b132 |
char ***tokens,
|
|
Packit |
40b132 |
char separator,
|
|
Packit |
40b132 |
char terminator,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_UInt32 numFilters = 0;
|
|
Packit |
40b132 |
char *endPos = NULL;
|
|
Packit |
40b132 |
char **filterP = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseTokens");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_THREE(arena, startPos, tokens);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
endPos = *startPos;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* First pass: parse to <terminator> to count number of components */
|
|
Packit |
40b132 |
numFilters = 0;
|
|
Packit |
40b132 |
while (*endPos != terminator && *endPos != '\0') {
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
if (*endPos == separator) {
|
|
Packit |
40b132 |
numFilters++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (*endPos != terminator) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_LOCATIONSTRINGNOTPROPERLYTERMINATED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Last component doesn't need a separator, although we allow it */
|
|
Packit |
40b132 |
if (endPos > *startPos && *(endPos-1) != separator) {
|
|
Packit |
40b132 |
numFilters++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* If string is a=xx, b=yy, c=zz, etc., use a=xx for filter,
|
|
Packit |
40b132 |
* and everything else for the base
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
if (numFilters > 2) numFilters = 2;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
filterP = PORT_ArenaZNewArray(arena, char*, numFilters+1);
|
|
Packit |
40b132 |
if (filterP == NULL) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Second pass: parse to fill in components in token array */
|
|
Packit |
40b132 |
*tokens = filterP;
|
|
Packit |
40b132 |
endPos = *startPos;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
while (numFilters) {
|
|
Packit |
40b132 |
if (*endPos == separator || *endPos == terminator) {
|
|
Packit |
40b132 |
PKIX_UInt32 len = endPos - *startPos;
|
|
Packit |
40b132 |
char *p = PORT_ArenaZAlloc(arena, len+1);
|
|
Packit |
40b132 |
if (p == NULL) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PORT_Memcpy(p, *startPos, len);
|
|
Packit |
40b132 |
p[len] = '\0';
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*filterP = p;
|
|
Packit |
40b132 |
filterP++;
|
|
Packit |
40b132 |
numFilters--;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
separator = terminator;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (*endPos == '\0') {
|
|
Packit |
40b132 |
*startPos = endPos;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
} else {
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
*startPos = endPos;
|
|
Packit |
40b132 |
continue;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*filterP = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
static int
|
|
Packit |
40b132 |
pkix_pl_HexDigitToInt(
|
|
Packit |
40b132 |
int ch)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
if (isdigit(ch)) {
|
|
Packit |
40b132 |
ch = ch - '0';
|
|
Packit |
40b132 |
} else if (isupper(ch)) {
|
|
Packit |
40b132 |
ch = ch - 'A' + 10;
|
|
Packit |
40b132 |
} else {
|
|
Packit |
40b132 |
ch = ch - 'a' + 10;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
return ch;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* Convert the "%" hex hex escape sequences in the URL 'location' in place.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
static void
|
|
Packit |
40b132 |
pkix_pl_UnescapeURL(
|
|
Packit |
40b132 |
char *location)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
const char *src;
|
|
Packit |
40b132 |
char *dst;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
for (src = dst = location; *src != '\0'; src++, dst++) {
|
|
Packit |
40b132 |
if (*src == '%' && isxdigit((unsigned char)*(src+1)) &&
|
|
Packit |
40b132 |
isxdigit((unsigned char)*(src+2))) {
|
|
Packit |
40b132 |
*dst = pkix_pl_HexDigitToInt((unsigned char)*(src+1));
|
|
Packit |
40b132 |
*dst *= 16;
|
|
Packit |
40b132 |
*dst += pkix_pl_HexDigitToInt((unsigned char)*(src+2));
|
|
Packit |
40b132 |
src += 2;
|
|
Packit |
40b132 |
} else {
|
|
Packit |
40b132 |
*dst = *src;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
*dst = *src; /* the terminating null */
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* FUNCTION: pkix_pl_InfoAccess_ParseLocation
|
|
Packit |
40b132 |
* DESCRIPTION:
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* This function parses the GeneralName pointed to by "generalName" into the
|
|
Packit |
40b132 |
* fields of the LDAPRequestParams pointed to by "request" and a domainName
|
|
Packit |
40b132 |
* pointed to by "pDomainName", using the PLArenaPool pointed to by "arena" to
|
|
Packit |
40b132 |
* allocate storage for the request components and for the domainName string.
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* The expected GeneralName string should be in the format described by the
|
|
Packit |
40b132 |
* following BNF:
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* ldap://<ldap-server-site>/[cn=<cname>][,o=<org>][,c=<country>]?
|
|
Packit |
40b132 |
* [caCertificate|crossCertificatPair|certificateRevocationList];
|
|
Packit |
40b132 |
* [binary|<other-type>]
|
|
Packit |
40b132 |
* [[,caCertificate|crossCertificatPair|certificateRevocationList]
|
|
Packit |
40b132 |
* [binary|<other-type>]]*
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* PARAMETERS
|
|
Packit |
40b132 |
* "generalName"
|
|
Packit |
40b132 |
* Address of the GeneralName whose LDAPLocation is to be parsed. Must be
|
|
Packit |
40b132 |
* non-NULL.
|
|
Packit |
40b132 |
* "arena"
|
|
Packit |
40b132 |
* Address of PLArenaPool to be used for the domainName and for components
|
|
Packit |
40b132 |
* of the LDAPRequest. Must be non-NULL.
|
|
Packit |
40b132 |
* "request"
|
|
Packit |
40b132 |
* Address of the LDAPRequestParams into which request components are
|
|
Packit |
40b132 |
* stored. Must be non-NULL.
|
|
Packit |
40b132 |
* *pDomainName"
|
|
Packit |
40b132 |
* Address at which the domainName is stored. Must be non-NULL.
|
|
Packit |
40b132 |
* "plContext"
|
|
Packit |
40b132 |
* Platform-specific context pointer.
|
|
Packit |
40b132 |
* THREAD SAFETY:
|
|
Packit |
40b132 |
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
|
Packit |
40b132 |
* RETURNS:
|
|
Packit |
40b132 |
* Returns NULL if the function succeeds.
|
|
Packit |
40b132 |
* Returns an InfoAccess Error if the function fails in a non-fatal way.
|
|
Packit |
40b132 |
* Returns a Fatal Error if the function fails in an unrecoverable way.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
PKIX_Error *
|
|
Packit |
40b132 |
pkix_pl_InfoAccess_ParseLocation(
|
|
Packit |
40b132 |
PKIX_PL_GeneralName *generalName,
|
|
Packit |
40b132 |
PLArenaPool *arena,
|
|
Packit |
40b132 |
LDAPRequestParams *request,
|
|
Packit |
40b132 |
char **pDomainName,
|
|
Packit |
40b132 |
void *plContext)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
PKIX_PL_String *locationString = NULL;
|
|
Packit |
40b132 |
PKIX_UInt32 len = 0;
|
|
Packit |
40b132 |
PKIX_UInt32 ncIndex = 0;
|
|
Packit |
40b132 |
char *domainName = NULL;
|
|
Packit |
40b132 |
char **avaArray = NULL;
|
|
Packit |
40b132 |
char **attrArray = NULL;
|
|
Packit |
40b132 |
char *attr = NULL;
|
|
Packit |
40b132 |
char *locationAscii = NULL;
|
|
Packit |
40b132 |
char *startPos = NULL;
|
|
Packit |
40b132 |
char *endPos = NULL;
|
|
Packit |
40b132 |
char *avaPtr = NULL;
|
|
Packit |
40b132 |
LdapAttrMask attrBit = 0;
|
|
Packit |
40b132 |
LDAPNameComponent **setOfNameComponent = NULL;
|
|
Packit |
40b132 |
LDAPNameComponent *nameComponent = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseLocation");
|
|
Packit |
40b132 |
PKIX_NULLCHECK_FOUR(generalName, arena, request, pDomainName);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_TOSTRING(generalName, &locationString, plContext,
|
|
Packit |
40b132 |
PKIX_GENERALNAMETOSTRINGFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(PKIX_PL_String_GetEncoded
|
|
Packit |
40b132 |
(locationString,
|
|
Packit |
40b132 |
PKIX_ESCASCII,
|
|
Packit |
40b132 |
(void **)&locationAscii,
|
|
Packit |
40b132 |
&len,
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_STRINGGETENCODEDFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
pkix_pl_UnescapeURL(locationAscii);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Skip "ldap:" */
|
|
Packit |
40b132 |
endPos = locationAscii;
|
|
Packit |
40b132 |
while (*endPos != ':' && *endPos != '\0') {
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
if (*endPos == '\0') {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGLOCATIONTYPE);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Skip "//" */
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
if (*endPos != '\0' && *(endPos+1) != '0' &&
|
|
Packit |
40b132 |
*endPos == '/' && *(endPos+1) == '/') {
|
|
Packit |
40b132 |
endPos += 2;
|
|
Packit |
40b132 |
} else {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGDOUBLESLASH);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Get the server-site */
|
|
Packit |
40b132 |
startPos = endPos;
|
|
Packit |
40b132 |
while(*endPos != '/' && *(endPos) != '\0') {
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
if (*endPos == '\0') {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGSERVERSITE);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
len = endPos - startPos;
|
|
Packit |
40b132 |
endPos++;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
domainName = PORT_ArenaZAlloc(arena, len + 1);
|
|
Packit |
40b132 |
if (!domainName) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PORT_Memcpy(domainName, startPos, len);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
domainName[len] = '\0';
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
*pDomainName = domainName;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* Get a list of AttrValueAssertions (such as
|
|
Packit |
40b132 |
* "cn=CommonName, o=Organization, c=US" into a null-terminated array
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
startPos = endPos;
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
|
|
Packit |
40b132 |
(arena,
|
|
Packit |
40b132 |
&startPos,
|
|
Packit |
40b132 |
(char ***) &avaArray,
|
|
Packit |
40b132 |
',',
|
|
Packit |
40b132 |
'?',
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_INFOACCESSPARSETOKENSFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Count how many AVAs we have */
|
|
Packit |
40b132 |
for (len = 0; avaArray[len] != NULL; len++) {}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (len < 2) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_NOTENOUGHNAMECOMPONENTSINGENERALNAME);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Use last name component for baseObject */
|
|
Packit |
40b132 |
request->baseObject = avaArray[len - 1];
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Use only one component for filter. LDAP servers aren't too smart. */
|
|
Packit |
40b132 |
len = 2; /* Eliminate this when servers get smarter. */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
avaArray[len - 1] = NULL;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Get room for null-terminated array of (LdapNameComponent *) */
|
|
Packit |
40b132 |
setOfNameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent *, len);
|
|
Packit |
40b132 |
if (setOfNameComponent == NULL) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Get room for the remaining LdapNameComponents */
|
|
Packit |
40b132 |
nameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent, --len);
|
|
Packit |
40b132 |
if (nameComponent == NULL) {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Convert remaining AVAs to LDAPNameComponents */
|
|
Packit |
40b132 |
for (ncIndex = 0; ncIndex < len; ncIndex ++) {
|
|
Packit |
40b132 |
setOfNameComponent[ncIndex] = nameComponent;
|
|
Packit |
40b132 |
avaPtr = avaArray[ncIndex];
|
|
Packit |
40b132 |
nameComponent->attrType = (unsigned char *)avaPtr;
|
|
Packit |
40b132 |
while ((*avaPtr != '=') && (*avaPtr != '\0')) {
|
|
Packit |
40b132 |
avaPtr++;
|
|
Packit |
40b132 |
if (*avaPtr == '\0') {
|
|
Packit |
40b132 |
PKIX_ERROR(PKIX_NAMECOMPONENTWITHNOEQ);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
*(avaPtr++) = '\0';
|
|
Packit |
40b132 |
nameComponent->attrValue = (unsigned char *)avaPtr;
|
|
Packit |
40b132 |
nameComponent++;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
setOfNameComponent[len] = NULL;
|
|
Packit |
40b132 |
request->nc = setOfNameComponent;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* Get a list of AttrTypes (such as
|
|
Packit |
40b132 |
* "caCertificate;binary, crossCertificatePair;binary") into
|
|
Packit |
40b132 |
* a null-terminated array
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
|
|
Packit |
40b132 |
(arena,
|
|
Packit |
40b132 |
(char **) &startPos,
|
|
Packit |
40b132 |
(char ***) &attrArray,
|
|
Packit |
40b132 |
',',
|
|
Packit |
40b132 |
'\0',
|
|
Packit |
40b132 |
plContext),
|
|
Packit |
40b132 |
PKIX_INFOACCESSPARSETOKENSFAILED);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Convert array of Attr Types into a bit mask */
|
|
Packit |
40b132 |
request->attributes = 0;
|
|
Packit |
40b132 |
attr = attrArray[0];
|
|
Packit |
40b132 |
while (attr != NULL) {
|
|
Packit |
40b132 |
PKIX_CHECK(pkix_pl_LdapRequest_AttrStringToBit
|
|
Packit |
40b132 |
(attr, &attrBit, plContext),
|
|
Packit |
40b132 |
PKIX_LDAPREQUESTATTRSTRINGTOBITFAILED);
|
|
Packit |
40b132 |
request->attributes |= attrBit;
|
|
Packit |
40b132 |
attr = *(++attrArray);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cleanup:
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_PL_Free(locationAscii, plContext);
|
|
Packit |
40b132 |
PKIX_DECREF(locationString);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PKIX_RETURN(INFOACCESS);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
#endif /* !NSS_PKIX_NO_LDAP */
|