base64.c revision a6d42e7d71324c5193c3b94d57d96ba2925d52e1
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifdef _KERNEL
#else
#include <string.h>
#include <errno.h>
#endif /* _KERNEL */
/*
* base64 decoding table (from uudecode.c)
*/
/* BEGIN CSTYLED */
static char base64_decode_tab[] = {
'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
'\377', '\377', '\377', 62, '\377', '\377', '\377', 63,
52, 53, 54, 55, 56, 57, 58, 59,
60, 61, '\377', '\377', '\377', '\377', '\377', '\377',
'\377', 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, '\377', '\377', '\377', '\377', '\377',
'\377', 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, '\377', '\377', '\377', '\377', '\377'
};
/* END CSTYLED */
/* true if the character is in the base64 encoding table */
('a' <= (c) && (c) <= 'z') || \
('0' <= (c) && (c) <= '9') || \
(c) == '+' || (c) == '/')
static int
{
int rc = 0;
switch (num) {
case 0:
case 1: /* these are impossible */
default:
break;
case 2: /* 2 base64 bytes == 1 decoded byte */
rc = 1;
break;
case 3: /* 3 base64 bytes == 2 decoded bytes */
rc = 2;
break;
case 4: /* 4 base64 bytes == 3 decoded bytes */
(char4 & 0x3F);
rc = 3;
break;
}
return (rc);
}
#define BUFSIZE 12
int
{
char *iptr;
/*
* base64 decode algorith, adapted from uudecode.c
*
* A valid base64 string is a multiple of 4 bytes in length
*/
if ((hstr_len % 4) != 0)
return (EINVAL);
endseen = numbase64chars = 0;
*out_len = 0;
/* decode chars */
endseen++;
if (validbase64(curchr))
/*
* if we've gathered 4 base64 octets
* we need to decode and output them
*/
if (numbase64chars == 4) {
numbase64chars = 0;
return (E2BIG);
}
/*
* handle any remaining base64 octets at end
*/
if (endseen && numbase64chars > 0) {
numbase64chars = 0;
return (E2BIG);
}
}
return (0);
}
static char base64_encode_tab[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
#define BASE64_BUF_HAS_ROOM(bytes_needed) \
int
char *base64_str_buf, int base64_buf_len)
{
char *optr;
int in_bytes_remaining;
/* base64 encode algorith, adapted from uuencode.c */
/*
* read must be a multiple of 3 bytes for
* this algorithm to work, and also must
* be small enough that read_size * (4/3)
* will always be 76 bytes or less, since
* base64 lines can be no longer than that
*/
if (!BASE64_BUF_HAS_ROOM(4))
return (E2BIG);
iptr += 3;
}
/* need output padding ? */
/* ASSERT(in_bytes_remaining < 3); */
switch (in_bytes_remaining) {
case 0:
/* no-op - 24 bits of data encoded */
if (!BASE64_BUF_HAS_ROOM(1))
return (E2BIG);
*(optr++) = '\0';
break;
case 1:
/* 8 bits encoded - pad with 2 '=' */
if (!BASE64_BUF_HAS_ROOM(5))
return (E2BIG);
*(optr++) = '=';
*(optr++) = '=';
*(optr++) = '\0';
break;
case 2:
/* 16 bits encoded - pad with 1 '=' */
if (!BASE64_BUF_HAS_ROOM(5))
return (E2BIG);
*(optr++) = '=';
*(optr++) = '\0';
break;
default:
/* impossible */
break;
}
return (0);
}