Exemplo n.º 1
0
static int
_read(st_asn1_struct* ctx,
      unsigned char constructed,
      unsigned char clazz,
      uint64 tag,
      unsigned char* data,
      size_t* length) {
  unsigned char* p;
  unsigned char b;
  uint64 rtag, rlength;
  
  if ((ctx->pos - ctx->data + 2) > ctx->datalength)
    return 0;

  p = ctx->pos;

  b = *p++;
  rtag = b & 0x1f;

  if ((clazz != (b & 0xc0)) ||
      (constructed != (b & 0x20)))
    return 0;

  if (rtag == 0x1f)
    if (!_read_base_128(&p, &rtag, ctx->datalength - (p - ctx->data)))
      return 0;
  if (tag != rtag)
    return 0;

  b = *p++;
  if (b & 0x80) {
    b &= 0x7f;
    if (b > 0) {
      if (b > (ctx->datalength - (p - ctx->data)))
        return 0;
      _read_base_256(&p, &rlength, b);
    } else
      rlength = 0;
  } else
    rlength = b & 0x7f;

  if (rlength > *length)
    return 0;
  *length = (size_t) rlength;

  if (rlength > 0)
    st_memcpy(data, p, (int) rlength);
  p += rlength;

  ctx->pos = p;

  return 1;
}
Exemplo n.º 2
0
static int
_write(st_asn1_struct* ctx,
       unsigned char constructed,
       unsigned char clazz,
       uint64 tag,
       unsigned char* data,
       uint64 length) {
  if ((ctx->pos - ctx->data + 2 + length) > ctx->datalength)
    return 0;
  
  if (tag < 31)
    *ctx->pos++ = (unsigned char) (clazz | constructed | tag);
  else {
    *ctx->pos++ = clazz | constructed | 0x1f;
    if (!_write_base_128(&ctx->pos,
                         ctx->datalength - (ctx->pos - ctx->data),
                         tag))
      return 0;
  }

  if (length == 0)
    *ctx->pos++ = 0x80;
  else if (length < 0x80)
    *ctx->pos++ = (unsigned char) length;
  else {
    unsigned char log = _log_base_256(length);
    *ctx->pos++ = 0x80 | log;
    if (!_write_base_256(ctx, length, log))
      return 0;
  }

  if ((ctx->pos - ctx->data + length) > ctx->datalength)
    return 0;

  if (length > 0) {
    st_memcpy(ctx->pos, data, (int) length);
    ctx->pos += length;
  }
  
  return 1;
}
Exemplo n.º 3
0
void * st_memmove(void *dst, const void *src, st_size_t len)
{
      st_size_t i;

      /*
	* If the buffers don't overlap, it doesn't matter what direction
	* we copy in. If they do, it does, so just assume they always do.
	* We don't concern ourselves with the possibility that the region
	* to copy might roll over across the top of memory, because it's
	* not going to happen.
	*
	* If the destination is above the source, we have to copy
	* back to front to avoid overwriting the data we want to
	* copy.
	*
	*      dest:       dddddddd
	*      src:    ssssssss   ^
	*              |   ^  |___|
	*              |___|
	*
	* If the destination is below the source, we have to copy
	* front to back.
	*
	*      dest:   dddddddd
	*      src:    ^   ssssssss
	*              |___|  ^   |
	*                     |___|
	*/

	if ((st_uintptr_t)dst < (st_uintptr_t)src) {
		/*
		  * As author/maintainer of libc, take advantage of the
		  * fact that we know memcpy copies forwards.
		  */
		return st_memcpy(dst, src, len);
	}

	/*
	  * Copy by words in the common case. Look in memcpy.c for more
	  * information.
	  */

	if ((st_uintptr_t)dst % sizeof(long) == 0 &&
	    (st_uintptr_t)src % sizeof(long) == 0 &&
	    len % sizeof(long) == 0) {
		long *d = dst;
		const long *s = src;
		/*
		  * The reason we copy index i-1 and test i>0 is that
		  * i is unsigned - so testing i>=0 doesn't work.
		  */
		for (i=len/sizeof(long); i>0; i--) 
			d[i-1] = s[i-1];
	}
	else {
		char *d = dst;
		const char *s = src;
		for (i=len; i>0; i--) 
			d[i-1] = s[i-1];
	}

	return dst;
}