nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / module / pkix_pl_ldapdefaultclient.c
blob45da0ab3fc00c89bf301f76b54a06259363c479f
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_ldapdefaultclient.c
40 * LDAPDefaultClient Function Definitions
44 /* We can't decode the length of a message without at least this many bytes */
45 #define MINIMUM_MSG_LENGTH 5
47 #include "pkix_pl_ldapdefaultclient.h"
49 /* --Private-LdapDefaultClient-Message-Building-Functions---------------- */
52 * FUNCTION: pkix_pl_LdapDefaultClient_MakeBind
53 * DESCRIPTION:
55 * This function creates and encodes a Bind message, using the arena pointed
56 * to by "arena", the version number contained in "versionData", the
57 * LDAPBindAPI pointed to by "bindAPI", and the messageID contained in
58 * "msgNum", and stores a pointer to the encoded string at "pBindMsg".
60 * See pkix_pl_ldaptemplates.c for the ASN.1 description of a Bind message.
62 * This code is not used if the DefaultClient was created with a NULL pointer
63 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
64 * expected for anonymous Search requests.)
66 * PARAMETERS:
67 * "arena"
68 * The address of the PRArenaPool used in encoding the message. Must be
69 * non-NULL.
70 * "versionData"
71 * The Int32 containing the version number to be encoded in the Bind
72 * message.
73 * "bindAPI"
74 * The address of the LDAPBindAPI to be encoded in the Bind message. Must
75 * be non-NULL.
76 * "msgNum"
77 * The Int32 containing the MessageID to be encoded in the Bind message.
78 * "pBindMsg"
79 * The address at which the encoded Bind message will be stored. Must be
80 * non-NULL.
81 * "plContext"
82 * Platform-specific context pointer.
83 * THREAD SAFETY:
84 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
85 * RETURNS:
86 * Returns NULL if the function succeeds.
87 * Returns a LdapDefaultClient Error if the function fails in a
88 * non-fatal way.
89 * Returns a Fatal Error if the function fails in an unrecoverable way.
91 static PKIX_Error *
92 pkix_pl_LdapDefaultClient_MakeBind(
93 PRArenaPool *arena,
94 PKIX_Int32 versionData,
95 LDAPBindAPI *bindAPI,
96 PKIX_UInt32 msgNum,
97 SECItem **pBindMsg,
98 void *plContext)
100 LDAPMessage msg;
101 char version = '\0';
102 SECItem *encoded = NULL;
103 PKIX_UInt32 len = 0;
105 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeBind");
106 PKIX_NULLCHECK_TWO(arena, pBindMsg);
108 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
109 (&msg, 0, sizeof (LDAPMessage)));
111 version = (char)versionData;
113 msg.messageID.type = siUnsignedInteger;
114 msg.messageID.data = (void*)&msgNum;
115 msg.messageID.len = sizeof (msgNum);
117 msg.protocolOp.selector = LDAP_BIND_TYPE;
119 msg.protocolOp.op.bindMsg.version.type = siUnsignedInteger;
120 msg.protocolOp.op.bindMsg.version.data = (void *)&version;
121 msg.protocolOp.op.bindMsg.version.len = sizeof (char);
124 * XXX At present we only know how to handle anonymous requests (no
125 * authentication), and we are guessing how to do simple authentication.
126 * This section will need to be revised and extended when other
127 * authentication is needed.
129 if (bindAPI->selector == SIMPLE_AUTH) {
130 msg.protocolOp.op.bindMsg.bindName.type = siAsciiString;
131 msg.protocolOp.op.bindMsg.bindName.data =
132 (void *)bindAPI->chooser.simple.bindName;
133 len = PL_strlen(bindAPI->chooser.simple.bindName);
134 msg.protocolOp.op.bindMsg.bindName.len = len;
136 msg.protocolOp.op.bindMsg.authentication.type = siAsciiString;
137 msg.protocolOp.op.bindMsg.authentication.data =
138 (void *)bindAPI->chooser.simple.authentication;
139 len = PL_strlen(bindAPI->chooser.simple.authentication);
140 msg.protocolOp.op.bindMsg.authentication.len = len;
143 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
144 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
145 if (!encoded) {
146 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
149 *pBindMsg = encoded;
150 cleanup:
152 PKIX_RETURN(LDAPDEFAULTCLIENT);
156 * FUNCTION: pkix_pl_LdapDefaultClient_MakeUnbind
157 * DESCRIPTION:
159 * This function creates and encodes a Unbind message, using the arena pointed
160 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
161 * to the encoded string at "pUnbindMsg".
163 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Unbind message.
165 * This code is not used if the DefaultClient was created with a NULL pointer
166 * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
167 * expected for anonymous Search requests.)
169 * PARAMETERS:
170 * "arena"
171 * The address of the PRArenaPool used in encoding the message. Must be
172 * non-NULL.
173 * "msgNum"
174 * The Int32 containing the MessageID to be encoded in the Unbind message.
175 * "pUnbindMsg"
176 * The address at which the encoded Unbind message will be stored. Must
177 * be non-NULL.
178 * "plContext"
179 * Platform-specific context pointer.
180 * THREAD SAFETY:
181 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
182 * RETURNS:
183 * Returns NULL if the function succeeds.
184 * Returns a LdapDefaultClient Error if the function fails in a
185 * non-fatal way.
186 * Returns a Fatal Error if the function fails in an unrecoverable way.
188 static PKIX_Error *
189 pkix_pl_LdapDefaultClient_MakeUnbind(
190 PRArenaPool *arena,
191 PKIX_UInt32 msgNum,
192 SECItem **pUnbindMsg,
193 void *plContext)
195 LDAPMessage msg;
196 SECItem *encoded = NULL;
198 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeUnbind");
199 PKIX_NULLCHECK_TWO(arena, pUnbindMsg);
201 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
202 (&msg, 0, sizeof (LDAPMessage)));
204 msg.messageID.type = siUnsignedInteger;
205 msg.messageID.data = (void*)&msgNum;
206 msg.messageID.len = sizeof (msgNum);
208 msg.protocolOp.selector = LDAP_UNBIND_TYPE;
210 msg.protocolOp.op.unbindMsg.dummy.type = siBuffer;
211 msg.protocolOp.op.unbindMsg.dummy.data = NULL;
212 msg.protocolOp.op.unbindMsg.dummy.len = 0;
214 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
215 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
216 if (!encoded) {
217 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
220 *pUnbindMsg = encoded;
221 cleanup:
223 PKIX_RETURN(LDAPDEFAULTCLIENT);
227 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAbandon
228 * DESCRIPTION:
230 * This function creates and encodes a Abandon message, using the arena pointed
231 * to by "arena" and the messageID contained in "msgNum", and stores a pointer
232 * to the encoded string at "pAbandonMsg".
234 * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Abandon message.
236 * PARAMETERS:
237 * "arena"
238 * The address of the PRArenaPool used in encoding the message. Must be
239 * non-NULL.
240 * "msgNum"
241 * The Int32 containing the MessageID to be encoded in the Abandon message.
242 * "pAbandonMsg"
243 * The address at which the encoded Abandon message will be stored. Must
244 * be non-NULL.
245 * "plContext"
246 * Platform-specific context pointer.
247 * THREAD SAFETY:
248 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
249 * RETURNS:
250 * Returns NULL if the function succeeds.
251 * Returns a LdapDefaultClient Error if the function fails in a
252 * non-fatal way.
253 * Returns a Fatal Error if the function fails in an unrecoverable way.
255 static PKIX_Error *
256 pkix_pl_LdapDefaultClient_MakeAbandon(
257 PRArenaPool *arena,
258 PKIX_UInt32 msgNum,
259 SECItem **pAbandonMsg,
260 void *plContext)
262 LDAPMessage msg;
263 SECItem *encoded = NULL;
265 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeAbandon");
266 PKIX_NULLCHECK_TWO(arena, pAbandonMsg);
268 PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
269 (&msg, 0, sizeof (LDAPMessage)));
271 msg.messageID.type = siUnsignedInteger;
272 msg.messageID.data = (void*)&msgNum;
273 msg.messageID.len = sizeof (msgNum);
275 msg.protocolOp.selector = LDAP_ABANDONREQUEST_TYPE;
277 msg.protocolOp.op.abandonRequestMsg.messageID.type = siBuffer;
278 msg.protocolOp.op.abandonRequestMsg.messageID.data = (void*)&msgNum;
279 msg.protocolOp.op.abandonRequestMsg.messageID.len = sizeof (msgNum);
281 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
282 (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
283 if (!encoded) {
284 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
287 *pAbandonMsg = encoded;
288 cleanup:
290 PKIX_RETURN(LDAPDEFAULTCLIENT);
294 * FUNCTION: pkix_pl_LdapDefaultClient_DecodeBindResponse
295 * DESCRIPTION:
297 * This function decodes the encoded data pointed to by "src", using the arena
298 * pointed to by "arena", storing the decoded LDAPMessage at "pBindResponse"
299 * and the decoding status at "pStatus".
301 * PARAMETERS:
302 * "arena"
303 * The address of the PRArenaPool to be used in decoding the message. Must
304 * be non-NULL.
305 * "src"
306 * The address of the SECItem containing the DER- (or BER-)encoded string.
307 * Must be non-NULL.
308 * "pBindResponse"
309 * The address at which the LDAPMessage is stored, if the decoding is
310 * successful (the returned status is SECSuccess). Must be non-NULL.
311 * "pStatus"
312 * The address at which the decoding status is stored. Must be non-NULL.
313 * "plContext"
314 * Platform-specific context pointer.
315 * THREAD SAFETY:
316 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
317 * RETURNS:
318 * Returns NULL if the function succeeds.
319 * Returns a LdapDefaultClient Error if the function fails in a
320 * non-fatal way.
321 * Returns a Fatal Error if the function fails in an unrecoverable way.
323 static PKIX_Error *
324 pkix_pl_LdapDefaultClient_DecodeBindResponse(
325 PRArenaPool *arena,
326 SECItem *src,
327 LDAPMessage *pBindResponse,
328 SECStatus *pStatus,
329 void *plContext)
331 SECStatus rv = SECFailure;
332 LDAPMessage response;
334 PKIX_ENTER
335 (LDAPDEFAULTCLIENT,
336 "pkix_pl_LdapDefaultClient_DecodeBindResponse");
337 PKIX_NULLCHECK_FOUR(arena, src, pBindResponse, pStatus);
339 PKIX_PL_NSSCALL
340 (LDAPDEFAULTCLIENT,
341 PORT_Memset,
342 (&response, 0, sizeof (LDAPMessage)));
344 PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, rv, SEC_ASN1DecodeItem,
345 (arena, &response, PKIX_PL_LDAPMessageTemplate, src));
347 if (rv == SECSuccess) {
348 *pBindResponse = response;
351 *pStatus = rv;
353 PKIX_RETURN(LDAPDEFAULTCLIENT);
357 * FUNCTION: pkix_pl_LdapDefaultClient_VerifyBindResponse
358 * DESCRIPTION:
360 * This function verifies that the contents of the message in the rcvbuf of
361 * the LdapDefaultClient object pointed to by "client", and whose length is
362 * provided by "buflen", is a response to a successful Bind.
364 * PARAMETERS:
365 * "client"
366 * The address of the LdapDefaultClient object. Must be non-NULL.
367 * "buflen"
368 * The value of the number of bytes in the receive buffer.
369 * "plContext"
370 * Platform-specific context pointer.
371 * THREAD SAFETY:
372 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
373 * RETURNS:
374 * Returns NULL if the function succeeds.
375 * Returns a LdapDefaultClient Error if the function fails in a
376 * non-fatal way.
377 * Returns a Fatal Error if the function fails in an unrecoverable way.
379 static PKIX_Error *
380 pkix_pl_LdapDefaultClient_VerifyBindResponse(
381 PKIX_PL_LdapDefaultClient *client,
382 PKIX_UInt32 bufLen,
383 void *plContext)
385 SECItem decode = {siBuffer, NULL, 0};
386 SECStatus rv = SECFailure;
387 LDAPMessage msg;
388 LDAPBindResponse *ldapBindResponse = NULL;
390 PKIX_ENTER
391 (LDAPDEFAULTCLIENT,
392 "pkix_pl_LdapDefaultClient_VerifyBindResponse");
393 PKIX_NULLCHECK_TWO(client, client->rcvBuf);
395 decode.data = (void *)(client->rcvBuf);
396 decode.len = bufLen;
398 PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
399 (client->arena, &decode, &msg, &rv, plContext),
400 PKIX_LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED);
402 if (rv == SECSuccess) {
403 ldapBindResponse = &msg.protocolOp.op.bindResponseMsg;
404 if (*(ldapBindResponse->resultCode.data) == SUCCESS) {
405 client->connectStatus = BOUND;
406 } else {
407 PKIX_ERROR(PKIX_BINDREJECTEDBYSERVER);
409 } else {
410 PKIX_ERROR(PKIX_CANTDECODEBINDRESPONSEFROMSERVER);
413 cleanup:
415 PKIX_RETURN(LDAPDEFAULTCLIENT);
419 * FUNCTION: pkix_pl_LdapDefaultClient_RecvCheckComplete
420 * DESCRIPTION:
422 * This function determines whether the current response in the
423 * LdapDefaultClient pointed to by "client" is complete, in the sense that all
424 * bytes required to satisfy the message length field in the encoding have been
425 * received. If so, the pointer to input data is updated to reflect the number
426 * of bytes consumed, provided by "bytesProcessed". The state machine flag
427 * pointed to by "pKeepGoing" is updated to indicate whether processing can
428 * continue without further input.
430 * PARAMETERS:
431 * "client"
432 * The address of the LdapDefaultClient object. Must be non-NULL.
433 * "bytesProcessed"
434 * The UInt32 value of the number of bytes consumed from the current
435 * buffer.
436 * "pKeepGoing"
437 * The address at which the Boolean state machine flag is stored to
438 * indicate whether processing can continue without further input.
439 * Must be non-NULL.
440 * "plContext"
441 * Platform-specific context pointer.
442 * THREAD SAFETY:
443 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
444 * RETURNS:
445 * Returns NULL if the function succeeds.
446 * Returns a LdapDefaultClient Error if the function fails in a
447 * non-fatal way.
448 * Returns a Fatal Error if the function fails in an unrecoverable way.
450 static PKIX_Error *
451 pkix_pl_LdapDefaultClient_RecvCheckComplete(
452 PKIX_PL_LdapDefaultClient *client,
453 PKIX_UInt32 bytesProcessed,
454 PKIX_Boolean *pKeepGoing,
455 void *plContext)
457 PKIX_Boolean complete = PKIX_FALSE;
458 SECStatus rv = SECFailure;
459 LDAPMessageType messageType = 0;
460 LDAPResultCode resultCode = 0;
462 PKIX_ENTER
463 (LDAPDEFAULTCLIENT,
464 "pkix_pl_LdapDefaultClient_RecvCheckComplete");
465 PKIX_NULLCHECK_TWO(client, pKeepGoing);
467 PKIX_CHECK(pkix_pl_LdapResponse_IsComplete
468 (client->currentResponse, &complete, plContext),
469 PKIX_LDAPRESPONSEISCOMPLETEFAILED);
471 if (complete) {
472 PKIX_CHECK(pkix_pl_LdapResponse_Decode
473 (client->arena, client->currentResponse, &rv, plContext),
474 PKIX_LDAPRESPONSEDECODEFAILED);
476 if (rv != SECSuccess) {
477 PKIX_ERROR(PKIX_CANTDECODESEARCHRESPONSEFROMSERVER);
480 PKIX_CHECK(pkix_pl_LdapResponse_GetMessageType
481 (client->currentResponse, &messageType, plContext),
482 PKIX_LDAPRESPONSEGETMESSAGETYPEFAILED);
484 if (messageType == LDAP_SEARCHRESPONSEENTRY_TYPE) {
486 if (client->entriesFound == NULL) {
487 PKIX_CHECK(PKIX_List_Create
488 (&(client->entriesFound), plContext),
489 PKIX_LISTCREATEFAILED);
492 PKIX_CHECK(PKIX_List_AppendItem
493 (client->entriesFound,
494 (PKIX_PL_Object *)client->currentResponse,
495 plContext),
496 PKIX_LISTAPPENDITEMFAILED);
498 PKIX_DECREF(client->currentResponse);
500 /* current receive buffer empty? */
501 if (client->currentBytesAvailable == 0) {
502 client->connectStatus = RECV;
503 *pKeepGoing = PKIX_TRUE;
504 } else {
505 client->connectStatus = RECV_INITIAL;
506 client->currentInPtr = &((char *)
507 (client->currentInPtr))[bytesProcessed];
508 *pKeepGoing = PKIX_TRUE;
511 } else if (messageType == LDAP_SEARCHRESPONSERESULT_TYPE) {
512 PKIX_CHECK(pkix_pl_LdapResponse_GetResultCode
513 (client->currentResponse,
514 &resultCode,
515 plContext),
516 PKIX_LDAPRESPONSEGETRESULTCODEFAILED);
518 if ((client->entriesFound == NULL) &&
519 ((resultCode == SUCCESS) ||
520 (resultCode == NOSUCHOBJECT))) {
521 PKIX_CHECK(PKIX_List_Create
522 (&(client->entriesFound), plContext),
523 PKIX_LISTCREATEFAILED);
524 } else if (resultCode == SUCCESS) {
525 PKIX_CHECK(PKIX_List_SetImmutable
526 (client->entriesFound, plContext),
527 PKIX_LISTSETIMMUTABLEFAILED);
528 PKIX_CHECK(PKIX_PL_HashTable_Add
529 (client->cachePtr,
530 (PKIX_PL_Object *)client->currentRequest,
531 (PKIX_PL_Object *)client->entriesFound,
532 plContext),
533 PKIX_HASHTABLEADDFAILED);
534 } else {
535 PKIX_ERROR(PKIX_UNEXPECTEDRESULTCODEINRESPONSE);
538 client->connectStatus = BOUND;
539 *pKeepGoing = PKIX_FALSE;
540 PKIX_DECREF(client->currentResponse);
542 } else {
543 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
545 } else {
546 client->connectStatus = RECV;
547 *pKeepGoing = PKIX_TRUE;
550 cleanup:
551 PKIX_RETURN(LDAPDEFAULTCLIENT);
554 /* --Private-LdapDefaultClient-Object-Functions------------------------- */
556 static PKIX_Error *
557 pkix_pl_LdapDefaultClient_InitiateRequest(
558 PKIX_PL_LdapClient *client,
559 LDAPRequestParams *requestParams,
560 void **pPollDesc,
561 PKIX_List **pResponse,
562 void *plContext);
564 static PKIX_Error *
565 pkix_pl_LdapDefaultClient_ResumeRequest(
566 PKIX_PL_LdapClient *client,
567 void **pPollDesc,
568 PKIX_List **pResponse,
569 void *plContext);
572 * FUNCTION: pkix_pl_LdapDefaultClient_CreateHelper
573 * DESCRIPTION:
575 * This function creates a new LdapDefaultClient using the Socket pointed to
576 * by "socket", the PRIntervalTime pointed to by "timeout", and the
577 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
579 * A value of zero for "timeout" means the LDAPClient will use non-blocking
580 * I/O.
582 * PARAMETERS:
583 * "socket"
584 * Address of the Socket to be used for the client. Must be non-NULL.
585 * "bindAPI"
586 * The address of the LDAPBindAPI containing the Bind information to be
587 * encoded in the Bind message.
588 * "pClient"
589 * The address at which the created LdapDefaultClient is to be stored.
590 * Must be non-NULL.
591 * "plContext"
592 * Platform-specific context pointer.
593 * THREAD SAFETY:
594 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
595 * RETURNS:
596 * Returns NULL if the function succeeds.
597 * Returns a LdapDefaultClient Error if the function fails in
598 * a non-fatal way.
599 * Returns a Fatal Error if the function fails in an unrecoverable way.
601 PKIX_Error *
602 pkix_pl_LdapDefaultClient_CreateHelper(
603 PKIX_PL_Socket *socket,
604 LDAPBindAPI *bindAPI,
605 PKIX_PL_LdapDefaultClient **pClient,
606 void *plContext)
608 PKIX_PL_HashTable *ht;
609 PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
610 PKIX_PL_Socket_Callback *callbackList;
611 PRFileDesc *fileDesc = NULL;
612 PRArenaPool *arena = NULL;
614 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_CreateHelper");
615 PKIX_NULLCHECK_TWO(socket, pClient);
617 PKIX_CHECK(PKIX_PL_Object_Alloc
618 (PKIX_LDAPDEFAULTCLIENT_TYPE,
619 sizeof (PKIX_PL_LdapDefaultClient),
620 (PKIX_PL_Object **)&ldapDefaultClient,
621 plContext),
622 PKIX_COULDNOTCREATELDAPDEFAULTCLIENTOBJECT);
624 ldapDefaultClient->vtable.initiateFcn =
625 pkix_pl_LdapDefaultClient_InitiateRequest;
626 ldapDefaultClient->vtable.resumeFcn =
627 pkix_pl_LdapDefaultClient_ResumeRequest;
629 PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
630 (socket, &fileDesc, plContext),
631 PKIX_SOCKETGETPRFILEDESCFAILED);
633 ldapDefaultClient->pollDesc.fd = fileDesc;
634 ldapDefaultClient->pollDesc.in_flags = 0;
635 ldapDefaultClient->pollDesc.out_flags = 0;
637 ldapDefaultClient->bindAPI = bindAPI;
639 PKIX_CHECK(PKIX_PL_HashTable_Create
640 (LDAP_CACHEBUCKETS, 0, &ht, plContext),
641 PKIX_HASHTABLECREATEFAILED);
643 ldapDefaultClient->cachePtr = ht;
645 PKIX_CHECK(pkix_pl_Socket_GetCallbackList
646 (socket, &callbackList, plContext),
647 PKIX_SOCKETGETCALLBACKLISTFAILED);
649 ldapDefaultClient->callbackList = callbackList;
651 PKIX_INCREF(socket);
652 ldapDefaultClient->clientSocket = socket;
654 ldapDefaultClient->messageID = 0;
656 ldapDefaultClient->bindAPI = bindAPI;
658 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
659 if (!arena) {
660 PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
662 ldapDefaultClient->arena = arena;
664 ldapDefaultClient->sendBuf = NULL;
665 ldapDefaultClient->bytesToWrite = 0;
667 PKIX_CHECK(PKIX_PL_Malloc
668 (RCVBUFSIZE, &ldapDefaultClient->rcvBuf, plContext),
669 PKIX_MALLOCFAILED);
670 ldapDefaultClient->capacity = RCVBUFSIZE;
672 ldapDefaultClient->bindMsg = NULL;
673 ldapDefaultClient->bindMsgLen = 0;
675 ldapDefaultClient->entriesFound = NULL;
676 ldapDefaultClient->currentRequest = NULL;
677 ldapDefaultClient->currentResponse = NULL;
679 *pClient = ldapDefaultClient;
681 cleanup:
683 if (PKIX_ERROR_RECEIVED) {
684 PKIX_DECREF(ldapDefaultClient);
687 PKIX_RETURN(LDAPDEFAULTCLIENT);
691 * FUNCTION: PKIX_PL_LdapDefaultClient_Create
692 * DESCRIPTION:
694 * This function creates a new LdapDefaultClient using the PRNetAddr pointed to
695 * by "sockaddr", the PRIntervalTime pointed to by "timeout", and the
696 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
698 * A value of zero for "timeout" means the LDAPClient will use non-blocking
699 * I/O.
701 * PARAMETERS:
702 * "sockaddr"
703 * Address of the PRNetAddr to be used for the socket connection. Must be
704 * non-NULL.
705 * "timeout"
706 * The PRIntervalTime to be used in I/O requests for this client.
707 * "bindAPI"
708 * The address of the LDAPBindAPI containing the Bind information to be
709 * encoded in the Bind message.
710 * "pClient"
711 * The address at which the created LdapDefaultClient is to be stored.
712 * Must be non-NULL.
713 * "plContext"
714 * Platform-specific context pointer.
715 * THREAD SAFETY:
716 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
717 * RETURNS:
718 * Returns NULL if the function succeeds.
719 * Returns a LdapDefaultClient Error if the function fails in
720 * a non-fatal way.
721 * Returns a Fatal Error if the function fails in an unrecoverable way.
723 PKIX_Error *
724 PKIX_PL_LdapDefaultClient_Create(
725 PRNetAddr *sockaddr,
726 PRIntervalTime timeout,
727 LDAPBindAPI *bindAPI,
728 PKIX_PL_LdapDefaultClient **pClient,
729 void *plContext)
731 PRErrorCode status = 0;
732 PKIX_PL_Socket *socket = NULL;
733 PKIX_PL_LdapDefaultClient *client = NULL;
735 PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_Create");
736 PKIX_NULLCHECK_TWO(sockaddr, pClient);
738 PKIX_CHECK(pkix_pl_Socket_Create
739 (PKIX_FALSE, timeout, sockaddr, &status, &socket, plContext),
740 PKIX_SOCKETCREATEFAILED);
742 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
743 (socket, bindAPI, &client, plContext),
744 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
746 /* Did Socket_Create say the connection was made? */
747 if (status == 0) {
748 if (client->bindAPI != NULL) {
749 client->connectStatus = CONNECTED;
750 } else {
751 client->connectStatus = BOUND;
753 } else {
754 client->connectStatus = CONNECT_PENDING;
757 *pClient = client;
759 cleanup:
760 if (PKIX_ERROR_RECEIVED) {
761 PKIX_DECREF(client);
764 PKIX_DECREF(socket);
766 PKIX_RETURN(LDAPDEFAULTCLIENT);
770 * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName
771 * DESCRIPTION:
773 * This function creates a new LdapDefaultClient using the hostname pointed to
774 * by "hostname", the PRIntervalTime pointed to by "timeout", and the
775 * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
777 * A value of zero for "timeout" means the LDAPClient will use non-blocking
778 * I/O.
780 * PARAMETERS:
781 * "hostname"
782 * Address of the hostname to be used for the socket connection. Must be
783 * non-NULL.
784 * "timeout"
785 * The PRIntervalTime to be used in I/O requests for this client.
786 * "bindAPI"
787 * The address of the LDAPBindAPI containing the Bind information to be
788 * encoded in the Bind message.
789 * "pClient"
790 * The address at which the created LdapDefaultClient is to be stored.
791 * Must be non-NULL.
792 * "plContext"
793 * Platform-specific context pointer.
794 * THREAD SAFETY:
795 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
796 * RETURNS:
797 * Returns NULL if the function succeeds.
798 * Returns a LdapDefaultClient Error if the function fails in
799 * a non-fatal way.
800 * Returns a Fatal Error if the function fails in an unrecoverable way.
802 PKIX_Error *
803 PKIX_PL_LdapDefaultClient_CreateByName(
804 char *hostname,
805 PRIntervalTime timeout,
806 LDAPBindAPI *bindAPI,
807 PKIX_PL_LdapDefaultClient **pClient,
808 void *plContext)
810 PRErrorCode status = 0;
811 PKIX_PL_Socket *socket = NULL;
812 PKIX_PL_LdapDefaultClient *client = NULL;
814 PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_CreateByName");
815 PKIX_NULLCHECK_TWO(hostname, pClient);
817 PKIX_CHECK(pkix_pl_Socket_CreateByName
818 (PKIX_FALSE, timeout, hostname, &status, &socket, plContext),
819 PKIX_SOCKETCREATEBYNAMEFAILED);
821 PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
822 (socket, bindAPI, &client, plContext),
823 PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
825 /* Did Socket_Create say the connection was made? */
826 if (status == 0) {
827 if (client->bindAPI != NULL) {
828 client->connectStatus = CONNECTED;
829 } else {
830 client->connectStatus = BOUND;
832 } else {
833 client->connectStatus = CONNECT_PENDING;
836 *pClient = client;
838 cleanup:
839 if (PKIX_ERROR_RECEIVED) {
840 PKIX_DECREF(client);
843 PKIX_DECREF(socket);
845 PKIX_RETURN(LDAPDEFAULTCLIENT);
849 * FUNCTION: pkix_pl_LdapDefaultClient_Destroy
850 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
852 static PKIX_Error *
853 pkix_pl_LdapDefaultClient_Destroy(
854 PKIX_PL_Object *object,
855 void *plContext)
857 PKIX_Int32 bytesWritten = 0;
858 PKIX_PL_LdapDefaultClient *client = NULL;
859 PKIX_PL_Socket_Callback *callbackList = NULL;
860 SECItem *encoded = NULL;
862 PKIX_ENTER(LDAPDEFAULTCLIENT,
863 "pkix_pl_LdapDefaultClient_Destroy");
864 PKIX_NULLCHECK_ONE(object);
866 PKIX_CHECK(pkix_CheckType
867 (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
868 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
870 client = (PKIX_PL_LdapDefaultClient *)object;
872 switch (client->connectStatus) {
873 case CONNECT_PENDING:
874 break;
875 case CONNECTED:
876 case BIND_PENDING:
877 case BIND_RESPONSE:
878 case BIND_RESPONSE_PENDING:
879 case BOUND:
880 case SEND_PENDING:
881 case RECV:
882 case RECV_PENDING:
883 case RECV_INITIAL:
884 case RECV_NONINITIAL:
885 case ABANDON_PENDING:
886 if (client->bindAPI != NULL) {
887 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeUnbind
888 (client->arena,
889 ++(client->messageID),
890 &encoded,
891 plContext),
892 PKIX_LDAPDEFAULTCLIENTMAKEUNBINDFAILED);
894 callbackList =
895 (PKIX_PL_Socket_Callback *)(client->callbackList);
896 PKIX_CHECK(callbackList->sendCallback
897 (client->clientSocket,
898 encoded->data,
899 encoded->len,
900 &bytesWritten,
901 plContext),
902 PKIX_SOCKETSENDFAILED);
904 break;
905 default:
906 PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTINILLEGALSTATE);
909 PKIX_DECREF(client->cachePtr);
910 PKIX_DECREF(client->clientSocket);
911 PKIX_DECREF(client->entriesFound);
912 PKIX_DECREF(client->currentRequest);
913 PKIX_DECREF(client->currentResponse);
915 PKIX_CHECK(PKIX_PL_Free
916 (client->rcvBuf, plContext), PKIX_FREEFAILED);
918 PKIX_PL_NSSCALL
919 (LDAPDEFAULTCLIENT,
920 PORT_FreeArena,
921 (client->arena, PR_FALSE));
923 cleanup:
925 PKIX_RETURN(LDAPDEFAULTCLIENT);
929 * FUNCTION: pkix_pl_LdapDefaultClient_Hashcode
930 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
932 static PKIX_Error *
933 pkix_pl_LdapDefaultClient_Hashcode(
934 PKIX_PL_Object *object,
935 PKIX_UInt32 *pHashcode,
936 void *plContext)
938 PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
939 PKIX_UInt32 tempHash = 0;
941 PKIX_ENTER
942 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Hashcode");
943 PKIX_NULLCHECK_TWO(object, pHashcode);
945 PKIX_CHECK(pkix_CheckType
946 (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
947 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
949 ldapDefaultClient = (PKIX_PL_LdapDefaultClient *)object;
951 PKIX_CHECK(PKIX_PL_Object_Hashcode
952 ((PKIX_PL_Object *)ldapDefaultClient->clientSocket,
953 &tempHash,
954 plContext),
955 PKIX_SOCKETHASHCODEFAILED);
957 if (ldapDefaultClient->bindAPI != NULL) {
958 tempHash = (tempHash << 7) +
959 ldapDefaultClient->bindAPI->selector;
962 *pHashcode = tempHash;
964 cleanup:
966 PKIX_RETURN(LDAPDEFAULTCLIENT);
970 * FUNCTION: pkix_pl_LdapDefaultClient_Equals
971 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
973 static PKIX_Error *
974 pkix_pl_LdapDefaultClient_Equals(
975 PKIX_PL_Object *firstObject,
976 PKIX_PL_Object *secondObject,
977 PKIX_Int32 *pResult,
978 void *plContext)
980 PKIX_PL_LdapDefaultClient *firstClientContext = NULL;
981 PKIX_PL_LdapDefaultClient *secondClientContext = NULL;
982 PKIX_Int32 compare = 0;
984 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Equals");
985 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
987 *pResult = PKIX_FALSE;
989 PKIX_CHECK(pkix_CheckTypes
990 (firstObject,
991 secondObject,
992 PKIX_LDAPDEFAULTCLIENT_TYPE,
993 plContext),
994 PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
996 firstClientContext = (PKIX_PL_LdapDefaultClient *)firstObject;
997 secondClientContext = (PKIX_PL_LdapDefaultClient *)secondObject;
999 if (firstClientContext == secondClientContext) {
1000 *pResult = PKIX_TRUE;
1001 goto cleanup;
1004 PKIX_CHECK(PKIX_PL_Object_Equals
1005 ((PKIX_PL_Object *)firstClientContext->clientSocket,
1006 (PKIX_PL_Object *)secondClientContext->clientSocket,
1007 &compare,
1008 plContext),
1009 PKIX_SOCKETEQUALSFAILED);
1011 if (!compare) {
1012 goto cleanup;
1015 if (PKIX_EXACTLY_ONE_NULL
1016 (firstClientContext->bindAPI, secondClientContext->bindAPI)) {
1017 goto cleanup;
1020 if (firstClientContext->bindAPI) {
1021 if (firstClientContext->bindAPI->selector !=
1022 secondClientContext->bindAPI->selector) {
1023 goto cleanup;
1027 *pResult = PKIX_TRUE;
1029 cleanup:
1031 PKIX_RETURN(LDAPDEFAULTCLIENT);
1035 * FUNCTION: pkix_pl_LdapDefaultClient_RegisterSelf
1037 * DESCRIPTION:
1038 * Registers PKIX_PL_LDAPDEFAULTCLIENT_TYPE and its related
1039 * functions with systemClasses[]
1041 * THREAD SAFETY:
1042 * Not Thread Safe - for performance and complexity reasons
1044 * Since this function is only called by PKIX_PL_Initialize, which should
1045 * only be called once, it is acceptable that this function is not
1046 * thread-safe.
1048 PKIX_Error *
1049 pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext)
1051 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1052 pkix_ClassTable_Entry entry;
1054 PKIX_ENTER
1055 (LDAPDEFAULTCLIENT,
1056 "pkix_pl_LdapDefaultClient_RegisterSelf");
1058 entry.description = "LdapDefaultClient";
1059 entry.objCounter = 0;
1060 entry.typeObjectSize = sizeof(PKIX_PL_LdapDefaultClient);
1061 entry.destructor = pkix_pl_LdapDefaultClient_Destroy;
1062 entry.equalsFunction = pkix_pl_LdapDefaultClient_Equals;
1063 entry.hashcodeFunction = pkix_pl_LdapDefaultClient_Hashcode;
1064 entry.toStringFunction = NULL;
1065 entry.comparator = NULL;
1066 entry.duplicateFunction = NULL;
1068 systemClasses[PKIX_LDAPDEFAULTCLIENT_TYPE] = entry;
1070 PKIX_RETURN(LDAPDEFAULTCLIENT);
1074 * FUNCTION: pkix_pl_LdapDefaultClient_GetPollDesc
1075 * DESCRIPTION:
1077 * This function retrieves the PRPollDesc from the LdapDefaultClient
1078 * pointed to by "context" and stores the address at "pPollDesc".
1080 * PARAMETERS:
1081 * "context"
1082 * The LdapDefaultClient whose PRPollDesc is desired. Must be non-NULL.
1083 * "pPollDesc"
1084 * Address where PRPollDesc will be stored. Must be non-NULL.
1085 * "plContext"
1086 * Platform-specific context pointer.
1087 * THREAD SAFETY:
1088 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1089 * RETURNS:
1090 * Returns NULL if the function succeeds.
1091 * Returns a Fatal Error if the function fails in an unrecoverable way.
1093 PKIX_Error *
1094 pkix_pl_LdapDefaultClient_GetPollDesc(
1095 PKIX_PL_LdapDefaultClient *context,
1096 PRPollDesc **pPollDesc,
1097 void *plContext)
1099 PKIX_ENTER
1100 (LDAPDEFAULTCLIENT,
1101 "pkix_pl_LdapDefaultClient_GetPollDesc");
1102 PKIX_NULLCHECK_TWO(context, pPollDesc);
1104 *pPollDesc = &(context->pollDesc);
1106 PKIX_RETURN(LDAPDEFAULTCLIENT);
1109 /* --Private-Ldap-CertStore-I/O-Functions---------------------------- */
1111 * FUNCTION: pkix_pl_LdapDefaultClient_ConnectContinue
1112 * DESCRIPTION:
1114 * This function determines whether a socket Connect initiated earlier for the
1115 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1116 * stores in "pKeepGoing" a flag indicating whether processing can continue
1117 * without further input.
1119 * PARAMETERS:
1120 * "client"
1121 * The address of the LdapDefaultClient object. Must be non-NULL.
1122 * "pKeepGoing"
1123 * The address at which the Boolean state machine flag is stored to
1124 * indicate whether processing can continue without further input.
1125 * Must be non-NULL.
1126 * "plContext"
1127 * Platform-specific context pointer.
1128 * THREAD SAFETY:
1129 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1130 * RETURNS:
1131 * Returns NULL if the function succeeds.
1132 * Returns a LdapDefaultClient Error if the function fails in a
1133 * non-fatal way.
1134 * Returns a Fatal Error if the function fails in an unrecoverable way.
1136 static PKIX_Error *
1137 pkix_pl_LdapDefaultClient_ConnectContinue(
1138 PKIX_PL_LdapDefaultClient *client,
1139 PKIX_Boolean *pKeepGoing,
1140 void *plContext)
1142 PKIX_PL_Socket_Callback *callbackList;
1143 PRErrorCode status;
1144 PKIX_Boolean keepGoing = PKIX_FALSE;
1146 PKIX_ENTER
1147 (LDAPDEFAULTCLIENT,
1148 "pkix_pl_LdapDefaultClient_ConnectContinue");
1149 PKIX_NULLCHECK_ONE(client);
1151 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1153 PKIX_CHECK(callbackList->connectcontinueCallback
1154 (client->clientSocket, &status, plContext),
1155 PKIX_SOCKETCONNECTCONTINUEFAILED);
1157 if (status == 0) {
1158 if (client->bindAPI != NULL) {
1159 client->connectStatus = CONNECTED;
1160 } else {
1161 client->connectStatus = BOUND;
1163 keepGoing = PKIX_FALSE;
1164 } else if (status != PR_IN_PROGRESS_ERROR) {
1165 PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION);
1168 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1169 ((PKIX_PL_Object *)client, plContext),
1170 PKIX_OBJECTINVALIDATECACHEFAILED);
1172 *pKeepGoing = keepGoing;
1174 cleanup:
1175 PKIX_RETURN(LDAPDEFAULTCLIENT);
1179 * FUNCTION: pkix_pl_LdapDefaultClient_Bind
1180 * DESCRIPTION:
1182 * This function creates and sends the LDAP-protocol Bind message for the
1183 * CertStore embodied in the LdapDefaultClient "client", and stores in
1184 * "pKeepGoing" a flag indicating whether processing can continue without
1185 * further input.
1187 * PARAMETERS:
1188 * "client"
1189 * The address of the LdapDefaultClient object. Must be non-NULL.
1190 * "pKeepGoing"
1191 * The address at which the Boolean state machine flag is stored to
1192 * indicate whether processing can continue without further input.
1193 * Must be non-NULL.
1194 * "plContext"
1195 * Platform-specific context pointer.
1196 * THREAD SAFETY:
1197 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1198 * RETURNS:
1199 * Returns NULL if the function succeeds.
1200 * Returns a LdapDefaultClient Error if the function fails in a
1201 * non-fatal way.
1202 * Returns a Fatal Error if the function fails in an unrecoverable way.
1204 static PKIX_Error *
1205 pkix_pl_LdapDefaultClient_Bind(
1206 PKIX_PL_LdapDefaultClient *client,
1207 PKIX_Boolean *pKeepGoing,
1208 void *plContext)
1210 SECItem *encoded = NULL;
1211 PKIX_Int32 bytesWritten = 0;
1212 PKIX_PL_Socket_Callback *callbackList;
1214 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Bind");
1215 PKIX_NULLCHECK_ONE(client);
1217 /* if we have not yet constructed the BIND message, build it now */
1218 if (!(client->bindMsg)) {
1219 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeBind
1220 (client->arena,
1222 client->bindAPI,
1223 client->messageID,
1224 &encoded,
1225 plContext),
1226 PKIX_LDAPDEFAULTCLIENTMAKEBINDFAILED);
1227 client->bindMsg = encoded->data;
1228 client->bindMsgLen = encoded->len;
1231 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1233 PKIX_CHECK(callbackList->sendCallback
1234 (client->clientSocket,
1235 client->bindMsg,
1236 client->bindMsgLen,
1237 &bytesWritten,
1238 plContext),
1239 PKIX_SOCKETSENDFAILED);
1241 client->lastIO = PR_Now();
1243 if (bytesWritten < 0) {
1244 client->connectStatus = BIND_PENDING;
1245 *pKeepGoing = PKIX_FALSE;
1246 } else {
1247 client->connectStatus = BIND_RESPONSE;
1248 *pKeepGoing = PKIX_TRUE;
1251 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1252 ((PKIX_PL_Object *)client, plContext),
1253 PKIX_OBJECTINVALIDATECACHEFAILED);
1255 cleanup:
1256 PKIX_RETURN(LDAPDEFAULTCLIENT);
1260 * FUNCTION: pkix_pl_LdapDefaultClient_BindContinue
1261 * DESCRIPTION:
1263 * This function determines whether the LDAP-protocol Bind message for the
1264 * CertStore embodied in the LdapDefaultClient "client" has completed, and
1265 * stores in "pKeepGoing" a flag indicating whether processing can continue
1266 * without further input.
1268 * PARAMETERS:
1269 * "client"
1270 * The address of the LdapDefaultClient object. Must be non-NULL.
1271 * "pKeepGoing"
1272 * The address at which the Boolean state machine flag is stored to
1273 * indicate whether processing can continue without further input.
1274 * Must be non-NULL.
1275 * "plContext"
1276 * Platform-specific context pointer.
1277 * THREAD SAFETY:
1278 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1279 * RETURNS:
1280 * Returns NULL if the function succeeds.
1281 * Returns a LdapDefaultClient Error if the function fails in a
1282 * non-fatal way.
1283 * Returns a Fatal Error if the function fails in an unrecoverable way.
1285 PKIX_Error *pkix_pl_LdapDefaultClient_BindContinue(
1286 PKIX_PL_LdapDefaultClient *client,
1287 PKIX_Boolean *pKeepGoing,
1288 void *plContext)
1290 PKIX_Int32 bytesWritten = 0;
1291 PKIX_PL_Socket_Callback *callbackList = NULL;
1293 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindContinue");
1294 PKIX_NULLCHECK_ONE(client);
1296 *pKeepGoing = PKIX_FALSE;
1298 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1300 PKIX_CHECK(callbackList->pollCallback
1301 (client->clientSocket, &bytesWritten, NULL, plContext),
1302 PKIX_SOCKETPOLLFAILED);
1305 * If the send completed we can proceed to try for the
1306 * response. If the send did not complete we will have
1307 * continue to poll.
1309 if (bytesWritten >= 0) {
1311 client->connectStatus = BIND_RESPONSE;
1313 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1314 ((PKIX_PL_Object *)client, plContext),
1315 PKIX_OBJECTINVALIDATECACHEFAILED);
1317 *pKeepGoing = PKIX_TRUE;
1320 cleanup:
1321 PKIX_RETURN(LDAPDEFAULTCLIENT);
1325 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponse
1326 * DESCRIPTION:
1328 * This function attempts to read the LDAP-protocol BindResponse message for
1329 * the CertStore embodied in the LdapDefaultClient "client", and stores in
1330 * "pKeepGoing" a flag indicating whether processing can continue without
1331 * further input.
1333 * If a BindResponse is received with a Result code of 0 (success), we
1334 * continue with the connection. If a non-zero Result code is received,
1335 * we throw an Error. Some more sophisticated handling of that condition
1336 * might be in order in the future.
1338 * PARAMETERS:
1339 * "client"
1340 * The address of the LdapDefaultClient object. Must be non-NULL.
1341 * "pKeepGoing"
1342 * The address at which the Boolean state machine flag is stored to
1343 * indicate whether processing can continue without further input.
1344 * Must be non-NULL.
1345 * "plContext"
1346 * Platform-specific context pointer.
1347 * THREAD SAFETY:
1348 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1349 * RETURNS:
1350 * Returns NULL if the function succeeds.
1351 * Returns a LdapDefaultClient Error if the function fails in a
1352 * non-fatal way.
1353 * Returns a Fatal Error if the function fails in an unrecoverable way.
1355 static PKIX_Error *
1356 pkix_pl_LdapDefaultClient_BindResponse(
1357 PKIX_PL_LdapDefaultClient *client,
1358 PKIX_Boolean *pKeepGoing,
1359 void *plContext)
1361 PKIX_Int32 bytesRead = 0;
1362 PKIX_PL_Socket_Callback *callbackList = NULL;
1364 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindResponse");
1365 PKIX_NULLCHECK_TWO(client, client->rcvBuf);
1367 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1369 PKIX_CHECK(callbackList->recvCallback
1370 (client->clientSocket,
1371 client->rcvBuf,
1372 client->capacity,
1373 &bytesRead,
1374 plContext),
1375 PKIX_SOCKETRECVFAILED);
1377 client->lastIO = PR_Now();
1379 if (bytesRead > 0) {
1380 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1381 (client, bytesRead, plContext),
1382 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
1384 * XXX What should we do if failure? At present if
1385 * VerifyBindResponse throws an Error, we do too.
1387 client->connectStatus = BOUND;
1388 } else {
1389 client->connectStatus = BIND_RESPONSE_PENDING;
1392 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1393 ((PKIX_PL_Object *)client, plContext),
1394 PKIX_OBJECTINVALIDATECACHEFAILED);
1396 *pKeepGoing = PKIX_TRUE;
1398 cleanup:
1399 PKIX_RETURN(LDAPDEFAULTCLIENT);
1403 * FUNCTION: pkix_pl_LdapDefaultClient_BindResponseContinue
1404 * DESCRIPTION:
1406 * This function determines whether the LDAP-protocol BindResponse message for
1407 * the CertStore embodied in the LdapDefaultClient "client" has completed, and
1408 * stores in "pKeepGoing" a flag indicating whether processing can continue
1409 * without further input.
1411 * PARAMETERS:
1412 * "client"
1413 * The address of the LdapDefaultClient object. Must be non-NULL.
1414 * "pKeepGoing"
1415 * The address at which the Boolean state machine flag is stored to
1416 * indicate whether processing can continue without further input.
1417 * Must be non-NULL.
1418 * "plContext"
1419 * Platform-specific context pointer.
1420 * THREAD SAFETY:
1421 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1422 * RETURNS:
1423 * Returns NULL if the function succeeds.
1424 * Returns a LdapDefaultClient Error if the function fails in a
1425 * non-fatal way.
1426 * Returns a Fatal Error if the function fails in an unrecoverable way.
1428 static PKIX_Error *
1429 pkix_pl_LdapDefaultClient_BindResponseContinue(
1430 PKIX_PL_LdapDefaultClient *client,
1431 PKIX_Boolean *pKeepGoing,
1432 void *plContext)
1434 PKIX_Int32 bytesRead = 0;
1435 PKIX_PL_Socket_Callback *callbackList = NULL;
1437 PKIX_ENTER
1438 (LDAPDEFAULTCLIENT,
1439 "pkix_pl_LdapDefaultClient_BindResponseContinue");
1440 PKIX_NULLCHECK_ONE(client);
1442 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1444 PKIX_CHECK(callbackList->pollCallback
1445 (client->clientSocket, NULL, &bytesRead, plContext),
1446 PKIX_SOCKETPOLLFAILED);
1448 if (bytesRead > 0) {
1449 PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
1450 (client, bytesRead, plContext),
1451 PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
1452 client->connectStatus = BOUND;
1454 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1455 ((PKIX_PL_Object *)client, plContext),
1456 PKIX_OBJECTINVALIDATECACHEFAILED);
1458 *pKeepGoing = PKIX_TRUE;
1459 } else {
1460 *pKeepGoing = PKIX_FALSE;
1463 cleanup:
1464 PKIX_RETURN(LDAPDEFAULTCLIENT);
1468 * FUNCTION: pkix_pl_LdapDefaultClient_Send
1469 * DESCRIPTION:
1471 * This function creates and sends an LDAP-protocol message for the
1472 * CertStore embodied in the LdapDefaultClient "client", and stores in
1473 * "pKeepGoing" a flag indicating whether processing can continue without
1474 * further input, and at "pBytesTransferred" the number of bytes sent.
1476 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1477 * and that transmission has not completed.
1479 * PARAMETERS:
1480 * "client"
1481 * The address of the LdapDefaultClient object. Must be non-NULL.
1482 * "pKeepGoing"
1483 * The address at which the Boolean state machine flag is stored to
1484 * indicate whether processing can continue without further input.
1485 * Must be non-NULL.
1486 * "pBytesTransferred"
1487 * The address at which the number of bytes sent is stored. Must be
1488 * non-NULL.
1489 * "plContext"
1490 * Platform-specific context pointer.
1491 * THREAD SAFETY:
1492 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1493 * RETURNS:
1494 * Returns NULL if the function succeeds.
1495 * Returns a LdapDefaultClient Error if the function fails in a
1496 * non-fatal way.
1497 * Returns a Fatal Error if the function fails in an unrecoverable way.
1499 static PKIX_Error *
1500 pkix_pl_LdapDefaultClient_Send(
1501 PKIX_PL_LdapDefaultClient *client,
1502 PKIX_Boolean *pKeepGoing,
1503 PKIX_UInt32 *pBytesTransferred,
1504 void *plContext)
1506 PKIX_Int32 bytesWritten = 0;
1507 PKIX_PL_Socket_Callback *callbackList = NULL;
1509 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Send");
1510 PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
1512 *pKeepGoing = PKIX_FALSE;
1514 /* Do we have anything waiting to go? */
1515 if (client->sendBuf) {
1516 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1518 PKIX_CHECK(callbackList->sendCallback
1519 (client->clientSocket,
1520 client->sendBuf,
1521 client->bytesToWrite,
1522 &bytesWritten,
1523 plContext),
1524 PKIX_SOCKETSENDFAILED);
1526 client->lastIO = PR_Now();
1529 * If the send completed we can proceed to try for the
1530 * response. If the send did not complete we will have
1531 * to poll for completion later.
1533 if (bytesWritten >= 0) {
1534 client->sendBuf = NULL;
1535 client->connectStatus = RECV;
1536 *pKeepGoing = PKIX_TRUE;
1538 } else {
1539 *pKeepGoing = PKIX_FALSE;
1540 client->connectStatus = SEND_PENDING;
1545 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1546 ((PKIX_PL_Object *)client, plContext),
1547 PKIX_OBJECTINVALIDATECACHEFAILED);
1549 *pBytesTransferred = bytesWritten;
1551 cleanup:
1552 PKIX_RETURN(LDAPDEFAULTCLIENT);
1556 * FUNCTION: pkix_pl_LdapDefaultClient_SendContinue
1557 * DESCRIPTION:
1559 * This function determines whether the sending of the LDAP-protocol message
1560 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1561 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1562 * without further input, and at "pBytesTransferred" the number of bytes sent.
1564 * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
1565 * and that transmission has not completed.
1567 * PARAMETERS:
1568 * "client"
1569 * The address of the LdapDefaultClient object. Must be non-NULL.
1570 * "pKeepGoing"
1571 * The address at which the Boolean state machine flag is stored to
1572 * indicate whether processing can continue without further input.
1573 * Must be non-NULL.
1574 * "pBytesTransferred"
1575 * The address at which the number of bytes sent is stored. Must be
1576 * non-NULL.
1577 * "plContext"
1578 * Platform-specific context pointer.
1579 * THREAD SAFETY:
1580 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1581 * RETURNS:
1582 * Returns NULL if the function succeeds.
1583 * Returns a LdapDefaultClient Error if the function fails in a
1584 * non-fatal way.
1585 * Returns a Fatal Error if the function fails in an unrecoverable way.
1587 static PKIX_Error *
1588 pkix_pl_LdapDefaultClient_SendContinue(
1589 PKIX_PL_LdapDefaultClient *client,
1590 PKIX_Boolean *pKeepGoing,
1591 PKIX_UInt32 *pBytesTransferred,
1592 void *plContext)
1594 PKIX_Int32 bytesWritten = 0;
1595 PKIX_PL_Socket_Callback *callbackList = NULL;
1597 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_SendContinue");
1598 PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
1600 *pKeepGoing = PKIX_FALSE;
1602 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1604 PKIX_CHECK(callbackList->pollCallback
1605 (client->clientSocket, &bytesWritten, NULL, plContext),
1606 PKIX_SOCKETPOLLFAILED);
1609 * If the send completed we can proceed to try for the
1610 * response. If the send did not complete we will have
1611 * continue to poll.
1613 if (bytesWritten >= 0) {
1614 client->sendBuf = NULL;
1615 client->connectStatus = RECV;
1617 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1618 ((PKIX_PL_Object *)client, plContext),
1619 PKIX_OBJECTINVALIDATECACHEFAILED);
1621 *pKeepGoing = PKIX_TRUE;
1624 *pBytesTransferred = bytesWritten;
1626 cleanup:
1627 PKIX_RETURN(LDAPDEFAULTCLIENT);
1631 * FUNCTION: pkix_pl_LdapDefaultClient_Recv
1632 * DESCRIPTION:
1634 * This function receives an LDAP-protocol message for the CertStore embodied
1635 * in the LdapDefaultClient "client", and stores in "pKeepGoing" a flag
1636 * indicating whether processing can continue without further input.
1638 * PARAMETERS:
1639 * "client"
1640 * The address of the LdapDefaultClient object. Must be non-NULL.
1641 * "pKeepGoing"
1642 * The address at which the Boolean state machine flag is stored to
1643 * indicate whether processing can continue without further input.
1644 * Must be non-NULL.
1645 * "plContext"
1646 * Platform-specific context pointer.
1647 * THREAD SAFETY:
1648 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1649 * RETURNS:
1650 * Returns NULL if the function succeeds.
1651 * Returns a LdapDefaultClient Error if the function fails in a
1652 * non-fatal way.
1653 * Returns a Fatal Error if the function fails in an unrecoverable way.
1655 static PKIX_Error *
1656 pkix_pl_LdapDefaultClient_Recv(
1657 PKIX_PL_LdapDefaultClient *client,
1658 PKIX_Boolean *pKeepGoing,
1659 void *plContext)
1661 PKIX_Int32 bytesRead = 0;
1662 PKIX_UInt32 bytesToRead = 0;
1663 PKIX_PL_Socket_Callback *callbackList = NULL;
1665 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Recv");
1666 PKIX_NULLCHECK_THREE(client, pKeepGoing, client->rcvBuf);
1668 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1671 * If we attempt to fill our buffer with every read, we increase
1672 * the risk of an ugly situation: one or two bytes of a new message
1673 * left over at the end of processing one message. With such a
1674 * fragment, we can't decode a byte count and so won't know how much
1675 * space to allocate for the next LdapResponse. We try to avoid that
1676 * case by reading just enough to complete the current message, unless
1677 * there will be at least MINIMUM_MSG_LENGTH bytes left over.
1679 if (client->currentResponse) {
1680 PKIX_CHECK(pkix_pl_LdapResponse_GetCapacity
1681 (client->currentResponse, &bytesToRead, plContext),
1682 PKIX_LDAPRESPONSEGETCAPACITYFAILED);
1683 if ((bytesToRead > client->capacity) ||
1684 ((bytesToRead + MINIMUM_MSG_LENGTH) < client->capacity)) {
1685 bytesToRead = client->capacity;
1687 } else {
1688 bytesToRead = client->capacity;
1691 client->currentBytesAvailable = 0;
1693 PKIX_CHECK(callbackList->recvCallback
1694 (client->clientSocket,
1695 (void *)client->rcvBuf,
1696 bytesToRead,
1697 &bytesRead,
1698 plContext),
1699 PKIX_SOCKETRECVFAILED);
1701 client->currentInPtr = client->rcvBuf;
1702 client->lastIO = PR_Now();
1704 if (bytesRead > 0) {
1705 client->currentBytesAvailable = bytesRead;
1706 client->connectStatus = RECV_INITIAL;
1707 *pKeepGoing = PKIX_TRUE;
1708 } else {
1709 client->connectStatus = RECV_PENDING;
1710 *pKeepGoing = PKIX_FALSE;
1713 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1714 ((PKIX_PL_Object *)client, plContext),
1715 PKIX_OBJECTINVALIDATECACHEFAILED);
1717 cleanup:
1718 PKIX_RETURN(LDAPDEFAULTCLIENT);
1722 * FUNCTION: pkix_pl_LdapDefaultClient_RecvContinue
1723 * DESCRIPTION:
1725 * This function determines whether the receiving of the LDAP-protocol message
1726 * for the CertStore embodied in the LdapDefaultClient "client" has completed,
1727 * and stores in "pKeepGoing" a flag indicating whether processing can continue
1728 * without further input.
1730 * PARAMETERS:
1731 * "client"
1732 * The address of the LdapDefaultClient object. Must be non-NULL.
1733 * "pKeepGoing"
1734 * The address at which the Boolean state machine flag is stored to
1735 * indicate whether processing can continue without further input.
1736 * Must be non-NULL.
1737 * "plContext"
1738 * Platform-specific context pointer.
1739 * THREAD SAFETY:
1740 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1741 * RETURNS:
1742 * Returns NULL if the function succeeds.
1743 * Returns a LdapDefaultClient Error if the function fails in a
1744 * non-fatal way.
1745 * Returns a Fatal Error if the function fails in an unrecoverable way.
1747 static PKIX_Error *
1748 pkix_pl_LdapDefaultClient_RecvContinue(
1749 PKIX_PL_LdapDefaultClient *client,
1750 PKIX_Boolean *pKeepGoing,
1751 void *plContext)
1753 PKIX_Int32 bytesRead = 0;
1754 PKIX_PL_Socket_Callback *callbackList = NULL;
1756 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvContinue");
1757 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1759 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1761 PKIX_CHECK(callbackList->pollCallback
1762 (client->clientSocket, NULL, &bytesRead, plContext),
1763 PKIX_SOCKETPOLLFAILED);
1765 if (bytesRead > 0) {
1766 client->currentBytesAvailable += bytesRead;
1767 client->connectStatus = RECV_INITIAL;
1768 *pKeepGoing = PKIX_TRUE;
1770 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1771 ((PKIX_PL_Object *)client, plContext),
1772 PKIX_OBJECTINVALIDATECACHEFAILED);
1773 } else {
1774 *pKeepGoing = PKIX_FALSE;
1777 cleanup:
1778 PKIX_RETURN(LDAPDEFAULTCLIENT);
1782 * FUNCTION: pkix_pl_LdapDefaultClient_AbandonContinue
1783 * DESCRIPTION:
1785 * This function determines whether the abandon-message request of the
1786 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1787 * "client" has completed, and stores in "pKeepGoing" a flag indicating whether
1788 * processing can continue without further input.
1790 * PARAMETERS:
1791 * "client"
1792 * The address of the LdapDefaultClient object. Must be non-NULL.
1793 * "pKeepGoing"
1794 * The address at which the Boolean state machine flag is stored to
1795 * indicate whether processing can continue without further input.
1796 * Must be non-NULL.
1797 * "plContext"
1798 * Platform-specific context pointer.
1799 * THREAD SAFETY:
1800 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1801 * RETURNS:
1802 * Returns NULL if the function succeeds.
1803 * Returns a LdapDefaultClient Error if the function fails in a
1804 * non-fatal way.
1805 * Returns a Fatal Error if the function fails in an unrecoverable way.
1807 static PKIX_Error *
1808 pkix_pl_LdapDefaultClient_AbandonContinue(
1809 PKIX_PL_LdapDefaultClient *client,
1810 PKIX_Boolean *pKeepGoing,
1811 void *plContext)
1813 PKIX_Int32 bytesWritten = 0;
1814 PKIX_PL_Socket_Callback *callbackList = NULL;
1816 PKIX_ENTER
1817 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_AbandonContinue");
1818 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1820 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1822 PKIX_CHECK(callbackList->pollCallback
1823 (client->clientSocket, &bytesWritten, NULL, plContext),
1824 PKIX_SOCKETPOLLFAILED);
1826 if (bytesWritten > 0) {
1827 client->connectStatus = BOUND;
1828 *pKeepGoing = PKIX_TRUE;
1830 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
1831 ((PKIX_PL_Object *)client, plContext),
1832 PKIX_OBJECTINVALIDATECACHEFAILED);
1833 } else {
1834 *pKeepGoing = PKIX_FALSE;
1837 cleanup:
1838 PKIX_RETURN(LDAPDEFAULTCLIENT);
1842 * FUNCTION: pkix_pl_LdapDefaultClient_RecvInitial
1843 * DESCRIPTION:
1845 * This function processes the contents of the first buffer of a received
1846 * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
1847 * "client", and stores in "pKeepGoing" a flag indicating whether processing can
1848 * continue without further input.
1850 * PARAMETERS:
1851 * "client"
1852 * The address of the LdapDefaultClient object. Must be non-NULL.
1853 * "pKeepGoing"
1854 * The address at which the Boolean state machine flag is stored to
1855 * indicate whether processing can continue without further input.
1856 * Must be non-NULL.
1857 * "plContext"
1858 * Platform-specific context pointer.
1859 * THREAD SAFETY:
1860 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1861 * RETURNS:
1862 * Returns NULL if the function succeeds.
1863 * Returns a LdapDefaultClient Error if the function fails in a
1864 * non-fatal way.
1865 * Returns a Fatal Error if the function fails in an unrecoverable way.
1867 static PKIX_Error *
1868 pkix_pl_LdapDefaultClient_RecvInitial(
1869 PKIX_PL_LdapDefaultClient *client,
1870 PKIX_Boolean *pKeepGoing,
1871 void *plContext)
1873 unsigned char *msgBuf = NULL;
1874 unsigned char *to = NULL;
1875 unsigned char *from = NULL;
1876 PKIX_UInt32 dataIndex = 0;
1877 PKIX_UInt32 messageIdLen = 0;
1878 PKIX_UInt32 messageLength = 0;
1879 PKIX_UInt32 sizeofLength = 0;
1880 PKIX_UInt32 bytesProcessed = 0;
1881 unsigned char messageChar = 0;
1882 LDAPMessageType messageType = 0;
1883 PKIX_Int32 bytesRead = 0;
1884 PKIX_PL_Socket_Callback *callbackList = NULL;
1886 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvInitial");
1887 PKIX_NULLCHECK_TWO(client, pKeepGoing);
1890 * Is there an LDAPResponse in progress? I.e., have we
1891 * already processed the tag and length at the beginning of
1892 * the message?
1894 if (client->currentResponse) {
1895 client->connectStatus = RECV_NONINITIAL;
1896 *pKeepGoing = PKIX_TRUE;
1897 goto cleanup;
1899 msgBuf = client->currentInPtr;
1901 /* Do we have enough of the message to decode the message length? */
1902 if (client->currentBytesAvailable < MINIMUM_MSG_LENGTH) {
1904 * No! Move these few bytes to the beginning of rcvBuf
1905 * and hang another read.
1908 to = (unsigned char *)client->rcvBuf;
1909 from = client->currentInPtr;
1910 for (dataIndex = 0;
1911 dataIndex < client->currentBytesAvailable;
1912 dataIndex++) {
1913 *to++ = *from++;
1915 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
1916 PKIX_CHECK(callbackList->recvCallback
1917 (client->clientSocket,
1918 (void *)to,
1919 client->capacity - client->currentBytesAvailable,
1920 &bytesRead,
1921 plContext),
1922 PKIX_SOCKETRECVFAILED);
1924 client->currentInPtr = client->rcvBuf;
1925 client->lastIO = PR_Now();
1927 if (bytesRead <= 0) {
1928 client->connectStatus = RECV_PENDING;
1929 *pKeepGoing = PKIX_FALSE;
1930 goto cleanup;
1931 } else {
1932 client->currentBytesAvailable += bytesRead;
1937 * We have to determine whether the response is an entry, with
1938 * application-specific tag LDAP_SEARCHRESPONSEENTRY_TYPE, or a
1939 * resultCode, with application tag LDAP_SEARCHRESPONSERESULT_TYPE.
1940 * First, we have to figure out where to look for the tag.
1943 /* Is the message length short form (one octet) or long form? */
1944 if ((msgBuf[1] & 0x80) != 0) {
1945 sizeofLength = msgBuf[1] & 0x7F;
1946 for (dataIndex = 0; dataIndex < sizeofLength; dataIndex++) {
1947 messageLength =
1948 (messageLength << 8) + msgBuf[dataIndex + 2];
1950 } else {
1951 messageLength = msgBuf[1];
1954 /* How many bytes did the messageID require? */
1955 messageIdLen = msgBuf[dataIndex + 3];
1957 messageChar = msgBuf[dataIndex + messageIdLen + 4];
1959 /* Are we looking at an Entry message or a ResultCode message? */
1960 if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
1961 LDAP_SEARCHRESPONSEENTRY_TYPE) == messageChar) {
1963 messageType = LDAP_SEARCHRESPONSEENTRY_TYPE;
1965 } else if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
1966 LDAP_SEARCHRESPONSERESULT_TYPE) == messageChar) {
1968 messageType = LDAP_SEARCHRESPONSERESULT_TYPE;
1970 } else {
1972 PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
1977 * messageLength is the length from (tag, length, value).
1978 * We have to allocate space for the tag and length bits too.
1980 PKIX_CHECK(pkix_pl_LdapResponse_Create
1981 (messageType,
1982 messageLength + dataIndex + 2,
1983 client->currentBytesAvailable,
1984 msgBuf,
1985 &bytesProcessed,
1986 &(client->currentResponse),
1987 plContext),
1988 PKIX_LDAPRESPONSECREATEFAILED);
1990 client->currentBytesAvailable -= bytesProcessed;
1992 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
1993 (client, bytesProcessed, pKeepGoing, plContext),
1994 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
1996 cleanup:
1998 PKIX_RETURN(LDAPDEFAULTCLIENT);
2002 * FUNCTION: pkix_pl_LdapDefaultClient_RecvNonInitial
2003 * DESCRIPTION:
2005 * This function processes the contents of buffers, after the first, of a
2006 * received LDAP-protocol message for the CertStore embodied in the
2007 * LdapDefaultClient "client", and stores in "pKeepGoing" a flag indicating
2008 * whether processing can continue without further input.
2010 * PARAMETERS:
2011 * "client"
2012 * The address of the LdapDefaultClient object. Must be non-NULL.
2013 * "pKeepGoing"
2014 * The address at which the Boolean state machine flag is stored to
2015 * indicate whether processing can continue without further input.
2016 * Must be non-NULL.
2017 * "plContext"
2018 * Platform-specific context pointer.
2019 * THREAD SAFETY:
2020 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2021 * RETURNS:
2022 * Returns NULL if the function succeeds.
2023 * Returns a LdapDefaultClient Error if the function fails in a
2024 * non-fatal way.
2025 * Returns a Fatal Error if the function fails in an unrecoverable way.
2027 static PKIX_Error *
2028 pkix_pl_LdapDefaultClient_RecvNonInitial(
2029 PKIX_PL_LdapDefaultClient *client,
2030 PKIX_Boolean *pKeepGoing,
2031 void *plContext)
2034 PKIX_UInt32 bytesProcessed = 0;
2036 PKIX_ENTER
2037 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvNonInitial");
2038 PKIX_NULLCHECK_TWO(client, pKeepGoing);
2040 PKIX_CHECK(pkix_pl_LdapResponse_Append
2041 (client->currentResponse,
2042 client->currentBytesAvailable,
2043 client->currentInPtr,
2044 &bytesProcessed,
2045 plContext),
2046 PKIX_LDAPRESPONSEAPPENDFAILED);
2048 client->currentBytesAvailable -= bytesProcessed;
2050 PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
2051 (client, bytesProcessed, pKeepGoing, plContext),
2052 PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
2054 cleanup:
2056 PKIX_RETURN(LDAPDEFAULTCLIENT);
2060 * FUNCTION: pkix_pl_LdapDefaultClient_Dispatch
2061 * DESCRIPTION:
2063 * This function is the state machine dispatcher for the CertStore embodied in
2064 * the LdapDefaultClient pointed to by "client". Results are returned by
2065 * changes to various fields in the context.
2067 * PARAMETERS:
2068 * "client"
2069 * The address of the LdapDefaultClient object. Must be non-NULL.
2070 * "plContext"
2071 * Platform-specific context pointer.
2072 * THREAD SAFETY:
2073 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2074 * RETURNS:
2075 * Returns NULL if the function succeeds.
2076 * Returns a LdapDefaultClient Error if the function fails in a
2077 * non-fatal way.
2078 * Returns a Fatal Error if the function fails in an unrecoverable way.
2080 static PKIX_Error *
2081 pkix_pl_LdapDefaultClient_Dispatch(
2082 PKIX_PL_LdapDefaultClient *client,
2083 void *plContext)
2085 PKIX_UInt32 bytesTransferred = 0;
2086 PKIX_Boolean keepGoing = PKIX_TRUE;
2088 PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Dispatch");
2089 PKIX_NULLCHECK_ONE(client);
2091 while (keepGoing) {
2092 switch (client->connectStatus) {
2093 case CONNECT_PENDING:
2094 PKIX_CHECK
2095 (pkix_pl_LdapDefaultClient_ConnectContinue
2096 (client, &keepGoing, plContext),
2097 PKIX_LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED);
2098 break;
2099 case CONNECTED:
2100 PKIX_CHECK
2101 (pkix_pl_LdapDefaultClient_Bind
2102 (client, &keepGoing, plContext),
2103 PKIX_LDAPDEFAULTCLIENTBINDFAILED);
2104 break;
2105 case BIND_PENDING:
2106 PKIX_CHECK
2107 (pkix_pl_LdapDefaultClient_BindContinue
2108 (client, &keepGoing, plContext),
2109 PKIX_LDAPDEFAULTCLIENTBINDCONTINUEFAILED);
2110 break;
2111 case BIND_RESPONSE:
2112 PKIX_CHECK
2113 (pkix_pl_LdapDefaultClient_BindResponse
2114 (client, &keepGoing, plContext),
2115 PKIX_LDAPDEFAULTCLIENTBINDRESPONSEFAILED);
2116 break;
2117 case BIND_RESPONSE_PENDING:
2118 PKIX_CHECK
2119 (pkix_pl_LdapDefaultClient_BindResponseContinue
2120 (client, &keepGoing, plContext),
2121 PKIX_LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED);
2122 break;
2123 case BOUND:
2124 PKIX_CHECK
2125 (pkix_pl_LdapDefaultClient_Send
2126 (client, &keepGoing, &bytesTransferred, plContext),
2127 PKIX_LDAPDEFAULTCLIENTSENDFAILED);
2128 break;
2129 case SEND_PENDING:
2130 PKIX_CHECK
2131 (pkix_pl_LdapDefaultClient_SendContinue
2132 (client, &keepGoing, &bytesTransferred, plContext),
2133 PKIX_LDAPDEFAULTCLIENTSENDCONTINUEFAILED);
2134 break;
2135 case RECV:
2136 PKIX_CHECK
2137 (pkix_pl_LdapDefaultClient_Recv
2138 (client, &keepGoing, plContext),
2139 PKIX_LDAPDEFAULTCLIENTRECVFAILED);
2140 break;
2141 case RECV_PENDING:
2142 PKIX_CHECK
2143 (pkix_pl_LdapDefaultClient_RecvContinue
2144 (client, &keepGoing, plContext),
2145 PKIX_LDAPDEFAULTCLIENTRECVCONTINUEFAILED);
2146 break;
2147 case RECV_INITIAL:
2148 PKIX_CHECK
2149 (pkix_pl_LdapDefaultClient_RecvInitial
2150 (client, &keepGoing, plContext),
2151 PKIX_LDAPDEFAULTCLIENTRECVINITIALFAILED);
2152 break;
2153 case RECV_NONINITIAL:
2154 PKIX_CHECK
2155 (pkix_pl_LdapDefaultClient_RecvNonInitial
2156 (client, &keepGoing, plContext),
2157 PKIX_LDAPDEFAULTCLIENTRECVNONINITIALFAILED);
2158 break;
2159 case ABANDON_PENDING:
2160 PKIX_CHECK
2161 (pkix_pl_LdapDefaultClient_AbandonContinue
2162 (client, &keepGoing, plContext),
2163 PKIX_LDAPDEFAULTCLIENTABANDONCONTINUEFAILED);
2164 break;
2165 default:
2166 PKIX_ERROR(PKIX_LDAPCERTSTOREINILLEGALSTATE);
2170 cleanup:
2172 PKIX_RETURN(LDAPDEFAULTCLIENT);
2176 * FUNCTION: pkix_pl_LdapDefaultClient_MakeAndFilter
2177 * DESCRIPTION:
2179 * This function allocates space from the arena pointed to by "arena" to
2180 * construct a filter that will match components of the X500Name pointed to by
2181 * XXX...
2183 * PARAMETERS:
2184 * "arena"
2185 * The address of the PRArenaPool used in creating the filter. Must be
2186 * non-NULL.
2187 * "nameComponent"
2188 * The address of a NULL-terminated list of LDAPNameComponents
2189 * Must be non-NULL.
2190 * "pFilter"
2191 * The address at which the result is stored.
2192 * "plContext"
2193 * Platform-specific context pointer
2194 * THREAD SAFETY:
2195 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2196 * RETURNS:
2197 * Returns NULL if the function succeeds.
2198 * Returns a CertStore Error if the function fails in a non-fatal way.
2199 * Returns a Fatal Error if the function fails in an unrecoverable way.
2201 static PKIX_Error *
2202 pkix_pl_LdapDefaultClient_MakeAndFilter(
2203 PRArenaPool *arena,
2204 LDAPNameComponent **nameComponents,
2205 LDAPFilter **pFilter,
2206 void *plContext)
2208 LDAPFilter **setOfFilter;
2209 LDAPFilter *andFilter = NULL;
2210 LDAPFilter *currentFilter = NULL;
2211 PKIX_UInt32 componentsPresent = 0;
2212 void *v = NULL;
2213 unsigned char *component = NULL;
2214 LDAPNameComponent **componentP = NULL;
2216 PKIX_ENTER(CERTSTORE, "pkix_pl_LdapDefaultClient_MakeAndFilter");
2217 PKIX_NULLCHECK_THREE(arena, nameComponents, pFilter);
2219 /* count how many components we were provided */
2220 for (componentP = nameComponents, componentsPresent = 0;
2221 *(componentP++) != NULL;
2222 componentsPresent++) {}
2224 /* Space for (componentsPresent + 1) pointers to LDAPFilter */
2225 PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc,
2226 (arena, (componentsPresent + 1)*sizeof(LDAPFilter *)));
2227 setOfFilter = (LDAPFilter **)v;
2229 /* Space for AndFilter and <componentsPresent> EqualFilters */
2230 PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray,
2231 (arena, LDAPFilter, componentsPresent + 1));
2232 setOfFilter[0] = (LDAPFilter *)v;
2234 /* Claim the first array element for the ANDFilter */
2235 andFilter = setOfFilter[0];
2237 /* Set ANDFilter to point to the first EqualFilter pointer */
2238 andFilter->selector = LDAP_ANDFILTER_TYPE;
2239 andFilter->filter.andFilter.filters = setOfFilter;
2241 currentFilter = andFilter + 1;
2243 for (componentP = nameComponents, componentsPresent = 0;
2244 *(componentP) != NULL; componentP++) {
2245 setOfFilter[componentsPresent++] = currentFilter;
2246 currentFilter->selector = LDAP_EQUALFILTER_TYPE;
2247 component = (*componentP)->attrType;
2248 currentFilter->filter.equalFilter.attrType.data = component;
2249 currentFilter->filter.equalFilter.attrType.len =
2250 PL_strlen((const char *)component);
2251 component = (*componentP)->attrValue;
2252 currentFilter->filter.equalFilter.attrValue.data = component;
2253 currentFilter->filter.equalFilter.attrValue.len =
2254 PL_strlen((const char *)component);
2255 currentFilter++;
2258 setOfFilter[componentsPresent] = NULL;
2260 *pFilter = andFilter;
2262 PKIX_RETURN(CERTSTORE);
2267 * FUNCTION: pkix_pl_LdapDefaultClient_InitiateRequest
2268 * DESCRIPTION:
2271 * PARAMETERS:
2272 * "client"
2273 * The address of the LdapDefaultClient object. Must be non-NULL.
2274 * "requestParams"
2275 * The address of an LdapClientParams object. Must be non-NULL.
2276 * "pPollDesc"
2277 * The location where the address of the PRPollDesc is stored, if the
2278 * client returns with I/O pending.
2279 * "pResponse"
2280 * The address where the List of LDAPResponses, or NULL for an
2281 * unfinished request, is stored. Must be non-NULL.
2282 * "plContext"
2283 * Platform-specific context pointer.
2284 * THREAD SAFETY:
2285 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2286 * RETURNS:
2287 * Returns NULL if the function succeeds.
2288 * Returns a LdapDefaultClient Error if the function fails in a
2289 * non-fatal way.
2290 * Returns a Fatal Error if the function fails in an unrecoverable way.
2292 static PKIX_Error *
2293 pkix_pl_LdapDefaultClient_InitiateRequest(
2294 PKIX_PL_LdapClient *genericClient,
2295 LDAPRequestParams *requestParams,
2296 void **pPollDesc,
2297 PKIX_List **pResponse,
2298 void *plContext)
2300 PKIX_List *searchResponseList = NULL;
2301 SECItem *encoded = NULL;
2302 LDAPFilter *filter = NULL;
2303 PKIX_PL_LdapDefaultClient *client = 0;
2305 PKIX_ENTER
2306 (LDAPDEFAULTCLIENT,
2307 "pkix_pl_LdapDefaultClient_InitiateRequest");
2308 PKIX_NULLCHECK_FOUR(genericClient, requestParams, pPollDesc, pResponse);
2310 PKIX_CHECK(pkix_CheckType
2311 ((PKIX_PL_Object *)genericClient,
2312 PKIX_LDAPDEFAULTCLIENT_TYPE,
2313 plContext),
2314 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
2316 client = (PKIX_PL_LdapDefaultClient *)genericClient;
2318 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAndFilter
2319 (client->arena, requestParams->nc, &filter, plContext),
2320 PKIX_LDAPDEFAULTCLIENTMAKEANDFILTERFAILED);
2322 PKIX_CHECK(pkix_pl_LdapRequest_Create
2323 (client->arena,
2324 client->messageID++,
2325 requestParams->baseObject,
2326 requestParams->scope,
2327 requestParams->derefAliases,
2328 requestParams->sizeLimit,
2329 requestParams->timeLimit,
2330 PKIX_FALSE, /* attrs only */
2331 filter,
2332 requestParams->attributes,
2333 &client->currentRequest,
2334 plContext),
2335 PKIX_LDAPREQUESTCREATEFAILED);
2337 /* check hashtable for matching request */
2338 PKIX_CHECK(PKIX_PL_HashTable_Lookup
2339 (client->cachePtr,
2340 (PKIX_PL_Object *)(client->currentRequest),
2341 (PKIX_PL_Object **)&searchResponseList,
2342 plContext),
2343 PKIX_HASHTABLELOOKUPFAILED);
2345 if (searchResponseList != NULL) {
2346 *pPollDesc = NULL;
2347 *pResponse = searchResponseList;
2348 PKIX_DECREF(client->currentRequest);
2349 goto cleanup;
2352 /* It wasn't cached. We'll have to actually send it. */
2354 PKIX_CHECK(pkix_pl_LdapRequest_GetEncoded
2355 (client->currentRequest, &encoded, plContext),
2356 PKIX_LDAPREQUESTGETENCODEDFAILED);
2358 client->sendBuf = encoded->data;
2359 client->bytesToWrite = encoded->len;
2361 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
2362 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
2365 * It's not enough that we may be done with a particular read.
2366 * We're still processing the transaction until we've gotten the
2367 * SearchResponseResult message and returned to the BOUND state.
2368 * Otherwise we must still have a read pending, and must hold off
2369 * on returning results.
2371 if ((client->connectStatus == BOUND) &&
2372 (client->entriesFound != NULL)) {
2373 *pPollDesc = NULL;
2374 *pResponse = client->entriesFound;
2375 client->entriesFound = NULL;
2376 PKIX_DECREF(client->currentRequest);
2377 } else {
2378 *pPollDesc = &client->pollDesc;
2379 *pResponse = NULL;
2382 cleanup:
2384 PKIX_RETURN(LDAPDEFAULTCLIENT);
2389 * FUNCTION: pkix_pl_LdapDefaultClient_ResumeRequest
2390 * DESCRIPTION:
2393 * PARAMETERS:
2394 * "client"
2395 * The address of the LdapDefaultClient object. Must be non-NULL.
2396 * "pPollDesc"
2397 * The location where the address of the PRPollDesc is stored, if the
2398 * client returns with I/O pending.
2399 * "pResponse"
2400 * The address where the List of LDAPResponses, or NULL for an
2401 * unfinished request, is stored. Must be non-NULL.
2402 * "plContext"
2403 * Platform-specific context pointer.
2404 * THREAD SAFETY:
2405 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2406 * RETURNS:
2407 * Returns NULL if the function succeeds.
2408 * Returns a LdapDefaultClient Error if the function fails in a
2409 * non-fatal way.
2410 * Returns a Fatal Error if the function fails in an unrecoverable way.
2412 static PKIX_Error *
2413 pkix_pl_LdapDefaultClient_ResumeRequest(
2414 PKIX_PL_LdapClient *genericClient,
2415 void **pPollDesc,
2416 PKIX_List **pResponse,
2417 void *plContext)
2419 PKIX_PL_LdapDefaultClient *client = 0;
2421 PKIX_ENTER
2422 (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_ResumeRequest");
2423 PKIX_NULLCHECK_THREE(genericClient, pPollDesc, pResponse);
2425 PKIX_CHECK(pkix_CheckType
2426 ((PKIX_PL_Object *)genericClient,
2427 PKIX_LDAPDEFAULTCLIENT_TYPE,
2428 plContext),
2429 PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
2431 client = (PKIX_PL_LdapDefaultClient *)genericClient;
2433 PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
2434 PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
2437 * It's not enough that we may be done with a particular read.
2438 * We're still processing the transaction until we've gotten the
2439 * SearchResponseResult message and returned to the BOUND state.
2440 * Otherwise we must still have a read pending, and must hold off
2441 * on returning results.
2443 if ((client->connectStatus == BOUND) &&
2444 (client->entriesFound != NULL)) {
2445 *pPollDesc = NULL;
2446 *pResponse = client->entriesFound;
2447 client->entriesFound = NULL;
2448 PKIX_DECREF(client->currentRequest);
2449 } else {
2450 *pPollDesc = &client->pollDesc;
2451 *pResponse = NULL;
2454 cleanup:
2456 PKIX_RETURN(LDAPDEFAULTCLIENT);
2460 /* --Public-LdapDefaultClient-Functions----------------------------------- */
2463 * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest
2464 * DESCRIPTION:
2466 * This function creates and sends an LDAP-protocol "Abandon" message to the
2467 * server connected to the LdapDefaultClient pointed to by "client".
2469 * PARAMETERS:
2470 * "client"
2471 * The LdapDefaultClient whose connection is to be abandoned. Must be
2472 * non-NULL.
2473 * "plContext"
2474 * Platform-specific context pointer.
2475 * THREAD SAFETY:
2476 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
2477 * RETURNS:
2478 * Returns NULL if the function succeeds.
2479 * Returns a Fatal Error if the function fails in an unrecoverable way.
2481 PKIX_Error *
2482 PKIX_PL_LdapDefaultClient_AbandonRequest(
2483 PKIX_PL_LdapDefaultClient *client,
2484 void *plContext)
2486 PKIX_Int32 bytesWritten = 0;
2487 PKIX_PL_Socket_Callback *callbackList = NULL;
2488 SECItem *encoded = NULL;
2490 PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapDefaultClient_AbandonRequest");
2491 PKIX_NULLCHECK_ONE(client);
2493 if (client->connectStatus == RECV_PENDING) {
2494 PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAbandon
2495 (client->arena,
2496 (client->messageID) - 1,
2497 &encoded,
2498 plContext),
2499 PKIX_LDAPDEFAULTCLIENTMAKEABANDONFAILED);
2501 callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
2502 PKIX_CHECK(callbackList->sendCallback
2503 (client->clientSocket,
2504 encoded->data,
2505 encoded->len,
2506 &bytesWritten,
2507 plContext),
2508 PKIX_SOCKETSENDFAILED);
2510 if (bytesWritten < 0) {
2511 client->connectStatus = ABANDON_PENDING;
2512 } else {
2513 client->connectStatus = BOUND;
2517 PKIX_DECREF(client->entriesFound);
2518 PKIX_DECREF(client->currentRequest);
2519 PKIX_DECREF(client->currentResponse);
2521 cleanup:
2523 PKIX_DECREF(client);
2525 PKIX_RETURN(CERTSTORE);