Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_infoaccess.c
6 *
7 * InfoAccess Object Definitions
8 *
9 */
10
11 #include "pkix_pl_infoaccess.h"
12
13 /* --Private-InfoAccess-Functions----------------------------------*/
14
15 /*
16 * FUNCTION: pkix_pl_InfoAccess_Create
17 * DESCRIPTION:
18 *
19 * This function creates an InfoAccess from the method provided in "method" and
20 * the GeneralName provided in "generalName" and stores the result at
21 * "pInfoAccess".
22 *
23 * PARAMETERS
24 * "method"
25 * The UInt32 value to be stored as the method field of the InfoAccess.
26 * "generalName"
27 * The GeneralName to be stored as the generalName field of the InfoAccess.
28 * Must be non-NULL.
29 * "pInfoAccess"
30 * Address where the result is stored. Must be non-NULL.
31 * "plContext"
32 * Platform-specific context pointer.
33 * THREAD SAFETY:
34 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
35 * RETURNS:
36 * Returns NULL if the function succeeds.
37 * Returns a Fatal Error if the function fails in an unrecoverable way.
38 */
39 static PKIX_Error *
40 pkix_pl_InfoAccess_Create(
41 PKIX_UInt32 method,
42 PKIX_PL_GeneralName *generalName,
43 PKIX_PL_InfoAccess **pInfoAccess,
44 void *plContext)
45 {
46
47 PKIX_PL_InfoAccess *infoAccess = NULL;
48
49 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Create");
50 PKIX_NULLCHECK_TWO(generalName, pInfoAccess);
51
52 PKIX_CHECK(PKIX_PL_Object_Alloc
53 (PKIX_INFOACCESS_TYPE,
54 sizeof (PKIX_PL_InfoAccess),
55 (PKIX_PL_Object **)&infoAccess,
56 plContext),
57 PKIX_COULDNOTCREATEINFOACCESSOBJECT);
58
59 infoAccess->method = method;
60
61 PKIX_INCREF(generalName);
62 infoAccess->location = generalName;
63
64 *pInfoAccess = infoAccess;
65 infoAccess = NULL;
66
67 cleanup:
68 PKIX_DECREF(infoAccess);
69
70 PKIX_RETURN(INFOACCESS);
71 }
72
73 /*
74 * FUNCTION: pkix_pl_InfoAccess_Destroy
75 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
76 */
77 static PKIX_Error *
78 pkix_pl_InfoAccess_Destroy(
79 PKIX_PL_Object *object,
80 void *plContext)
81 {
82 PKIX_PL_InfoAccess *infoAccess = NULL;
83
84 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Destroy");
85 PKIX_NULLCHECK_ONE(object);
86
87 PKIX_CHECK(pkix_CheckType(object, PKIX_INFOACCESS_TYPE, plContext),
88 PKIX_OBJECTNOTANINFOACCESS);
89
90 infoAccess = (PKIX_PL_InfoAccess *)object;
91
92 PKIX_DECREF(infoAccess->location);
93
94 cleanup:
95
96 PKIX_RETURN(INFOACCESS);
97 }
98
99 /*
100 * FUNCTION: pkix_pl_InfoAccess_ToString
101 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_pki.h)
102 */
103 static PKIX_Error *
104 pkix_pl_InfoAccess_ToString(
105 PKIX_PL_Object *object,
106 PKIX_PL_String **pString,
107 void *plContext)
108 {
109 PKIX_PL_InfoAccess *infoAccess;
110 PKIX_PL_String *infoAccessString = NULL;
111 char *asciiFormat = NULL;
112 char *asciiMethod = NULL;
113 PKIX_PL_String *formatString = NULL;
114 PKIX_PL_String *methodString = NULL;
115 PKIX_PL_String *locationString = NULL;
116
117 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ToString");
118 PKIX_NULLCHECK_TWO(object, pString);
119
120 PKIX_CHECK(pkix_CheckType
121 (object, PKIX_INFOACCESS_TYPE, plContext),
122 PKIX_OBJECTNOTINFOACCESS);
123
124 infoAccess = (PKIX_PL_InfoAccess *)object;
125
126 asciiFormat =
127 "["
128 "method:%s, "
129 "location:%s"
130 "]";
131
132 PKIX_CHECK(PKIX_PL_String_Create
133 (PKIX_ESCASCII,
134 asciiFormat,
135 0,
136 &formatString,
137 plContext),
138 PKIX_STRINGCREATEFAILED);
139
140 switch(infoAccess->method) {
141 case PKIX_INFOACCESS_CA_ISSUERS:
142 asciiMethod = "caIssuers";
143 break;
144 case PKIX_INFOACCESS_OCSP:
145 asciiMethod = "ocsp";
146 break;
147 case PKIX_INFOACCESS_TIMESTAMPING:
148 asciiMethod = "timestamping";
149 break;
150 case PKIX_INFOACCESS_CA_REPOSITORY:
151 asciiMethod = "caRepository";
152 break;
153 default:
154 asciiMethod = "unknown";
155 }
156
157 PKIX_CHECK(PKIX_PL_String_Create
158 (PKIX_ESCASCII,
159 asciiMethod,
160 0,
161 &methodString,
162 plContext),
163 PKIX_STRINGCREATEFAILED);
164
165 PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
166 PKIX_GENERALNAMETOSTRINGFAILED);
167
168 PKIX_CHECK(PKIX_PL_Sprintf
169 (&infoAccessString,
170 plContext,
171 formatString,
172 methodString,
173 locationString),
174 PKIX_SPRINTFFAILED);
175
176 *pString = infoAccessString;
177
178 cleanup:
179
180 PKIX_DECREF(formatString);
181 PKIX_DECREF(methodString);
182 PKIX_DECREF(locationString);
183
184 PKIX_RETURN(INFOACCESS);
185 }
186
187 /*
188 * FUNCTION: pkix_pl_InfoAccess_Hashcode
189 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_pki.h)
190 */
191 static PKIX_Error *
192 pkix_pl_InfoAccess_Hashcode(
193 PKIX_PL_Object *object,
194 PKIX_UInt32 *pHashcode,
195 void *plContext)
196 {
197 PKIX_PL_InfoAccess *infoAccess = NULL;
198 PKIX_UInt32 infoAccessHash;
199
200 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Hashcode");
201 PKIX_NULLCHECK_TWO(object, pHashcode);
202
203 PKIX_CHECK(pkix_CheckType
204 (object, PKIX_INFOACCESS_TYPE, plContext),
205 PKIX_OBJECTNOTINFOACCESS);
206
207 infoAccess = (PKIX_PL_InfoAccess *)object;
208
209 PKIX_HASHCODE(infoAccess->location, &infoAccessHash, plContext,
210 PKIX_OBJECTHASHCODEFAILED);
211
212 infoAccessHash += (infoAccess->method << 7);
213
214 *pHashcode = infoAccessHash;
215
216 cleanup:
217
218 PKIX_RETURN(INFOACCESS);
219
220 }
221
222 /*
223 * FUNCTION: pkix_pl_InfoAccess_Equals
224 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_pki.h)
225 */
226 static PKIX_Error *
227 pkix_pl_InfoAccess_Equals(
228 PKIX_PL_Object *firstObject,
229 PKIX_PL_Object *secondObject,
230 PKIX_Boolean *pResult,
231 void *plContext)
232 {
233 PKIX_PL_InfoAccess *firstInfoAccess = NULL;
234 PKIX_PL_InfoAccess *secondInfoAccess = NULL;
235 PKIX_UInt32 secondType;
236 PKIX_Boolean cmpResult;
237
238 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Equals");
239 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
240
241 /* test that firstObject is a InfoAccess */
242 PKIX_CHECK(pkix_CheckType
243 (firstObject, PKIX_INFOACCESS_TYPE, plContext),
244 PKIX_FIRSTOBJECTNOTINFOACCESS);
245
246 /*
247 * Since we know firstObject is a InfoAccess, if both references are
248 * identical, they must be equal
249 */
250 if (firstObject == secondObject){
251 *pResult = PKIX_TRUE;
252 goto cleanup;
253 }
254
255 /*
256 * If secondObject isn't a InfoAccess, we don't throw an error.
257 * We simply return a Boolean result of FALSE
258 */
259 *pResult = PKIX_FALSE;
260 PKIX_CHECK(PKIX_PL_Object_GetType
261 (secondObject, &secondType, plContext),
262 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
263 if (secondType != PKIX_INFOACCESS_TYPE) goto cleanup;
264
265 firstInfoAccess = (PKIX_PL_InfoAccess *)firstObject;
266 secondInfoAccess = (PKIX_PL_InfoAccess *)secondObject;
267
268 *pResult = PKIX_FALSE;
269
270 if (firstInfoAccess->method != secondInfoAccess->method) {
271 goto cleanup;
272 }
273
274 PKIX_EQUALS(firstInfoAccess, secondInfoAccess, &cmpResult, plContext,
275 PKIX_OBJECTEQUALSFAILED);
276
277 *pResult = cmpResult;
278
279 cleanup:
280
281 PKIX_RETURN(INFOACCESS);
282 }
283
284 /*
285 * FUNCTION: pkix_pl_InfoAccess_RegisterSelf
286 * DESCRIPTION:
287 * Registers PKIX_INFOACCESS_TYPE and its related functions with systemClasses[ ]
288 * THREAD SAFETY:
289 * Not Thread Safe - for performance and complexity reasons
290 *
291 * Since this function is only called by PKIX_PL_Initialize, which should
292 * only be called once, it is acceptable that this function is not
293 * thread-safe.
294 */
295 PKIX_Error *
296 pkix_pl_InfoAccess_RegisterSelf(void *plContext)
297 {
298 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
299 pkix_ClassTable_Entry entry;
300
301 PKIX_ENTER(INFOACCESS,
302 "pkix_pl_InfoAccess_RegisterSelf");
303
304 entry.description = "InfoAccess";
305 entry.objCounter = 0;
306 entry.typeObjectSize = sizeof(PKIX_PL_InfoAccess);
307 entry.destructor = pkix_pl_InfoAccess_Destroy;
308 entry.equalsFunction = pkix_pl_InfoAccess_Equals;
309 entry.hashcodeFunction = pkix_pl_InfoAccess_Hashcode;
310 entry.toStringFunction = pkix_pl_InfoAccess_ToString;
311 entry.comparator = NULL;
312 entry.duplicateFunction = pkix_duplicateImmutable;
313
314 systemClasses[PKIX_INFOACCESS_TYPE] = entry;
315
316 PKIX_RETURN(INFOACCESS);
317 }
318
319 /*
320 * FUNCTION: pkix_pl_InfoAccess_CreateList
321 * DESCRIPTION:
322 *
323 * Based on data in CERTAuthInfoAccess array "nssInfoAccess", this function
324 * creates and returns a PKIX_List of PKIX_PL_InfoAccess at "pInfoAccessList".
325 *
326 * PARAMETERS
327 * "nssInfoAccess"
328 * The pointer array of CERTAuthInfoAccess that contains access data.
329 * May be NULL.
330 * "pInfoAccessList"
331 * Address where a list of PKIX_PL_InfoAccess is returned.
332 * Must be non-NULL.
333 * "plContext"
334 * Platform-specific context pointer.
335 * THREAD SAFETY:
336 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
337 * RETURNS:
338 * Returns NULL if the function succeeds.
339 * Returns a Fatal Error if the function fails in an unrecoverable way.
340 */
341 PKIX_Error *
342 pkix_pl_InfoAccess_CreateList(
343 CERTAuthInfoAccess **nssInfoAccess,
344 PKIX_List **pInfoAccessList, /* of PKIX_PL_InfoAccess */
345 void *plContext)
346 {
347 PKIX_List *infoAccessList = NULL;
348 PKIX_PL_InfoAccess *infoAccess = NULL;
349 PKIX_PL_GeneralName *location = NULL;
350 PKIX_UInt32 method;
351 int i;
352
353 PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_CreateList");
354 PKIX_NULLCHECK_ONE(pInfoAccessList);
355
356 PKIX_CHECK(PKIX_List_Create(&infoAccessList, plContext),
357 PKIX_LISTCREATEFAILED);
358
359 if (nssInfoAccess == NULL) {
360 goto cleanup;
361 }
362
363 for (i = 0; nssInfoAccess[i] != NULL; i++) {
364
365 if (nssInfoAccess[i]->location == NULL) {
366 continue;
367 }
368
369 PKIX_CHECK(pkix_pl_GeneralName_Create
370 (nssInfoAccess[i]->location, &location, plContext),
371 PKIX_GENERALNAMECREATEFAILED);
372
373 PKIX_CERT_DEBUG("\t\tCalling SECOID_FindOIDTag).\n");
374 method = SECOID_FindOIDTag(&nssInfoAccess[i]->method);
375 /* Map NSS access method value into PKIX constant */
376 switch(method) {
377 case SEC_OID_PKIX_CA_ISSUERS:
378 method = PKIX_INFOACCESS_CA_ISSUERS;
379 break;
380 case SEC_OID_PKIX_OCSP:
381 method = PKIX_INFOACCESS_OCSP;
382 break;
383 case SEC_OID_PKIX_TIMESTAMPING:
384 method = PKIX_INFOACCESS_TIMESTAMPING;
385 break;
386 case SEC_OID_PKIX_CA_REPOSITORY:
387 method = PKIX_INFOACCESS_CA_REPOSITORY;
388 break;
389 default:
390 PKIX_ERROR(PKIX_UNKNOWNINFOACCESSMETHOD);
391 }
392
393 PKIX_CHECK(pkix_pl_InfoAccess_Create
394 (method, location, &infoAccess, plContext),
395 PKIX_INFOACCESSCREATEFAILED);
396
397 PKIX_CHECK(PKIX_List_AppendItem
398 (infoAccessList,
399 (PKIX_PL_Object *)infoAccess,
400 plContext),
401 PKIX_LISTAPPENDITEMFAILED);
402 PKIX_DECREF(infoAccess);
403 PKIX_DECREF(location);
404 }
405
406 *pInfoAccessList = infoAccessList;
407 infoAccessList = NULL;
408
409 cleanup:
410
411 PKIX_DECREF(infoAccessList);
412 PKIX_DECREF(infoAccess);
413 PKIX_DECREF(location);
414
415 PKIX_RETURN(INFOACCESS);
416 }
417
418 /* --Public-Functions------------------------------------------------------- */
419
420 /*
421 * FUNCTION: PKIX_PL_InfoAccess_GetMethod (see comments in pkix_pl_pki.h)
422 */
423 PKIX_Error *
424 PKIX_PL_InfoAccess_GetMethod(
425 PKIX_PL_InfoAccess *infoAccess,
426 PKIX_UInt32 *pMethod,
427 void *plContext)
428 {
429 PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetMethod");
430 PKIX_NULLCHECK_TWO(infoAccess, pMethod);
431
432 *pMethod = infoAccess->method;
433
434 PKIX_RETURN(INFOACCESS);
435 }
436
437 /*
438 * FUNCTION: PKIX_PL_InfoAccess_GetLocation (see comments in pkix_pl_pki.h)
439 */
440 PKIX_Error *
441 PKIX_PL_InfoAccess_GetLocation(
442 PKIX_PL_InfoAccess *infoAccess,
443 PKIX_PL_GeneralName **pLocation,
444 void *plContext)
445 {
446 PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocation");
447 PKIX_NULLCHECK_TWO(infoAccess, pLocation);
448
449 PKIX_INCREF(infoAccess->location);
450
451 *pLocation = infoAccess->location;
452
453 cleanup:
454 PKIX_RETURN(INFOACCESS);
455 }
456
457 /*
458 * FUNCTION: PKIX_PL_InfoAccess_GetLocationType (see comments in pkix_pl_pki.h)
459 */
460 PKIX_Error *
461 PKIX_PL_InfoAccess_GetLocationType(
462 PKIX_PL_InfoAccess *infoAccess,
463 PKIX_UInt32 *pType,
464 void *plContext)
465 {
466 PKIX_PL_String *locationString = NULL;
467 PKIX_UInt32 type = PKIX_INFOACCESS_LOCATION_UNKNOWN;
468 PKIX_UInt32 len = 0;
469 void *location = NULL;
470
471 PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocationType");
472 PKIX_NULLCHECK_TWO(infoAccess, pType);
473
474 if (infoAccess->location != NULL) {
475
476 PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
477 PKIX_GENERALNAMETOSTRINGFAILED);
478
479 PKIX_CHECK(PKIX_PL_String_GetEncoded
480 (locationString, PKIX_ESCASCII, &location, &len, plContext),
481 PKIX_STRINGGETENCODEDFAILED);
482
483 PKIX_OID_DEBUG("\tCalling PORT_Strcmp).\n");
484 #ifndef NSS_PKIX_NO_LDAP
485 if (PORT_Strncmp(location, "ldap:", 5) == 0){
486 type = PKIX_INFOACCESS_LOCATION_LDAP;
487 } else
488 #endif
489 if (PORT_Strncmp(location, "http:", 5) == 0){
490 type = PKIX_INFOACCESS_LOCATION_HTTP;
491 }
492 }
493
494 *pType = type;
495
496 cleanup:
497
498 PKIX_PL_Free(location, plContext);
499 PKIX_DECREF(locationString);
500
501 PKIX_RETURN(INFOACCESS);
502 }
503
504 #ifndef NSS_PKIX_NO_LDAP
505 /*
506 * FUNCTION: pkix_pl_InfoAccess_ParseTokens
507 * DESCRIPTION:
508 *
509 * This function parses the string beginning at "startPos" into tokens using
510 * the separator contained in "separator" and the terminator contained in
511 * "terminator", copying the tokens into space allocated from the arena
512 * pointed to by "arena". It stores in "tokens" a null-terminated array of
513 * pointers to those tokens.
514 *
515 * PARAMETERS
516 * "arena"
517 * Address of a PLArenaPool to be used in populating the LDAPLocation.
518 * Must be non-NULL.
519 * "startPos"
520 * The address of char string that contains a subset of ldap location.
521 * "tokens"
522 * The address of an array of char string for storing returned tokens.
523 * Must be non-NULL.
524 * "separator"
525 * The character that is taken as token separator. Must be non-NULL.
526 * "terminator"
527 * The character that is taken as parsing terminator. Must be non-NULL.
528 * "plContext"
529 * Platform-specific context pointer.
530 * THREAD SAFETY:
531 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
532 * RETURNS:
533 * Returns NULL if the function succeeds.
534 * Returns an InfoAccess Error if the function fails in a non-fatal way.
535 * Returns a Fatal Error if the function fails in an unrecoverable way.
536 */
537 static PKIX_Error *
538 pkix_pl_InfoAccess_ParseTokens(
539 PLArenaPool *arena,
540 char **startPos, /* return update */
541 char ***tokens,
542 char separator,
543 char terminator,
544 void *plContext)
545 {
546 PKIX_UInt32 numFilters = 0;
547 char *endPos = NULL;
548 char **filterP = NULL;
549
550 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseTokens");
551 PKIX_NULLCHECK_THREE(arena, startPos, tokens);
552
553 endPos = *startPos;
554
555 /* First pass: parse to <terminator> to count number of components */
556 numFilters = 0;
557 while (*endPos != terminator && *endPos != '\0') {
558 endPos++;
559 if (*endPos == separator) {
560 numFilters++;
561 }
562 }
563
564 if (*endPos != terminator) {
565 PKIX_ERROR(PKIX_LOCATIONSTRINGNOTPROPERLYTERMINATED);
566 }
567
568 /* Last component doesn't need a separator, although we allow it */
569 if (endPos > *startPos && *(endPos-1) != separator) {
570 numFilters++;
571 }
572
573 /*
574 * If string is a=xx, b=yy, c=zz, etc., use a=xx for filter,
575 * and everything else for the base
576 */
577 if (numFilters > 2) numFilters = 2;
578
579 filterP = PORT_ArenaZNewArray(arena, char*, numFilters+1);
580 if (filterP == NULL) {
581 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
582 }
583
584 /* Second pass: parse to fill in components in token array */
585 *tokens = filterP;
586 endPos = *startPos;
587
588 while (numFilters) {
589 if (*endPos == separator || *endPos == terminator) {
590 PKIX_UInt32 len = endPos - *startPos;
591 char *p = PORT_ArenaZAlloc(arena, len+1);
592 if (p == NULL) {
593 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
594 }
595
596 PORT_Memcpy(p, *startPos, len);
597 p[len] = '\0';
598
599 *filterP = p;
600 filterP++;
601 numFilters--;
602
603 separator = terminator;
604
605 if (*endPos == '\0') {
606 *startPos = endPos;
607 break;
608 } else {
609 endPos++;
610 *startPos = endPos;
611 continue;
612 }
613 }
614 endPos++;
615 }
616
617 *filterP = NULL;
618
619 cleanup:
620
621 PKIX_RETURN(INFOACCESS);
622 }
623
624 static int
625 pkix_pl_HexDigitToInt(
626 int ch)
627 {
628 if (isdigit(ch)) {
629 ch = ch - '0';
630 } else if (isupper(ch)) {
631 ch = ch - 'A' + 10;
632 } else {
633 ch = ch - 'a' + 10;
634 }
635 return ch;
636 }
637
638 /*
639 * Convert the "%" hex hex escape sequences in the URL 'location' in place.
640 */
641 static void
642 pkix_pl_UnescapeURL(
643 char *location)
644 {
645 const char *src;
646 char *dst;
647
648 for (src = dst = location; *src != '\0'; src++, dst++) {
649 if (*src == '%' && isxdigit((unsigned char)*(src+1)) &&
650 isxdigit((unsigned char)*(src+2))) {
651 *dst = pkix_pl_HexDigitToInt((unsigned char)*(src+1));
652 *dst *= 16;
653 *dst += pkix_pl_HexDigitToInt((unsigned char)*(src+2));
654 src += 2;
655 } else {
656 *dst = *src;
657 }
658 }
659 *dst = *src; /* the terminating null */
660 }
661
662 /*
663 * FUNCTION: pkix_pl_InfoAccess_ParseLocation
664 * DESCRIPTION:
665 *
666 * This function parses the GeneralName pointed to by "generalName" into the
667 * fields of the LDAPRequestParams pointed to by "request" and a domainName
668 * pointed to by "pDomainName", using the PLArenaPool pointed to by "arena" to
669 * allocate storage for the request components and for the domainName string.
670 *
671 * The expected GeneralName string should be in the format described by the
672 * following BNF:
673 *
674 * ldap://<ldap-server-site>/[cn=<cname>][,o=<org>][,c=<country>]?
675 * [caCertificate|crossCertificatPair|certificateRevocationList];
676 * [binary|<other-type>]
677 * [[,caCertificate|crossCertificatPair|certificateRevocationList]
678 * [binary|<other-type>]]*
679 *
680 * PARAMETERS
681 * "generalName"
682 * Address of the GeneralName whose LDAPLocation is to be parsed. Must be
683 * non-NULL.
684 * "arena"
685 * Address of PLArenaPool to be used for the domainName and for components
686 * of the LDAPRequest. Must be non-NULL.
687 * "request"
688 * Address of the LDAPRequestParams into which request components are
689 * stored. Must be non-NULL.
690 * *pDomainName"
691 * Address at which the domainName is stored. Must be non-NULL.
692 * "plContext"
693 * Platform-specific context pointer.
694 * THREAD SAFETY:
695 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
696 * RETURNS:
697 * Returns NULL if the function succeeds.
698 * Returns an InfoAccess Error if the function fails in a non-fatal way.
699 * Returns a Fatal Error if the function fails in an unrecoverable way.
700 */
701 PKIX_Error *
702 pkix_pl_InfoAccess_ParseLocation(
703 PKIX_PL_GeneralName *generalName,
704 PLArenaPool *arena,
705 LDAPRequestParams *request,
706 char **pDomainName,
707 void *plContext)
708 {
709 PKIX_PL_String *locationString = NULL;
710 PKIX_UInt32 len = 0;
711 PKIX_UInt32 ncIndex = 0;
712 char *domainName = NULL;
713 char **avaArray = NULL;
714 char **attrArray = NULL;
715 char *attr = NULL;
716 char *locationAscii = NULL;
717 char *startPos = NULL;
718 char *endPos = NULL;
719 char *avaPtr = NULL;
720 LdapAttrMask attrBit = 0;
721 LDAPNameComponent **setOfNameComponent = NULL;
722 LDAPNameComponent *nameComponent = NULL;
723
724 PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseLocation");
725 PKIX_NULLCHECK_FOUR(generalName, arena, request, pDomainName);
726
727 PKIX_TOSTRING(generalName, &locationString, plContext,
728 PKIX_GENERALNAMETOSTRINGFAILED);
729
730 PKIX_CHECK(PKIX_PL_String_GetEncoded
731 (locationString,
732 PKIX_ESCASCII,
733 (void **)&locationAscii,
734 &len,
735 plContext),
736 PKIX_STRINGGETENCODEDFAILED);
737
738 pkix_pl_UnescapeURL(locationAscii);
739
740 /* Skip "ldap:" */
741 endPos = locationAscii;
742 while (*endPos != ':' && *endPos != '\0') {
743 endPos++;
744 }
745 if (*endPos == '\0') {
746 PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGLOCATIONTYPE);
747 }
748
749 /* Skip "//" */
750 endPos++;
751 if (*endPos != '\0' && *(endPos+1) != '0' &&
752 *endPos == '/' && *(endPos+1) == '/') {
753 endPos += 2;
754 } else {
755 PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGDOUBLESLASH);
756 }
757
758 /* Get the server-site */
759 startPos = endPos;
760 while(*endPos != '/' && *(endPos) != '\0') {
761 endPos++;
762 }
763 if (*endPos == '\0') {
764 PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGSERVERSITE);
765 }
766
767 len = endPos - startPos;
768 endPos++;
769
770 domainName = PORT_ArenaZAlloc(arena, len + 1);
771 if (!domainName) {
772 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
773 }
774
775 PORT_Memcpy(domainName, startPos, len);
776
777 domainName[len] = '\0';
778
779 *pDomainName = domainName;
780
781 /*
782 * Get a list of AttrValueAssertions (such as
783 * "cn=CommonName, o=Organization, c=US" into a null-terminated array
784 */
785 startPos = endPos;
786 PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
787 (arena,
788 &startPos,
789 (char ***) &avaArray,
790 ',',
791 '?',
792 plContext),
793 PKIX_INFOACCESSPARSETOKENSFAILED);
794
795 /* Count how many AVAs we have */
796 for (len = 0; avaArray[len] != NULL; len++) {}
797
798 if (len < 2) {
799 PKIX_ERROR(PKIX_NOTENOUGHNAMECOMPONENTSINGENERALNAME);
800 }
801
802 /* Use last name component for baseObject */
803 request->baseObject = avaArray[len - 1];
804
805 /* Use only one component for filter. LDAP servers aren't too smart. */
806 len = 2; /* Eliminate this when servers get smarter. */
807
808 avaArray[len - 1] = NULL;
809
810 /* Get room for null-terminated array of (LdapNameComponent *) */
811 setOfNameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent *, len );
812 if (setOfNameComponent == NULL) {
813 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
814 }
815
816 /* Get room for the remaining LdapNameComponents */
817 nameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent, --len);
818 if (nameComponent == NULL) {
819 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
820 }
821
822 /* Convert remaining AVAs to LDAPNameComponents */
823 for (ncIndex = 0; ncIndex < len; ncIndex ++) {
824 setOfNameComponent[ncIndex] = nameComponent;
825 avaPtr = avaArray[ncIndex];
826 nameComponent->attrType = (unsigned char *)avaPtr;
827 while ((*avaPtr != '=') && (*avaPtr != '\0')) {
828 avaPtr++;
829 if (*avaPtr == '\0') {
830 PKIX_ERROR(PKIX_NAMECOMPONENTWITHNOEQ);
831 }
832 }
833 *(avaPtr++) = '\0';
834 nameComponent->attrValue = (unsigned char *)avaPtr;
835 nameComponent++;
836 }
837
838 setOfNameComponent[len] = NULL;
839 request->nc = setOfNameComponent;
840
841 /*
842 * Get a list of AttrTypes (such as
843 * "caCertificate;binary, crossCertificatePair;binary") into
844 * a null-terminated array
845 */
846
847 PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
848 (arena,
849 (char **) &startPos,
850 (char ***) &attrArray,
851 ',',
852 '\0',
853 plContext),
854 PKIX_INFOACCESSPARSETOKENSFAILED);
855
856 /* Convert array of Attr Types into a bit mask */
857 request->attributes = 0;
858 attr = attrArray[0];
859 while (attr != NULL) {
860 PKIX_CHECK(pkix_pl_LdapRequest_AttrStringToBit
861 (attr, &attrBit, plContext),
862 PKIX_LDAPREQUESTATTRSTRINGTOBITFAILED);
863 request->attributes |= attrBit;
864 attr = *(++attrArray);
865 }
866
867 cleanup:
868
869 PKIX_PL_Free(locationAscii, plContext);
870 PKIX_DECREF(locationString);
871
872 PKIX_RETURN(INFOACCESS);
873 }
874 #endif /* !NSS_PKIX_NO_LDAP */
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h ('k') | nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698