1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 1995-2001 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include <config.h> 37 38#include <stdlib.h> 39#include <string.h> 40#include <limits.h> 41#include <krb5/base64.h> 42 43static const char base64_chars[] = 44 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 45 46static int 47pos(char c) 48{ 49 const char *p; 50 for (p = base64_chars; *p; p++) 51 if (*p == c) 52 return p - base64_chars; 53 return -1; 54} 55 56ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 57base64_encode(const void *data, int size, char **str) 58{ 59 char *s, *p; 60 int i; 61 int c; 62 const unsigned char *q; 63 64 if (size > INT_MAX/4 || size < 0) { 65 *str = NULL; 66 return -1; 67 } 68 69 p = s = (char *) malloc(size * 4 / 3 + 4); 70 if (p == NULL) { 71 *str = NULL; 72 return -1; 73 } 74 q = (const unsigned char *) data; 75 76 for (i = 0; i < size;) { 77 c = q[i++]; 78 c *= 256; 79 if (i < size) 80 c += q[i]; 81 i++; 82 c *= 256; 83 if (i < size) 84 c += q[i]; 85 i++; 86 p[0] = base64_chars[(c & 0x00fc0000) >> 18]; 87 p[1] = base64_chars[(c & 0x0003f000) >> 12]; 88 p[2] = base64_chars[(c & 0x00000fc0) >> 6]; 89 p[3] = base64_chars[(c & 0x0000003f) >> 0]; 90 if (i > size) 91 p[3] = '='; 92 if (i > size + 1) 93 p[2] = '='; 94 p += 4; 95 } 96 *p = 0; 97 *str = s; 98 return (int) strlen(s); 99} 100 101#define DECODE_ERROR 0xffffffff 102 103static unsigned int 104token_decode(const char *token) 105{ 106 int i; 107 unsigned int val = 0; 108 int marker = 0; 109 if (strlen(token) < 4) 110 return DECODE_ERROR; 111 for (i = 0; i < 4; i++) { 112 val *= 64; 113 if (token[i] == '=') 114 marker++; 115 else if (marker > 0) 116 return DECODE_ERROR; 117 else 118 val += pos(token[i]); 119 } 120 if (marker > 2) 121 return DECODE_ERROR; 122 return (marker << 24) | val; 123} 124 125ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 126base64_decode(const char *str, void *data) 127{ 128 const char *p; 129 unsigned char *q; 130 131 q = data; 132 for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { 133 unsigned int val = token_decode(p); 134 unsigned int marker = (val >> 24) & 0xff; 135 if (val == DECODE_ERROR) 136 return -1; 137 *q++ = (val >> 16) & 0xff; 138 if (marker < 2) 139 *q++ = (val >> 8) & 0xff; 140 if (marker < 1) 141 *q++ = val & 0xff; 142 } 143 return q - (unsigned char *) data; 144} 145