| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 /* | |
| 5 * pkix_pl_ldapresponse.c | |
| 6 * | |
| 7 */ | |
| 8 | |
| 9 #include <fcntl.h> | |
| 10 #include "pkix_pl_ldapresponse.h" | |
| 11 | |
| 12 /* --Private-LdapResponse-Functions------------------------------------- */ | |
| 13 | |
| 14 /* | |
| 15 * FUNCTION: pkix_pl_LdapResponse_Destroy | |
| 16 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
| 17 */ | |
| 18 static PKIX_Error * | |
| 19 pkix_pl_LdapResponse_Destroy( | |
| 20 PKIX_PL_Object *object, | |
| 21 void *plContext) | |
| 22 { | |
| 23 PKIX_PL_LdapResponse *ldapRsp = NULL; | |
| 24 LDAPMessage *m = NULL; | |
| 25 LDAPSearchResponseEntry *entry = NULL; | |
| 26 LDAPSearchResponseResult *result = NULL; | |
| 27 LDAPSearchResponseAttr **attributes = NULL; | |
| 28 LDAPSearchResponseAttr *attr = NULL; | |
| 29 SECItem **valp = NULL; | |
| 30 SECItem *val = NULL; | |
| 31 | |
| 32 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Destroy"); | |
| 33 PKIX_NULLCHECK_ONE(object); | |
| 34 | |
| 35 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext), | |
| 36 PKIX_OBJECTNOTLDAPRESPONSE); | |
| 37 | |
| 38 ldapRsp = (PKIX_PL_LdapResponse *)object; | |
| 39 | |
| 40 m = &ldapRsp->decoded; | |
| 41 | |
| 42 if (m->messageID.data != NULL) { | |
| 43 PR_Free(m->messageID.data); | |
| 44 } | |
| 45 | |
| 46 if (m->protocolOp.selector == | |
| 47 LDAP_SEARCHRESPONSEENTRY_TYPE) { | |
| 48 entry = &m->protocolOp.op.searchResponseEntryMsg; | |
| 49 if (entry->objectName.data != NULL) { | |
| 50 PR_Free(entry->objectName.data); | |
| 51 } | |
| 52 if (entry->attributes != NULL) { | |
| 53 for (attributes = entry->attributes; | |
| 54 *attributes != NULL; | |
| 55 attributes++) { | |
| 56 attr = *attributes; | |
| 57 PR_Free(attr->attrType.data); | |
| 58 for (valp = attr->val; *valp != NULL; valp++) { | |
| 59 val = *valp; | |
| 60 if (val->data != NULL) { | |
| 61 PR_Free(val->data); | |
| 62 } | |
| 63 PR_Free(val); | |
| 64 } | |
| 65 PR_Free(attr->val); | |
| 66 PR_Free(attr); | |
| 67 } | |
| 68 PR_Free(entry->attributes); | |
| 69 } | |
| 70 } else if (m->protocolOp.selector == | |
| 71 LDAP_SEARCHRESPONSERESULT_TYPE) { | |
| 72 result = &m->protocolOp.op.searchResponseResultMsg; | |
| 73 if (result->resultCode.data != NULL) { | |
| 74 PR_Free(result->resultCode.data); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 PKIX_FREE(ldapRsp->derEncoded.data); | |
| 79 | |
| 80 cleanup: | |
| 81 | |
| 82 PKIX_RETURN(LDAPRESPONSE); | |
| 83 } | |
| 84 | |
| 85 /* | |
| 86 * FUNCTION: pkix_pl_LdapResponse_Hashcode | |
| 87 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
| 88 */ | |
| 89 static PKIX_Error * | |
| 90 pkix_pl_LdapResponse_Hashcode( | |
| 91 PKIX_PL_Object *object, | |
| 92 PKIX_UInt32 *pHashcode, | |
| 93 void *plContext) | |
| 94 { | |
| 95 PKIX_UInt32 dataLen = 0; | |
| 96 PKIX_UInt32 dindex = 0; | |
| 97 PKIX_UInt32 sizeOfLength = 0; | |
| 98 PKIX_UInt32 idLen = 0; | |
| 99 const unsigned char *msgBuf = NULL; | |
| 100 PKIX_PL_LdapResponse *ldapRsp = NULL; | |
| 101 | |
| 102 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Hashcode"); | |
| 103 PKIX_NULLCHECK_TWO(object, pHashcode); | |
| 104 | |
| 105 PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext), | |
| 106 PKIX_OBJECTNOTLDAPRESPONSE); | |
| 107 | |
| 108 ldapRsp = (PKIX_PL_LdapResponse *)object; | |
| 109 | |
| 110 *pHashcode = 0; | |
| 111 | |
| 112 /* | |
| 113 * Two responses that differ only in msgnum are a match! Therefore, | |
| 114 * start hashcoding beyond the encoded messageID field. | |
| 115 */ | |
| 116 if (ldapRsp->derEncoded.data) { | |
| 117 msgBuf = (const unsigned char *)ldapRsp->derEncoded.data; | |
| 118 /* Is message length short form (one octet) or long form? */ | |
| 119 if ((msgBuf[1] & 0x80) != 0) { | |
| 120 sizeOfLength = msgBuf[1] & 0x7F; | |
| 121 for (dindex = 0; dindex < sizeOfLength; dindex++) { | |
| 122 dataLen = (dataLen << 8) + msgBuf[dindex + 2]; | |
| 123 } | |
| 124 } else { | |
| 125 dataLen = msgBuf[1]; | |
| 126 } | |
| 127 | |
| 128 /* How many bytes for the messageID? (Assume short form) */ | |
| 129 idLen = msgBuf[dindex + 3] + 2; | |
| 130 dindex += idLen; | |
| 131 dataLen -= idLen; | |
| 132 msgBuf = &msgBuf[dindex + 2]; | |
| 133 | |
| 134 PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext), | |
| 135 PKIX_HASHFAILED); | |
| 136 } | |
| 137 | |
| 138 cleanup: | |
| 139 | |
| 140 PKIX_RETURN(LDAPRESPONSE); | |
| 141 | |
| 142 } | |
| 143 | |
| 144 /* | |
| 145 * FUNCTION: pkix_pl_LdapResponse_Equals | |
| 146 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
| 147 */ | |
| 148 static PKIX_Error * | |
| 149 pkix_pl_LdapResponse_Equals( | |
| 150 PKIX_PL_Object *firstObj, | |
| 151 PKIX_PL_Object *secondObj, | |
| 152 PKIX_Boolean *pResult, | |
| 153 void *plContext) | |
| 154 { | |
| 155 PKIX_PL_LdapResponse *rsp1 = NULL; | |
| 156 PKIX_PL_LdapResponse *rsp2 = NULL; | |
| 157 PKIX_UInt32 secondType = 0; | |
| 158 PKIX_UInt32 firstLen = 0; | |
| 159 const unsigned char *firstData = NULL; | |
| 160 const unsigned char *secondData = NULL; | |
| 161 PKIX_UInt32 sizeOfLength = 0; | |
| 162 PKIX_UInt32 dindex = 0; | |
| 163 PKIX_UInt32 i = 0; | |
| 164 | |
| 165 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Equals"); | |
| 166 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult); | |
| 167 | |
| 168 /* test that firstObj is a LdapResponse */ | |
| 169 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPRESPONSE_TYPE, plContext), | |
| 170 PKIX_FIRSTOBJARGUMENTNOTLDAPRESPONSE); | |
| 171 | |
| 172 /* | |
| 173 * Since we know firstObj is a LdapResponse, if both references are | |
| 174 * identical, they must be equal | |
| 175 */ | |
| 176 if (firstObj == secondObj){ | |
| 177 *pResult = PKIX_TRUE; | |
| 178 goto cleanup; | |
| 179 } | |
| 180 | |
| 181 /* | |
| 182 * If secondObj isn't a LdapResponse, we don't throw an error. | |
| 183 * We simply return a Boolean result of FALSE | |
| 184 */ | |
| 185 *pResult = PKIX_FALSE; | |
| 186 PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext), | |
| 187 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
| 188 if (secondType != PKIX_LDAPRESPONSE_TYPE) { | |
| 189 goto cleanup; | |
| 190 } | |
| 191 | |
| 192 rsp1 = (PKIX_PL_LdapResponse *)firstObj; | |
| 193 rsp2 = (PKIX_PL_LdapResponse *)secondObj; | |
| 194 | |
| 195 /* If either lacks an encoded string, they cannot be compared */ | |
| 196 if (!(rsp1->derEncoded.data) || !(rsp2->derEncoded.data)) { | |
| 197 goto cleanup; | |
| 198 } | |
| 199 | |
| 200 if (rsp1->derEncoded.len != rsp2->derEncoded.len) { | |
| 201 goto cleanup; | |
| 202 } | |
| 203 | |
| 204 firstData = (const unsigned char *)rsp1->derEncoded.data; | |
| 205 secondData = (const unsigned char *)rsp2->derEncoded.data; | |
| 206 | |
| 207 /* | |
| 208 * Two responses that differ only in msgnum are equal! Therefore, | |
| 209 * start the byte comparison beyond the encoded messageID field. | |
| 210 */ | |
| 211 | |
| 212 /* Is message length short form (one octet) or long form? */ | |
| 213 if ((firstData[1] & 0x80) != 0) { | |
| 214 sizeOfLength = firstData[1] & 0x7F; | |
| 215 for (dindex = 0; dindex < sizeOfLength; dindex++) { | |
| 216 firstLen = (firstLen << 8) + firstData[dindex + 2]; | |
| 217 } | |
| 218 } else { | |
| 219 firstLen = firstData[1]; | |
| 220 } | |
| 221 | |
| 222 /* How many bytes for the messageID? (Assume short form) */ | |
| 223 i = firstData[dindex + 3] + 2; | |
| 224 dindex += i; | |
| 225 firstLen -= i; | |
| 226 firstData = &firstData[dindex + 2]; | |
| 227 | |
| 228 /* | |
| 229 * In theory, we have to calculate where the second message data | |
| 230 * begins by checking its length encodings. But if these messages | |
| 231 * are equal, we can re-use the calculation we already did. If they | |
| 232 * are not equal, the byte comparisons will surely fail. | |
| 233 */ | |
| 234 | |
| 235 secondData = &secondData[dindex + 2]; | |
| 236 | |
| 237 for (i = 0; i < firstLen; i++) { | |
| 238 if (firstData[i] != secondData[i]) { | |
| 239 goto cleanup; | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 *pResult = PKIX_TRUE; | |
| 244 | |
| 245 cleanup: | |
| 246 | |
| 247 PKIX_RETURN(LDAPRESPONSE); | |
| 248 } | |
| 249 | |
| 250 /* | |
| 251 * FUNCTION: pkix_pl_LdapResponse_RegisterSelf | |
| 252 * DESCRIPTION: | |
| 253 * Registers PKIX_LDAPRESPONSE_TYPE and its related functions with | |
| 254 * systemClasses[] | |
| 255 * PARAMETERS: | |
| 256 * "plContext" | |
| 257 * Platform-specific context pointer. | |
| 258 * THREAD SAFETY: | |
| 259 * Not Thread Safe - for performance and complexity reasons | |
| 260 * | |
| 261 * Since this function is only called by PKIX_PL_Initialize, which should | |
| 262 * only be called once, it is acceptable that this function is not | |
| 263 * thread-safe. | |
| 264 */ | |
| 265 PKIX_Error * | |
| 266 pkix_pl_LdapResponse_RegisterSelf(void *plContext) | |
| 267 { | |
| 268 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
| 269 pkix_ClassTable_Entry entry; | |
| 270 | |
| 271 PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_RegisterSelf"); | |
| 272 | |
| 273 entry.description = "LdapResponse"; | |
| 274 entry.objCounter = 0; | |
| 275 entry.typeObjectSize = sizeof(PKIX_PL_LdapResponse); | |
| 276 entry.destructor = pkix_pl_LdapResponse_Destroy; | |
| 277 entry.equalsFunction = pkix_pl_LdapResponse_Equals; | |
| 278 entry.hashcodeFunction = pkix_pl_LdapResponse_Hashcode; | |
| 279 entry.toStringFunction = NULL; | |
| 280 entry.comparator = NULL; | |
| 281 entry.duplicateFunction = pkix_duplicateImmutable; | |
| 282 | |
| 283 systemClasses[PKIX_LDAPRESPONSE_TYPE] = entry; | |
| 284 | |
| 285 PKIX_RETURN(LDAPRESPONSE); | |
| 286 } | |
| 287 | |
| 288 /* --Public-Functions------------------------------------------------------- */ | |
| 289 | |
| 290 /* | |
| 291 * FUNCTION: pkix_pl_LdapResponse_Create | |
| 292 * DESCRIPTION: | |
| 293 * | |
| 294 * This function creates an LdapResponse for the LDAPMessageType provided in | |
| 295 * "responseType" and a buffer capacity provided by "totalLength". It copies | |
| 296 * into its buffer either "totalLength" or "bytesAvailable" bytes, whichever | |
| 297 * is less, from the buffer pointed to by "partialData", storing the number of | |
| 298 * bytes copied at "pBytesConsumed" and storing the address of the LdapResponse | |
| 299 * at "pLdapResponse". | |
| 300 * | |
| 301 * If a message is complete in a single I/O buffer, the LdapResponse will be | |
| 302 * complete when this function returns. If the message carries over into | |
| 303 * additional buffers, their contents will be added to the LdapResponse by | |
| 304 * susequent calls to pkix_pl_LdapResponse_Append. | |
| 305 * | |
| 306 * PARAMETERS | |
| 307 * "responseType" | |
| 308 * The value of the message type (LDAP_SEARCHRESPONSEENTRY_TYPE or | |
| 309 * LDAP_SEARCHRESPONSERESULT_TYPE) for the LdapResponse being created | |
| 310 * "totalLength" | |
| 311 * The UInt32 value for the total length of the encoded message to be | |
| 312 * stored in the LdapResponse | |
| 313 * "bytesAvailable" | |
| 314 * The UInt32 value for the number of bytes of data available in the | |
| 315 * current buffer. | |
| 316 * "partialData" | |
| 317 * The address from which data is to be copied. | |
| 318 * "pBytesConsumed" | |
| 319 * The address at which is stored the UInt32 number of bytes taken from the | |
| 320 * current buffer. If this number is less than "bytesAvailable", then bytes | |
| 321 * remain in the buffer for the next LdapResponse. Must be non-NULL. | |
| 322 * "pLdapResponse" | |
| 323 * The address where the created LdapResponse is stored. Must be non-NULL. | |
| 324 * "plContext" | |
| 325 * Platform-specific context pointer. | |
| 326 * THREAD SAFETY: | |
| 327 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 328 * RETURNS: | |
| 329 * Returns NULL if the function succeeds. | |
| 330 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 331 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 332 */ | |
| 333 PKIX_Error * | |
| 334 pkix_pl_LdapResponse_Create( | |
| 335 LDAPMessageType responseType, | |
| 336 PKIX_UInt32 totalLength, | |
| 337 PKIX_UInt32 bytesAvailable, | |
| 338 void *partialData, | |
| 339 PKIX_UInt32 *pBytesConsumed, | |
| 340 PKIX_PL_LdapResponse **pLdapResponse, | |
| 341 void *plContext) | |
| 342 { | |
| 343 PKIX_UInt32 bytesConsumed = 0; | |
| 344 PKIX_PL_LdapResponse *ldapResponse = NULL; | |
| 345 void *data = NULL; | |
| 346 | |
| 347 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Create"); | |
| 348 PKIX_NULLCHECK_ONE(pLdapResponse); | |
| 349 | |
| 350 if (bytesAvailable <= totalLength) { | |
| 351 bytesConsumed = bytesAvailable; | |
| 352 } else { | |
| 353 bytesConsumed = totalLength; | |
| 354 } | |
| 355 | |
| 356 /* create a PKIX_PL_LdapResponse object */ | |
| 357 PKIX_CHECK(PKIX_PL_Object_Alloc | |
| 358 (PKIX_LDAPRESPONSE_TYPE, | |
| 359 sizeof (PKIX_PL_LdapResponse), | |
| 360 (PKIX_PL_Object **)&ldapResponse, | |
| 361 plContext), | |
| 362 PKIX_COULDNOTCREATEOBJECT); | |
| 363 | |
| 364 ldapResponse->decoded.protocolOp.selector = responseType; | |
| 365 ldapResponse->totalLength = totalLength; | |
| 366 ldapResponse->partialLength = bytesConsumed; | |
| 367 | |
| 368 if (totalLength != 0){ | |
| 369 /* Alloc space for array */ | |
| 370 PKIX_NULLCHECK_ONE(partialData); | |
| 371 | |
| 372 PKIX_CHECK(PKIX_PL_Malloc | |
| 373 (totalLength, | |
| 374 &data, | |
| 375 plContext), | |
| 376 PKIX_MALLOCFAILED); | |
| 377 | |
| 378 PKIX_PL_NSSCALL | |
| 379 (LDAPRESPONSE, | |
| 380 PORT_Memcpy, | |
| 381 (data, partialData, bytesConsumed)); | |
| 382 } | |
| 383 | |
| 384 ldapResponse->derEncoded.type = siBuffer; | |
| 385 ldapResponse->derEncoded.data = data; | |
| 386 ldapResponse->derEncoded.len = totalLength; | |
| 387 *pBytesConsumed = bytesConsumed; | |
| 388 *pLdapResponse = ldapResponse; | |
| 389 | |
| 390 cleanup: | |
| 391 | |
| 392 if (PKIX_ERROR_RECEIVED){ | |
| 393 PKIX_DECREF(ldapResponse); | |
| 394 } | |
| 395 | |
| 396 PKIX_RETURN(LDAPRESPONSE); | |
| 397 } | |
| 398 | |
| 399 /* | |
| 400 * FUNCTION: pkix_pl_LdapResponse_Append | |
| 401 * DESCRIPTION: | |
| 402 * | |
| 403 * This function updates the LdapResponse pointed to by "response" with up to | |
| 404 * "incrLength" from the buffer pointer to by "incrData", storing the number of | |
| 405 * bytes copied at "pBytesConsumed". | |
| 406 * | |
| 407 * PARAMETERS | |
| 408 * "response" | |
| 409 * The address of the LdapResponse being updated. Must be non-zero. | |
| 410 * "incrLength" | |
| 411 * The UInt32 value for the number of bytes of data available in the | |
| 412 * current buffer. | |
| 413 * "incrData" | |
| 414 * The address from which data is to be copied. | |
| 415 * "pBytesConsumed" | |
| 416 * The address at which is stored the UInt32 number of bytes taken from the | |
| 417 * current buffer. If this number is less than "incrLength", then bytes | |
| 418 * remain in the buffer for the next LdapResponse. Must be non-NULL. | |
| 419 * "plContext" | |
| 420 * Platform-specific context pointer. | |
| 421 * THREAD SAFETY: | |
| 422 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 423 * RETURNS: | |
| 424 * Returns NULL if the function succeeds. | |
| 425 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 426 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 427 */ | |
| 428 PKIX_Error * | |
| 429 pkix_pl_LdapResponse_Append( | |
| 430 PKIX_PL_LdapResponse *response, | |
| 431 PKIX_UInt32 incrLength, | |
| 432 void *incrData, | |
| 433 PKIX_UInt32 *pBytesConsumed, | |
| 434 void *plContext) | |
| 435 { | |
| 436 PKIX_UInt32 newPartialLength = 0; | |
| 437 PKIX_UInt32 bytesConsumed = 0; | |
| 438 void *dest = NULL; | |
| 439 | |
| 440 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Append"); | |
| 441 PKIX_NULLCHECK_TWO(response, pBytesConsumed); | |
| 442 | |
| 443 if (incrLength > 0) { | |
| 444 | |
| 445 /* Calculate how many bytes we have room for. */ | |
| 446 bytesConsumed = | |
| 447 response->totalLength - response->partialLength; | |
| 448 | |
| 449 if (bytesConsumed > incrLength) { | |
| 450 bytesConsumed = incrLength; | |
| 451 } | |
| 452 | |
| 453 newPartialLength = response->partialLength + bytesConsumed; | |
| 454 | |
| 455 PKIX_NULLCHECK_ONE(incrData); | |
| 456 | |
| 457 dest = &(((char *)response->derEncoded.data)[ | |
| 458 response->partialLength]); | |
| 459 | |
| 460 PKIX_PL_NSSCALL | |
| 461 (LDAPRESPONSE, | |
| 462 PORT_Memcpy, | |
| 463 (dest, incrData, bytesConsumed)); | |
| 464 | |
| 465 response->partialLength = newPartialLength; | |
| 466 } | |
| 467 | |
| 468 *pBytesConsumed = bytesConsumed; | |
| 469 | |
| 470 PKIX_RETURN(LDAPRESPONSE); | |
| 471 } | |
| 472 | |
| 473 /* | |
| 474 * FUNCTION: pkix_pl_LdapResponse_IsComplete | |
| 475 * DESCRIPTION: | |
| 476 * | |
| 477 * This function determines whether the LdapResponse pointed to by "response" | |
| 478 * contains all the data called for by the "totalLength" parameter provided | |
| 479 * when it was created, storing PKIX_TRUE at "pIsComplete" if so, and | |
| 480 * PKIX_FALSE otherwise. | |
| 481 * | |
| 482 * PARAMETERS | |
| 483 * "response" | |
| 484 * The address of the LdapResponse being evaluaTED. Must be non-zero. | |
| 485 * "incrLength" | |
| 486 * The UInt32 value for the number of bytes of data available in the | |
| 487 * current buffer. | |
| 488 * "incrData" | |
| 489 * The address from which data is to be copied. | |
| 490 * "pIsComplete" | |
| 491 * The address at which is stored the Boolean indication of whether the | |
| 492 * LdapResponse is complete. Must be non-NULL. | |
| 493 * "plContext" | |
| 494 * Platform-specific context pointer. | |
| 495 * THREAD SAFETY: | |
| 496 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 497 * RETURNS: | |
| 498 * Returns NULL if the function succeeds. | |
| 499 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 500 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 501 */ | |
| 502 PKIX_Error * | |
| 503 pkix_pl_LdapResponse_IsComplete( | |
| 504 PKIX_PL_LdapResponse *response, | |
| 505 PKIX_Boolean *pIsComplete, | |
| 506 void *plContext) | |
| 507 { | |
| 508 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_IsComplete"); | |
| 509 PKIX_NULLCHECK_TWO(response, pIsComplete); | |
| 510 | |
| 511 if (response->totalLength == response->partialLength) { | |
| 512 *pIsComplete = PKIX_TRUE; | |
| 513 } else { | |
| 514 *pIsComplete = PKIX_FALSE; | |
| 515 } | |
| 516 | |
| 517 PKIX_RETURN(LDAPRESPONSE); | |
| 518 } | |
| 519 | |
| 520 /* | |
| 521 * FUNCTION: pkix_pl_LdapResponse_Decode | |
| 522 * DESCRIPTION: | |
| 523 * | |
| 524 * This function decodes the DER data contained in the LdapResponse pointed to | |
| 525 * by "response", using the arena pointed to by "arena", and storing at | |
| 526 * "pStatus" SECSuccess if the decoding was successful and SECFailure | |
| 527 * otherwise. The decoded message is stored in an element of "response". | |
| 528 * | |
| 529 * PARAMETERS | |
| 530 * "arena" | |
| 531 * The address of the PLArenaPool to be used in the decoding. Must be | |
| 532 * non-NULL. | |
| 533 * "response" | |
| 534 * The address of the LdapResponse whose DER data is to be decoded. Must | |
| 535 * be non-NULL. | |
| 536 * "pStatus" | |
| 537 * The address at which is stored the status from the decoding, SECSuccess | |
| 538 * if successful, SECFailure otherwise. Must be non-NULL. | |
| 539 * "plContext" | |
| 540 * Platform-specific context pointer. | |
| 541 * THREAD SAFETY: | |
| 542 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 543 * RETURNS: | |
| 544 * Returns NULL if the function succeeds. | |
| 545 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 546 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 547 */ | |
| 548 PKIX_Error * | |
| 549 pkix_pl_LdapResponse_Decode( | |
| 550 PLArenaPool *arena, | |
| 551 PKIX_PL_LdapResponse *response, | |
| 552 SECStatus *pStatus, | |
| 553 void *plContext) | |
| 554 { | |
| 555 LDAPMessage *msg; | |
| 556 SECStatus rv = SECFailure; | |
| 557 | |
| 558 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Decode"); | |
| 559 PKIX_NULLCHECK_THREE(arena, response, pStatus); | |
| 560 | |
| 561 if (response->totalLength != response->partialLength) { | |
| 562 PKIX_ERROR(PKIX_ATTEMPTTODECODEANINCOMPLETERESPONSE); | |
| 563 } | |
| 564 | |
| 565 msg = &(response->decoded); | |
| 566 | |
| 567 PKIX_PL_NSSCALL | |
| 568 (LDAPRESPONSE, PORT_Memset, (msg, 0, sizeof (LDAPMessage))); | |
| 569 | |
| 570 PKIX_PL_NSSCALLRV(LDAPRESPONSE, rv, SEC_ASN1DecodeItem, | |
| 571 (NULL, msg, PKIX_PL_LDAPMessageTemplate, &(response->derEncoded))); | |
| 572 | |
| 573 *pStatus = rv; | |
| 574 cleanup: | |
| 575 | |
| 576 PKIX_RETURN(LDAPRESPONSE); | |
| 577 } | |
| 578 | |
| 579 /* | |
| 580 * FUNCTION: pkix_pl_LdapResponse_GetMessage | |
| 581 * DESCRIPTION: | |
| 582 * | |
| 583 * This function obtains the decoded message from the LdapResponse pointed to | |
| 584 * by "response", storing the result at "pMessage". | |
| 585 * | |
| 586 * PARAMETERS | |
| 587 * "response" | |
| 588 * The address of the LdapResponse whose decoded message is to be | |
| 589 * retrieved. Must be non-NULL. | |
| 590 * "pMessage" | |
| 591 * The address at which is stored the address of the decoded message. Must | |
| 592 * be non-NULL. | |
| 593 * "plContext" | |
| 594 * Platform-specific context pointer. | |
| 595 * THREAD SAFETY: | |
| 596 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 597 * RETURNS: | |
| 598 * Returns NULL if the function succeeds. | |
| 599 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 600 */ | |
| 601 PKIX_Error * | |
| 602 pkix_pl_LdapResponse_GetMessage( | |
| 603 PKIX_PL_LdapResponse *response, | |
| 604 LDAPMessage **pMessage, | |
| 605 void *plContext) | |
| 606 { | |
| 607 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessage"); | |
| 608 PKIX_NULLCHECK_TWO(response, pMessage); | |
| 609 | |
| 610 *pMessage = &response->decoded; | |
| 611 | |
| 612 PKIX_RETURN(LDAPRESPONSE); | |
| 613 } | |
| 614 | |
| 615 /* | |
| 616 * FUNCTION: pkix_pl_LdapResponse_GetCapacity | |
| 617 * DESCRIPTION: | |
| 618 * | |
| 619 * This function obtains from the LdapResponse pointed to by "response" the | |
| 620 * number of bytes remaining to be read, based on the totalLength that was | |
| 621 * provided to LdapResponse_Create and the data subsequently provided to | |
| 622 * LdapResponse_Append, storing the result at "pMessage". | |
| 623 * | |
| 624 * PARAMETERS | |
| 625 * "response" | |
| 626 * The address of the LdapResponse whose remaining capacity is to be | |
| 627 * retrieved. Must be non-NULL. | |
| 628 * "pCapacity" | |
| 629 * The address at which is stored the address of the decoded message. Must | |
| 630 * be non-NULL. | |
| 631 * "plContext" | |
| 632 * Platform-specific context pointer. | |
| 633 * THREAD SAFETY: | |
| 634 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 635 * RETURNS: | |
| 636 * Returns NULL if the function succeeds. | |
| 637 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 638 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 639 */ | |
| 640 PKIX_Error * | |
| 641 pkix_pl_LdapResponse_GetCapacity( | |
| 642 PKIX_PL_LdapResponse *response, | |
| 643 PKIX_UInt32 *pCapacity, | |
| 644 void *plContext) | |
| 645 { | |
| 646 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetCapacity"); | |
| 647 PKIX_NULLCHECK_TWO(response, pCapacity); | |
| 648 | |
| 649 *pCapacity = response->totalLength - response->partialLength; | |
| 650 | |
| 651 PKIX_RETURN(LDAPRESPONSE); | |
| 652 } | |
| 653 | |
| 654 /* | |
| 655 * FUNCTION: pkix_pl_LdapResponse_GetMessageType | |
| 656 * DESCRIPTION: | |
| 657 * | |
| 658 * This function obtains the message type from the LdapResponse pointed to | |
| 659 * by "response", storing the result at "pMessageType". | |
| 660 * | |
| 661 * PARAMETERS | |
| 662 * "response" | |
| 663 * The address of the LdapResponse whose message type is to be | |
| 664 * retrieved. Must be non-NULL. | |
| 665 * "pMessageType" | |
| 666 * The address at which is stored the type of the response message. Must | |
| 667 * be non-NULL. | |
| 668 * "plContext" | |
| 669 * Platform-specific context pointer. | |
| 670 * THREAD SAFETY: | |
| 671 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 672 * RETURNS: | |
| 673 * Returns NULL if the function succeeds. | |
| 674 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 675 */ | |
| 676 PKIX_Error * | |
| 677 pkix_pl_LdapResponse_GetMessageType( | |
| 678 PKIX_PL_LdapResponse *response, | |
| 679 LDAPMessageType *pMessageType, | |
| 680 void *plContext) | |
| 681 { | |
| 682 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessageType"); | |
| 683 PKIX_NULLCHECK_TWO(response, pMessageType); | |
| 684 | |
| 685 *pMessageType = response->decoded.protocolOp.selector; | |
| 686 | |
| 687 PKIX_RETURN(LDAPRESPONSE); | |
| 688 } | |
| 689 | |
| 690 /* | |
| 691 * FUNCTION: pkix_pl_LdapResponse_GetResultCode | |
| 692 * DESCRIPTION: | |
| 693 * | |
| 694 * This function obtains the result code from the LdapResponse pointed to | |
| 695 * by "response", storing the result at "pResultCode". | |
| 696 * | |
| 697 * PARAMETERS | |
| 698 * "response" | |
| 699 * The address of the LdapResponse whose result code is to be | |
| 700 * retrieved. Must be non-NULL. | |
| 701 * "pResultCode" | |
| 702 * The address at which is stored the address of the decoded message. Must | |
| 703 * be non-NULL. | |
| 704 * "plContext" | |
| 705 * Platform-specific context pointer. | |
| 706 * THREAD SAFETY: | |
| 707 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 708 * RETURNS: | |
| 709 * Returns NULL if the function succeeds. | |
| 710 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 711 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 712 */ | |
| 713 PKIX_Error * | |
| 714 pkix_pl_LdapResponse_GetResultCode( | |
| 715 PKIX_PL_LdapResponse *response, | |
| 716 LDAPResultCode *pResultCode, | |
| 717 void *plContext) | |
| 718 { | |
| 719 LDAPMessageType messageType = 0; | |
| 720 LDAPSearchResponseResult *resultMsg = NULL; | |
| 721 | |
| 722 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode"); | |
| 723 PKIX_NULLCHECK_TWO(response, pResultCode); | |
| 724 | |
| 725 messageType = response->decoded.protocolOp.selector; | |
| 726 | |
| 727 if (messageType != LDAP_SEARCHRESPONSERESULT_TYPE) { | |
| 728 PKIX_ERROR(PKIX_GETRESULTCODECALLEDFORNONRESULTMESSAGE); | |
| 729 } | |
| 730 | |
| 731 resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg; | |
| 732 | |
| 733 *pResultCode = *(resultMsg->resultCode.data); | |
| 734 | |
| 735 cleanup: | |
| 736 | |
| 737 PKIX_RETURN(LDAPRESPONSE); | |
| 738 } | |
| 739 | |
| 740 /* | |
| 741 * FUNCTION: pkix_pl_LdapResponse_GetAttributes | |
| 742 * DESCRIPTION: | |
| 743 * | |
| 744 * This function obtains the attributes from the LdapResponse pointed to | |
| 745 * by "response", storing the result at "pAttributes". | |
| 746 * | |
| 747 * PARAMETERS | |
| 748 * "response" | |
| 749 * The address of the LdapResponse whose decoded message is to be | |
| 750 * retrieved. Must be non-NULL. | |
| 751 * "pAttributes" | |
| 752 * The address at which is stored the attributes of the message. Must be | |
| 753 * non-NULL. | |
| 754 * "plContext" | |
| 755 * Platform-specific context pointer. | |
| 756 * THREAD SAFETY: | |
| 757 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 758 * RETURNS: | |
| 759 * Returns NULL if the function succeeds. | |
| 760 * Returns an LdapResponse Error if the function fails in a non-fatal way. | |
| 761 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 762 */ | |
| 763 PKIX_Error * | |
| 764 pkix_pl_LdapResponse_GetAttributes( | |
| 765 PKIX_PL_LdapResponse *response, | |
| 766 LDAPSearchResponseAttr ***pAttributes, | |
| 767 void *plContext) | |
| 768 { | |
| 769 LDAPMessageType messageType = 0; | |
| 770 | |
| 771 PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode"); | |
| 772 PKIX_NULLCHECK_TWO(response, pAttributes); | |
| 773 | |
| 774 messageType = response->decoded.protocolOp.selector; | |
| 775 | |
| 776 if (messageType != LDAP_SEARCHRESPONSEENTRY_TYPE) { | |
| 777 PKIX_ERROR(PKIX_GETATTRIBUTESCALLEDFORNONENTRYMESSAGE); | |
| 778 } | |
| 779 | |
| 780 *pAttributes = response-> | |
| 781 decoded.protocolOp.op.searchResponseEntryMsg.attributes; | |
| 782 | |
| 783 cleanup: | |
| 784 | |
| 785 PKIX_RETURN(LDAPRESPONSE); | |
| 786 } | |
| OLD | NEW |