~ubuntu-branches/ubuntu/hardy/gnupg/hardy-updates

« back to all changes in this revision

Viewing changes to g10/tlv.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-12-16 16:57:39 UTC
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051216165739-v0m2d1you6hd8jho
Tags: upstream-1.4.2
ImportĀ upstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* tlv.c - Tag-Length-Value Utilities
2
 
 *      Copyright (C) 2003, 2004 Free Software Foundation, Inc.
 
2
 *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
15
15
 *
16
16
 * You should have received a copy of the GNU General Public License
17
17
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
19
 * USA.
19
20
 */
20
21
 
21
22
#include <config.h>
25
26
#include <string.h>
26
27
#include <assert.h>
27
28
 
28
 
#include "errors.h"
29
 
#include "util.h"
30
 
#include "packet.h"
 
29
#if GNUPG_MAJOR_VERSION == 1
 
30
#define GPG_ERR_EOF               (-1)
 
31
#define GPG_ERR_BAD_BER           (1)  /*G10ERR_GENERAL*/
 
32
#define GPG_ERR_INV_SEXP          (45) /*G10ERR_INV_ARG*/
 
33
typedef int gpg_error_t;
 
34
#define gpg_error(n) (n)
 
35
#else
 
36
#include <gpg-error.h>
 
37
#endif
 
38
 
 
39
 
31
40
#include "tlv.h"
32
41
 
33
42
static const unsigned char *
114
123
 
115
124
/* Locate a TLV encoded data object in BUFFER of LENGTH and
116
125
   return a pointer to value as well as its length in NBYTES.  Return
 
126
   NULL if it was not found or if the object does not fit into the buffer. */
 
127
const unsigned char *
 
128
find_tlv (const unsigned char *buffer, size_t length,
 
129
          int tag, size_t *nbytes)
 
130
{
 
131
  const unsigned char *p;
 
132
 
 
133
  p = do_find_tlv (buffer, length, tag, nbytes, 0);
 
134
  if (p && *nbytes > (length - (p-buffer)))
 
135
    p = NULL; /* Object longer than buffer. */
 
136
  return p;
 
137
}
 
138
 
 
139
 
 
140
 
 
141
/* Locate a TLV encoded data object in BUFFER of LENGTH and
 
142
   return a pointer to value as well as its length in NBYTES.  Return
117
143
   NULL if it was not found.  Note, that the function does not check
118
144
   whether the value fits into the provided buffer. */
119
145
const unsigned char *
120
 
find_tlv (const unsigned char *buffer, size_t length,
121
 
          int tag, size_t *nbytes)
 
146
find_tlv_unchecked (const unsigned char *buffer, size_t length,
 
147
                    int tag, size_t *nbytes)
122
148
{
123
149
  return do_find_tlv (buffer, length, tag, nbytes, 0);
124
150
}
125
151
 
126
152
 
127
 
 
128
 
 
129
153
/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag
130
154
   and the length part from the TLV triplet.  Update BUFFER and SIZE
131
155
   on success. */
207
231
  *size = length;
208
232
  return 0;
209
233
}
 
234
 
 
235
 
 
236
/* FIXME: The following function should not go into this file but for
 
237
   now it is easier to keep it here. */
 
238
 
 
239
/* Return the next token of an canconical encoded S-expression.  BUF
 
240
   is the pointer to the S-expression and BUFLEN is a pointer to the
 
241
   length of this S-expression (used to validate the syntax).  Both
 
242
   are updated to reflect the new position.  The token itself is
 
243
   returned as a pointer into the orginal buffer at TOK and TOKLEN.
 
244
   If a parentheses is the next token, TOK will be set to NULL.
 
245
   TOKLEN is checked to be within the bounds.  On error a error code
 
246
   is returned and all pointers should are not guaranteed to point to
 
247
   a meanigful value. DEPTH should be initialized to 0 and will
 
248
   reflect on return the actual depth of the tree. To detect the end
 
249
   of the S-expression it is advisable to check DEPTH after a
 
250
   successful return:
 
251
 
 
252
   depth = 0;
 
253
   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
 
254
          && depth)
 
255
     process_token (tok, toklen);
 
256
   if (err)  
 
257
     handle_error ();
 
258
 */
 
259
gpg_error_t
 
260
parse_sexp (unsigned char const **buf, size_t *buflen,
 
261
            int *depth, unsigned char const **tok, size_t *toklen)
 
262
{
 
263
  const unsigned char *s;
 
264
  size_t n, vlen;
 
265
 
 
266
  s = *buf;
 
267
  n = *buflen;
 
268
  *tok = NULL;
 
269
  *toklen = 0;
 
270
  if (!n)
 
271
    return *depth ? gpg_error (GPG_ERR_INV_SEXP) : 0;
 
272
  if (*s == '(')
 
273
    {
 
274
      s++; n--;
 
275
      (*depth)++;
 
276
      *buf = s;
 
277
      *buflen = n;
 
278
      return 0;
 
279
    }
 
280
  if (*s == ')')
 
281
    {
 
282
      if (!*depth)
 
283
        return gpg_error (GPG_ERR_INV_SEXP);
 
284
      *toklen = 1;
 
285
      s++; n--;
 
286
      (*depth)--;
 
287
      *buf = s;
 
288
      *buflen = n;
 
289
      return 0;
 
290
    }
 
291
  for (vlen=0; n && *s && *s != ':' && (*s >= '0' && *s <= '9'); s++, n--)
 
292
    vlen = vlen*10 + (*s - '0');
 
293
  if (!n || *s != ':')
 
294
    return gpg_error (GPG_ERR_INV_SEXP);
 
295
  s++; n--;
 
296
  if (vlen > n)
 
297
    return gpg_error (GPG_ERR_INV_SEXP);
 
298
  *tok = s;
 
299
  *toklen = vlen;
 
300
  s += vlen;
 
301
  n -= vlen;
 
302
  *buf = s;
 
303
  *buflen = n;
 
304
  return 0;
 
305
}
 
306