00001
00017 #define _GNU_SOURCE
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <assert.h>
00024 #include <string.h>
00025 #include <stdarg.h>
00026 #include <fcntl.h>
00027
00028 #include <unistd.h>
00029 #include <sys/select.h>
00030 #include <sys/types.h>
00031 #include <sys/socket.h>
00032 #include <netinet/in.h>
00033 #include <arpa/inet.h>
00034 #include <netdb.h>
00035
00036 #include "mihl.h"
00037
00038 #include "glovars.h"
00039
00040 #include "tcp_utils.h"
00041 #include "b64.h"
00042
00050 static void encodeblock( uint8_t in[3], uint8_t out[4], int len ) {
00051 static const char cb64[]=
00052 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00053 out[0] = cb64[ in[0] >> 2 ];
00054 out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
00055 out[2] = (uint8_t) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
00056 out[3] = (uint8_t) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
00057 }
00058
00067 void mihl_base64_encode( char const *bin, size_t size, char *bout, size_t maxlen ) {
00068
00069 memset( bout, 0, maxlen );
00070 int bi = 0;
00071 for ( unsigned index = 0; index < size; ) {
00072 uint8_t in[3], out[4];
00073 int len = 0;
00074 for( int i = 0; i < 3; i++ ) {
00075 in[i] = (uint8_t) bin[index++];
00076 if( index <= size )
00077 len++;
00078 else
00079 in[i] = 0;
00080 }
00081 if( len ) {
00082 encodeblock( in, out, len );
00083 for( int i = 0; i < 4; i++ )
00084 bout[bi++] = out[i];
00085 }
00086 }
00087
00088 }
00089
00098 static void decodeblock( uint8_t in[4], uint8_t out[3] ) {
00099 out[ 0 ] = (uint8_t ) (in[0] << 2 | in[1] >> 4);
00100 out[ 1 ] = (uint8_t ) (in[1] << 4 | in[2] >> 2);
00101 out[ 2 ] = (uint8_t ) (((in[2] << 6) & 0xc0) | in[3]);
00102 }
00103
00112 void mihl_base64_decode( char const *bin, size_t size, char *bout, size_t maxlen ) {
00113 static const char cd64[]=
00114 "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
00115 memset( bout, 0, maxlen );
00116 int bi = 0;
00117 for ( unsigned index = 0; index < size; ) {
00118 uint8_t in[4], out[3];
00119 for( int i = 0; i < 4; i++, index++ ) {
00120 if ( index < size ) {
00121 uint8_t v = (uint8_t) bin[index];
00122 v = ((v < 43) || (v > 122)) ? 0 : cd64[v-43];
00123 if ( v )
00124 v = (v == '$') ? 0 : v-61;
00125 in[i] = (v) ? v-1 : 0;
00126 }
00127 else {
00128 in[i] = 0;
00129 }
00130 }
00131 decodeblock( in, out );
00132 for( int i = 0; i < 3; i++ )
00133 bout[bi++] = out[i];
00134 }
00135 bout[bi++] = 0;
00136 }