Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c |
=================================================================== |
--- mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c (revision 191424) |
+++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c (working copy) |
@@ -1,870 +0,0 @@ |
-/* 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"); |
- if (PORT_Strncmp(location, "ldap:", 5) == 0){ |
- type = PKIX_INFOACCESS_LOCATION_LDAP; |
- } else |
- 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); |
-} |
- |
-/* |
- * 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 PRArenaPool 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( |
- PRArenaPool *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 PRArenaPool 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 PRArenaPool 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, |
- PRArenaPool *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); |
-} |