pam-modules/lib/base64.c
2022-02-04 09:38:17 +02:00

75 lines
1.9 KiB
C

/* This file is part of pam-modules.
Copyright (C) 2008-2022 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) {
if (gray_slist_append_char(slist,
(data[0] << 2) | ((data[1] & 0x30) >> 4)) != 1)
return -1;
if (gray_slist_append_char(slist,
((data[1] & 0xf) << 4) | ((data[2] & 0x3c) >> 2))
!= 1)
return -1;
if (gray_slist_append_char(slist,
((data[2] & 0x3) << 6) | data[3]) != 1)
return -1;
nbytes += 3 - pad;
} else {
errno = EILSEQ;
return -1;
}
i = 0;
}
return nbytes;
}