 2f88ff228a
			
		
	
	2f88ff228a
	
	
	
		
			
			git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@311 ec53bebd-3082-4978-b11e-865c3cabbd6b
		
			
				
	
	
		
			257 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <krb5_locl.h>
 | |
| #include <d.h>
 | |
| 
 | |
| int
 | |
| buf_getbyte (Buffer *b)
 | |
| {
 | |
|      if (b->p >= b->buf + b->len)
 | |
| 	  return EOF;
 | |
|      return *b->p++;
 | |
| }
 | |
| 
 | |
| void
 | |
| buf_init (Buffer *b, char *ptr, unsigned len)
 | |
| {
 | |
|      b->buf = b->p = ptr;
 | |
|      b->len = len;
 | |
| }
 | |
| 
 | |
| Buffer *
 | |
| buf_derive (Buffer *b, Buffer *tmp, int len)
 | |
| {
 | |
|      tmp->buf = tmp->p = b->p;
 | |
|      if(len == -1)
 | |
| 	  tmp->len = buf_bytesleft (b);
 | |
|      else
 | |
| 	  tmp->len = len;
 | |
|      return tmp;
 | |
| }
 | |
| 
 | |
| int
 | |
| buf_bytesleft (Buffer *b)
 | |
| {
 | |
|      return b->len - (b->p - b->buf);
 | |
| }
 | |
| 
 | |
| void
 | |
| buf_advance (Buffer *b, int n)
 | |
| {
 | |
|      b->p += n;
 | |
| }
 | |
| 
 | |
| int
 | |
| buf_length (Buffer *b)
 | |
| {
 | |
|      return b->p - b->buf;
 | |
| }
 | |
| 
 | |
| Identifier *
 | |
| getid (Buffer *b, Identifier *i)
 | |
| {
 | |
|      int c, len;
 | |
| 
 | |
|      c = buf_getbyte (b);
 | |
|      if (c == EOF)
 | |
| 	  return NULL;
 | |
|      i->class = c >> 6;
 | |
|      i->type  = (c >> 5) & 1;
 | |
|      i->tag   = c & 0x1F;
 | |
|      if (i->tag == 0x1F) {
 | |
| 	  do {
 | |
| 	       c = buf_getbyte (b);
 | |
| 	       if (c == EOF)
 | |
| 		    return NULL;
 | |
| 	       i->tag = i->tag * 0x80 + (c & 0x7F);
 | |
| 	  } while( c & 0x80);
 | |
|      }
 | |
| 
 | |
|      c = buf_getbyte (b);
 | |
|      if (c == EOF)
 | |
| 	  return NULL;
 | |
|      len = c;
 | |
|      if (len < 0x80) {
 | |
| 	  i->len = len;
 | |
|      } else if(len > 0x80) {
 | |
| 	  len &= 0x7F;
 | |
| 	  i->len = 0;
 | |
| 	  while (len--) {
 | |
| 	       c = buf_getbyte (b);
 | |
| 	       if (c == EOF)
 | |
| 		    return NULL;
 | |
| 	       i->len = i->len * 0x100 + c;
 | |
| 	  }
 | |
|      } else if (len == 0x80)
 | |
| 	  i->len = -1;
 | |
|      return i;
 | |
| }
 | |
| 
 | |
| Identifier *
 | |
| matchid (Buffer *b, Identifier *i)
 | |
| {
 | |
|      Identifier tmp;
 | |
| 
 | |
|      if (getid (b, &tmp) == NULL)
 | |
| 	  return NULL;
 | |
|      if (tmp.class == i->class && tmp.type == i->type && tmp.tag == i->tag) {
 | |
| 	  i->len = tmp.len;
 | |
| 	  return i;
 | |
|      } else
 | |
| 	  return NULL;
 | |
| }
 | |
| 
 | |
| static Identifier dummy;
 | |
| 
 | |
| Identifier *
 | |
| matchid3 (Buffer *b, Identifier *i, Der_class class, Der_type type,
 | |
| 	  unsigned tag)
 | |
| {
 | |
|      i->class = class;
 | |
|      i->type  = type;
 | |
|      i->tag   = tag;
 | |
|      return matchid (b, i);
 | |
| }
 | |
| 
 | |
| Identifier *
 | |
| matchcontextid (Buffer *b, Identifier *i, int tag)
 | |
| {
 | |
|      Identifier tmp;
 | |
|      
 | |
|      if (matchid3 (b, &tmp, CONTEXT, CONS, tag) == NULL ||
 | |
| 	 matchid (b, i) == NULL)
 | |
| 	  return NULL;
 | |
|      return i;
 | |
| }
 | |
| 
 | |
| Identifier *
 | |
| matchcontextid3 (Buffer *b, Identifier *i, Der_class class,
 | |
| 		 Der_type dtype,
 | |
| 		 int type,
 | |
| 		 unsigned tag)
 | |
| {
 | |
|      i->class = class;
 | |
|      i->type  = dtype;
 | |
|      i->tag   = type;
 | |
|      return matchcontextid (b, i, tag);
 | |
| }
 | |
| 
 | |
| int
 | |
| der_get_integer (Buffer *b, void *val)
 | |
| {
 | |
|      int c;
 | |
|      int res;
 | |
|      int len;
 | |
| 
 | |
|      res = len = 0;
 | |
|      while ((c = buf_getbyte (b)) != EOF) {
 | |
| 	  res = res * 0x100 + c;
 | |
| 	  ++len;
 | |
|      }
 | |
|      *((int *)val) = res;
 | |
|      return len;
 | |
| }
 | |
| 
 | |
| int
 | |
| der_get_octetstring (Buffer *b, void *val)
 | |
| {
 | |
|      krb5_data *str = (krb5_data *)val;
 | |
|      int len, c;
 | |
|      char *p;
 | |
| 
 | |
|      len = buf_bytesleft (b);
 | |
|      str->length = len;
 | |
|      str->data   = p = malloc (len + 1);
 | |
|      while (len && (c = buf_getbyte (b)) != EOF) {
 | |
| 	  *p++ = c;
 | |
| 	  --len;
 | |
|      }
 | |
|      *p++ = '\0';
 | |
|      return len;
 | |
| }
 | |
| 
 | |
| int
 | |
| der_get_generalizedtime (Buffer *b, void *val)
 | |
| {
 | |
|      time_t *t = (time_t *)val;
 | |
|      int len;
 | |
|      krb5_data str;
 | |
|      struct tm tm, *tm2;
 | |
| 
 | |
|      len = der_get_octetstring (b, &str);
 | |
|      sscanf (str.data, "%04d%02d%02d%02d%02d%02dZ",
 | |
| 	     &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
 | |
| 	     &tm.tm_min, &tm.tm_sec);
 | |
|      tm.tm_year -= 1900;
 | |
|      tm.tm_mon -= 1;
 | |
|      tm.tm_isdst = 0;
 | |
| 
 | |
|      *t = mktime (&tm);
 | |
| 
 | |
|      tm2 = gmtime (t);
 | |
| 
 | |
|      *t += *t - mktime (tm2);
 | |
|      string_free (str);
 | |
|      return len;
 | |
| }
 | |
| 
 | |
| static int (*get_univ_funcs[])(Buffer *, void *val) = {
 | |
|      NULL,			/*  0 */
 | |
|      NULL,			/*  1 */
 | |
|      der_get_integer,		/*  2 */
 | |
|      NULL,			/*  3 */
 | |
|      der_get_octetstring,	/*  4 */
 | |
|      NULL,			/*  5 */
 | |
|      NULL,			/*  6 */
 | |
|      NULL,			/*  7 */
 | |
|      NULL,			/*  8 */
 | |
|      NULL,			/*  9 */
 | |
|      NULL,			/* 10 */
 | |
|      NULL,			/* 11 */
 | |
|      NULL,			/* 12 */
 | |
|      NULL,			/* 13 */
 | |
|      NULL,			/* 14 */
 | |
|      NULL,			/* 15 */
 | |
|      NULL,			/* 16 */
 | |
|      NULL,			/* 17 */
 | |
|      NULL,			/* 18 */
 | |
|      NULL,			/* 19 */
 | |
|      NULL,			/* 20 */
 | |
|      NULL,			/* 21 */
 | |
|      NULL,			/* 22 */
 | |
|      NULL,			/* 23 */
 | |
|      der_get_generalizedtime,	/* 24 */
 | |
|      NULL,			/* 25 */
 | |
|      NULL,			/* 26 */
 | |
|      der_get_octetstring,	/* 27 */
 | |
| };
 | |
| 
 | |
| int
 | |
| der_get_val (Buffer *b, int type, void *val)
 | |
| {
 | |
|      return (*(get_univ_funcs[type]))(b, val);
 | |
| }
 | |
| 
 | |
| void
 | |
| getzeros (Buffer *b, int len)
 | |
| {
 | |
|      if (len == -1) {
 | |
| 	  buf_getbyte (b);
 | |
| 	  buf_getbyte (b);
 | |
|      }
 | |
| }
 | |
| 
 | |
| int
 | |
| getdata (Buffer *b, Identifier *i, void *arg)
 | |
| {
 | |
|      Buffer tmp;
 | |
|      int res;
 | |
| 
 | |
|      buf_derive (b, &tmp, i->len);
 | |
|      res = der_get_val (&tmp, i->tag, arg);
 | |
|      if (i->len == -1) {
 | |
| 	  getzeros (b, i->len);
 | |
| 	  buf_advance (b, res);
 | |
|      } else
 | |
| 	  buf_advance (b, i->len);
 | |
|      return res;
 | |
| }
 |