Fix base{32,64}_decode(). The former handled padding incorrectly; the
latter was derived from the former, and had a couple of copy-paste bugs in addition to the padding bug. git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@770 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
parent
576e1e6b1c
commit
4645bc1762
|
@ -1,5 +1,5 @@
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2013 Universitetet i Oslo
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -120,7 +120,7 @@ base32_dec(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||||
uint64_t bits;
|
uint64_t bits;
|
||||||
int shift;
|
int shift;
|
||||||
|
|
||||||
for (len = 0, bits = 0, shift = 40; ilen && *in; --ilen, ++in) {
|
for (len = 0, bits = 0, shift = 40; ilen && *in && *in != '='; --ilen, ++in) {
|
||||||
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n') {
|
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n') {
|
||||||
continue;
|
continue;
|
||||||
} else if (*in >= 'A' && *in <= 'Z') {
|
} else if (*in >= 'A' && *in <= 'Z') {
|
||||||
|
@ -132,33 +132,75 @@ base32_dec(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||||
} else if (*in >= '2' && *in <= '7') {
|
} else if (*in >= '2' && *in <= '7') {
|
||||||
shift -= 5;
|
shift -= 5;
|
||||||
bits |= (uint64_t)(*in - '2' + 26) << shift;
|
bits |= (uint64_t)(*in - '2' + 26) << shift;
|
||||||
} else if (*in == '=' &&
|
} else if (*in == '=') {
|
||||||
(shift == 30 || shift == 20 || shift == 15 || shift == 5)) {
|
/* handled below */
|
||||||
/* hack: assume the rest of the padding is ok */
|
break;
|
||||||
shift = 0;
|
|
||||||
} else {
|
} else {
|
||||||
*olen = 0;
|
goto bad;
|
||||||
return (-1);
|
|
||||||
}
|
}
|
||||||
if (shift == 0) {
|
if (shift == 0) {
|
||||||
if ((len += 5) <= *olen) {
|
if ((len += 5) <= *olen) {
|
||||||
out[0] = (bits >> 32) & 0xff;
|
*out++ = (bits >> 32) & 0xff;
|
||||||
out[1] = (bits >> 24) & 0xff;
|
*out++ = (bits >> 24) & 0xff;
|
||||||
out[2] = (bits >> 16) & 0xff;
|
*out++ = (bits >> 16) & 0xff;
|
||||||
out[3] = (bits >> 8) & 0xff;
|
*out++ = (bits >> 8) & 0xff;
|
||||||
out[4] = bits & 0xff;
|
*out++ = bits & 0xff;
|
||||||
out += 5;
|
|
||||||
}
|
}
|
||||||
bits = 0;
|
bits = 0;
|
||||||
shift = 40;
|
shift = 40;
|
||||||
}
|
}
|
||||||
if (*in == '=')
|
}
|
||||||
|
if (ilen && *in == '=' &&
|
||||||
|
(shift == 30 || shift == 20 || shift == 15 || shift == 5)) {
|
||||||
|
/*
|
||||||
|
* Padding:
|
||||||
|
*
|
||||||
|
* 00 8 AA====== 30
|
||||||
|
* 00 00 16 AAAA==== 20
|
||||||
|
* 00 00 00 24 AAAAA=== 15
|
||||||
|
* 00 00 00 00 32 AAAAAAA= 5
|
||||||
|
*
|
||||||
|
* XXX We should check that the last few bits before the
|
||||||
|
* padding starts are zero.
|
||||||
|
*/
|
||||||
|
switch (shift) {
|
||||||
|
case 5:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 32) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
|
case 15:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 32) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
|
case 20:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 32) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
|
case 30:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 32) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
/* consume remaining padding and whitespace */
|
||||||
|
for (; ilen && *in; --ilen, ++in) {
|
||||||
|
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n')
|
||||||
|
continue;
|
||||||
|
else if (*in == '=' && shift)
|
||||||
|
shift -= 5;
|
||||||
|
else
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (len > *olen) {
|
if (ilen)
|
||||||
*olen = len;
|
goto bad;
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
if (len > *olen)
|
||||||
|
return (-1);
|
||||||
return (0);
|
return (0);
|
||||||
|
bad:
|
||||||
|
*olen = 0;
|
||||||
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2013 Universitetet i Oslo
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -119,37 +119,69 @@ base64_dec(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||||
bits |= (uint32_t)(*in - 'a' + 26) << shift;
|
bits |= (uint32_t)(*in - 'a' + 26) << shift;
|
||||||
} else if (*in >= '0' && *in <= '9') {
|
} else if (*in >= '0' && *in <= '9') {
|
||||||
shift -= 6;
|
shift -= 6;
|
||||||
bits |= (uint32_t)(*in - '2' + 52) << shift;
|
bits |= (uint32_t)(*in - '0' + 52) << shift;
|
||||||
} else if (*in == '+') {
|
} else if (*in == '+') {
|
||||||
shift -= 6;
|
shift -= 6;
|
||||||
bits |= (uint32_t)62 << shift;
|
bits |= (uint32_t)62 << shift;
|
||||||
} else if (*in == '/') {
|
} else if (*in == '/') {
|
||||||
shift -= 6;
|
shift -= 6;
|
||||||
bits |= (uint32_t)63 << shift;
|
bits |= (uint32_t)63 << shift;
|
||||||
} else if (*in == '=' && (shift == 12 || shift == 6)) {
|
} else if (*in == '=') {
|
||||||
/* hack: assume the rest of the padding is ok */
|
/* handled below */
|
||||||
shift = 0;
|
break;
|
||||||
} else {
|
} else {
|
||||||
*olen = 0;
|
goto bad;
|
||||||
return (-1);
|
|
||||||
}
|
}
|
||||||
if (shift == 0) {
|
if (shift == 0) {
|
||||||
if ((len += 3) <= *olen) {
|
if ((len += 3) <= *olen) {
|
||||||
out[1] = (bits >> 16) & 0xff;
|
*out++ = (bits >> 16) & 0xff;
|
||||||
out[1] = (bits >> 8) & 0xff;
|
*out++ = (bits >> 8) & 0xff;
|
||||||
out[2] = bits & 0xff;
|
*out++ = bits & 0xff;
|
||||||
out += 3;
|
|
||||||
}
|
}
|
||||||
bits = 0;
|
bits = 0;
|
||||||
shift = 24;
|
shift = 24;
|
||||||
}
|
}
|
||||||
if (*in == '=')
|
}
|
||||||
|
if (ilen && *in == '=' && (shift == 12 || shift == 6)) {
|
||||||
|
/*
|
||||||
|
* Padding:
|
||||||
|
*
|
||||||
|
* 00 8 AA== 12
|
||||||
|
* 00 00 16 AAA= 6
|
||||||
|
*
|
||||||
|
* XXX We should check that the last few bits before the
|
||||||
|
* padding starts are zero.
|
||||||
|
*/
|
||||||
|
switch (shift) {
|
||||||
|
case 6:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 16) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
|
case 12:
|
||||||
|
if (++len <= *olen)
|
||||||
|
*out++ = (bits >> 16) & 0xff;
|
||||||
|
bits <<= 8;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
/* consume remaining padding and whitespace */
|
||||||
|
for (; ilen && *in; --ilen, ++in) {
|
||||||
|
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n')
|
||||||
|
continue;
|
||||||
|
else if (*in == '=' && shift)
|
||||||
|
shift -= 6;
|
||||||
|
else
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (len > *olen) {
|
if (ilen)
|
||||||
*olen = len;
|
goto bad;
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
*olen = len;
|
*olen = len;
|
||||||
|
if (len > *olen)
|
||||||
|
return (-1);
|
||||||
return (0);
|
return (0);
|
||||||
|
bad:
|
||||||
|
*olen = 0;
|
||||||
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue