Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/net/base64.c
Show All 35 Lines | |||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, | ||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING | ||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN | ||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
#include <sys/types.h> | |||||
kib: This is wrong place for any include addition. There must be no any lines between cdefs.h and… | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <sys/socket.h> | |||||
#include <netinet/in.h> | |||||
#include <arpa/inet.h> | |||||
#include <arpa/nameser.h> | |||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <resolv.h> | #include <b64.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#define Assert(Cond) if (!(Cond)) abort() | #define Assert(Cond) if (!(Cond)) abort() | ||||
static const char Base64[] = | static const char Base64[] = | ||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | |||||
/* skips all whitespace anywhere. | /* skips all whitespace anywhere. | ||||
converts characters, four at a time, starting at (or after) | converts characters, four at a time, starting at (or after) | ||||
src from base - 64 numbers into three 8 bit bytes in the target area. | src from base - 64 numbers into three 8 bit bytes in the target area. | ||||
it returns the number of data bytes stored at the target, or -1 on error. | it returns the number of data bytes stored at the target, or -1 on error. | ||||
*/ | */ | ||||
int | int | ||||
b64_pton(const char *src, u_char *target, size_t targsize) | b64_pton_partial(const char *src, unsigned char **original, size_t targsize) | ||||
{ | { | ||||
int tarindex, state, ch; | int tarindex, state, ch; | ||||
u_char nextbyte; | unsigned char nextbyte, *target; | ||||
char *pos; | char *pos; | ||||
state = 0; | state = 0; | ||||
tarindex = 0; | tarindex = 0; | ||||
target = *original; | |||||
while ((ch = *src++) != '\0') { | while ((ch = *src++) != '\0') { | ||||
if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */ | if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */ | ||||
continue; | continue; | ||||
if (ch == Pad64) | if (ch == Pad64) | ||||
break; | break; | ||||
pos = strchr(Base64, ch); | pos = strchr(Base64, ch); | ||||
if (pos == NULL) /* A non-base64 character. */ | if (pos == NULL) /* A non-base64 character. */ | ||||
return (-1); | goto error; | ||||
switch (state) { | switch (state) { | ||||
case 0: | case 0: | ||||
if (target) { | if (target) { | ||||
if ((size_t)tarindex >= targsize) | if ((size_t)tarindex >= targsize) | ||||
return (-1); | goto error; | ||||
target[tarindex] = (pos - Base64) << 2; | target[tarindex] = (pos - Base64) << 2; | ||||
} | } | ||||
state = 1; | state = 1; | ||||
break; | break; | ||||
case 1: | case 1: | ||||
if (target) { | if (target) { | ||||
if ((size_t)tarindex >= targsize) | if ((size_t)tarindex >= targsize) | ||||
return (-1); | goto error; | ||||
target[tarindex] |= (pos - Base64) >> 4; | target[tarindex] |= (pos - Base64) >> 4; | ||||
nextbyte = ((pos - Base64) & 0x0f) << 4; | nextbyte = ((pos - Base64) & 0x0f) << 4; | ||||
if ((size_t)tarindex + 1 < targsize) | if ((size_t)tarindex + 1 < targsize) | ||||
target[tarindex + 1] = nextbyte; | target[tarindex + 1] = nextbyte; | ||||
else if (nextbyte) | else if (nextbyte) | ||||
return (-1); | goto error; | ||||
} | } | ||||
tarindex++; | tarindex++; | ||||
state = 2; | state = 2; | ||||
break; | break; | ||||
case 2: | case 2: | ||||
if (target) { | if (target) { | ||||
if ((size_t)tarindex >= targsize) | if ((size_t)tarindex >= targsize) | ||||
return (-1); | goto error; | ||||
target[tarindex] |= (pos - Base64) >> 2; | target[tarindex] |= (pos - Base64) >> 2; | ||||
nextbyte = ((pos - Base64) & 0x03) << 6; | nextbyte = ((pos - Base64) & 0x03) << 6; | ||||
if ((size_t)tarindex + 1 < targsize) | if ((size_t)tarindex + 1 < targsize) | ||||
target[tarindex + 1] = nextbyte; | target[tarindex + 1] = nextbyte; | ||||
else if (nextbyte) | else if (nextbyte) | ||||
return (-1); | goto error; | ||||
} | } | ||||
tarindex++; | tarindex++; | ||||
state = 3; | state = 3; | ||||
break; | break; | ||||
case 3: | case 3: | ||||
if (target) { | if (target) { | ||||
if ((size_t)tarindex >= targsize) | if ((size_t)tarindex >= targsize) | ||||
return (-1); | goto error; | ||||
target[tarindex] |= (pos - Base64); | target[tarindex] |= (pos - Base64); | ||||
} | } | ||||
tarindex++; | tarindex++; | ||||
state = 0; | state = 0; | ||||
break; | break; | ||||
default: | default: | ||||
abort(); | abort(); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* We are done decoding Base-64 chars. Let's see if we ended | * We are done decoding Base-64 chars. Let's see if we ended | ||||
* on a byte boundary, and/or with erroneous trailing characters. | * on a byte boundary, and/or with erroneous trailing characters. | ||||
*/ | */ | ||||
if (ch == Pad64) { /* We got a pad char. */ | if (ch == Pad64) { /* We got a pad char. */ | ||||
ch = *src++; /* Skip it, get next. */ | ch = *src++; /* Skip it, get next. */ | ||||
switch (state) { | switch (state) { | ||||
case 0: /* Invalid = in first position */ | case 0: /* Invalid = in first position */ | ||||
case 1: /* Invalid = in second position */ | case 1: /* Invalid = in second position */ | ||||
return (-1); | goto error; | ||||
case 2: /* Valid, means one byte of info */ | case 2: /* Valid, means one byte of info */ | ||||
/* Skip any number of spaces. */ | /* Skip any number of spaces. */ | ||||
for ((void)NULL; ch != '\0'; ch = *src++) | for ((void)NULL; ch != '\0'; ch = *src++) | ||||
if (!isspace((unsigned char)ch)) | if (!isspace((unsigned char)ch)) | ||||
break; | break; | ||||
/* Make sure there is another trailing = sign. */ | /* Make sure there is another trailing = sign. */ | ||||
if (ch != Pad64) | if (ch != Pad64) | ||||
return (-1); | goto error; | ||||
ch = *src++; /* Skip the = */ | ch = *src++; /* Skip the = */ | ||||
/* Fall through to "single trailing =" case. */ | /* Fall through to "single trailing =" case. */ | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case 3: /* Valid, means two bytes of info */ | case 3: /* Valid, means two bytes of info */ | ||||
/* | /* | ||||
* We know this char is an =. Is there anything but | * We know this char is an =. Is there anything but | ||||
* whitespace after it? | * whitespace after it? | ||||
*/ | */ | ||||
for ((void)NULL; ch != '\0'; ch = *src++) | for ((void)NULL; ch != '\0'; ch = *src++) | ||||
if (!isspace((unsigned char)ch)) | if (!isspace((unsigned char)ch)) | ||||
return (-1); | goto error; | ||||
/* | /* | ||||
* Now make sure for cases 2 and 3 that the "extra" | * Now make sure for cases 2 and 3 that the "extra" | ||||
* bits that slopped past the last full byte were | * bits that slopped past the last full byte were | ||||
* zeros. If we don't check them, they become a | * zeros. If we don't check them, they become a | ||||
* subliminal channel. | * subliminal channel. | ||||
*/ | */ | ||||
if (target && (size_t)tarindex < targsize && | if (target && (size_t)tarindex < targsize && | ||||
target[tarindex] != 0) | target[tarindex] != 0) | ||||
return (-1); | goto error; | ||||
} | } | ||||
} else { | } else { | ||||
/* | /* | ||||
* We ended by seeing the end of the string. Make sure we | * We ended by seeing the end of the string. Make sure we | ||||
* have no partial bytes lying around. | * have no partial bytes lying around. | ||||
*/ | */ | ||||
if (state != 0) | if (state != 0) | ||||
return (-1); | goto error; | ||||
} | } | ||||
*original = target + tarindex; | |||||
return (tarindex); | return (tarindex); | ||||
error: | |||||
*original = target + tarindex; | |||||
return (-1); | |||||
} | |||||
int | |||||
b64_pton(const char *src, unsigned char *target, size_t targsize) | |||||
{ | |||||
return b64_pton_partial(src, &target, targsize); | |||||
kibUnsubmitted Not Done Inline Actionsreturn (); kib: `return ();` | |||||
} | } |
This is wrong place for any include addition. There must be no any lines between cdefs.h and FBSDID (not least because both lines are going to be removed somewhere in the future)