Blame src/base64.c

Packit 762fc5
/*
Packit 762fc5
**
Packit 762fc5
** Copyright (C) 1994 Swedish University Network (SUNET)
Packit 762fc5
** Modified by Rami Lehti (C) 1999
Packit 762fc5
** $Header$
Packit 762fc5
**
Packit 762fc5
**
Packit 762fc5
** This program is free software; you can redistribute it and/or modify
Packit 762fc5
** it under the terms of the GNU General Public License as published by
Packit 762fc5
** the Free Software Foundation; either version 2 of the License, or
Packit 762fc5
** (at your option) any later version.
Packit 762fc5
**
Packit 762fc5
** This program is distributed in the hope that it will be useful,
Packit 762fc5
** but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 762fc5
** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the
Packit 762fc5
** GNU General Public License for more details.
Packit 762fc5
** 
Packit 762fc5
** You should have received a copy of the GNU General Public License
Packit 762fc5
** along with this program; if not, write to the Free Software
Packit 762fc5
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit 762fc5
**
Packit 762fc5
**
Packit 762fc5
**                                        Martin.Wendel@udac.uu.se
Packit 762fc5
**                                        Torbjorn.Wictorin@udac.uu.se
Packit 762fc5
**
Packit 762fc5
**                                        UDAC	
Packit 762fc5
**                                        P.O. Box 174
Packit 762fc5
**                                        S-751 04 Uppsala
Packit 762fc5
**                                        Sweden
Packit 762fc5
**
Packit 762fc5
*/
Packit 762fc5
Packit 762fc5
#include "aide.h"
Packit 762fc5
#include <string.h>
Packit 762fc5
#include <stdio.h>
Packit 762fc5
#include <stdlib.h>
Packit 762fc5
#include "base64.h"
Packit 762fc5
#include "report.h"
Packit 762fc5
/*for locale support*/
Packit 762fc5
#include "locale-aide.h"
Packit 762fc5
/*for locale support*/
Packit 762fc5
Packit 762fc5
char tob64[] = 
Packit 762fc5
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Packit 762fc5
Packit 762fc5
Packit 762fc5
Packit 762fc5
int fromb64[] = {
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, SKIP, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
Packit 762fc5
SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, 0x3e, FAIL, FAIL, FAIL, 0x3f,
Packit 762fc5
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,  
Packit 762fc5
0x3c, 0x3d, FAIL, FAIL, FAIL, SKIP, FAIL, FAIL,
Packit 762fc5
Packit 762fc5
FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  
Packit 762fc5
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
Packit 762fc5
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  
Packit 762fc5
0x17, 0x18, 0x19, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
Packit 762fc5
FAIL, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,  
Packit 762fc5
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
Packit 762fc5
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,  
Packit 762fc5
0x31, 0x32, 0x33, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  
Packit 762fc5
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL
Packit 762fc5
};
Packit 762fc5
Packit 762fc5
/* Returns NULL on error */
Packit 762fc5
/* FIXME Possible buffer overflow on outputs larger than B64_BUF */
Packit 762fc5
char* encode_base64(byte* src,size_t ssize)
Packit 762fc5
{
Packit 762fc5
  char* outbuf;
Packit 762fc5
  char* retbuf;
Packit 762fc5
  int pos;
Packit 762fc5
  int i, l, left;
Packit 762fc5
  unsigned long triple;
Packit 762fc5
  byte *inb;
Packit 762fc5
  
Packit 762fc5
  error(235, "encode base64");
Packit 762fc5
  /* Exit on empty input */
Packit 762fc5
  if (!ssize||src==NULL){
Packit 762fc5
    error(240,"\n");
Packit 762fc5
    return NULL;
Packit 762fc5
  }
Packit 762fc5
  outbuf = (char *)malloc(sizeof(char)*B64_BUF);
Packit 762fc5
  
Packit 762fc5
  /* Initialize working pointers */
Packit 762fc5
  inb = src;
Packit 762fc5
  i = 0;
Packit 762fc5
  triple = 0;
Packit 762fc5
  pos = 0;
Packit 762fc5
  left = ssize;
Packit 762fc5
  error(235, ", data length: %d\n", left);
Packit 762fc5
  /*
Packit 762fc5
   * Process entire inbuf.
Packit 762fc5
   */
Packit 762fc5
  while (left != 0)
Packit 762fc5
    {
Packit 762fc5
      i++;
Packit 762fc5
      left--;
Packit 762fc5
      
Packit 762fc5
      triple = (triple <<8) | *inb;
Packit 762fc5
      if (i == 3 || left == 0)
Packit 762fc5
	{
Packit 762fc5
	  switch (i) 
Packit 762fc5
	    {
Packit 762fc5
	    case 1:
Packit 762fc5
	      triple = triple<<4;
Packit 762fc5
	      break;
Packit 762fc5
	    case 2:
Packit 762fc5
	      triple = triple<<2;
Packit 762fc5
	      break;
Packit 762fc5
	    default:
Packit 762fc5
	      break;
Packit 762fc5
	    }
Packit 762fc5
	  for (l = i; l >= 0; l--){
Packit 762fc5
	    /* register */ 
Packit 762fc5
	    int rr; 
Packit 762fc5
	    rr = 0x3f & (triple>>(6*l)); 
Packit 762fc5
	    assert (rr < 64); 
Packit 762fc5
	    outbuf[pos]=tob64[rr];
Packit 762fc5
	    pos++;
Packit 762fc5
	      }
Packit 762fc5
	  if (left == 0)
Packit 762fc5
	    switch(i)
Packit 762fc5
	      {
Packit 762fc5
	      case 2:
Packit 762fc5
		outbuf[pos]='=';
Packit 762fc5
		pos++;
Packit 762fc5
		break;
Packit 762fc5
	      case 1:
Packit 762fc5
		outbuf[pos]='=';
Packit 762fc5
		pos++;
Packit 762fc5
		outbuf[pos]='=';
Packit 762fc5
		pos++;
Packit 762fc5
		break;
Packit 762fc5
	      default:
Packit 762fc5
		break;
Packit 762fc5
	      }
Packit 762fc5
	  triple = 0;
Packit 762fc5
	  i = 0;
Packit 762fc5
	  }
Packit 762fc5
      inb++;
Packit 762fc5
  }
Packit 762fc5
  
Packit 762fc5
  /* outbuf is not completely used so we use retbuf */
Packit 762fc5
  retbuf=(char*)malloc(sizeof(char)*(pos+1));
Packit 762fc5
  memcpy(retbuf,outbuf,pos);
Packit 762fc5
  retbuf[pos]='\0';
Packit 762fc5
  free(outbuf);
Packit 762fc5
Packit 762fc5
  return retbuf;
Packit 762fc5
}
Packit 762fc5
Packit 762fc5
/* FIXME Possible buffer overflow on outputs larger than B64_BUF */
Packit 762fc5
byte* decode_base64(char* src,size_t ssize, size_t *ret_len)
Packit 762fc5
{
Packit 762fc5
  byte* outbuf;
Packit 762fc5
  byte* retbuf;
Packit 762fc5
  char* inb;
Packit 762fc5
  int i;
Packit 762fc5
  int l;
Packit 762fc5
  int left;
Packit 762fc5
  int pos;
Packit 762fc5
  unsigned long triple;
Packit 762fc5
Packit 762fc5
  error(235, "decode base64\n");
Packit 762fc5
  /* Exit on empty input */
Packit 762fc5
  if (!ssize||src==NULL)
Packit 762fc5
    return NULL;
Packit 762fc5
Packit 762fc5
Packit 762fc5
  /* Initialize working pointers */
Packit 762fc5
  inb = src;
Packit 762fc5
  outbuf = (byte *)malloc(sizeof(byte)*B64_BUF);
Packit 762fc5
Packit 762fc5
  l = 0;
Packit 762fc5
  triple = 0;
Packit 762fc5
  pos=0;
Packit 762fc5
  left = ssize;
Packit 762fc5
  /*
Packit 762fc5
   * Process entire inbuf.
Packit 762fc5
   */
Packit 762fc5
  while (left != 0)
Packit 762fc5
    {
Packit 762fc5
      left--;
Packit 762fc5
      i = fromb64[(unsigned char)*inb];
Packit 762fc5
      switch(i)
Packit 762fc5
	{
Packit 762fc5
	case FAIL:
Packit 762fc5
	  error(3, "decode_base64: Illegal character: %c\n", *inb);
Packit 762fc5
	  error(230, "decode_base64: Illegal line:\n%s\n", src);
Packit d0fd42
	  free(outbuf);
Packit 762fc5
	  return NULL;
Packit 762fc5
	  break;
Packit 762fc5
	case SKIP:
Packit 762fc5
	  break;
Packit 762fc5
	default:
Packit 762fc5
	  triple = triple<<6 | (0x3f & i);
Packit 762fc5
	  l++;
Packit 762fc5
	  break;
Packit 762fc5
	}
Packit 762fc5
      if (l == 4 || left == 0)
Packit 762fc5
	{
Packit 762fc5
	  switch(l)
Packit 762fc5
	    {
Packit 762fc5
	    case 2:
Packit 762fc5
	      triple = triple>>4;
Packit 762fc5
	      break;
Packit 762fc5
	    case 3:
Packit 762fc5
	      triple = triple>>2;
Packit 762fc5
	      break;
Packit 762fc5
	    default:
Packit 762fc5
	      break;
Packit 762fc5
	    }
Packit 762fc5
	  for (l  -= 2; l >= 0; l--)
Packit 762fc5
	    {
Packit 762fc5
	      outbuf[pos]=( 0xff & (triple>>(l*8)));
Packit 762fc5
	      pos++;
Packit 762fc5
	    }
Packit 762fc5
	  triple = 0;
Packit 762fc5
	  l = 0;
Packit 762fc5
	}
Packit 762fc5
      inb++;
Packit 762fc5
    }
Packit 762fc5
  
Packit 762fc5
  retbuf=(byte*)malloc(sizeof(byte)*(pos+1));
Packit 762fc5
  memcpy(retbuf,outbuf,pos);
Packit 762fc5
  retbuf[pos]='\0';
Packit 762fc5
  
Packit 762fc5
  free(outbuf);
Packit 762fc5
Packit 762fc5
  if (ret_len) *ret_len = pos;
Packit 762fc5
  
Packit 762fc5
  return retbuf;
Packit 762fc5
}
Packit 762fc5
Packit 762fc5
size_t length_base64(char* src,size_t ssize)
Packit 762fc5
{
Packit 762fc5
  char* inb;
Packit 762fc5
  int i;
Packit 762fc5
  int l;
Packit 762fc5
  int left;
Packit 762fc5
  size_t pos;
Packit d0fd42
  //unsigned long triple;
Packit 762fc5
Packit 762fc5
  error(235, "decode base64\n");
Packit 762fc5
  /* Exit on empty input */
Packit 762fc5
  if (!ssize||src==NULL)
Packit 762fc5
    return 0;
Packit 762fc5
Packit 762fc5
Packit 762fc5
Packit 762fc5
  /* Initialize working pointers */
Packit 762fc5
  inb = src;
Packit 762fc5
Packit 762fc5
  l = 0;
Packit d0fd42
  //triple = 0;
Packit 762fc5
  pos=0;
Packit 762fc5
  left = ssize;
Packit 762fc5
  /*
Packit 762fc5
   * Process entire inbuf.
Packit 762fc5
   */
Packit 762fc5
  while (left != 0)
Packit 762fc5
    {
Packit 762fc5
      left--;
Packit 762fc5
      i = fromb64[(unsigned char)*inb];
Packit 762fc5
      switch(i)
Packit 762fc5
	{
Packit 762fc5
	case FAIL:
Packit 762fc5
	  error(3, "length_base64: Illegal character: %c\n", *inb);
Packit 762fc5
	  error(230, "length_base64: Illegal line:\n%s\n", src);
Packit 762fc5
	  return 0; 
Packit 762fc5
	  break;
Packit 762fc5
	case SKIP:
Packit 762fc5
	  break;
Packit 762fc5
	default:
Packit d0fd42
	  //triple = triple<<6 | (0x3f & i);
Packit 762fc5
	  l++;
Packit 762fc5
	  break;
Packit 762fc5
	}
Packit 762fc5
      if (l == 4 || left == 0)
Packit 762fc5
	{
Packit 762fc5
	  switch(l)
Packit 762fc5
	    {
Packit 762fc5
	    case 2:
Packit d0fd42
	      //triple = triple>>4;
Packit 762fc5
	      break;
Packit 762fc5
	    case 3:
Packit d0fd42
	      //triple = triple>>2;
Packit 762fc5
	      break;
Packit 762fc5
	    default:
Packit 762fc5
	      break;
Packit 762fc5
	    }
Packit 762fc5
	  for (l  -= 2; l >= 0; l--)
Packit 762fc5
	    {
Packit 762fc5
	      pos++;
Packit 762fc5
	    }
Packit d0fd42
	  //triple = 0;
Packit 762fc5
	  l = 0;
Packit 762fc5
	}
Packit 762fc5
      inb++;
Packit 762fc5
    }
Packit 762fc5
  
Packit 762fc5
  return pos;
Packit 762fc5
}
Packit 762fc5