Blame src/base64.c

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