libalpm
Arch Linux Package Manager Library
|
00001 /* 00002 * RFC 1521 base64 encoding/decoding 00003 * 00004 * Copyright (C) 2006-2010, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 /* 00025 * Pacman Notes: 00026 * 00027 * Taken from the PolarSSL project at www.polarssl.org under terms of the 00028 * GPL. This is from version 0.14.2 of the library, and has been modified 00029 * as following, which may be helpful for future updates: 00030 * * remove "polarssl/config.h" include 00031 * * change include from "polarssl/base64.h" to "base64.h" 00032 * * removal of SELF_TEST code 00033 */ 00034 00035 #include <stdint.h> 00036 00037 #include "base64.h" 00038 00039 static const unsigned char base64_enc_map[64] = 00040 { 00041 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00042 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00043 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 00044 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 00045 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 00046 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 00047 '8', '9', '+', '/' 00048 }; 00049 00050 static const unsigned char base64_dec_map[128] = 00051 { 00052 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00053 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00054 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00055 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00056 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, 00057 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 00058 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 00059 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 00060 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 00061 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 00062 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 00063 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 00064 49, 50, 51, 127, 127, 127, 127, 127 00065 }; 00066 00067 #if 0 00068 /* 00069 * Encode a buffer into base64 format 00070 */ 00071 int base64_encode( unsigned char *dst, size_t *dlen, 00072 const unsigned char *src, size_t slen ) 00073 { 00074 size_t i, n; 00075 int C1, C2, C3; 00076 unsigned char *p; 00077 00078 if( slen == 0 ) 00079 return( 0 ); 00080 00081 n = (slen << 3) / 6; 00082 00083 switch( (slen << 3) - (n * 6) ) 00084 { 00085 case 2: n += 3; break; 00086 case 4: n += 2; break; 00087 default: break; 00088 } 00089 00090 if( *dlen < n + 1 ) 00091 { 00092 *dlen = n + 1; 00093 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 00094 } 00095 00096 n = (slen / 3) * 3; 00097 00098 for( i = 0, p = dst; i < n; i += 3 ) 00099 { 00100 C1 = *src++; 00101 C2 = *src++; 00102 C3 = *src++; 00103 00104 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00105 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00106 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; 00107 *p++ = base64_enc_map[C3 & 0x3F]; 00108 } 00109 00110 if( i < slen ) 00111 { 00112 C1 = *src++; 00113 C2 = ((i + 1) < slen) ? *src++ : 0; 00114 00115 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00116 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00117 00118 if( (i + 1) < slen ) 00119 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; 00120 else *p++ = '='; 00121 00122 *p++ = '='; 00123 } 00124 00125 *dlen = p - dst; 00126 *p = 0; 00127 00128 return( 0 ); 00129 } 00130 #endif 00131 00132 /* 00133 * Decode a base64-formatted buffer 00134 */ 00135 int base64_decode( unsigned char *dst, size_t *dlen, 00136 const unsigned char *src, size_t slen ) 00137 { 00138 size_t i, n; 00139 uint32_t j, x; 00140 unsigned char *p; 00141 00142 for( i = j = n = 0; i < slen; i++ ) 00143 { 00144 if( ( slen - i ) >= 2 && 00145 src[i] == '\r' && src[i + 1] == '\n' ) 00146 continue; 00147 00148 if( src[i] == '\n' ) 00149 continue; 00150 00151 if( src[i] == '=' && ++j > 2 ) 00152 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00153 00154 if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) 00155 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00156 00157 if( base64_dec_map[src[i]] < 64 && j != 0 ) 00158 return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 00159 00160 n++; 00161 } 00162 00163 if( n == 0 ) 00164 return( 0 ); 00165 00166 n = ((n * 6) + 7) >> 3; 00167 00168 if( *dlen < n ) 00169 { 00170 *dlen = n; 00171 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 00172 } 00173 00174 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) 00175 { 00176 if( *src == '\r' || *src == '\n' ) 00177 continue; 00178 00179 j -= ( base64_dec_map[*src] == 64 ); 00180 x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); 00181 00182 if( ++n == 4 ) 00183 { 00184 n = 0; 00185 if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); 00186 if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); 00187 if( j > 2 ) *p++ = (unsigned char)( x ); 00188 } 00189 } 00190 00191 *dlen = p - dst; 00192 00193 return( 0 ); 00194 }