00001
00002
00003
00004
00005
00013 #if HAVE_CONFIG_H
00014 #include <config.h>
00015 #endif
00016
00017 #include <stdio.h>
00018 #include "odr-priv.h"
00019
00034 int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt,
00035 const char *name)
00036 {
00037 struct Odr_ber_tag *odr_ber_tag = &o->op->odr_ber_tag;
00038 int rd;
00039 char **pp = (char **)p;
00040
00041 if (o->direction == ODR_DECODE)
00042 *pp = 0;
00043 o->op->t_class = -1;
00044 if (ODR_STACK_EMPTY(o))
00045 {
00046 odr_seek(o, ODR_S_SET, 0);
00047 o->top = 0;
00048 o->bp = o->buf;
00049 odr_ber_tag->lclass = -1;
00050 }
00051 switch (o->direction)
00052 {
00053 case ODR_ENCODE:
00054 if (!*pp)
00055 {
00056 if (!opt)
00057 {
00058 odr_seterror(o, OREQUIRED, 24);
00059 odr_setelement (o, name);
00060 }
00061 return 0;
00062 }
00063 if ((rd = ber_enctag(o, zclass, tag, *constructed)) < 0)
00064 return -1;
00065 return 1;
00066 case ODR_DECODE:
00067 if (ODR_STACK_NOT_EMPTY(o) && !odr_constructed_more(o))
00068 {
00069 if (!opt)
00070 {
00071 odr_seterror(o, OREQUIRED, 25);
00072 odr_setelement(o, name);
00073 }
00074 return 0;
00075 }
00076 if (odr_ber_tag->lclass < 0)
00077 {
00078 if ((odr_ber_tag->br =
00079 ber_dectag(o->bp, &odr_ber_tag->lclass,
00080 &odr_ber_tag->ltag, &odr_ber_tag->lcons,
00081 odr_max(o))) <= 0)
00082 {
00083 odr_seterror(o, OPROTO, 26);
00084 odr_setelement(o, name);
00085 return 0;
00086 }
00087 }
00088 if (zclass == odr_ber_tag->lclass && tag == odr_ber_tag->ltag)
00089 {
00090 o->bp += odr_ber_tag->br;
00091 *constructed = odr_ber_tag->lcons;
00092 odr_ber_tag->lclass = -1;
00093 return 1;
00094 }
00095 else
00096 {
00097 if (!opt)
00098 {
00099 odr_seterror(o, OREQUIRED, 27);
00100 odr_setelement(o, name);
00101 }
00102 return 0;
00103 }
00104 case ODR_PRINT:
00105 if (!*pp && !opt)
00106 {
00107 odr_seterror(o,OREQUIRED, 28);
00108 odr_setelement(o, name);
00109 }
00110 return *pp != 0;
00111 default:
00112 odr_seterror(o, OOTHER, 29);
00113 odr_setelement(o, name);
00114 return 0;
00115 }
00116 }
00117
00123 int ber_enctag(ODR o, int zclass, int tag, int constructed)
00124 {
00125 int cons = (constructed ? 1 : 0), n = 0;
00126 unsigned char octs[sizeof(int)], b;
00127
00128 b = (zclass << 6) & 0XC0;
00129 b |= (cons << 5) & 0X20;
00130 if (tag <= 30)
00131 {
00132 b |= tag & 0X1F;
00133 if (odr_putc(o, b) < 0)
00134 return -1;
00135 return 1;
00136 }
00137 else
00138 {
00139 b |= 0X1F;
00140 if (odr_putc(o, b) < 0)
00141 return -1;
00142 do
00143 {
00144 octs[n++] = tag & 0X7F;
00145 tag >>= 7;
00146 }
00147 while (tag);
00148 while (n--)
00149 {
00150 unsigned char oo;
00151
00152 oo = octs[n] | ((n > 0) << 7);
00153 if (odr_putc(o, oo) < 0)
00154 return -1;
00155 }
00156 return 0;
00157 }
00158 }
00159
00165 int ber_dectag(const unsigned char *b, int *zclass, int *tag,
00166 int *constructed, int max)
00167 {
00168 int l = 1;
00169
00170 if (l > max)
00171 return -1;
00172
00173 *zclass = *b >> 6;
00174 *constructed = (*b >> 5) & 0X01;
00175 if ((*tag = *b & 0x1F) <= 30)
00176 return 1;
00177 *tag = 0;
00178 do
00179 {
00180 if (l >= max)
00181 return -1;
00182 *tag <<= 7;
00183 *tag |= b[l] & 0X7F;
00184 }
00185 while (b[l++] & 0X80);
00186 return l;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195