diff nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200 (2014-07-28)
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,874 @@
+/* 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_pl_infoaccess.c
+ *
+ * InfoAccess Object Definitions
+ *
+ */
+
+#include "pkix_pl_infoaccess.h"
+
+/* --Private-InfoAccess-Functions----------------------------------*/
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_Create
+ * DESCRIPTION:
+ *
+ *  This function creates an InfoAccess from the method provided in "method" and
+ *  the GeneralName provided in "generalName" and stores the result at
+ *  "pInfoAccess".
+ *
+ * PARAMETERS
+ *  "method"
+ *      The UInt32 value to be stored as the method field of the InfoAccess.
+ *  "generalName"
+ *      The GeneralName to be stored as the generalName field of the InfoAccess.
+ *      Must be non-NULL.
+ *  "pInfoAccess"
+ *      Address where the result is 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 Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_pl_InfoAccess_Create(
+        PKIX_UInt32 method,
+        PKIX_PL_GeneralName *generalName,
+        PKIX_PL_InfoAccess **pInfoAccess,
+        void *plContext)
+{
+
+        PKIX_PL_InfoAccess *infoAccess = NULL;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Create");
+        PKIX_NULLCHECK_TWO(generalName, pInfoAccess);
+
+        PKIX_CHECK(PKIX_PL_Object_Alloc
+                (PKIX_INFOACCESS_TYPE,
+                sizeof (PKIX_PL_InfoAccess),
+                (PKIX_PL_Object **)&infoAccess,
+                plContext),
+                PKIX_COULDNOTCREATEINFOACCESSOBJECT);
+
+        infoAccess->method = method;
+
+        PKIX_INCREF(generalName);
+        infoAccess->location = generalName;
+
+        *pInfoAccess = infoAccess;
+        infoAccess = NULL;
+
+cleanup:
+        PKIX_DECREF(infoAccess);
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
+ */
+static PKIX_Error *
+pkix_pl_InfoAccess_Destroy(
+        PKIX_PL_Object *object,
+        void *plContext)
+{
+        PKIX_PL_InfoAccess *infoAccess = NULL;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Destroy");
+        PKIX_NULLCHECK_ONE(object);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_INFOACCESS_TYPE, plContext),
+                PKIX_OBJECTNOTANINFOACCESS);
+
+        infoAccess = (PKIX_PL_InfoAccess *)object;
+
+        PKIX_DECREF(infoAccess->location);
+
+cleanup:
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_ToString
+ * (see comments for PKIX_PL_ToStringCallback in pkix_pl_pki.h)
+ */
+static PKIX_Error *
+pkix_pl_InfoAccess_ToString(
+        PKIX_PL_Object *object,
+        PKIX_PL_String **pString,
+        void *plContext)
+{
+        PKIX_PL_InfoAccess *infoAccess;
+        PKIX_PL_String *infoAccessString = NULL;
+        char *asciiFormat = NULL;
+        char *asciiMethod = NULL;
+        PKIX_PL_String *formatString = NULL;
+        PKIX_PL_String *methodString = NULL;
+        PKIX_PL_String *locationString = NULL;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ToString");
+        PKIX_NULLCHECK_TWO(object, pString);
+
+        PKIX_CHECK(pkix_CheckType
+                    (object, PKIX_INFOACCESS_TYPE, plContext),
+                    PKIX_OBJECTNOTINFOACCESS);
+
+        infoAccess = (PKIX_PL_InfoAccess *)object;
+
+        asciiFormat =
+                "["
+                "method:%s, "
+                "location:%s"
+                "]";
+
+        PKIX_CHECK(PKIX_PL_String_Create
+                    (PKIX_ESCASCII,
+                    asciiFormat,
+                    0,
+                    &formatString,
+                    plContext),
+                    PKIX_STRINGCREATEFAILED);
+
+        switch(infoAccess->method) {
+            case PKIX_INFOACCESS_CA_ISSUERS:
+                    asciiMethod = "caIssuers";
+                    break;
+            case PKIX_INFOACCESS_OCSP:
+                    asciiMethod = "ocsp";
+                    break;
+            case PKIX_INFOACCESS_TIMESTAMPING:
+                    asciiMethod = "timestamping";
+                    break;
+            case PKIX_INFOACCESS_CA_REPOSITORY:
+                    asciiMethod = "caRepository";
+                    break;
+            default:
+                    asciiMethod = "unknown";
+        }
+
+        PKIX_CHECK(PKIX_PL_String_Create
+                    (PKIX_ESCASCII,
+                    asciiMethod,
+                    0,
+                    &methodString,
+                    plContext),
+                    PKIX_STRINGCREATEFAILED);
+
+        PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
+                    PKIX_GENERALNAMETOSTRINGFAILED);
+
+        PKIX_CHECK(PKIX_PL_Sprintf
+                    (&infoAccessString,
+                    plContext,
+                    formatString,
+                    methodString,
+                    locationString),
+                    PKIX_SPRINTFFAILED);
+
+        *pString = infoAccessString;
+
+cleanup:
+
+        PKIX_DECREF(formatString);
+        PKIX_DECREF(methodString);
+        PKIX_DECREF(locationString);
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_Hashcode
+ * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_pki.h)
+ */
+static PKIX_Error *
+pkix_pl_InfoAccess_Hashcode(
+        PKIX_PL_Object *object,
+        PKIX_UInt32 *pHashcode,
+        void *plContext)
+{
+        PKIX_PL_InfoAccess *infoAccess = NULL;
+        PKIX_UInt32 infoAccessHash;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Hashcode");
+        PKIX_NULLCHECK_TWO(object, pHashcode);
+
+        PKIX_CHECK(pkix_CheckType
+                    (object, PKIX_INFOACCESS_TYPE, plContext),
+                    PKIX_OBJECTNOTINFOACCESS);
+
+        infoAccess = (PKIX_PL_InfoAccess *)object;
+
+        PKIX_HASHCODE(infoAccess->location, &infoAccessHash, plContext,
+                    PKIX_OBJECTHASHCODEFAILED);
+
+        infoAccessHash += (infoAccess->method << 7);
+
+        *pHashcode = infoAccessHash;
+
+cleanup:
+
+        PKIX_RETURN(INFOACCESS);
+
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_Equals
+ * (see comments for PKIX_PL_Equals_Callback in pkix_pl_pki.h)
+ */
+static PKIX_Error *
+pkix_pl_InfoAccess_Equals(
+        PKIX_PL_Object *firstObject,
+        PKIX_PL_Object *secondObject,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_InfoAccess *firstInfoAccess = NULL;
+        PKIX_PL_InfoAccess *secondInfoAccess = NULL;
+        PKIX_UInt32 secondType;
+        PKIX_Boolean cmpResult;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Equals");
+        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
+
+        /* test that firstObject is a InfoAccess */
+        PKIX_CHECK(pkix_CheckType
+                (firstObject, PKIX_INFOACCESS_TYPE, plContext),
+                PKIX_FIRSTOBJECTNOTINFOACCESS);
+
+        /*
+         * Since we know firstObject is a InfoAccess, if both references are
+         * identical, they must be equal
+         */
+        if (firstObject == secondObject){
+                *pResult = PKIX_TRUE;
+                goto cleanup;
+        }
+
+        /*
+         * If secondObject isn't a InfoAccess, we don't throw an error.
+         * We simply return a Boolean result of FALSE
+         */
+        *pResult = PKIX_FALSE;
+        PKIX_CHECK(PKIX_PL_Object_GetType
+                    (secondObject, &secondType, plContext),
+                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
+        if (secondType != PKIX_INFOACCESS_TYPE) goto cleanup;
+
+        firstInfoAccess = (PKIX_PL_InfoAccess *)firstObject;
+        secondInfoAccess = (PKIX_PL_InfoAccess *)secondObject;
+
+        *pResult = PKIX_FALSE;
+
+        if (firstInfoAccess->method != secondInfoAccess->method) {
+                goto cleanup;
+        }
+
+        PKIX_EQUALS(firstInfoAccess, secondInfoAccess, &cmpResult, plContext,
+                PKIX_OBJECTEQUALSFAILED);
+
+        *pResult = cmpResult;
+
+cleanup:
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_RegisterSelf
+ * DESCRIPTION:
+ *  Registers PKIX_INFOACCESS_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_pl_InfoAccess_RegisterSelf(void *plContext)
+{
+        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+        pkix_ClassTable_Entry entry;
+
+        PKIX_ENTER(INFOACCESS,
+                "pkix_pl_InfoAccess_RegisterSelf");
+
+        entry.description = "InfoAccess";
+        entry.objCounter = 0;
+        entry.typeObjectSize = sizeof(PKIX_PL_InfoAccess);
+        entry.destructor = pkix_pl_InfoAccess_Destroy;
+        entry.equalsFunction = pkix_pl_InfoAccess_Equals;
+        entry.hashcodeFunction = pkix_pl_InfoAccess_Hashcode;
+        entry.toStringFunction = pkix_pl_InfoAccess_ToString;
+        entry.comparator = NULL;
+        entry.duplicateFunction = pkix_duplicateImmutable;
+
+        systemClasses[PKIX_INFOACCESS_TYPE] = entry;
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_CreateList
+ * DESCRIPTION:
+ *
+ *  Based on data in CERTAuthInfoAccess array "nssInfoAccess", this function
+ *  creates and returns a PKIX_List of PKIX_PL_InfoAccess at "pInfoAccessList".
+ *
+ * PARAMETERS
+ *  "nssInfoAccess"
+ *      The pointer array of CERTAuthInfoAccess that contains access data.
+ *      May be NULL.
+ *  "pInfoAccessList"
+ *      Address where a list of PKIX_PL_InfoAccess 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 Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_pl_InfoAccess_CreateList(
+        CERTAuthInfoAccess **nssInfoAccess,
+        PKIX_List **pInfoAccessList, /* of PKIX_PL_InfoAccess */
+        void *plContext)
+{
+        PKIX_List *infoAccessList = NULL;
+        PKIX_PL_InfoAccess *infoAccess = NULL;
+        PKIX_PL_GeneralName *location = NULL;
+        PKIX_UInt32 method;
+        int i;
+
+        PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_CreateList");
+        PKIX_NULLCHECK_ONE(pInfoAccessList);
+
+        PKIX_CHECK(PKIX_List_Create(&infoAccessList, plContext),
+                PKIX_LISTCREATEFAILED);
+
+        if (nssInfoAccess == NULL) {
+                goto cleanup;
+        }
+
+        for (i = 0; nssInfoAccess[i] != NULL; i++) {
+
+                if (nssInfoAccess[i]->location == NULL) {
+                    continue;
+                }
+
+                PKIX_CHECK(pkix_pl_GeneralName_Create
+                        (nssInfoAccess[i]->location, &location, plContext),
+                        PKIX_GENERALNAMECREATEFAILED);
+
+                PKIX_CERT_DEBUG("\t\tCalling SECOID_FindOIDTag).\n");
+                method = SECOID_FindOIDTag(&nssInfoAccess[i]->method);
+                /* Map NSS access method value into PKIX constant */
+                switch(method) {
+                        case SEC_OID_PKIX_CA_ISSUERS:
+                                method = PKIX_INFOACCESS_CA_ISSUERS;
+                                break;
+                        case SEC_OID_PKIX_OCSP:
+                                method = PKIX_INFOACCESS_OCSP;
+                                break;
+                        case SEC_OID_PKIX_TIMESTAMPING:
+                                method = PKIX_INFOACCESS_TIMESTAMPING;
+                                break;
+                        case SEC_OID_PKIX_CA_REPOSITORY:
+                                method = PKIX_INFOACCESS_CA_REPOSITORY;
+                                break;
+                        default:
+                                PKIX_ERROR(PKIX_UNKNOWNINFOACCESSMETHOD);
+                }
+
+                PKIX_CHECK(pkix_pl_InfoAccess_Create
+                        (method, location, &infoAccess, plContext),
+                        PKIX_INFOACCESSCREATEFAILED);
+
+                PKIX_CHECK(PKIX_List_AppendItem
+                            (infoAccessList,
+                            (PKIX_PL_Object *)infoAccess,
+                            plContext),
+                            PKIX_LISTAPPENDITEMFAILED);
+                PKIX_DECREF(infoAccess);
+                PKIX_DECREF(location);
+        }
+
+        *pInfoAccessList = infoAccessList;
+        infoAccessList = NULL;
+
+cleanup:
+
+        PKIX_DECREF(infoAccessList);
+        PKIX_DECREF(infoAccess);
+        PKIX_DECREF(location);
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/* --Public-Functions------------------------------------------------------- */
+
+/*
+ * FUNCTION: PKIX_PL_InfoAccess_GetMethod (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_InfoAccess_GetMethod(
+        PKIX_PL_InfoAccess *infoAccess,
+        PKIX_UInt32 *pMethod,
+        void *plContext)
+{
+        PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetMethod");
+        PKIX_NULLCHECK_TWO(infoAccess, pMethod);
+
+        *pMethod = infoAccess->method;
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: PKIX_PL_InfoAccess_GetLocation (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_InfoAccess_GetLocation(
+        PKIX_PL_InfoAccess *infoAccess,
+        PKIX_PL_GeneralName **pLocation,
+        void *plContext)
+{
+        PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocation");
+        PKIX_NULLCHECK_TWO(infoAccess, pLocation);
+
+        PKIX_INCREF(infoAccess->location);
+
+        *pLocation = infoAccess->location;
+
+cleanup:
+        PKIX_RETURN(INFOACCESS);
+}
+
+/*
+ * FUNCTION: PKIX_PL_InfoAccess_GetLocationType (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_InfoAccess_GetLocationType(
+        PKIX_PL_InfoAccess *infoAccess,
+        PKIX_UInt32 *pType,
+        void *plContext)
+{
+        PKIX_PL_String *locationString = NULL;
+        PKIX_UInt32 type = PKIX_INFOACCESS_LOCATION_UNKNOWN;
+        PKIX_UInt32 len = 0;
+        void *location = NULL;
+
+        PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocationType");
+        PKIX_NULLCHECK_TWO(infoAccess, pType);
+
+        if (infoAccess->location != NULL) {
+
+                PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
+                    PKIX_GENERALNAMETOSTRINGFAILED);
+
+                PKIX_CHECK(PKIX_PL_String_GetEncoded
+                    (locationString, PKIX_ESCASCII, &location, &len, plContext),
+                    PKIX_STRINGGETENCODEDFAILED);
+
+                PKIX_OID_DEBUG("\tCalling PORT_Strcmp).\n");
+#ifndef NSS_PKIX_NO_LDAP
+                if (PORT_Strncmp(location, "ldap:", 5) == 0){
+                        type = PKIX_INFOACCESS_LOCATION_LDAP;
+                } else
+#endif
+                if (PORT_Strncmp(location, "http:", 5) == 0){
+                        type = PKIX_INFOACCESS_LOCATION_HTTP;
+                }
+        }
+
+        *pType = type;
+
+cleanup:
+
+        PKIX_PL_Free(location, plContext);
+        PKIX_DECREF(locationString);
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+#ifndef NSS_PKIX_NO_LDAP
+/*
+ * FUNCTION: pkix_pl_InfoAccess_ParseTokens
+ * DESCRIPTION:
+ *
+ *  This function parses the string beginning at "startPos" into tokens using
+ *  the separator contained in "separator" and the terminator contained in
+ *  "terminator", copying the tokens into space allocated from the arena
+ *  pointed to by "arena". It stores in "tokens" a null-terminated array of
+ *  pointers to those tokens.
+ *
+ * PARAMETERS
+ *  "arena"
+ *      Address of a PLArenaPool to be used in populating the LDAPLocation.
+ *      Must be non-NULL.
+ *  "startPos"
+ *      The address of char string that contains a subset of ldap location.
+ *  "tokens"
+ *      The address of an array of char string for storing returned tokens.
+ *      Must be non-NULL.
+ *  "separator"
+ *      The character that is taken as token separator. Must be non-NULL.
+ *  "terminator"
+ *      The character that is taken as parsing terminator. 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 an InfoAccess 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_pl_InfoAccess_ParseTokens(
+        PLArenaPool *arena,
+        char **startPos, /* return update */
+        char ***tokens,
+        char separator,
+        char terminator,
+        void *plContext)
+{
+        PKIX_UInt32 numFilters = 0;
+        char *endPos = NULL;
+        char **filterP = NULL;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseTokens");
+        PKIX_NULLCHECK_THREE(arena, startPos, tokens);
+
+        endPos = *startPos;
+
+        /* First pass: parse to <terminator> to count number of components */
+        numFilters = 0;
+        while (*endPos != terminator && *endPos != '\0') {
+                endPos++;
+                if (*endPos == separator) {
+                        numFilters++;
+                }
+        }
+
+        if (*endPos != terminator) {
+                PKIX_ERROR(PKIX_LOCATIONSTRINGNOTPROPERLYTERMINATED);
+        }
+
+        /* Last component doesn't need a separator, although we allow it */
+        if (endPos > *startPos && *(endPos-1) != separator) {
+                numFilters++;
+        }
+
+        /*
+         * If string is a=xx, b=yy, c=zz, etc., use a=xx for filter,
+         * and everything else for the base
+         */
+        if (numFilters > 2) numFilters = 2;
+
+        filterP = PORT_ArenaZNewArray(arena, char*, numFilters+1);
+        if (filterP == NULL) {
+            PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+        }
+
+        /* Second pass: parse to fill in components in token array */
+        *tokens = filterP;
+        endPos = *startPos;
+
+        while (numFilters) {
+            if (*endPos == separator || *endPos == terminator) {
+                    PKIX_UInt32 len = endPos - *startPos;
+                    char *p = PORT_ArenaZAlloc(arena, len+1);
+                    if (p == NULL) {
+                        PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+                    }
+
+                    PORT_Memcpy(p, *startPos, len);
+                    p[len] = '\0';
+
+                    *filterP = p;
+                    filterP++;
+                    numFilters--;
+
+                    separator = terminator;
+
+                    if (*endPos == '\0') {
+                        *startPos = endPos;
+                        break;
+                    } else {
+                        endPos++;
+                        *startPos = endPos;
+                        continue;
+                    }
+            }
+            endPos++;
+        }
+
+        *filterP = NULL;
+
+cleanup:
+
+        PKIX_RETURN(INFOACCESS);
+}
+
+static int
+pkix_pl_HexDigitToInt(
+        int ch)
+{
+        if (isdigit(ch)) {
+                ch = ch - '0';
+        } else if (isupper(ch)) {
+                ch = ch - 'A' + 10;
+        } else {
+                ch = ch - 'a' + 10;
+        }
+        return ch;
+}
+
+/*
+ * Convert the "%" hex hex escape sequences in the URL 'location' in place.
+ */
+static void
+pkix_pl_UnescapeURL(
+        char *location)
+{
+        const char *src;
+        char *dst;
+
+        for (src = dst = location; *src != '\0'; src++, dst++) {
+                if (*src == '%' && isxdigit((unsigned char)*(src+1)) &&
+                    isxdigit((unsigned char)*(src+2))) {
+                        *dst = pkix_pl_HexDigitToInt((unsigned char)*(src+1));
+                        *dst *= 16;
+                        *dst += pkix_pl_HexDigitToInt((unsigned char)*(src+2));
+                        src += 2;
+                } else {
+                        *dst = *src;
+                }
+        }
+        *dst = *src;  /* the terminating null */
+}
+
+/*
+ * FUNCTION: pkix_pl_InfoAccess_ParseLocation
+ * DESCRIPTION:
+ *
+ *  This function parses the GeneralName pointed to by "generalName" into the
+ *  fields of the LDAPRequestParams pointed to by "request" and a domainName
+ *  pointed to by "pDomainName", using the PLArenaPool pointed to by "arena" to
+ *  allocate storage for the request components and for the domainName string.
+ *
+ *  The expected GeneralName string should be in the format described by the
+ *  following BNF:
+ *
+ *  ldap://<ldap-server-site>/[cn=<cname>][,o=<org>][,c=<country>]?
+ *  [caCertificate|crossCertificatPair|certificateRevocationList];
+ *  [binary|<other-type>]
+ *  [[,caCertificate|crossCertificatPair|certificateRevocationList]
+ *   [binary|<other-type>]]*
+ *
+ * PARAMETERS
+ *  "generalName"
+ *      Address of the GeneralName whose LDAPLocation is to be parsed. Must be
+ *      non-NULL.
+ *  "arena"
+ *      Address of PLArenaPool to be used for the domainName and for components
+ *      of the LDAPRequest. Must be non-NULL.
+ *  "request"
+ *      Address of the LDAPRequestParams into which request components are
+ *      stored. Must be non-NULL.
+ *  *pDomainName"
+ *      Address at which the domainName is 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 an InfoAccess 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_pl_InfoAccess_ParseLocation(
+        PKIX_PL_GeneralName *generalName,
+        PLArenaPool *arena,
+        LDAPRequestParams *request,
+        char **pDomainName,
+        void *plContext)
+{
+        PKIX_PL_String *locationString = NULL;
+        PKIX_UInt32 len = 0;
+        PKIX_UInt32 ncIndex = 0;
+        char *domainName = NULL;
+        char **avaArray = NULL;
+        char **attrArray = NULL;
+        char *attr = NULL;
+        char *locationAscii = NULL;
+        char *startPos = NULL;
+        char *endPos = NULL;
+        char *avaPtr = NULL;
+        LdapAttrMask attrBit = 0;
+        LDAPNameComponent **setOfNameComponent = NULL;
+        LDAPNameComponent *nameComponent = NULL;
+
+        PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseLocation");
+        PKIX_NULLCHECK_FOUR(generalName, arena, request, pDomainName);
+
+        PKIX_TOSTRING(generalName, &locationString, plContext,
+                PKIX_GENERALNAMETOSTRINGFAILED);
+
+        PKIX_CHECK(PKIX_PL_String_GetEncoded
+                (locationString,
+                PKIX_ESCASCII,
+                (void **)&locationAscii,
+                &len,
+                plContext),
+                PKIX_STRINGGETENCODEDFAILED);
+
+        pkix_pl_UnescapeURL(locationAscii);
+
+        /* Skip "ldap:" */
+        endPos = locationAscii;
+        while (*endPos != ':' && *endPos != '\0') {
+                endPos++;
+        }
+        if (*endPos == '\0') {
+                PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGLOCATIONTYPE);
+        }
+
+        /* Skip "//" */
+        endPos++;
+        if (*endPos != '\0' && *(endPos+1) != '0' &&
+            *endPos == '/' && *(endPos+1) == '/') {
+                endPos += 2;
+        } else {
+                PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGDOUBLESLASH);
+        }
+
+        /* Get the server-site */
+        startPos = endPos;
+        while(*endPos != '/' && *(endPos) != '\0') {
+                endPos++;
+        }
+        if (*endPos == '\0') {
+                PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGSERVERSITE);
+        }
+
+        len = endPos - startPos;
+        endPos++;
+
+        domainName = PORT_ArenaZAlloc(arena, len + 1);
+        if (!domainName) {
+            PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+        }
+
+        PORT_Memcpy(domainName, startPos, len);
+
+        domainName[len] = '\0';
+
+        *pDomainName = domainName;
+
+        /*
+         * Get a list of AttrValueAssertions (such as 
+         * "cn=CommonName, o=Organization, c=US" into a null-terminated array
+         */
+        startPos = endPos;
+        PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
+                (arena,
+                &startPos,
+                (char ***) &avaArray,
+                ',',
+                '?',
+                plContext),
+                PKIX_INFOACCESSPARSETOKENSFAILED);
+
+        /* Count how many AVAs we have */
+        for (len = 0; avaArray[len] != NULL; len++) {}
+
+        if (len < 2) {
+                PKIX_ERROR(PKIX_NOTENOUGHNAMECOMPONENTSINGENERALNAME);
+        }
+
+        /* Use last name component for baseObject */
+        request->baseObject = avaArray[len - 1];
+
+        /* Use only one component for filter. LDAP servers aren't too smart. */
+        len = 2;   /* Eliminate this when servers get smarter. */
+
+        avaArray[len - 1] = NULL;
+
+        /* Get room for null-terminated array of (LdapNameComponent *) */
+        setOfNameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent *, len);
+        if (setOfNameComponent == NULL) {
+            PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+        }
+
+        /* Get room for the remaining LdapNameComponents */
+        nameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent, --len);
+        if (nameComponent == NULL) {
+            PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
+        }
+
+        /* Convert remaining AVAs to LDAPNameComponents */
+        for (ncIndex = 0; ncIndex < len; ncIndex ++) {
+                setOfNameComponent[ncIndex] = nameComponent;
+                avaPtr = avaArray[ncIndex];
+                nameComponent->attrType = (unsigned char *)avaPtr;
+                while ((*avaPtr != '=') && (*avaPtr != '\0')) {
+                        avaPtr++;
+                        if (*avaPtr == '\0') {
+                                PKIX_ERROR(PKIX_NAMECOMPONENTWITHNOEQ);
+                        }
+                }
+                *(avaPtr++) = '\0';
+                nameComponent->attrValue = (unsigned char *)avaPtr;
+                nameComponent++;
+        }
+
+        setOfNameComponent[len] = NULL;
+        request->nc = setOfNameComponent;
+                
+        /*
+         * Get a list of AttrTypes (such as 
+         * "caCertificate;binary, crossCertificatePair;binary") into
+         * a null-terminated array
+         */
+
+        PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
+                (arena,
+                (char **) &startPos,
+                (char ***) &attrArray,
+                ',',
+                '\0',
+                plContext),
+                PKIX_INFOACCESSPARSETOKENSFAILED);
+
+        /* Convert array of Attr Types into a bit mask */
+        request->attributes = 0;
+        attr = attrArray[0];
+        while (attr != NULL) {
+                PKIX_CHECK(pkix_pl_LdapRequest_AttrStringToBit
+                        (attr, &attrBit, plContext),
+                        PKIX_LDAPREQUESTATTRSTRINGTOBITFAILED);
+                request->attributes |= attrBit;
+                attr = *(++attrArray);
+        }
+
+cleanup:
+
+        PKIX_PL_Free(locationAscii, plContext);
+        PKIX_DECREF(locationString);
+
+        PKIX_RETURN(INFOACCESS);
+}
+#endif /* !NSS_PKIX_NO_LDAP */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)