comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_ldaprequest.c
6 *
7 */
8
9 #include "pkix_pl_ldaprequest.h"
10
11 /* --Private-LdapRequest-Functions------------------------------------- */
12
13 /* Note: lengths do not include the NULL terminator */
14 static const char caAttr[] = "caCertificate;binary";
15 static unsigned int caAttrLen = sizeof(caAttr) - 1;
16 static const char uAttr[] = "userCertificate;binary";
17 static unsigned int uAttrLen = sizeof(uAttr) - 1;
18 static const char ccpAttr[] = "crossCertificatePair;binary";
19 static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1;
20 static const char crlAttr[] = "certificateRevocationList;binary";
21 static unsigned int crlAttrLen = sizeof(crlAttr) - 1;
22 static const char arlAttr[] = "authorityRevocationList;binary";
23 static unsigned int arlAttrLen = sizeof(arlAttr) - 1;
24
25 /*
26 * XXX If this function were moved into pkix_pl_ldapcertstore.c then all of
27 * LdapRequest and LdapResponse could be considered part of the LDAP client.
28 * But the constants, above, would have to be copied as well, and they are
29 * also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be
30 * two copies.
31 */
32
33 /*
34 * FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit
35 * DESCRIPTION:
36 *
37 * This function creates an attribute mask bit corresponding to the SECItem
38 * pointed to by "attrType", storing the result at "pAttrBit". The comparison
39 * is case-insensitive. If "attrType" does not match any of the known types,
40 * zero is stored at "pAttrBit".
41 *
42 * PARAMETERS
43 * "attrType"
44 * The address of the SECItem whose string contents are to be compared to
45 * the various known attribute types. Must be non-NULL.
46 * "pAttrBit"
47 * The address where the result is stored. Must be non-NULL.
48 * "plContext"
49 * Platform-specific context pointer.
50 * THREAD SAFETY:
51 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
52 * RETURNS:
53 * Returns NULL if the function succeeds.
54 * Returns an LdapRequest Error if the function fails in a non-fatal way.
55 * Returns a Fatal Error if the function fails in an unrecoverable way.
56 */
57 PKIX_Error *
58 pkix_pl_LdapRequest_AttrTypeToBit(
59 SECItem *attrType,
60 LdapAttrMask *pAttrBit,
61 void *plContext)
62 {
63 LdapAttrMask attrBit = 0;
64 unsigned int attrLen = 0;
65 const char *s = NULL;
66
67 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit");
68 PKIX_NULLCHECK_TWO(attrType, pAttrBit);
69
70 s = (const char *)attrType->data;
71 attrLen = attrType->len;
72
73 /*
74 * Taking note of the fact that all of the comparand strings are
75 * different lengths, we do a slight optimization. If a string
76 * length matches but the string does not match, we skip comparing
77 * to the other strings. If new strings are added to the comparand
78 * list, and any are of equal length, be careful to change the
79 * grouping of tests accordingly.
80 */
81 if (attrLen == caAttrLen) {
82 if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) {
83 attrBit = LDAPATTR_CACERT;
84 }
85 } else if (attrLen == uAttrLen) {
86 if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) {
87 attrBit = LDAPATTR_USERCERT;
88 }
89 } else if (attrLen == ccpAttrLen) {
90 if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) {
91 attrBit = LDAPATTR_CROSSPAIRCERT;
92 }
93 } else if (attrLen == crlAttrLen) {
94 if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) {
95 attrBit = LDAPATTR_CERTREVLIST;
96 }
97 } else if (attrLen == arlAttrLen) {
98 if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) {
99 attrBit = LDAPATTR_AUTHREVLIST;
100 }
101 }
102
103 *pAttrBit = attrBit;
104
105 PKIX_RETURN(LDAPREQUEST);
106 }
107
108 /*
109 * FUNCTION: pkix_pl_LdapRequest_AttrStringToBit
110 * DESCRIPTION:
111 *
112 * This function creates an attribute mask bit corresponding to the null-
113 * terminated string pointed to by "attrString", storing the result at
114 * "pAttrBit". The comparison is case-insensitive. If "attrString" does not
115 * match any of the known types, zero is stored at "pAttrBit".
116 *
117 * PARAMETERS
118 * "attrString"
119 * The address of the null-terminated string whose contents are to be compared to
120 * the various known attribute types. Must be non-NULL.
121 * "pAttrBit"
122 * The address where the result is stored. Must be non-NULL.
123 * "plContext"
124 * Platform-specific context pointer.
125 * THREAD SAFETY:
126 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
127 * RETURNS:
128 * Returns NULL if the function succeeds.
129 * Returns an LdapRequest Error if the function fails in a non-fatal way.
130 * Returns a Fatal Error if the function fails in an unrecoverable way.
131 */
132 PKIX_Error *
133 pkix_pl_LdapRequest_AttrStringToBit(
134 char *attrString,
135 LdapAttrMask *pAttrBit,
136 void *plContext)
137 {
138 LdapAttrMask attrBit = 0;
139 unsigned int attrLen = 0;
140
141 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit");
142 PKIX_NULLCHECK_TWO(attrString, pAttrBit);
143
144 attrLen = PL_strlen(attrString);
145
146 /*
147 * Taking note of the fact that all of the comparand strings are
148 * different lengths, we do a slight optimization. If a string
149 * length matches but the string does not match, we skip comparing
150 * to the other strings. If new strings are added to the comparand
151 * list, and any are of equal length, be careful to change the
152 * grouping of tests accordingly.
153 */
154 if (attrLen == caAttrLen) {
155 if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) {
156 attrBit = LDAPATTR_CACERT;
157 }
158 } else if (attrLen == uAttrLen) {
159 if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) {
160 attrBit = LDAPATTR_USERCERT;
161 }
162 } else if (attrLen == ccpAttrLen) {
163 if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) {
164 attrBit = LDAPATTR_CROSSPAIRCERT;
165 }
166 } else if (attrLen == crlAttrLen) {
167 if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) {
168 attrBit = LDAPATTR_CERTREVLIST;
169 }
170 } else if (attrLen == arlAttrLen) {
171 if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) {
172 attrBit = LDAPATTR_AUTHREVLIST;
173 }
174 }
175
176 *pAttrBit = attrBit;
177
178 PKIX_RETURN(LDAPREQUEST);
179 }
180
181 /*
182 * FUNCTION: pkix_pl_LdapRequest_EncodeAttrs
183 * DESCRIPTION:
184 *
185 * This function obtains the attribute mask bits from the LdapRequest pointed
186 * to by "request", creates the corresponding array of AttributeTypes for the
187 * encoding of the SearchRequest message.
188 *
189 * PARAMETERS
190 * "request"
191 * The address of the LdapRequest whose attributes are to be encoded. Must
192 * be non-NULL.
193 * "plContext"
194 * Platform-specific context pointer.
195 * THREAD SAFETY:
196 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
197 * RETURNS:
198 * Returns NULL if the function succeeds.
199 * Returns an LdapRequest Error if the function fails in a non-fatal way.
200 * Returns a Fatal Error if the function fails in an unrecoverable way.
201 */
202 static PKIX_Error *
203 pkix_pl_LdapRequest_EncodeAttrs(
204 PKIX_PL_LdapRequest *request,
205 void *plContext)
206 {
207 SECItem **attrArray = NULL;
208 PKIX_UInt32 attrIndex = 0;
209 LdapAttrMask attrBits;
210
211 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs");
212 PKIX_NULLCHECK_ONE(request);
213
214 /* construct "attrs" according to bits in request->attrBits */
215 attrBits = request->attrBits;
216 attrArray = request->attrArray;
217 if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) {
218 attrArray[attrIndex] = &(request->attributes[attrIndex]);
219 request->attributes[attrIndex].type = siAsciiString;
220 request->attributes[attrIndex].data = (unsigned char *)caAttr;
221 request->attributes[attrIndex].len = caAttrLen;
222 attrIndex++;
223 }
224 if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) {
225 attrArray[attrIndex] = &(request->attributes[attrIndex]);
226 request->attributes[attrIndex].type = siAsciiString;
227 request->attributes[attrIndex].data = (unsigned char *)uAttr;
228 request->attributes[attrIndex].len = uAttrLen;
229 attrIndex++;
230 }
231 if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) {
232 attrArray[attrIndex] = &(request->attributes[attrIndex]);
233 request->attributes[attrIndex].type = siAsciiString;
234 request->attributes[attrIndex].data = (unsigned char *)ccpAttr;
235 request->attributes[attrIndex].len = ccpAttrLen;
236 attrIndex++;
237 }
238 if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) {
239 attrArray[attrIndex] = &(request->attributes[attrIndex]);
240 request->attributes[attrIndex].type = siAsciiString;
241 request->attributes[attrIndex].data = (unsigned char *)crlAttr;
242 request->attributes[attrIndex].len = crlAttrLen;
243 attrIndex++;
244 }
245 if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) {
246 attrArray[attrIndex] = &(request->attributes[attrIndex]);
247 request->attributes[attrIndex].type = siAsciiString;
248 request->attributes[attrIndex].data = (unsigned char *)arlAttr;
249 request->attributes[attrIndex].len = arlAttrLen;
250 attrIndex++;
251 }
252 attrArray[attrIndex] = (SECItem *)NULL;
253
254 PKIX_RETURN(LDAPREQUEST);
255 }
256
257 /*
258 * FUNCTION: pkix_pl_LdapRequest_Destroy
259 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
260 */
261 static PKIX_Error *
262 pkix_pl_LdapRequest_Destroy(
263 PKIX_PL_Object *object,
264 void *plContext)
265 {
266 PKIX_PL_LdapRequest *ldapRq = NULL;
267
268 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy");
269 PKIX_NULLCHECK_ONE(object);
270
271 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
272 PKIX_OBJECTNOTLDAPREQUEST);
273
274 ldapRq = (PKIX_PL_LdapRequest *)object;
275
276 /*
277 * All dynamic fields in an LDAPRequest are allocated
278 * in an arena, and will be freed when the arena is destroyed.
279 */
280
281 cleanup:
282
283 PKIX_RETURN(LDAPREQUEST);
284 }
285
286 /*
287 * FUNCTION: pkix_pl_LdapRequest_Hashcode
288 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
289 */
290 static PKIX_Error *
291 pkix_pl_LdapRequest_Hashcode(
292 PKIX_PL_Object *object,
293 PKIX_UInt32 *pHashcode,
294 void *plContext)
295 {
296 PKIX_UInt32 dataLen = 0;
297 PKIX_UInt32 dindex = 0;
298 PKIX_UInt32 sizeOfLength = 0;
299 PKIX_UInt32 idLen = 0;
300 const unsigned char *msgBuf = NULL;
301 PKIX_PL_LdapRequest *ldapRq = NULL;
302
303 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode");
304 PKIX_NULLCHECK_TWO(object, pHashcode);
305
306 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
307 PKIX_OBJECTNOTLDAPREQUEST);
308
309 ldapRq = (PKIX_PL_LdapRequest *)object;
310
311 *pHashcode = 0;
312
313 /*
314 * Two requests that differ only in msgnum are a match! Therefore,
315 * start hashcoding beyond the encoded messageID field.
316 */
317 if (ldapRq->encoded) {
318 msgBuf = (const unsigned char *)ldapRq->encoded->data;
319 /* Is message length short form (one octet) or long form? */
320 if ((msgBuf[1] & 0x80) != 0) {
321 sizeOfLength = msgBuf[1] & 0x7F;
322 for (dindex = 0; dindex < sizeOfLength; dindex++) {
323 dataLen = (dataLen << 8) + msgBuf[dindex + 2];
324 }
325 } else {
326 dataLen = msgBuf[1];
327 }
328
329 /* How many bytes for the messageID? (Assume short form) */
330 idLen = msgBuf[dindex + 3] + 2;
331 dindex += idLen;
332 dataLen -= idLen;
333 msgBuf = &msgBuf[dindex + 2];
334
335 PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
336 PKIX_HASHFAILED);
337 }
338
339 cleanup:
340
341 PKIX_RETURN(LDAPREQUEST);
342
343 }
344
345 /*
346 * FUNCTION: pkix_pl_LdapRequest_Equals
347 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
348 */
349 static PKIX_Error *
350 pkix_pl_LdapRequest_Equals(
351 PKIX_PL_Object *firstObj,
352 PKIX_PL_Object *secondObj,
353 PKIX_Boolean *pResult,
354 void *plContext)
355 {
356 PKIX_PL_LdapRequest *firstReq = NULL;
357 PKIX_PL_LdapRequest *secondReq = NULL;
358 PKIX_UInt32 secondType = 0;
359 PKIX_UInt32 firstLen = 0;
360 const unsigned char *firstData = NULL;
361 const unsigned char *secondData = NULL;
362 PKIX_UInt32 sizeOfLength = 0;
363 PKIX_UInt32 dindex = 0;
364 PKIX_UInt32 i = 0;
365
366 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals");
367 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
368
369 /* test that firstObj is a LdapRequest */
370 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext),
371 PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST);
372
373 /*
374 * Since we know firstObj is a LdapRequest, if both references are
375 * identical, they must be equal
376 */
377 if (firstObj == secondObj){
378 *pResult = PKIX_TRUE;
379 goto cleanup;
380 }
381
382 /*
383 * If secondObj isn't a LdapRequest, we don't throw an error.
384 * We simply return a Boolean result of FALSE
385 */
386 *pResult = PKIX_FALSE;
387 PKIX_CHECK(PKIX_PL_Object_GetType
388 (secondObj, &secondType, plContext),
389 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
390 if (secondType != PKIX_LDAPREQUEST_TYPE) {
391 goto cleanup;
392 }
393
394 firstReq = (PKIX_PL_LdapRequest *)firstObj;
395 secondReq = (PKIX_PL_LdapRequest *)secondObj;
396
397 /* If either lacks an encoded string, they cannot be compared */
398 if (!(firstReq->encoded) || !(secondReq->encoded)) {
399 goto cleanup;
400 }
401
402 if (firstReq->encoded->len != secondReq->encoded->len) {
403 goto cleanup;
404 }
405
406 firstData = (const unsigned char *)firstReq->encoded->data;
407 secondData = (const unsigned char *)secondReq->encoded->data;
408
409 /*
410 * Two requests that differ only in msgnum are equal! Therefore,
411 * start the byte comparison beyond the encoded messageID field.
412 */
413
414 /* Is message length short form (one octet) or long form? */
415 if ((firstData[1] & 0x80) != 0) {
416 sizeOfLength = firstData[1] & 0x7F;
417 for (dindex = 0; dindex < sizeOfLength; dindex++) {
418 firstLen = (firstLen << 8) + firstData[dindex + 2];
419 }
420 } else {
421 firstLen = firstData[1];
422 }
423
424 /* How many bytes for the messageID? (Assume short form) */
425 i = firstData[dindex + 3] + 2;
426 dindex += i;
427 firstLen -= i;
428 firstData = &firstData[dindex + 2];
429
430 /*
431 * In theory, we have to calculate where the second message data
432 * begins by checking its length encodings. But if these messages
433 * are equal, we can re-use the calculation we already did. If they
434 * are not equal, the byte comparisons will surely fail.
435 */
436
437 secondData = &secondData[dindex + 2];
438
439 for (i = 0; i < firstLen; i++) {
440 if (firstData[i] != secondData[i]) {
441 goto cleanup;
442 }
443 }
444
445 *pResult = PKIX_TRUE;
446
447 cleanup:
448
449 PKIX_RETURN(LDAPREQUEST);
450 }
451
452 /*
453 * FUNCTION: pkix_pl_LdapRequest_RegisterSelf
454 * DESCRIPTION:
455 * Registers PKIX_LDAPREQUEST_TYPE and its related functions with
456 * systemClasses[]
457 * PARAMETERS:
458 * "plContext"
459 * Platform-specific context pointer.
460 * THREAD SAFETY:
461 * Not Thread Safe - for performance and complexity reasons
462 *
463 * Since this function is only called by PKIX_PL_Initialize, which should
464 * only be called once, it is acceptable that this function is not
465 * thread-safe.
466 */
467 PKIX_Error *
468 pkix_pl_LdapRequest_RegisterSelf(void *plContext)
469 {
470 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
471 pkix_ClassTable_Entry entry;
472
473 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf");
474
475 entry.description = "LdapRequest";
476 entry.objCounter = 0;
477 entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest);
478 entry.destructor = pkix_pl_LdapRequest_Destroy;
479 entry.equalsFunction = pkix_pl_LdapRequest_Equals;
480 entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode;
481 entry.toStringFunction = NULL;
482 entry.comparator = NULL;
483 entry.duplicateFunction = pkix_duplicateImmutable;
484
485 systemClasses[PKIX_LDAPREQUEST_TYPE] = entry;
486
487 PKIX_RETURN(LDAPREQUEST);
488 }
489
490 /* --Public-Functions------------------------------------------------------- */
491
492 /*
493 * FUNCTION: pkix_pl_LdapRequest_Create
494 * DESCRIPTION:
495 *
496 * This function creates an LdapRequest using the PLArenaPool pointed to by
497 * "arena", a message number whose value is "msgnum", a base object pointed to
498 * by "issuerDN", a scope whose value is "scope", a derefAliases flag whose
499 * value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit
500 * whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a
501 * filter whose value is "filter", and attribute bits whose value is
502 * "attrBits"; storing the result at "pRequestMsg".
503 *
504 * See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of
505 * message components, and see pkix_pl_ldapt.h for data types.
506 *
507 * PARAMETERS
508 * "arena"
509 * The address of the PLArenaPool to be used in the encoding. Must be
510 * non-NULL.
511 * "msgnum"
512 * The UInt32 message number to be used for the messageID component of the
513 * LDAP message exchange.
514 * "issuerDN"
515 * The address of the string to be used for the baseObject component of the
516 * LDAP SearchRequest message. Must be non-NULL.
517 * "scope"
518 * The (enumerated) ScopeType to be used for the scope component of the
519 * LDAP SearchRequest message
520 * "derefAliases"
521 * The (enumerated) DerefType to be used for the derefAliases component of
522 * the LDAP SearchRequest message
523 * "sizeLimit"
524 * The UInt32 value to be used for the sizeLimit component of the LDAP
525 * SearchRequest message
526 * "timeLimit"
527 * The UInt32 value to be used for the timeLimit component of the LDAP
528 * SearchRequest message
529 * "attrsOnly"
530 * The Boolean value to be used for the attrsOnly component of the LDAP
531 * SearchRequest message
532 * "filter"
533 * The filter to be used for the filter component of the LDAP
534 * SearchRequest message
535 * "attrBits"
536 * The LdapAttrMask bits indicating the attributes to be included in the
537 * attributes sequence of the LDAP SearchRequest message
538 * "pRequestMsg"
539 * The address at which the address of the LdapRequest is stored. Must
540 * be non-NULL.
541 * "plContext"
542 * Platform-specific context pointer.
543 * THREAD SAFETY:
544 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
545 * RETURNS:
546 * Returns NULL if the function succeeds.
547 * Returns an LdapRequest Error if the function fails in a non-fatal way.
548 * Returns a Fatal Error if the function fails in an unrecoverable way.
549 */
550 /*
551 * SearchRequest ::=
552 * [APPLICATION 3] SEQUENCE {
553 * baseObject LDAPDN,
554 * scope ENUMERATED {
555 * baseObject (0),
556 * singleLevel (1),
557 * wholeSubtree (2)
558 * },
559 * derefAliases ENUMERATED {
560 * neverDerefAliases (0),
561 * derefInSearching (1),
562 * derefFindingBaseObj (2),
563 * alwaysDerefAliases (3)
564 * },
565 * sizeLimit INTEGER (0 .. MAXINT),
566 * -- value of 0 implies no sizeLimit
567 * timeLimit INTEGER (0 .. MAXINT),
568 * -- value of 0 implies no timeLimit
569 * attrsOnly BOOLEAN,
570 * -- TRUE, if only attributes (without values)
571 * -- to be returned
572 * filter Filter,
573 * attributes SEQUENCE OF AttributeType
574 * }
575 *
576 * Filter ::=
577 * CHOICE {
578 * and [0] SET OF Filter,
579 * or [1] SET OF Filter,
580 * not [2] Filter,
581 * equalityMatch [3] AttributeValueAssertion,
582 * substrings [4] SubstringFilter,
583 * greaterOrEqual [5] AttributeValueAssertion,
584 * lessOrEqual [6] AttributeValueAssertion,
585 * present [7] AttributeType,
586 * approxMatch [8] AttributeValueAssertion
587 * }
588 *
589 * SubstringFilter ::=
590 * SEQUENCE {
591 * type AttributeType,
592 * SEQUENCE OF CHOICE {
593 * initial [0] LDAPString,
594 * any [1] LDAPString,
595 * final [2] LDAPString,
596 * }
597 * }
598 *
599 * AttributeValueAssertion ::=
600 * SEQUENCE {
601 * attributeType AttributeType,
602 * attributeValue AttributeValue,
603 * }
604 *
605 * AttributeValue ::= OCTET STRING
606 *
607 * AttributeType ::= LDAPString
608 * -- text name of the attribute, or dotted
609 * -- OID representation
610 *
611 * LDAPDN ::= LDAPString
612 *
613 * LDAPString ::= OCTET STRING
614 *
615 */
616 PKIX_Error *
617 pkix_pl_LdapRequest_Create(
618 PLArenaPool *arena,
619 PKIX_UInt32 msgnum,
620 char *issuerDN,
621 ScopeType scope,
622 DerefType derefAliases,
623 PKIX_UInt32 sizeLimit,
624 PKIX_UInt32 timeLimit,
625 char attrsOnly,
626 LDAPFilter *filter,
627 LdapAttrMask attrBits,
628 PKIX_PL_LdapRequest **pRequestMsg,
629 void *plContext)
630 {
631 LDAPMessage msg;
632 LDAPSearch *search;
633 PKIX_PL_LdapRequest *ldapRequest = NULL;
634 char scopeTypeAsChar;
635 char derefAliasesTypeAsChar;
636 SECItem *attrArray[MAX_LDAPATTRS + 1];
637
638 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create");
639 PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg);
640
641 /* create a PKIX_PL_LdapRequest object */
642 PKIX_CHECK(PKIX_PL_Object_Alloc
643 (PKIX_LDAPREQUEST_TYPE,
644 sizeof (PKIX_PL_LdapRequest),
645 (PKIX_PL_Object **)&ldapRequest,
646 plContext),
647 PKIX_COULDNOTCREATEOBJECT);
648
649 ldapRequest->arena = arena;
650 ldapRequest->msgnum = msgnum;
651 ldapRequest->issuerDN = issuerDN;
652 ldapRequest->scope = scope;
653 ldapRequest->derefAliases = derefAliases;
654 ldapRequest->sizeLimit = sizeLimit;
655 ldapRequest->timeLimit = timeLimit;
656 ldapRequest->attrsOnly = attrsOnly;
657 ldapRequest->filter = filter;
658 ldapRequest->attrBits = attrBits;
659
660 ldapRequest->attrArray = attrArray;
661
662 PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs
663 (ldapRequest, plContext),
664 PKIX_LDAPREQUESTENCODEATTRSFAILED);
665
666 PKIX_PL_NSSCALL
667 (LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage)));
668
669 msg.messageID.type = siUnsignedInteger;
670 msg.messageID.data = (void*)&msgnum;
671 msg.messageID.len = sizeof (msgnum);
672
673 msg.protocolOp.selector = LDAP_SEARCH_TYPE;
674
675 search = &(msg.protocolOp.op.searchMsg);
676
677 search->baseObject.type = siAsciiString;
678 search->baseObject.data = (void *)issuerDN;
679 search->baseObject.len = PL_strlen(issuerDN);
680 scopeTypeAsChar = (char)scope;
681 search->scope.type = siUnsignedInteger;
682 search->scope.data = (void *)&scopeTypeAsChar;
683 search->scope.len = sizeof (scopeTypeAsChar);
684 derefAliasesTypeAsChar = (char)derefAliases;
685 search->derefAliases.type = siUnsignedInteger;
686 search->derefAliases.data =
687 (void *)&derefAliasesTypeAsChar;
688 search->derefAliases.len =
689 sizeof (derefAliasesTypeAsChar);
690 search->sizeLimit.type = siUnsignedInteger;
691 search->sizeLimit.data = (void *)&sizeLimit;
692 search->sizeLimit.len = sizeof (PKIX_UInt32);
693 search->timeLimit.type = siUnsignedInteger;
694 search->timeLimit.data = (void *)&timeLimit;
695 search->timeLimit.len = sizeof (PKIX_UInt32);
696 search->attrsOnly.type = siBuffer;
697 search->attrsOnly.data = (void *)&attrsOnly;
698 search->attrsOnly.len = sizeof (attrsOnly);
699
700 PKIX_PL_NSSCALL
701 (LDAPREQUEST,
702 PORT_Memcpy,
703 (&search->filter, filter, sizeof (LDAPFilter)));
704
705 search->attributes = attrArray;
706
707 PKIX_PL_NSSCALLRV
708 (LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem,
709 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
710
711 if (!(ldapRequest->encoded)) {
712 PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST);
713 }
714
715 *pRequestMsg = ldapRequest;
716
717 cleanup:
718
719 if (PKIX_ERROR_RECEIVED) {
720 PKIX_DECREF(ldapRequest);
721 }
722
723 PKIX_RETURN(LDAPREQUEST);
724 }
725
726 /*
727 * FUNCTION: pkix_pl_LdapRequest_GetEncoded
728 * DESCRIPTION:
729 *
730 * This function obtains the encoded message from the LdapRequest pointed to
731 * by "request", storing the result at "pRequestBuf".
732 *
733 * PARAMETERS
734 * "request"
735 * The address of the LdapRequest whose encoded message is to be
736 * retrieved. Must be non-NULL.
737 * "pRequestBuf"
738 * The address at which is stored the address of the encoded message. Must
739 * be non-NULL.
740 * "plContext"
741 * Platform-specific context pointer.
742 * THREAD SAFETY:
743 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
744 * RETURNS:
745 * Returns NULL if the function succeeds.
746 * Returns an LdapRequest Error if the function fails in a non-fatal way.
747 * Returns a Fatal Error if the function fails in an unrecoverable way.
748 */
749 PKIX_Error *
750 pkix_pl_LdapRequest_GetEncoded(
751 PKIX_PL_LdapRequest *request,
752 SECItem **pRequestBuf,
753 void *plContext)
754 {
755 PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded");
756 PKIX_NULLCHECK_TWO(request, pRequestBuf);
757
758 *pRequestBuf = request->encoded;
759
760 PKIX_RETURN(LDAPREQUEST);
761 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)