/*
 * Copyright (c) 1997-2007  The Stanford SRP Authentication Project
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Redistributions in source or binary form must retain an intact copy
 * of this copyright notice.
 */

/*#define _POSIX_SOURCE*/
#include <stdio.h>
#include "t_defines.h"
#include "cstr.h"

static int
hexDigitToInt(c)
     char c;
{
  if(c >= '0' && c <= '9')
    return c - '0';
  else if(c >= 'a' && c <= 'f')
    return c - 'a' + 10;
  else if(c >= 'A' && c <= 'F')
    return c - 'A' + 10;
  else
    return 0;
}

/*
 * Convert a hex string to a string of bytes; return size of dst
 */
_TYPE( int )
t_fromhex(dst, src)
     char * dst;
     const char * src;
{
  register char *chp = dst;
  register unsigned size = strlen(src);

  /* FIXME: handle whitespace and non-hex digits by setting size and src
     appropriately. */

  if(size % 2 == 1) {
    *chp++ = hexDigitToInt(*src++);
    --size;
  }
  while(size > 0) {
    *chp++ = (hexDigitToInt(*src) << 4) | hexDigitToInt(*(src + 1));
    src += 2;
    size -= 2;
  }
  return chp - dst;
}

/*
 * Convert a string of bytes to their hex representation
 */
_TYPE( char * )
t_tohex(dst, src, size)
     char * dst;
     const char * src;
     unsigned size;
{
   int notleading = 0;

   register char *chp = dst;
   *dst = '\0';
   if (size != 0) do {
      if(notleading || *src != '\0') {
	if(!notleading && (*src & 0xf0) == 0) {
	  sprintf(chp, "%.1X", * (unsigned char *) src);
	  chp += 1;
	}
	else {
	  sprintf(chp, "%.2X", * (unsigned char *) src);
	  chp += 2;
	}
	notleading = 1;
      }
      ++src;
   } while (--size != 0);
   return dst;
}

_TYPE( char * )
t_tohexcstr(dst, src, size)
     cstr * dst;
     const char * src;
     unsigned size;
{
  cstr_set_length(dst, 2 * size + 1);
  return t_tohex(dst->data, src, size);
}

static char b64table[] =
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";

/*
 * Convert a base64 string into raw byte array representation.
 */
_TYPE( int )
t_fromb64(dst, src)
     char * dst;
     const char * src;
{
  unsigned char *a;
  char *loc;
  int i, j;
  unsigned int size;

  while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
      ++src;
  size = strlen(src);

  a = malloc((size + 1) * sizeof(unsigned char));
  if(a == (unsigned char *) 0)
    return -1;

  i = 0;
  while(i < size) {
    loc = strchr(b64table, src[i]);
    if(loc == (char *) 0)
      break;
    else
      a[i] = loc - b64table;
    ++i;
  }
  size = i;

  i = size - 1;
  j = size;
  while(1) {
    a[j] = a[i];
    if(--i < 0)
      break;
    a[j] |= (a[i] & 3) << 6;
    --j;
    a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
    if(--i < 0)
      break;
    a[j] |= (a[i] & 0xf) << 4;
    --j;
    a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
    if(--i < 0)
      break;
    a[j] |= (a[i] << 2);

    a[--j] = 0;
    if(--i < 0)
      break;
  }

  while(a[j] == 0 && j <= size)
    ++j;

  memcpy(dst, a + j, size - j + 1);
  free(a);
  return size - j + 1;
}

_TYPE( int )
t_cstrfromb64(dst, src)
     cstr * dst;
     const char * src;
{
  int len;
  cstr_set_length(dst, (strlen(src) * 6 + 7) / 8);
  len = t_fromb64(dst->data, src);
  cstr_set_length(dst, len);
  return len;
}

/*
 * Convert a raw byte string into a null-terminated base64 ASCII string.
 */
_TYPE( char * )
t_tob64(dst, src, size)
     char * dst;
     const char * src;
     unsigned size;
{
  int c, pos = size % 3;
  unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
  char *olddst = dst;

  switch(pos) {
  case 1:
    b2 = src[0];
    break;
  case 2:
    b1 = src[0];
    b2 = src[1];
    break;
  }

  while(1) {
    c = (b0 & 0xfc) >> 2;
    if(notleading || c != 0) {
      *dst++ = b64table[c];
      notleading = 1;
    }
    c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
    if(notleading || c != 0) {
      *dst++ = b64table[c];
      notleading = 1;
    }
    c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
    if(notleading || c != 0) {
      *dst++ = b64table[c];
      notleading = 1;
    }
    c = b2 & 0x3f;
    if(notleading || c != 0) {
      *dst++ = b64table[c];
      notleading = 1;
    }
    if(pos >= size)
      break;
    else {
      b0 = src[pos++];
      b1 = src[pos++];
      b2 = src[pos++];
    }
  }

  *dst++ = '\0';
  return olddst;
}

_TYPE( char * )
t_tob64cstr(dst, src, sz)
     cstr * dst;
     const char * src;
     unsigned int sz;
{
  cstr_set_length(dst, (sz * 8 + 5) / 6 + 1);
  return t_tob64(dst->data, src, sz);
}
