parser_aux.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2004, 2006, 2007 Free Software Foundation
00003  *      Copyright (C) 2000,2001 Fabio Fiorina
00004  *
00005  * This file is part of LIBTASN1.
00006  *
00007  * The LIBTASN1 library is free software; you can redistribute it
00008  * and/or modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00020  * 02110-1301, USA
00021  */
00022 
00023 #include <int.h>
00024 #include "parser_aux.h"
00025 #include "gstr.h"
00026 #include "structure.h"
00027 #include "element.h"
00028 
00029 
00030 
00031 char MHD__asn1_identifierMissing[MAX_NAME_SIZE + 1];    /* identifier name not found */
00032 
00033 /***********************************************/
00034 /* Type: list_type                             */
00035 /* Description: type used in the list during   */
00036 /* the structure creation.                     */
00037 /***********************************************/
00038 typedef struct list_struct
00039 {
00040   node_asn *node;
00041   struct list_struct *next;
00042 } list_type;
00043 
00044 
00045 /* Pointer to the first element of the list */
00046 list_type *MHD_firstElement = NULL;
00047 
00048 /******************************************************/
00049 /* Function : MHD__asn1_add_node                          */
00050 /* Description: creates a new NODE_ASN element and    */
00051 /* puts it in the list pointed by MHD_firstElement.       */
00052 /* Parameters:                                        */
00053 /*   type: type of the new element (see TYPE_         */
00054 /*         and CONST_ constants).                     */
00055 /* Return: pointer to the new element.                */
00056 /******************************************************/
00057 node_asn *
00058 MHD__asn1_add_node (unsigned int type)
00059 {
00060   list_type *listElement;
00061   node_asn *punt;
00062 
00063   punt = (node_asn *) MHD__asn1_calloc (1, sizeof (node_asn));
00064   if (punt == NULL)
00065     return NULL;
00066 
00067   listElement = (list_type *) MHD__asn1_malloc (sizeof (list_type));
00068   if (listElement == NULL)
00069     {
00070       MHD__asn1_free (punt);
00071       return NULL;
00072     }
00073 
00074   listElement->node = punt;
00075   listElement->next = MHD_firstElement;
00076   MHD_firstElement = listElement;
00077 
00078   punt->type = type;
00079 
00080   return punt;
00081 }
00082 
00095 ASN1_TYPE
00096 MHD__asn1_find_node (ASN1_TYPE pointer, const char *name)
00097 {
00098   node_asn *p;
00099   char *n_end, n[MAX_NAME_SIZE + 1];
00100   const char *n_start;
00101 
00102   if (pointer == NULL)
00103     return NULL;
00104 
00105   if (name == NULL)
00106     return NULL;
00107 
00108   p = pointer;
00109   n_start = name;
00110 
00111   if (p->name != NULL)
00112     {                           /* has *pointer got a name ? */
00113       n_end = strchr (n_start, '.');    /* search the first dot */
00114       if (n_end)
00115         {
00116           memcpy (n, n_start, n_end - n_start);
00117           n[n_end - n_start] = 0;
00118           n_start = n_end;
00119           n_start++;
00120         }
00121       else
00122         {
00123           MHD__asn1_str_cpy (n, sizeof (n), n_start);
00124           n_start = NULL;
00125         }
00126 
00127       while (p)
00128         {
00129           if ((p->name) && (!strcmp (p->name, n)))
00130             break;
00131           else
00132             p = p->right;
00133         }                       /* while */
00134 
00135       if (p == NULL)
00136         return NULL;
00137     }
00138   else
00139     {                           /* *pointer doesn't have a name */
00140       if (n_start[0] == 0)
00141         return p;
00142     }
00143 
00144   while (n_start)
00145     {                           /* Has the end of NAME been reached? */
00146       n_end = strchr (n_start, '.');    /* search the next dot */
00147       if (n_end)
00148         {
00149           memcpy (n, n_start, n_end - n_start);
00150           n[n_end - n_start] = 0;
00151           n_start = n_end;
00152           n_start++;
00153         }
00154       else
00155         {
00156           MHD__asn1_str_cpy (n, sizeof (n), n_start);
00157           n_start = NULL;
00158         }
00159 
00160       if (p->down == NULL)
00161         return NULL;
00162 
00163       p = p->down;
00164 
00165       /* The identifier "?LAST" indicates the last element
00166          in the right chain. */
00167       if (!strcmp (n, "?LAST"))
00168         {
00169           if (p == NULL)
00170             return NULL;
00171           while (p->right)
00172             p = p->right;
00173         }
00174       else
00175         {                       /* no "?LAST" */
00176           while (p)
00177             {
00178               if ((p->name) && (!strcmp (p->name, n)))
00179                 break;
00180               else
00181                 p = p->right;
00182             }
00183           if (p == NULL)
00184             return NULL;
00185         }
00186     }                           /* while */
00187 
00188   return p;
00189 }
00190 
00191 
00192 /******************************************************************/
00193 /* Function : MHD__asn1_set_value                                     */
00194 /* Description: sets the field VALUE in a NODE_ASN element. The   */
00195 /*              previous value (if exist) will be lost            */
00196 /* Parameters:                                                    */
00197 /*   node: element pointer.                                       */
00198 /*   value: pointer to the value that you want to set.            */
00199 /*   len: character number of value.                              */
00200 /* Return: pointer to the NODE_ASN element.                       */
00201 /******************************************************************/
00202 node_asn *
00203 MHD__asn1_set_value (node_asn * node, const void *_value, unsigned int len)
00204 {
00205   const unsigned char *value = _value;
00206 
00207   if (node == NULL)
00208     return node;
00209   if (node->value)
00210     {
00211       MHD__asn1_free (node->value);
00212       node->value = NULL;
00213       node->value_len = 0;
00214     }
00215   if (!len)
00216     return node;
00217   node->value = (unsigned char *) MHD__asn1_malloc (len);
00218   if (node->value == NULL)
00219     return NULL;
00220   node->value_len = len;
00221 
00222   memcpy (node->value, value, len);
00223   return node;
00224 }
00225 
00226 /******************************************************************/
00227 /* Function : MHD__asn1_set_name                                      */
00228 /* Description: sets the field NAME in a NODE_ASN element. The    */
00229 /*              previous value (if exist) will be lost            */
00230 /* Parameters:                                                    */
00231 /*   node: element pointer.                                       */
00232 /*   name: a null terminated string with the name that you want   */
00233 /*         to set.                                                */
00234 /* Return: pointer to the NODE_ASN element.                       */
00235 /******************************************************************/
00236 node_asn *
00237 MHD__asn1_set_name (node_asn * node, const char *name)
00238 {
00239   if (node == NULL)
00240     return node;
00241 
00242   if (node->name)
00243     {
00244       MHD__asn1_free (node->name);
00245       node->name = NULL;
00246     }
00247 
00248   if (name == NULL)
00249     return node;
00250 
00251   if (strlen (name))
00252     {
00253       node->name = (char *) MHD__asn1_strdup (name);
00254       if (node->name == NULL)
00255         return NULL;
00256     }
00257   else
00258     node->name = NULL;
00259   return node;
00260 }
00261 
00262 /******************************************************************/
00263 /* Function : MHD__asn1_set_right                                     */
00264 /* Description: sets the field RIGHT in a NODE_ASN element.       */
00265 /* Parameters:                                                    */
00266 /*   node: element pointer.                                       */
00267 /*   right: pointer to a NODE_ASN element that you want be pointed*/
00268 /*          by NODE.                                              */
00269 /* Return: pointer to *NODE.                                      */
00270 /******************************************************************/
00271 node_asn *
00272 MHD__asn1_set_right (node_asn * node, node_asn * right)
00273 {
00274   if (node == NULL)
00275     return node;
00276   node->right = right;
00277   if (right)
00278     right->left = node;
00279   return node;
00280 }
00281 
00282 /******************************************************************/
00283 /* Function : MHD__asn1_set_down                                      */
00284 /* Description: sets the field DOWN in a NODE_ASN element.        */
00285 /* Parameters:                                                    */
00286 /*   node: element pointer.                                       */
00287 /*   down: pointer to a NODE_ASN element that you want be pointed */
00288 /*          by NODE.                                              */
00289 /* Return: pointer to *NODE.                                      */
00290 /******************************************************************/
00291 node_asn *
00292 MHD__asn1_set_down (node_asn * node, node_asn * down)
00293 {
00294   if (node == NULL)
00295     return node;
00296   node->down = down;
00297   if (down)
00298     down->left = node;
00299   return node;
00300 }
00301 
00302 /******************************************************************/
00303 /* Function : MHD__asn1_remove_node                                   */
00304 /* Description: gets free the memory allocated for an NODE_ASN    */
00305 /*              element (not the elements pointed by it).         */
00306 /* Parameters:                                                    */
00307 /*   node: NODE_ASN element pointer.                              */
00308 /******************************************************************/
00309 void
00310 MHD__asn1_remove_node (node_asn * node)
00311 {
00312   if (node == NULL)
00313     return;
00314 
00315   if (node->name != NULL)
00316     MHD__asn1_free (node->name);
00317   if (node->value != NULL)
00318     MHD__asn1_free (node->value);
00319   MHD__asn1_free (node);
00320 }
00321 
00322 /******************************************************************/
00323 /* Function : MHD__asn1_find_up                                       */
00324 /* Description: return the father of the NODE_ASN element.        */
00325 /* Parameters:                                                    */
00326 /*   node: NODE_ASN element pointer.                              */
00327 /* Return: Null if not found.                                     */
00328 /******************************************************************/
00329 node_asn *
00330 MHD__asn1_find_up (node_asn * node)
00331 {
00332   node_asn *p;
00333 
00334   if (node == NULL)
00335     return NULL;
00336 
00337   p = node;
00338 
00339   while ((p->left != NULL) && (p->left->right == p))
00340     p = p->left;
00341 
00342   return p->left;
00343 }
00344 
00345 /******************************************************************/
00346 /* Function : MHD__asn1_delete_list                                   */
00347 /* Description: deletes the list elements (not the elements       */
00348 /*  pointed by them).                                             */
00349 /******************************************************************/
00350 void
00351 MHD__asn1_delete_list (void)
00352 {
00353   list_type *listElement;
00354 
00355   while (MHD_firstElement)
00356     {
00357       listElement = MHD_firstElement;
00358       MHD_firstElement = MHD_firstElement->next;
00359       MHD__asn1_free (listElement);
00360     }
00361 }
00362 
00363 /******************************************************************/
00364 /* Function : MHD__asn1_delete_list_and nodes                         */
00365 /* Description: deletes the list elements and the elements        */
00366 /*  pointed by them.                                              */
00367 /******************************************************************/
00368 void
00369 MHD__asn1_delete_list_and_nodes (void)
00370 {
00371   list_type *listElement;
00372 
00373   while (MHD_firstElement)
00374     {
00375       listElement = MHD_firstElement;
00376       MHD_firstElement = MHD_firstElement->next;
00377       MHD__asn1_remove_node (listElement->node);
00378       MHD__asn1_free (listElement);
00379     }
00380 }
00381 
00382 
00383 char *
00384 MHD__asn1_ltostr (long v, char *str)
00385 {
00386   long d, r;
00387   char temp[20];
00388   int count, k, start;
00389 
00390   if (v < 0)
00391     {
00392       str[0] = '-';
00393       start = 1;
00394       v = -v;
00395     }
00396   else
00397     start = 0;
00398 
00399   count = 0;
00400   do
00401     {
00402       d = v / 10;
00403       r = v - d * 10;
00404       temp[start + count] = '0' + (char) r;
00405       count++;
00406       v = d;
00407     }
00408   while (v);
00409 
00410   for (k = 0; k < count; k++)
00411     str[k + start] = temp[start + count - k - 1];
00412   str[count + start] = 0;
00413   return str;
00414 }
00415 
00416 
00417 /******************************************************************/
00418 /* Function : MHD__asn1_change_integer_value                          */
00419 /* Description: converts into DER coding the value assign to an   */
00420 /*   INTEGER constant.                                            */
00421 /* Parameters:                                                    */
00422 /*   node: root of an ASN1element.                                */
00423 /* Return:                                                        */
00424 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
00425 /*   otherwise ASN1_SUCCESS                                             */
00426 /******************************************************************/
00427 MHD__asn1_retCode
00428 MHD__asn1_change_integer_value (ASN1_TYPE node)
00429 {
00430   node_asn *p;
00431   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
00432   unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
00433   int len;
00434 
00435   if (node == NULL)
00436     return ASN1_ELEMENT_NOT_FOUND;
00437 
00438   p = node;
00439   while (p)
00440     {
00441       if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
00442         {
00443           if (p->value)
00444             {
00445               MHD__asn1_convert_integer ((const char *) p->value, val,
00446                                          sizeof (val), &len);
00447               MHD__asn1_octet_der (val, len, val2, &len);
00448               MHD__asn1_set_value (p, val2, len);
00449             }
00450         }
00451 
00452       if (p->down)
00453         {
00454           p = p->down;
00455         }
00456       else
00457         {
00458           if (p == node)
00459             p = NULL;
00460           else if (p->right)
00461             p = p->right;
00462           else
00463             {
00464               while (1)
00465                 {
00466                   p = MHD__asn1_find_up (p);
00467                   if (p == node)
00468                     {
00469                       p = NULL;
00470                       break;
00471                     }
00472                   if (p->right)
00473                     {
00474                       p = p->right;
00475                       break;
00476                     }
00477                 }
00478             }
00479         }
00480     }
00481 
00482   return ASN1_SUCCESS;
00483 }
00484 
00485 
00486 /******************************************************************/
00487 /* Function : MHD__asn1_expand_object_id                              */
00488 /* Description: expand the IDs of an OBJECT IDENTIFIER constant.  */
00489 /* Parameters:                                                    */
00490 /*   node: root of an ASN1 element.                               */
00491 /* Return:                                                        */
00492 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
00493 /*   otherwise ASN1_SUCCESS                                             */
00494 /******************************************************************/
00495 MHD__asn1_retCode
00496 MHD__asn1_expand_object_id (ASN1_TYPE node)
00497 {
00498   node_asn *p, *p2, *p3, *p4, *p5;
00499   char name_root[MAX_NAME_SIZE], name2[2 * MAX_NAME_SIZE + 1];
00500   int move, tlen;
00501 
00502   if (node == NULL)
00503     return ASN1_ELEMENT_NOT_FOUND;
00504 
00505   MHD__asn1_str_cpy (name_root, sizeof (name_root), node->name);
00506 
00507   p = node;
00508   move = DOWN;
00509 
00510   while (!((p == node) && (move == UP)))
00511     {
00512       if (move != UP)
00513         {
00514           if ((type_field (p->type) == TYPE_OBJECT_ID)
00515               && (p->type & CONST_ASSIGN))
00516             {
00517               p2 = p->down;
00518               if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
00519                 {
00520                   if (p2->value && !isdigit (p2->value[0]))
00521                     {
00522                       MHD__asn1_str_cpy (name2, sizeof (name2), name_root);
00523                       MHD__asn1_str_cat (name2, sizeof (name2), ".");
00524                       MHD__asn1_str_cat (name2, sizeof (name2),
00525                                          (const char *) p2->value);
00526                       p3 = MHD__asn1_find_node (node, name2);
00527                       if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
00528                           !(p3->type & CONST_ASSIGN))
00529                         return ASN1_ELEMENT_NOT_FOUND;
00530                       MHD__asn1_set_down (p, p2->right);
00531                       MHD__asn1_remove_node (p2);
00532                       p2 = p;
00533                       p4 = p3->down;
00534                       while (p4)
00535                         {
00536                           if (type_field (p4->type) == TYPE_CONSTANT)
00537                             {
00538                               p5 = MHD__asn1_add_node_only (TYPE_CONSTANT);
00539                               MHD__asn1_set_name (p5, p4->name);
00540                               tlen = strlen ((const char *) p4->value);
00541                               if (tlen > 0)
00542                                 MHD__asn1_set_value (p5, p4->value, tlen + 1);
00543                               if (p2 == p)
00544                                 {
00545                                   MHD__asn1_set_right (p5, p->down);
00546                                   MHD__asn1_set_down (p, p5);
00547                                 }
00548                               else
00549                                 {
00550                                   MHD__asn1_set_right (p5, p2->right);
00551                                   MHD__asn1_set_right (p2, p5);
00552                                 }
00553                               p2 = p5;
00554                             }
00555                           p4 = p4->right;
00556                         }
00557                       move = DOWN;
00558                       continue;
00559                     }
00560                 }
00561             }
00562           move = DOWN;
00563         }
00564       else
00565         move = RIGHT;
00566 
00567       if (move == DOWN)
00568         {
00569           if (p->down)
00570             p = p->down;
00571           else
00572             move = RIGHT;
00573         }
00574 
00575       if (p == node)
00576         {
00577           move = UP;
00578           continue;
00579         }
00580 
00581       if (move == RIGHT)
00582         {
00583           if (p->right)
00584             p = p->right;
00585           else
00586             move = UP;
00587         }
00588       if (move == UP)
00589         p = MHD__asn1_find_up (p);
00590     }
00591 
00592 
00593   /*******************************/
00594   /*       expand DEFAULT        */
00595   /*******************************/
00596   p = node;
00597   move = DOWN;
00598 
00599   while (!((p == node) && (move == UP)))
00600     {
00601       if (move != UP)
00602         {
00603           if ((type_field (p->type) == TYPE_OBJECT_ID) &&
00604               (p->type & CONST_DEFAULT))
00605             {
00606               p2 = p->down;
00607               if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
00608                 {
00609                   MHD__asn1_str_cpy (name2, sizeof (name2), name_root);
00610                   MHD__asn1_str_cat (name2, sizeof (name2), ".");
00611                   MHD__asn1_str_cat (name2, sizeof (name2),
00612                                      (const char *) p2->value);
00613                   p3 = MHD__asn1_find_node (node, name2);
00614                   if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
00615                       !(p3->type & CONST_ASSIGN))
00616                     return ASN1_ELEMENT_NOT_FOUND;
00617                   p4 = p3->down;
00618                   name2[0] = 0;
00619                   while (p4)
00620                     {
00621                       if (type_field (p4->type) == TYPE_CONSTANT)
00622                         {
00623                           if (name2[0])
00624                             MHD__asn1_str_cat (name2, sizeof (name2), ".");
00625                           MHD__asn1_str_cat (name2, sizeof (name2),
00626                                              (const char *) p4->value);
00627                         }
00628                       p4 = p4->right;
00629                     }
00630                   tlen = strlen (name2);
00631                   if (tlen > 0)
00632                     MHD__asn1_set_value (p2, name2, tlen + 1);
00633                 }
00634             }
00635           move = DOWN;
00636         }
00637       else
00638         move = RIGHT;
00639 
00640       if (move == DOWN)
00641         {
00642           if (p->down)
00643             p = p->down;
00644           else
00645             move = RIGHT;
00646         }
00647 
00648       if (p == node)
00649         {
00650           move = UP;
00651           continue;
00652         }
00653 
00654       if (move == RIGHT)
00655         {
00656           if (p->right)
00657             p = p->right;
00658           else
00659             move = UP;
00660         }
00661       if (move == UP)
00662         p = MHD__asn1_find_up (p);
00663     }
00664 
00665   return ASN1_SUCCESS;
00666 }
00667 
00668 /******************************************************************/
00669 /* Function : MHD__asn1_check_identifier                              */
00670 /* Description: checks the definitions of all the identifiers     */
00671 /*   and the first element of an OBJECT_ID (e.g. {pkix 0 4}).     */
00672 /*   The MHD__asn1_identifierMissing global variable is filled if     */
00673 /*   necessary.                                                   */
00674 /* Parameters:                                                    */
00675 /*   node: root of an ASN1 element.                               */
00676 /* Return:                                                        */
00677 /*   ASN1_ELEMENT_NOT_FOUND      if NODE is NULL,                 */
00678 /*   ASN1_IDENTIFIER_NOT_FOUND   if an identifier is not defined, */
00679 /*   otherwise ASN1_SUCCESS                                       */
00680 /******************************************************************/
00681 MHD__asn1_retCode
00682 MHD__asn1_check_identifier (ASN1_TYPE node)
00683 {
00684   node_asn *p, *p2;
00685   char name2[MAX_NAME_SIZE * 2 + 2];
00686 
00687   if (node == NULL)
00688     return ASN1_ELEMENT_NOT_FOUND;
00689 
00690   p = node;
00691   while (p)
00692     {
00693       if (type_field (p->type) == TYPE_IDENTIFIER)
00694         {
00695           MHD__asn1_str_cpy (name2, sizeof (name2), node->name);
00696           MHD__asn1_str_cat (name2, sizeof (name2), ".");
00697           MHD__asn1_str_cat (name2, sizeof (name2), (const char *) p->value);
00698           p2 = MHD__asn1_find_node (node, name2);
00699           if (p2 == NULL)
00700             {
00701               strcpy (MHD__asn1_identifierMissing, (const char *) p->value);
00702               return ASN1_IDENTIFIER_NOT_FOUND;
00703             }
00704         }
00705       else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
00706                (p->type & CONST_DEFAULT))
00707         {
00708           p2 = p->down;
00709           if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
00710             {
00711               MHD__asn1_str_cpy (name2, sizeof (name2), node->name);
00712               MHD__asn1_str_cat (name2, sizeof (name2), ".");
00713               MHD__asn1_str_cat (name2, sizeof (name2),
00714                                  (const char *) p2->value);
00715               strcpy (MHD__asn1_identifierMissing, (const char *) p2->value);
00716               p2 = MHD__asn1_find_node (node, name2);
00717               if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
00718                   !(p2->type & CONST_ASSIGN))
00719                 return ASN1_IDENTIFIER_NOT_FOUND;
00720               else
00721                 MHD__asn1_identifierMissing[0] = 0;
00722             }
00723         }
00724       else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
00725                (p->type & CONST_ASSIGN))
00726         {
00727           p2 = p->down;
00728           if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
00729             {
00730               if (p2->value && !isdigit (p2->value[0]))
00731                 {
00732                   MHD__asn1_str_cpy (name2, sizeof (name2), node->name);
00733                   MHD__asn1_str_cat (name2, sizeof (name2), ".");
00734                   MHD__asn1_str_cat (name2, sizeof (name2),
00735                                      (const char *) p2->value);
00736                   strcpy (MHD__asn1_identifierMissing,
00737                           (const char *) p2->value);
00738                   p2 = MHD__asn1_find_node (node, name2);
00739                   if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
00740                       !(p2->type & CONST_ASSIGN))
00741                     return ASN1_IDENTIFIER_NOT_FOUND;
00742                   else
00743                     MHD__asn1_identifierMissing[0] = 0;
00744                 }
00745             }
00746         }
00747 
00748       if (p->down)
00749         {
00750           p = p->down;
00751         }
00752       else if (p->right)
00753         p = p->right;
00754       else
00755         {
00756           while (1)
00757             {
00758               p = MHD__asn1_find_up (p);
00759               if (p == node)
00760                 {
00761                   p = NULL;
00762                   break;
00763                 }
00764               if (p->right)
00765                 {
00766                   p = p->right;
00767                   break;
00768                 }
00769             }
00770         }
00771     }
00772 
00773   return ASN1_SUCCESS;
00774 }

Generated on Tue May 19 23:21:07 2009 for GNU libmicrohttpd by  doxygen 1.5.8