Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / module / pkix_pl_ldapresponse.c
blobdd4c3b928c87163d4979201965f169c2e9e06acd
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 Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Sun Microsystems
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.destructor = pkix_pl_LdapResponse_Destroy;
308 entry.equalsFunction = pkix_pl_LdapResponse_Equals;
309 entry.hashcodeFunction = pkix_pl_LdapResponse_Hashcode;
310 entry.toStringFunction = NULL;
311 entry.comparator = NULL;
312 entry.duplicateFunction = pkix_duplicateImmutable;
314 systemClasses[PKIX_LDAPRESPONSE_TYPE] = entry;
316 PKIX_RETURN(LDAPRESPONSE);
319 /* --Public-Functions------------------------------------------------------- */
322 * FUNCTION: pkix_pl_LdapResponse_Create
323 * DESCRIPTION:
325 * This function creates an LdapResponse for the LDAPMessageType provided in
326 * "responseType" and a buffer capacity provided by "totalLength". It copies
327 * into its buffer either "totalLength" or "bytesAvailable" bytes, whichever
328 * is less, from the buffer pointed to by "partialData", storing the number of
329 * bytes copied at "pBytesConsumed" and storing the address of the LdapResponse
330 * at "pLdapResponse".
332 * If a message is complete in a single I/O buffer, the LdapResponse will be
333 * complete when this function returns. If the message carries over into
334 * additional buffers, their contents will be added to the LdapResponse by
335 * susequent calls to pkix_pl_LdapResponse_Append.
337 * PARAMETERS
338 * "responseType"
339 * The value of the message type (LDAP_SEARCHRESPONSEENTRY_TYPE or
340 * LDAP_SEARCHRESPONSERESULT_TYPE) for the LdapResponse being created
341 * "totalLength"
342 * The UInt32 value for the total length of the encoded message to be
343 * stored in the LdapResponse
344 * "bytesAvailable"
345 * The UInt32 value for the number of bytes of data available in the
346 * current buffer.
347 * "partialData"
348 * The address from which data is to be copied.
349 * "pBytesConsumed"
350 * The address at which is stored the UInt32 number of bytes taken from the
351 * current buffer. If this number is less than "bytesAvailable", then bytes
352 * remain in the buffer for the next LdapResponse. Must be non-NULL.
353 * "pLdapResponse"
354 * The address where the created LdapResponse is stored. Must be non-NULL.
355 * "plContext"
356 * Platform-specific context pointer.
357 * THREAD SAFETY:
358 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
359 * RETURNS:
360 * Returns NULL if the function succeeds.
361 * Returns an LdapResponse Error if the function fails in a non-fatal way.
362 * Returns a Fatal Error if the function fails in an unrecoverable way.
364 PKIX_Error *
365 pkix_pl_LdapResponse_Create(
366 LDAPMessageType responseType,
367 PKIX_UInt32 totalLength,
368 PKIX_UInt32 bytesAvailable,
369 void *partialData,
370 PKIX_UInt32 *pBytesConsumed,
371 PKIX_PL_LdapResponse **pLdapResponse,
372 void *plContext)
374 PKIX_UInt32 bytesConsumed = 0;
375 PKIX_PL_LdapResponse *ldapResponse = NULL;
376 void *data = NULL;
378 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Create");
379 PKIX_NULLCHECK_ONE(pLdapResponse);
381 if (bytesAvailable <= totalLength) {
382 bytesConsumed = bytesAvailable;
383 } else {
384 bytesConsumed = totalLength;
387 /* create a PKIX_PL_LdapResponse object */
388 PKIX_CHECK(PKIX_PL_Object_Alloc
389 (PKIX_LDAPRESPONSE_TYPE,
390 sizeof (PKIX_PL_LdapResponse),
391 (PKIX_PL_Object **)&ldapResponse,
392 plContext),
393 PKIX_COULDNOTCREATEOBJECT);
395 ldapResponse->decoded.protocolOp.selector = responseType;
396 ldapResponse->totalLength = totalLength;
397 ldapResponse->partialLength = bytesConsumed;
399 if (totalLength != 0){
400 /* Alloc space for array */
401 PKIX_NULLCHECK_ONE(partialData);
403 PKIX_CHECK(PKIX_PL_Malloc
404 (totalLength,
405 &data,
406 plContext),
407 PKIX_MALLOCFAILED);
409 PKIX_PL_NSSCALL
410 (LDAPRESPONSE,
411 PORT_Memcpy,
412 (data, partialData, bytesConsumed));
415 ldapResponse->derEncoded.type = siBuffer;
416 ldapResponse->derEncoded.data = data;
417 ldapResponse->derEncoded.len = totalLength;
418 *pBytesConsumed = bytesConsumed;
419 *pLdapResponse = ldapResponse;
421 cleanup:
423 if (PKIX_ERROR_RECEIVED){
424 PKIX_DECREF(ldapResponse);
427 PKIX_RETURN(LDAPRESPONSE);
431 * FUNCTION: pkix_pl_LdapResponse_Append
432 * DESCRIPTION:
434 * This function updates the LdapResponse pointed to by "response" with up to
435 * "incrLength" from the buffer pointer to by "incrData", storing the number of
436 * bytes copied at "pBytesConsumed".
438 * PARAMETERS
439 * "response"
440 * The address of the LdapResponse being updated. Must be non-zero.
441 * "incrLength"
442 * The UInt32 value for the number of bytes of data available in the
443 * current buffer.
444 * "incrData"
445 * The address from which data is to be copied.
446 * "pBytesConsumed"
447 * The address at which is stored the UInt32 number of bytes taken from the
448 * current buffer. If this number is less than "incrLength", then bytes
449 * remain in the buffer for the next LdapResponse. Must be non-NULL.
450 * "plContext"
451 * Platform-specific context pointer.
452 * THREAD SAFETY:
453 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
454 * RETURNS:
455 * Returns NULL if the function succeeds.
456 * Returns an LdapResponse Error if the function fails in a non-fatal way.
457 * Returns a Fatal Error if the function fails in an unrecoverable way.
459 PKIX_Error *
460 pkix_pl_LdapResponse_Append(
461 PKIX_PL_LdapResponse *response,
462 PKIX_UInt32 incrLength,
463 void *incrData,
464 PKIX_UInt32 *pBytesConsumed,
465 void *plContext)
467 PKIX_UInt32 newPartialLength = 0;
468 PKIX_UInt32 bytesConsumed = 0;
469 void *dest = NULL;
471 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Append");
472 PKIX_NULLCHECK_TWO(response, pBytesConsumed);
474 if (incrLength > 0) {
476 /* Calculate how many bytes we have room for. */
477 bytesConsumed =
478 response->totalLength - response->partialLength;
480 if (bytesConsumed > incrLength) {
481 bytesConsumed = incrLength;
484 newPartialLength = response->partialLength + bytesConsumed;
486 PKIX_NULLCHECK_ONE(incrData);
488 dest = &(((char *)response->derEncoded.data)[
489 response->partialLength]);
491 PKIX_PL_NSSCALL
492 (LDAPRESPONSE,
493 PORT_Memcpy,
494 (dest, incrData, bytesConsumed));
496 response->partialLength = newPartialLength;
499 *pBytesConsumed = bytesConsumed;
501 PKIX_RETURN(LDAPRESPONSE);
505 * FUNCTION: pkix_pl_LdapResponse_IsComplete
506 * DESCRIPTION:
508 * This function determines whether the LdapResponse pointed to by "response"
509 * contains all the data called for by the "totalLength" parameter provided
510 * when it was created, storing PKIX_TRUE at "pIsComplete" if so, and
511 * PKIX_FALSE otherwise.
513 * PARAMETERS
514 * "response"
515 * The address of the LdapResponse being evaluaTED. Must be non-zero.
516 * "incrLength"
517 * The UInt32 value for the number of bytes of data available in the
518 * current buffer.
519 * "incrData"
520 * The address from which data is to be copied.
521 * "pIsComplete"
522 * The address at which is stored the Boolean indication of whether the
523 * LdapResponse is complete. Must be non-NULL.
524 * "plContext"
525 * Platform-specific context pointer.
526 * THREAD SAFETY:
527 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
528 * RETURNS:
529 * Returns NULL if the function succeeds.
530 * Returns an LdapResponse Error if the function fails in a non-fatal way.
531 * Returns a Fatal Error if the function fails in an unrecoverable way.
533 PKIX_Error *
534 pkix_pl_LdapResponse_IsComplete(
535 PKIX_PL_LdapResponse *response,
536 PKIX_Boolean *pIsComplete,
537 void *plContext)
539 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_IsComplete");
540 PKIX_NULLCHECK_TWO(response, pIsComplete);
542 if (response->totalLength == response->partialLength) {
543 *pIsComplete = PKIX_TRUE;
544 } else {
545 *pIsComplete = PKIX_FALSE;
548 PKIX_RETURN(LDAPRESPONSE);
552 * FUNCTION: pkix_pl_LdapResponse_Decode
553 * DESCRIPTION:
555 * This function decodes the DER data contained in the LdapResponse pointed to
556 * by "response", using the arena pointed to by "arena", and storing at
557 * "pStatus" SECSuccess if the decoding was successful and SECFailure
558 * otherwise. The decoded message is stored in an element of "response".
560 * PARAMETERS
561 * "arena"
562 * The address of the PRArenaPool to be used in the decoding. Must be
563 * non-NULL.
564 * "response"
565 * The address of the LdapResponse whose DER data is to be decoded. Must
566 * be non-NULL.
567 * "pStatus"
568 * The address at which is stored the status from the decoding, SECSuccess
569 * if successful, SECFailure otherwise. Must be non-NULL.
570 * "plContext"
571 * Platform-specific context pointer.
572 * THREAD SAFETY:
573 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
574 * RETURNS:
575 * Returns NULL if the function succeeds.
576 * Returns an LdapResponse Error if the function fails in a non-fatal way.
577 * Returns a Fatal Error if the function fails in an unrecoverable way.
579 PKIX_Error *
580 pkix_pl_LdapResponse_Decode(
581 PRArenaPool *arena,
582 PKIX_PL_LdapResponse *response,
583 SECStatus *pStatus,
584 void *plContext)
586 LDAPMessage *msg;
587 SECStatus rv = SECFailure;
589 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Decode");
590 PKIX_NULLCHECK_THREE(arena, response, pStatus);
592 if (response->totalLength != response->partialLength) {
593 PKIX_ERROR(PKIX_ATTEMPTTODECODEANINCOMPLETERESPONSE);
596 msg = &(response->decoded);
598 PKIX_PL_NSSCALL
599 (LDAPRESPONSE, PORT_Memset, (msg, 0, sizeof (LDAPMessage)));
601 PKIX_PL_NSSCALLRV(LDAPRESPONSE, rv, SEC_ASN1DecodeItem,
602 (NULL, msg, PKIX_PL_LDAPMessageTemplate, &(response->derEncoded)));
604 *pStatus = rv;
605 cleanup:
607 PKIX_RETURN(LDAPRESPONSE);
611 * FUNCTION: pkix_pl_LdapResponse_GetMessage
612 * DESCRIPTION:
614 * This function obtains the decoded message from the LdapResponse pointed to
615 * by "response", storing the result at "pMessage".
617 * PARAMETERS
618 * "response"
619 * The address of the LdapResponse whose decoded message is to be
620 * retrieved. Must be non-NULL.
621 * "pMessage"
622 * The address at which is stored the address of the decoded message. Must
623 * be non-NULL.
624 * "plContext"
625 * Platform-specific context pointer.
626 * THREAD SAFETY:
627 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
628 * RETURNS:
629 * Returns NULL if the function succeeds.
630 * Returns a Fatal Error if the function fails in an unrecoverable way.
632 PKIX_Error *
633 pkix_pl_LdapResponse_GetMessage(
634 PKIX_PL_LdapResponse *response,
635 LDAPMessage **pMessage,
636 void *plContext)
638 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessage");
639 PKIX_NULLCHECK_TWO(response, pMessage);
641 *pMessage = &response->decoded;
643 PKIX_RETURN(LDAPRESPONSE);
647 * FUNCTION: pkix_pl_LdapResponse_GetCapacity
648 * DESCRIPTION:
650 * This function obtains from the LdapResponse pointed to by "response" the
651 * number of bytes remaining to be read, based on the totalLength that was
652 * provided to LdapResponse_Create and the data subsequently provided to
653 * LdapResponse_Append, storing the result at "pMessage".
655 * PARAMETERS
656 * "response"
657 * The address of the LdapResponse whose remaining capacity is to be
658 * retrieved. Must be non-NULL.
659 * "pCapacity"
660 * The address at which is stored the address of the decoded message. Must
661 * be non-NULL.
662 * "plContext"
663 * Platform-specific context pointer.
664 * THREAD SAFETY:
665 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
666 * RETURNS:
667 * Returns NULL if the function succeeds.
668 * Returns an LdapResponse Error if the function fails in a non-fatal way.
669 * Returns a Fatal Error if the function fails in an unrecoverable way.
671 PKIX_Error *
672 pkix_pl_LdapResponse_GetCapacity(
673 PKIX_PL_LdapResponse *response,
674 PKIX_UInt32 *pCapacity,
675 void *plContext)
677 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetCapacity");
678 PKIX_NULLCHECK_TWO(response, pCapacity);
680 *pCapacity = response->totalLength - response->partialLength;
682 PKIX_RETURN(LDAPRESPONSE);
686 * FUNCTION: pkix_pl_LdapResponse_GetMessageType
687 * DESCRIPTION:
689 * This function obtains the message type from the LdapResponse pointed to
690 * by "response", storing the result at "pMessageType".
692 * PARAMETERS
693 * "response"
694 * The address of the LdapResponse whose message type is to be
695 * retrieved. Must be non-NULL.
696 * "pMessageType"
697 * The address at which is stored the type of the response message. Must
698 * be non-NULL.
699 * "plContext"
700 * Platform-specific context pointer.
701 * THREAD SAFETY:
702 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
703 * RETURNS:
704 * Returns NULL if the function succeeds.
705 * Returns a Fatal Error if the function fails in an unrecoverable way.
707 PKIX_Error *
708 pkix_pl_LdapResponse_GetMessageType(
709 PKIX_PL_LdapResponse *response,
710 LDAPMessageType *pMessageType,
711 void *plContext)
713 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessageType");
714 PKIX_NULLCHECK_TWO(response, pMessageType);
716 *pMessageType = response->decoded.protocolOp.selector;
718 PKIX_RETURN(LDAPRESPONSE);
722 * FUNCTION: pkix_pl_LdapResponse_GetResultCode
723 * DESCRIPTION:
725 * This function obtains the result code from the LdapResponse pointed to
726 * by "response", storing the result at "pResultCode".
728 * PARAMETERS
729 * "response"
730 * The address of the LdapResponse whose result code is to be
731 * retrieved. Must be non-NULL.
732 * "pResultCode"
733 * The address at which is stored the address of the decoded message. Must
734 * be non-NULL.
735 * "plContext"
736 * Platform-specific context pointer.
737 * THREAD SAFETY:
738 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
739 * RETURNS:
740 * Returns NULL if the function succeeds.
741 * Returns an LdapResponse Error if the function fails in a non-fatal way.
742 * Returns a Fatal Error if the function fails in an unrecoverable way.
744 PKIX_Error *
745 pkix_pl_LdapResponse_GetResultCode(
746 PKIX_PL_LdapResponse *response,
747 LDAPResultCode *pResultCode,
748 void *plContext)
750 LDAPMessageType messageType = 0;
751 LDAPSearchResponseResult *resultMsg = NULL;
753 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
754 PKIX_NULLCHECK_TWO(response, pResultCode);
756 messageType = response->decoded.protocolOp.selector;
758 if (messageType != LDAP_SEARCHRESPONSERESULT_TYPE) {
759 PKIX_ERROR(PKIX_GETRESULTCODECALLEDFORNONRESULTMESSAGE);
762 resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
764 *pResultCode = *(char *)(resultMsg->resultCode.data);
766 cleanup:
768 PKIX_RETURN(LDAPRESPONSE);
772 * FUNCTION: pkix_pl_LdapResponse_GetAttributes
773 * DESCRIPTION:
775 * This function obtains the attributes from the LdapResponse pointed to
776 * by "response", storing the result at "pAttributes".
778 * PARAMETERS
779 * "response"
780 * The address of the LdapResponse whose decoded message is to be
781 * retrieved. Must be non-NULL.
782 * "pAttributes"
783 * The address at which is stored the attributes of the message. Must be
784 * non-NULL.
785 * "plContext"
786 * Platform-specific context pointer.
787 * THREAD SAFETY:
788 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
789 * RETURNS:
790 * Returns NULL if the function succeeds.
791 * Returns an LdapResponse Error if the function fails in a non-fatal way.
792 * Returns a Fatal Error if the function fails in an unrecoverable way.
794 PKIX_Error *
795 pkix_pl_LdapResponse_GetAttributes(
796 PKIX_PL_LdapResponse *response,
797 LDAPSearchResponseAttr ***pAttributes,
798 void *plContext)
800 LDAPMessageType messageType = 0;
802 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
803 PKIX_NULLCHECK_TWO(response, pAttributes);
805 messageType = response->decoded.protocolOp.selector;
807 if (messageType != LDAP_SEARCHRESPONSEENTRY_TYPE) {
808 PKIX_ERROR(PKIX_GETATTRIBUTESCALLEDFORNONENTRYMESSAGE);
811 *pAttributes = response->
812 decoded.protocolOp.op.searchResponseEntryMsg.attributes;
814 cleanup:
816 PKIX_RETURN(LDAPRESPONSE);