coding.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2004, 2006 Free Software Foundation
00003  *      Copyright (C) 2002  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 
00024 /*****************************************************/
00025 /* File: coding.c                                    */
00026 /* Description: Functions to create a DER coding of  */
00027 /*   an ASN1 type.                                   */
00028 /*****************************************************/
00029 
00030 #include <int.h>
00031 #include "parser_aux.h"
00032 #include <gstr.h>
00033 #include "element.h"
00034 #include <structure.h>
00035 
00036 #define MAX_TAG_LEN 16
00037 
00038 /******************************************************/
00039 /* Function : MHD__asn1_error_description_value_not_found */
00040 /* Description: creates the ErrorDescription string   */
00041 /* for the ASN1_VALUE_NOT_FOUND error.                */
00042 /* Parameters:                                        */
00043 /*   node: node of the tree where the value is NULL.  */
00044 /*   ErrorDescription: string returned.               */
00045 /* Return:                                            */
00046 /******************************************************/
00047 static void
00048 MHD__asn1_error_description_value_not_found (node_asn * node,
00049                                              char *ErrorDescription)
00050 {
00051 
00052   if (ErrorDescription == NULL)
00053     return;
00054 
00055   Estrcpy (ErrorDescription, ":: value of element '");
00056   MHD__asn1_hierarchical_name (node,
00057                                ErrorDescription + strlen (ErrorDescription),
00058                                MAX_ERROR_DESCRIPTION_SIZE - 40);
00059   Estrcat (ErrorDescription, "' not found");
00060 
00061 }
00062 
00072 void
00073 MHD__asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
00074 {
00075   int k;
00076   unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
00077 
00078   if (len < 128)
00079     {
00080       /* short form */
00081       if (ans != NULL)
00082         ans[0] = (unsigned char) len;
00083       *ans_len = 1;
00084     }
00085   else
00086     {
00087       /* Long form */
00088       k = 0;
00089       while (len)
00090         {
00091           temp[k++] = len & 0xFF;
00092           len = len >> 8;
00093         }
00094       *ans_len = k + 1;
00095       if (ans != NULL)
00096         {
00097           ans[0] = ((unsigned char) k & 0x7F) + 128;
00098           while (k--)
00099             ans[*ans_len - 1 - k] = temp[k];
00100         }
00101     }
00102 }
00103 
00104 /******************************************************/
00105 /* Function : MHD__asn1_tag_der                           */
00106 /* Description: creates the DER coding for the CLASS  */
00107 /* and TAG parameters.                                */
00108 /* Parameters:                                        */
00109 /*   class: value to convert.                         */
00110 /*   tag_value: value to convert.                     */
00111 /*   ans: string returned.                            */
00112 /*   ans_len: number of meaningful bytes of ANS       */
00113 /*            (ans[0]..ans[ans_len-1]).               */
00114 /* Return:                                            */
00115 /******************************************************/
00116 static void
00117 MHD__asn1_tag_der (unsigned char class, unsigned int tag_value,
00118                    unsigned char *ans, int *ans_len)
00119 {
00120   int k;
00121   unsigned char temp[SIZEOF_UNSIGNED_INT];
00122 
00123   if (tag_value < 31)
00124     {
00125       /* short form */
00126       ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
00127       *ans_len = 1;
00128     }
00129   else
00130     {
00131       /* Long form */
00132       ans[0] = (class & 0xE0) + 31;
00133       k = 0;
00134       while (tag_value)
00135         {
00136           temp[k++] = tag_value & 0x7F;
00137           tag_value = tag_value >> 7;
00138         }
00139       *ans_len = k + 1;
00140       while (k--)
00141         ans[*ans_len - 1 - k] = temp[k] + 128;
00142       ans[*ans_len - 1] -= 128;
00143     }
00144 }
00145 
00155 void
00156 MHD__asn1_octet_der (const unsigned char *str, int str_len,
00157                      unsigned char *der, int *der_len)
00158 {
00159   int len_len;
00160 
00161   if (der == NULL || str_len < 0)
00162     return;
00163   MHD__asn1_length_der (str_len, der, &len_len);
00164   memcpy (der + len_len, str, str_len);
00165   *der_len = str_len + len_len;
00166 }
00167 
00168 /******************************************************/
00169 /* Function : MHD__asn1_time_der                          */
00170 /* Description: creates the DER coding for a TIME     */
00171 /* type (length included).                            */
00172 /* Parameters:                                        */
00173 /*   str: TIME null-terminated string.                */
00174 /*   der: string returned.                            */
00175 /*   der_len: number of meaningful bytes of DER       */
00176 /*            (der[0]..der[ans_len-1]). Initially it  */
00177 /*            if must store the lenght of DER.        */
00178 /* Return:                                            */
00179 /*   ASN1_MEM_ERROR when DER isn't big enough         */
00180 /*   ASN1_SUCCESS otherwise                           */
00181 /******************************************************/
00182 static MHD__asn1_retCode
00183 MHD__asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
00184 {
00185   int len_len;
00186   int max_len;
00187 
00188   max_len = *der_len;
00189 
00190   MHD__asn1_length_der (strlen ((const char *) str),
00191                         (max_len > 0) ? der : NULL, &len_len);
00192 
00193   if ((len_len + (int) strlen ((const char *) str)) <= max_len)
00194     memcpy (der + len_len, str, strlen ((const char *) str));
00195   *der_len = len_len + strlen ((const char *) str);
00196 
00197   if ((*der_len) > max_len)
00198     return ASN1_MEM_ERROR;
00199 
00200   return ASN1_SUCCESS;
00201 }
00202 
00203 /******************************************************/
00204 /* Function : MHD__asn1_objectid_der                      */
00205 /* Description: creates the DER coding for an         */
00206 /* OBJECT IDENTIFIER  type (length included).         */
00207 /* Parameters:                                        */
00208 /*   str: OBJECT IDENTIFIER null-terminated string.   */
00209 /*   der: string returned.                            */
00210 /*   der_len: number of meaningful bytes of DER       */
00211 /*            (der[0]..der[ans_len-1]). Initially it  */
00212 /*            must store the length of DER.           */
00213 /* Return:                                            */
00214 /*   ASN1_MEM_ERROR when DER isn't big enough         */
00215 /*   ASN1_SUCCESS otherwise                           */
00216 /******************************************************/
00217 static MHD__asn1_retCode
00218 MHD__asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
00219 {
00220   int len_len, counter, k, first, max_len;
00221   char *temp, *n_end, *n_start;
00222   unsigned char bit7;
00223   unsigned long val, val1 = 0;
00224 
00225   max_len = *der_len;
00226 
00227   temp = (char *) MHD__asn1_alloca (strlen ((const char *) str) + 2);
00228   if (temp == NULL)
00229     return ASN1_MEM_ALLOC_ERROR;
00230 
00231   strcpy (temp, (const char *) str);
00232   strcat (temp, ".");
00233 
00234   counter = 0;
00235   n_start = temp;
00236   while ((n_end = strchr (n_start, '.')))
00237     {
00238       *n_end = 0;
00239       val = strtoul (n_start, NULL, 10);
00240       counter++;
00241 
00242       if (counter == 1)
00243         val1 = val;
00244       else if (counter == 2)
00245         {
00246           if (max_len > 0)
00247             der[0] = 40 * val1 + val;
00248           *der_len = 1;
00249         }
00250       else
00251         {
00252           first = 0;
00253           for (k = 4; k >= 0; k--)
00254             {
00255               bit7 = (val >> (k * 7)) & 0x7F;
00256               if (bit7 || first || !k)
00257                 {
00258                   if (k)
00259                     bit7 |= 0x80;
00260                   if (max_len > (*der_len))
00261                     der[*der_len] = bit7;
00262                   (*der_len)++;
00263                   first = 1;
00264                 }
00265             }
00266 
00267         }
00268       n_start = n_end + 1;
00269     }
00270 
00271   MHD__asn1_length_der (*der_len, NULL, &len_len);
00272   if (max_len >= (*der_len + len_len))
00273     {
00274       memmove (der + len_len, der, *der_len);
00275       MHD__asn1_length_der (*der_len, der, &len_len);
00276     }
00277   *der_len += len_len;
00278 
00279   MHD__asn1_afree (temp);
00280 
00281   if (max_len < (*der_len))
00282     return ASN1_MEM_ERROR;
00283 
00284   return ASN1_SUCCESS;
00285 }
00286 
00287 
00288 const char MHD_bit_mask[] =
00289   { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
00290 
00302 void
00303 MHD__asn1_bit_der (const unsigned char *str, int bit_len,
00304                    unsigned char *der, int *der_len)
00305 {
00306   int len_len, len_byte, len_pad;
00307 
00308   if (der == NULL)
00309     return;
00310   len_byte = bit_len >> 3;
00311   len_pad = 8 - (bit_len & 7);
00312   if (len_pad == 8)
00313     len_pad = 0;
00314   else
00315     len_byte++;
00316   MHD__asn1_length_der (len_byte + 1, der, &len_len);
00317   der[len_len] = len_pad;
00318   memcpy (der + len_len + 1, str, len_byte);
00319   der[len_len + len_byte] &= MHD_bit_mask[len_pad];
00320   *der_len = len_byte + len_len + 1;
00321 }
00322 
00323 
00324 /******************************************************/
00325 /* Function : MHD__asn1_complete_explicit_tag             */
00326 /* Description: add the length coding to the EXPLICIT */
00327 /* tags.                                              */
00328 /* Parameters:                                        */
00329 /*   node: pointer to the tree element.               */
00330 /*   der: string with the DER coding of the whole tree*/
00331 /*   counter: number of meaningful bytes of DER       */
00332 /*            (der[0]..der[*counter-1]).              */
00333 /*   max_len: size of der vector                      */
00334 /* Return:                                            */
00335 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
00336 /*   otherwise ASN1_SUCCESS.                          */
00337 /******************************************************/
00338 static MHD__asn1_retCode
00339 MHD__asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
00340                                  int *counter, int *max_len)
00341 {
00342   node_asn *p;
00343   int is_tag_implicit, len2, len3;
00344   unsigned char temp[SIZEOF_UNSIGNED_INT];
00345 
00346   is_tag_implicit = 0;
00347 
00348   if (node->type & CONST_TAG)
00349     {
00350       p = node->down;
00351       /* When there are nested tags we must complete them reverse to
00352          the order they were created. This is because completing a tag
00353          modifies all data within it, including the incomplete tags
00354          which store buffer positions -- simon@josefsson.org 2002-09-06
00355        */
00356       while (p->right)
00357         p = p->right;
00358       while (p && p != node->down->left)
00359         {
00360           if (type_field (p->type) == TYPE_TAG)
00361             {
00362               if (p->type & CONST_EXPLICIT)
00363                 {
00364                   len2 = strtol (p->name, NULL, 10);
00365                   MHD__asn1_set_name (p, NULL);
00366                   MHD__asn1_length_der (*counter - len2, temp, &len3);
00367                   if (len3 <= (*max_len))
00368                     {
00369                       memmove (der + len2 + len3, der + len2,
00370                                *counter - len2);
00371                       memcpy (der + len2, temp, len3);
00372                     }
00373                   *max_len -= len3;
00374                   *counter += len3;
00375                   is_tag_implicit = 0;
00376                 }
00377               else
00378                 {               /* CONST_IMPLICIT */
00379                   if (!is_tag_implicit)
00380                     {
00381                       is_tag_implicit = 1;
00382                     }
00383                 }
00384             }
00385           p = p->left;
00386         }
00387     }
00388 
00389   if (*max_len < 0)
00390     return ASN1_MEM_ERROR;
00391 
00392   return ASN1_SUCCESS;
00393 }
00394 
00395 
00396 /******************************************************/
00397 /* Function : MHD__asn1_insert_tag_der                    */
00398 /* Description: creates the DER coding of tags of one */
00399 /* NODE.                                              */
00400 /* Parameters:                                        */
00401 /*   node: pointer to the tree element.               */
00402 /*   der: string returned                             */
00403 /*   counter: number of meaningful bytes of DER       */
00404 /*            (counter[0]..der[*counter-1]).          */
00405 /*   max_len: size of der vector                      */
00406 /* Return:                                            */
00407 /*   ASN1_GENERIC_ERROR if the type is unknown,       */
00408 /*   ASN1_MEM_ERROR if der vector isn't big enough,   */
00409 /*   otherwise ASN1_SUCCESS.                          */
00410 /******************************************************/
00411 static MHD__asn1_retCode
00412 MHD__asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
00413                           int *max_len)
00414 {
00415   node_asn *p;
00416   int tag_len, is_tag_implicit;
00417   unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
00418   unsigned long tag_implicit = 0;
00419   char tag_der[MAX_TAG_LEN];
00420 
00421   is_tag_implicit = 0;
00422 
00423   if (node->type & CONST_TAG)
00424     {
00425       p = node->down;
00426       while (p)
00427         {
00428           if (type_field (p->type) == TYPE_TAG)
00429             {
00430               if (p->type & CONST_APPLICATION)
00431                 class = ASN1_CLASS_APPLICATION;
00432               else if (p->type & CONST_UNIVERSAL)
00433                 class = ASN1_CLASS_UNIVERSAL;
00434               else if (p->type & CONST_PRIVATE)
00435                 class = ASN1_CLASS_PRIVATE;
00436               else
00437                 class = ASN1_CLASS_CONTEXT_SPECIFIC;
00438 
00439               if (p->type & CONST_EXPLICIT)
00440                 {
00441                   if (is_tag_implicit)
00442                     MHD__asn1_tag_der (class_implicit, tag_implicit,
00443                                        (unsigned char *) tag_der, &tag_len);
00444                   else
00445                     MHD__asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
00446                                        strtoul ((const char *) p->value, NULL,
00447                                                 10),
00448                                        (unsigned char *) tag_der, &tag_len);
00449 
00450                   *max_len -= tag_len;
00451                   if (*max_len >= 0)
00452                     memcpy (der + *counter, tag_der, tag_len);
00453                   *counter += tag_len;
00454 
00455                   MHD__asn1_ltostr (*counter, (char *) temp);
00456                   MHD__asn1_set_name (p, (const char *) temp);
00457 
00458                   is_tag_implicit = 0;
00459                 }
00460               else
00461                 {               /* CONST_IMPLICIT */
00462                   if (!is_tag_implicit)
00463                     {
00464                       if ((type_field (node->type) == TYPE_SEQUENCE) ||
00465                           (type_field (node->type) == TYPE_SEQUENCE_OF) ||
00466                           (type_field (node->type) == TYPE_SET) ||
00467                           (type_field (node->type) == TYPE_SET_OF))
00468                         class |= ASN1_CLASS_STRUCTURED;
00469                       class_implicit = class;
00470                       tag_implicit =
00471                         strtoul ((const char *) p->value, NULL, 10);
00472                       is_tag_implicit = 1;
00473                     }
00474                 }
00475             }
00476           p = p->right;
00477         }
00478     }
00479 
00480   if (is_tag_implicit)
00481     {
00482       MHD__asn1_tag_der (class_implicit, tag_implicit,
00483                          (unsigned char *) tag_der, &tag_len);
00484     }
00485   else
00486     {
00487       switch (type_field (node->type))
00488         {
00489         case TYPE_NULL:
00490           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL,
00491                              (unsigned char *) tag_der, &tag_len);
00492           break;
00493         case TYPE_BOOLEAN:
00494           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN,
00495                              (unsigned char *) tag_der, &tag_len);
00496           break;
00497         case TYPE_INTEGER:
00498           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER,
00499                              (unsigned char *) tag_der, &tag_len);
00500           break;
00501         case TYPE_ENUMERATED:
00502           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED,
00503                              (unsigned char *) tag_der, &tag_len);
00504           break;
00505         case TYPE_OBJECT_ID:
00506           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID,
00507                              (unsigned char *) tag_der, &tag_len);
00508           break;
00509         case TYPE_TIME:
00510           if (node->type & CONST_UTC)
00511             {
00512               MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime,
00513                                  (unsigned char *) tag_der, &tag_len);
00514             }
00515           else
00516             MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
00517                                (unsigned char *) tag_der, &tag_len);
00518           break;
00519         case TYPE_OCTET_STRING:
00520           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING,
00521                              (unsigned char *) tag_der, &tag_len);
00522           break;
00523         case TYPE_GENERALSTRING:
00524           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
00525                              (unsigned char *) tag_der, &tag_len);
00526           break;
00527         case TYPE_BIT_STRING:
00528           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING,
00529                              (unsigned char *) tag_der, &tag_len);
00530           break;
00531         case TYPE_SEQUENCE:
00532         case TYPE_SEQUENCE_OF:
00533           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
00534                              ASN1_TAG_SEQUENCE, (unsigned char *) tag_der,
00535                              &tag_len);
00536           break;
00537         case TYPE_SET:
00538         case TYPE_SET_OF:
00539           MHD__asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
00540                              ASN1_TAG_SET, (unsigned char *) tag_der,
00541                              &tag_len);
00542           break;
00543         case TYPE_TAG:
00544           tag_len = 0;
00545           break;
00546         case TYPE_CHOICE:
00547           tag_len = 0;
00548           break;
00549         case TYPE_ANY:
00550           tag_len = 0;
00551           break;
00552         default:
00553           return ASN1_GENERIC_ERROR;
00554         }
00555     }
00556 
00557   *max_len -= tag_len;
00558   if (*max_len >= 0)
00559     memcpy (der + *counter, tag_der, tag_len);
00560   *counter += tag_len;
00561 
00562   if (*max_len < 0)
00563     return ASN1_MEM_ERROR;
00564 
00565   return ASN1_SUCCESS;
00566 }
00567 
00568 /******************************************************/
00569 /* Function : MHD__asn1_ordering_set                      */
00570 /* Description: puts the elements of a SET type in    */
00571 /* the correct order according to DER rules.          */
00572 /* Parameters:                                        */
00573 /*   der: string with the DER coding.                 */
00574 /*   node: pointer to the SET element.                */
00575 /* Return:                                            */
00576 /******************************************************/
00577 static void
00578 MHD__asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
00579 {
00580   struct vet
00581   {
00582     int end;
00583     unsigned long value;
00584     struct vet *next, *prev;
00585   };
00586 
00587   int counter, len, len2;
00588   struct vet *first, *last, *p_vet, *p2_vet;
00589   node_asn *p;
00590   unsigned char class, *temp;
00591   unsigned long tag;
00592 
00593   counter = 0;
00594 
00595   if (type_field (node->type) != TYPE_SET)
00596     return;
00597 
00598   p = node->down;
00599   while ((p != NULL) &&
00600          ((type_field (p->type) == TYPE_TAG)
00601           || (type_field (p->type) == TYPE_SIZE)))
00602     p = p->right;
00603 
00604   if ((p == NULL) || (p->right == NULL))
00605     return;
00606 
00607   first = last = NULL;
00608   while (p)
00609     {
00610       p_vet = (struct vet *) MHD__asn1_alloca (sizeof (struct vet));
00611       if (p_vet == NULL)
00612         return;
00613 
00614       p_vet->next = NULL;
00615       p_vet->prev = last;
00616       if (first == NULL)
00617         first = p_vet;
00618       else
00619         last->next = p_vet;
00620       last = p_vet;
00621 
00622       /* tag value calculation */
00623       if (MHD__asn1_get_tag_der
00624           (der + counter, der_len - counter, &class, &len2,
00625            &tag) != ASN1_SUCCESS)
00626         return;
00627       p_vet->value = (class << 24) | tag;
00628       counter += len2;
00629 
00630       /* extraction and length */
00631       len2 =
00632         MHD__asn1_get_length_der (der + counter, der_len - counter, &len);
00633       if (len2 < 0)
00634         return;
00635       counter += len + len2;
00636 
00637       p_vet->end = counter;
00638       p = p->right;
00639     }
00640 
00641   p_vet = first;
00642 
00643   while (p_vet)
00644     {
00645       p2_vet = p_vet->next;
00646       counter = 0;
00647       while (p2_vet)
00648         {
00649           if (p_vet->value > p2_vet->value)
00650             {
00651               /* change position */
00652               temp =
00653                 (unsigned char *) MHD__asn1_alloca (p_vet->end - counter);
00654               if (temp == NULL)
00655                 return;
00656 
00657               memcpy (temp, der + counter, p_vet->end - counter);
00658               memcpy (der + counter, der + p_vet->end,
00659                       p2_vet->end - p_vet->end);
00660               memcpy (der + counter + p2_vet->end - p_vet->end, temp,
00661                       p_vet->end - counter);
00662               MHD__asn1_afree (temp);
00663 
00664               tag = p_vet->value;
00665               p_vet->value = p2_vet->value;
00666               p2_vet->value = tag;
00667 
00668               p_vet->end = counter + (p2_vet->end - p_vet->end);
00669             }
00670           counter = p_vet->end;
00671 
00672           p2_vet = p2_vet->next;
00673           p_vet = p_vet->next;
00674         }
00675 
00676       if (p_vet != first)
00677         p_vet->prev->next = NULL;
00678       else
00679         first = NULL;
00680       MHD__asn1_afree (p_vet);
00681       p_vet = first;
00682     }
00683 }
00684 
00685 /******************************************************/
00686 /* Function : MHD__asn1_ordering_set_of                   */
00687 /* Description: puts the elements of a SET OF type in */
00688 /* the correct order according to DER rules.          */
00689 /* Parameters:                                        */
00690 /*   der: string with the DER coding.                 */
00691 /*   node: pointer to the SET OF element.             */
00692 /* Return:                                            */
00693 /******************************************************/
00694 static void
00695 MHD__asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
00696 {
00697   struct vet
00698   {
00699     int end;
00700     struct vet *next, *prev;
00701   };
00702 
00703   int counter, len, len2, change;
00704   struct vet *first, *last, *p_vet, *p2_vet;
00705   node_asn *p;
00706   unsigned char *temp, class;
00707   unsigned long k, max;
00708 
00709   counter = 0;
00710 
00711   if (type_field (node->type) != TYPE_SET_OF)
00712     return;
00713 
00714   p = node->down;
00715   while ((type_field (p->type) == TYPE_TAG)
00716          || (type_field (p->type) == TYPE_SIZE))
00717     p = p->right;
00718   p = p->right;
00719 
00720   if ((p == NULL) || (p->right == NULL))
00721     return;
00722 
00723   first = last = NULL;
00724   while (p)
00725     {
00726       p_vet = (struct vet *) MHD__asn1_alloca (sizeof (struct vet));
00727       if (p_vet == NULL)
00728         return;
00729 
00730       p_vet->next = NULL;
00731       p_vet->prev = last;
00732       if (first == NULL)
00733         first = p_vet;
00734       else
00735         last->next = p_vet;
00736       last = p_vet;
00737 
00738       /* extraction of tag and length */
00739       if (der_len - counter > 0)
00740         {
00741 
00742           if (MHD__asn1_get_tag_der
00743               (der + counter, der_len - counter, &class, &len,
00744                NULL) != ASN1_SUCCESS)
00745             return;
00746           counter += len;
00747 
00748           len2 =
00749             MHD__asn1_get_length_der (der + counter, der_len - counter, &len);
00750           if (len2 < 0)
00751             return;
00752           counter += len + len2;
00753         }
00754 
00755       p_vet->end = counter;
00756       p = p->right;
00757     }
00758 
00759   p_vet = first;
00760 
00761   while (p_vet)
00762     {
00763       p2_vet = p_vet->next;
00764       counter = 0;
00765       while (p2_vet)
00766         {
00767           if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
00768             max = p_vet->end - counter;
00769           else
00770             max = p2_vet->end - p_vet->end;
00771 
00772           change = -1;
00773           for (k = 0; k < max; k++)
00774             if (der[counter + k] > der[p_vet->end + k])
00775               {
00776                 change = 1;
00777                 break;
00778               }
00779             else if (der[counter + k] < der[p_vet->end + k])
00780               {
00781                 change = 0;
00782                 break;
00783               }
00784 
00785           if ((change == -1)
00786               && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
00787             change = 1;
00788 
00789           if (change == 1)
00790             {
00791               /* change position */
00792               temp =
00793                 (unsigned char *) MHD__asn1_alloca (p_vet->end - counter);
00794               if (temp == NULL)
00795                 return;
00796 
00797               memcpy (temp, der + counter, (p_vet->end) - counter);
00798               memcpy (der + counter, der + (p_vet->end),
00799                       (p2_vet->end) - (p_vet->end));
00800               memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
00801                       (p_vet->end) - counter);
00802               MHD__asn1_afree (temp);
00803 
00804               p_vet->end = counter + (p2_vet->end - p_vet->end);
00805             }
00806           counter = p_vet->end;
00807 
00808           p2_vet = p2_vet->next;
00809           p_vet = p_vet->next;
00810         }
00811 
00812       if (p_vet != first)
00813         p_vet->prev->next = NULL;
00814       else
00815         first = NULL;
00816       MHD__asn1_afree (p_vet);
00817       p_vet = first;
00818     }
00819 }
00820 
00848 MHD__asn1_retCode
00849 MHD__asn1_der_coding (ASN1_TYPE element, const char *name, void *ider,
00850                       int *len, char *ErrorDescription)
00851 {
00852   node_asn *node, *p, *p2;
00853   char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
00854   int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
00855   MHD__asn1_retCode err;
00856   unsigned char *der = ider;
00857 
00858   node = MHD__asn1_find_node (element, name);
00859   if (node == NULL)
00860     return ASN1_ELEMENT_NOT_FOUND;
00861 
00862   /* Node is now a locally allocated variable.
00863    * That is because in some point we modify the
00864    * structure, and I don't know why! --nmav
00865    */
00866   node = MHD__asn1_copy_structure3 (node);
00867   if (node == NULL)
00868     return ASN1_ELEMENT_NOT_FOUND;
00869 
00870   max_len = *len;
00871 
00872   counter = 0;
00873   move = DOWN;
00874   p = node;
00875   while (1)
00876     {
00877 
00878       counter_old = counter;
00879       max_len_old = max_len;
00880       if (move != UP)
00881         {
00882           err = MHD__asn1_insert_tag_der (p, der, &counter, &max_len);
00883           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
00884             goto error;
00885         }
00886       switch (type_field (p->type))
00887         {
00888         case TYPE_NULL:
00889           max_len--;
00890           if (max_len >= 0)
00891             der[counter] = 0;
00892           counter++;
00893           move = RIGHT;
00894           break;
00895         case TYPE_BOOLEAN:
00896           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
00897             {
00898               counter = counter_old;
00899               max_len = max_len_old;
00900             }
00901           else
00902             {
00903               if (p->value == NULL)
00904                 {
00905                   MHD__asn1_error_description_value_not_found (p,
00906                                                                ErrorDescription);
00907                   err = ASN1_VALUE_NOT_FOUND;
00908                   goto error;
00909                 }
00910               max_len -= 2;
00911               if (max_len >= 0)
00912                 {
00913                   der[counter++] = 1;
00914                   if (p->value[0] == 'F')
00915                     der[counter++] = 0;
00916                   else
00917                     der[counter++] = 0xFF;
00918                 }
00919               else
00920                 counter += 2;
00921             }
00922           move = RIGHT;
00923           break;
00924         case TYPE_INTEGER:
00925         case TYPE_ENUMERATED:
00926           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
00927             {
00928               counter = counter_old;
00929               max_len = max_len_old;
00930             }
00931           else
00932             {
00933               if (p->value == NULL)
00934                 {
00935                   MHD__asn1_error_description_value_not_found (p,
00936                                                                ErrorDescription);
00937                   err = ASN1_VALUE_NOT_FOUND;
00938                   goto error;
00939                 }
00940               len2 = MHD__asn1_get_length_der (p->value, p->value_len, &len3);
00941               if (len2 < 0)
00942                 {
00943                   err = ASN1_DER_ERROR;
00944                   goto error;
00945                 }
00946               max_len -= len2 + len3;
00947               if (max_len >= 0)
00948                 memcpy (der + counter, p->value, len3 + len2);
00949               counter += len3 + len2;
00950             }
00951           move = RIGHT;
00952           break;
00953         case TYPE_OBJECT_ID:
00954           if ((p->type & CONST_DEFAULT) && (p->value == NULL))
00955             {
00956               counter = counter_old;
00957               max_len = max_len_old;
00958             }
00959           else
00960             {
00961               if (p->value == NULL)
00962                 {
00963                   MHD__asn1_error_description_value_not_found (p,
00964                                                                ErrorDescription);
00965                   err = ASN1_VALUE_NOT_FOUND;
00966                   goto error;
00967                 }
00968               len2 = max_len;
00969               err = MHD__asn1_objectid_der (p->value, der + counter, &len2);
00970               if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
00971                 goto error;
00972 
00973               max_len -= len2;
00974               counter += len2;
00975             }
00976           move = RIGHT;
00977           break;
00978         case TYPE_TIME:
00979           if (p->value == NULL)
00980             {
00981               MHD__asn1_error_description_value_not_found (p,
00982                                                            ErrorDescription);
00983               err = ASN1_VALUE_NOT_FOUND;
00984               goto error;
00985             }
00986           len2 = max_len;
00987           err = MHD__asn1_time_der (p->value, der + counter, &len2);
00988           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
00989             goto error;
00990 
00991           max_len -= len2;
00992           counter += len2;
00993           move = RIGHT;
00994           break;
00995         case TYPE_OCTET_STRING:
00996           if (p->value == NULL)
00997             {
00998               MHD__asn1_error_description_value_not_found (p,
00999                                                            ErrorDescription);
01000               err = ASN1_VALUE_NOT_FOUND;
01001               goto error;
01002             }
01003           len2 = MHD__asn1_get_length_der (p->value, p->value_len, &len3);
01004           if (len2 < 0)
01005             {
01006               err = ASN1_DER_ERROR;
01007               goto error;
01008             }
01009           max_len -= len2 + len3;
01010           if (max_len >= 0)
01011             memcpy (der + counter, p->value, len3 + len2);
01012           counter += len3 + len2;
01013           move = RIGHT;
01014           break;
01015         case TYPE_GENERALSTRING:
01016           if (p->value == NULL)
01017             {
01018               MHD__asn1_error_description_value_not_found (p,
01019                                                            ErrorDescription);
01020               err = ASN1_VALUE_NOT_FOUND;
01021               goto error;
01022             }
01023           len2 = MHD__asn1_get_length_der (p->value, p->value_len, &len3);
01024           if (len2 < 0)
01025             {
01026               err = ASN1_DER_ERROR;
01027               goto error;
01028             }
01029           max_len -= len2 + len3;
01030           if (max_len >= 0)
01031             memcpy (der + counter, p->value, len3 + len2);
01032           counter += len3 + len2;
01033           move = RIGHT;
01034           break;
01035         case TYPE_BIT_STRING:
01036           if (p->value == NULL)
01037             {
01038               MHD__asn1_error_description_value_not_found (p,
01039                                                            ErrorDescription);
01040               err = ASN1_VALUE_NOT_FOUND;
01041               goto error;
01042             }
01043           len2 = MHD__asn1_get_length_der (p->value, p->value_len, &len3);
01044           if (len2 < 0)
01045             {
01046               err = ASN1_DER_ERROR;
01047               goto error;
01048             }
01049           max_len -= len2 + len3;
01050           if (max_len >= 0)
01051             memcpy (der + counter, p->value, len3 + len2);
01052           counter += len3 + len2;
01053           move = RIGHT;
01054           break;
01055         case TYPE_SEQUENCE:
01056         case TYPE_SET:
01057           if (move != UP)
01058             {
01059               MHD__asn1_ltostr (counter, temp);
01060               tlen = strlen (temp);
01061               if (tlen > 0)
01062                 MHD__asn1_set_value (p, temp, tlen + 1);
01063               if (p->down == NULL)
01064                 {
01065                   move = UP;
01066                   continue;
01067                 }
01068               else
01069                 {
01070                   p2 = p->down;
01071                   while (p2 && (type_field (p2->type) == TYPE_TAG))
01072                     p2 = p2->right;
01073                   if (p2)
01074                     {
01075                       p = p2;
01076                       move = RIGHT;
01077                       continue;
01078                     }
01079                   move = UP;
01080                   continue;
01081                 }
01082             }
01083           else
01084             {                   /* move==UP */
01085               len2 = strtol ((const char *) p->value, NULL, 10);
01086               MHD__asn1_set_value (p, NULL, 0);
01087               if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
01088                 MHD__asn1_ordering_set (der + len2, max_len - len2, p);
01089               MHD__asn1_length_der (counter - len2, (unsigned char *) temp,
01090                                     &len3);
01091               max_len -= len3;
01092               if (max_len >= 0)
01093                 {
01094                   memmove (der + len2 + len3, der + len2, counter - len2);
01095                   memcpy (der + len2, temp, len3);
01096                 }
01097               counter += len3;
01098               move = RIGHT;
01099             }
01100           break;
01101         case TYPE_SEQUENCE_OF:
01102         case TYPE_SET_OF:
01103           if (move != UP)
01104             {
01105               MHD__asn1_ltostr (counter, temp);
01106               tlen = strlen (temp);
01107 
01108               if (tlen > 0)
01109                 MHD__asn1_set_value (p, temp, tlen + 1);
01110               p = p->down;
01111               while ((type_field (p->type) == TYPE_TAG)
01112                      || (type_field (p->type) == TYPE_SIZE))
01113                 p = p->right;
01114               if (p->right)
01115                 {
01116                   p = p->right;
01117                   move = RIGHT;
01118                   continue;
01119                 }
01120               else
01121                 p = MHD__asn1_find_up (p);
01122               move = UP;
01123             }
01124           if (move == UP)
01125             {
01126               len2 = strtol ((const char *) p->value, NULL, 10);
01127               MHD__asn1_set_value (p, NULL, 0);
01128               if ((type_field (p->type) == TYPE_SET_OF)
01129                   && (max_len - len2 > 0))
01130                 {
01131                   MHD__asn1_ordering_set_of (der + len2, max_len - len2, p);
01132                 }
01133               MHD__asn1_length_der (counter - len2, (unsigned char *) temp,
01134                                     &len3);
01135               max_len -= len3;
01136               if (max_len >= 0)
01137                 {
01138                   memmove (der + len2 + len3, der + len2, counter - len2);
01139                   memcpy (der + len2, temp, len3);
01140                 }
01141               counter += len3;
01142               move = RIGHT;
01143             }
01144           break;
01145         case TYPE_ANY:
01146           if (p->value == NULL)
01147             {
01148               MHD__asn1_error_description_value_not_found (p,
01149                                                            ErrorDescription);
01150               err = ASN1_VALUE_NOT_FOUND;
01151               goto error;
01152             }
01153           len2 = MHD__asn1_get_length_der (p->value, p->value_len, &len3);
01154           if (len2 < 0)
01155             {
01156               err = ASN1_DER_ERROR;
01157               goto error;
01158             }
01159           max_len -= len2;
01160           if (max_len >= 0)
01161             memcpy (der + counter, p->value + len3, len2);
01162           counter += len2;
01163           move = RIGHT;
01164           break;
01165         default:
01166           move = (move == UP) ? RIGHT : DOWN;
01167           break;
01168         }
01169 
01170       if ((move != DOWN) && (counter != counter_old))
01171         {
01172           err = MHD__asn1_complete_explicit_tag (p, der, &counter, &max_len);
01173           if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
01174             goto error;
01175         }
01176 
01177       if (p == node && move != DOWN)
01178         break;
01179 
01180       if (move == DOWN)
01181         {
01182           if (p->down)
01183             p = p->down;
01184           else
01185             move = RIGHT;
01186         }
01187       if (move == RIGHT)
01188         {
01189           if (p->right)
01190             p = p->right;
01191           else
01192             move = UP;
01193         }
01194       if (move == UP)
01195         p = MHD__asn1_find_up (p);
01196     }
01197 
01198   *len = counter;
01199 
01200   if (max_len < 0)
01201     {
01202       err = ASN1_MEM_ERROR;
01203       goto error;
01204     }
01205 
01206   err = ASN1_SUCCESS;
01207 
01208 error:
01209   MHD__asn1_delete_structure (&node);
01210   return err;
01211 }

Generated on Sun Jul 26 17:20:55 2009 for GNU libmicrohttpd by  doxygen 1.5.9