nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / module / pkix_pl_ldapresponse.c
bloba3915b1a4b486050d6996ca445e11c771242bd87
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
21 * Contributor(s):
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_pl_ldapresponse.c
42 #include <fcntl.h>
43 #include "pkix_pl_ldapresponse.h"
45 /* --Private-LdapResponse-Functions------------------------------------- */
48 * FUNCTION: pkix_pl_LdapResponse_Destroy
49 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
51 static PKIX_Error *
52 pkix_pl_LdapResponse_Destroy(
53 PKIX_PL_Object *object,
54 void *plContext)
56 PKIX_PL_LdapResponse *ldapRsp = NULL;
57 LDAPMessage *m = NULL;
58 LDAPSearchResponseEntry *entry = NULL;
59 LDAPSearchResponseResult *result = NULL;
60 LDAPSearchResponseAttr **attributes = NULL;
61 LDAPSearchResponseAttr *attr = NULL;
62 SECItem **valp = NULL;
63 SECItem *val = NULL;
65 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Destroy");
66 PKIX_NULLCHECK_ONE(object);
68 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
69 PKIX_OBJECTNOTLDAPRESPONSE);
71 ldapRsp = (PKIX_PL_LdapResponse *)object;
73 m = &ldapRsp->decoded;
75 if (m->messageID.data != NULL) {
76 PR_Free(m->messageID.data);
79 if (m->protocolOp.selector ==
80 LDAP_SEARCHRESPONSEENTRY_TYPE) {
81 entry = &m->protocolOp.op.searchResponseEntryMsg;
82 if (entry->objectName.data != NULL) {
83 PR_Free(entry->objectName.data);
85 if (entry->attributes != NULL) {
86 for (attributes = entry->attributes;
87 *attributes != NULL;
88 attributes++) {
89 attr = *attributes;
90 PR_Free(attr->attrType.data);
91 for (valp = attr->val; *valp != NULL; valp++) {
92 val = *valp;
93 if (val->data != NULL) {
94 PR_Free(val->data);
96 PR_Free(val);
98 PR_Free(attr->val);
99 PR_Free(attr);
101 PR_Free(entry->attributes);
103 } else if (m->protocolOp.selector ==
104 LDAP_SEARCHRESPONSERESULT_TYPE) {
105 result = &m->protocolOp.op.searchResponseResultMsg;
106 if (result->resultCode.data != NULL) {
107 PR_Free(result->resultCode.data);
111 PKIX_FREE(ldapRsp->derEncoded.data);
113 cleanup:
115 PKIX_RETURN(LDAPRESPONSE);
119 * FUNCTION: pkix_pl_LdapResponse_Hashcode
120 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
122 static PKIX_Error *
123 pkix_pl_LdapResponse_Hashcode(
124 PKIX_PL_Object *object,
125 PKIX_UInt32 *pHashcode,
126 void *plContext)
128 PKIX_UInt32 dataLen = 0;
129 PKIX_UInt32 dindex = 0;
130 PKIX_UInt32 sizeOfLength = 0;
131 PKIX_UInt32 idLen = 0;
132 const unsigned char *msgBuf = NULL;
133 PKIX_PL_LdapResponse *ldapRsp = NULL;
135 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Hashcode");
136 PKIX_NULLCHECK_TWO(object, pHashcode);
138 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
139 PKIX_OBJECTNOTLDAPRESPONSE);
141 ldapRsp = (PKIX_PL_LdapResponse *)object;
143 *pHashcode = 0;
146 * Two responses that differ only in msgnum are a match! Therefore,
147 * start hashcoding beyond the encoded messageID field.
149 if (ldapRsp->derEncoded.data) {
150 msgBuf = (const unsigned char *)ldapRsp->derEncoded.data;
151 /* Is message length short form (one octet) or long form? */
152 if ((msgBuf[1] & 0x80) != 0) {
153 sizeOfLength = msgBuf[1] & 0x7F;
154 for (dindex = 0; dindex < sizeOfLength; dindex++) {
155 dataLen = (dataLen << 8) + msgBuf[dindex + 2];
157 } else {
158 dataLen = msgBuf[1];
161 /* How many bytes for the messageID? (Assume short form) */
162 idLen = msgBuf[dindex + 3] + 2;
163 dindex += idLen;
164 dataLen -= idLen;
165 msgBuf = &msgBuf[dindex + 2];
167 PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
168 PKIX_HASHFAILED);
171 cleanup:
173 PKIX_RETURN(LDAPRESPONSE);
178 * FUNCTION: pkix_pl_LdapResponse_Equals
179 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
181 static PKIX_Error *
182 pkix_pl_LdapResponse_Equals(
183 PKIX_PL_Object *firstObj,
184 PKIX_PL_Object *secondObj,
185 PKIX_Boolean *pResult,
186 void *plContext)
188 PKIX_PL_LdapResponse *rsp1 = NULL;
189 PKIX_PL_LdapResponse *rsp2 = NULL;
190 PKIX_UInt32 secondType = 0;
191 PKIX_UInt32 firstLen = 0;
192 const unsigned char *firstData = NULL;
193 const unsigned char *secondData = NULL;
194 PKIX_UInt32 sizeOfLength = 0;
195 PKIX_UInt32 dindex = 0;
196 PKIX_UInt32 i = 0;
198 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Equals");
199 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
201 /* test that firstObj is a LdapResponse */
202 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPRESPONSE_TYPE, plContext),
203 PKIX_FIRSTOBJARGUMENTNOTLDAPRESPONSE);
206 * Since we know firstObj is a LdapResponse, if both references are
207 * identical, they must be equal
209 if (firstObj == secondObj){
210 *pResult = PKIX_TRUE;
211 goto cleanup;
215 * If secondObj isn't a LdapResponse, we don't throw an error.
216 * We simply return a Boolean result of FALSE
218 *pResult = PKIX_FALSE;
219 PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext),
220 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
221 if (secondType != PKIX_LDAPRESPONSE_TYPE) {
222 goto cleanup;
225 rsp1 = (PKIX_PL_LdapResponse *)firstObj;
226 rsp2 = (PKIX_PL_LdapResponse *)secondObj;
228 /* If either lacks an encoded string, they cannot be compared */
229 if (!(rsp1->derEncoded.data) || !(rsp2->derEncoded.data)) {
230 goto cleanup;
233 if (rsp1->derEncoded.len != rsp2->derEncoded.len) {
234 goto cleanup;
237 firstData = (const unsigned char *)rsp1->derEncoded.data;
238 secondData = (const unsigned char *)rsp2->derEncoded.data;
241 * Two responses that differ only in msgnum are equal! Therefore,
242 * start the byte comparison beyond the encoded messageID field.
245 /* Is message length short form (one octet) or long form? */
246 if ((firstData[1] & 0x80) != 0) {
247 sizeOfLength = firstData[1] & 0x7F;
248 for (dindex = 0; dindex < sizeOfLength; dindex++) {
249 firstLen = (firstLen << 8) + firstData[dindex + 2];
251 } else {
252 firstLen = firstData[1];
255 /* How many bytes for the messageID? (Assume short form) */
256 i = firstData[dindex + 3] + 2;
257 dindex += i;
258 firstLen -= i;
259 firstData = &firstData[dindex + 2];
262 * In theory, we have to calculate where the second message data
263 * begins by checking its length encodings. But if these messages
264 * are equal, we can re-use the calculation we already did. If they
265 * are not equal, the byte comparisons will surely fail.
268 secondData = &secondData[dindex + 2];
270 for (i = 0; i < firstLen; i++) {
271 if (firstData[i] != secondData[i]) {
272 goto cleanup;
276 *pResult = PKIX_TRUE;
278 cleanup:
280 PKIX_RETURN(LDAPRESPONSE);
284 * FUNCTION: pkix_pl_LdapResponse_RegisterSelf
285 * DESCRIPTION:
286 * Registers PKIX_LDAPRESPONSE_TYPE and its related functions with
287 * systemClasses[]
288 * PARAMETERS:
289 * "plContext"
290 * Platform-specific context pointer.
291 * THREAD SAFETY:
292 * Not Thread Safe - for performance and complexity reasons
294 * Since this function is only called by PKIX_PL_Initialize, which should
295 * only be called once, it is acceptable that this function is not
296 * thread-safe.
298 PKIX_Error *
299 pkix_pl_LdapResponse_RegisterSelf(void *plContext)
301 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
302 pkix_ClassTable_Entry entry;
304 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_RegisterSelf");
306 entry.description = "LdapResponse";
307 entry.objCounter = 0;
308 entry.typeObjectSize = sizeof(PKIX_PL_LdapResponse);
309 entry.destructor = pkix_pl_LdapResponse_Destroy;
310 entry.equalsFunction = pkix_pl_LdapResponse_Equals;
311 entry.hashcodeFunction = pkix_pl_LdapResponse_Hashcode;
312 entry.toStringFunction = NULL;
313 entry.comparator = NULL;
314 entry.duplicateFunction = pkix_duplicateImmutable;
316 systemClasses[PKIX_LDAPRESPONSE_TYPE] = entry;
318 PKIX_RETURN(LDAPRESPONSE);
321 /* --Public-Functions------------------------------------------------------- */
324 * FUNCTION: pkix_pl_LdapResponse_Create
325 * DESCRIPTION:
327 * This function creates an LdapResponse for the LDAPMessageType provided in
328 * "responseType" and a buffer capacity provided by "totalLength". It copies
329 * into its buffer either "totalLength" or "bytesAvailable" bytes, whichever
330 * is less, from the buffer pointed to by "partialData", storing the number of
331 * bytes copied at "pBytesConsumed" and storing the address of the LdapResponse
332 * at "pLdapResponse".
334 * If a message is complete in a single I/O buffer, the LdapResponse will be
335 * complete when this function returns. If the message carries over into
336 * additional buffers, their contents will be added to the LdapResponse by
337 * susequent calls to pkix_pl_LdapResponse_Append.
339 * PARAMETERS
340 * "responseType"
341 * The value of the message type (LDAP_SEARCHRESPONSEENTRY_TYPE or
342 * LDAP_SEARCHRESPONSERESULT_TYPE) for the LdapResponse being created
343 * "totalLength"
344 * The UInt32 value for the total length of the encoded message to be
345 * stored in the LdapResponse
346 * "bytesAvailable"
347 * The UInt32 value for the number of bytes of data available in the
348 * current buffer.
349 * "partialData"
350 * The address from which data is to be copied.
351 * "pBytesConsumed"
352 * The address at which is stored the UInt32 number of bytes taken from the
353 * current buffer. If this number is less than "bytesAvailable", then bytes
354 * remain in the buffer for the next LdapResponse. Must be non-NULL.
355 * "pLdapResponse"
356 * The address where the created LdapResponse is stored. Must be non-NULL.
357 * "plContext"
358 * Platform-specific context pointer.
359 * THREAD SAFETY:
360 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
361 * RETURNS:
362 * Returns NULL if the function succeeds.
363 * Returns an LdapResponse Error if the function fails in a non-fatal way.
364 * Returns a Fatal Error if the function fails in an unrecoverable way.
366 PKIX_Error *
367 pkix_pl_LdapResponse_Create(
368 LDAPMessageType responseType,
369 PKIX_UInt32 totalLength,
370 PKIX_UInt32 bytesAvailable,
371 void *partialData,
372 PKIX_UInt32 *pBytesConsumed,
373 PKIX_PL_LdapResponse **pLdapResponse,
374 void *plContext)
376 PKIX_UInt32 bytesConsumed = 0;
377 PKIX_PL_LdapResponse *ldapResponse = NULL;
378 void *data = NULL;
380 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Create");
381 PKIX_NULLCHECK_ONE(pLdapResponse);
383 if (bytesAvailable <= totalLength) {
384 bytesConsumed = bytesAvailable;
385 } else {
386 bytesConsumed = totalLength;
389 /* create a PKIX_PL_LdapResponse object */
390 PKIX_CHECK(PKIX_PL_Object_Alloc
391 (PKIX_LDAPRESPONSE_TYPE,
392 sizeof (PKIX_PL_LdapResponse),
393 (PKIX_PL_Object **)&ldapResponse,
394 plContext),
395 PKIX_COULDNOTCREATEOBJECT);
397 ldapResponse->decoded.protocolOp.selector = responseType;
398 ldapResponse->totalLength = totalLength;
399 ldapResponse->partialLength = bytesConsumed;
401 if (totalLength != 0){
402 /* Alloc space for array */
403 PKIX_NULLCHECK_ONE(partialData);
405 PKIX_CHECK(PKIX_PL_Malloc
406 (totalLength,
407 &data,
408 plContext),
409 PKIX_MALLOCFAILED);
411 PKIX_PL_NSSCALL
412 (LDAPRESPONSE,
413 PORT_Memcpy,
414 (data, partialData, bytesConsumed));
417 ldapResponse->derEncoded.type = siBuffer;
418 ldapResponse->derEncoded.data = data;
419 ldapResponse->derEncoded.len = totalLength;
420 *pBytesConsumed = bytesConsumed;
421 *pLdapResponse = ldapResponse;
423 cleanup:
425 if (PKIX_ERROR_RECEIVED){
426 PKIX_DECREF(ldapResponse);
429 PKIX_RETURN(LDAPRESPONSE);
433 * FUNCTION: pkix_pl_LdapResponse_Append
434 * DESCRIPTION:
436 * This function updates the LdapResponse pointed to by "response" with up to
437 * "incrLength" from the buffer pointer to by "incrData", storing the number of
438 * bytes copied at "pBytesConsumed".
440 * PARAMETERS
441 * "response"
442 * The address of the LdapResponse being updated. Must be non-zero.
443 * "incrLength"
444 * The UInt32 value for the number of bytes of data available in the
445 * current buffer.
446 * "incrData"
447 * The address from which data is to be copied.
448 * "pBytesConsumed"
449 * The address at which is stored the UInt32 number of bytes taken from the
450 * current buffer. If this number is less than "incrLength", then bytes
451 * remain in the buffer for the next LdapResponse. Must be non-NULL.
452 * "plContext"
453 * Platform-specific context pointer.
454 * THREAD SAFETY:
455 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
456 * RETURNS:
457 * Returns NULL if the function succeeds.
458 * Returns an LdapResponse Error if the function fails in a non-fatal way.
459 * Returns a Fatal Error if the function fails in an unrecoverable way.
461 PKIX_Error *
462 pkix_pl_LdapResponse_Append(
463 PKIX_PL_LdapResponse *response,
464 PKIX_UInt32 incrLength,
465 void *incrData,
466 PKIX_UInt32 *pBytesConsumed,
467 void *plContext)
469 PKIX_UInt32 newPartialLength = 0;
470 PKIX_UInt32 bytesConsumed = 0;
471 void *dest = NULL;
473 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Append");
474 PKIX_NULLCHECK_TWO(response, pBytesConsumed);
476 if (incrLength > 0) {
478 /* Calculate how many bytes we have room for. */
479 bytesConsumed =
480 response->totalLength - response->partialLength;
482 if (bytesConsumed > incrLength) {
483 bytesConsumed = incrLength;
486 newPartialLength = response->partialLength + bytesConsumed;
488 PKIX_NULLCHECK_ONE(incrData);
490 dest = &(((char *)response->derEncoded.data)[
491 response->partialLength]);
493 PKIX_PL_NSSCALL
494 (LDAPRESPONSE,
495 PORT_Memcpy,
496 (dest, incrData, bytesConsumed));
498 response->partialLength = newPartialLength;
501 *pBytesConsumed = bytesConsumed;
503 PKIX_RETURN(LDAPRESPONSE);
507 * FUNCTION: pkix_pl_LdapResponse_IsComplete
508 * DESCRIPTION:
510 * This function determines whether the LdapResponse pointed to by "response"
511 * contains all the data called for by the "totalLength" parameter provided
512 * when it was created, storing PKIX_TRUE at "pIsComplete" if so, and
513 * PKIX_FALSE otherwise.
515 * PARAMETERS
516 * "response"
517 * The address of the LdapResponse being evaluaTED. Must be non-zero.
518 * "incrLength"
519 * The UInt32 value for the number of bytes of data available in the
520 * current buffer.
521 * "incrData"
522 * The address from which data is to be copied.
523 * "pIsComplete"
524 * The address at which is stored the Boolean indication of whether the
525 * LdapResponse is complete. Must be non-NULL.
526 * "plContext"
527 * Platform-specific context pointer.
528 * THREAD SAFETY:
529 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
530 * RETURNS:
531 * Returns NULL if the function succeeds.
532 * Returns an LdapResponse Error if the function fails in a non-fatal way.
533 * Returns a Fatal Error if the function fails in an unrecoverable way.
535 PKIX_Error *
536 pkix_pl_LdapResponse_IsComplete(
537 PKIX_PL_LdapResponse *response,
538 PKIX_Boolean *pIsComplete,
539 void *plContext)
541 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_IsComplete");
542 PKIX_NULLCHECK_TWO(response, pIsComplete);
544 if (response->totalLength == response->partialLength) {
545 *pIsComplete = PKIX_TRUE;
546 } else {
547 *pIsComplete = PKIX_FALSE;
550 PKIX_RETURN(LDAPRESPONSE);
554 * FUNCTION: pkix_pl_LdapResponse_Decode
555 * DESCRIPTION:
557 * This function decodes the DER data contained in the LdapResponse pointed to
558 * by "response", using the arena pointed to by "arena", and storing at
559 * "pStatus" SECSuccess if the decoding was successful and SECFailure
560 * otherwise. The decoded message is stored in an element of "response".
562 * PARAMETERS
563 * "arena"
564 * The address of the PRArenaPool to be used in the decoding. Must be
565 * non-NULL.
566 * "response"
567 * The address of the LdapResponse whose DER data is to be decoded. Must
568 * be non-NULL.
569 * "pStatus"
570 * The address at which is stored the status from the decoding, SECSuccess
571 * if successful, SECFailure otherwise. Must be non-NULL.
572 * "plContext"
573 * Platform-specific context pointer.
574 * THREAD SAFETY:
575 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
576 * RETURNS:
577 * Returns NULL if the function succeeds.
578 * Returns an LdapResponse Error if the function fails in a non-fatal way.
579 * Returns a Fatal Error if the function fails in an unrecoverable way.
581 PKIX_Error *
582 pkix_pl_LdapResponse_Decode(
583 PRArenaPool *arena,
584 PKIX_PL_LdapResponse *response,
585 SECStatus *pStatus,
586 void *plContext)
588 LDAPMessage *msg;
589 SECStatus rv = SECFailure;
591 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Decode");
592 PKIX_NULLCHECK_THREE(arena, response, pStatus);
594 if (response->totalLength != response->partialLength) {
595 PKIX_ERROR(PKIX_ATTEMPTTODECODEANINCOMPLETERESPONSE);
598 msg = &(response->decoded);
600 PKIX_PL_NSSCALL
601 (LDAPRESPONSE, PORT_Memset, (msg, 0, sizeof (LDAPMessage)));
603 PKIX_PL_NSSCALLRV(LDAPRESPONSE, rv, SEC_ASN1DecodeItem,
604 (NULL, msg, PKIX_PL_LDAPMessageTemplate, &(response->derEncoded)));
606 *pStatus = rv;
607 cleanup:
609 PKIX_RETURN(LDAPRESPONSE);
613 * FUNCTION: pkix_pl_LdapResponse_GetMessage
614 * DESCRIPTION:
616 * This function obtains the decoded message from the LdapResponse pointed to
617 * by "response", storing the result at "pMessage".
619 * PARAMETERS
620 * "response"
621 * The address of the LdapResponse whose decoded message is to be
622 * retrieved. Must be non-NULL.
623 * "pMessage"
624 * The address at which is stored the address of the decoded message. Must
625 * be non-NULL.
626 * "plContext"
627 * Platform-specific context pointer.
628 * THREAD SAFETY:
629 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
630 * RETURNS:
631 * Returns NULL if the function succeeds.
632 * Returns a Fatal Error if the function fails in an unrecoverable way.
634 PKIX_Error *
635 pkix_pl_LdapResponse_GetMessage(
636 PKIX_PL_LdapResponse *response,
637 LDAPMessage **pMessage,
638 void *plContext)
640 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessage");
641 PKIX_NULLCHECK_TWO(response, pMessage);
643 *pMessage = &response->decoded;
645 PKIX_RETURN(LDAPRESPONSE);
649 * FUNCTION: pkix_pl_LdapResponse_GetCapacity
650 * DESCRIPTION:
652 * This function obtains from the LdapResponse pointed to by "response" the
653 * number of bytes remaining to be read, based on the totalLength that was
654 * provided to LdapResponse_Create and the data subsequently provided to
655 * LdapResponse_Append, storing the result at "pMessage".
657 * PARAMETERS
658 * "response"
659 * The address of the LdapResponse whose remaining capacity is to be
660 * retrieved. Must be non-NULL.
661 * "pCapacity"
662 * The address at which is stored the address of the decoded message. Must
663 * be non-NULL.
664 * "plContext"
665 * Platform-specific context pointer.
666 * THREAD SAFETY:
667 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
668 * RETURNS:
669 * Returns NULL if the function succeeds.
670 * Returns an LdapResponse Error if the function fails in a non-fatal way.
671 * Returns a Fatal Error if the function fails in an unrecoverable way.
673 PKIX_Error *
674 pkix_pl_LdapResponse_GetCapacity(
675 PKIX_PL_LdapResponse *response,
676 PKIX_UInt32 *pCapacity,
677 void *plContext)
679 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetCapacity");
680 PKIX_NULLCHECK_TWO(response, pCapacity);
682 *pCapacity = response->totalLength - response->partialLength;
684 PKIX_RETURN(LDAPRESPONSE);
688 * FUNCTION: pkix_pl_LdapResponse_GetMessageType
689 * DESCRIPTION:
691 * This function obtains the message type from the LdapResponse pointed to
692 * by "response", storing the result at "pMessageType".
694 * PARAMETERS
695 * "response"
696 * The address of the LdapResponse whose message type is to be
697 * retrieved. Must be non-NULL.
698 * "pMessageType"
699 * The address at which is stored the type of the response message. Must
700 * be non-NULL.
701 * "plContext"
702 * Platform-specific context pointer.
703 * THREAD SAFETY:
704 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
705 * RETURNS:
706 * Returns NULL if the function succeeds.
707 * Returns a Fatal Error if the function fails in an unrecoverable way.
709 PKIX_Error *
710 pkix_pl_LdapResponse_GetMessageType(
711 PKIX_PL_LdapResponse *response,
712 LDAPMessageType *pMessageType,
713 void *plContext)
715 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessageType");
716 PKIX_NULLCHECK_TWO(response, pMessageType);
718 *pMessageType = response->decoded.protocolOp.selector;
720 PKIX_RETURN(LDAPRESPONSE);
724 * FUNCTION: pkix_pl_LdapResponse_GetResultCode
725 * DESCRIPTION:
727 * This function obtains the result code from the LdapResponse pointed to
728 * by "response", storing the result at "pResultCode".
730 * PARAMETERS
731 * "response"
732 * The address of the LdapResponse whose result code is to be
733 * retrieved. Must be non-NULL.
734 * "pResultCode"
735 * The address at which is stored the address of the decoded message. Must
736 * be non-NULL.
737 * "plContext"
738 * Platform-specific context pointer.
739 * THREAD SAFETY:
740 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
741 * RETURNS:
742 * Returns NULL if the function succeeds.
743 * Returns an LdapResponse Error if the function fails in a non-fatal way.
744 * Returns a Fatal Error if the function fails in an unrecoverable way.
746 PKIX_Error *
747 pkix_pl_LdapResponse_GetResultCode(
748 PKIX_PL_LdapResponse *response,
749 LDAPResultCode *pResultCode,
750 void *plContext)
752 LDAPMessageType messageType = 0;
753 LDAPSearchResponseResult *resultMsg = NULL;
755 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
756 PKIX_NULLCHECK_TWO(response, pResultCode);
758 messageType = response->decoded.protocolOp.selector;
760 if (messageType != LDAP_SEARCHRESPONSERESULT_TYPE) {
761 PKIX_ERROR(PKIX_GETRESULTCODECALLEDFORNONRESULTMESSAGE);
764 resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
766 *pResultCode = *(char *)(resultMsg->resultCode.data);
768 cleanup:
770 PKIX_RETURN(LDAPRESPONSE);
774 * FUNCTION: pkix_pl_LdapResponse_GetAttributes
775 * DESCRIPTION:
777 * This function obtains the attributes from the LdapResponse pointed to
778 * by "response", storing the result at "pAttributes".
780 * PARAMETERS
781 * "response"
782 * The address of the LdapResponse whose decoded message is to be
783 * retrieved. Must be non-NULL.
784 * "pAttributes"
785 * The address at which is stored the attributes of the message. Must be
786 * non-NULL.
787 * "plContext"
788 * Platform-specific context pointer.
789 * THREAD SAFETY:
790 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
791 * RETURNS:
792 * Returns NULL if the function succeeds.
793 * Returns an LdapResponse Error if the function fails in a non-fatal way.
794 * Returns a Fatal Error if the function fails in an unrecoverable way.
796 PKIX_Error *
797 pkix_pl_LdapResponse_GetAttributes(
798 PKIX_PL_LdapResponse *response,
799 LDAPSearchResponseAttr ***pAttributes,
800 void *plContext)
802 LDAPMessageType messageType = 0;
804 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
805 PKIX_NULLCHECK_TWO(response, pAttributes);
807 messageType = response->decoded.protocolOp.selector;
809 if (messageType != LDAP_SEARCHRESPONSEENTRY_TYPE) {
810 PKIX_ERROR(PKIX_GETATTRIBUTESCALLEDFORNONENTRYMESSAGE);
813 *pAttributes = response->
814 decoded.protocolOp.op.searchResponseEntryMsg.attributes;
816 cleanup:
818 PKIX_RETURN(LDAPRESPONSE);