aboutsummaryrefslogtreecommitdiff
path: root/lib/base64.c
blob: 8fb971e9149e16f4040a43b8f0aaaa7181a4bdba (plain)
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* This file is part of pam-modules.
   Copyright (C) 2008, 2010-2012, 2014-2015 Sergey Poznyakoff
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 3 of the License, or (at your
   option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <graypam.h>

static int
b64_input(char c)
{
	const char table[64] =
	   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	int i;

	for (i = 0; i < 64; i++) {
		if (table[i] == c)
			return i;
	}
	return -1;
}

ssize_t
gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize)
{
	int i = 0, pad = 0;
	size_t consumed = 0;
	ssize_t nbytes;
	unsigned char data[4];

	nbytes = 0;
	while (consumed < isize) {
		while (i < 4 && consumed < isize) {
			int tmp = b64_input(*iptr++);
			consumed++;
			if (tmp != -1)
				data[i++] = tmp;
			else if (iptr[-1] == '=') {
				data[i++] = '\0';
				pad++;
			}
		}

		/* I have a entire block of data 32 bits get the output
		   data.  */
		if (i == 4) {
			gray_slist_append_char(slist,
			     (data[0] << 2) | ((data[1] & 0x30) >> 4));
			gray_slist_append_char(slist,
			     ((data[1] & 0xf) << 4) | ((data[2] & 0x3c) >> 2));
			gray_slist_append_char(slist,
			     ((data[2] & 0x3) << 6) | data[3]);
			nbytes += 3 - pad;
		} else 
			return -1;
		i = 0;
	}
	return nbytes;
}

Return to:

Send suggestions and report system problems to the System administrator.