diff nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.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
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,761 @@
+/* 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_ldaprequest.c
+ *
+ */
+
+#include "pkix_pl_ldaprequest.h"
+
+/* --Private-LdapRequest-Functions------------------------------------- */
+
+/* Note: lengths do not include the NULL terminator */
+static const char caAttr[] = "caCertificate;binary";
+static unsigned int caAttrLen = sizeof(caAttr) - 1;
+static const char uAttr[] = "userCertificate;binary";
+static unsigned int uAttrLen = sizeof(uAttr) - 1;
+static const char ccpAttr[] = "crossCertificatePair;binary";
+static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1;
+static const char crlAttr[] = "certificateRevocationList;binary";
+static unsigned int crlAttrLen = sizeof(crlAttr) - 1;
+static const char arlAttr[] = "authorityRevocationList;binary";
+static unsigned int arlAttrLen = sizeof(arlAttr) - 1;
+
+/*
+ * XXX If this function were moved into pkix_pl_ldapcertstore.c then all of
+ * LdapRequest and LdapResponse could be considered part of the LDAP client.
+ * But the constants, above, would have to be copied as well, and they are
+ * also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be
+ * two copies.
+ */
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit
+ * DESCRIPTION:
+ *
+ *  This function creates an attribute mask bit corresponding to the SECItem
+ *  pointed to by "attrType", storing the result at "pAttrBit". The comparison
+ *  is case-insensitive. If "attrType" does not match any of the known types,
+ *  zero is stored at "pAttrBit".
+ *
+ * PARAMETERS
+ *  "attrType"
+ *      The address of the SECItem whose string contents are to be compared to
+ *      the various known attribute types. Must be non-NULL.
+ *  "pAttrBit"
+ *      The 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 an LdapRequest 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_LdapRequest_AttrTypeToBit(
+        SECItem *attrType,
+        LdapAttrMask *pAttrBit,
+        void *plContext)
+{
+        LdapAttrMask attrBit = 0;
+        unsigned int attrLen = 0;
+        const char *s = NULL;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit");
+        PKIX_NULLCHECK_TWO(attrType, pAttrBit);
+
+        s = (const char *)attrType->data;
+        attrLen = attrType->len;
+
+        /*
+         * Taking note of the fact that all of the comparand strings are
+         * different lengths, we do a slight optimization. If a string
+         * length matches but the string does not match, we skip comparing
+         * to the other strings. If new strings are added to the comparand
+         * list, and any are of equal length, be careful to change the
+         * grouping of tests accordingly.
+         */
+        if (attrLen == caAttrLen) {
+                if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) {
+                        attrBit = LDAPATTR_CACERT;
+                }
+        } else if (attrLen == uAttrLen) {
+                if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) {
+                        attrBit = LDAPATTR_USERCERT;
+                }
+        } else if (attrLen == ccpAttrLen) {
+                if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) {
+                        attrBit = LDAPATTR_CROSSPAIRCERT;
+                }
+        } else if (attrLen == crlAttrLen) {
+                if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) {
+                        attrBit = LDAPATTR_CERTREVLIST;
+                }
+        } else if (attrLen == arlAttrLen) {
+                if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) {
+                        attrBit = LDAPATTR_AUTHREVLIST;
+                }
+        }
+
+        *pAttrBit = attrBit;
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_AttrStringToBit
+ * DESCRIPTION:
+ *
+ *  This function creates an attribute mask bit corresponding to the null-
+ *  terminated string pointed to by "attrString", storing the result at
+ *  "pAttrBit". The comparison is case-insensitive. If "attrString" does not
+ *  match any of the known types, zero is stored at "pAttrBit".
+ *
+ * PARAMETERS
+ *  "attrString"
+ *      The address of the null-terminated string whose contents are to be compared to
+ *      the various known attribute types. Must be non-NULL.
+ *  "pAttrBit"
+ *      The 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 an LdapRequest 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_LdapRequest_AttrStringToBit(
+        char *attrString,
+        LdapAttrMask *pAttrBit,
+        void *plContext)
+{
+        LdapAttrMask attrBit = 0;
+        unsigned int attrLen = 0;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit");
+        PKIX_NULLCHECK_TWO(attrString, pAttrBit);
+
+        attrLen = PL_strlen(attrString);
+
+        /*
+         * Taking note of the fact that all of the comparand strings are
+         * different lengths, we do a slight optimization. If a string
+         * length matches but the string does not match, we skip comparing
+         * to the other strings. If new strings are added to the comparand
+         * list, and any are of equal length, be careful to change the
+         * grouping of tests accordingly.
+         */
+        if (attrLen == caAttrLen) {
+                if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) {
+                        attrBit = LDAPATTR_CACERT;
+                }
+        } else if (attrLen == uAttrLen) {
+                if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) {
+                        attrBit = LDAPATTR_USERCERT;
+                }
+        } else if (attrLen == ccpAttrLen) {
+                if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) {
+                        attrBit = LDAPATTR_CROSSPAIRCERT;
+                }
+        } else if (attrLen == crlAttrLen) {
+                if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) {
+                        attrBit = LDAPATTR_CERTREVLIST;
+                }
+        } else if (attrLen == arlAttrLen) {
+                if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) {
+                        attrBit = LDAPATTR_AUTHREVLIST;
+                }
+        }
+
+        *pAttrBit = attrBit;
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_EncodeAttrs
+ * DESCRIPTION:
+ *
+ *  This function obtains the attribute mask bits from the LdapRequest pointed
+ *  to by "request", creates the corresponding array of AttributeTypes for the
+ *  encoding of the SearchRequest message.
+ *
+ * PARAMETERS
+ *  "request"
+ *      The address of the LdapRequest whose attributes are to be encoded. 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 LdapRequest 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_LdapRequest_EncodeAttrs(
+        PKIX_PL_LdapRequest *request,
+        void *plContext)
+{
+        SECItem **attrArray = NULL;
+        PKIX_UInt32 attrIndex = 0;
+        LdapAttrMask attrBits;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs");
+        PKIX_NULLCHECK_ONE(request);
+
+        /* construct "attrs" according to bits in request->attrBits */
+        attrBits = request->attrBits;
+        attrArray = request->attrArray;
+        if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) {
+                attrArray[attrIndex] = &(request->attributes[attrIndex]);
+                request->attributes[attrIndex].type = siAsciiString;
+                request->attributes[attrIndex].data = (unsigned char *)caAttr;
+                request->attributes[attrIndex].len = caAttrLen;
+                attrIndex++;
+        }
+        if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) {
+                attrArray[attrIndex] = &(request->attributes[attrIndex]);
+                request->attributes[attrIndex].type = siAsciiString;
+                request->attributes[attrIndex].data = (unsigned char *)uAttr;
+                request->attributes[attrIndex].len = uAttrLen;
+                attrIndex++;
+        }
+        if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) {
+                attrArray[attrIndex] = &(request->attributes[attrIndex]);
+                request->attributes[attrIndex].type = siAsciiString;
+                request->attributes[attrIndex].data = (unsigned char *)ccpAttr;
+                request->attributes[attrIndex].len = ccpAttrLen;
+                attrIndex++;
+        }
+        if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) {
+                attrArray[attrIndex] = &(request->attributes[attrIndex]);
+                request->attributes[attrIndex].type = siAsciiString;
+                request->attributes[attrIndex].data = (unsigned char *)crlAttr;
+                request->attributes[attrIndex].len = crlAttrLen;
+                attrIndex++;
+        }
+        if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) {
+                attrArray[attrIndex] = &(request->attributes[attrIndex]);
+                request->attributes[attrIndex].type = siAsciiString;
+                request->attributes[attrIndex].data = (unsigned char *)arlAttr;
+                request->attributes[attrIndex].len = arlAttrLen;
+                attrIndex++;
+        }
+        attrArray[attrIndex] = (SECItem *)NULL;
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_LdapRequest_Destroy(
+        PKIX_PL_Object *object,
+        void *plContext)
+{
+        PKIX_PL_LdapRequest *ldapRq = NULL;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy");
+        PKIX_NULLCHECK_ONE(object);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
+                    PKIX_OBJECTNOTLDAPREQUEST);
+
+        ldapRq = (PKIX_PL_LdapRequest *)object;
+
+        /*
+         * All dynamic fields in an LDAPRequest are allocated
+         * in an arena, and will be freed when the arena is destroyed.
+         */
+
+cleanup:
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_Hashcode
+ * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_LdapRequest_Hashcode(
+        PKIX_PL_Object *object,
+        PKIX_UInt32 *pHashcode,
+        void *plContext)
+{
+        PKIX_UInt32 dataLen = 0;
+        PKIX_UInt32 dindex = 0;
+        PKIX_UInt32 sizeOfLength = 0;
+        PKIX_UInt32 idLen = 0;
+        const unsigned char *msgBuf = NULL;
+        PKIX_PL_LdapRequest *ldapRq = NULL;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode");
+        PKIX_NULLCHECK_TWO(object, pHashcode);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
+                    PKIX_OBJECTNOTLDAPREQUEST);
+
+        ldapRq = (PKIX_PL_LdapRequest *)object;
+
+        *pHashcode = 0;
+
+        /*
+         * Two requests that differ only in msgnum are a match! Therefore,
+         * start hashcoding beyond the encoded messageID field.
+         */
+        if (ldapRq->encoded) {
+                msgBuf = (const unsigned char *)ldapRq->encoded->data;
+                /* Is message length short form (one octet) or long form? */
+                if ((msgBuf[1] & 0x80) != 0) {
+                        sizeOfLength = msgBuf[1] & 0x7F;
+                        for (dindex = 0; dindex < sizeOfLength; dindex++) {
+                                dataLen = (dataLen << 8) + msgBuf[dindex + 2];
+                        }
+                } else {
+                        dataLen = msgBuf[1];
+                }
+
+                /* How many bytes for the messageID? (Assume short form) */
+                idLen = msgBuf[dindex + 3] + 2;
+                dindex += idLen;
+                dataLen -= idLen;
+                msgBuf = &msgBuf[dindex + 2];
+
+                PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
+                        PKIX_HASHFAILED);
+        }
+
+cleanup:
+
+        PKIX_RETURN(LDAPREQUEST);
+
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_Equals
+ * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_pl_LdapRequest_Equals(
+        PKIX_PL_Object *firstObj,
+        PKIX_PL_Object *secondObj,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_PL_LdapRequest *firstReq = NULL;
+        PKIX_PL_LdapRequest *secondReq = NULL;
+        PKIX_UInt32 secondType = 0;
+        PKIX_UInt32 firstLen = 0;
+        const unsigned char *firstData = NULL;
+        const unsigned char *secondData = NULL;
+        PKIX_UInt32 sizeOfLength = 0;
+        PKIX_UInt32 dindex = 0;
+        PKIX_UInt32 i = 0;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals");
+        PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
+
+        /* test that firstObj is a LdapRequest */
+        PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext),
+                    PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST);
+
+        /*
+         * Since we know firstObj is a LdapRequest, if both references are
+         * identical, they must be equal
+         */
+        if (firstObj == secondObj){
+                *pResult = PKIX_TRUE;
+                goto cleanup;
+        }
+
+        /*
+         * If secondObj isn't a LdapRequest, we don't throw an error.
+         * We simply return a Boolean result of FALSE
+         */
+        *pResult = PKIX_FALSE;
+        PKIX_CHECK(PKIX_PL_Object_GetType
+                    (secondObj, &secondType, plContext),
+                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
+        if (secondType != PKIX_LDAPREQUEST_TYPE) {
+                goto cleanup;
+        }
+
+        firstReq = (PKIX_PL_LdapRequest *)firstObj;
+        secondReq = (PKIX_PL_LdapRequest *)secondObj;
+
+        /* If either lacks an encoded string, they cannot be compared */
+        if (!(firstReq->encoded) || !(secondReq->encoded)) {
+                goto cleanup;
+        }
+
+        if (firstReq->encoded->len != secondReq->encoded->len) {
+                goto cleanup;
+        }
+
+        firstData = (const unsigned char *)firstReq->encoded->data;
+        secondData = (const unsigned char *)secondReq->encoded->data;
+
+        /*
+         * Two requests that differ only in msgnum are equal! Therefore,
+         * start the byte comparison beyond the encoded messageID field.
+         */
+
+        /* Is message length short form (one octet) or long form? */
+        if ((firstData[1] & 0x80) != 0) {
+                sizeOfLength = firstData[1] & 0x7F;
+                for (dindex = 0; dindex < sizeOfLength; dindex++) {
+                        firstLen = (firstLen << 8) + firstData[dindex + 2];
+                }
+        } else {
+                firstLen = firstData[1];
+        }
+
+        /* How many bytes for the messageID? (Assume short form) */
+        i = firstData[dindex + 3] + 2;
+        dindex += i;
+        firstLen -= i;
+        firstData = &firstData[dindex + 2];
+
+        /*
+         * In theory, we have to calculate where the second message data
+         * begins by checking its length encodings. But if these messages
+         * are equal, we can re-use the calculation we already did. If they
+         * are not equal, the byte comparisons will surely fail.
+         */
+
+        secondData = &secondData[dindex + 2];
+        
+        for (i = 0; i < firstLen; i++) {
+                if (firstData[i] != secondData[i]) {
+                        goto cleanup;
+                }
+        }
+
+        *pResult = PKIX_TRUE;
+
+cleanup:
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_RegisterSelf
+ * DESCRIPTION:
+ *  Registers PKIX_LDAPREQUEST_TYPE and its related functions with
+ *  systemClasses[]
+ * PARAMETERS:
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * 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_LdapRequest_RegisterSelf(void *plContext)
+{
+        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+        pkix_ClassTable_Entry entry;
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf");
+
+        entry.description = "LdapRequest";
+        entry.objCounter = 0;
+        entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest);
+        entry.destructor = pkix_pl_LdapRequest_Destroy;
+        entry.equalsFunction = pkix_pl_LdapRequest_Equals;
+        entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode;
+        entry.toStringFunction = NULL;
+        entry.comparator = NULL;
+        entry.duplicateFunction = pkix_duplicateImmutable;
+
+        systemClasses[PKIX_LDAPREQUEST_TYPE] = entry;
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/* --Public-Functions------------------------------------------------------- */
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_Create
+ * DESCRIPTION:
+ *
+ *  This function creates an LdapRequest using the PLArenaPool pointed to by
+ *  "arena", a message number whose value is "msgnum", a base object pointed to
+ *  by "issuerDN", a scope whose value is "scope", a derefAliases flag whose
+ *  value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit
+ *  whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a
+ *  filter whose value is "filter", and attribute bits whose value is
+ *  "attrBits"; storing the result at "pRequestMsg".
+ *
+ *  See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of
+ *  message components, and see pkix_pl_ldapt.h for data types.
+ *
+ * PARAMETERS
+ *  "arena"
+ *      The address of the PLArenaPool to be used in the encoding. Must be
+ *      non-NULL.
+ *  "msgnum"
+ *      The UInt32 message number to be used for the messageID component of the
+ *      LDAP message exchange.
+ *  "issuerDN"
+ *      The address of the string to be used for the baseObject component of the
+ *      LDAP SearchRequest message. Must be non-NULL.
+ *  "scope"
+ *      The (enumerated) ScopeType to be used for the scope component of the
+ *      LDAP SearchRequest message
+ *  "derefAliases"
+ *      The (enumerated) DerefType to be used for the derefAliases component of
+ *      the LDAP SearchRequest message
+ *  "sizeLimit"
+ *      The UInt32 value to be used for the sizeLimit component of the LDAP
+ *      SearchRequest message
+ *  "timeLimit"
+ *      The UInt32 value to be used for the timeLimit component of the LDAP
+ *      SearchRequest message
+ *  "attrsOnly"
+ *      The Boolean value to be used for the attrsOnly component of the LDAP
+ *      SearchRequest message
+ *  "filter"
+ *      The filter to be used for the filter component of the LDAP
+ *      SearchRequest message
+ *  "attrBits"
+ *      The LdapAttrMask bits indicating the attributes to be included in the
+ *      attributes sequence of the LDAP SearchRequest message
+ *  "pRequestMsg"
+ *      The address at which the address of the LdapRequest 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 LdapRequest Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+/*
+ * SearchRequest ::=
+ *      [APPLICATION 3] SEQUENCE {
+ *              baseObject      LDAPDN,
+ *              scope           ENUMERATED {
+ *                                      baseObject              (0),
+ *                                      singleLevel             (1),
+ *                                      wholeSubtree            (2)
+ *                              },
+ *              derefAliases    ENUMERATED {
+ *                                      neverDerefAliases       (0),
+ *                                      derefInSearching        (1),
+ *                                      derefFindingBaseObj     (2),
+ *                                      alwaysDerefAliases      (3)
+ *                              },
+ *              sizeLimit       INTEGER (0 .. MAXINT),
+ *                              -- value of 0 implies no sizeLimit
+ *              timeLimit       INTEGER (0 .. MAXINT),
+ *                              -- value of 0 implies no timeLimit
+ *              attrsOnly       BOOLEAN,
+ *                              -- TRUE, if only attributes (without values)
+ *                              -- to be returned
+ *              filter          Filter,
+ *              attributes      SEQUENCE OF AttributeType
+ *      }
+ *
+ * Filter ::=
+ *      CHOICE {
+ *              and             [0] SET OF Filter,
+ *              or              [1] SET OF Filter,
+ *              not             [2] Filter,
+ *              equalityMatch   [3] AttributeValueAssertion,
+ *              substrings      [4] SubstringFilter,
+ *              greaterOrEqual  [5] AttributeValueAssertion,
+ *              lessOrEqual     [6] AttributeValueAssertion,
+ *              present         [7] AttributeType,
+ *              approxMatch     [8] AttributeValueAssertion
+ *      }
+ *
+ * SubstringFilter ::=
+ *      SEQUENCE {
+ *              type            AttributeType,
+ *              SEQUENCE OF CHOICE {
+ *                      initial [0] LDAPString,
+ *                      any     [1] LDAPString,
+ *                      final   [2] LDAPString,
+ *              }
+ *      }
+ *
+ * AttributeValueAssertion ::=
+ *      SEQUENCE {
+ *              attributeType   AttributeType,
+ *              attributeValue  AttributeValue,
+ *      }
+ *
+ * AttributeValue ::= OCTET STRING
+ *
+ * AttributeType ::= LDAPString
+ *               -- text name of the attribute, or dotted
+ *               -- OID representation
+ *
+ * LDAPDN ::= LDAPString
+ *
+ * LDAPString ::= OCTET STRING
+ *
+ */
+PKIX_Error *
+pkix_pl_LdapRequest_Create(
+        PLArenaPool *arena,
+        PKIX_UInt32 msgnum,
+        char *issuerDN,
+        ScopeType scope,
+        DerefType derefAliases,
+        PKIX_UInt32 sizeLimit,
+        PKIX_UInt32 timeLimit,
+        char attrsOnly,
+        LDAPFilter *filter,
+        LdapAttrMask attrBits,
+        PKIX_PL_LdapRequest **pRequestMsg,
+        void *plContext)
+{
+        LDAPMessage msg;
+        LDAPSearch *search;
+        PKIX_PL_LdapRequest *ldapRequest = NULL;
+        char scopeTypeAsChar;
+        char derefAliasesTypeAsChar;
+        SECItem *attrArray[MAX_LDAPATTRS + 1];
+
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create");
+        PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg);
+
+        /* create a PKIX_PL_LdapRequest object */
+        PKIX_CHECK(PKIX_PL_Object_Alloc
+                    (PKIX_LDAPREQUEST_TYPE,
+                    sizeof (PKIX_PL_LdapRequest),
+                    (PKIX_PL_Object **)&ldapRequest,
+                    plContext),
+                    PKIX_COULDNOTCREATEOBJECT);
+
+        ldapRequest->arena = arena;
+        ldapRequest->msgnum = msgnum;
+        ldapRequest->issuerDN = issuerDN;
+        ldapRequest->scope = scope;
+        ldapRequest->derefAliases = derefAliases;
+        ldapRequest->sizeLimit = sizeLimit;
+        ldapRequest->timeLimit = timeLimit;
+        ldapRequest->attrsOnly = attrsOnly;
+        ldapRequest->filter = filter;
+        ldapRequest->attrBits = attrBits;
+
+        ldapRequest->attrArray = attrArray;
+
+        PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs
+                (ldapRequest, plContext),
+                PKIX_LDAPREQUESTENCODEATTRSFAILED);
+
+        PKIX_PL_NSSCALL
+                (LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage)));
+
+        msg.messageID.type = siUnsignedInteger;
+        msg.messageID.data = (void*)&msgnum;
+        msg.messageID.len = sizeof (msgnum);
+
+        msg.protocolOp.selector = LDAP_SEARCH_TYPE;
+
+        search = &(msg.protocolOp.op.searchMsg);
+
+        search->baseObject.type = siAsciiString;
+        search->baseObject.data = (void *)issuerDN;
+        search->baseObject.len = PL_strlen(issuerDN);
+        scopeTypeAsChar = (char)scope;
+        search->scope.type = siUnsignedInteger;
+        search->scope.data = (void *)&scopeTypeAsChar;
+        search->scope.len = sizeof (scopeTypeAsChar);
+        derefAliasesTypeAsChar = (char)derefAliases;
+        search->derefAliases.type = siUnsignedInteger;
+        search->derefAliases.data =
+                (void *)&derefAliasesTypeAsChar;
+        search->derefAliases.len =
+                sizeof (derefAliasesTypeAsChar);
+        search->sizeLimit.type = siUnsignedInteger;
+        search->sizeLimit.data = (void *)&sizeLimit;
+        search->sizeLimit.len = sizeof (PKIX_UInt32);
+        search->timeLimit.type = siUnsignedInteger;
+        search->timeLimit.data = (void *)&timeLimit;
+        search->timeLimit.len = sizeof (PKIX_UInt32);
+        search->attrsOnly.type = siBuffer;
+        search->attrsOnly.data = (void *)&attrsOnly;
+        search->attrsOnly.len = sizeof (attrsOnly);
+
+        PKIX_PL_NSSCALL
+                (LDAPREQUEST,
+                PORT_Memcpy,
+                (&search->filter, filter, sizeof (LDAPFilter)));
+
+        search->attributes = attrArray;
+
+        PKIX_PL_NSSCALLRV
+                (LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem,
+                (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
+
+        if (!(ldapRequest->encoded)) {
+                PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST);
+        }
+
+        *pRequestMsg = ldapRequest;
+
+cleanup:
+
+        if (PKIX_ERROR_RECEIVED) {
+                PKIX_DECREF(ldapRequest);
+        }
+
+        PKIX_RETURN(LDAPREQUEST);
+}
+
+/*
+ * FUNCTION: pkix_pl_LdapRequest_GetEncoded
+ * DESCRIPTION:
+ *
+ *  This function obtains the encoded message from the LdapRequest pointed to
+ *  by "request", storing the result at "pRequestBuf".
+ *
+ * PARAMETERS
+ *  "request"
+ *      The address of the LdapRequest whose encoded message is to be
+ *      retrieved. Must be non-NULL.
+ *  "pRequestBuf"
+ *      The address at which is stored the address of the encoded message. 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 LdapRequest 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_LdapRequest_GetEncoded(
+        PKIX_PL_LdapRequest *request,
+        SECItem **pRequestBuf,
+        void *plContext)
+{
+        PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded");
+        PKIX_NULLCHECK_TWO(request, pRequestBuf);
+
+        *pRequestBuf = request->encoded;
+
+        PKIX_RETURN(LDAPREQUEST);
+}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)