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